60#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();
620 StringRef TargetTriple,
622 StringRef DarwinArchName =
"") {
624 if (
const Arg *A = Args.getLastArg(options::OPT_target))
625 TargetTriple = A->getValue();
627 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
632 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
636 if (
Target.isOSBinFormatMachO()) {
638 if (!DarwinArchName.empty()) {
641 return llvm::Triple(
Target.normalize());
645 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
646 StringRef ArchName = A->getValue();
653 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
654 options::OPT_mbig_endian)) {
655 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
656 ?
Target.getLittleEndianArchVariant()
657 :
Target.getBigEndianArchVariant();
658 if (T.getArch() != llvm::Triple::UnknownArch) {
659 Target = llvm::Triple(T.normalize());
660 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
665 if (
Target.getArch() == llvm::Triple::tce)
671 if (!Args.hasArg(options::OPT_target)) {
672 if (std::optional<std::string> ObjectModeValue =
673 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
674 StringRef ObjectMode = *ObjectModeValue;
675 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
678 const bool OtherAllowedMode =
679 ObjectMode ==
"32_64" || ObjectMode ==
"any";
680 if (ObjectMode ==
"64") {
681 AT =
Target.get64BitArchVariant().getArch();
682 }
else if (ObjectMode ==
"32") {
683 AT =
Target.get32BitArchVariant().getArch();
684 }
else if (!OtherAllowedMode) {
685 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
688 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
697 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
698 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
701 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
703 D.
Diag(diag::err_drv_unsupported_opt_for_target)
704 << A->getAsString(Args) <<
Target.str();
707 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
708 options::OPT_m32, options::OPT_m16,
709 options::OPT_maix32, options::OPT_maix64);
711 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
713 if (A->getOption().matches(options::OPT_m64) ||
714 A->getOption().matches(options::OPT_maix64)) {
715 AT =
Target.get64BitArchVariant().getArch();
716 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
717 Target.getEnvironment() == llvm::Triple::GNUT64)
718 Target.setEnvironment(llvm::Triple::GNU);
719 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
720 Target.setEnvironment(llvm::Triple::Musl);
721 }
else if (A->getOption().matches(options::OPT_mx32) &&
722 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
723 AT = llvm::Triple::x86_64;
724 if (
Target.getEnvironment() == llvm::Triple::Musl)
725 Target.setEnvironment(llvm::Triple::MuslX32);
727 Target.setEnvironment(llvm::Triple::GNUX32);
728 }
else if (A->getOption().matches(options::OPT_m32) ||
729 A->getOption().matches(options::OPT_maix32)) {
731 D.
Diag(diag::err_drv_unsupported_opt_for_target)
732 << A->getAsString(Args) <<
Target.str();
734 AT =
Target.get32BitArchVariant().getArch();
735 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
736 Target.setEnvironment(llvm::Triple::GNU);
737 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
738 Target.setEnvironment(llvm::Triple::Musl);
740 }
else if (A->getOption().matches(options::OPT_m16) &&
741 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
742 AT = llvm::Triple::x86;
743 Target.setEnvironment(llvm::Triple::CODE16);
746 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
748 if (
Target.isWindowsGNUEnvironment())
756 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
762 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
763 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
764 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
767 if (A && !A->getOption().matches(options::OPT_m32))
768 D.
Diag(diag::err_drv_argument_not_allowed_with)
769 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
771 Target.setArch(llvm::Triple::x86);
772 Target.setArchName(
"i586");
773 Target.setEnvironmentName(
"");
774 Target.setOS(llvm::Triple::ELFIAMCU);
775 Target.setVendor(llvm::Triple::Intel);
781 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
782 StringRef ABIName = A->getValue();
783 if (ABIName ==
"32") {
785 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
786 Target.getEnvironment() == llvm::Triple::GNUABIN32)
787 Target.setEnvironment(llvm::Triple::GNU);
788 }
else if (ABIName ==
"n32") {
790 if (
Target.getEnvironment() == llvm::Triple::GNU ||
791 Target.getEnvironment() == llvm::Triple::GNUT64 ||
792 Target.getEnvironment() == llvm::Triple::GNUABI64)
793 Target.setEnvironment(llvm::Triple::GNUABIN32);
794 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
795 Target.getEnvironment() == llvm::Triple::MuslABI64)
796 Target.setEnvironment(llvm::Triple::MuslABIN32);
797 }
else if (ABIName ==
"64") {
799 if (
Target.getEnvironment() == llvm::Triple::GNU ||
800 Target.getEnvironment() == llvm::Triple::GNUT64 ||
801 Target.getEnvironment() == llvm::Triple::GNUABIN32)
802 Target.setEnvironment(llvm::Triple::GNUABI64);
803 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
804 Target.getEnvironment() == llvm::Triple::MuslABIN32)
805 Target.setEnvironment(llvm::Triple::MuslABI64);
815 if (Args.hasArg(options::OPT_march_EQ) ||
816 Args.hasArg(options::OPT_mcpu_EQ)) {
818 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
820 if (!llvm::errorToBool(ISAInfo.takeError())) {
821 unsigned XLen = (*ISAInfo)->getXLen();
823 if (
Target.isLittleEndian())
824 Target.setArch(llvm::Triple::riscv32);
826 Target.setArch(llvm::Triple::riscv32be);
828 }
else if (XLen == 64) {
829 if (
Target.isLittleEndian())
830 Target.setArch(llvm::Triple::riscv64);
832 Target.setArch(llvm::Triple::riscv64be);
839 if (
Target.getArch() == llvm::Triple::riscv32be ||
840 Target.getArch() == llvm::Triple::riscv64be) {
841 static bool WarnedRISCVBE =
false;
842 if (!WarnedRISCVBE) {
843 D.
Diag(diag::warn_drv_riscv_be_experimental);
844 WarnedRISCVBE =
true;
853 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
855 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
857 RuntimeName = A->getValue();
859 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
867 Diag(diag::err_drv_unsupported_option_argument)
868 << A->getSpelling() << A->getValue();
871 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
880 StringRef Program =
C.getArgs().getLastArgValue(
881 options::OPT_offload_arch_tool_EQ,
"offload-arch");
884 if (llvm::ErrorOr<std::string> Executable =
885 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
888 Args.push_back(
"--only=amdgpu");
890 Args.push_back(
"--only=nvptx");
891 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
894 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
899 if ((*StdoutOrErr)->getBuffer().empty()) {
900 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
906 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
908 GPUArchs.push_back(
Arch.str());
910 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
921 std::set<std::string> Archs;
922 for (Arg *A :
C.getInputArgs()) {
923 for (StringRef
Arch : A->getValues()) {
924 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
925 if (
Arch ==
"native") {
927 Archs.insert(Str.str());
929 Archs.insert(
Arch.str());
931 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
935 Archs.erase(
Arch.str());
941 for (llvm::StringRef
Arch : Archs) {
945 llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
946 llvm::Triple::AMD, llvm::Triple::AMDHSA),
950 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
955 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
961 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
966 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
967 <<
"offload" <<
Arch;
971 llvm::Triple Triple =
977 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
978 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
979 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
980 C.getArgs().MakeArgString(Triple.getArchName()),
981 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
983 C.getArgs().append(A);
984 C.getArgs().AddSynthesizedArg(A);
986 auto It = Triples.lower_bound(Triple);
987 if (It == Triples.end() || *It != Triple)
988 Triples.insert(It, Triple);
993 Triples.insert(llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
994 llvm::Triple::AMD, llvm::Triple::AMDHSA));
996 llvm::Triple::ArchType
Arch =
997 C.getDefaultToolChain().getTriple().isArch64Bit()
998 ? llvm::Triple::nvptx64
999 : llvm::Triple::nvptx;
1000 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1001 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1004 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1005 ? llvm::Triple::spirv64
1006 : llvm::Triple::spirv32));
1009 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1010 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1017 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1018 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1020 llvm::any_of(Inputs,
1021 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1026 (llvm::any_of(Inputs,
1027 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1030 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1031 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1033 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1034 options::OPT_fno_sycl,
false);
1035 bool IsOpenMPOffloading =
1037 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1038 options::OPT_fno_openmp,
false) &&
1039 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1040 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1041 !(IsCuda || IsHIP))));
1043 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1044 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1049 for (
const auto &[Active, Kind] : ActiveKinds)
1054 if (Kinds.size() > 1) {
1055 Diag(clang::diag::err_drv_mix_offload)
1062 if (IsCuda || IsHIP)
1069 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1070 std::vector<std::string> ArgValues =
1071 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1072 for (llvm::StringRef
Target : ArgValues) {
1076 if (ArgValues.empty())
1077 Diag(clang::diag::warn_drv_empty_joined_argument)
1079 .getLastArg(options::OPT_offload_targets_EQ)
1080 ->getAsString(
C.getInputArgs());
1087 llvm::StringMap<StringRef> FoundNormalizedTriples;
1088 for (
const llvm::Triple &
Target : Triples) {
1093 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1101 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1102 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1103 Diag(clang::diag::err_drv_argument_not_allowed_with)
1104 << IncompatArg->getSpelling() <<
"-fsycl";
1109 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1110 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1115 std::string NormalizedName =
Target.normalize();
1116 auto [TripleIt, Inserted] =
1117 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1119 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1120 <<
Target.str() << TripleIt->second;
1124 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1125 C.getDefaultToolChain().getTriple());
1129 auto &CudaInstallation =
1131 if (CudaInstallation.isValid())
1132 CudaInstallation.WarnIfUnsupportedVersion();
1135 C.addOffloadDeviceToolChain(&TC, Kind);
1140bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1145 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1149 if (!PathLIBEnv.empty()) {
1150 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1151 if (llvm::sys::fs::is_directory(PathLIBEnv))
1152 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1153 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1154 return readConfigFile(CustomizationFile, ExpCtx);
1155 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1160 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1161 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1162 return readConfigFile(CustomizationFile, ExpCtx);
1172 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1173 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1174 Copy->getValues() = Opt->getValues();
1175 if (Opt->isClaimed())
1177 Copy->setOwnsValues(Opt->getOwnsValues());
1178 Opt->setOwnsValues(
false);
1180 if (Opt->getAlias()) {
1181 const Arg *Alias = Opt->getAlias();
1182 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1183 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1184 Args.getArgString(Index), Index);
1185 AliasCopy->getValues() = Alias->getValues();
1186 AliasCopy->setOwnsValues(
false);
1187 if (Alias->isClaimed())
1189 Copy->setAlias(std::move(AliasCopy));
1193bool Driver::readConfigFile(StringRef
FileName,
1194 llvm::cl::ExpansionContext &ExpCtx) {
1198 Diag(diag::err_drv_cannot_open_config_file)
1199 <<
FileName << Status.getError().message();
1202 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1203 Diag(diag::err_drv_cannot_open_config_file)
1204 <<
FileName <<
"not a regular file";
1209 SmallVector<const char *, 32> NewCfgFileArgs;
1210 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1211 Diag(diag::err_drv_cannot_read_config_file)
1217 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1218 for (
const char *Opt : NewCfgFileArgs) {
1220 if (Opt[0] ==
'$' && Opt[1])
1221 NewCfgTailArgs.push_back(Opt + 1);
1223 NewCfgHeadArgs.push_back(Opt);
1227 llvm::SmallString<128> CfgFileName(
FileName);
1228 llvm::sys::path::native(CfgFileName);
1229 bool ContainErrors =
false;
1230 auto NewHeadOptions = std::make_unique<InputArgList>(
1234 auto NewTailOptions = std::make_unique<InputArgList>(
1241 for (Arg *A : *NewHeadOptions)
1243 for (Arg *A : *NewTailOptions)
1246 if (!CfgOptionsHead)
1247 CfgOptionsHead = std::move(NewHeadOptions);
1250 for (
auto *Opt : *NewHeadOptions)
1254 if (!CfgOptionsTail)
1255 CfgOptionsTail = std::move(NewTailOptions);
1258 for (
auto *Opt : *NewTailOptions)
1262 ConfigFiles.push_back(std::string(CfgFileName));
1266bool Driver::loadConfigFiles() {
1267 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1268 llvm::cl::tokenizeConfigFile, &
getVFS());
1272 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1273 SmallString<128> CfgDir;
1275 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1276 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1281 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1282 SmallString<128> CfgDir;
1283 llvm::sys::fs::expand_tilde(
1284 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1285 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1294 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1297 if (loadDefaultConfigFiles(ExpCtx))
1301 SmallString<128> CfgFilePath;
1303 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1306 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1307 CfgFilePath.assign(CfgFileName);
1308 if (llvm::sys::path::is_relative(CfgFilePath)) {
1309 if (
getVFS().makeAbsolute(CfgFilePath)) {
1310 Diag(diag::err_drv_cannot_open_config_file)
1311 << CfgFilePath <<
"cannot get absolute path";
1315 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1317 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1318 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1319 if (!SearchDir.empty())
1320 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1325 if (readConfigFile(CfgFilePath, ExpCtx))
1336 llvm::Triple Triple, std::string Suffix) {
1338 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1342 VersionTuple OSVersion = Triple.getOSVersion();
1343 if (!OSVersion.getMinor().has_value())
1346 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1350 if (OSVersion.getMajor() != 0) {
1351 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1352 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1358 Triple.setOSName(BaseOSName);
1359 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1362bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1365 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1369 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1372 std::string RealMode = getExecutableForDriverMode(Mode);
1373 llvm::Triple Triple;
1382 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1383 PrefixTriple.isOSUnknown())
1384 Triple = std::move(PrefixTriple);
1388 llvm::Triple RealTriple =
1390 if (Triple.str().empty()) {
1391 Triple = RealTriple;
1392 assert(!Triple.str().empty());
1397 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1411 SmallString<128> CfgFilePath;
1413 "-" + RealMode +
".cfg"))
1414 return readConfigFile(CfgFilePath, ExpCtx);
1418 if (TryModeSuffix) {
1421 return readConfigFile(CfgFilePath, ExpCtx);
1426 std::string CfgFileName = RealMode +
".cfg";
1427 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1428 if (readConfigFile(CfgFilePath, ExpCtx))
1430 }
else if (TryModeSuffix) {
1432 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1433 readConfigFile(CfgFilePath, ExpCtx))
1439 return readConfigFile(CfgFilePath, ExpCtx);
1447 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1456 if (!DriverMode.empty())
1457 setDriverMode(DriverMode);
1463 CLOptions = std::make_unique<InputArgList>(
1468 ContainsError = loadConfigFiles();
1469 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1470 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1474 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1476 if (HasConfigFileHead)
1477 for (
auto *Opt : *CLOptions)
1478 if (!Opt->getOption().matches(options::OPT_config))
1482 if (
IsCLMode() && !ContainsError) {
1484 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1486 CLModePassThroughArgList.push_back(A->getValue());
1489 if (!CLModePassThroughArgList.empty()) {
1492 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1497 for (
auto *Opt : *CLModePassThroughOptions)
1503 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1504 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1505 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1508 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1509 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1510 if (!VFS->exists(IncludeDir))
1511 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1516 bool CCCPrintPhases;
1519 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1520 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1523 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1524 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1527 Args.ClaimAllArgs(options::OPT_pipe);
1535 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1537 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1538 CCCGenericGCCName = A->getValue();
1541 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1545 if (Args.hasArg(options::OPT_fproc_stat_report))
1552 llvm::Triple T(TargetTriple);
1553 T.setOS(llvm::Triple::Win32);
1554 T.setVendor(llvm::Triple::PC);
1555 T.setEnvironment(llvm::Triple::MSVC);
1556 T.setObjectFormat(llvm::Triple::COFF);
1557 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1558 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1559 TargetTriple = T.str();
1562 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1563 StringRef TargetProfile = A->getValue();
1566 TargetTriple = *Triple;
1568 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1572 if (Args.hasArg(options::OPT_spirv)) {
1573 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1574 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1575 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1576 llvm::Triple T(TargetTriple);
1579 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1581 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1582 TargetInfo = ValidTargets.find(A->getValue());
1584 Diag(diag::err_drv_invalid_value)
1585 << A->getAsString(Args) << A->getValue();
1591 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1592 TargetTriple = T.str();
1596 Diag(diag::err_drv_dxc_missing_target_profile);
1600 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1601 TargetTriple = A->getValue();
1602 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1603 Dir = A->getValue();
1604 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1608 if (std::optional<std::string> CompilerPathValue =
1609 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1610 StringRef CompilerPath = *CompilerPathValue;
1611 while (!CompilerPath.empty()) {
1612 std::pair<StringRef, StringRef> Split =
1613 CompilerPath.split(llvm::sys::EnvPathSeparator);
1614 PrefixDirs.push_back(std::string(Split.first));
1615 CompilerPath = Split.second;
1618 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1620 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1623 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1626 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1627 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1628 .Case(
"cwd", SaveTempsCwd)
1629 .Case(
"obj", SaveTempsObj)
1630 .Default(SaveTempsCwd);
1633 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1634 options::OPT_offload_device_only,
1635 options::OPT_offload_host_device)) {
1636 if (A->getOption().matches(options::OPT_offload_host_only))
1637 Offload = OffloadHost;
1638 else if (A->getOption().matches(options::OPT_offload_device_only))
1639 Offload = OffloadDevice;
1641 Offload = OffloadHostDevice;
1645 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1646 StringRef
Name = A->getValue();
1647 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1648 .Case(
"off", EmbedNone)
1649 .Case(
"all", EmbedBitcode)
1650 .Case(
"bitcode", EmbedBitcode)
1651 .Case(
"marker", EmbedMarker)
1654 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1657 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1661 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1662 llvm::sys::fs::remove(A->getValue());
1668 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1670 !Args.hasArg(options::OPT_fmodules) && Std &&
1671 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1672 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1673 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1674 Std->containsValue(
"c++latest"));
1677 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1678 options::OPT_fmodule_header)) {
1680 ModulesModeCXX20 =
true;
1681 if (A->getOption().matches(options::OPT_fmodule_header))
1684 StringRef ArgName = A->getValue();
1685 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1690 Diags.Report(diag::err_drv_invalid_value)
1691 << A->getAsString(Args) << ArgName;
1697 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1698 std::make_unique<InputArgList>(std::move(Args));
1708 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1709 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1711 bool MLContainsError;
1712 auto MultilibMacroDefineList =
1714 MLMacroDefinesChar,
false, MLContainsError));
1715 if (!MLContainsError) {
1716 for (
auto *Opt : *MultilibMacroDefineList) {
1723 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1727 if (!Triple.isWasm()) {
1728 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1729 StringRef TripleObjectFormat =
1730 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1731 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1732 TripleVersionName != TripleObjectFormat) {
1733 Diags.Report(diag::err_drv_triple_version_invalid)
1735 ContainsError =
true;
1740 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1741 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1742 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1750 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1751 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1753 case llvm::Triple::arm:
1754 case llvm::Triple::armeb:
1755 case llvm::Triple::thumb:
1756 case llvm::Triple::thumbeb:
1757 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1758 Diag(diag::warn_target_unrecognized_env)
1760 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1763 case llvm::Triple::aarch64:
1764 case llvm::Triple::aarch64_be:
1765 case llvm::Triple::aarch64_32:
1766 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1767 Diag(diag::warn_target_unrecognized_env)
1769 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1786 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1787 if (HasConfigFileTail && Inputs.size()) {
1790 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1791 for (Arg *A : *CfgOptionsTail)
1792 TranslatedLinkerIns.append(A);
1793 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1800 bool UseModulesDriver =
C->getArgs().hasFlag(
1801 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1803 if (UseModulesDriver) {
1804 Diags.Report(diag::remark_performing_driver_managed_module_build);
1812 const auto StdModuleManifestPath =
1815 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1816 Diags.Report(diag::remark_modules_manifest_not_found);
1818 Diags.Report(diag::remark_using_modules_manifest)
1819 << StdModuleManifestPath;
1820 if (
auto ManifestOrErr =
1822 ModulesManifest = std::move(*ManifestOrErr);
1824 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1825 return !ModuleEntry.IsStdlib;
1830 llvm::handleAllErrors(
1831 ManifestOrErr.takeError(),
1832 [&](llvm::json::ParseError &Err) {
1833 Diags.Report(diag::err_modules_manifest_failed_parse)
1836 [&](llvm::FileError &Err) {
1837 Diags.Report(diag::err_cannot_open_file)
1838 << Err.getFileName() << Err.messageWithoutFileInfo();
1846 if (TC.
getTriple().isOSBinFormatMachO())
1851 if (CCCPrintPhases) {
1858 if (UseModulesDriver)
1865 llvm::opt::ArgStringList ASL;
1866 for (
const auto *A : Args) {
1870 while (A->getAlias())
1872 A->render(Args, ASL);
1875 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1876 if (I != ASL.begin())
1878 llvm::sys::printArg(OS, *I,
true);
1883bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1884 SmallString<128> &CrashDiagDir) {
1885 using namespace llvm::sys;
1886 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1887 "Only knows about .crash files on Darwin");
1889 auto BypassSandbox = sandbox::scopedDisable();
1894 path::home_directory(CrashDiagDir);
1895 if (CrashDiagDir.starts_with(
"/var/root"))
1897 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1905 fs::file_status FileStatus;
1906 TimePoint<> LastAccessTime;
1907 SmallString<128> CrashFilePath;
1910 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1911 File != FileEnd && !EC;
File.increment(EC)) {
1915 if (fs::status(
File->path(), FileStatus))
1917 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1918 llvm::MemoryBuffer::getFile(
File->path());
1923 StringRef
Data = CrashFile.get()->getBuffer();
1924 if (!
Data.starts_with(
"Process:"))
1927 size_t ParentProcPos =
Data.find(
"Parent Process:");
1928 if (ParentProcPos == StringRef::npos)
1930 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1931 if (LineEnd == StringRef::npos)
1933 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1934 int OpenBracket = -1, CloseBracket = -1;
1935 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1936 if (ParentProcess[i] ==
'[')
1938 if (ParentProcess[i] ==
']')
1944 if (OpenBracket < 0 || CloseBracket < 0 ||
1945 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1946 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1956 const auto FileAccessTime = FileStatus.getLastModificationTime();
1957 if (FileAccessTime > LastAccessTime) {
1958 CrashFilePath.assign(
File->path());
1959 LastAccessTime = FileAccessTime;
1964 if (!CrashFilePath.empty()) {
1965 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1975 "\n********************\n\n"
1976 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
1984 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1987 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
1990 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1991 Level = llvm::StringSwitch<unsigned>(A->getValue())
1993 .Case(
"compiler", 1)
2005 ArgStringList SavedTemps;
2007 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2008 if (!IsLLD || Level < 2)
2015 SavedTemps = std::move(
C.getTempFiles());
2016 assert(!
C.getTempFiles().size());
2033 C.initCompilationForDiagnostics();
2038 Command NewLLDInvocation = Cmd;
2039 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2040 StringRef ReproduceOption =
2041 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2044 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2048 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2050 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2051 Diag(clang::diag::note_drv_command_failed_diag_msg)
2052 <<
"\n\n********************";
2054 Report->TemporaryFiles.push_back(TmpName);
2062 ArgStringList IRInputs;
2063 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2064 bool IgnoreInput =
false;
2070 IRInputs.push_back(it->second->getValue());
2074 }
else if (!strcmp(it->second->getValue(),
"-")) {
2075 Diag(clang::diag::note_drv_command_failed_diag_msg)
2076 <<
"Error generating preprocessed source(s) - "
2077 "ignoring input from stdin.";
2082 it = Inputs.erase(it);
2089 if (Inputs.empty() && IRInputs.empty()) {
2090 Diag(clang::diag::note_drv_command_failed_diag_msg)
2091 <<
"Error generating preprocessed source(s) - "
2092 "no preprocessable inputs.";
2099 for (
const Arg *A :
C.getArgs()) {
2100 if (A->getOption().matches(options::OPT_arch)) {
2101 StringRef ArchName = A->getValue();
2108 if (FailingArch.empty()) {
2109 Diag(clang::diag::note_drv_command_failed_diag_msg)
2110 <<
"Error generating preprocessed source(s) - cannot generate "
2111 "preprocessed source with multiple -arch options.";
2114 C.getArgs().eraseArg(options::OPT_arch);
2115 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2120 if (!Inputs.empty()) {
2123 const ToolChain &TC =
C.getDefaultToolChain();
2124 if (TC.
getTriple().isOSBinFormatMachO())
2133 Diag(clang::diag::note_drv_command_failed_diag_msg)
2134 <<
"Error generating preprocessed source(s).";
2139 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2142 if (!FailingCommands.empty()) {
2143 Diag(clang::diag::note_drv_command_failed_diag_msg)
2144 <<
"Error generating preprocessed source(s).";
2148 const ArgStringList &TempFiles =
C.getTempFiles();
2149 if (TempFiles.empty()) {
2150 Diag(clang::diag::note_drv_command_failed_diag_msg)
2151 <<
"Error generating preprocessed source(s).";
2157 const ArgStringList &Files =
C.getTempFiles();
2162 for (
auto const *Input : IRInputs) {
2166 StringRef extension = llvm::sys::path::extension(Input);
2167 if (!extension.empty())
2168 extension = extension.drop_front();
2170 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2171 llvm::sys::path::stem(Input), extension, FD, Path);
2173 Diag(clang::diag::note_drv_command_failed_diag_msg)
2174 <<
"Error generating run script: " <<
"Failed copying IR input files"
2175 <<
" " << EC.message();
2179 EC = llvm::sys::fs::copy_file(Input, FD);
2181 Diag(clang::diag::note_drv_command_failed_diag_msg)
2182 <<
"Error generating run script: " <<
"Failed copying IR input files"
2183 <<
" " << EC.message();
2187 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2194 for (std::string &TempFile : TempFiles) {
2196 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2198 Report->TemporaryFiles.push_back(TempFile);
2199 if (ReproCrashFilename.empty()) {
2200 ReproCrashFilename = TempFile;
2201 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2203 if (StringRef(TempFile).ends_with(
".cache")) {
2206 VFS = llvm::sys::path::filename(TempFile);
2207 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2211 for (
const char *TempFile : SavedTemps)
2212 TempFiles.push_back(TempFile);
2218 llvm::sys::path::replace_extension(Script,
"sh");
2220 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2221 llvm::sys::fs::FA_Write,
2222 llvm::sys::fs::OF_Text);
2224 Diag(clang::diag::note_drv_command_failed_diag_msg)
2225 <<
"Error generating run script: " << Script <<
" " << EC.message();
2228 <<
"# Driver args: ";
2230 ScriptOS <<
"# Original command: ";
2231 Cmd.
Print(ScriptOS,
"\n",
true);
2232 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2233 if (!AdditionalInformation.empty())
2234 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2237 Report->TemporaryFiles.push_back(std::string(Script));
2238 TempFiles.push_back(std::string(Script));
2241 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2244 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2245 StringRef CrashDiagnosticsTar = A->getValue();
2247 llvm::TarWriter::create(CrashDiagnosticsTar,
2248 llvm::sys::path::stem(CrashDiagnosticsTar));
2250 Diag(clang::diag::note_drv_command_failed_diag_msg)
2251 << (std::string(
"Error creating reproducer tarball: ") +
2252 llvm::toString(TarOrErr.takeError()));
2254 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2255 for (
const std::string &TempFile : TempFiles) {
2256 if (llvm::sys::fs::is_directory(TempFile)) {
2258 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2259 I != E && !EC; I.increment(EC)) {
2260 if (llvm::sys::fs::is_regular_file(I->path())) {
2261 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2265 llvm::sys::path::filename(TempFile);
2266 StringRef SubPath = I->path();
2267 if (SubPath.consume_front(TempFile)) {
2268 if (!SubPath.empty() &&
2269 llvm::sys::path::is_separator(SubPath.front())) {
2270 SubPath = SubPath.drop_front();
2272 llvm::sys::path::append(PathInTar, SubPath);
2273 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2276 Diag(clang::diag::note_drv_command_failed_diag_msg)
2277 << (std::string(
"Error reading file for tarball: ") +
2283 Diag(clang::diag::note_drv_command_failed_diag_msg)
2284 << (std::string(
"Error iterating directory for tarball: ") +
2285 TempFile +
" " + EC.message());
2288 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2290 Tar->append(llvm::sys::path::filename(TempFile),
2291 (*BufferOrErr)->getBuffer());
2293 Diag(clang::diag::note_drv_command_failed_diag_msg)
2294 << (std::string(
"Error reading file for tarball: ") + TempFile);
2298 Diag(clang::diag::note_drv_command_failed_diag_msg)
2299 << CrashDiagnosticsTar;
2304 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2306 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2307 Diag(clang::diag::note_drv_command_failed_diag_msg)
2308 << ReproCrashFilename.str();
2310 llvm::sys::path::append(CrashDiagDir,
Name);
2311 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2312 Diag(clang::diag::note_drv_command_failed_diag_msg)
2313 <<
"Crash backtrace is located in";
2314 Diag(clang::diag::note_drv_command_failed_diag_msg)
2315 << CrashDiagDir.str();
2316 Diag(clang::diag::note_drv_command_failed_diag_msg)
2317 <<
"(choose the .crash file that corresponds to your crash)";
2321 Diag(clang::diag::note_drv_command_failed_diag_msg)
2322 <<
"\n\n********************";
2332 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2343 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2344 if (
C.getArgs().hasArg(options::OPT_v))
2345 C.getJobs().Print(llvm::errs(),
"\n",
true);
2347 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2350 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2357 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2358 C.getJobs().Print(llvm::errs(),
"\n",
true);
2359 return Diags.hasErrorOccurred() ? 1 : 0;
2363 if (Diags.hasErrorOccurred())
2367 for (
auto &Job :
C.getJobs())
2368 setUpResponseFiles(
C, Job);
2370 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2373 if (FailingCommands.empty())
2379 for (
const auto &CmdPair : FailingCommands) {
2380 int CommandRes = CmdPair.first;
2381 const Command *FailingCommand = CmdPair.second;
2386 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2390 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2395 if (CommandRes == EX_IOERR) {
2415 if (CommandRes > 128 && CommandRes != 255)
2419 Diag(clang::diag::err_drv_command_signalled)
2422 Diag(clang::diag::err_drv_command_failed)
2430 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2432 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2446 const ToolChain &TC =
C.getDefaultToolChain();
2450 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2453 OS <<
"Thread model: " << A->getValue();
2459 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2464 if (!llvm::cl::getCompilerBuildConfig().empty())
2465 llvm::cl::printBuildConfig(OS);
2468 for (
auto ConfigFile : ConfigFiles)
2469 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2482 if (PassedFlags ==
"")
2486 std::vector<std::string> SuggestedCompletions;
2487 std::vector<std::string> Flags;
2499 const bool HasSpace = PassedFlags.ends_with(
",");
2503 StringRef TargetFlags = PassedFlags;
2504 while (TargetFlags !=
"") {
2506 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2507 Flags.push_back(std::string(CurFlag));
2512 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2515 const llvm::opt::OptTable &Opts =
getOpts();
2517 Cur = Flags.at(Flags.size() - 1);
2519 if (Flags.size() >= 2) {
2520 Prev = Flags.at(Flags.size() - 2);
2521 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2524 if (SuggestedCompletions.empty())
2525 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2532 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2533 llvm::outs() <<
'\n';
2539 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2543 SuggestedCompletions = Opts.findByPrefix(
2544 Cur, VisibilityMask,
2551 if (S.starts_with(Cur))
2552 SuggestedCompletions.push_back(std::string(S));
2559 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2560 if (
int X = A.compare_insensitive(B))
2562 return A.compare(B) > 0;
2565 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2572 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2573 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2577 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2580 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2584 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2589 if (
C.getArgs().hasArg(options::OPT_help) ||
2590 C.getArgs().hasArg(options::OPT__help_hidden)) {
2591 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2595 if (
C.getArgs().hasArg(options::OPT__version)) {
2602 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2603 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2604 if (ListExtractors || ListFormats) {
2612 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2617 if (
C.getArgs().hasArg(options::OPT_v) ||
2618 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2619 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2620 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2621 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2623 SuppressMissingInputWarning =
true;
2626 if (
C.getArgs().hasArg(options::OPT_v)) {
2628 llvm::errs() <<
"System configuration file directory: "
2631 llvm::errs() <<
"User configuration file directory: "
2635 const ToolChain &TC =
C.getDefaultToolChain();
2637 if (
C.getArgs().hasArg(options::OPT_v))
2640 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2645 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2646 llvm::outs() <<
"programs: =";
2647 bool separator =
false;
2651 llvm::outs() << llvm::sys::EnvPathSeparator;
2652 llvm::outs() << Path;
2657 llvm::outs() << llvm::sys::EnvPathSeparator;
2658 llvm::outs() << Path;
2661 llvm::outs() <<
"\n";
2664 StringRef sysroot =
C.getSysRoot();
2668 llvm::outs() << llvm::sys::EnvPathSeparator;
2671 llvm::outs() << sysroot << Path.substr(1);
2673 llvm::outs() << Path;
2675 llvm::outs() <<
"\n";
2679 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2685 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2686 for (
auto RuntimePath :
2688 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2689 llvm::outs() << *RuntimePath <<
'\n';
2693 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2697 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2699 for (std::size_t I = 0; I != Flags.size(); I += 2)
2700 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2706 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2707 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2711 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2712 StringRef ProgName = A->getValue();
2715 if (! ProgName.empty())
2718 llvm::outs() <<
"\n";
2722 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2723 StringRef PassedFlags = A->getValue();
2728 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2738 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2743 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2746 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2752 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2759 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2762 std::set<llvm::StringRef> SortedFlags;
2763 for (
const auto &FlagEntry : ExpandedFlags)
2764 SortedFlags.insert(FlagEntry.getKey());
2765 for (
auto Flag : SortedFlags)
2766 llvm::outs() << Flag <<
'\n';
2770 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2773 llvm::outs() <<
".\n";
2776 assert(Suffix.front() ==
'/');
2777 llvm::outs() << Suffix.substr(1) <<
"\n";
2783 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2788 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2790 llvm::outs() << Triple.getTriple() <<
"\n";
2794 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2795 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2812 std::map<Action *, unsigned> &Ids,
2814 if (
auto It = Ids.find(A); It != Ids.end())
2818 llvm::raw_string_ostream os(str);
2820 auto getSibIndent = [](
int K) -> Twine {
2824 Twine SibIndent =
Indent + getSibIndent(Kind);
2828 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2830 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2831 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2832 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2834 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2835 assert(TC &&
"Unknown host toolchain");
2850 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2858 const char *Prefix =
"{";
2859 for (
Action *PreRequisite : *AL) {
2860 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2871 std::string offload_str;
2872 llvm::raw_string_ostream offload_os(offload_str);
2876 offload_os <<
", (" << S;
2883 auto getSelfIndent = [](
int K) -> Twine {
2887 unsigned Id = Ids.size();
2889 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2898 std::map<Action *, unsigned> Ids;
2899 for (
Action *A :
C.getActions())
2915 DerivedArgList &Args =
C.getArgs();
2917 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2922 for (Arg *A : Args) {
2923 if (A->getOption().matches(options::OPT_arch)) {
2926 llvm::Triple::ArchType
Arch =
2928 if (
Arch == llvm::Triple::UnknownArch) {
2929 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2934 if (
ArchNames.insert(A->getValue()).second)
2935 Archs.push_back(A->getValue());
2949 for (
Action* Act : SingleActions) {
2957 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2961 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2966 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2967 Actions.append(Inputs.begin(), Inputs.end());
2969 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2972 Arg *A = Args.getLastArg(options::OPT_g_Group);
2973 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2974 !A->getOption().matches(options::OPT_gstabs);
2975 bool enablesPseudoProbe =
2976 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2977 options::OPT_fno_pseudo_probe_for_profiling,
false);
2978 bool enablesDebugInfoForProfiling =
2979 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2980 options::OPT_fno_debug_info_for_profiling,
false);
2981 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2982 enablesDebugInfoForProfiling) &&
2990 if (Act->getType() == types::TY_Image) {
2992 Inputs.push_back(Actions.back());
2999 if (Args.hasArg(options::OPT_verify_debug_info)) {
3000 Action *LastAction = Actions.pop_back_val();
3002 LastAction, types::TY_Nothing));
3009 bool TypoCorrect)
const {
3021 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3022 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3034 std::string Nearest;
3035 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3036 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3037 <<
Value << Nearest;
3076 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3079 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3087 return types::TY_CXXUHeader;
3089 return types::TY_CXXSHeader;
3093 llvm_unreachable(
"should not be called in this case");
3095 return types::TY_CXXHUHeader;
3101 const llvm::opt::OptTable &Opts =
getOpts();
3105 types::ID InputType = types::TY_Nothing;
3106 Arg *InputTypeArg =
nullptr;
3109 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3110 options::OPT__SLASH_TP)) {
3111 InputTypeArg = TCTP;
3112 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3117 bool ShowNote =
false;
3119 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3121 Diag(clang::diag::warn_drv_overriding_option)
3122 <<
Previous->getSpelling() << A->getSpelling();
3128 Diag(clang::diag::note_drv_t_option_is_global);
3133 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3134 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3135 if (LastXArg && LastInputArg &&
3136 LastInputArg->getIndex() < LastXArg->getIndex())
3137 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3140 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3142 for (Arg *A : Args) {
3143 if (A->getOption().
getKind() == Option::InputClass) {
3144 const char *
Value = A->getValue();
3148 if (InputType == types::TY_Nothing) {
3151 InputTypeArg->claim();
3154 if (strcmp(
Value,
"-") == 0) {
3156 Ty = types::TY_Fortran;
3158 Ty = types::TY_HLSL;
3159 }
else if (IsSYCL) {
3169 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3170 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3171 : clang::diag::err_drv_unknown_stdin_type);
3180 if (
const char *Ext = strrchr(
Value,
'.'))
3189 Ty = types::TY_HLSL;
3191 Ty = types::TY_Object;
3202 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3203 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3204 << getTypeName(OldTy) << getTypeName(Ty);
3209 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3210 Ty == types::TY_Object)
3211 Ty = types::TY_LLVM_BC;
3219 if (Ty != types::TY_Object) {
3220 if (Args.hasArg(options::OPT_ObjC))
3221 Ty = types::TY_ObjC;
3222 else if (Args.hasArg(options::OPT_ObjCXX))
3223 Ty = types::TY_ObjCXX;
3230 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3234 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3235 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3238 const char *Ext = strrchr(
Value,
'.');
3240 Ty = types::TY_Object;
3244 InputTypeArg->claim();
3248 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3249 Args.hasArgNoClaim(options::OPT_hipstdpar))
3253 Inputs.push_back(std::make_pair(Ty, A));
3255 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3256 StringRef
Value = A->getValue();
3259 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3260 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3263 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3264 StringRef
Value = A->getValue();
3267 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3268 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3274 Inputs.push_back(std::make_pair(types::TY_Object, A));
3276 }
else if (A->getOption().matches(options::OPT_x)) {
3285 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3286 InputType = types::TY_Object;
3293 }
else if (A->getOption().getID() == options::OPT_U) {
3294 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3295 StringRef Val = A->getValue(0);
3296 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3298 Diag(diag::warn_slash_u_filename) << Val;
3299 Diag(diag::note_use_dashdash);
3303 if (
CCCIsCPP() && Inputs.empty()) {
3307 Inputs.push_back(std::make_pair(types::TY_C, A));
3314class OffloadingActionBuilder final {
3316 bool IsValid =
false;
3322 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3325 std::map<Action *, const Arg *> HostActionToInputArgMap;
3328 class DeviceActionBuilder {
3332 enum ActionBuilderReturnCode {
3350 const ToolChain *FatBinaryToolChain =
nullptr;
3353 DerivedArgList &Args;
3362 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3365 :
C(
C), Args(Args), Inputs(Inputs),
3366 AssociatedOffloadKind(AssociatedOffloadKind) {}
3367 virtual ~DeviceActionBuilder() {}
3372 virtual ActionBuilderReturnCode
3373 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3376 return ABRT_Inactive;
3381 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3382 return ABRT_Inactive;
3386 virtual void appendTopLevelActions(
ActionList &AL) {}
3389 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3392 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3395 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3402 virtual bool canUseBundlerUnbundler()
const {
return false; }
3406 bool isValid() {
return !ToolChains.empty(); }
3410 return AssociatedOffloadKind;
3416 class CudaActionBuilderBase :
public DeviceActionBuilder {
3420 bool CompileHostOnly =
false;
3421 bool CompileDeviceOnly =
false;
3423 bool EmitAsm =
false;
3426 SmallVector<BoundArch, 4> GpuArchList;
3432 Action *CudaFatBinary =
nullptr;
3435 bool IsActive =
false;
3438 bool Relocatable =
false;
3441 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3444 const CUIDOptions &CUIDOpts;
3447 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3449 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3450 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3452 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3453 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3454 options::OPT_fno_gpu_rdc,
false);
3457 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3464 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3467 if (!(IA->getType() == types::TY_CUDA ||
3468 IA->getType() == types::TY_HIP ||
3469 IA->getType() == types::TY_PP_HIP)) {
3472 return ABRT_Inactive;
3479 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3481 if (CompileHostOnly)
3482 return ABRT_Success;
3485 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3486 : types::TY_CUDA_DEVICE;
3487 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3488 CudaDeviceActions.push_back(
3489 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3492 return ABRT_Success;
3496 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3500 if (UA->getType() == types::TY_Object && !Relocatable)
3501 return ABRT_Inactive;
3503 CudaDeviceActions.clear();
3505 std::string
FileName = IA->getInputArg().getAsString(Args);
3511 const StringRef LibFileExt =
".lib";
3512 if (IA->getType() == types::TY_Object &&
3513 (!llvm::sys::path::has_extension(
FileName) ||
3515 llvm::sys::path::extension(
FileName).drop_front()) !=
3517 llvm::sys::path::extension(
FileName) == LibFileExt))
3518 return ABRT_Inactive;
3520 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3521 CudaDeviceActions.push_back(UA);
3522 UA->registerDependentActionInfo(ToolChain,
Arch,
3523 AssociatedOffloadKind);
3526 return ABRT_Success;
3529 return IsActive ? ABRT_Success : ABRT_Inactive;
3532 void appendTopLevelActions(
ActionList &AL)
override {
3534 auto AddTopLevel = [&](Action *A, BoundArch BA,
const ToolChain *TC) {
3535 OffloadAction::DeviceDependences Dep;
3536 Dep.
add(*A, *TC, BA, AssociatedOffloadKind);
3537 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3541 if (CudaFatBinary) {
3542 AddTopLevel(CudaFatBinary, {}, FatBinaryToolChain);
3543 CudaDeviceActions.clear();
3544 CudaFatBinary =
nullptr;
3548 if (CudaDeviceActions.empty())
3554 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3555 "Expecting one action per GPU architecture.");
3556 assert(ToolChains.size() == GpuArchList.size() &&
3557 "Expecting to have a toolchain per GPU architecture");
3558 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3559 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3561 CudaDeviceActions.clear();
3564 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3582 assert(HostTC &&
"No toolchain for host compilation.");
3587 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3592 std::set<std::pair<BoundArch, const ToolChain *>> GpuArchs;
3594 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3596 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3597 GpuArchs.insert({
Arch, I.second});
3601 for (
auto [
Arch, TC] : GpuArchs) {
3602 GpuArchList.push_back(
Arch);
3603 ToolChains.push_back(TC);
3606 FatBinaryToolChain = ToolChains.front();
3607 CompileHostOnly =
C.getDriver().offloadHostOnly();
3608 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3609 EmitAsm = Args.getLastArg(options::OPT_S);
3617 class CudaActionBuilder final :
public CudaActionBuilderBase {
3619 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3621 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3622 DefaultOffloadArch = OffloadArch::CudaDefault;
3625 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3627 const std::set<StringRef> &GpuArchs)
override {
3628 return std::nullopt;
3631 ActionBuilderReturnCode
3632 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3634 PhasesTy &Phases)
override {
3636 return ABRT_Inactive;
3640 if (CudaDeviceActions.empty())
3641 return ABRT_Success;
3643 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3644 "Expecting one action per GPU architecture.");
3645 assert(!CompileHostOnly &&
3646 "Not expecting CUDA actions in host-only compilation.");
3656 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3659 for (
auto Ph : Phases) {
3664 if (Ph > FinalPhase)
3667 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3682 Action *AssembleAction = CudaDeviceActions[I];
3683 assert(AssembleAction->
getType() == types::TY_Object);
3684 assert(AssembleAction->
getInputs().size() == 1);
3690 OffloadAction::DeviceDependences DDep;
3692 DeviceActions.push_back(
3693 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3698 if (!DeviceActions.empty()) {
3700 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3702 if (!CompileDeviceOnly) {
3703 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3707 CudaFatBinary =
nullptr;
3712 CudaDeviceActions.clear();
3716 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3721 return ABRT_Success;
3725 "instructions should only occur "
3726 "before the backend phase!");
3729 for (Action *&A : CudaDeviceActions)
3730 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3732 return ABRT_Success;
3737 class HIPActionBuilder final :
public CudaActionBuilderBase {
3739 SmallVector<ActionList, 8> DeviceLinkerInputs;
3745 std::optional<bool> BundleOutput;
3746 std::optional<bool> EmitReloc;
3749 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3751 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3753 DefaultOffloadArch = OffloadArch::HIPDefault;
3755 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3756 options::OPT_fno_hip_emit_relocatable)) {
3757 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3758 options::OPT_fno_hip_emit_relocatable, false);
3762 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3763 <<
"-fhip-emit-relocatable"
3767 if (!CompileDeviceOnly) {
3768 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3769 <<
"-fhip-emit-relocatable"
3770 <<
"--offload-device-only";
3775 if (Args.hasArg(options::OPT_gpu_bundle_output,
3776 options::OPT_no_gpu_bundle_output))
3777 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3778 options::OPT_no_gpu_bundle_output,
true) &&
3779 (!EmitReloc || !*EmitReloc);
3782 bool canUseBundlerUnbundler()
const override {
return true; }
3784 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3786 const std::set<StringRef> &GpuArchs)
override {
3790 ActionBuilderReturnCode
3791 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3793 PhasesTy &Phases)
override {
3795 return ABRT_Inactive;
3801 if (CudaDeviceActions.empty())
3802 return ABRT_Success;
3805 CudaDeviceActions.size() == GpuArchList.size()) &&
3806 "Expecting one action per GPU architecture.");
3807 assert(!CompileHostOnly &&
3808 "Not expecting HIP actions in host-only compilation.");
3810 bool ShouldLink = !EmitReloc || !*EmitReloc;
3813 !EmitAsm && ShouldLink) {
3819 bool ExplicitOffloadLTO = Args.hasArg(options::OPT_foffload_lto,
3820 options::OPT_foffload_lto_EQ);
3821 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3822 if (ExplicitOffloadLTO &&
3823 ToolChains[I]->isUsingLTO(Args, AssociatedOffloadKind)) {
3827 AL.push_back(CudaDeviceActions[I]);
3830 CudaDeviceActions[I] =
3831 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3837 if (ToolChains[I]->
getTriple().isSPIRV() ||
3838 (ToolChains[I]->
getTriple().isAMDGCN() &&
3839 GpuArchList[I].ArchName == StringRef(
"amdgcnspirv"))) {
3843 types::ID Output = Args.hasArg(options::OPT_S)
3845 : types::TY_LLVM_BC;
3847 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3853 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3855 AssociatedOffloadKind);
3856 AL.push_back(AssembleAction);
3859 CudaDeviceActions[I] =
3860 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3869 OffloadAction::DeviceDependences DDep;
3870 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3871 AssociatedOffloadKind);
3872 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3873 DDep, CudaDeviceActions[I]->getType());
3876 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3878 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3879 types::TY_HIP_FATBIN);
3881 if (!CompileDeviceOnly) {
3882 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3883 AssociatedOffloadKind);
3886 CudaFatBinary =
nullptr;
3891 CudaDeviceActions.clear();
3894 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3897 return ABRT_Success;
3903 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3904 auto LI = DeviceLinkerInputs.begin();
3905 for (
auto *A : CudaDeviceActions) {
3912 CudaDeviceActions.clear();
3913 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3917 for (
unsigned I = 0, E = CudaDeviceActions.size(); I != E; ++I)
3918 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3919 C, Args, CurPhase, CudaDeviceActions[I], AssociatedOffloadKind,
3920 ToolChains[I]->getLTOMode(Args, AssociatedOffloadKind));
3922 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3924 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3925 OffloadAction::DeviceDependences DDep;
3926 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3927 AssociatedOffloadKind);
3928 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3929 DDep, CudaDeviceActions[I]->getType());
3932 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3933 CudaDeviceActions.clear();
3936 return (CompileDeviceOnly &&
3937 (CurPhase == FinalPhase ||
3943 void appendLinkDeviceActions(
ActionList &AL)
override {
3944 if (DeviceLinkerInputs.size() == 0)
3947 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3948 "Linker inputs and GPU arch list sizes do not match.");
3954 for (
auto &LI : DeviceLinkerInputs) {
3956 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3960 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3963 OffloadAction::DeviceDependences DeviceLinkDeps;
3964 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3965 AssociatedOffloadKind);
3966 Actions.push_back(
C.MakeAction<OffloadAction>(
3967 DeviceLinkDeps, DeviceLinkAction->getType()));
3970 DeviceLinkerInputs.clear();
3973 if (Args.hasArg(options::OPT_emit_llvm)) {
3981 OffloadAction::DeviceDependences DDeps;
3982 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3983 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3985 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3986 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain, {},
3987 AssociatedOffloadKind);
3990 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3996 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3998 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
4006 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
4012 bool ShouldUseBundler;
4015 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
4023 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
4026 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4034 unsigned ValidBuilders = 0u;
4035 unsigned ValidBuildersSupportingBundling = 0u;
4036 for (
auto *SB : SpecializedBuilders) {
4037 IsValid = IsValid && !SB->initialize();
4040 if (SB->isValid()) {
4042 if (SB->canUseBundlerUnbundler())
4043 ++ValidBuildersSupportingBundling;
4047 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4049 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4050 options::OPT_no_gpu_bundle_output,
true);
4053 ~OffloadingActionBuilder() {
4054 for (
auto *SB : SpecializedBuilders)
4059 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4060 assert(HostAction &&
"Invalid host action");
4061 assert(InputArg &&
"Invalid input argument");
4062 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4063 assert(Loc->second == InputArg &&
4064 "host action mapped to multiple input arguments");
4073 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4075 DeviceActionBuilder::PhasesTy &Phases) {
4079 if (SpecializedBuilders.empty())
4082 assert(HostAction &&
"Invalid host action!");
4083 recordHostAction(HostAction, InputArg);
4088 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4089 unsigned InactiveBuilders = 0u;
4090 unsigned IgnoringBuilders = 0u;
4091 for (
auto *SB : SpecializedBuilders) {
4092 if (!SB->isValid()) {
4097 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4102 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4107 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4108 OffloadKind |= SB->getAssociatedOffloadKind();
4113 if (IgnoringBuilders &&
4114 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4131 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4132 const Arg *InputArg) {
4136 recordHostAction(HostAction, InputArg);
4145 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4147 HostAction->
getType() == types::TY_PP_HIP)) {
4148 auto UnbundlingHostAction =
4153 HostAction = UnbundlingHostAction;
4154 recordHostAction(HostAction, InputArg);
4157 assert(HostAction &&
"Invalid host action!");
4160 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4161 for (
auto *SB : SpecializedBuilders) {
4165 auto RetCode = SB->addDeviceDependences(HostAction);
4169 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4170 "Host dependence not expected to be ignored.!");
4174 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4175 OffloadKind |= SB->getAssociatedOffloadKind();
4180 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4190 const Arg *InputArg) {
4192 recordHostAction(HostAction, InputArg);
4196 for (
auto *SB : SpecializedBuilders) {
4199 SB->appendTopLevelActions(OffloadAL);
4206 if (CanUseBundler && ShouldUseBundler && HostAction &&
4207 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4209 OffloadAL.push_back(HostAction);
4213 assert(HostAction == AL.back() &&
"Host action not in the list??");
4215 recordHostAction(HostAction, InputArg);
4216 AL.back() = HostAction;
4218 AL.append(OffloadAL.begin(), OffloadAL.end());
4228 void appendDeviceLinkActions(
ActionList &AL) {
4229 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4232 SB->appendLinkDeviceActions(AL);
4236 Action *makeHostLinkAction() {
4239 appendDeviceLinkActions(DeviceAL);
4240 if (DeviceAL.empty())
4245 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4248 HA = SB->appendLinkHostActions(DeviceAL);
4265 for (
auto *SB : SpecializedBuilders) {
4269 SB->appendLinkDependences(DDeps);
4273 unsigned ActiveOffloadKinds = 0u;
4274 for (
auto &I : InputArgToOffloadKindMap)
4275 ActiveOffloadKinds |= I.second;
4287 for (
auto *A : HostAction->
inputs()) {
4288 auto ArgLoc = HostActionToInputArgMap.find(A);
4289 if (ArgLoc == HostActionToInputArgMap.end())
4291 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4292 if (OFKLoc == InputArgToOffloadKindMap.end())
4304 {}, ActiveOffloadKinds);
4310void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4315 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4316 StringRef
V = A->getValue();
4317 if (Inputs.size() > 1 && !
V.empty() &&
4318 !llvm::sys::path::is_separator(
V.back())) {
4320 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4321 << A->getSpelling() <<
V;
4322 Args.eraseArg(options::OPT__SLASH_Fo);
4327 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4328 StringRef
V = A->getValue();
4329 if (Inputs.size() > 1 && !
V.empty() &&
4330 !llvm::sys::path::is_separator(
V.back())) {
4332 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4333 << A->getSpelling() <<
V;
4334 Args.eraseArg(options::OPT__SLASH_Fa);
4339 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4340 if (A->getValue()[0] ==
'\0') {
4342 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4343 Args.eraseArg(options::OPT__SLASH_o);
4348 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4349 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4350 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4351 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4352 Args.eraseArg(options::OPT__SLASH_Yc);
4353 Args.eraseArg(options::OPT__SLASH_Yu);
4354 YcArg = YuArg =
nullptr;
4356 if (YcArg && Inputs.size() > 1) {
4357 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4358 Args.eraseArg(options::OPT__SLASH_Yc);
4366 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4367 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4368 Args.AddFlagArg(
nullptr,
4369 getOpts().getOption(options::OPT_frtlib_add_rpath));
4373 if (Args.hasArg(options::OPT_emit_llvm) &&
4374 !Args.hasArg(options::OPT_hip_link) &&
4375 !
C.getDefaultToolChain().getTriple().isSPIRV())
4376 Diag(clang::diag::err_drv_emit_llvm_link);
4377 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4378 C.getDefaultToolChain().isUsingLTO(Args) &&
4379 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4380 .starts_with_insensitive(
"lld"))
4381 Diag(clang::diag::err_drv_lto_without_lld);
4387 if (!Args.hasArg(options::OPT_dumpdir)) {
4388 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4389 Arg *Arg = Args.MakeSeparateArg(
4390 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4392 (FinalOutput ? FinalOutput->getValue()
4404 Args.eraseArg(options::OPT__SLASH_Fp);
4405 Args.eraseArg(options::OPT__SLASH_Yc);
4406 Args.eraseArg(options::OPT__SLASH_Yu);
4407 YcArg = YuArg =
nullptr;
4410 if (Args.hasArg(options::OPT_include_pch) &&
4411 Args.hasArg(options::OPT_ignore_pch)) {
4415 Args.eraseArg(options::OPT_include_pch);
4418 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4419 for (
auto &I : Inputs) {
4421 const Arg *InputArg = I.second;
4426 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4430 if (InitialPhase > FinalPhase) {
4431 if (InputArg->isClaimed())
4438 if (Args.hasArg(options::OPT_Qunused_arguments))
4444 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4445 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4449 (Args.getLastArg(options::OPT__SLASH_EP,
4450 options::OPT__SLASH_P) ||
4451 Args.getLastArg(options::OPT_E) ||
4452 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4454 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4455 << InputArg->getAsString(Args) << !!FinalPhaseArg
4456 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4458 Diag(clang::diag::warn_drv_input_file_unused)
4459 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4461 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4470 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4471 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
4476 Actions.push_back(ClangClPch);
4488 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4489 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4498 const llvm::opt::DerivedArgList &Args,
4501 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4503 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4506 bool HasAMDGCNHIPDevice =
false;
4508 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4510 const llvm::Triple &Tr = TC->
getTriple();
4513 HasAMDGCNHIPDevice =
true;
4515 return HasAMDGCNHIPDevice;
4520 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4522 if (!SuppressMissingInputWarning && Inputs.empty()) {
4523 Diag(clang::diag::err_drv_no_input_files);
4527 handleArguments(
C, Args, Inputs, Actions);
4529 bool UseNewOffloadingDriver = Args.hasFlag(
4530 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4534 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4535 !UseNewOffloadingDriver
4536 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4544 for (
auto &I : Inputs) {
4546 const Arg *InputArg = I.second;
4559 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4567 if (!UseNewOffloadingDriver)
4568 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4574 if (!UseNewOffloadingDriver)
4575 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4576 Current, InputArg, Phase, PL.back(), FullPL);
4582 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4585 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4586 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4588 LinkerInputs.push_back(Current);
4598 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4599 MergerInputs.push_back(Current);
4616 C.getDefaultToolChain().getLTOMode(Args));
4619 if (NewCurrent == Current)
4622 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4625 Current = NewCurrent;
4629 if (UseNewOffloadingDriver)
4631 &HIPAsmDeviceActions);
4634 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4638 if (Current->
getType() == types::TY_Nothing)
4644 if (Current && !HIPAsmDeviceActions.empty()) {
4645 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4647 BundleInputs.append(HIPAsmDeviceActions);
4648 BundleInputs.push_back(Current);
4654 Actions.push_back(Current);
4657 if (!UseNewOffloadingDriver)
4658 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4666 if (LinkerInputs.empty()) {
4669 if (!UseNewOffloadingDriver)
4670 OffloadBuilder->appendDeviceLinkActions(Actions);
4673 if (!LinkerInputs.empty()) {
4674 if (!UseNewOffloadingDriver)
4675 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4676 LinkerInputs.push_back(Wrapper);
4681 }
else if (UseNewOffloadingDriver ||
4682 Args.hasArg(options::OPT_offload_link)) {
4690 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4691 C.getDefaultToolChain().getTriple().isSPIRV();
4692 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4696 if (!UseNewOffloadingDriver)
4697 LA = OffloadBuilder->processHostLinkAction(LA);
4698 Actions.push_back(LA);
4702 if (!MergerInputs.empty())
4706 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4713 for (
auto &I : Inputs) {
4715 const Arg *InputArg = I.second;
4720 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4721 InputType == types::TY_Asm)
4726 for (
auto Phase : PhaseList) {
4730 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4735 if (InputType == types::TY_Object)
4742 assert(Phase == PhaseList.back() &&
4743 "merging must be final compilation step.");
4744 MergerInputs.push_back(Current);
4753 Actions.push_back(Current);
4757 if (!MergerInputs.empty())
4762 for (
auto Opt : {options::OPT_print_supported_cpus,
4763 options::OPT_print_supported_extensions,
4764 options::OPT_print_enabled_extensions}) {
4771 if (Arg *A = Args.getLastArg(Opt)) {
4772 if (Opt == options::OPT_print_supported_extensions &&
4773 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4774 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4775 !
C.getDefaultToolChain().getTriple().isARM()) {
4776 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4777 <<
"--print-supported-extensions";
4780 if (Opt == options::OPT_print_enabled_extensions &&
4781 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4782 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4783 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4784 <<
"--print-enabled-extensions";
4791 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4794 for (
auto &I : Inputs)
4799 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4800 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4801 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4807 if (TC.requiresObjcopy(Args)) {
4808 Action *LastAction = Actions.back();
4810 if (LastAction->
getType() == types::TY_Object)
4816 auto ValInfo = TC.getValidationInfo(Args);
4817 if (ValInfo.NeedsValidation) {
4818 Action *LastAction = Actions.back();
4819 if (LastAction->
getType() == types::TY_Object) {
4821 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4828 if (TC.requiresBinaryTranslation(Args)) {
4829 Action *LastAction = Actions.back();
4833 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4834 LastAction->
getType() == types::TY_Object)
4836 LastAction, types::TY_DX_CONTAINER));
4841 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4847 const llvm::opt::DerivedArgList &Args,
4849 const llvm::Triple &Triple) {
4854 if (Triple.isNVPTX() &&
4856 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4857 <<
"CUDA" << ArchStr;
4859 }
else if (Triple.isAMDGPU() &&
4861 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4862 <<
"HIP" << ArchStr;
4870 llvm::StringMap<bool> Features;
4873 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4885static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4887 llvm::Triple Triple) {
4888 if (!Triple.isAMDGPU())
4889 return std::nullopt;
4891 std::set<StringRef> ArchSet;
4892 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4896llvm::SmallVector<BoundArch>
4900 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4901 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4902 options::OPT_no_offload_arch_EQ)) {
4903 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4905 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4907 :
"--no-offload-arch");
4910 llvm::DenseSet<StringRef> Archs;
4911 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
4914 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4915 for (StringRef
Arch : Arg->getValues()) {
4916 if (
Arch ==
"native" ||
Arch.empty()) {
4921 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4925 for (
auto ArchStr : *GPUsOrErr) {
4927 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4928 if (!CanonicalStr.empty())
4929 Archs.insert(CanonicalStr);
4934 StringRef CanonicalStr =
4936 if (!CanonicalStr.empty())
4937 Archs.insert(CanonicalStr);
4942 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4943 for (StringRef
Arch : Arg->getValues()) {
4944 if (
Arch ==
"all") {
4949 Archs.erase(ArchStr);
4955 if (
auto ConflictingArchs =
4957 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4958 << ConflictingArchs->first << ConflictingArchs->second;
4961 if (Archs.empty()) {
4971 Archs.insert(StringRef());
4974 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
4975 .getLastArg(options::OPT_march_EQ)) {
4976 Archs.insert(Arg->getValue());
4981 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4982 <<
"--offload-arch";
4983 }
else if (!ArchsOrErr->empty()) {
4984 for (
auto Arch : *ArchsOrErr)
4985 Archs.insert(Args.MakeArgStringRef(
Arch));
4987 Archs.insert(StringRef());
4992 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4993 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
5000 Result.reserve(Sorted.size());
5001 for (StringRef
Arch : Sorted)
5008 const InputTy &Input, StringRef CUID,
5018 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5020 bool HIPRelocatableObj =
5022 Args.hasFlag(options::OPT_fhip_emit_relocatable,
5023 options::OPT_fno_hip_emit_relocatable,
false);
5025 if (!HIPNoRDC && HIPRelocatableObj)
5026 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
5027 <<
"-fhip-emit-relocatable"
5031 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
5032 <<
"-fhip-emit-relocatable"
5033 <<
"--offload-device-only";
5051 auto TCRange =
C.getOffloadToolChains(Kind);
5052 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5053 ToolChains.push_back(TI->second);
5055 if (ToolChains.empty())
5059 const Arg *InputArg = Input.second;
5068 for (
const ToolChain *TC : ToolChains) {
5070 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5071 DeviceActions.push_back(
5072 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5076 if (DeviceActions.empty())
5082 HostAction->
getType() != types::TY_Nothing &&
5092 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5101 auto *TCAndArch = TCAndArchs.begin();
5102 for (
Action *&A : DeviceActions) {
5103 if (A->
getType() == types::TY_Nothing)
5110 TCAndArch->first->getLTOMode(Args, Kind));
5114 HostAction->
getType() != types::TY_Nothing) {
5121 TCAndArch->second, Kind);
5123 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5133 for (
Action *&A : DeviceActions) {
5138 OffloadTriple && OffloadTriple->isSPIRV() &&
5139 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5140 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5142 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5143 A->
getType() != types::TY_LTO_BC) ||
5150 auto *TCAndArch = TCAndArchs.begin();
5151 for (
Action *A : DeviceActions) {
5152 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5154 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5159 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5161 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
5170 bool ShouldBundleHIP =
5171 Args.hasFlag(options::OPT_gpu_bundle_output,
5172 options::OPT_no_gpu_bundle_output,
false) ||
5173 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5175 return A->
getType() != types::TY_Image;
5182 if (OffloadActions.empty())
5187 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5191 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5198 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5199 DDep.
add(*FatbinAction,
5202 }
else if (HIPNoRDC) {
5205 if (HIPAsmBundleDeviceOut &&
5207 for (
Action *OA : OffloadActions)
5208 HIPAsmBundleDeviceOut->push_back(OA);
5222 DDep.
add(*PackagerAction,
5231 {},
C.getActiveOffloadKinds());
5240 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5241 return A->
getType() == types::TY_Nothing;
5245 {}, SingleDeviceOutput ? DDep : DDeps);
5246 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5252 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5262 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5268 llvm_unreachable(
"link action invalid here.");
5270 llvm_unreachable(
"ifsmerge action invalid here.");
5275 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5276 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5277 OutputTy = types::TY_Dependencies;
5282 if (!Args.hasFlag(options::OPT_frewrite_includes,
5283 options::OPT_fno_rewrite_includes,
false) &&
5284 !Args.hasFlag(options::OPT_frewrite_imports,
5285 options::OPT_fno_rewrite_imports,
false) &&
5286 !Args.hasFlag(options::OPT_fdirectives_only,
5287 options::OPT_fno_directives_only,
false) &&
5291 "Cannot preprocess this input type!");
5297 if (Args.hasArg(options::OPT_extract_api))
5302 if (Input->
getType() == types::TY_CXXStdModule ||
5303 Input->
getType() == types::TY_PP_CXXStdModule)
5305 Input, getPrecompiledType(Input->
getType()));
5313 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5314 (Input->
getType() == driver::types::TY_CXXModule ||
5315 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5316 !Args.getLastArg(options::OPT__precompile) &&
5317 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5322 "Cannot precompile this input type!");
5326 const char *ModName =
nullptr;
5327 if (OutputTy == types::TY_PCH) {
5328 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5329 ModName = A->getValue();
5331 OutputTy = types::TY_ModuleFile;
5334 if (Args.hasArg(options::OPT_fsyntax_only)) {
5336 OutputTy = types::TY_Nothing;
5342 if (Args.hasArg(options::OPT_fsyntax_only))
5344 if (Args.hasArg(options::OPT_rewrite_objc))
5346 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5348 types::TY_RewrittenLegacyObjC);
5349 if (Args.hasArg(options::OPT__analyze))
5351 if (Args.hasArg(options::OPT_emit_ast))
5353 if (Args.hasArg(options::OPT_emit_cir))
5355 if (Args.hasArg(options::OPT_module_file_info))
5357 if (Args.hasArg(options::OPT_verify_pch))
5359 if (Args.hasArg(options::OPT_extract_api))
5366 if (!IsDeviceOffload) {
5368 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5369 !Args.hasArg(options::OPT_emit_llvm))
5370 Output = types::TY_PP_Asm;
5371 else if (Args.hasArg(options::OPT_S))
5372 Output = types::TY_LTO_IR;
5374 Output = types::TY_LTO_BC;
5378 if (Args.hasArg(options::OPT_emit_llvm)) {
5380 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5382 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5386 Output = types::TY_PP_Asm;
5387 }
else if (Args.hasArg(options::OPT_S)) {
5388 Output = types::TY_LTO_IR;
5390 Output = types::TY_LTO_BC;
5394 if (Args.hasArg(options::OPT_emit_llvm) ||
5397 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5407 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5411 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5413 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5433 unsigned NumOutputs = 0;
5434 unsigned NumIfsOutputs = 0;
5435 for (
const Action *A :
C.getActions()) {
5445 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
5446 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
5449 if (A->
getType() != types::TY_Nothing &&
5451 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5453 0 == NumIfsOutputs++) ||
5458 A->
getType() == types::TY_Nothing &&
5459 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5460 NumOutputs += A->
size();
5463 if (NumOutputs > 1) {
5464 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5465 FinalOutput =
nullptr;
5469 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5473 if (RawTriple.isOSBinFormatMachO())
5474 for (
const Arg *A :
C.getArgs())
5475 if (A->getOption().matches(options::OPT_arch))
5479 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5480 for (
Action *A :
C.getActions()) {
5487 const char *LinkingOutput =
nullptr;
5490 LinkingOutput = FinalOutput->getValue();
5499 LinkingOutput, CachedResults,
5506 for (
auto &J :
C.getJobs())
5507 J.InProcess =
false;
5510 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5511 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5516 const char *LinkingOutput =
nullptr;
5518 LinkingOutput = FinalOutput->getValue();
5525 using namespace llvm;
5528 <<
"output=" << LinkingOutput;
5529 outs() <<
", total="
5530 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5532 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5533 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5537 llvm::raw_string_ostream Out(Buffer);
5538 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5541 llvm::sys::printArg(Out, LinkingOutput,
true);
5542 Out <<
',' << ProcStat->TotalTime.count() <<
','
5543 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5548 llvm::sys::fs::OF_Append |
5549 llvm::sys::fs::OF_Text);
5554 llvm::errs() <<
"ERROR: Cannot lock file "
5556 <<
toString(L.takeError()) <<
"\n";
5567 bool ReportUnusedArguments =
5568 !Diags.hasErrorOccurred() &&
5569 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5572 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5574 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5577 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5578 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5580 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5584 return strstr(J.getCreator().getShortName(),
"assembler");
5586 for (Arg *A :
C.getArgs()) {
5590 if (!A->isClaimed()) {
5596 const Option &Opt = A->getOption();
5597 if (Opt.getKind() == Option::FlagClass) {
5598 bool DuplicateClaimed =
false;
5600 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5601 if (AA->isClaimed()) {
5602 DuplicateClaimed =
true;
5607 if (DuplicateClaimed)
5613 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5615 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5620 !
C.getActions().empty()) {
5621 Diag(diag::err_drv_unsupported_opt_for_target)
5623 }
else if (ReportUnusedArguments) {
5624 Diag(clang::diag::warn_drv_unused_argument)
5625 << A->getAsString(
C.getArgs());
5635class ToolSelector final {
5646 bool IsHostSelector;
5657 bool CanBeCollapsed =
true) {
5659 if (Inputs.size() != 1)
5662 Action *CurAction = *Inputs.begin();
5663 if (CanBeCollapsed &&
5669 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5673 if (!IsHostSelector) {
5674 if (OA->hasSingleDeviceDependence(
true)) {
5676 OA->getSingleDeviceDependence(
true);
5677 if (CanBeCollapsed &&
5680 SavedOffloadAction.push_back(OA);
5681 return dyn_cast<JobAction>(CurAction);
5683 }
else if (OA->hasHostDependence()) {
5684 CurAction = OA->getHostDependence();
5685 if (CanBeCollapsed &&
5688 SavedOffloadAction.push_back(OA);
5689 return dyn_cast<JobAction>(CurAction);
5694 return dyn_cast<JobAction>(CurAction);
5698 bool canCollapseAssembleAction()
const {
5699 return TC.useIntegratedAs() && !SaveTemps &&
5700 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5701 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5702 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5703 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5707 bool canCollapsePreprocessorAction()
const {
5708 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5709 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5710 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5715 struct JobActionInfo final {
5717 const JobAction *JA =
nullptr;
5725 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5726 ArrayRef<JobActionInfo> &ActionInfo,
5727 unsigned ElementNum) {
5728 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5729 for (
unsigned I = 0; I < ElementNum; ++I)
5730 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5731 ActionInfo[I].SavedOffloadAction.end());
5744 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5747 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5749 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5750 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5751 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5752 if (!AJ || !BJ || !CJ)
5756 const Tool *T = TC.SelectTool(*CJ);
5769 const Tool *BT = TC.SelectTool(*BJ);
5777 Inputs = CJ->getInputs();
5778 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5782 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5785 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5787 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5788 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5793 const Tool *T = TC.SelectTool(*BJ);
5800 Inputs = BJ->getInputs();
5801 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5805 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5808 if (ActionInfo.size() < 2)
5810 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5811 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5815 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5816 for (
auto &Input : AI.JA->getInputs())
5827 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5828 if (SaveTemps && !InputIsBitcode)
5832 const Tool *T = TC.SelectTool(*CJ);
5845 Inputs = CJ->getInputs();
5846 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5855 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5863 for (Action *A : Inputs) {
5864 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5866 NewInputs.push_back(A);
5872 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5873 PreprocessJobOffloadActions.end());
5874 NewInputs.append(PJ->input_begin(), PJ->input_end());
5880 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5882 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5884 assert(BaseAction &&
"Invalid base action.");
5900 SmallVector<JobActionInfo, 5> ActionChain(1);
5901 ActionChain.back().JA = BaseAction;
5902 while (ActionChain.back().JA) {
5903 const Action *CurAction = ActionChain.back().JA;
5906 ActionChain.resize(ActionChain.size() + 1);
5907 JobActionInfo &AI = ActionChain.back();
5911 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5915 ActionChain.pop_back();
5923 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5924 CollapsedOffloadAction);
5926 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5928 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5934 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5947 std::string TriplePlusArch = TC->
getTriple().normalize();
5949 TriplePlusArch +=
"-";
5952 TriplePlusArch +=
"-";
5954 return TriplePlusArch;
5959 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5960 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5963 std::pair<const Action *, std::string> ActionTC = {
5965 auto CachedResult = CachedResults.find(ActionTC);
5966 if (CachedResult != CachedResults.end()) {
5967 return CachedResult->second;
5970 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
5971 TargetDeviceOffloadKind);
5972 CachedResults[ActionTC] =
Result;
5977 const JobAction *JA,
const char *BaseInput,
5980 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5991 if (!
Arch.empty()) {
5992 OffloadingPrefix +=
"-";
5993 OffloadingPrefix +=
Arch.ArchName;
5996 C.getDriver().isSaveTempsEnabled()) {
6003 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6004 Path = A->getValue();
6005 if (llvm::sys::fs::is_directory(Path)) {
6007 ? llvm::sys::path::stem(
Result.getFilename())
6008 : llvm::sys::path::stem(BaseInput));
6009 Tmp += OffloadingPrefix;
6011 llvm::sys::path::append(Path, Tmp);
6014 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6017 Path = DumpDir->getValue();
6018 Path += llvm::sys::path::stem(BaseInput);
6019 Path += OffloadingPrefix;
6021 }
else if (!OffloadingPrefix.empty()) {
6025 TraceName += OffloadingPrefix;
6026 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6027 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6028 llvm::sys::path::append(Path, TraceName);
6031 Path =
Result.getFilename();
6032 llvm::sys::path::replace_extension(Path,
"json");
6035 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6036 C.addTimeTraceFile(ResultFile, JA);
6037 C.addResultFile(ResultFile, JA);
6042 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6043 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6046 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6050 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
6051 C.setCurrentBoundArch(BA);
6052 auto RestoreBoundArch =
6053 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
6056 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6057 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6089 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6091 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6092 BoundArch DepBoundArch) {
6094 !DepBoundArch.
empty(),
6095 LinkingOutput, CachedResults,
6105 OA->doOnEachDependence(
6106 BuildingForOffloadDevice,
6107 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6109 C, DepA, DepTC, DepBoundArch,
false,
6110 !DepBoundArch.
empty(), LinkingOutput,
6114 A = BuildingForOffloadDevice
6115 ? OA->getSingleDeviceDependence(
true)
6116 : OA->getHostDependence();
6120 std::pair<const Action *, std::string> ActionTC = {
6121 OA->getHostDependence(),
6123 auto It = CachedResults.find(ActionTC);
6124 if (It != CachedResults.end()) {
6126 Inputs.append(OffloadDependencesInputInfo);
6131 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6134 const Arg &Input = IA->getInputArg();
6136 if (Input.getOption().matches(options::OPT_INPUT)) {
6137 const char *
Name = Input.getValue();
6140 return {InputInfo(A, &Input,
"")};
6143 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6144 const ToolChain *TC;
6145 BoundArch ArchName = BAA->
getArch();
6147 if (!ArchName.
empty())
6148 TC = &getToolChain(
C.getArgs(),
6152 TC = &
C.getDefaultToolChain();
6155 MultipleArchs, LinkingOutput, CachedResults,
6156 TargetDeviceOffloadKind);
6167 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6170 return {InputInfo()};
6174 for (
const auto *OA : CollapsedOffloadActions)
6176 BuildingForOffloadDevice,
6177 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6179 C, DepA, DepTC, DepBoundArch,
false,
6180 !DepBoundArch.
empty(), LinkingOutput,
6186 for (
const Action *Input : Inputs) {
6190 bool SubJobAtTopLevel =
6193 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6198 const char *BaseInput = InputInfos[0].getBaseInput();
6199 for (
auto &Info : InputInfos) {
6200 if (Info.isFilename()) {
6201 BaseInput = Info.getBaseInput();
6208 if (JA->
getType() == types::TY_dSYM)
6209 BaseInput = InputInfos[0].getFilename();
6212 if (!OffloadDependencesInputInfo.empty())
6213 InputInfos.append(OffloadDependencesInputInfo.begin(),
6214 OffloadDependencesInputInfo.end());
6217 llvm::Triple EffectiveTriple;
6219 const ArgList &Args =
6221 if (InputInfos.size() != 1) {
6226 EffectiveTriple = llvm::Triple(
6229 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6234 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6238 for (
auto &UI : UA->getDependentActionsInfo()) {
6240 "Unbundling with no offloading??");
6247 UI.DependentOffloadKind, UI.DependentToolChain->getTripleString(),
6249 auto CurI = InputInfo(
6258 UnbundlingResults.push_back(CurI);
6267 Arch = BoundArch(UI.DependentBoundArch);
6272 UI.DependentOffloadKind)}] = {
6278 std::pair<const Action *, std::string> ActionTC = {
6280 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6281 "Result does not exist??");
6282 Result = CachedResults[ActionTC].front();
6283 }
else if (JA->
getType() == types::TY_Nothing)
6284 Result = {InputInfo(A, BaseInput)};
6295 MultipleArchs, OffloadingPrefix),
6303 <<
'"' <<
" - \"" << T->
getName() <<
"\", inputs: [";
6304 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6305 llvm::errs() << InputInfos[i].getAsString();
6307 llvm::errs() <<
", ";
6309 if (UnbundlingResults.empty())
6310 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6312 llvm::errs() <<
"], outputs: [";
6313 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6314 llvm::errs() << UnbundlingResults[i].getAsString();
6316 llvm::errs() <<
", ";
6318 llvm::errs() <<
"] \n";
6321 if (UnbundlingResults.empty())
6325 Args, LinkingOutput);
6331 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6332 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6344 if (ArgValue.empty()) {
6346 Filename = BaseName;
6347 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6349 llvm::sys::path::append(Filename, BaseName);
6352 if (!llvm::sys::path::has_extension(ArgValue)) {
6357 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6362 llvm::sys::path::replace_extension(Filename, Extension);
6365 return Args.MakeArgString(Filename.c_str());
6380 StringRef Suffix,
bool MultipleArchs,
6381 StringRef BoundArchStr,
6382 bool NeedUniqueDirectory)
const {
6384 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6385 std::optional<std::string> CrashDirectory =
6387 ? std::string(A->getValue())
6388 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6389 if (CrashDirectory) {
6390 if (!
getVFS().exists(*CrashDirectory))
6391 llvm::sys::fs::create_directories(*CrashDirectory);
6393 llvm::sys::path::append(Path, Prefix);
6394 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6395 if (std::error_code EC =
6396 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6397 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6401 if (MultipleArchs && !BoundArchStr.empty()) {
6402 if (NeedUniqueDirectory) {
6404 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
6415 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6430 const char *BaseInput) {
6432 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6433 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6438 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6443 bool AtTopLevel,
bool MultipleArchs,
6444 StringRef OffloadingPrefix)
const {
6447 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6449 auto CreateTempOutputPath = [&](StringRef Prefix) {
6450 const char *Suffix =
6455 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
6456 const bool NeedUniqueDirectory =
6459 Triple.isOSDarwin();
6461 NeedUniqueDirectory);
6466 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
6467 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
6468 StringRef Filename = llvm::sys::path::filename(BaseInput);
6469 StringRef Stem = llvm::sys::path::stem(Filename);
6470 return CreateTempOutputPath(Stem);
6475 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6476 return C.addResultFile(FinalOutput->getValue(), &JA);
6480 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6482 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6484 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6485 NameArg = A->getValue();
6486 return C.addResultFile(
6496 if (JA.
getType() == types::TY_ModuleFile &&
6497 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6501 if (JA.
getType() == types::TY_PP_Asm &&
6502 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6503 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6506 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
6509 if ((JA.
getType() == types::TY_Object &&
6510 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6511 JA.
getType() == types::TY_DX_CONTAINER) {
6512 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6513 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6514 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6515 "expected DXIL or SPIR-V triple for HLSL output path");
6520 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6522 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
6523 StringRef
Name = llvm::sys::path::filename(BaseInput);
6524 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6530 if (JA.
getType() == types::TY_PP_Asm &&
6531 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6532 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6534 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6535 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6536 return C.addResultFile(
6541 if (JA.
getType() == types::TY_API_INFO &&
6542 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6543 C.getArgs().hasArg(options::OPT_o))
6544 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6545 <<
C.getArgs().getLastArgValue(options::OPT_o);
6552 bool SpecifiedModuleOutput =
6553 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6554 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6555 if (MultipleArchs && SpecifiedModuleOutput)
6556 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6561 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6562 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6568 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6570 StringRef
Name = llvm::sys::path::filename(BaseInput);
6571 return CreateTempOutputPath(
Name.split(
'.').first);
6580 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6585 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6586 llvm::sys::path::filename(BasePath));
6587 BaseName = ExternalPath;
6589 BaseName = BasePath;
6591 BaseName = llvm::sys::path::filename(BasePath);
6594 const char *NamedOutput;
6596 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6597 JA.
getType() == types::TY_LLVM_BC ||
6598 JA.
getType() == types::TY_LLVM_IR) &&
6599 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6603 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6607 }
else if (JA.
getType() == types::TY_Image &&
6608 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6609 options::OPT__SLASH_o)) {
6613 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6617 }
else if (JA.
getType() == types::TY_Image) {
6627 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6628 options::OPT_fno_gpu_rdc,
false);
6630 if (UseOutExtension) {
6632 llvm::sys::path::replace_extension(Output,
"");
6634 Output += OffloadingPrefix;
6635 if (MultipleArchs && !BoundArchStr.empty()) {
6637 Output.append(BoundArchStr);
6639 if (UseOutExtension)
6641 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6644 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6645 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6646 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6649 .getLastArg(options::OPT__SLASH_o)
6654 const char *Suffix =
6656 assert(Suffix &&
"All types used for output should have a suffix.");
6658 std::string::size_type End = std::string::npos;
6660 End = BaseName.rfind(
'.');
6662 Suffixed += OffloadingPrefix;
6663 if (MultipleArchs && !BoundArchStr.empty()) {
6665 Suffixed.append(BoundArchStr);
6670 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6671 const llvm::opt::DerivedArgList &Args) {
6678 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6680 Args.hasFlag(options::OPT_offload_new_driver,
6681 options::OPT_no_offload_new_driver,
true))) ||
6688 bool IsLinkerWrapper =
6690 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6691 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6692 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6694 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6698 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6702 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6703 JA.
getType() != types::TY_PCH) {
6704 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6706 llvm::sys::path::remove_filename(TempPath);
6707 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6708 llvm::sys::path::append(TempPath, OutputFileName);
6709 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6715 bool SameFile =
false;
6717 llvm::sys::fs::current_path(
Result);
6718 llvm::sys::path::append(
Result, BaseName);
6719 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6722 StringRef
Name = llvm::sys::path::filename(BaseInput);
6723 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6727 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6733 llvm::sys::path::remove_filename(BasePath);
6734 if (BasePath.empty())
6735 BasePath = NamedOutput;
6737 llvm::sys::path::append(BasePath, NamedOutput);
6738 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6741 return C.addResultFile(NamedOutput, &JA);
6747 -> std::optional<std::string> {
6750 for (
const auto &
Dir : P) {
6754 llvm::sys::path::append(P,
Name);
6755 if (llvm::sys::fs::exists(Twine(P)))
6756 return std::string(P);
6758 return std::nullopt;
6765 llvm::sys::path::append(R,
Name);
6766 if (llvm::sys::fs::exists(Twine(R)))
6767 return std::string(R);
6770 llvm::sys::path::append(P,
Name);
6771 if (llvm::sys::fs::exists(Twine(P)))
6772 return std::string(P);
6776 if (std::optional<std::string> IntrPath =
6779 llvm::sys::path::append(P,
Name);
6780 if (llvm::sys::fs::exists(P))
6781 return std::string(P);
6786 llvm::sys::path::append(D,
"..",
Name);
6787 if (llvm::sys::fs::exists(Twine(D)))
6788 return std::string(D);
6797 llvm::sys::path::append(R2,
"..",
"..",
Name);
6798 if (llvm::sys::fs::exists(Twine(R2)))
6799 return std::string(R2);
6801 return std::string(
Name);
6804void Driver::generatePrefixedToolNames(
6808 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6809 Names.emplace_back(
Tool);
6813 llvm::sys::path::append(Dir, Name);
6814 if (llvm::sys::fs::can_execute(Twine(Dir)))
6816 llvm::sys::path::remove_filename(Dir);
6822 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6827 if (llvm::sys::fs::is_directory(PrefixDir)) {
6830 return std::string(P);
6833 if (llvm::sys::fs::can_execute(Twine(P)))
6834 return std::string(P);
6839 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6847 for (
const auto &Path : List) {
6850 return std::string(P);
6854 if (llvm::ErrorOr<std::string> P =
6855 llvm::sys::findProgramByName(TargetSpecificExecutable))
6859 return std::string(
Name);
6864 std::string error =
"<NOT PRESENT>";
6866 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6871 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6888 llvm::sys::path::remove_filename(path);
6889 llvm::sys::path::append(path,
"libc++.modules.json");
6890 if (TC.
getVFS().exists(path))
6891 return static_cast<std::string
>(path);
6896 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6899 return evaluate(
"libc++.a").value_or(error);
6903 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6907 llvm::sys::path::remove_filename(path);
6908 llvm::sys::path::append(path,
"libstdc++.modules.json");
6909 if (TC.
getVFS().exists(path))
6910 return static_cast<std::string
>(path);
6915 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6918 return evaluate(
"libstdc++.a").value_or(error);
6927 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6929 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6933 return std::string(Path);
6938 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6940 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6944 return std::string(Path);
6949 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6953 Output = FpArg->getValue();
6957 if (!llvm::sys::path::has_extension(Output))
6960 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6961 Output = YcArg->getValue();
6964 llvm::sys::path::replace_extension(Output,
".pch");
6966 return std::string(Output);
6969const ToolChain &Driver::getOffloadToolChain(
6971 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6972 std::unique_ptr<ToolChain> &TC =
6973 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6974 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6976 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6979 switch (
Target.getOS()) {
6980 case llvm::Triple::CUDA:
6981 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6984 case llvm::Triple::AMDHSA:
6986 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6989 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6998 switch (
Target.getArch()) {
6999 case llvm::Triple::spir:
7000 case llvm::Triple::spir64:
7001 case llvm::Triple::spirv:
7002 case llvm::Triple::spirv32:
7003 case llvm::Triple::spirv64:
7006 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
7010 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7014 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7018 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7032 return getToolChain(Args,
Target);
7036const ToolChain &Driver::getToolChain(
const ArgList &Args,
7037 const llvm::Triple &
Target)
const {
7039 auto &TC = ToolChains[
Target.str()];
7041 switch (
Target.getOS()) {
7042 case llvm::Triple::AIX:
7043 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7045 case llvm::Triple::Haiku:
7046 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7048 case llvm::Triple::Darwin:
7049 case llvm::Triple::MacOSX:
7050 case llvm::Triple::IOS:
7051 case llvm::Triple::TvOS:
7052 case llvm::Triple::WatchOS:
7053 case llvm::Triple::XROS:
7054 case llvm::Triple::DriverKit:
7055 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7057 case llvm::Triple::DragonFly:
7058 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7060 case llvm::Triple::OpenBSD:
7061 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7063 case llvm::Triple::NetBSD:
7064 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7066 case llvm::Triple::FreeBSD:
7068 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7071 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7073 case llvm::Triple::Linux:
7074 case llvm::Triple::ELFIAMCU:
7075 if (
Target.getArch() == llvm::Triple::hexagon)
7076 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7078 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7079 !
Target.hasEnvironment())
7080 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7083 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7085 else if (
Target.getArch() == llvm::Triple::ve)
7086 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7087 else if (
Target.isOHOSFamily())
7088 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7089 else if (
Target.isWALI())
7090 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7092 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7094 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7096 case llvm::Triple::Fuchsia:
7097 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7099 case llvm::Triple::Managarm:
7100 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7102 case llvm::Triple::Serenity:
7103 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7105 case llvm::Triple::Solaris:
7106 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7108 case llvm::Triple::CUDA:
7109 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7111 case llvm::Triple::AMDHSA: {
7112 if (
Target.getArch() == llvm::Triple::spirv64) {
7113 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7118 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7120 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7125 case llvm::Triple::AMDPAL:
7126 case llvm::Triple::Mesa3D:
7127 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7129 case llvm::Triple::UEFI:
7130 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7132 case llvm::Triple::Win32:
7133 switch (
Target.getEnvironment()) {
7135 if (
Target.isOSBinFormatELF())
7136 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7137 else if (
Target.isOSBinFormatMachO())
7138 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7140 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7142 case llvm::Triple::GNU:
7143 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7145 case llvm::Triple::Cygnus:
7146 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7148 case llvm::Triple::Itanium:
7149 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7152 case llvm::Triple::MSVC:
7153 case llvm::Triple::UnknownEnvironment:
7154 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7155 .starts_with_insensitive(
"bfd"))
7156 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7160 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7164 case llvm::Triple::PS4:
7165 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7167 case llvm::Triple::PS5:
7168 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7170 case llvm::Triple::Hurd:
7171 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7173 case llvm::Triple::LiteOS:
7174 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7176 case llvm::Triple::ZOS:
7177 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7179 case llvm::Triple::Vulkan:
7180 case llvm::Triple::ShaderModel:
7181 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7182 Target.getArch() == llvm::Triple::spirv64) &&
7184 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7186 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7188 case llvm::Triple::ChipStar:
7189 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7194 switch (
Target.getArch()) {
7195 case llvm::Triple::tce:
7196 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7198 case llvm::Triple::tcele:
7199 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7201 case llvm::Triple::tcele64:
7203 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7205 case llvm::Triple::hexagon:
7206 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7209 case llvm::Triple::lanai:
7210 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7212 case llvm::Triple::xcore:
7213 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7215 case llvm::Triple::wasm32:
7216 case llvm::Triple::wasm64:
7217 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7219 case llvm::Triple::avr:
7220 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7222 case llvm::Triple::msp430:
7223 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7225 case llvm::Triple::riscv32:
7226 case llvm::Triple::riscv64:
7227 case llvm::Triple::riscv32be:
7228 case llvm::Triple::riscv64be:
7229 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7231 case llvm::Triple::ve:
7232 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7234 case llvm::Triple::spirv32:
7235 case llvm::Triple::spirv64:
7236 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7238 case llvm::Triple::csky:
7239 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7241 case llvm::Triple::amdgcn:
7242 case llvm::Triple::r600:
7243 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7247 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7248 else if (
Target.isOSBinFormatELF())
7249 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7250 else if (
Target.isAppleFirmware())
7251 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7252 else if (
Target.isAppleMachO())
7253 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7254 else if (
Target.isOSBinFormatMachO())
7255 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7257 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7267 if (JA.
size() != 1 ||
7282 if (JA.
size() != 1 ||
7296 if (Args.hasArg(options::OPT_emit_static_lib))
7307 unsigned &Micro,
bool &HadExtra) {
7310 Major = Minor = Micro = 0;
7314 if (Str.consumeInteger(10, Major))
7318 if (!Str.consume_front(
"."))
7321 if (Str.consumeInteger(10, Minor))
7325 if (!Str.consume_front(
"."))
7328 if (Str.consumeInteger(10, Micro))
7346 unsigned CurDigit = 0;
7347 while (CurDigit < Digits.size()) {
7349 if (Str.consumeInteger(10, Digit))
7351 Digits[CurDigit] = Digit;
7354 if (!Str.consume_front(
"."))
7363llvm::opt::Visibility
7364Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7377const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7393 llvm_unreachable(
"Unhandled Mode");
7397 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7402 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7403 options::OPT_fno_save_optimization_record,
false))
7407 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7408 options::OPT_fno_save_optimization_record,
false))
7412 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7413 options::OPT_fno_save_optimization_record,
false))
7417 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7418 options::OPT_fno_save_optimization_record,
false))
7425 static StringRef OptName =
7427 llvm::StringRef Opt;
7428 for (StringRef Arg : Args) {
7429 if (!Arg.starts_with(OptName))
7435 return Opt.consume_front(OptName) ? Opt :
"";
7442 llvm::BumpPtrAllocator &Alloc,
7443 llvm::vfs::FileSystem *FS) {
7452 for (
const char *F : Args) {
7453 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7455 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7456 RSPQuoting = Windows;
7462 bool MarkEOLs = ClangCLMode;
7464 llvm::cl::TokenizerCallback Tokenizer;
7465 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7466 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7468 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7470 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7473 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7474 ECtx.setMarkEOLs(MarkEOLs);
7478 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7482 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7483 [](
const char *A) {
return A !=
nullptr; });
7484 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7487 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7488 Args.resize(newEnd - Args.begin());
7492 return llvm::Error::success();
7496 return SavedStrings.insert(S).first->getKeyData();
7530 llvm::StringSet<> &SavedStrings) {
7533 if (Edit[0] ==
'^') {
7534 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7535 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7536 Args.insert(Args.begin() + 1, Str);
7537 }
else if (Edit[0] ==
'+') {
7538 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7539 OS <<
"### Adding argument " << Str <<
" at end\n";
7540 Args.push_back(Str);
7541 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7542 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7543 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7544 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7545 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7547 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7549 if (Args[i] ==
nullptr)
7551 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7553 if (Repl != Args[i]) {
7554 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7558 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7559 auto Option = Edit.substr(1);
7560 for (
unsigned i = 1; i < Args.size();) {
7561 if (Option == Args[i]) {
7562 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7563 Args.erase(Args.begin() + i);
7564 if (Edit[0] ==
'X') {
7565 if (i < Args.size()) {
7566 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7567 Args.erase(Args.begin() + i);
7569 OS <<
"### Invalid X edit, end of command line!\n";
7574 }
else if (Edit[0] ==
'O') {
7575 for (
unsigned i = 1; i < Args.size();) {
7576 const char *A = Args[i];
7580 if (A[0] ==
'-' && A[1] ==
'O' &&
7581 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7582 (
'0' <= A[2] && A[2] <=
'9'))))) {
7583 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7584 Args.erase(Args.begin() + i);
7588 OS <<
"### Adding argument " << Edit <<
" at end\n";
7589 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7591 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7596 const char *OverrideStr,
7597 llvm::StringSet<> &SavedStrings,
7598 StringRef EnvVar, raw_ostream *OS) {
7600 OS = &llvm::nulls();
7602 if (OverrideStr[0] ==
'#') {
7604 OS = &llvm::nulls();
7607 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7611 const char *S = OverrideStr;
7613 const char *End = ::strchr(S,
' ');
7615 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
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 const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static bool 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.
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)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ 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