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 {
556 return ((v < 2) || ((v == 2) && (r < 4)));
560 if (ArgTarget.equals_insensitive(
"CURRENT")) {
564 unsigned int Version = 0;
565 unsigned int Release = 0;
566 unsigned int Modification = 0;
568 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
569 llvm::Regex HexRegex(
572 "([0-9a-fA-F][0-9a-fA-F])"
573 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
576 if (ZOsvRegex.match(ArgTarget, &Matches)) {
577 Matches[1].getAsInteger(10, Version);
578 Matches[2].getAsInteger(10, Release);
580 if (IsTooOldToBeSupported(Version, Release)) {
582 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
585 }
else if (HexRegex.match(ArgTarget, &Matches)) {
586 Matches[1].getAsInteger(16, Version);
587 Matches[2].getAsInteger(16, Release);
588 Matches[3].getAsInteger(16, Modification);
589 if (IsTooOldToBeSupported(Version, Release)) {
591 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
597 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
602 llvm::VersionTuple
V(Version, Release, Modification);
603 llvm::VersionTuple TV =
Target.getOSVersion();
606 if (TV.empty() ||
V < TV) {
608 Str = llvm::Triple::getOSTypeName(
Target.getOS());
609 Str +=
V.getAsString();
622 StringRef TargetTriple,
624 StringRef DarwinArchName =
"") {
626 if (
const Arg *A = Args.getLastArg(options::OPT_target))
627 TargetTriple = A->getValue();
629 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
634 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
638 if (
Target.isOSBinFormatMachO()) {
640 if (!DarwinArchName.empty()) {
647 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
648 StringRef ArchName = A->getValue();
655 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
656 options::OPT_mbig_endian)) {
657 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
658 ?
Target.getLittleEndianArchVariant()
659 :
Target.getBigEndianArchVariant();
660 if (T.getArch() != llvm::Triple::UnknownArch) {
662 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
667 if (
Target.getArch() == llvm::Triple::tce)
673 if (!Args.hasArg(options::OPT_target)) {
674 if (std::optional<std::string> ObjectModeValue =
675 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
676 StringRef ObjectMode = *ObjectModeValue;
677 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
679 if (ObjectMode ==
"64") {
680 AT =
Target.get64BitArchVariant().getArch();
681 }
else if (ObjectMode ==
"32") {
682 AT =
Target.get32BitArchVariant().getArch();
684 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
687 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
694 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
695 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
698 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
700 D.
Diag(diag::err_drv_unsupported_opt_for_target)
701 << A->getAsString(Args) <<
Target.str();
704 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
705 options::OPT_m32, options::OPT_m16,
706 options::OPT_maix32, options::OPT_maix64);
708 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
710 if (A->getOption().matches(options::OPT_m64) ||
711 A->getOption().matches(options::OPT_maix64)) {
712 AT =
Target.get64BitArchVariant().getArch();
713 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
714 Target.getEnvironment() == llvm::Triple::GNUT64)
715 Target.setEnvironment(llvm::Triple::GNU);
716 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
717 Target.setEnvironment(llvm::Triple::Musl);
718 }
else if (A->getOption().matches(options::OPT_mx32) &&
719 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
720 AT = llvm::Triple::x86_64;
721 if (
Target.getEnvironment() == llvm::Triple::Musl)
722 Target.setEnvironment(llvm::Triple::MuslX32);
724 Target.setEnvironment(llvm::Triple::GNUX32);
725 }
else if (A->getOption().matches(options::OPT_m32) ||
726 A->getOption().matches(options::OPT_maix32)) {
728 D.
Diag(diag::err_drv_unsupported_opt_for_target)
729 << A->getAsString(Args) <<
Target.str();
731 AT =
Target.get32BitArchVariant().getArch();
732 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
733 Target.setEnvironment(llvm::Triple::GNU);
734 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
735 Target.setEnvironment(llvm::Triple::Musl);
737 }
else if (A->getOption().matches(options::OPT_m16) &&
738 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
739 AT = llvm::Triple::x86;
740 Target.setEnvironment(llvm::Triple::CODE16);
743 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
745 if (
Target.isWindowsGNUEnvironment())
751 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
757 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
758 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
759 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
762 if (A && !A->getOption().matches(options::OPT_m32))
763 D.
Diag(diag::err_drv_argument_not_allowed_with)
764 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
766 Target.setArch(llvm::Triple::x86);
767 Target.setArchName(
"i586");
768 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
769 Target.setEnvironmentName(
"");
770 Target.setOS(llvm::Triple::ELFIAMCU);
771 Target.setVendor(llvm::Triple::UnknownVendor);
772 Target.setVendorName(
"intel");
778 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
779 StringRef ABIName = A->getValue();
780 if (ABIName ==
"32") {
782 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
783 Target.getEnvironment() == llvm::Triple::GNUABIN32)
784 Target.setEnvironment(llvm::Triple::GNU);
785 }
else if (ABIName ==
"n32") {
787 if (
Target.getEnvironment() == llvm::Triple::GNU ||
788 Target.getEnvironment() == llvm::Triple::GNUT64 ||
789 Target.getEnvironment() == llvm::Triple::GNUABI64)
790 Target.setEnvironment(llvm::Triple::GNUABIN32);
791 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
792 Target.getEnvironment() == llvm::Triple::MuslABI64)
793 Target.setEnvironment(llvm::Triple::MuslABIN32);
794 }
else if (ABIName ==
"64") {
796 if (
Target.getEnvironment() == llvm::Triple::GNU ||
797 Target.getEnvironment() == llvm::Triple::GNUT64 ||
798 Target.getEnvironment() == llvm::Triple::GNUABIN32)
799 Target.setEnvironment(llvm::Triple::GNUABI64);
800 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
801 Target.getEnvironment() == llvm::Triple::MuslABIN32)
802 Target.setEnvironment(llvm::Triple::MuslABI64);
810 if (Args.hasArg(options::OPT_march_EQ) ||
811 Args.hasArg(options::OPT_mcpu_EQ)) {
813 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
815 if (!llvm::errorToBool(ISAInfo.takeError())) {
816 unsigned XLen = (*ISAInfo)->getXLen();
818 if (
Target.isLittleEndian())
819 Target.setArch(llvm::Triple::riscv32);
821 Target.setArch(llvm::Triple::riscv32be);
822 }
else if (XLen == 64) {
823 if (
Target.isLittleEndian())
824 Target.setArch(llvm::Triple::riscv64);
826 Target.setArch(llvm::Triple::riscv64be);
832 if (
Target.getArch() == llvm::Triple::riscv32be ||
833 Target.getArch() == llvm::Triple::riscv64be) {
834 static bool WarnedRISCVBE =
false;
835 if (!WarnedRISCVBE) {
836 D.
Diag(diag::warn_drv_riscv_be_experimental);
837 WarnedRISCVBE =
true;
846 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
848 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
850 RuntimeName = A->getValue();
852 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
860 Diag(diag::err_drv_unsupported_option_argument)
861 << A->getSpelling() << A->getValue();
864 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
873 StringRef Program =
C.getArgs().getLastArgValue(
874 options::OPT_offload_arch_tool_EQ,
"offload-arch");
877 if (llvm::ErrorOr<std::string> Executable =
878 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
881 Args.push_back(
"--only=amdgpu");
883 Args.push_back(
"--only=nvptx");
884 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
887 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
892 if ((*StdoutOrErr)->getBuffer().empty()) {
893 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
899 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
901 GPUArchs.push_back(
Arch.str());
903 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
914 std::set<std::string> Archs;
915 for (Arg *A :
C.getInputArgs()) {
916 for (StringRef
Arch : A->getValues()) {
917 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
918 if (
Arch ==
"native") {
920 Archs.insert(Str.str());
922 Archs.insert(
Arch.str());
924 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
928 Archs.erase(
Arch.str());
934 for (llvm::StringRef
Arch : Archs) {
938 llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
939 llvm::Triple::AMD, llvm::Triple::AMDHSA),
943 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
948 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
954 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
959 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
960 <<
"offload" <<
Arch;
964 llvm::Triple Triple =
970 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
971 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
972 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
973 C.getArgs().MakeArgString(Triple.getArchName()),
974 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
976 C.getArgs().append(A);
977 C.getArgs().AddSynthesizedArg(A);
979 auto It = Triples.lower_bound(Triple);
980 if (It == Triples.end() || *It != Triple)
981 Triples.insert(It, Triple);
986 Triples.insert(llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
987 llvm::Triple::AMD, llvm::Triple::AMDHSA));
989 llvm::Triple::ArchType
Arch =
990 C.getDefaultToolChain().getTriple().isArch64Bit()
991 ? llvm::Triple::nvptx64
992 : llvm::Triple::nvptx;
993 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
994 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
997 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
998 ? llvm::Triple::spirv64
999 : llvm::Triple::spirv32));
1002 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1003 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1010 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1011 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1013 llvm::any_of(Inputs,
1014 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1019 (llvm::any_of(Inputs,
1020 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1023 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1024 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1026 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1027 options::OPT_fno_sycl,
false);
1028 bool IsOpenMPOffloading =
1030 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1031 options::OPT_fno_openmp,
false) &&
1032 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1033 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1034 !(IsCuda || IsHIP))));
1036 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1037 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1042 for (
const auto &[Active, Kind] : ActiveKinds)
1047 if (Kinds.size() > 1) {
1048 Diag(clang::diag::err_drv_mix_offload)
1055 if (IsCuda || IsHIP)
1062 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1063 std::vector<std::string> ArgValues =
1064 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1065 for (llvm::StringRef
Target : ArgValues) {
1069 if (ArgValues.empty())
1070 Diag(clang::diag::warn_drv_empty_joined_argument)
1072 .getLastArg(options::OPT_offload_targets_EQ)
1073 ->getAsString(
C.getInputArgs());
1080 llvm::StringMap<StringRef> FoundNormalizedTriples;
1081 for (
const llvm::Triple &
Target : Triples) {
1086 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1094 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1095 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1096 Diag(clang::diag::err_drv_argument_not_allowed_with)
1097 << IncompatArg->getSpelling() <<
"-fsycl";
1102 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1103 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1108 std::string NormalizedName =
Target.normalize();
1109 auto [TripleIt, Inserted] =
1110 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1112 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1113 <<
Target.str() << TripleIt->second;
1117 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1118 C.getDefaultToolChain().getTriple());
1122 auto &CudaInstallation =
1124 if (CudaInstallation.isValid())
1125 CudaInstallation.WarnIfUnsupportedVersion();
1128 C.addOffloadDeviceToolChain(&TC, Kind);
1133bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1138 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1142 if (!PathLIBEnv.empty()) {
1143 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1144 if (llvm::sys::fs::is_directory(PathLIBEnv))
1145 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1146 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1147 return readConfigFile(CustomizationFile, ExpCtx);
1148 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1153 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1154 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1155 return readConfigFile(CustomizationFile, ExpCtx);
1165 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1166 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1167 Copy->getValues() = Opt->getValues();
1168 if (Opt->isClaimed())
1170 Copy->setOwnsValues(Opt->getOwnsValues());
1171 Opt->setOwnsValues(
false);
1173 if (Opt->getAlias()) {
1174 const Arg *Alias = Opt->getAlias();
1175 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1176 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1177 Args.getArgString(Index), Index);
1178 AliasCopy->getValues() = Alias->getValues();
1179 AliasCopy->setOwnsValues(
false);
1180 if (Alias->isClaimed())
1182 Copy->setAlias(std::move(AliasCopy));
1186bool Driver::readConfigFile(StringRef
FileName,
1187 llvm::cl::ExpansionContext &ExpCtx) {
1191 Diag(diag::err_drv_cannot_open_config_file)
1192 <<
FileName << Status.getError().message();
1195 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1196 Diag(diag::err_drv_cannot_open_config_file)
1197 <<
FileName <<
"not a regular file";
1202 SmallVector<const char *, 32> NewCfgFileArgs;
1203 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1204 Diag(diag::err_drv_cannot_read_config_file)
1210 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1211 for (
const char *Opt : NewCfgFileArgs) {
1213 if (Opt[0] ==
'$' && Opt[1])
1214 NewCfgTailArgs.push_back(Opt + 1);
1216 NewCfgHeadArgs.push_back(Opt);
1220 llvm::SmallString<128> CfgFileName(
FileName);
1221 llvm::sys::path::native(CfgFileName);
1222 bool ContainErrors =
false;
1223 auto NewHeadOptions = std::make_unique<InputArgList>(
1227 auto NewTailOptions = std::make_unique<InputArgList>(
1234 for (Arg *A : *NewHeadOptions)
1236 for (Arg *A : *NewTailOptions)
1239 if (!CfgOptionsHead)
1240 CfgOptionsHead = std::move(NewHeadOptions);
1243 for (
auto *Opt : *NewHeadOptions)
1247 if (!CfgOptionsTail)
1248 CfgOptionsTail = std::move(NewTailOptions);
1251 for (
auto *Opt : *NewTailOptions)
1255 ConfigFiles.push_back(std::string(CfgFileName));
1259bool Driver::loadConfigFiles() {
1260 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1261 llvm::cl::tokenizeConfigFile, &
getVFS());
1265 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1266 SmallString<128> CfgDir;
1268 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1269 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1274 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1275 SmallString<128> CfgDir;
1276 llvm::sys::fs::expand_tilde(
1277 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1278 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1287 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1290 if (loadDefaultConfigFiles(ExpCtx))
1294 SmallString<128> CfgFilePath;
1296 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1299 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1300 CfgFilePath.assign(CfgFileName);
1301 if (llvm::sys::path::is_relative(CfgFilePath)) {
1302 if (
getVFS().makeAbsolute(CfgFilePath)) {
1303 Diag(diag::err_drv_cannot_open_config_file)
1304 << CfgFilePath <<
"cannot get absolute path";
1308 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1310 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1311 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1312 if (!SearchDir.empty())
1313 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1318 if (readConfigFile(CfgFilePath, ExpCtx))
1329 llvm::Triple Triple, std::string Suffix) {
1331 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1335 VersionTuple OSVersion = Triple.getOSVersion();
1336 if (!OSVersion.getMinor().has_value())
1339 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1343 if (OSVersion.getMajor() != 0) {
1344 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1345 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1351 Triple.setOSName(BaseOSName);
1352 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1355bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1358 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1362 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1365 std::string RealMode = getExecutableForDriverMode(Mode);
1366 llvm::Triple Triple;
1375 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1376 PrefixTriple.isOSUnknown())
1377 Triple = std::move(PrefixTriple);
1381 llvm::Triple RealTriple =
1383 if (Triple.str().empty()) {
1384 Triple = RealTriple;
1385 assert(!Triple.str().empty());
1390 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1404 SmallString<128> CfgFilePath;
1406 "-" + RealMode +
".cfg"))
1407 return readConfigFile(CfgFilePath, ExpCtx);
1411 if (TryModeSuffix) {
1414 return readConfigFile(CfgFilePath, ExpCtx);
1419 std::string CfgFileName = RealMode +
".cfg";
1420 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1421 if (readConfigFile(CfgFilePath, ExpCtx))
1423 }
else if (TryModeSuffix) {
1425 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1426 readConfigFile(CfgFilePath, ExpCtx))
1432 return readConfigFile(CfgFilePath, ExpCtx);
1440 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1449 if (!DriverMode.empty())
1450 setDriverMode(DriverMode);
1456 CLOptions = std::make_unique<InputArgList>(
1461 ContainsError = loadConfigFiles();
1462 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1463 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1467 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1469 if (HasConfigFileHead)
1470 for (
auto *Opt : *CLOptions)
1471 if (!Opt->getOption().matches(options::OPT_config))
1475 if (
IsCLMode() && !ContainsError) {
1477 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1479 CLModePassThroughArgList.push_back(A->getValue());
1482 if (!CLModePassThroughArgList.empty()) {
1485 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1490 for (
auto *Opt : *CLModePassThroughOptions)
1496 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1497 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1498 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1501 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1502 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1503 if (!VFS->exists(IncludeDir))
1504 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1509 bool CCCPrintPhases;
1512 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1513 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1516 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1517 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1520 Args.ClaimAllArgs(options::OPT_pipe);
1528 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1530 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1531 CCCGenericGCCName = A->getValue();
1534 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1538 if (Args.hasArg(options::OPT_fproc_stat_report))
1545 llvm::Triple T(TargetTriple);
1546 T.setOS(llvm::Triple::Win32);
1547 T.setVendor(llvm::Triple::PC);
1548 T.setEnvironment(llvm::Triple::MSVC);
1549 T.setObjectFormat(llvm::Triple::COFF);
1550 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1551 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1552 TargetTriple = T.str();
1555 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1556 StringRef TargetProfile = A->getValue();
1559 TargetTriple = *Triple;
1561 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1565 if (Args.hasArg(options::OPT_spirv)) {
1566 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1567 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1568 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1569 llvm::Triple T(TargetTriple);
1572 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1574 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1575 TargetInfo = ValidTargets.find(A->getValue());
1577 Diag(diag::err_drv_invalid_value)
1578 << A->getAsString(Args) << A->getValue();
1584 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1585 TargetTriple = T.str();
1589 Diag(diag::err_drv_dxc_missing_target_profile);
1593 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1594 TargetTriple = A->getValue();
1595 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1596 Dir = A->getValue();
1597 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1601 if (std::optional<std::string> CompilerPathValue =
1602 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1603 StringRef CompilerPath = *CompilerPathValue;
1604 while (!CompilerPath.empty()) {
1605 std::pair<StringRef, StringRef> Split =
1606 CompilerPath.split(llvm::sys::EnvPathSeparator);
1607 PrefixDirs.push_back(std::string(Split.first));
1608 CompilerPath = Split.second;
1611 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1613 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1616 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1619 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1620 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1621 .Case(
"cwd", SaveTempsCwd)
1622 .Case(
"obj", SaveTempsObj)
1623 .Default(SaveTempsCwd);
1626 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1627 options::OPT_offload_device_only,
1628 options::OPT_offload_host_device)) {
1629 if (A->getOption().matches(options::OPT_offload_host_only))
1630 Offload = OffloadHost;
1631 else if (A->getOption().matches(options::OPT_offload_device_only))
1632 Offload = OffloadDevice;
1634 Offload = OffloadHostDevice;
1638 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1639 StringRef
Name = A->getValue();
1640 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1641 .Case(
"off", EmbedNone)
1642 .Case(
"all", EmbedBitcode)
1643 .Case(
"bitcode", EmbedBitcode)
1644 .Case(
"marker", EmbedMarker)
1647 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1650 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1654 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1655 llvm::sys::fs::remove(A->getValue());
1661 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1663 !Args.hasArg(options::OPT_fmodules) && Std &&
1664 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1665 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1666 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1667 Std->containsValue(
"c++latest"));
1670 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1671 options::OPT_fmodule_header)) {
1673 ModulesModeCXX20 =
true;
1674 if (A->getOption().matches(options::OPT_fmodule_header))
1677 StringRef ArgName = A->getValue();
1678 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1683 Diags.Report(diag::err_drv_invalid_value)
1684 << A->getAsString(Args) << ArgName;
1690 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1691 std::make_unique<InputArgList>(std::move(Args));
1701 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1702 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1704 bool MLContainsError;
1705 auto MultilibMacroDefineList =
1707 MLMacroDefinesChar,
false, MLContainsError));
1708 if (!MLContainsError) {
1709 for (
auto *Opt : *MultilibMacroDefineList) {
1716 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1720 if (!Triple.isWasm()) {
1721 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1722 StringRef TripleObjectFormat =
1723 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1724 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1725 TripleVersionName != TripleObjectFormat) {
1726 Diags.Report(diag::err_drv_triple_version_invalid)
1728 ContainsError =
true;
1733 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1734 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1735 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1743 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1744 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1746 case llvm::Triple::arm:
1747 case llvm::Triple::armeb:
1748 case llvm::Triple::thumb:
1749 case llvm::Triple::thumbeb:
1750 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1751 Diag(diag::warn_target_unrecognized_env)
1753 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1756 case llvm::Triple::aarch64:
1757 case llvm::Triple::aarch64_be:
1758 case llvm::Triple::aarch64_32:
1759 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1760 Diag(diag::warn_target_unrecognized_env)
1762 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1779 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1780 if (HasConfigFileTail && Inputs.size()) {
1783 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1784 for (Arg *A : *CfgOptionsTail)
1785 TranslatedLinkerIns.append(A);
1786 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1793 bool UseModulesDriver =
C->getArgs().hasFlag(
1794 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1796 if (UseModulesDriver) {
1797 Diags.Report(diag::remark_performing_driver_managed_module_build);
1805 const auto StdModuleManifestPath =
1808 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1809 Diags.Report(diag::remark_modules_manifest_not_found);
1811 Diags.Report(diag::remark_using_modules_manifest)
1812 << StdModuleManifestPath;
1813 if (
auto ManifestOrErr =
1815 ModulesManifest = std::move(*ManifestOrErr);
1817 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1818 return !ModuleEntry.IsStdlib;
1823 llvm::handleAllErrors(
1824 ManifestOrErr.takeError(),
1825 [&](llvm::json::ParseError &Err) {
1826 Diags.Report(diag::err_modules_manifest_failed_parse)
1829 [&](llvm::FileError &Err) {
1830 Diags.Report(diag::err_cannot_open_file)
1831 << Err.getFileName() << Err.messageWithoutFileInfo();
1839 if (TC.
getTriple().isOSBinFormatMachO())
1844 if (CCCPrintPhases) {
1851 if (UseModulesDriver)
1858 llvm::opt::ArgStringList ASL;
1859 for (
const auto *A : Args) {
1863 while (A->getAlias())
1865 A->render(Args, ASL);
1868 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1869 if (I != ASL.begin())
1871 llvm::sys::printArg(OS, *I,
true);
1876bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1877 SmallString<128> &CrashDiagDir) {
1878 using namespace llvm::sys;
1879 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1880 "Only knows about .crash files on Darwin");
1882 auto BypassSandbox = sandbox::scopedDisable();
1887 path::home_directory(CrashDiagDir);
1888 if (CrashDiagDir.starts_with(
"/var/root"))
1890 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1898 fs::file_status FileStatus;
1899 TimePoint<> LastAccessTime;
1900 SmallString<128> CrashFilePath;
1903 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1904 File != FileEnd && !EC;
File.increment(EC)) {
1908 if (fs::status(
File->path(), FileStatus))
1910 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1911 llvm::MemoryBuffer::getFile(
File->path());
1916 StringRef
Data = CrashFile.get()->getBuffer();
1917 if (!
Data.starts_with(
"Process:"))
1920 size_t ParentProcPos =
Data.find(
"Parent Process:");
1921 if (ParentProcPos == StringRef::npos)
1923 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1924 if (LineEnd == StringRef::npos)
1926 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1927 int OpenBracket = -1, CloseBracket = -1;
1928 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1929 if (ParentProcess[i] ==
'[')
1931 if (ParentProcess[i] ==
']')
1937 if (OpenBracket < 0 || CloseBracket < 0 ||
1938 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1939 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1949 const auto FileAccessTime = FileStatus.getLastModificationTime();
1950 if (FileAccessTime > LastAccessTime) {
1951 CrashFilePath.assign(
File->path());
1952 LastAccessTime = FileAccessTime;
1957 if (!CrashFilePath.empty()) {
1958 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1968 "\n********************\n\n"
1969 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
1977 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1980 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
1983 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1984 Level = llvm::StringSwitch<unsigned>(A->getValue())
1986 .Case(
"compiler", 1)
1998 ArgStringList SavedTemps;
2000 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2001 if (!IsLLD || Level < 2)
2008 SavedTemps = std::move(
C.getTempFiles());
2009 assert(!
C.getTempFiles().size());
2026 C.initCompilationForDiagnostics();
2031 Command NewLLDInvocation = Cmd;
2032 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2033 StringRef ReproduceOption =
2034 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2037 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2041 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2043 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2044 Diag(clang::diag::note_drv_command_failed_diag_msg)
2045 <<
"\n\n********************";
2047 Report->TemporaryFiles.push_back(TmpName);
2055 ArgStringList IRInputs;
2056 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2057 bool IgnoreInput =
false;
2063 IRInputs.push_back(it->second->getValue());
2067 }
else if (!strcmp(it->second->getValue(),
"-")) {
2068 Diag(clang::diag::note_drv_command_failed_diag_msg)
2069 <<
"Error generating preprocessed source(s) - "
2070 "ignoring input from stdin.";
2075 it = Inputs.erase(it);
2082 if (Inputs.empty() && IRInputs.empty()) {
2083 Diag(clang::diag::note_drv_command_failed_diag_msg)
2084 <<
"Error generating preprocessed source(s) - "
2085 "no preprocessable inputs.";
2092 for (
const Arg *A :
C.getArgs()) {
2093 if (A->getOption().matches(options::OPT_arch)) {
2094 StringRef ArchName = A->getValue();
2101 if (FailingArch.empty()) {
2102 Diag(clang::diag::note_drv_command_failed_diag_msg)
2103 <<
"Error generating preprocessed source(s) - cannot generate "
2104 "preprocessed source with multiple -arch options.";
2107 C.getArgs().eraseArg(options::OPT_arch);
2108 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2113 if (!Inputs.empty()) {
2116 const ToolChain &TC =
C.getDefaultToolChain();
2117 if (TC.
getTriple().isOSBinFormatMachO())
2126 Diag(clang::diag::note_drv_command_failed_diag_msg)
2127 <<
"Error generating preprocessed source(s).";
2132 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2135 if (!FailingCommands.empty()) {
2136 Diag(clang::diag::note_drv_command_failed_diag_msg)
2137 <<
"Error generating preprocessed source(s).";
2141 const ArgStringList &TempFiles =
C.getTempFiles();
2142 if (TempFiles.empty()) {
2143 Diag(clang::diag::note_drv_command_failed_diag_msg)
2144 <<
"Error generating preprocessed source(s).";
2150 const ArgStringList &Files =
C.getTempFiles();
2155 for (
auto const *Input : IRInputs) {
2159 StringRef extension = llvm::sys::path::extension(Input);
2160 if (!extension.empty())
2161 extension = extension.drop_front();
2163 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2164 llvm::sys::path::stem(Input), extension, FD, Path);
2166 Diag(clang::diag::note_drv_command_failed_diag_msg)
2167 <<
"Error generating run script: " <<
"Failed copying IR input files"
2168 <<
" " << EC.message();
2172 EC = llvm::sys::fs::copy_file(Input, FD);
2174 Diag(clang::diag::note_drv_command_failed_diag_msg)
2175 <<
"Error generating run script: " <<
"Failed copying IR input files"
2176 <<
" " << EC.message();
2180 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2187 for (std::string &TempFile : TempFiles) {
2189 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2191 Report->TemporaryFiles.push_back(TempFile);
2192 if (ReproCrashFilename.empty()) {
2193 ReproCrashFilename = TempFile;
2194 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2196 if (StringRef(TempFile).ends_with(
".cache")) {
2199 VFS = llvm::sys::path::filename(TempFile);
2200 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2204 for (
const char *TempFile : SavedTemps)
2205 TempFiles.push_back(TempFile);
2211 llvm::sys::path::replace_extension(Script,
"sh");
2213 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2214 llvm::sys::fs::FA_Write,
2215 llvm::sys::fs::OF_Text);
2217 Diag(clang::diag::note_drv_command_failed_diag_msg)
2218 <<
"Error generating run script: " << Script <<
" " << EC.message();
2221 <<
"# Driver args: ";
2223 ScriptOS <<
"# Original command: ";
2224 Cmd.
Print(ScriptOS,
"\n",
true);
2225 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2226 if (!AdditionalInformation.empty())
2227 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2230 Report->TemporaryFiles.push_back(std::string(Script));
2231 TempFiles.push_back(std::string(Script));
2234 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2237 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2238 StringRef CrashDiagnosticsTar = A->getValue();
2240 llvm::TarWriter::create(CrashDiagnosticsTar,
2241 llvm::sys::path::stem(CrashDiagnosticsTar));
2243 Diag(clang::diag::note_drv_command_failed_diag_msg)
2244 << (std::string(
"Error creating reproducer tarball: ") +
2245 llvm::toString(TarOrErr.takeError()));
2247 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2248 for (
const std::string &TempFile : TempFiles) {
2249 if (llvm::sys::fs::is_directory(TempFile)) {
2251 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2252 I != E && !EC; I.increment(EC)) {
2253 if (llvm::sys::fs::is_regular_file(I->path())) {
2254 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2258 llvm::sys::path::filename(TempFile);
2259 StringRef SubPath = I->path();
2260 if (SubPath.consume_front(TempFile)) {
2261 if (!SubPath.empty() &&
2262 llvm::sys::path::is_separator(SubPath.front())) {
2263 SubPath = SubPath.drop_front();
2265 llvm::sys::path::append(PathInTar, SubPath);
2266 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2269 Diag(clang::diag::note_drv_command_failed_diag_msg)
2270 << (std::string(
"Error reading file for tarball: ") +
2276 Diag(clang::diag::note_drv_command_failed_diag_msg)
2277 << (std::string(
"Error iterating directory for tarball: ") +
2278 TempFile +
" " + EC.message());
2281 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2283 Tar->append(llvm::sys::path::filename(TempFile),
2284 (*BufferOrErr)->getBuffer());
2286 Diag(clang::diag::note_drv_command_failed_diag_msg)
2287 << (std::string(
"Error reading file for tarball: ") + TempFile);
2291 Diag(clang::diag::note_drv_command_failed_diag_msg)
2292 << CrashDiagnosticsTar;
2297 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2299 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2300 Diag(clang::diag::note_drv_command_failed_diag_msg)
2301 << ReproCrashFilename.str();
2303 llvm::sys::path::append(CrashDiagDir,
Name);
2304 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2305 Diag(clang::diag::note_drv_command_failed_diag_msg)
2306 <<
"Crash backtrace is located in";
2307 Diag(clang::diag::note_drv_command_failed_diag_msg)
2308 << CrashDiagDir.str();
2309 Diag(clang::diag::note_drv_command_failed_diag_msg)
2310 <<
"(choose the .crash file that corresponds to your crash)";
2314 Diag(clang::diag::note_drv_command_failed_diag_msg)
2315 <<
"\n\n********************";
2325 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2336 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2337 if (
C.getArgs().hasArg(options::OPT_v))
2338 C.getJobs().Print(llvm::errs(),
"\n",
true);
2340 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2343 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2350 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2351 C.getJobs().Print(llvm::errs(),
"\n",
true);
2352 return Diags.hasErrorOccurred() ? 1 : 0;
2356 if (Diags.hasErrorOccurred())
2360 for (
auto &Job :
C.getJobs())
2361 setUpResponseFiles(
C, Job);
2363 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2366 if (FailingCommands.empty())
2372 for (
const auto &CmdPair : FailingCommands) {
2373 int CommandRes = CmdPair.first;
2374 const Command *FailingCommand = CmdPair.second;
2379 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2383 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2388 if (CommandRes == EX_IOERR) {
2408 if (CommandRes > 128 && CommandRes != 255)
2412 Diag(clang::diag::err_drv_command_signalled)
2415 Diag(clang::diag::err_drv_command_failed)
2423 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2425 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2439 const ToolChain &TC =
C.getDefaultToolChain();
2443 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2446 OS <<
"Thread model: " << A->getValue();
2452 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2457 if (!llvm::cl::getCompilerBuildConfig().empty())
2458 llvm::cl::printBuildConfig(OS);
2461 for (
auto ConfigFile : ConfigFiles)
2462 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2475 if (PassedFlags ==
"")
2479 std::vector<std::string> SuggestedCompletions;
2480 std::vector<std::string> Flags;
2492 const bool HasSpace = PassedFlags.ends_with(
",");
2496 StringRef TargetFlags = PassedFlags;
2497 while (TargetFlags !=
"") {
2499 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2500 Flags.push_back(std::string(CurFlag));
2505 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2508 const llvm::opt::OptTable &Opts =
getOpts();
2510 Cur = Flags.at(Flags.size() - 1);
2512 if (Flags.size() >= 2) {
2513 Prev = Flags.at(Flags.size() - 2);
2514 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2517 if (SuggestedCompletions.empty())
2518 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2525 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2526 llvm::outs() <<
'\n';
2532 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2536 SuggestedCompletions = Opts.findByPrefix(
2537 Cur, VisibilityMask,
2544 if (S.starts_with(Cur))
2545 SuggestedCompletions.push_back(std::string(S));
2552 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2553 if (
int X = A.compare_insensitive(B))
2555 return A.compare(B) > 0;
2558 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2565 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2566 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2570 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2573 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2577 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2582 if (
C.getArgs().hasArg(options::OPT_help) ||
2583 C.getArgs().hasArg(options::OPT__help_hidden)) {
2584 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2588 if (
C.getArgs().hasArg(options::OPT__version)) {
2595 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2596 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2597 if (ListExtractors || ListFormats) {
2605 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2610 if (
C.getArgs().hasArg(options::OPT_v) ||
2611 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2612 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2613 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2614 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2616 SuppressMissingInputWarning =
true;
2619 if (
C.getArgs().hasArg(options::OPT_v)) {
2621 llvm::errs() <<
"System configuration file directory: "
2624 llvm::errs() <<
"User configuration file directory: "
2628 const ToolChain &TC =
C.getDefaultToolChain();
2630 if (
C.getArgs().hasArg(options::OPT_v))
2633 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2638 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2639 llvm::outs() <<
"programs: =";
2640 bool separator =
false;
2644 llvm::outs() << llvm::sys::EnvPathSeparator;
2645 llvm::outs() << Path;
2650 llvm::outs() << llvm::sys::EnvPathSeparator;
2651 llvm::outs() << Path;
2654 llvm::outs() <<
"\n";
2657 StringRef sysroot =
C.getSysRoot();
2661 llvm::outs() << llvm::sys::EnvPathSeparator;
2664 llvm::outs() << sysroot << Path.substr(1);
2666 llvm::outs() << Path;
2668 llvm::outs() <<
"\n";
2672 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2678 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2679 for (
auto RuntimePath :
2681 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2682 llvm::outs() << *RuntimePath <<
'\n';
2686 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2690 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2692 for (std::size_t I = 0; I != Flags.size(); I += 2)
2693 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2699 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2700 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2704 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2705 StringRef ProgName = A->getValue();
2708 if (! ProgName.empty())
2711 llvm::outs() <<
"\n";
2715 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2716 StringRef PassedFlags = A->getValue();
2721 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2735 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2738 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2744 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2751 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2754 std::set<llvm::StringRef> SortedFlags;
2755 for (
const auto &FlagEntry : ExpandedFlags)
2756 SortedFlags.insert(FlagEntry.getKey());
2757 for (
auto Flag : SortedFlags)
2758 llvm::outs() << Flag <<
'\n';
2762 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2765 llvm::outs() <<
".\n";
2768 assert(Suffix.front() ==
'/');
2769 llvm::outs() << Suffix.substr(1) <<
"\n";
2775 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2780 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2782 llvm::outs() << Triple.getTriple() <<
"\n";
2786 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2787 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2804 std::map<Action *, unsigned> &Ids,
2806 if (
auto It = Ids.find(A); It != Ids.end())
2810 llvm::raw_string_ostream os(str);
2812 auto getSibIndent = [](
int K) -> Twine {
2816 Twine SibIndent =
Indent + getSibIndent(Kind);
2820 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2822 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2823 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2824 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2826 OA->doOnEachDependence(
2828 assert(TC &&
"Unknown host toolchain");
2840 os <<
":" << BoundArch;
2843 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2851 const char *Prefix =
"{";
2852 for (
Action *PreRequisite : *AL) {
2853 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2864 std::string offload_str;
2865 llvm::raw_string_ostream offload_os(offload_str);
2869 offload_os <<
", (" << S;
2876 auto getSelfIndent = [](
int K) -> Twine {
2880 unsigned Id = Ids.size();
2882 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2891 std::map<Action *, unsigned> Ids;
2892 for (
Action *A :
C.getActions())
2908 DerivedArgList &Args =
C.getArgs();
2910 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2915 for (Arg *A : Args) {
2916 if (A->getOption().matches(options::OPT_arch)) {
2919 llvm::Triple::ArchType
Arch =
2921 if (
Arch == llvm::Triple::UnknownArch) {
2922 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2927 if (
ArchNames.insert(A->getValue()).second)
2928 Archs.push_back(A->getValue());
2942 for (
Action* Act : SingleActions) {
2950 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2954 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2959 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2960 Actions.append(Inputs.begin(), Inputs.end());
2962 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2965 Arg *A = Args.getLastArg(options::OPT_g_Group);
2966 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2967 !A->getOption().matches(options::OPT_gstabs);
2968 bool enablesPseudoProbe =
2969 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2970 options::OPT_fno_pseudo_probe_for_profiling,
false);
2971 bool enablesDebugInfoForProfiling =
2972 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2973 options::OPT_fno_debug_info_for_profiling,
false);
2974 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2975 enablesDebugInfoForProfiling) &&
2983 if (Act->getType() == types::TY_Image) {
2985 Inputs.push_back(Actions.back());
2992 if (Args.hasArg(options::OPT_verify_debug_info)) {
2993 Action *LastAction = Actions.pop_back_val();
2995 LastAction, types::TY_Nothing));
3002 bool TypoCorrect)
const {
3014 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3015 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3027 std::string Nearest;
3028 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3029 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3030 <<
Value << Nearest;
3069 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3072 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3080 return types::TY_CXXUHeader;
3082 return types::TY_CXXSHeader;
3086 llvm_unreachable(
"should not be called in this case");
3088 return types::TY_CXXHUHeader;
3094 const llvm::opt::OptTable &Opts =
getOpts();
3098 types::ID InputType = types::TY_Nothing;
3099 Arg *InputTypeArg =
nullptr;
3102 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3103 options::OPT__SLASH_TP)) {
3104 InputTypeArg = TCTP;
3105 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3110 bool ShowNote =
false;
3112 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3114 Diag(clang::diag::warn_drv_overriding_option)
3115 <<
Previous->getSpelling() << A->getSpelling();
3121 Diag(clang::diag::note_drv_t_option_is_global);
3126 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3127 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3128 if (LastXArg && LastInputArg &&
3129 LastInputArg->getIndex() < LastXArg->getIndex())
3130 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3133 for (Arg *A : Args) {
3134 if (A->getOption().
getKind() == Option::InputClass) {
3135 const char *
Value = A->getValue();
3139 if (InputType == types::TY_Nothing) {
3142 InputTypeArg->claim();
3145 if (strcmp(
Value,
"-") == 0) {
3147 Ty = types::TY_Fortran;
3149 Ty = types::TY_HLSL;
3158 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3159 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3160 : clang::diag::err_drv_unknown_stdin_type);
3169 if (
const char *Ext = strrchr(
Value,
'.'))
3178 Ty = types::TY_HLSL;
3180 Ty = types::TY_Object;
3191 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3192 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3193 << getTypeName(OldTy) << getTypeName(Ty);
3198 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3199 Ty == types::TY_Object)
3200 Ty = types::TY_LLVM_BC;
3208 if (Ty != types::TY_Object) {
3209 if (Args.hasArg(options::OPT_ObjC))
3210 Ty = types::TY_ObjC;
3211 else if (Args.hasArg(options::OPT_ObjCXX))
3212 Ty = types::TY_ObjCXX;
3219 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3223 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3224 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3227 const char *Ext = strrchr(
Value,
'.');
3229 Ty = types::TY_Object;
3233 InputTypeArg->claim();
3237 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3238 Args.hasArgNoClaim(options::OPT_hipstdpar))
3242 Inputs.push_back(std::make_pair(Ty, A));
3244 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3245 StringRef
Value = A->getValue();
3248 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3249 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3252 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3253 StringRef
Value = A->getValue();
3256 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3257 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3263 Inputs.push_back(std::make_pair(types::TY_Object, A));
3265 }
else if (A->getOption().matches(options::OPT_x)) {
3274 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3275 InputType = types::TY_Object;
3282 }
else if (A->getOption().getID() == options::OPT_U) {
3283 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3284 StringRef Val = A->getValue(0);
3285 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3287 Diag(diag::warn_slash_u_filename) << Val;
3288 Diag(diag::note_use_dashdash);
3292 if (
CCCIsCPP() && Inputs.empty()) {
3296 Inputs.push_back(std::make_pair(types::TY_C, A));
3303class OffloadingActionBuilder final {
3305 bool IsValid =
false;
3311 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3314 std::map<Action *, const Arg *> HostActionToInputArgMap;
3317 class DeviceActionBuilder {
3321 enum ActionBuilderReturnCode {
3339 const ToolChain *FatBinaryToolChain =
nullptr;
3342 DerivedArgList &Args;
3351 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3354 :
C(
C), Args(Args), Inputs(Inputs),
3355 AssociatedOffloadKind(AssociatedOffloadKind) {}
3356 virtual ~DeviceActionBuilder() {}
3361 virtual ActionBuilderReturnCode
3362 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3365 return ABRT_Inactive;
3370 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3371 return ABRT_Inactive;
3375 virtual void appendTopLevelActions(
ActionList &AL) {}
3378 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3381 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3384 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3391 virtual bool canUseBundlerUnbundler()
const {
return false; }
3395 bool isValid() {
return !ToolChains.empty(); }
3399 return AssociatedOffloadKind;
3405 class CudaActionBuilderBase :
public DeviceActionBuilder {
3409 bool CompileHostOnly =
false;
3410 bool CompileDeviceOnly =
false;
3412 bool EmitAsm =
false;
3422 TargetID(
const char *ID) :
ID(
ID) {}
3423 operator const char *() {
return ID; }
3424 operator StringRef() {
return StringRef(ID); }
3427 SmallVector<TargetID, 4> GpuArchList;
3433 Action *CudaFatBinary =
nullptr;
3436 bool IsActive =
false;
3439 bool Relocatable =
false;
3442 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3445 const CUIDOptions &CUIDOpts;
3448 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3450 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3451 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3453 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3454 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3455 options::OPT_fno_gpu_rdc,
false);
3458 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3465 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3468 if (!(IA->getType() == types::TY_CUDA ||
3469 IA->getType() == types::TY_HIP ||
3470 IA->getType() == types::TY_PP_HIP)) {
3473 return ABRT_Inactive;
3480 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3482 if (CompileHostOnly)
3483 return ABRT_Success;
3486 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3487 : types::TY_CUDA_DEVICE;
3488 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3489 CudaDeviceActions.push_back(
3490 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3493 return ABRT_Success;
3497 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3501 if (UA->getType() == types::TY_Object && !Relocatable)
3502 return ABRT_Inactive;
3504 CudaDeviceActions.clear();
3506 std::string
FileName = IA->getInputArg().getAsString(Args);
3512 const StringRef LibFileExt =
".lib";
3513 if (IA->getType() == types::TY_Object &&
3514 (!llvm::sys::path::has_extension(
FileName) ||
3516 llvm::sys::path::extension(
FileName).drop_front()) !=
3518 llvm::sys::path::extension(
FileName) == LibFileExt))
3519 return ABRT_Inactive;
3521 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3522 CudaDeviceActions.push_back(UA);
3523 UA->registerDependentActionInfo(ToolChain,
Arch,
3524 AssociatedOffloadKind);
3527 return ABRT_Success;
3530 return IsActive ? ABRT_Success : ABRT_Inactive;
3533 void appendTopLevelActions(
ActionList &AL)
override {
3535 auto AddTopLevel = [&](Action *A, TargetID TargetID,
3536 const ToolChain *TC) {
3537 OffloadAction::DeviceDependences Dep;
3538 Dep.
add(*A, *TC, TargetID, AssociatedOffloadKind);
3539 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3543 if (CudaFatBinary) {
3544 AddTopLevel(CudaFatBinary, OffloadArch::Unused, FatBinaryToolChain);
3545 CudaDeviceActions.clear();
3546 CudaFatBinary =
nullptr;
3550 if (CudaDeviceActions.empty())
3556 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3557 "Expecting one action per GPU architecture.");
3558 assert(ToolChains.size() == GpuArchList.size() &&
3559 "Expecting to have a toolchain per GPU architecture");
3560 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3561 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3563 CudaDeviceActions.clear();
3566 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3584 assert(HostTC &&
"No toolchain for host compilation.");
3589 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3594 std::set<std::pair<StringRef, const ToolChain *>> GpuArchs;
3596 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3598 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3599 GpuArchs.insert({
Arch, I.second});
3603 for (
auto [
Arch, TC] : GpuArchs) {
3604 GpuArchList.push_back(
Arch.data());
3605 ToolChains.push_back(TC);
3608 FatBinaryToolChain = ToolChains.front();
3609 CompileHostOnly =
C.getDriver().offloadHostOnly();
3610 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3611 EmitAsm = Args.getLastArg(options::OPT_S);
3619 class CudaActionBuilder final :
public CudaActionBuilderBase {
3621 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3623 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3624 DefaultOffloadArch = OffloadArch::CudaDefault;
3627 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3629 const std::set<StringRef> &GpuArchs)
override {
3630 return std::nullopt;
3633 ActionBuilderReturnCode
3634 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3636 PhasesTy &Phases)
override {
3638 return ABRT_Inactive;
3642 if (CudaDeviceActions.empty())
3643 return ABRT_Success;
3645 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3646 "Expecting one action per GPU architecture.");
3647 assert(!CompileHostOnly &&
3648 "Not expecting CUDA actions in host-only compilation.");
3658 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3661 for (
auto Ph : Phases) {
3666 if (Ph > FinalPhase)
3669 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3684 Action *AssembleAction = CudaDeviceActions[I];
3685 assert(AssembleAction->
getType() == types::TY_Object);
3686 assert(AssembleAction->
getInputs().size() == 1);
3692 OffloadAction::DeviceDependences DDep;
3694 DeviceActions.push_back(
3695 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3700 if (!DeviceActions.empty()) {
3702 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3704 if (!CompileDeviceOnly) {
3705 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3709 CudaFatBinary =
nullptr;
3714 CudaDeviceActions.clear();
3718 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3723 return ABRT_Success;
3727 "instructions should only occur "
3728 "before the backend phase!");
3731 for (Action *&A : CudaDeviceActions)
3732 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3734 return ABRT_Success;
3739 class HIPActionBuilder final :
public CudaActionBuilderBase {
3741 SmallVector<ActionList, 8> DeviceLinkerInputs;
3747 std::optional<bool> BundleOutput;
3748 std::optional<bool> EmitReloc;
3751 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3753 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3755 DefaultOffloadArch = OffloadArch::HIPDefault;
3757 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3758 options::OPT_fno_hip_emit_relocatable)) {
3759 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3760 options::OPT_fno_hip_emit_relocatable, false);
3764 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3765 <<
"-fhip-emit-relocatable"
3769 if (!CompileDeviceOnly) {
3770 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3771 <<
"-fhip-emit-relocatable"
3772 <<
"--offload-device-only";
3777 if (Args.hasArg(options::OPT_gpu_bundle_output,
3778 options::OPT_no_gpu_bundle_output))
3779 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3780 options::OPT_no_gpu_bundle_output,
true) &&
3781 (!EmitReloc || !*EmitReloc);
3784 bool canUseBundlerUnbundler()
const override {
return true; }
3786 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3788 const std::set<StringRef> &GpuArchs)
override {
3792 ActionBuilderReturnCode
3793 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3795 PhasesTy &Phases)
override {
3797 return ABRT_Inactive;
3803 if (CudaDeviceActions.empty())
3804 return ABRT_Success;
3807 CudaDeviceActions.size() == GpuArchList.size()) &&
3808 "Expecting one action per GPU architecture.");
3809 assert(!CompileHostOnly &&
3810 "Not expecting HIP actions in host-only compilation.");
3812 bool ShouldLink = !EmitReloc || !*EmitReloc;
3815 !EmitAsm && ShouldLink) {
3821 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3822 if (ToolChains[I]->isUsingLTO(Args, AssociatedOffloadKind)) {
3826 AL.push_back(CudaDeviceActions[I]);
3829 CudaDeviceActions[I] =
3830 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3836 if (ToolChains[I]->
getTriple().isSPIRV() ||
3837 (ToolChains[I]->
getTriple().isAMDGCN() &&
3838 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3842 types::ID Output = Args.hasArg(options::OPT_S)
3844 : types::TY_LLVM_BC;
3846 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3849 ToolChains[I]->getLTOMode(Args, AssociatedOffloadKind);
3852 AssociatedOffloadKind, DevLTO);
3854 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3856 AssociatedOffloadKind);
3857 AL.push_back(AssembleAction);
3860 CudaDeviceActions[I] =
3861 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3870 OffloadAction::DeviceDependences DDep;
3871 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3872 AssociatedOffloadKind);
3873 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3874 DDep, CudaDeviceActions[I]->getType());
3877 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3879 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3880 types::TY_HIP_FATBIN);
3882 if (!CompileDeviceOnly) {
3883 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3884 AssociatedOffloadKind);
3887 CudaFatBinary =
nullptr;
3892 CudaDeviceActions.clear();
3895 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3898 return ABRT_Success;
3904 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3905 auto LI = DeviceLinkerInputs.begin();
3906 for (
auto *A : CudaDeviceActions) {
3913 CudaDeviceActions.clear();
3914 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3918 for (
unsigned I = 0, E = CudaDeviceActions.size(); I != E; ++I)
3919 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3920 C, Args, CurPhase, CudaDeviceActions[I], AssociatedOffloadKind,
3921 ToolChains[I]->getLTOMode(Args, AssociatedOffloadKind));
3923 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3925 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3926 OffloadAction::DeviceDependences DDep;
3927 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3928 AssociatedOffloadKind);
3929 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3930 DDep, CudaDeviceActions[I]->getType());
3933 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3934 CudaDeviceActions.clear();
3937 return (CompileDeviceOnly &&
3938 (CurPhase == FinalPhase ||
3944 void appendLinkDeviceActions(
ActionList &AL)
override {
3945 if (DeviceLinkerInputs.size() == 0)
3948 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3949 "Linker inputs and GPU arch list sizes do not match.");
3955 for (
auto &LI : DeviceLinkerInputs) {
3957 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3961 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3964 OffloadAction::DeviceDependences DeviceLinkDeps;
3965 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3966 AssociatedOffloadKind);
3967 Actions.push_back(
C.MakeAction<OffloadAction>(
3968 DeviceLinkDeps, DeviceLinkAction->getType()));
3971 DeviceLinkerInputs.clear();
3974 if (Args.hasArg(options::OPT_emit_llvm)) {
3982 OffloadAction::DeviceDependences DDeps;
3983 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3984 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3986 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3987 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain,
nullptr,
3988 AssociatedOffloadKind);
3991 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3997 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3999 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
4007 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
4013 bool ShouldUseBundler;
4016 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
4024 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
4027 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4035 unsigned ValidBuilders = 0u;
4036 unsigned ValidBuildersSupportingBundling = 0u;
4037 for (
auto *SB : SpecializedBuilders) {
4038 IsValid = IsValid && !SB->initialize();
4041 if (SB->isValid()) {
4043 if (SB->canUseBundlerUnbundler())
4044 ++ValidBuildersSupportingBundling;
4048 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4050 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4051 options::OPT_no_gpu_bundle_output,
true);
4054 ~OffloadingActionBuilder() {
4055 for (
auto *SB : SpecializedBuilders)
4060 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4061 assert(HostAction &&
"Invalid host action");
4062 assert(InputArg &&
"Invalid input argument");
4063 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4064 assert(Loc->second == InputArg &&
4065 "host action mapped to multiple input arguments");
4074 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4076 DeviceActionBuilder::PhasesTy &Phases) {
4080 if (SpecializedBuilders.empty())
4083 assert(HostAction &&
"Invalid host action!");
4084 recordHostAction(HostAction, InputArg);
4089 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4090 unsigned InactiveBuilders = 0u;
4091 unsigned IgnoringBuilders = 0u;
4092 for (
auto *SB : SpecializedBuilders) {
4093 if (!SB->isValid()) {
4098 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4103 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4108 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4109 OffloadKind |= SB->getAssociatedOffloadKind();
4114 if (IgnoringBuilders &&
4115 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4132 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4133 const Arg *InputArg) {
4137 recordHostAction(HostAction, InputArg);
4146 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4148 HostAction->
getType() == types::TY_PP_HIP)) {
4149 auto UnbundlingHostAction =
4154 HostAction = UnbundlingHostAction;
4155 recordHostAction(HostAction, InputArg);
4158 assert(HostAction &&
"Invalid host action!");
4161 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4162 for (
auto *SB : SpecializedBuilders) {
4166 auto RetCode = SB->addDeviceDependences(HostAction);
4170 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4171 "Host dependence not expected to be ignored.!");
4175 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4176 OffloadKind |= SB->getAssociatedOffloadKind();
4181 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4191 const Arg *InputArg) {
4193 recordHostAction(HostAction, InputArg);
4197 for (
auto *SB : SpecializedBuilders) {
4200 SB->appendTopLevelActions(OffloadAL);
4207 if (CanUseBundler && ShouldUseBundler && HostAction &&
4208 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4210 OffloadAL.push_back(HostAction);
4214 assert(HostAction == AL.back() &&
"Host action not in the list??");
4216 recordHostAction(HostAction, InputArg);
4217 AL.back() = HostAction;
4219 AL.append(OffloadAL.begin(), OffloadAL.end());
4229 void appendDeviceLinkActions(
ActionList &AL) {
4230 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4233 SB->appendLinkDeviceActions(AL);
4237 Action *makeHostLinkAction() {
4240 appendDeviceLinkActions(DeviceAL);
4241 if (DeviceAL.empty())
4246 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4249 HA = SB->appendLinkHostActions(DeviceAL);
4266 for (
auto *SB : SpecializedBuilders) {
4270 SB->appendLinkDependences(DDeps);
4274 unsigned ActiveOffloadKinds = 0u;
4275 for (
auto &I : InputArgToOffloadKindMap)
4276 ActiveOffloadKinds |= I.second;
4288 for (
auto *A : HostAction->
inputs()) {
4289 auto ArgLoc = HostActionToInputArgMap.find(A);
4290 if (ArgLoc == HostActionToInputArgMap.end())
4292 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4293 if (OFKLoc == InputArgToOffloadKindMap.end())
4305 nullptr, ActiveOffloadKinds);
4311void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4316 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4317 StringRef
V = A->getValue();
4318 if (Inputs.size() > 1 && !
V.empty() &&
4319 !llvm::sys::path::is_separator(
V.back())) {
4321 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4322 << A->getSpelling() <<
V;
4323 Args.eraseArg(options::OPT__SLASH_Fo);
4328 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4329 StringRef
V = A->getValue();
4330 if (Inputs.size() > 1 && !
V.empty() &&
4331 !llvm::sys::path::is_separator(
V.back())) {
4333 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4334 << A->getSpelling() <<
V;
4335 Args.eraseArg(options::OPT__SLASH_Fa);
4340 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4341 if (A->getValue()[0] ==
'\0') {
4343 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4344 Args.eraseArg(options::OPT__SLASH_o);
4349 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4350 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4351 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4352 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4353 Args.eraseArg(options::OPT__SLASH_Yc);
4354 Args.eraseArg(options::OPT__SLASH_Yu);
4355 YcArg = YuArg =
nullptr;
4357 if (YcArg && Inputs.size() > 1) {
4358 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4359 Args.eraseArg(options::OPT__SLASH_Yc);
4367 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4368 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4369 Args.AddFlagArg(
nullptr,
4370 getOpts().getOption(options::OPT_frtlib_add_rpath));
4374 if (Args.hasArg(options::OPT_emit_llvm) &&
4375 !Args.hasArg(options::OPT_hip_link) &&
4376 !
C.getDefaultToolChain().getTriple().isSPIRV())
4377 Diag(clang::diag::err_drv_emit_llvm_link);
4378 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4379 C.getDefaultToolChain().isUsingLTO(Args) &&
4380 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4381 .starts_with_insensitive(
"lld"))
4382 Diag(clang::diag::err_drv_lto_without_lld);
4388 if (!Args.hasArg(options::OPT_dumpdir)) {
4389 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4390 Arg *Arg = Args.MakeSeparateArg(
4391 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4393 (FinalOutput ? FinalOutput->getValue()
4405 Args.eraseArg(options::OPT__SLASH_Fp);
4406 Args.eraseArg(options::OPT__SLASH_Yc);
4407 Args.eraseArg(options::OPT__SLASH_Yu);
4408 YcArg = YuArg =
nullptr;
4411 if (Args.hasArg(options::OPT_include_pch) &&
4412 Args.hasArg(options::OPT_ignore_pch)) {
4416 Args.eraseArg(options::OPT_include_pch);
4419 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4420 for (
auto &I : Inputs) {
4422 const Arg *InputArg = I.second;
4427 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4431 if (InitialPhase > FinalPhase) {
4432 if (InputArg->isClaimed())
4439 if (Args.hasArg(options::OPT_Qunused_arguments))
4445 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4446 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4450 (Args.getLastArg(options::OPT__SLASH_EP,
4451 options::OPT__SLASH_P) ||
4452 Args.getLastArg(options::OPT_E) ||
4453 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4455 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4456 << InputArg->getAsString(Args) << !!FinalPhaseArg
4457 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4459 Diag(clang::diag::warn_drv_input_file_unused)
4460 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4462 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4471 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4472 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
4477 Actions.push_back(ClangClPch);
4489 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4490 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4499 const llvm::opt::DerivedArgList &Args,
4502 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4504 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4507 bool HasAMDGCNHIPDevice =
false;
4509 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4511 const llvm::Triple &Tr = TC->
getTriple();
4514 HasAMDGCNHIPDevice =
true;
4516 return HasAMDGCNHIPDevice;
4521 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4523 if (!SuppressMissingInputWarning && Inputs.empty()) {
4524 Diag(clang::diag::err_drv_no_input_files);
4528 handleArguments(
C, Args, Inputs, Actions);
4530 bool UseNewOffloadingDriver = Args.hasFlag(
4531 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4535 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4536 !UseNewOffloadingDriver
4537 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4545 for (
auto &I : Inputs) {
4547 const Arg *InputArg = I.second;
4560 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4568 if (!UseNewOffloadingDriver)
4569 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4575 if (!UseNewOffloadingDriver)
4576 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4577 Current, InputArg, Phase, PL.back(), FullPL);
4583 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4586 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4587 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4589 LinkerInputs.push_back(Current);
4599 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4600 MergerInputs.push_back(Current);
4617 C.getDefaultToolChain().getLTOMode(Args));
4620 if (NewCurrent == Current)
4623 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4626 Current = NewCurrent;
4630 if (UseNewOffloadingDriver)
4632 &HIPAsmDeviceActions);
4635 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4639 if (Current->
getType() == types::TY_Nothing)
4645 if (Current && !HIPAsmDeviceActions.empty()) {
4646 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4648 BundleInputs.append(HIPAsmDeviceActions);
4649 BundleInputs.push_back(Current);
4655 Actions.push_back(Current);
4658 if (!UseNewOffloadingDriver)
4659 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4667 if (LinkerInputs.empty()) {
4670 if (!UseNewOffloadingDriver)
4671 OffloadBuilder->appendDeviceLinkActions(Actions);
4674 if (!LinkerInputs.empty()) {
4675 if (!UseNewOffloadingDriver)
4676 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4677 LinkerInputs.push_back(Wrapper);
4682 }
else if (UseNewOffloadingDriver ||
4683 Args.hasArg(options::OPT_offload_link)) {
4691 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4692 C.getDefaultToolChain().getTriple().isSPIRV();
4693 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4697 if (!UseNewOffloadingDriver)
4698 LA = OffloadBuilder->processHostLinkAction(LA);
4699 Actions.push_back(LA);
4703 if (!MergerInputs.empty())
4707 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4714 for (
auto &I : Inputs) {
4716 const Arg *InputArg = I.second;
4721 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4722 InputType == types::TY_Asm)
4727 for (
auto Phase : PhaseList) {
4731 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4736 if (InputType == types::TY_Object)
4743 assert(Phase == PhaseList.back() &&
4744 "merging must be final compilation step.");
4745 MergerInputs.push_back(Current);
4754 Actions.push_back(Current);
4758 if (!MergerInputs.empty())
4763 for (
auto Opt : {options::OPT_print_supported_cpus,
4764 options::OPT_print_supported_extensions,
4765 options::OPT_print_enabled_extensions}) {
4772 if (Arg *A = Args.getLastArg(Opt)) {
4773 if (Opt == options::OPT_print_supported_extensions &&
4774 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4775 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4776 !
C.getDefaultToolChain().getTriple().isARM()) {
4777 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4778 <<
"--print-supported-extensions";
4781 if (Opt == options::OPT_print_enabled_extensions &&
4782 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4783 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4784 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4785 <<
"--print-enabled-extensions";
4792 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4795 for (
auto &I : Inputs)
4800 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4801 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4802 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4808 if (TC.requiresObjcopy(Args)) {
4809 Action *LastAction = Actions.back();
4811 if (LastAction->
getType() == types::TY_Object)
4817 auto ValInfo = TC.getValidationInfo(Args);
4818 if (ValInfo.NeedsValidation) {
4819 Action *LastAction = Actions.back();
4820 if (LastAction->
getType() == types::TY_Object) {
4822 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4829 if (TC.requiresBinaryTranslation(Args)) {
4830 Action *LastAction = Actions.back();
4834 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4835 LastAction->
getType() == types::TY_Object)
4837 LastAction, types::TY_DX_CONTAINER));
4842 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4848 const llvm::opt::DerivedArgList &Args,
4850 const llvm::Triple &Triple) {
4855 if (Triple.isNVPTX() &&
4857 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4858 <<
"CUDA" << ArchStr;
4860 }
else if (Triple.isAMDGPU() &&
4862 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4863 <<
"HIP" << ArchStr;
4871 llvm::StringMap<bool> Features;
4874 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4886static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4888 llvm::Triple Triple) {
4889 if (!Triple.isAMDGPU())
4890 return std::nullopt;
4892 std::set<StringRef> ArchSet;
4893 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4897llvm::SmallVector<StringRef>
4901 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4902 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4903 options::OPT_no_offload_arch_EQ)) {
4904 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4906 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4908 :
"--no-offload-arch");
4911 llvm::DenseSet<StringRef> Archs;
4912 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4915 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4916 for (StringRef
Arch : Arg->getValues()) {
4917 if (
Arch ==
"native" ||
Arch.empty()) {
4922 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4926 for (
auto ArchStr : *GPUsOrErr) {
4928 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4929 if (!CanonicalStr.empty())
4930 Archs.insert(CanonicalStr);
4935 StringRef CanonicalStr =
4937 if (!CanonicalStr.empty())
4938 Archs.insert(CanonicalStr);
4943 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4944 for (StringRef
Arch : Arg->getValues()) {
4945 if (
Arch ==
"all") {
4950 Archs.erase(ArchStr);
4956 if (
auto ConflictingArchs =
4958 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4959 << ConflictingArchs->first << ConflictingArchs->second;
4962 if (Archs.empty()) {
4972 Archs.insert(StringRef());
4975 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4976 .getLastArg(options::OPT_march_EQ)) {
4977 Archs.insert(Arg->getValue());
4982 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4983 <<
"--offload-arch";
4984 }
else if (!ArchsOrErr->empty()) {
4985 for (
auto Arch : *ArchsOrErr)
4986 Archs.insert(Args.MakeArgStringRef(
Arch));
4988 Archs.insert(StringRef());
4993 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4994 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
5003 const InputTy &Input, StringRef CUID,
5013 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5015 bool HIPRelocatableObj =
5017 Args.hasFlag(options::OPT_fhip_emit_relocatable,
5018 options::OPT_fno_hip_emit_relocatable,
false);
5020 if (!HIPNoRDC && HIPRelocatableObj)
5021 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
5022 <<
"-fhip-emit-relocatable"
5026 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
5027 <<
"-fhip-emit-relocatable"
5028 <<
"--offload-device-only";
5046 auto TCRange =
C.getOffloadToolChains(Kind);
5047 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5048 ToolChains.push_back(TI->second);
5050 if (ToolChains.empty())
5054 const Arg *InputArg = Input.second;
5063 for (
const ToolChain *TC : ToolChains) {
5065 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5066 DeviceActions.push_back(
5067 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5071 if (DeviceActions.empty())
5077 HostAction->
getType() != types::TY_Nothing &&
5087 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5096 auto *TCAndArch = TCAndArchs.begin();
5097 for (
Action *&A : DeviceActions) {
5098 if (A->
getType() == types::TY_Nothing)
5105 TCAndArch->first->getLTOMode(Args, Kind));
5109 HostAction->
getType() != types::TY_Nothing) {
5116 TCAndArch->second.data(), Kind);
5118 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5128 for (
Action *&A : DeviceActions) {
5133 OffloadTriple && OffloadTriple->isSPIRV() &&
5134 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5135 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5136 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5137 options::OPT_no_use_spirv_backend,
5144 bool IsAMDGCNSPIRVWithBackend =
5145 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5148 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5149 A->
getType() != types::TY_LTO_BC) ||
5157 auto *TCAndArch = TCAndArchs.begin();
5158 for (
Action *A : DeviceActions) {
5159 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5161 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5166 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5168 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5177 bool ShouldBundleHIP =
5178 Args.hasFlag(options::OPT_gpu_bundle_output,
5179 options::OPT_no_gpu_bundle_output,
false) ||
5180 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5182 return A->
getType() != types::TY_Image;
5189 if (OffloadActions.empty())
5194 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5198 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5205 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5206 DDep.
add(*FatbinAction,
5209 }
else if (HIPNoRDC) {
5212 if (HIPAsmBundleDeviceOut &&
5214 for (
Action *OA : OffloadActions)
5215 HIPAsmBundleDeviceOut->push_back(OA);
5229 DDep.
add(*PackagerAction,
5238 nullptr,
C.getActiveOffloadKinds());
5247 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5248 return A->
getType() == types::TY_Nothing;
5252 nullptr, SingleDeviceOutput ? DDep : DDeps);
5253 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5259 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5269 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5275 llvm_unreachable(
"link action invalid here.");
5277 llvm_unreachable(
"ifsmerge action invalid here.");
5282 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5283 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5284 OutputTy = types::TY_Dependencies;
5289 if (!Args.hasFlag(options::OPT_frewrite_includes,
5290 options::OPT_fno_rewrite_includes,
false) &&
5291 !Args.hasFlag(options::OPT_frewrite_imports,
5292 options::OPT_fno_rewrite_imports,
false) &&
5293 !Args.hasFlag(options::OPT_fdirectives_only,
5294 options::OPT_fno_directives_only,
false) &&
5298 "Cannot preprocess this input type!");
5304 if (Args.hasArg(options::OPT_extract_api))
5309 if (Input->
getType() == types::TY_CXXStdModule ||
5310 Input->
getType() == types::TY_PP_CXXStdModule)
5312 Input, getPrecompiledType(Input->
getType()));
5320 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5321 (Input->
getType() == driver::types::TY_CXXModule ||
5322 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5323 !Args.getLastArg(options::OPT__precompile) &&
5324 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5329 "Cannot precompile this input type!");
5333 const char *ModName =
nullptr;
5334 if (OutputTy == types::TY_PCH) {
5335 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5336 ModName = A->getValue();
5338 OutputTy = types::TY_ModuleFile;
5341 if (Args.hasArg(options::OPT_fsyntax_only)) {
5343 OutputTy = types::TY_Nothing;
5349 if (Args.hasArg(options::OPT_fsyntax_only))
5351 if (Args.hasArg(options::OPT_rewrite_objc))
5353 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5355 types::TY_RewrittenLegacyObjC);
5356 if (Args.hasArg(options::OPT__analyze))
5358 if (Args.hasArg(options::OPT_emit_ast))
5360 if (Args.hasArg(options::OPT_emit_cir))
5362 if (Args.hasArg(options::OPT_module_file_info))
5364 if (Args.hasArg(options::OPT_verify_pch))
5366 if (Args.hasArg(options::OPT_extract_api))
5375 Args.hasFlag(options::OPT_offload_new_driver,
5376 options::OPT_no_offload_new_driver,
5379 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm)))
5384 if (!IsDeviceOffload) {
5386 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5387 !Args.hasArg(options::OPT_emit_llvm))
5388 Output = types::TY_PP_Asm;
5389 else if (Args.hasArg(options::OPT_S))
5390 Output = types::TY_LTO_IR;
5392 Output = types::TY_LTO_BC;
5396 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5399 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5400 options::OPT_no_use_spirv_backend,
5408 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5410 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5412 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5414 const ToolChain &DefaultToolChain =
C.getDefaultToolChain();
5415 const llvm::Triple &DefaultToolChainTriple = DefaultToolChain.
getTriple();
5420 bool EmitBitcodeForNonOffloadAMDSPIRV =
5421 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5422 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5423 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5425 if (Args.hasArg(options::OPT_emit_llvm) ||
5426 EmitBitcodeForNonOffloadAMDSPIRV ||
5432 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5433 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5435 (Args.hasFlag(options::OPT_offload_new_driver,
5436 options::OPT_no_offload_new_driver,
5438 !(Args.hasArg(options::OPT_S) &&
5439 !Args.hasArg(options::OPT_emit_llvm)) &&
5446 Args.hasArg(options::OPT_S) &&
5450 !Args.hasFlag(options::OPT_offload_new_driver,
5451 options::OPT_no_offload_new_driver,
5452 C.getActiveOffloadKinds() !=
5455 : types::TY_LLVM_BC;
5468 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5477 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5481 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5483 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5503 unsigned NumOutputs = 0;
5504 unsigned NumIfsOutputs = 0;
5505 for (
const Action *A :
C.getActions()) {
5515 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
5516 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
5519 if (A->
getType() != types::TY_Nothing &&
5521 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5523 0 == NumIfsOutputs++) ||
5528 A->
getType() == types::TY_Nothing &&
5529 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5530 NumOutputs += A->
size();
5533 if (NumOutputs > 1) {
5534 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5535 FinalOutput =
nullptr;
5539 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5543 if (RawTriple.isOSBinFormatMachO())
5544 for (
const Arg *A :
C.getArgs())
5545 if (A->getOption().matches(options::OPT_arch))
5549 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5550 for (
Action *A :
C.getActions()) {
5557 const char *LinkingOutput =
nullptr;
5560 LinkingOutput = FinalOutput->getValue();
5569 LinkingOutput, CachedResults,
5576 for (
auto &J :
C.getJobs())
5577 J.InProcess =
false;
5580 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5581 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5586 const char *LinkingOutput =
nullptr;
5588 LinkingOutput = FinalOutput->getValue();
5595 using namespace llvm;
5598 <<
"output=" << LinkingOutput;
5599 outs() <<
", total="
5600 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5602 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5603 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5607 llvm::raw_string_ostream Out(Buffer);
5608 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5611 llvm::sys::printArg(Out, LinkingOutput,
true);
5612 Out <<
',' << ProcStat->TotalTime.count() <<
','
5613 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5618 llvm::sys::fs::OF_Append |
5619 llvm::sys::fs::OF_Text);
5624 llvm::errs() <<
"ERROR: Cannot lock file "
5626 <<
toString(L.takeError()) <<
"\n";
5637 bool ReportUnusedArguments =
5638 !Diags.hasErrorOccurred() &&
5639 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5642 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5644 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5647 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5648 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5650 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5654 return strstr(J.getCreator().getShortName(),
"assembler");
5656 for (Arg *A :
C.getArgs()) {
5660 if (!A->isClaimed()) {
5666 const Option &Opt = A->getOption();
5667 if (Opt.getKind() == Option::FlagClass) {
5668 bool DuplicateClaimed =
false;
5670 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5671 if (AA->isClaimed()) {
5672 DuplicateClaimed =
true;
5677 if (DuplicateClaimed)
5683 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5685 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5690 !
C.getActions().empty()) {
5691 Diag(diag::err_drv_unsupported_opt_for_target)
5693 }
else if (ReportUnusedArguments) {
5694 Diag(clang::diag::warn_drv_unused_argument)
5695 << A->getAsString(
C.getArgs());
5705class ToolSelector final {
5716 bool IsHostSelector;
5727 bool CanBeCollapsed =
true) {
5729 if (Inputs.size() != 1)
5732 Action *CurAction = *Inputs.begin();
5733 if (CanBeCollapsed &&
5739 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5743 if (!IsHostSelector) {
5744 if (OA->hasSingleDeviceDependence(
true)) {
5746 OA->getSingleDeviceDependence(
true);
5747 if (CanBeCollapsed &&
5750 SavedOffloadAction.push_back(OA);
5751 return dyn_cast<JobAction>(CurAction);
5753 }
else if (OA->hasHostDependence()) {
5754 CurAction = OA->getHostDependence();
5755 if (CanBeCollapsed &&
5758 SavedOffloadAction.push_back(OA);
5759 return dyn_cast<JobAction>(CurAction);
5764 return dyn_cast<JobAction>(CurAction);
5768 bool canCollapseAssembleAction()
const {
5769 return TC.useIntegratedAs() && !SaveTemps &&
5770 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5771 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5772 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5773 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5777 bool canCollapsePreprocessorAction()
const {
5778 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5779 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5780 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5785 struct JobActionInfo final {
5787 const JobAction *JA =
nullptr;
5795 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5796 ArrayRef<JobActionInfo> &ActionInfo,
5797 unsigned ElementNum) {
5798 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5799 for (
unsigned I = 0; I < ElementNum; ++I)
5800 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5801 ActionInfo[I].SavedOffloadAction.end());
5814 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5817 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5819 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5820 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5821 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5822 if (!AJ || !BJ || !CJ)
5826 const Tool *T = TC.SelectTool(*CJ);
5839 const Tool *BT = TC.SelectTool(*BJ);
5847 Inputs = CJ->getInputs();
5848 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5852 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5855 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5857 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5858 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5863 const Tool *T = TC.SelectTool(*BJ);
5870 Inputs = BJ->getInputs();
5871 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5875 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5878 if (ActionInfo.size() < 2)
5880 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5881 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5885 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5886 for (
auto &Input : AI.JA->getInputs())
5897 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5898 if (SaveTemps && !InputIsBitcode)
5902 const Tool *T = TC.SelectTool(*CJ);
5915 Inputs = CJ->getInputs();
5916 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5925 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5933 for (Action *A : Inputs) {
5934 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5936 NewInputs.push_back(A);
5942 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5943 PreprocessJobOffloadActions.end());
5944 NewInputs.append(PJ->input_begin(), PJ->input_end());
5950 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5952 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5954 assert(BaseAction &&
"Invalid base action.");
5970 SmallVector<JobActionInfo, 5> ActionChain(1);
5971 ActionChain.back().JA = BaseAction;
5972 while (ActionChain.back().JA) {
5973 const Action *CurAction = ActionChain.back().JA;
5976 ActionChain.resize(ActionChain.size() + 1);
5977 JobActionInfo &AI = ActionChain.back();
5981 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5985 ActionChain.pop_back();
5993 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5994 CollapsedOffloadAction);
5996 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5998 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
6004 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
6016 StringRef BoundArch,
6018 std::string TriplePlusArch = TC->
getTriple().normalize();
6019 if (!BoundArch.empty()) {
6020 TriplePlusArch +=
"-";
6021 TriplePlusArch += BoundArch;
6023 TriplePlusArch +=
"-";
6025 return TriplePlusArch;
6030 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6031 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6034 std::pair<const Action *, std::string> ActionTC = {
6036 auto CachedResult = CachedResults.find(ActionTC);
6037 if (CachedResult != CachedResults.end()) {
6038 return CachedResult->second;
6041 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
6042 CachedResults, TargetDeviceOffloadKind);
6043 CachedResults[ActionTC] =
Result;
6048 const JobAction *JA,
const char *BaseInput,
6051 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6062 OffloadingPrefix +=
"-";
6063 OffloadingPrefix +=
Arch;
6066 C.getDriver().isSaveTempsEnabled()) {
6073 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6074 Path = A->getValue();
6075 if (llvm::sys::fs::is_directory(Path)) {
6077 ? llvm::sys::path::stem(
Result.getFilename())
6078 : llvm::sys::path::stem(BaseInput));
6079 Tmp += OffloadingPrefix;
6081 llvm::sys::path::append(Path, Tmp);
6084 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6087 Path = DumpDir->getValue();
6088 Path += llvm::sys::path::stem(BaseInput);
6089 Path += OffloadingPrefix;
6091 }
else if (!OffloadingPrefix.empty()) {
6095 TraceName += OffloadingPrefix;
6096 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6097 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6098 llvm::sys::path::append(Path, TraceName);
6101 Path =
Result.getFilename();
6102 llvm::sys::path::replace_extension(Path,
"json");
6105 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6106 C.addTimeTraceFile(ResultFile, JA);
6107 C.addResultFile(ResultFile, JA);
6112 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6113 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6116 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6120 StringRef SavedBoundArch =
C.getCurrentBoundArch();
6121 C.setCurrentBoundArch(BoundArch);
6122 auto RestoreBoundArch =
6123 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
6126 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6127 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6159 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6161 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6162 const char *DepBoundArch) {
6165 LinkingOutput, CachedResults,
6175 OA->doOnEachDependence(
6176 BuildingForOffloadDevice,
6177 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6179 C, DepA, DepTC, DepBoundArch,
false,
6180 !!DepBoundArch, LinkingOutput, CachedResults,
6184 A = BuildingForOffloadDevice
6185 ? OA->getSingleDeviceDependence(
true)
6186 : OA->getHostDependence();
6190 std::pair<const Action *, std::string> ActionTC = {
6191 OA->getHostDependence(),
6193 auto It = CachedResults.find(ActionTC);
6194 if (It != CachedResults.end()) {
6196 Inputs.append(OffloadDependencesInputInfo);
6201 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6204 const Arg &Input = IA->getInputArg();
6206 if (Input.getOption().matches(options::OPT_INPUT)) {
6207 const char *
Name = Input.getValue();
6210 return {InputInfo(A, &Input,
"")};
6213 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6214 const ToolChain *TC;
6217 if (!ArchName.empty())
6218 TC = &getToolChain(
C.getArgs(),
6220 C.getArgs(), ArchName));
6222 TC = &
C.getDefaultToolChain();
6225 MultipleArchs, LinkingOutput, CachedResults,
6226 TargetDeviceOffloadKind);
6237 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6240 return {InputInfo()};
6244 for (
const auto *OA : CollapsedOffloadActions)
6246 BuildingForOffloadDevice,
6247 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6249 C, DepA, DepTC, DepBoundArch,
false,
6250 !!DepBoundArch, LinkingOutput, CachedResults,
6256 for (
const Action *Input : Inputs) {
6260 bool SubJobAtTopLevel =
6263 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6268 const char *BaseInput = InputInfos[0].getBaseInput();
6269 for (
auto &Info : InputInfos) {
6270 if (Info.isFilename()) {
6271 BaseInput = Info.getBaseInput();
6278 if (JA->
getType() == types::TY_dSYM)
6279 BaseInput = InputInfos[0].getFilename();
6282 if (!OffloadDependencesInputInfo.empty())
6283 InputInfos.append(OffloadDependencesInputInfo.begin(),
6284 OffloadDependencesInputInfo.end());
6287 llvm::Triple EffectiveTriple;
6289 const ArgList &Args =
6291 if (InputInfos.size() != 1) {
6297 Args, BoundArch, InputInfos[0].getType()));
6299 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6304 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6308 for (
auto &UI : UA->getDependentActionsInfo()) {
6310 "Unbundling with no offloading??");
6317 UI.DependentOffloadKind,
6318 UI.DependentToolChain->getTriple().normalize(),
6320 auto CurI = InputInfo(
6329 UnbundlingResults.push_back(CurI);
6338 Arch = UI.DependentBoundArch;
6343 UI.DependentOffloadKind)}] = {
6349 std::pair<const Action *, std::string> ActionTC = {
6351 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6352 "Result does not exist??");
6353 Result = CachedResults[ActionTC].front();
6354 }
else if (JA->
getType() == types::TY_Nothing)
6355 Result = {InputInfo(A, BaseInput)};
6365 AtTopLevel, MultipleArchs,
6374 <<
'"' <<
" - \"" << T->
getName() <<
"\", inputs: [";
6375 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6376 llvm::errs() << InputInfos[i].getAsString();
6378 llvm::errs() <<
", ";
6380 if (UnbundlingResults.empty())
6381 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6383 llvm::errs() <<
"], outputs: [";
6384 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6385 llvm::errs() << UnbundlingResults[i].getAsString();
6387 llvm::errs() <<
", ";
6389 llvm::errs() <<
"] \n";
6392 if (UnbundlingResults.empty())
6396 Args, LinkingOutput);
6402 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6403 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6415 if (ArgValue.empty()) {
6417 Filename = BaseName;
6418 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6420 llvm::sys::path::append(Filename, BaseName);
6423 if (!llvm::sys::path::has_extension(ArgValue)) {
6428 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6433 llvm::sys::path::replace_extension(Filename, Extension);
6436 return Args.MakeArgString(Filename.c_str());
6451 StringRef Suffix,
bool MultipleArchs,
6452 StringRef BoundArch,
6453 bool NeedUniqueDirectory)
const {
6455 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6456 std::optional<std::string> CrashDirectory =
6458 ? std::string(A->getValue())
6459 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6460 if (CrashDirectory) {
6461 if (!
getVFS().exists(*CrashDirectory))
6462 llvm::sys::fs::create_directories(*CrashDirectory);
6464 llvm::sys::path::append(Path, Prefix);
6465 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6466 if (std::error_code EC =
6467 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6468 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6472 if (MultipleArchs && !BoundArch.empty()) {
6473 if (NeedUniqueDirectory) {
6475 llvm::sys::path::append(TmpName,
6476 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6486 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6501 const char *BaseInput) {
6503 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6504 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6509 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6513 const char *BaseInput,
6514 StringRef OrigBoundArch,
bool AtTopLevel,
6516 StringRef OffloadingPrefix)
const {
6519 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6521 auto CreateTempOutputPath = [&](StringRef Prefix) {
6522 const char *Suffix =
6527 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
6528 const bool NeedUniqueDirectory =
6531 Triple.isOSDarwin();
6533 NeedUniqueDirectory);
6538 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
6539 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
6540 StringRef Filename = llvm::sys::path::filename(BaseInput);
6541 StringRef Stem = llvm::sys::path::stem(Filename);
6542 return CreateTempOutputPath(Stem);
6547 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6548 return C.addResultFile(FinalOutput->getValue(), &JA);
6552 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6554 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6556 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6557 NameArg = A->getValue();
6558 return C.addResultFile(
6568 if (JA.
getType() == types::TY_ModuleFile &&
6569 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6573 if (JA.
getType() == types::TY_PP_Asm &&
6574 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6575 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6578 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6581 if ((JA.
getType() == types::TY_Object &&
6582 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6583 JA.
getType() == types::TY_DX_CONTAINER) {
6584 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6585 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6586 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6587 "expected DXIL or SPIR-V triple for HLSL output path");
6592 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6594 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6595 StringRef
Name = llvm::sys::path::filename(BaseInput);
6596 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6602 if (JA.
getType() == types::TY_PP_Asm &&
6603 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6604 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6606 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6607 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6608 return C.addResultFile(
6613 if (JA.
getType() == types::TY_API_INFO &&
6614 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6615 C.getArgs().hasArg(options::OPT_o))
6616 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6617 <<
C.getArgs().getLastArgValue(options::OPT_o);
6624 bool SpecifiedModuleOutput =
6625 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6626 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6627 if (MultipleArchs && SpecifiedModuleOutput)
6628 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6633 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6634 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6640 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6642 StringRef
Name = llvm::sys::path::filename(BaseInput);
6643 return CreateTempOutputPath(
Name.split(
'.').first);
6652 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6657 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6658 llvm::sys::path::filename(BasePath));
6659 BaseName = ExternalPath;
6661 BaseName = BasePath;
6663 BaseName = llvm::sys::path::filename(BasePath);
6666 const char *NamedOutput;
6668 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6669 JA.
getType() == types::TY_LLVM_BC ||
6670 JA.
getType() == types::TY_LLVM_IR) &&
6671 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6675 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6679 }
else if (JA.
getType() == types::TY_Image &&
6680 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6681 options::OPT__SLASH_o)) {
6685 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6689 }
else if (JA.
getType() == types::TY_Image) {
6699 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6700 options::OPT_fno_gpu_rdc,
false);
6702 if (UseOutExtension) {
6704 llvm::sys::path::replace_extension(Output,
"");
6706 Output += OffloadingPrefix;
6707 if (MultipleArchs && !BoundArch.empty()) {
6709 Output.append(BoundArch);
6711 if (UseOutExtension)
6713 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6716 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6717 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6718 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6721 .getLastArg(options::OPT__SLASH_o)
6726 const char *Suffix =
6728 assert(Suffix &&
"All types used for output should have a suffix.");
6730 std::string::size_type End = std::string::npos;
6732 End = BaseName.rfind(
'.');
6734 Suffixed += OffloadingPrefix;
6735 if (MultipleArchs && !BoundArch.empty()) {
6737 Suffixed.append(BoundArch);
6742 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6743 const llvm::opt::DerivedArgList &Args) {
6750 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6752 Args.hasFlag(options::OPT_offload_new_driver,
6753 options::OPT_no_offload_new_driver,
true))) ||
6760 bool IsLinkerWrapper =
6762 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6763 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6764 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6766 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6770 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6774 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6775 JA.
getType() != types::TY_PCH) {
6776 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6778 llvm::sys::path::remove_filename(TempPath);
6779 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6780 llvm::sys::path::append(TempPath, OutputFileName);
6781 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6787 bool SameFile =
false;
6789 llvm::sys::fs::current_path(
Result);
6790 llvm::sys::path::append(
Result, BaseName);
6791 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6794 StringRef
Name = llvm::sys::path::filename(BaseInput);
6795 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6799 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6805 llvm::sys::path::remove_filename(BasePath);
6806 if (BasePath.empty())
6807 BasePath = NamedOutput;
6809 llvm::sys::path::append(BasePath, NamedOutput);
6810 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6813 return C.addResultFile(NamedOutput, &JA);
6819 -> std::optional<std::string> {
6822 for (
const auto &
Dir : P) {
6826 llvm::sys::path::append(P,
Name);
6827 if (llvm::sys::fs::exists(Twine(P)))
6828 return std::string(P);
6830 return std::nullopt;
6837 llvm::sys::path::append(R,
Name);
6838 if (llvm::sys::fs::exists(Twine(R)))
6839 return std::string(R);
6842 llvm::sys::path::append(P,
Name);
6843 if (llvm::sys::fs::exists(Twine(P)))
6844 return std::string(P);
6848 if (std::optional<std::string> IntrPath =
6851 llvm::sys::path::append(P,
Name);
6852 if (llvm::sys::fs::exists(P))
6853 return std::string(P);
6858 llvm::sys::path::append(D,
"..",
Name);
6859 if (llvm::sys::fs::exists(Twine(D)))
6860 return std::string(D);
6869 llvm::sys::path::append(R2,
"..",
"..",
Name);
6870 if (llvm::sys::fs::exists(Twine(R2)))
6871 return std::string(R2);
6873 return std::string(
Name);
6876void Driver::generatePrefixedToolNames(
6880 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6881 Names.emplace_back(
Tool);
6885 llvm::sys::path::append(Dir, Name);
6886 if (llvm::sys::fs::can_execute(Twine(Dir)))
6888 llvm::sys::path::remove_filename(Dir);
6894 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6899 if (llvm::sys::fs::is_directory(PrefixDir)) {
6902 return std::string(P);
6905 if (llvm::sys::fs::can_execute(Twine(P)))
6906 return std::string(P);
6911 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6919 for (
const auto &Path : List) {
6922 return std::string(P);
6926 if (llvm::ErrorOr<std::string> P =
6927 llvm::sys::findProgramByName(TargetSpecificExecutable))
6931 return std::string(
Name);
6936 std::string error =
"<NOT PRESENT>";
6938 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6943 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6960 llvm::sys::path::remove_filename(path);
6961 llvm::sys::path::append(path,
"libc++.modules.json");
6962 if (TC.
getVFS().exists(path))
6963 return static_cast<std::string
>(path);
6968 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6971 return evaluate(
"libc++.a").value_or(error);
6975 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6979 llvm::sys::path::remove_filename(path);
6980 llvm::sys::path::append(path,
"libstdc++.modules.json");
6981 if (TC.
getVFS().exists(path))
6982 return static_cast<std::string
>(path);
6987 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6990 return evaluate(
"libstdc++.a").value_or(error);
6999 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
7001 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7005 return std::string(Path);
7010 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
7012 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7016 return std::string(Path);
7021 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
7025 Output = FpArg->getValue();
7029 if (!llvm::sys::path::has_extension(Output))
7032 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
7033 Output = YcArg->getValue();
7036 llvm::sys::path::replace_extension(Output,
".pch");
7038 return std::string(Output);
7041const ToolChain &Driver::getOffloadToolChain(
7043 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
7044 std::unique_ptr<ToolChain> &TC =
7045 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
7046 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
7048 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
7051 switch (
Target.getOS()) {
7052 case llvm::Triple::CUDA:
7053 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7056 case llvm::Triple::AMDHSA:
7058 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
7061 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
7070 switch (
Target.getArch()) {
7071 case llvm::Triple::spir:
7072 case llvm::Triple::spir64:
7073 case llvm::Triple::spirv:
7074 case llvm::Triple::spirv32:
7075 case llvm::Triple::spirv64:
7078 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
7082 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7086 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7090 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7104 return getToolChain(Args,
Target);
7108const ToolChain &Driver::getToolChain(
const ArgList &Args,
7109 const llvm::Triple &
Target)
const {
7111 auto &TC = ToolChains[
Target.str()];
7113 switch (
Target.getOS()) {
7114 case llvm::Triple::AIX:
7115 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7117 case llvm::Triple::Haiku:
7118 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7120 case llvm::Triple::Darwin:
7121 case llvm::Triple::MacOSX:
7122 case llvm::Triple::IOS:
7123 case llvm::Triple::TvOS:
7124 case llvm::Triple::WatchOS:
7125 case llvm::Triple::XROS:
7126 case llvm::Triple::DriverKit:
7127 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7129 case llvm::Triple::DragonFly:
7130 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7132 case llvm::Triple::OpenBSD:
7133 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7135 case llvm::Triple::NetBSD:
7136 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7138 case llvm::Triple::FreeBSD:
7140 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7143 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7145 case llvm::Triple::Linux:
7146 case llvm::Triple::ELFIAMCU:
7147 if (
Target.getArch() == llvm::Triple::hexagon)
7148 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7150 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7151 !
Target.hasEnvironment())
7152 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7155 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7157 else if (
Target.getArch() == llvm::Triple::ve)
7158 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7159 else if (
Target.isOHOSFamily())
7160 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7161 else if (
Target.isWALI())
7162 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7164 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7166 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7168 case llvm::Triple::Fuchsia:
7169 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7171 case llvm::Triple::Managarm:
7172 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7174 case llvm::Triple::Serenity:
7175 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7177 case llvm::Triple::Solaris:
7178 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7180 case llvm::Triple::CUDA:
7181 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7183 case llvm::Triple::AMDHSA: {
7184 if (
Target.getArch() == llvm::Triple::spirv64) {
7185 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7190 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7192 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7197 case llvm::Triple::AMDPAL:
7198 case llvm::Triple::Mesa3D:
7199 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7201 case llvm::Triple::UEFI:
7202 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7204 case llvm::Triple::Win32:
7205 switch (
Target.getEnvironment()) {
7207 if (
Target.isOSBinFormatELF())
7208 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7209 else if (
Target.isOSBinFormatMachO())
7210 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7212 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7214 case llvm::Triple::GNU:
7215 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7217 case llvm::Triple::Cygnus:
7218 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7220 case llvm::Triple::Itanium:
7221 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7224 case llvm::Triple::MSVC:
7225 case llvm::Triple::UnknownEnvironment:
7226 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7227 .starts_with_insensitive(
"bfd"))
7228 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7232 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7236 case llvm::Triple::PS4:
7237 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7239 case llvm::Triple::PS5:
7240 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7242 case llvm::Triple::Hurd:
7243 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7245 case llvm::Triple::LiteOS:
7246 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7248 case llvm::Triple::ZOS:
7249 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7251 case llvm::Triple::Vulkan:
7252 case llvm::Triple::ShaderModel:
7253 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7254 Target.getArch() == llvm::Triple::spirv64) &&
7256 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7258 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7260 case llvm::Triple::ChipStar:
7261 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7266 switch (
Target.getArch()) {
7267 case llvm::Triple::tce:
7268 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7270 case llvm::Triple::tcele:
7271 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7273 case llvm::Triple::tcele64:
7275 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7277 case llvm::Triple::hexagon:
7278 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7281 case llvm::Triple::lanai:
7282 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7284 case llvm::Triple::xcore:
7285 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7287 case llvm::Triple::wasm32:
7288 case llvm::Triple::wasm64:
7289 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7291 case llvm::Triple::avr:
7292 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7294 case llvm::Triple::msp430:
7295 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7297 case llvm::Triple::riscv32:
7298 case llvm::Triple::riscv64:
7299 case llvm::Triple::riscv32be:
7300 case llvm::Triple::riscv64be:
7301 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7303 case llvm::Triple::ve:
7304 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7306 case llvm::Triple::spirv32:
7307 case llvm::Triple::spirv64:
7308 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7310 case llvm::Triple::csky:
7311 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7313 case llvm::Triple::amdgcn:
7314 case llvm::Triple::r600:
7315 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7319 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7320 else if (
Target.isOSBinFormatELF())
7321 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7322 else if (
Target.isAppleFirmware())
7323 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7324 else if (
Target.isAppleMachO())
7325 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7326 else if (
Target.isOSBinFormatMachO())
7327 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7329 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7339 if (JA.
size() != 1 ||
7354 if (JA.
size() != 1 ||
7368 if (Args.hasArg(options::OPT_emit_static_lib))
7379 unsigned &Micro,
bool &HadExtra) {
7382 Major = Minor = Micro = 0;
7386 if (Str.consumeInteger(10, Major))
7390 if (!Str.consume_front(
"."))
7393 if (Str.consumeInteger(10, Minor))
7397 if (!Str.consume_front(
"."))
7400 if (Str.consumeInteger(10, Micro))
7418 unsigned CurDigit = 0;
7419 while (CurDigit < Digits.size()) {
7421 if (Str.consumeInteger(10, Digit))
7423 Digits[CurDigit] = Digit;
7426 if (!Str.consume_front(
"."))
7435llvm::opt::Visibility
7436Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7449const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7465 llvm_unreachable(
"Unhandled Mode");
7469 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7474 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7475 options::OPT_fno_save_optimization_record,
false))
7479 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7480 options::OPT_fno_save_optimization_record,
false))
7484 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7485 options::OPT_fno_save_optimization_record,
false))
7489 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7490 options::OPT_fno_save_optimization_record,
false))
7497 static StringRef OptName =
7499 llvm::StringRef Opt;
7500 for (StringRef Arg : Args) {
7501 if (!Arg.starts_with(OptName))
7507 return Opt.consume_front(OptName) ? Opt :
"";
7514 llvm::BumpPtrAllocator &Alloc,
7515 llvm::vfs::FileSystem *FS) {
7524 for (
const char *F : Args) {
7525 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7527 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7528 RSPQuoting = Windows;
7534 bool MarkEOLs = ClangCLMode;
7536 llvm::cl::TokenizerCallback Tokenizer;
7537 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7538 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7540 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7542 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7545 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7546 ECtx.setMarkEOLs(MarkEOLs);
7550 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7554 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7555 [](
const char *A) {
return A !=
nullptr; });
7556 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7559 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7560 Args.resize(newEnd - Args.begin());
7564 return llvm::Error::success();
7568 return SavedStrings.insert(S).first->getKeyData();
7602 llvm::StringSet<> &SavedStrings) {
7605 if (Edit[0] ==
'^') {
7606 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7607 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7608 Args.insert(Args.begin() + 1, Str);
7609 }
else if (Edit[0] ==
'+') {
7610 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7611 OS <<
"### Adding argument " << Str <<
" at end\n";
7612 Args.push_back(Str);
7613 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7614 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7615 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7616 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7617 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7619 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7621 if (Args[i] ==
nullptr)
7623 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7625 if (Repl != Args[i]) {
7626 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7630 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7631 auto Option = Edit.substr(1);
7632 for (
unsigned i = 1; i < Args.size();) {
7633 if (Option == Args[i]) {
7634 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7635 Args.erase(Args.begin() + i);
7636 if (Edit[0] ==
'X') {
7637 if (i < Args.size()) {
7638 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7639 Args.erase(Args.begin() + i);
7641 OS <<
"### Invalid X edit, end of command line!\n";
7646 }
else if (Edit[0] ==
'O') {
7647 for (
unsigned i = 1; i < Args.size();) {
7648 const char *A = Args[i];
7652 if (A[0] ==
'-' && A[1] ==
'O' &&
7653 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7654 (
'0' <= A[2] && A[2] <=
'9'))))) {
7655 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7656 Args.erase(Args.begin() + i);
7660 OS <<
"### Adding argument " << Edit <<
" at end\n";
7661 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7663 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7668 const char *OverrideStr,
7669 llvm::StringSet<> &SavedStrings,
7670 StringRef EnvVar, raw_ostream *OS) {
7672 OS = &llvm::nulls();
7674 if (OverrideStr[0] ==
'#') {
7676 OS = &llvm::nulls();
7679 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7683 const char *S = OverrideStr;
7685 const char *End = ::strchr(S,
' ');
7687 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 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 std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static 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.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
StringRef getBoundArch() const
Return the bound architecture for this command, if any.
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
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.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
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.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
llvm::SmallVector< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string Name
The name the driver was invoked as.
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 char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(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.
@ 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.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
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)
@ 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.
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