59#include "clang/Config/config.h"
76#include "llvm/ADT/ArrayRef.h"
77#include "llvm/ADT/STLExtras.h"
78#include "llvm/ADT/ScopeExit.h"
79#include "llvm/ADT/SmallSet.h"
80#include "llvm/ADT/SmallVector.h"
81#include "llvm/ADT/StringExtras.h"
82#include "llvm/ADT/StringRef.h"
83#include "llvm/ADT/StringSet.h"
84#include "llvm/ADT/StringSwitch.h"
85#include "llvm/Config/llvm-config.h"
86#include "llvm/MC/TargetRegistry.h"
87#include "llvm/Option/Arg.h"
88#include "llvm/Option/ArgList.h"
89#include "llvm/Option/OptSpecifier.h"
90#include "llvm/Option/OptTable.h"
91#include "llvm/Option/Option.h"
92#include "llvm/Support/CommandLine.h"
93#include "llvm/Support/ErrorHandling.h"
94#include "llvm/Support/ExitCodes.h"
95#include "llvm/Support/FileSystem.h"
96#include "llvm/Support/FileUtilities.h"
97#include "llvm/Support/FormatVariadic.h"
98#include "llvm/Support/IOSandbox.h"
99#include "llvm/Support/JSON.h"
100#include "llvm/Support/MD5.h"
101#include "llvm/Support/MemoryBuffer.h"
102#include "llvm/Support/Path.h"
103#include "llvm/Support/PrettyStackTrace.h"
104#include "llvm/Support/Process.h"
105#include "llvm/Support/Program.h"
106#include "llvm/Support/Regex.h"
107#include "llvm/Support/StringSaver.h"
108#include "llvm/Support/TarWriter.h"
109#include "llvm/Support/VirtualFileSystem.h"
110#include "llvm/Support/raw_ostream.h"
111#include "llvm/TargetParser/Host.h"
112#include "llvm/TargetParser/RISCVISAInfo.h"
125using namespace clang;
128template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
129 return llvm::any_of(Args, [&](Arg *A) {
130 return (A->getOption().matches(options::OPT_x) &&
132 (A->getOption().
getKind() == Option::InputClass &&
133 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
135 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
140 return Arg ==
"-internal-isystem" || Arg ==
"-internal-externc-isystem" ||
141 Arg ==
"-isystem" || Arg ==
"-cxx-isystem" || Arg ==
"-idirafter";
145 const ArgList &Args) {
146 ArgStringList CC1Args;
147 if (Args.hasArg(options::OPT_stdlibxx_isystem))
152 for (
size_t I = 0; I < CC1Args.size(); ++I) {
153 StringRef Arg(CC1Args[I]);
155 llvm::outs() << CC1Args[++I] <<
'\n';
161 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
162 StringRef UseCUIDStr = A->getValue();
163 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
164 .Case(
"hash", Kind::Hash)
165 .Case(
"random", Kind::Random)
166 .Case(
"none", Kind::None)
167 .Default(Kind::Invalid);
168 if (UseCUID == Kind::Invalid)
169 D.Diag(clang::diag::err_drv_invalid_value)
170 << A->getAsString(Args) << UseCUIDStr;
173 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
174 if (!FixedCUID.empty())
179 llvm::opt::DerivedArgList &Args)
const {
180 std::string CUID = FixedCUID.str();
183 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
187 llvm::MD5::MD5Result
Hash;
188 Hasher.update(InputFile);
189 for (
auto *A : Args) {
190 if (A->getOption().matches(options::OPT_INPUT))
192 Hasher.update(A->getAsString(Args));
195 CUID = llvm::utohexstr(
Hash.low(),
true);
203 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
204 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
210 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
211 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
212 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
215 this->VFS = llvm::vfs::getRealFileSystem();
220 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
223 llvm::sys::path::append(P,
SysRoot);
227#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
228 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
232 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
233 llvm::sys::path::remove_dots(configFileDir,
true);
237#if defined(CLANG_CONFIG_FILE_USER_DIR)
240 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
249void Driver::setDriverMode(StringRef
Value) {
250 static StringRef OptName =
251 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
252 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
253 .Case(
"gcc", GCCMode)
254 .Case(
"g++", GXXMode)
255 .Case(
"cpp", CPPMode)
257 .Case(
"flang", FlangMode)
258 .Case(
"dxc", DXCMode)
262 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
267 bool &ContainsError)
const {
268 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
269 ContainsError =
false;
271 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
272 unsigned MissingArgIndex, MissingArgCount;
273 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
274 MissingArgCount, VisibilityMask);
277 if (MissingArgCount) {
278 Diag(diag::err_drv_missing_argument)
279 << Args.getArgString(MissingArgIndex) << MissingArgCount;
281 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
286 for (
const Arg *A : Args) {
288 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
289 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
296 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
297 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
298 ContainsError |= Diags.getDiagnosticLevel(
299 diag::warn_drv_empty_joined_argument,
304 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
306 auto ArgString = A->getAsString(Args);
308 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
310 if (
getOpts().findExact(ArgString, Nearest,
312 DiagID = diag::err_drv_unknown_argument_with_suggestion;
313 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
315 DiagID = diag::err_drv_unknown_argument;
316 Diags.Report(DiagID) << ArgString;
319 llvm::opt::Visibility(
321 DiagID = diag::err_drv_unknown_argument_with_suggestion;
322 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
324 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
325 : diag::err_drv_unknown_argument;
326 Diags.Report(DiagID) << ArgString;
330 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
331 : diag::err_drv_unknown_argument_with_suggestion;
332 Diags.Report(DiagID) << ArgString << Nearest;
334 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
338 for (
const Arg *A : Args.filtered(options::OPT_o)) {
339 if (ArgStrings[A->getIndex()] == A->getSpelling())
343 std::string ArgString = ArgStrings[A->getIndex()];
345 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
346 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
347 << A->getAsString(Args) << Nearest;
357 Arg **FinalPhaseArg)
const {
358 Arg *PhaseArg =
nullptr;
362 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
374 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
377 options::OPT_fmodule_header_EQ))) {
380 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
381 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
383 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
384 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
385 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
386 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
387 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
388 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
389 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
390 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
394 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
398 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
401 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
409 *FinalPhaseArg = PhaseArg;
417 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
418 llvm::sys::fs::OF_Text);
419 llvm::FileRemover OutputRemover(OutputFile.c_str());
420 std::optional<llvm::StringRef> Redirects[] = {
426 std::string ErrorMessage;
427 int SecondsToWait = 60;
428 if (std::optional<std::string> Str =
429 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
430 if (!llvm::to_integer(*Str, SecondsToWait))
431 return llvm::createStringError(std::error_code(),
432 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
433 "an integer, got '" +
435 SecondsToWait = std::max(SecondsToWait, 0);
437 StringRef Executable = Args[0];
438 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
440 return llvm::createStringError(std::error_code(),
441 Executable +
": " + ErrorMessage);
443 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
444 llvm::MemoryBuffer::getFile(OutputFile.c_str());
446 return llvm::createStringError(OutputBuf.getError(),
447 "Failed to read stdout of " + Executable +
448 ": " + OutputBuf.getError().message());
449 return std::move(*OutputBuf);
453 StringRef
Value,
bool Claim) {
454 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
455 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
456 Args.AddSynthesizedArg(A);
462DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
463 const llvm::opt::OptTable &Opts =
getOpts();
464 DerivedArgList *DAL =
new DerivedArgList(Args);
466 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
467 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
468 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
469 bool IgnoreUnused =
false;
470 for (Arg *A : Args) {
474 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
478 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
479 IgnoreUnused =
false;
489 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
490 A->getOption().matches(options::OPT_Xlinker)) &&
491 A->containsValue(
"--no-demangle")) {
493 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
496 for (StringRef Val : A->getValues())
497 if (Val !=
"--no-demangle")
498 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
506 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
507 A->getNumValues() > 0 &&
508 (A->getValue(0) == StringRef(
"-MD") ||
509 A->getValue(0) == StringRef(
"-MMD"))) {
511 if (A->getValue(0) == StringRef(
"-MD"))
512 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
514 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
515 if (A->getNumValues() == 2)
516 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
521 if (A->getOption().matches(options::OPT_l)) {
522 StringRef
Value = A->getValue();
525 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
527 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
532 if (
Value ==
"cc_kext") {
533 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
539 if (A->getOption().matches(options::OPT__DASH_DASH)) {
541 for (StringRef Val : A->getValues())
550 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
551 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
554 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
555 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
559#if defined(HOST_LINK_VERSION)
560 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
561 strlen(HOST_LINK_VERSION) > 0) {
562 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
564 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
572 StringRef ArgTarget) {
574 static bool BeSilent =
false;
575 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
return v < 3; };
578 if (ArgTarget.equals_insensitive(
"CURRENT")) {
582 unsigned int Version = 0;
583 unsigned int Release = 0;
584 unsigned int Modification = 0;
586 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
587 llvm::Regex HexRegex(
590 "([0-9a-fA-F][0-9a-fA-F])"
591 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
594 if (ZOsvRegex.match(ArgTarget, &Matches)) {
595 Matches[1].getAsInteger(10, Version);
596 Matches[2].getAsInteger(10, Release);
598 if (IsTooOldToBeSupported(Version, Release)) {
600 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
603 }
else if (HexRegex.match(ArgTarget, &Matches)) {
604 Matches[1].getAsInteger(16, Version);
605 Matches[2].getAsInteger(16, Release);
606 Matches[3].getAsInteger(16, Modification);
607 if (IsTooOldToBeSupported(Version, Release)) {
609 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
615 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
620 llvm::VersionTuple
V(Version, Release, Modification);
621 llvm::VersionTuple TV =
Target.getOSVersion();
624 if (TV.empty() ||
V < TV) {
626 Str = llvm::Triple::getOSTypeName(
Target.getOS());
627 Str +=
V.getAsString();
641 StringRef ArchName =
"") {
643 if (
const Arg *A = Args.getLastArg(options::OPT_target))
644 TargetTriple = A->getValue();
646 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
651 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
655 if (
Target.isOSBinFormatMachO()) {
657 if (!ArchName.empty()) {
659 return llvm::Triple(
Target.normalize());
663 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
664 StringRef ArchName = A->getValue();
667 }
else if (!ArchName.empty()) {
668 Target.setArchName(ArchName);
674 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
675 options::OPT_mbig_endian)) {
676 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
677 ?
Target.getLittleEndianArchVariant()
678 :
Target.getBigEndianArchVariant();
679 if (
T.getArch() != llvm::Triple::UnknownArch) {
680 Target = llvm::Triple(
T.normalize());
681 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
686 if (
Target.getArch() == llvm::Triple::tce)
692 if (!Args.hasArg(options::OPT_target)) {
693 if (std::optional<std::string> ObjectModeValue =
694 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
695 StringRef ObjectMode = *ObjectModeValue;
696 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
699 if (ObjectMode ==
"64") {
700 AT =
Target.get64BitArchVariant().getArch();
701 }
else if (ObjectMode ==
"32" || ObjectMode ==
"32_64" ||
702 ObjectMode ==
"any") {
704 if (Args.hasArg(options::OPT_maix64, options::OPT_m64))
705 AT =
Target.get64BitArchVariant().getArch();
707 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
709 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
713 const bool OtherAllowedMode =
714 ObjectMode ==
"32_64" || ObjectMode ==
"any";
715 if (ObjectMode ==
"64")
716 AT =
Target.get64BitArchVariant().getArch();
717 else if (ObjectMode ==
"32")
718 AT =
Target.get32BitArchVariant().getArch();
719 else if (!OtherAllowedMode)
720 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
723 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
728 !Args.hasArg(options::OPT_maix64, options::OPT_m64)) {
731 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
737 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
738 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
741 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
743 D.
Diag(diag::err_drv_unsupported_opt_for_target)
744 << A->getAsString(Args) <<
Target.str();
747 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
748 options::OPT_m32, options::OPT_m16,
749 options::OPT_maix32, options::OPT_maix64);
751 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
753 if (A->getOption().matches(options::OPT_m64) ||
754 A->getOption().matches(options::OPT_maix64)) {
755 AT =
Target.get64BitArchVariant().getArch();
756 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
757 Target.getEnvironment() == llvm::Triple::GNUT64)
758 Target.setEnvironment(llvm::Triple::GNU);
759 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
760 Target.setEnvironment(llvm::Triple::Musl);
761 }
else if (A->getOption().matches(options::OPT_mx32) &&
762 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
763 AT = llvm::Triple::x86_64;
764 if (
Target.getEnvironment() == llvm::Triple::Musl)
765 Target.setEnvironment(llvm::Triple::MuslX32);
767 Target.setEnvironment(llvm::Triple::GNUX32);
768 }
else if (A->getOption().matches(options::OPT_m32) ||
769 A->getOption().matches(options::OPT_maix32)) {
772 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
774 D.
Diag(diag::err_drv_unsupported_opt_for_target)
775 << A->getAsString(Args) <<
Target.str();
778 AT =
Target.get32BitArchVariant().getArch();
779 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
780 Target.setEnvironment(llvm::Triple::GNU);
781 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
782 Target.setEnvironment(llvm::Triple::Musl);
784 }
else if (A->getOption().matches(options::OPT_m16) &&
785 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
786 AT = llvm::Triple::x86;
787 Target.setEnvironment(llvm::Triple::CODE16);
790 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
792 if (
Target.isWindowsGNUEnvironment())
800 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
806 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
807 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
808 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
811 if (A && !A->getOption().matches(options::OPT_m32))
812 D.
Diag(diag::err_drv_argument_not_allowed_with)
813 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
815 Target.setArch(llvm::Triple::x86);
816 Target.setArchName(
"i586");
817 Target.setEnvironmentName(
"");
818 Target.setOS(llvm::Triple::ELFIAMCU);
819 Target.setVendor(llvm::Triple::Intel);
825 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
826 StringRef ABIName = A->getValue();
827 if (ABIName ==
"32") {
829 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
830 Target.getEnvironment() == llvm::Triple::GNUABIN32)
831 Target.setEnvironment(llvm::Triple::GNU);
832 }
else if (ABIName ==
"n32") {
834 if (
Target.getEnvironment() == llvm::Triple::GNU ||
835 Target.getEnvironment() == llvm::Triple::GNUT64 ||
836 Target.getEnvironment() == llvm::Triple::GNUABI64)
837 Target.setEnvironment(llvm::Triple::GNUABIN32);
838 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
839 Target.getEnvironment() == llvm::Triple::MuslABI64)
840 Target.setEnvironment(llvm::Triple::MuslABIN32);
841 }
else if (ABIName ==
"64") {
843 if (
Target.getEnvironment() == llvm::Triple::GNU ||
844 Target.getEnvironment() == llvm::Triple::GNUT64 ||
845 Target.getEnvironment() == llvm::Triple::GNUABIN32)
846 Target.setEnvironment(llvm::Triple::GNUABI64);
847 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
848 Target.getEnvironment() == llvm::Triple::MuslABIN32)
849 Target.setEnvironment(llvm::Triple::MuslABI64);
859 if (Args.hasArg(options::OPT_march_EQ) ||
860 Args.hasArg(options::OPT_mcpu_EQ)) {
862 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
864 if (!llvm::errorToBool(ISAInfo.takeError())) {
865 unsigned XLen = (*ISAInfo)->getXLen();
867 if (
Target.isLittleEndian())
868 Target.setArch(llvm::Triple::riscv32);
870 Target.setArch(llvm::Triple::riscv32be);
872 }
else if (XLen == 64) {
873 if (
Target.isLittleEndian())
874 Target.setArch(llvm::Triple::riscv64);
876 Target.setArch(llvm::Triple::riscv64be);
883 if (
Target.getArch() == llvm::Triple::riscv32be ||
884 Target.getArch() == llvm::Triple::riscv64be) {
885 static bool WarnedRISCVBE =
false;
886 if (!WarnedRISCVBE) {
887 D.
Diag(diag::warn_drv_riscv_be_experimental);
888 WarnedRISCVBE =
true;
897 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
899 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
901 RuntimeName = A->getValue();
903 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
911 Diag(diag::err_drv_unsupported_option_argument)
912 << A->getSpelling() << A->getValue();
915 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
924 StringRef Program =
C.getArgs().getLastArgValue(
925 options::OPT_offload_arch_tool_EQ,
"offload-arch");
928 if (llvm::ErrorOr<std::string> Executable =
929 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
931 bool UsesLLVMOffloading =
932 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
933 options::OPT_fno_offload_via_llvm,
false);
934 if (!UsesLLVMOffloading) {
936 Args.push_back(
"--only=amdgpu");
938 Args.push_back(
"--only=nvptx");
940 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
943 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
948 if ((*StdoutOrErr)->getBuffer().empty()) {
949 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
955 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
957 GPUArchs.push_back(
Arch.str());
959 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
970 std::set<std::string> Archs;
971 for (Arg *A :
C.getInputArgs()) {
972 for (StringRef
Arch : A->getValues()) {
973 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
974 if (
Arch ==
"native") {
976 Archs.insert(Str.str());
978 Archs.insert(
Arch.str());
980 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
984 Archs.erase(
Arch.str());
990 for (llvm::StringRef
Arch : Archs) {
992 if (ID.isUnknown()) {
993 llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
994 llvm::Triple::AMD, llvm::Triple::AMDHSA);
998 bool UsesLLVMOffloading =
999 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
1000 options::OPT_fno_offload_via_llvm,
false);
1001 if (!UsesLLVMOffloading) {
1002 if (Kind ==
Action::OFK_HIP && !ID.isAMDGPU() && !ID.isAMDGCNSPIRV()) {
1003 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1008 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1014 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1018 if (ID.isUnknown() || ID.isUnused()) {
1019 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1020 <<
"offload" <<
Arch;
1024 llvm::Triple Triple =
1026 if (UsesLLVMOffloading)
1027 Triple.setEnvironment(llvm::Triple::LLVM);
1032 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1033 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1034 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1035 C.getArgs().MakeArgString(Triple.getArchName()),
1036 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1038 C.getArgs().append(A);
1039 C.getArgs().AddSynthesizedArg(A);
1041 auto It = Triples.lower_bound(Triple);
1042 if (It == Triples.end() || *It != Triple)
1043 Triples.insert(It, Triple);
1048 Triples.insert(llvm::Triple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
1049 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1051 llvm::Triple::ArchType
Arch =
1052 C.getDefaultToolChain().getTriple().isArch64Bit()
1053 ? llvm::Triple::nvptx64
1054 : llvm::Triple::nvptx;
1055 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1056 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1059 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1060 ? llvm::Triple::spirv64
1061 : llvm::Triple::spirv32));
1064 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1065 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1073 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1077 (llvm::any_of(Inputs,
1078 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1081 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1082 C.getInputArgs().hasArg(options::OPT_hipstdpar));
1083 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1084 options::OPT_fno_sycl,
false);
1085 bool IsOpenMPOffloading =
1086 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1087 options::OPT_fno_openmp,
false) &&
1088 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1089 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1090 !(IsCuda || IsHIP))));
1092 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1093 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1098 for (
const auto &[Active, Kind] : ActiveKinds)
1103 if (Kinds.size() > 1) {
1104 Diag(clang::diag::err_drv_mix_offload)
1111 if (IsCuda || IsHIP)
1118 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1119 std::vector<std::string> ArgValues =
1120 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1121 for (llvm::StringRef
Target : ArgValues) {
1125 if (ArgValues.empty())
1126 Diag(clang::diag::warn_drv_empty_joined_argument)
1128 .getLastArg(options::OPT_offload_targets_EQ)
1129 ->getAsString(
C.getInputArgs());
1136 llvm::StringMap<StringRef> FoundNormalizedTriples;
1137 for (
const llvm::Triple &
Target : Triples) {
1142 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1150 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1151 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1152 Diag(clang::diag::err_drv_argument_not_allowed_with)
1153 << IncompatArg->getSpelling() <<
"-fsycl";
1158 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1159 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1164 std::string NormalizedName =
Target.normalize();
1165 auto [TripleIt, Inserted] =
1166 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1168 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1169 <<
Target.str() << TripleIt->second;
1173 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1174 C.getDefaultToolChain().getTriple());
1178 auto &CudaInstallation =
1180 if (CudaInstallation.isValid())
1181 CudaInstallation.WarnIfUnsupportedVersion();
1184 C.addOffloadDeviceToolChain(&TC, Kind);
1189bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1194 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1198 if (!PathLIBEnv.empty()) {
1199 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1200 if (llvm::sys::fs::is_directory(PathLIBEnv))
1201 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1202 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1203 return readConfigFile(CustomizationFile, ExpCtx);
1204 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1209 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1210 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1211 return readConfigFile(CustomizationFile, ExpCtx);
1221 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1222 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1223 Copy->getValues() = Opt->getValues();
1224 if (Opt->isClaimed())
1226 Copy->setOwnsValues(Opt->getOwnsValues());
1227 Opt->setOwnsValues(
false);
1229 if (Opt->getAlias()) {
1230 const Arg *Alias = Opt->getAlias();
1231 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1232 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1233 Args.getArgString(Index), Index);
1234 AliasCopy->getValues() = Alias->getValues();
1235 AliasCopy->setOwnsValues(
false);
1236 if (Alias->isClaimed())
1238 Copy->setAlias(std::move(AliasCopy));
1242bool Driver::readConfigFile(StringRef
FileName,
1243 llvm::cl::ExpansionContext &ExpCtx) {
1247 Diag(diag::err_drv_cannot_open_config_file)
1248 <<
FileName << Status.getError().message();
1251 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1252 Diag(diag::err_drv_cannot_open_config_file)
1253 <<
FileName <<
"not a regular file";
1258 SmallVector<const char *, 32> NewCfgFileArgs;
1259 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1260 Diag(diag::err_drv_cannot_read_config_file)
1266 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1267 for (
const char *Opt : NewCfgFileArgs) {
1269 if (Opt[0] ==
'$' && Opt[1])
1270 NewCfgTailArgs.push_back(Opt + 1);
1272 NewCfgHeadArgs.push_back(Opt);
1276 llvm::SmallString<128> CfgFileName(
FileName);
1277 llvm::sys::path::native(CfgFileName);
1278 bool ContainErrors =
false;
1279 auto NewHeadOptions = std::make_unique<InputArgList>(
1283 auto NewTailOptions = std::make_unique<InputArgList>(
1290 for (Arg *A : *NewHeadOptions)
1292 for (Arg *A : *NewTailOptions)
1295 if (!CfgOptionsHead)
1296 CfgOptionsHead = std::move(NewHeadOptions);
1299 for (
auto *Opt : *NewHeadOptions)
1303 if (!CfgOptionsTail)
1304 CfgOptionsTail = std::move(NewTailOptions);
1307 for (
auto *Opt : *NewTailOptions)
1311 ConfigFiles.push_back(std::string(CfgFileName));
1315bool Driver::loadConfigFiles() {
1316 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1317 llvm::cl::tokenizeConfigFile, &
getVFS());
1321 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1322 SmallString<128> CfgDir;
1324 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1325 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1330 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1331 SmallString<128> CfgDir;
1332 llvm::sys::fs::expand_tilde(
1333 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1334 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1343 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1346 if (loadDefaultConfigFiles(ExpCtx))
1350 SmallString<128> CfgFilePath;
1352 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1355 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1356 CfgFilePath.assign(CfgFileName);
1357 if (llvm::sys::path::is_relative(CfgFilePath)) {
1358 if (
getVFS().makeAbsolute(CfgFilePath)) {
1359 Diag(diag::err_drv_cannot_open_config_file)
1360 << CfgFilePath <<
"cannot get absolute path";
1364 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1366 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1367 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1368 if (!SearchDir.empty())
1369 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1374 if (readConfigFile(CfgFilePath, ExpCtx))
1385 llvm::Triple Triple, std::string Suffix) {
1387 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1391 VersionTuple OSVersion = Triple.getOSVersion();
1392 if (!OSVersion.getMinor().has_value())
1395 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1399 if (OSVersion.getMajor() != 0) {
1400 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1401 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1407 Triple.setOSName(BaseOSName);
1408 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1411bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1414 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1418 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1421 std::string RealMode = getExecutableForDriverMode(Mode);
1422 llvm::Triple Triple;
1431 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1432 PrefixTriple.isOSUnknown())
1433 Triple = std::move(PrefixTriple);
1437 llvm::Triple RealTriple =
1439 if (Triple.str().empty()) {
1440 Triple = RealTriple;
1441 assert(!Triple.str().empty());
1446 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1460 SmallString<128> CfgFilePath;
1462 "-" + RealMode +
".cfg"))
1463 return readConfigFile(CfgFilePath, ExpCtx);
1467 if (TryModeSuffix) {
1470 return readConfigFile(CfgFilePath, ExpCtx);
1475 std::string CfgFileName = RealMode +
".cfg";
1476 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1477 if (readConfigFile(CfgFilePath, ExpCtx))
1479 }
else if (TryModeSuffix) {
1481 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1482 readConfigFile(CfgFilePath, ExpCtx))
1488 return readConfigFile(CfgFilePath, ExpCtx);
1496 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1505 if (!DriverMode.empty())
1506 setDriverMode(DriverMode);
1512 CLOptions = std::make_unique<InputArgList>(
1517 ContainsError = loadConfigFiles();
1518 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1519 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1523 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1525 if (HasConfigFileHead)
1526 for (
auto *Opt : *CLOptions)
1527 if (!Opt->getOption().matches(options::OPT_config))
1531 if (
IsCLMode() && !ContainsError) {
1533 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1535 CLModePassThroughArgList.push_back(A->getValue());
1538 if (!CLModePassThroughArgList.empty()) {
1541 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1546 for (
auto *Opt : *CLModePassThroughOptions)
1552 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1553 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1554 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1557 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1558 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1559 if (!VFS->exists(IncludeDir))
1560 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1565 bool CCCPrintPhases;
1568 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1569 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1572 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1573 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1576 Args.ClaimAllArgs(options::OPT_pipe);
1584 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1586 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1587 CCCGenericGCCName = A->getValue();
1590 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1594 if (Args.hasArg(options::OPT_fproc_stat_report))
1601 llvm::Triple
T(TargetTriple);
1602 T.setOS(llvm::Triple::Win32);
1603 T.setVendor(llvm::Triple::PC);
1604 T.setEnvironment(llvm::Triple::MSVC);
1605 T.setObjectFormat(llvm::Triple::COFF);
1606 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1607 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1608 TargetTriple =
T.str();
1611 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1612 StringRef TargetProfile = A->getValue();
1615 TargetTriple = *Triple;
1617 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1621 if (Args.hasArg(options::OPT_spirv)) {
1622 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1623 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1624 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1625 llvm::Triple
T(TargetTriple);
1628 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1630 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1631 TargetInfo = ValidTargets.find(A->getValue());
1633 Diag(diag::err_drv_invalid_value)
1634 << A->getAsString(Args) << A->getValue();
1640 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1641 TargetTriple =
T.str();
1645 Diag(diag::err_drv_dxc_missing_target_profile);
1649 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1650 TargetTriple = A->getValue();
1651 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1652 Dir = A->getValue();
1653 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1657 if (std::optional<std::string> CompilerPathValue =
1658 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1659 StringRef CompilerPath = *CompilerPathValue;
1660 while (!CompilerPath.empty()) {
1661 std::pair<StringRef, StringRef> Split =
1662 CompilerPath.split(llvm::sys::EnvPathSeparator);
1663 PrefixDirs.push_back(std::string(Split.first));
1664 CompilerPath = Split.second;
1667 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1669 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1672 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1675 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1676 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1677 .Case(
"cwd", SaveTempsCwd)
1678 .Case(
"obj", SaveTempsObj)
1679 .Default(SaveTempsCwd);
1682 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1683 options::OPT_offload_device_only,
1684 options::OPT_offload_host_device)) {
1685 if (A->getOption().matches(options::OPT_offload_host_only))
1686 Offload = OffloadHost;
1687 else if (A->getOption().matches(options::OPT_offload_device_only))
1688 Offload = OffloadDevice;
1690 Offload = OffloadHostDevice;
1694 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1695 StringRef
Name = A->getValue();
1696 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1697 .Case(
"off", EmbedNone)
1698 .Case(
"all", EmbedBitcode)
1699 .Case(
"bitcode", EmbedBitcode)
1700 .Case(
"marker", EmbedMarker)
1703 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1706 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1710 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1711 llvm::sys::fs::remove(A->getValue());
1717 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1719 !Args.hasArg(options::OPT_fmodules) && Std &&
1720 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1721 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1722 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1723 Std->containsValue(
"c++2d") || Std->containsValue(
"c++latest"));
1726 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1727 options::OPT_fmodule_header)) {
1729 ModulesModeCXX20 =
true;
1730 if (A->getOption().matches(options::OPT_fmodule_header))
1733 StringRef ArgName = A->getValue();
1734 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1739 Diags.Report(diag::err_drv_invalid_value)
1740 << A->getAsString(Args) << ArgName;
1746 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1747 std::make_unique<InputArgList>(std::move(Args));
1757 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1758 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1760 bool MLContainsError;
1761 auto MultilibMacroDefineList =
1763 MLMacroDefinesChar,
false, MLContainsError));
1764 if (!MLContainsError) {
1765 for (
auto *Opt : *MultilibMacroDefineList) {
1772 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1776 if (!Triple.isWasm()) {
1777 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1778 StringRef TripleObjectFormat =
1779 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1780 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1781 TripleVersionName != TripleObjectFormat) {
1782 Diags.Report(diag::err_drv_triple_version_invalid)
1784 ContainsError =
true;
1789 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1790 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1791 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1799 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1800 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1802 case llvm::Triple::arm:
1803 case llvm::Triple::armeb:
1804 case llvm::Triple::thumb:
1805 case llvm::Triple::thumbeb:
1806 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1807 Diag(diag::warn_target_unrecognized_env)
1809 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1812 case llvm::Triple::aarch64:
1813 case llvm::Triple::aarch64_be:
1814 case llvm::Triple::aarch64_32:
1815 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1816 Diag(diag::warn_target_unrecognized_env)
1818 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1835 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1836 if (HasConfigFileTail && Inputs.size()) {
1839 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1840 for (Arg *A : *CfgOptionsTail)
1841 TranslatedLinkerIns.append(A);
1842 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1849 bool UseModulesDriver =
C->getArgs().hasFlag(
1850 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1852 if (UseModulesDriver) {
1853 Diags.Report(diag::remark_performing_driver_managed_module_build);
1861 const auto StdModuleManifestPath =
1864 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1865 Diags.Report(diag::remark_modules_manifest_not_found);
1867 Diags.Report(diag::remark_using_modules_manifest)
1868 << StdModuleManifestPath;
1869 if (
auto ManifestOrErr =
1871 ModulesManifest = std::move(*ManifestOrErr);
1873 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1874 return !ModuleEntry.IsStdlib;
1879 llvm::handleAllErrors(
1880 ManifestOrErr.takeError(),
1881 [&](llvm::json::ParseError &Err) {
1882 Diags.Report(diag::err_modules_manifest_failed_parse)
1885 [&](llvm::FileError &Err) {
1886 Diags.Report(diag::err_cannot_open_file)
1887 << Err.getFileName() << Err.messageWithoutFileInfo();
1895 if (TC.
getTriple().isOSBinFormatMachO())
1900 if (CCCPrintPhases) {
1907 if (UseModulesDriver)
1914 llvm::opt::ArgStringList ASL;
1915 for (
const auto *A : Args) {
1919 while (A->getAlias())
1921 A->render(Args, ASL);
1924 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1925 if (I != ASL.begin())
1927 llvm::sys::printArg(OS, *I,
true);
1932bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1933 SmallString<128> &CrashDiagDir) {
1934 using namespace llvm::sys;
1935 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1936 "Only knows about .crash files on Darwin");
1938 auto BypassSandbox = sandbox::scopedDisable();
1943 path::home_directory(CrashDiagDir);
1944 if (CrashDiagDir.starts_with(
"/var/root"))
1946 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1954 fs::file_status FileStatus;
1955 TimePoint<> LastAccessTime;
1956 SmallString<128> CrashFilePath;
1959 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1960 File != FileEnd && !EC;
File.increment(EC)) {
1964 if (fs::status(
File->path(), FileStatus))
1966 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1967 llvm::MemoryBuffer::getFile(
File->path());
1972 StringRef
Data = CrashFile.get()->getBuffer();
1973 if (!
Data.starts_with(
"Process:"))
1976 size_t ParentProcPos =
Data.find(
"Parent Process:");
1977 if (ParentProcPos == StringRef::npos)
1979 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1980 if (LineEnd == StringRef::npos)
1982 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1983 int OpenBracket = -1, CloseBracket = -1;
1984 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1985 if (ParentProcess[i] ==
'[')
1987 if (ParentProcess[i] ==
']')
1993 if (OpenBracket < 0 || CloseBracket < 0 ||
1994 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1995 .getAsInteger(10, CrashPID) || CrashPID != PID) {
2005 const auto FileAccessTime = FileStatus.getLastModificationTime();
2006 if (FileAccessTime > LastAccessTime) {
2007 CrashFilePath.assign(
File->path());
2008 LastAccessTime = FileAccessTime;
2013 if (!CrashFilePath.empty()) {
2014 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2024 "\n********************\n\n"
2025 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
2033 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2036 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
2039 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2040 Level = llvm::StringSwitch<unsigned>(A->getValue())
2042 .Case(
"compiler", 1)
2054 ArgStringList SavedTemps;
2056 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2057 if (!IsLLD || Level < 2)
2064 SavedTemps = std::move(
C.getTempFiles());
2065 assert(!
C.getTempFiles().size());
2082 C.initCompilationForDiagnostics();
2087 Command NewLLDInvocation = Cmd;
2088 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2089 StringRef ReproduceOption =
2090 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2093 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2097 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2099 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2100 Diag(clang::diag::note_drv_command_failed_diag_msg)
2101 <<
"\n\n********************";
2103 Report->TemporaryFiles.push_back(TmpName);
2111 ArgStringList IRInputs;
2112 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2113 bool IgnoreInput =
false;
2119 IRInputs.push_back(it->second->getValue());
2123 }
else if (!strcmp(it->second->getValue(),
"-")) {
2124 Diag(clang::diag::note_drv_command_failed_diag_msg)
2125 <<
"Error generating preprocessed source(s) - "
2126 "ignoring input from stdin.";
2131 it = Inputs.erase(it);
2138 if (Inputs.empty() && IRInputs.empty()) {
2139 Diag(clang::diag::note_drv_command_failed_diag_msg)
2140 <<
"Error generating preprocessed source(s) - "
2141 "no preprocessable inputs.";
2147 llvm::StringSet<> ArchNames;
2148 for (
const Arg *A :
C.getArgs()) {
2149 if (A->getOption().matches(options::OPT_arch)) {
2150 StringRef ArchName = A->getValue();
2151 ArchNames.insert(ArchName);
2154 if (ArchNames.size() > 1) {
2157 if (FailingArch.empty()) {
2158 Diag(clang::diag::note_drv_command_failed_diag_msg)
2159 <<
"Error generating preprocessed source(s) - cannot generate "
2160 "preprocessed source with multiple -arch options.";
2163 C.getArgs().eraseArg(options::OPT_arch);
2164 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2169 if (!Inputs.empty()) {
2172 const ToolChain &TC =
C.getDefaultToolChain();
2173 if (TC.
getTriple().isOSBinFormatMachO())
2182 Diag(clang::diag::note_drv_command_failed_diag_msg)
2183 <<
"Error generating preprocessed source(s).";
2188 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2191 if (!FailingCommands.empty()) {
2192 Diag(clang::diag::note_drv_command_failed_diag_msg)
2193 <<
"Error generating preprocessed source(s).";
2197 const ArgStringList &TempFiles =
C.getTempFiles();
2198 if (TempFiles.empty()) {
2199 Diag(clang::diag::note_drv_command_failed_diag_msg)
2200 <<
"Error generating preprocessed source(s).";
2206 const ArgStringList &Files =
C.getTempFiles();
2211 for (
auto const *Input : IRInputs) {
2215 StringRef extension = llvm::sys::path::extension(Input);
2216 if (!extension.empty())
2217 extension = extension.drop_front();
2219 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2220 llvm::sys::path::stem(Input), extension, FD, Path);
2222 Diag(clang::diag::note_drv_command_failed_diag_msg)
2223 <<
"Error generating run script: " <<
"Failed copying IR input files"
2224 <<
" " << EC.message();
2228 EC = llvm::sys::fs::copy_file(Input, FD);
2230 Diag(clang::diag::note_drv_command_failed_diag_msg)
2231 <<
"Error generating run script: " <<
"Failed copying IR input files"
2232 <<
" " << EC.message();
2236 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2243 for (std::string &TempFile : TempFiles) {
2245 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2247 Report->TemporaryFiles.push_back(TempFile);
2248 if (ReproCrashFilename.empty()) {
2249 ReproCrashFilename = TempFile;
2250 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2252 if (StringRef(TempFile).ends_with(
".cache")) {
2255 VFS = llvm::sys::path::filename(TempFile);
2256 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2260 for (
const char *TempFile : SavedTemps)
2261 TempFiles.push_back(TempFile);
2267 llvm::sys::path::replace_extension(Script,
"sh");
2269 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2270 llvm::sys::fs::FA_Write,
2271 llvm::sys::fs::OF_Text);
2273 Diag(clang::diag::note_drv_command_failed_diag_msg)
2274 <<
"Error generating run script: " << Script <<
" " << EC.message();
2277 <<
"# Driver args: ";
2279 ScriptOS <<
"# Original command: ";
2280 Cmd.
Print(ScriptOS,
"\n",
true);
2281 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2282 if (!AdditionalInformation.empty())
2283 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2286 Report->TemporaryFiles.push_back(std::string(Script));
2287 TempFiles.push_back(std::string(Script));
2290 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2293 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2294 StringRef CrashDiagnosticsTar = A->getValue();
2296 llvm::TarWriter::create(CrashDiagnosticsTar,
2297 llvm::sys::path::stem(CrashDiagnosticsTar));
2299 Diag(clang::diag::note_drv_command_failed_diag_msg)
2300 << (std::string(
"Error creating reproducer tarball: ") +
2301 llvm::toString(TarOrErr.takeError()));
2303 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2304 for (
const std::string &TempFile : TempFiles) {
2305 if (llvm::sys::fs::is_directory(TempFile)) {
2307 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2308 I != E && !EC; I.increment(EC)) {
2309 if (llvm::sys::fs::is_regular_file(I->path())) {
2310 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2314 llvm::sys::path::filename(TempFile);
2315 StringRef SubPath = I->path();
2316 if (SubPath.consume_front(TempFile)) {
2317 if (!SubPath.empty() &&
2318 llvm::sys::path::is_separator(SubPath.front())) {
2319 SubPath = SubPath.drop_front();
2321 llvm::sys::path::append(PathInTar, SubPath);
2322 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2325 Diag(clang::diag::note_drv_command_failed_diag_msg)
2326 << (std::string(
"Error reading file for tarball: ") +
2332 Diag(clang::diag::note_drv_command_failed_diag_msg)
2333 << (std::string(
"Error iterating directory for tarball: ") +
2334 TempFile +
" " + EC.message());
2337 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2339 Tar->append(llvm::sys::path::filename(TempFile),
2340 (*BufferOrErr)->getBuffer());
2342 Diag(clang::diag::note_drv_command_failed_diag_msg)
2343 << (std::string(
"Error reading file for tarball: ") + TempFile);
2347 Diag(clang::diag::note_drv_command_failed_diag_msg)
2348 << CrashDiagnosticsTar;
2353 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2355 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2356 Diag(clang::diag::note_drv_command_failed_diag_msg)
2357 << ReproCrashFilename.str();
2359 llvm::sys::path::append(CrashDiagDir,
Name);
2360 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2361 Diag(clang::diag::note_drv_command_failed_diag_msg)
2362 <<
"Crash backtrace is located in";
2363 Diag(clang::diag::note_drv_command_failed_diag_msg)
2364 << CrashDiagDir.str();
2365 Diag(clang::diag::note_drv_command_failed_diag_msg)
2366 <<
"(choose the .crash file that corresponds to your crash)";
2370 Diag(clang::diag::note_drv_command_failed_diag_msg)
2371 <<
"\n\n********************";
2381 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2392 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2393 if (
C.getArgs().hasArg(options::OPT_v))
2394 C.getJobs().Print(llvm::errs(),
"\n",
true);
2396 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2399 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2406 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2407 C.getJobs().Print(llvm::errs(),
"\n",
true);
2408 return Diags.hasErrorOccurred() ? 1 : 0;
2412 if (Diags.hasErrorOccurred())
2416 for (
auto &Job :
C.getJobs())
2417 setUpResponseFiles(
C, Job);
2419 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2422 if (FailingCommands.empty())
2428 for (
const auto &CmdPair : FailingCommands) {
2429 int CommandRes = CmdPair.first;
2430 const Command *FailingCommand = CmdPair.second;
2435 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2439 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2444 if (CommandRes == EX_IOERR) {
2464 if (CommandRes > 128 && CommandRes != 255)
2468 Diag(clang::diag::err_drv_command_signalled)
2471 Diag(clang::diag::err_drv_command_failed)
2479 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2481 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2495 const ToolChain &TC =
C.getDefaultToolChain();
2499 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2502 OS <<
"Thread model: " << A->getValue();
2508 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2513 if (!llvm::cl::getCompilerBuildConfig().empty())
2514 llvm::cl::printBuildConfig(OS);
2517 for (
auto ConfigFile : ConfigFiles)
2518 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2531 if (PassedFlags ==
"")
2535 std::vector<std::string> SuggestedCompletions;
2536 std::vector<std::string> Flags;
2548 const bool HasSpace = PassedFlags.ends_with(
",");
2552 StringRef TargetFlags = PassedFlags;
2553 while (TargetFlags !=
"") {
2555 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2556 Flags.push_back(std::string(CurFlag));
2561 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2564 const llvm::opt::OptTable &Opts =
getOpts();
2566 Cur = Flags.at(Flags.size() - 1);
2568 if (Flags.size() >= 2) {
2569 Prev = Flags.at(Flags.size() - 2);
2570 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2573 if (SuggestedCompletions.empty())
2574 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2581 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2582 llvm::outs() <<
'\n';
2588 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2592 SuggestedCompletions = Opts.findByPrefix(
2593 Cur, VisibilityMask,
2600 if (S.starts_with(Cur))
2601 SuggestedCompletions.push_back(std::string(S));
2608 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2609 if (
int X = A.compare_insensitive(B))
2611 return A.compare(B) > 0;
2614 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2621 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2622 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2626 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2629 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2633 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2638 if (
C.getArgs().hasArg(options::OPT_help) ||
2639 C.getArgs().hasArg(options::OPT__help_hidden)) {
2640 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2644 if (
C.getArgs().hasArg(options::OPT__version)) {
2651 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2652 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2653 if (ListExtractors || ListFormats) {
2661 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2666 if (
C.getArgs().hasArg(options::OPT_v) ||
2667 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2668 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2669 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2670 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2672 SuppressMissingInputWarning =
true;
2675 if (
C.getArgs().hasArg(options::OPT_v)) {
2677 llvm::errs() <<
"System configuration file directory: "
2680 llvm::errs() <<
"User configuration file directory: "
2684 const ToolChain &TC =
C.getDefaultToolChain();
2686 if (
C.getArgs().hasArg(options::OPT_v))
2689 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2694 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2695 llvm::outs() <<
"programs: =";
2696 bool separator =
false;
2700 llvm::outs() << llvm::sys::EnvPathSeparator;
2701 llvm::outs() << Path;
2706 llvm::outs() << llvm::sys::EnvPathSeparator;
2707 llvm::outs() << Path;
2710 llvm::outs() <<
"\n";
2713 StringRef sysroot =
C.getSysRoot();
2717 llvm::outs() << llvm::sys::EnvPathSeparator;
2720 llvm::outs() << sysroot << Path.substr(1);
2722 llvm::outs() << Path;
2724 llvm::outs() <<
"\n";
2728 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib)) {
2733 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib_include_dirs)) {
2738 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2744 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2745 for (
auto RuntimePath :
2747 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2748 llvm::outs() << *RuntimePath <<
'\n';
2752 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2756 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2758 for (std::size_t I = 0; I != Flags.size(); I += 2)
2759 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2765 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2766 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2770 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2771 StringRef ProgName = A->getValue();
2774 if (! ProgName.empty())
2777 llvm::outs() <<
"\n";
2781 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2782 StringRef PassedFlags = A->getValue();
2787 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2797 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2802 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2805 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2811 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2818 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2821 std::set<llvm::StringRef> SortedFlags;
2822 for (
const auto &FlagEntry : ExpandedFlags)
2823 SortedFlags.insert(FlagEntry.getKey());
2824 for (
auto Flag : SortedFlags)
2825 llvm::outs() << Flag <<
'\n';
2829 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2832 llvm::outs() <<
".\n";
2835 assert(Suffix.front() ==
'/');
2836 llvm::outs() << Suffix.substr(1) <<
"\n";
2842 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2847 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2849 llvm::outs() << Triple.getTriple() <<
"\n";
2853 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2854 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2871 std::map<Action *, unsigned> &Ids,
2873 if (
auto It = Ids.find(A); It != Ids.end())
2877 llvm::raw_string_ostream os(str);
2879 auto getSibIndent = [](
int K) -> Twine {
2883 Twine SibIndent =
Indent + getSibIndent(Kind);
2887 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2889 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2890 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2891 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2893 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2894 assert(TC &&
"Unknown host toolchain");
2909 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2917 const char *Prefix =
"{";
2918 for (
Action *PreRequisite : *AL) {
2919 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2930 std::string offload_str;
2931 llvm::raw_string_ostream offload_os(offload_str);
2935 offload_os <<
", (" << S;
2942 auto getSelfIndent = [](
int K) -> Twine {
2946 unsigned Id = Ids.size();
2948 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2957 std::map<Action *, unsigned> Ids;
2958 for (
Action *A :
C.getActions())
2974 DerivedArgList &Args =
C.getArgs();
2976 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2979 llvm::StringSet<> ArchNames;
2981 for (Arg *A : Args) {
2982 if (A->getOption().matches(options::OPT_arch)) {
2985 llvm::Triple::ArchType
Arch =
2987 if (
Arch == llvm::Triple::UnknownArch) {
2988 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2993 if (ArchNames.insert(A->getValue()).second)
2994 Archs.push_back(A->getValue());
3008 for (
Action* Act : SingleActions) {
3016 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
3020 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
3025 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
3026 Actions.append(Inputs.begin(), Inputs.end());
3028 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
3031 Arg *A = Args.getLastArg(options::OPT_g_Group);
3032 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
3033 !A->getOption().matches(options::OPT_gstabs);
3034 bool enablesPseudoProbe =
3035 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
3036 options::OPT_fno_pseudo_probe_for_profiling,
false);
3037 bool enablesDebugInfoForProfiling =
3038 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
3039 options::OPT_fno_debug_info_for_profiling,
false);
3040 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
3041 enablesDebugInfoForProfiling) &&
3049 if (Act->getType() == types::TY_Image) {
3051 Inputs.push_back(Actions.back());
3058 if (Args.hasArg(options::OPT_verify_debug_info)) {
3059 Action *LastAction = Actions.pop_back_val();
3061 LastAction, types::TY_Nothing));
3068 bool TypoCorrect)
const {
3080 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3081 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3093 std::string Nearest;
3094 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3095 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3096 <<
Value << Nearest;
3135 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3138 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3146 return types::TY_CXXUHeader;
3148 return types::TY_CXXSHeader;
3152 llvm_unreachable(
"should not be called in this case");
3154 return types::TY_CXXHUHeader;
3160 const llvm::opt::OptTable &Opts =
getOpts();
3164 types::ID InputType = types::TY_Nothing;
3165 Arg *InputTypeArg =
nullptr;
3168 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3169 options::OPT__SLASH_TP)) {
3170 InputTypeArg = TCTP;
3171 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3176 bool ShowNote =
false;
3178 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3180 Diag(clang::diag::warn_drv_overriding_option)
3181 <<
Previous->getSpelling() << A->getSpelling();
3187 Diag(clang::diag::note_drv_t_option_is_global);
3192 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3193 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3194 if (LastXArg && LastInputArg &&
3195 LastInputArg->getIndex() < LastXArg->getIndex())
3196 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3199 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3201 for (Arg *A : Args) {
3202 if (A->getOption().
getKind() == Option::InputClass) {
3203 const char *
Value = A->getValue();
3207 if (InputType == types::TY_Nothing) {
3210 InputTypeArg->claim();
3213 if (strcmp(
Value,
"-") == 0) {
3215 Ty = types::TY_Fortran;
3217 Ty = types::TY_HLSL;
3218 }
else if (IsSYCL) {
3228 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3229 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3230 : clang::diag::err_drv_unknown_stdin_type);
3239 if (
const char *Ext = strrchr(
Value,
'.'))
3248 Ty = types::TY_HLSL;
3250 Ty = types::TY_Object;
3261 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3262 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3263 << getTypeName(OldTy) << getTypeName(Ty);
3268 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3269 Ty == types::TY_Object)
3270 Ty = types::TY_LLVM_BC;
3278 if (Ty != types::TY_Object) {
3279 if (Args.hasArg(options::OPT_ObjC))
3280 Ty = types::TY_ObjC;
3281 else if (Args.hasArg(options::OPT_ObjCXX))
3282 Ty = types::TY_ObjCXX;
3289 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3293 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3294 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3297 const char *Ext = strrchr(
Value,
'.');
3299 Ty = types::TY_Object;
3303 InputTypeArg->claim();
3307 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3308 Args.hasArgNoClaim(options::OPT_hipstdpar))
3312 Inputs.push_back(std::make_pair(Ty, A));
3314 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3315 StringRef
Value = A->getValue();
3318 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3319 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3322 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3323 StringRef
Value = A->getValue();
3326 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3327 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3333 Inputs.push_back(std::make_pair(types::TY_Object, A));
3335 }
else if (A->getOption().matches(options::OPT_x)) {
3344 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3345 InputType = types::TY_Object;
3352 }
else if (A->getOption().getID() == options::OPT_U) {
3353 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3354 StringRef Val = A->getValue(0);
3355 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3357 Diag(diag::warn_slash_u_filename) << Val;
3358 Diag(diag::note_use_dashdash);
3362 if (
CCCIsCPP() && Inputs.empty()) {
3366 Inputs.push_back(std::make_pair(types::TY_C, A));
3373class OffloadingActionBuilder final {
3375 bool IsValid =
false;
3381 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3384 std::map<Action *, const Arg *> HostActionToInputArgMap;
3387 class DeviceActionBuilder {
3391 enum ActionBuilderReturnCode {
3409 const ToolChain *FatBinaryToolChain =
nullptr;
3412 DerivedArgList &Args;
3421 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3424 :
C(
C), Args(Args), Inputs(Inputs),
3425 AssociatedOffloadKind(AssociatedOffloadKind) {}
3426 virtual ~DeviceActionBuilder() {}
3431 virtual ActionBuilderReturnCode
3432 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3435 return ABRT_Inactive;
3440 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3441 return ABRT_Inactive;
3445 virtual void appendTopLevelActions(
ActionList &AL) {}
3448 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3451 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3454 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3458 virtual bool initialize() {
return false; }
3461 virtual bool canUseBundlerUnbundler()
const {
return false; }
3465 bool isValid() {
return !ToolChains.empty(); }
3469 return AssociatedOffloadKind;
3475 class CudaActionBuilderBase :
public DeviceActionBuilder {
3479 bool CompileHostOnly =
false;
3480 bool CompileDeviceOnly =
false;
3482 bool EmitAsm =
false;
3485 SmallVector<BoundArch, 4> GpuArchList;
3491 Action *CudaFatBinary =
nullptr;
3494 bool IsActive =
false;
3497 bool Relocatable =
false;
3503 const CUIDOptions &CUIDOpts;
3506 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3508 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3509 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3511 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3512 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3513 options::OPT_fno_gpu_rdc,
false);
3516 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3523 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3526 if (!(IA->getType() == types::TY_CUDA ||
3527 IA->getType() == types::TY_HIP ||
3528 IA->getType() == types::TY_PP_HIP)) {
3531 return ABRT_Inactive;
3538 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3540 if (CompileHostOnly)
3541 return ABRT_Success;
3544 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3545 : types::TY_CUDA_DEVICE;
3546 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3547 CudaDeviceActions.push_back(
3548 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3551 return ABRT_Success;
3555 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3559 if (UA->getType() == types::TY_Object && !Relocatable)
3560 return ABRT_Inactive;
3562 CudaDeviceActions.clear();
3564 std::string
FileName = IA->getInputArg().getAsString(Args);
3570 const StringRef LibFileExt =
".lib";
3571 if (IA->getType() == types::TY_Object &&
3572 (!llvm::sys::path::has_extension(
FileName) ||
3574 llvm::sys::path::extension(
FileName).drop_front()) !=
3576 llvm::sys::path::extension(
FileName) == LibFileExt))
3577 return ABRT_Inactive;
3579 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3580 CudaDeviceActions.push_back(UA);
3581 UA->registerDependentActionInfo(ToolChain,
Arch,
3582 AssociatedOffloadKind);
3585 return ABRT_Success;
3588 return IsActive ? ABRT_Success : ABRT_Inactive;
3591 void appendTopLevelActions(
ActionList &AL)
override {
3593 auto AddTopLevel = [&](Action *A, BoundArch BA,
const ToolChain *TC) {
3594 OffloadAction::DeviceDependences Dep;
3595 Dep.
add(*A, *TC, BA, AssociatedOffloadKind);
3596 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3600 if (CudaFatBinary) {
3601 AddTopLevel(CudaFatBinary, {}, FatBinaryToolChain);
3602 CudaDeviceActions.clear();
3603 CudaFatBinary =
nullptr;
3607 if (CudaDeviceActions.empty())
3613 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3614 "Expecting one action per GPU architecture.");
3615 assert(ToolChains.size() == GpuArchList.size() &&
3616 "Expecting to have a toolchain per GPU architecture");
3617 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3618 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3620 CudaDeviceActions.clear();
3623 bool initialize()
override {
3638 assert(HostTC &&
"No toolchain for host compilation.");
3643 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3648 std::set<std::pair<BoundArch, const ToolChain *>> GpuArchs;
3650 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3652 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3653 GpuArchs.insert({
Arch, I.second});
3657 for (
auto [
Arch, TC] : GpuArchs) {
3658 GpuArchList.push_back(
Arch);
3659 ToolChains.push_back(TC);
3662 FatBinaryToolChain = ToolChains.front();
3663 CompileHostOnly =
C.getDriver().offloadHostOnly();
3664 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3665 EmitAsm = Args.getLastArg(options::OPT_S);
3673 class CudaActionBuilder final :
public CudaActionBuilderBase {
3675 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3677 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3681 ActionBuilderReturnCode
3682 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3684 PhasesTy &Phases)
override {
3686 return ABRT_Inactive;
3690 if (CudaDeviceActions.empty())
3691 return ABRT_Success;
3693 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3694 "Expecting one action per GPU architecture.");
3695 assert(!CompileHostOnly &&
3696 "Not expecting CUDA actions in host-only compilation.");
3706 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3709 for (
auto Ph : Phases) {
3714 if (Ph > FinalPhase)
3717 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3732 Action *AssembleAction = CudaDeviceActions[I];
3733 assert(AssembleAction->
getType() == types::TY_Object);
3734 assert(AssembleAction->
getInputs().size() == 1);
3740 OffloadAction::DeviceDependences DDep;
3742 DeviceActions.push_back(
3743 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3748 if (!DeviceActions.empty()) {
3750 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3752 if (!CompileDeviceOnly) {
3753 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3757 CudaFatBinary =
nullptr;
3762 CudaDeviceActions.clear();
3766 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3771 return ABRT_Success;
3775 "instructions should only occur "
3776 "before the backend phase!");
3779 for (Action *&A : CudaDeviceActions)
3780 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3782 return ABRT_Success;
3787 class HIPActionBuilder final :
public CudaActionBuilderBase {
3789 SmallVector<ActionList, 8> DeviceLinkerInputs;
3795 std::optional<bool> BundleOutput;
3796 std::optional<bool> EmitReloc;
3799 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3801 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3805 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3806 options::OPT_fno_hip_emit_relocatable)) {
3807 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3808 options::OPT_fno_hip_emit_relocatable,
false);
3812 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3813 <<
"-fhip-emit-relocatable"
3817 if (!CompileDeviceOnly) {
3818 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3819 <<
"-fhip-emit-relocatable"
3820 <<
"--offload-device-only";
3825 if (Args.hasArg(options::OPT_gpu_bundle_output,
3826 options::OPT_no_gpu_bundle_output))
3827 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3828 options::OPT_no_gpu_bundle_output,
true) &&
3829 (!EmitReloc || !*EmitReloc);
3832 bool canUseBundlerUnbundler()
const override {
return true; }
3834 ActionBuilderReturnCode
3835 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3837 PhasesTy &Phases)
override {
3839 return ABRT_Inactive;
3845 if (CudaDeviceActions.empty())
3846 return ABRT_Success;
3849 CudaDeviceActions.size() == GpuArchList.size()) &&
3850 "Expecting one action per GPU architecture.");
3851 assert(!CompileHostOnly &&
3852 "Not expecting HIP actions in host-only compilation.");
3854 bool ShouldLink = !EmitReloc || !*EmitReloc;
3857 !EmitAsm && ShouldLink) {
3863 bool ExplicitOffloadLTO = Args.hasArg(options::OPT_foffload_lto,
3864 options::OPT_foffload_lto_EQ);
3865 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3866 if (ExplicitOffloadLTO &&
3867 ToolChains[I]->isUsingLTO(Args, AssociatedOffloadKind)) {
3871 AL.push_back(CudaDeviceActions[I]);
3874 CudaDeviceActions[I] =
3875 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3881 if (ToolChains[I]->
getTriple().isSPIRV() ||
3882 (ToolChains[I]->
getTriple().isAMDGCN() &&
3883 GpuArchList[I].ArchName == StringRef(
"amdgcnspirv"))) {
3887 types::ID Output = Args.hasArg(options::OPT_S)
3889 : types::TY_LLVM_BC;
3891 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3897 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3899 AssociatedOffloadKind);
3900 AL.push_back(AssembleAction);
3903 CudaDeviceActions[I] =
3904 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3913 OffloadAction::DeviceDependences DDep;
3914 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3915 AssociatedOffloadKind);
3916 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3917 DDep, CudaDeviceActions[I]->getType());
3920 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3922 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3923 types::TY_HIP_FATBIN);
3925 if (!CompileDeviceOnly) {
3926 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3927 AssociatedOffloadKind);
3930 CudaFatBinary =
nullptr;
3935 CudaDeviceActions.clear();
3938 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3941 return ABRT_Success;
3947 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3948 auto LI = DeviceLinkerInputs.begin();
3949 for (
auto *A : CudaDeviceActions) {
3956 CudaDeviceActions.clear();
3957 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3961 for (
unsigned I = 0, E = CudaDeviceActions.size(); I != E; ++I)
3962 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3963 C, Args, CurPhase, CudaDeviceActions[I], AssociatedOffloadKind,
3964 ToolChains[I]->getLTOMode(Args, AssociatedOffloadKind));
3966 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3968 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3969 OffloadAction::DeviceDependences DDep;
3970 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3971 AssociatedOffloadKind);
3972 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3973 DDep, CudaDeviceActions[I]->getType());
3976 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3977 CudaDeviceActions.clear();
3980 return (CompileDeviceOnly &&
3981 (CurPhase == FinalPhase ||
3987 void appendLinkDeviceActions(
ActionList &AL)
override {
3988 if (DeviceLinkerInputs.size() == 0)
3991 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3992 "Linker inputs and GPU arch list sizes do not match.");
3998 for (
auto &LI : DeviceLinkerInputs) {
4000 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
4004 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
4007 OffloadAction::DeviceDependences DeviceLinkDeps;
4008 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
4009 AssociatedOffloadKind);
4010 Actions.push_back(
C.MakeAction<OffloadAction>(
4011 DeviceLinkDeps, DeviceLinkAction->getType()));
4014 DeviceLinkerInputs.clear();
4017 if (Args.hasArg(options::OPT_emit_llvm)) {
4025 OffloadAction::DeviceDependences DDeps;
4026 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
4027 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
4029 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
4030 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain, {},
4031 AssociatedOffloadKind);
4034 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
4040 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
4042 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
4050 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
4056 bool ShouldUseBundler;
4059 OffloadingActionBuilder(Compilation &
C, DerivedArgList &Args,
4067 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
4070 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4078 unsigned ValidBuilders = 0u;
4079 unsigned ValidBuildersSupportingBundling = 0u;
4080 for (
auto *SB : SpecializedBuilders) {
4081 IsValid = IsValid && !SB->initialize();
4084 if (SB->isValid()) {
4086 if (SB->canUseBundlerUnbundler())
4087 ++ValidBuildersSupportingBundling;
4091 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4093 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4094 options::OPT_no_gpu_bundle_output,
true);
4097 ~OffloadingActionBuilder() {
4098 for (
auto *SB : SpecializedBuilders)
4103 void recordHostAction(Action *HostAction,
const Arg *InputArg) {
4104 assert(HostAction &&
"Invalid host action");
4105 assert(InputArg &&
"Invalid input argument");
4106 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4107 assert(Loc->second == InputArg &&
4108 "host action mapped to multiple input arguments");
4117 addDeviceDependencesToHostAction(Action *HostAction,
const Arg *InputArg,
4119 DeviceActionBuilder::PhasesTy &Phases) {
4123 if (SpecializedBuilders.empty())
4126 assert(HostAction &&
"Invalid host action!");
4127 recordHostAction(HostAction, InputArg);
4129 OffloadAction::DeviceDependences DDeps;
4132 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4133 unsigned InactiveBuilders = 0u;
4134 unsigned IgnoringBuilders = 0u;
4135 for (
auto *SB : SpecializedBuilders) {
4136 if (!SB->isValid()) {
4141 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4146 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4151 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4152 OffloadKind |= SB->getAssociatedOffloadKind();
4157 if (IgnoringBuilders &&
4158 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4166 OffloadAction::HostDependence HDep(
4169 return C.MakeAction<OffloadAction>(HDep, DDeps);
4175 bool addHostDependenceToDeviceActions(Action *&HostAction,
4176 const Arg *InputArg) {
4180 recordHostAction(HostAction, InputArg);
4189 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4191 HostAction->
getType() == types::TY_PP_HIP)) {
4192 auto UnbundlingHostAction =
4193 C.MakeAction<OffloadUnbundlingJobAction>(HostAction);
4194 UnbundlingHostAction->registerDependentActionInfo(
4197 HostAction = UnbundlingHostAction;
4198 recordHostAction(HostAction, InputArg);
4201 assert(HostAction &&
"Invalid host action!");
4204 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4205 for (
auto *SB : SpecializedBuilders) {
4209 auto RetCode = SB->addDeviceDependences(HostAction);
4213 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4214 "Host dependence not expected to be ignored.!");
4218 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4219 OffloadKind |= SB->getAssociatedOffloadKind();
4224 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4233 bool appendTopLevelActions(
ActionList &AL, Action *HostAction,
4234 const Arg *InputArg) {
4236 recordHostAction(HostAction, InputArg);
4240 for (
auto *SB : SpecializedBuilders) {
4243 SB->appendTopLevelActions(OffloadAL);
4250 if (CanUseBundler && ShouldUseBundler && HostAction &&
4251 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4253 OffloadAL.push_back(HostAction);
4257 assert(HostAction == AL.back() &&
"Host action not in the list??");
4258 HostAction =
C.MakeAction<OffloadBundlingJobAction>(OffloadAL);
4259 recordHostAction(HostAction, InputArg);
4260 AL.back() = HostAction;
4262 AL.append(OffloadAL.begin(), OffloadAL.end());
4272 void appendDeviceLinkActions(
ActionList &AL) {
4273 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4276 SB->appendLinkDeviceActions(AL);
4280 Action *makeHostLinkAction() {
4283 appendDeviceLinkActions(DeviceAL);
4284 if (DeviceAL.empty())
4288 Action* HA =
nullptr;
4289 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4292 HA = SB->appendLinkHostActions(DeviceAL);
4306 Action *processHostLinkAction(Action *HostAction) {
4308 OffloadAction::DeviceDependences DDeps;
4309 for (
auto *SB : SpecializedBuilders) {
4313 SB->appendLinkDependences(DDeps);
4317 unsigned ActiveOffloadKinds = 0u;
4318 for (
auto &I : InputArgToOffloadKindMap)
4319 ActiveOffloadKinds |= I.second;
4331 for (
auto *A : HostAction->
inputs()) {
4332 auto ArgLoc = HostActionToInputArgMap.find(A);
4333 if (ArgLoc == HostActionToInputArgMap.end())
4335 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4336 if (OFKLoc == InputArgToOffloadKindMap.end())
4346 OffloadAction::HostDependence HDep(
4348 {}, ActiveOffloadKinds);
4349 return C.MakeAction<OffloadAction>(HDep, DDeps);
4354void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4359 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4360 StringRef
V = A->getValue();
4361 if (Inputs.size() > 1 && !
V.empty() &&
4362 !llvm::sys::path::is_separator(
V.back())) {
4364 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4365 << A->getSpelling() <<
V;
4366 Args.eraseArg(options::OPT__SLASH_Fo);
4371 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4372 StringRef
V = A->getValue();
4373 if (Inputs.size() > 1 && !
V.empty() &&
4374 !llvm::sys::path::is_separator(
V.back())) {
4376 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4377 << A->getSpelling() <<
V;
4378 Args.eraseArg(options::OPT__SLASH_Fa);
4383 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4384 if (A->getValue()[0] ==
'\0') {
4386 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4387 Args.eraseArg(options::OPT__SLASH_o);
4392 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4393 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4394 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4395 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4396 Args.eraseArg(options::OPT__SLASH_Yc);
4397 Args.eraseArg(options::OPT__SLASH_Yu);
4398 YcArg = YuArg =
nullptr;
4400 if (YcArg && Inputs.size() > 1) {
4401 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4402 Args.eraseArg(options::OPT__SLASH_Yc);
4410 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4411 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4412 Args.AddFlagArg(
nullptr,
4413 getOpts().getOption(options::OPT_frtlib_add_rpath));
4417 if (Args.hasArg(options::OPT_emit_llvm) &&
4418 !Args.hasArg(options::OPT_hip_link) &&
4419 !
C.getDefaultToolChain().getTriple().isSPIRV())
4420 Diag(clang::diag::err_drv_emit_llvm_link);
4421 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4422 C.getDefaultToolChain().isUsingLTO(Args) &&
4423 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4424 .starts_with_insensitive(
"lld"))
4425 Diag(clang::diag::err_drv_lto_without_lld);
4431 if (!Args.hasArg(options::OPT_dumpdir)) {
4432 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4433 Arg *Arg = Args.MakeSeparateArg(
4434 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4436 (FinalOutput ? FinalOutput->getValue()
4448 Args.eraseArg(options::OPT__SLASH_Fp);
4449 Args.eraseArg(options::OPT__SLASH_Yc);
4450 Args.eraseArg(options::OPT__SLASH_Yu);
4451 YcArg = YuArg =
nullptr;
4454 if (Args.hasArg(options::OPT_include_pch) &&
4455 Args.hasArg(options::OPT_ignore_pch)) {
4459 Args.eraseArg(options::OPT_include_pch);
4462 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4463 for (
auto &I : Inputs) {
4465 const Arg *InputArg = I.second;
4470 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4474 if (InitialPhase > FinalPhase) {
4475 if (InputArg->isClaimed())
4482 if (Args.hasArg(options::OPT_Qunused_arguments))
4488 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4489 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4493 (Args.getLastArg(options::OPT__SLASH_EP,
4494 options::OPT__SLASH_P) ||
4495 Args.getLastArg(options::OPT_E) ||
4496 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4498 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4499 << InputArg->getAsString(Args) << !!FinalPhaseArg
4500 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4502 Diag(clang::diag::warn_drv_input_file_unused)
4503 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4505 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4514 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4515 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
4520 Actions.push_back(ClangClPch);
4532 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4533 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4542 const llvm::opt::DerivedArgList &Args,
4545 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4547 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4550 bool HasAMDGCNHIPDevice =
false;
4552 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4554 const llvm::Triple &Tr = TC->
getTriple();
4557 HasAMDGCNHIPDevice =
true;
4559 return HasAMDGCNHIPDevice;
4564 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4566 if (!SuppressMissingInputWarning && Inputs.empty()) {
4567 Diag(clang::diag::err_drv_no_input_files);
4571 handleArguments(
C, Args, Inputs, Actions);
4573 bool UseNewOffloadingDriver = Args.hasFlag(
4574 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4576 bool HIPRDCDeviceOnlyFatBin =
4579 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4581 !Args.hasArg(options::OPT_emit_llvm) &&
4582 Args.hasFlag(options::OPT_gpu_bundle_output,
4583 options::OPT_no_gpu_bundle_output,
true);
4586 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4587 !UseNewOffloadingDriver
4588 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4596 for (
auto &I : Inputs) {
4598 const Arg *InputArg = I.second;
4610 if (HIPRDCDeviceOnlyFatBin && InputType == types::TY_LLVM_BC) {
4611 LinkerInputs.push_back(Current);
4617 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4625 if (!UseNewOffloadingDriver)
4626 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4632 if (!UseNewOffloadingDriver)
4633 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4634 Current, InputArg, Phase, PL.back(), FullPL);
4640 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4643 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4644 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4646 LinkerInputs.push_back(Current);
4656 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4657 MergerInputs.push_back(Current);
4674 C.getDefaultToolChain().getLTOMode(Args));
4677 if (NewCurrent == Current)
4680 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4683 Current = NewCurrent;
4687 if (UseNewOffloadingDriver)
4689 &HIPAsmDeviceActions);
4692 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4696 if (Current->
getType() == types::TY_Nothing)
4702 if (Current && !HIPAsmDeviceActions.empty()) {
4703 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4705 BundleInputs.append(HIPAsmDeviceActions);
4706 BundleInputs.push_back(Current);
4712 Actions.push_back(Current);
4715 if (!UseNewOffloadingDriver)
4716 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4724 if (LinkerInputs.empty()) {
4727 if (!UseNewOffloadingDriver)
4728 OffloadBuilder->appendDeviceLinkActions(Actions);
4731 if (!LinkerInputs.empty()) {
4732 if (!UseNewOffloadingDriver)
4733 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4734 LinkerInputs.push_back(Wrapper);
4739 }
else if (UseNewOffloadingDriver ||
4740 Args.hasArg(options::OPT_offload_link)) {
4743 HIPRDCDeviceOnlyFatBin ? types::TY_HIP_FATBIN : types::TY_Image);
4750 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4751 C.getDefaultToolChain().getTriple().isSPIRV();
4752 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4756 if (!UseNewOffloadingDriver)
4757 LA = OffloadBuilder->processHostLinkAction(LA);
4758 Actions.push_back(LA);
4762 if (!MergerInputs.empty())
4766 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4773 for (
auto &I : Inputs) {
4775 const Arg *InputArg = I.second;
4780 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4781 InputType == types::TY_Asm)
4786 for (
auto Phase : PhaseList) {
4790 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4795 if (InputType == types::TY_Object)
4802 assert(Phase == PhaseList.back() &&
4803 "merging must be final compilation step.");
4804 MergerInputs.push_back(Current);
4813 Actions.push_back(Current);
4817 if (!MergerInputs.empty())
4822 for (
auto Opt : {options::OPT_print_supported_cpus,
4823 options::OPT_print_supported_extensions,
4824 options::OPT_print_enabled_extensions}) {
4831 if (Arg *A = Args.getLastArg(Opt)) {
4832 if (Opt == options::OPT_print_supported_extensions &&
4833 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4834 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4835 !
C.getDefaultToolChain().getTriple().isARM()) {
4836 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4837 <<
"--print-supported-extensions";
4840 if (Opt == options::OPT_print_enabled_extensions &&
4841 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4842 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4843 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4844 <<
"--print-enabled-extensions";
4851 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4854 for (
auto &I : Inputs)
4859 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4860 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4861 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4867 if (TC.requiresObjcopy(Args)) {
4868 Action *LastAction = Actions.back();
4870 if (LastAction->
getType() == types::TY_Object) {
4878 auto ValInfo = TC.getValidationInfo(Args);
4879 if (ValInfo.NeedsValidation) {
4880 Action *LastAction = Actions.back();
4881 if (LastAction->
getType() == types::TY_Object) {
4883 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4890 if (TC.requiresBinaryTranslation(Args)) {
4891 Action *LastAction = Actions.back();
4895 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4896 LastAction->
getType() == types::TY_Object)
4898 LastAction, types::TY_DX_CONTAINER));
4903 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4909 const llvm::opt::DerivedArgList &Args,
4911 const llvm::Triple &Triple) {
4916 if (Triple.isNVPTX() && (
Arch.isUnknown() || !
Arch.isNVPTX())) {
4917 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4918 <<
"CUDA" << ArchStr;
4920 }
else if (Triple.isAMDGPU()) {
4921 if (
Arch.isUnknown() || (!
Arch.isAMDGPU() && !
Arch.isAMDGCNSPIRV())) {
4922 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4923 <<
"HIP" << ArchStr;
4927 if (Triple.getSubArch() != llvm::Triple::NoSubArch) {
4929 if (ArchSubArch != Triple.getSubArch() &&
4930 llvm::AMDGPU::getMajorSubArch(ArchSubArch) != Triple.getSubArch()) {
4931 C.getDriver().Diag(clang::diag::err_target_unsupported_arch)
4932 << ArchStr << Triple.getArchName();
4941 if (
Arch.isAMDGPU() ||
Arch.isAMDGCNSPIRV()) {
4942 llvm::StringMap<bool> Features;
4945 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4957static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4959 llvm::Triple Triple) {
4960 if (!Triple.isAMDGPU())
4961 return std::nullopt;
4963 std::set<StringRef> ArchSet;
4964 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4968llvm::SmallVector<BoundArch>
4972 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4973 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4974 options::OPT_no_offload_arch_EQ)) {
4975 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4977 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4979 :
"--no-offload-arch");
4982 llvm::DenseSet<StringRef> Archs;
4983 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
4986 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4987 for (StringRef
Arch : Arg->getValues()) {
4988 if (
Arch ==
"native" ||
Arch.empty()) {
4993 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4997 for (
auto ArchStr : *GPUsOrErr) {
4999 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
5000 if (!CanonicalStr.empty())
5001 Archs.insert(CanonicalStr);
5006 StringRef CanonicalStr =
5008 if (!CanonicalStr.empty())
5009 Archs.insert(CanonicalStr);
5014 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
5015 for (StringRef
Arch : Arg->getValues()) {
5016 if (
Arch ==
"all") {
5021 Archs.erase(ArchStr);
5027 if (
auto ConflictingArchs =
5029 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
5030 << ConflictingArchs->first << ConflictingArchs->second;
5033 bool HasSubArch = TC.
getTriple().isAMDGCN() &&
5034 TC.
getTriple().getSubArch() != llvm::Triple::NoSubArch;
5035 if (Archs.empty() && !HasSubArch) {
5045 Archs.insert(StringRef());
5048 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
5049 .getLastArg(options::OPT_march_EQ)) {
5050 Archs.insert(Arg->getValue());
5055 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
5056 <<
"--offload-arch";
5057 }
else if (!ArchsOrErr->empty()) {
5058 for (
auto Arch : *ArchsOrErr)
5059 Archs.insert(Args.MakeArgStringRef(
Arch));
5061 Archs.insert(StringRef());
5065 }
else if (Archs.empty() && HasSubArch) {
5072 llvm::StringRef ArchStr = TripleOffloadArch.
isUnknown()
5075 StringRef CanonicalStr =
5077 if (!CanonicalStr.empty())
5078 Archs.insert(CanonicalStr);
5081 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
5082 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
5089 Result.reserve(Sorted.size());
5090 for (StringRef
Arch : Sorted)
5097 const InputTy &Input, StringRef CUID,
5107 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5109 bool HIPRelocatableObj =
5111 Args.hasFlag(options::OPT_fhip_emit_relocatable,
5112 options::OPT_fno_hip_emit_relocatable,
false);
5114 if (!HIPNoRDC && HIPRelocatableObj)
5115 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
5116 <<
"-fhip-emit-relocatable"
5120 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
5121 <<
"-fhip-emit-relocatable"
5122 <<
"--offload-device-only";
5130 bool UsesLLVMOffloading = Args.hasArg(
5131 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
5143 auto TCRange =
C.getOffloadToolChains(Kind);
5144 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5145 ToolChains.push_back(TI->second);
5147 if (ToolChains.empty())
5151 const Arg *InputArg = Input.second;
5160 for (
const ToolChain *TC : ToolChains) {
5162 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5163 DeviceActions.push_back(
5164 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5168 if (DeviceActions.empty())
5174 HostAction->
getType() != types::TY_Nothing &&
5184 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5193 auto *TCAndArch = TCAndArchs.begin();
5194 for (
Action *&A : DeviceActions) {
5195 if (A->
getType() == types::TY_Nothing)
5202 TCAndArch->first->getLTOMode(Args, Kind));
5206 HostAction->
getType() != types::TY_Nothing) {
5213 TCAndArch->second, Kind);
5215 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5225 for (
Action *&A : DeviceActions) {
5230 OffloadTriple && OffloadTriple->isSPIRV() &&
5231 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5232 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5234 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5235 A->
getType() != types::TY_LTO_BC) ||
5242 auto *TCAndArch = TCAndArchs.begin();
5243 for (
Action *A : DeviceActions) {
5244 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5246 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5253 A->
getType() == types::TY_Object &&
5254 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5256 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
5265 bool ShouldBundleHIP =
5266 Args.hasFlag(options::OPT_gpu_bundle_output,
5267 options::OPT_no_gpu_bundle_output,
false) ||
5268 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5270 return A->
getType() != types::TY_Image;
5277 if (OffloadActions.empty())
5282 (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) ||
5283 Args.hasArg(options::OPT_cuda_emit_nvcc_abi))) {
5287 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5294 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5295 DDep.
add(*FatbinAction,
5298 }
else if (!UsesLLVMOffloading && HIPNoRDC) {
5301 if (HIPAsmBundleDeviceOut &&
5303 for (
Action *OA : OffloadActions)
5304 HIPAsmBundleDeviceOut->push_back(OA);
5318 DDep.
add(*PackagerAction,
5327 {},
C.getActiveOffloadKinds());
5336 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5337 return A->
getType() == types::TY_Nothing;
5341 {}, SingleDeviceOutput ? DDep : DDeps);
5342 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5348 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5358 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5364 llvm_unreachable(
"link action invalid here.");
5366 llvm_unreachable(
"ifsmerge action invalid here.");
5371 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5372 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5373 OutputTy = types::TY_Dependencies;
5378 if (!Args.hasFlag(options::OPT_frewrite_includes,
5379 options::OPT_fno_rewrite_includes,
false) &&
5380 !Args.hasFlag(options::OPT_frewrite_imports,
5381 options::OPT_fno_rewrite_imports,
false) &&
5382 !Args.hasFlag(options::OPT_fdirectives_only,
5383 options::OPT_fno_directives_only,
false) &&
5387 "Cannot preprocess this input type!");
5393 if (Args.hasArg(options::OPT_extract_api))
5398 if (Input->
getType() == types::TY_CXXStdModule ||
5399 Input->
getType() == types::TY_PP_CXXStdModule)
5401 Input, getPrecompiledType(Input->
getType()));
5409 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5410 (Input->
getType() == driver::types::TY_CXXModule ||
5411 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5412 !Args.getLastArg(options::OPT__precompile) &&
5413 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5418 "Cannot precompile this input type!");
5422 const char *ModName =
nullptr;
5423 if (OutputTy == types::TY_PCH) {
5424 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5425 ModName = A->getValue();
5427 OutputTy = types::TY_ModuleFile;
5430 if (Args.hasArg(options::OPT_fsyntax_only)) {
5432 OutputTy = types::TY_Nothing;
5438 if (Args.hasArg(options::OPT_fsyntax_only))
5440 if (Args.hasArg(options::OPT_rewrite_objc))
5442 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5444 types::TY_RewrittenLegacyObjC);
5445 if (Args.hasArg(options::OPT__analyze))
5447 if (Args.hasArg(options::OPT_emit_ast))
5449 if (Args.hasArg(options::OPT_emit_cir))
5451 if (Args.hasArg(options::OPT_module_file_info))
5453 if (Args.hasArg(options::OPT_verify_pch))
5455 if (Args.hasArg(options::OPT_extract_api))
5462 if (!IsDeviceOffload) {
5464 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5465 !Args.hasArg(options::OPT_emit_llvm))
5466 Output = types::TY_PP_Asm;
5467 else if (Args.hasArg(options::OPT_S))
5468 Output = types::TY_LTO_IR;
5470 Output = types::TY_LTO_BC;
5474 if (Args.hasArg(options::OPT_emit_llvm)) {
5476 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5478 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5482 Output = types::TY_PP_Asm;
5483 }
else if (Args.hasArg(options::OPT_S)) {
5484 Output = types::TY_LTO_IR;
5486 Output = types::TY_LTO_BC;
5490 if (Args.hasArg(options::OPT_emit_llvm) ||
5493 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5502 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5503 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
5514 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5536 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
5556 if (!OffloadJobs.isValid())
5557 D.
Diag(diag::err_drv_invalid_int_value)
5558 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
5560 OffloadJobs.A->claim();
5564 for (
auto &Job :
C.getJobs()) {
5568 Job.setOffloadDeviceParallelJobGroup(
5574 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5576 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5596 unsigned NumOutputs = 0;
5597 unsigned NumIfsOutputs = 0;
5598 for (
const Action *A :
C.getActions()) {
5608 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
5609 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
5612 if (A->
getType() != types::TY_Nothing &&
5614 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5616 0 == NumIfsOutputs++) ||
5621 A->
getType() == types::TY_Nothing &&
5622 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5623 NumOutputs += A->
size();
5626 if (NumOutputs > 1) {
5627 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5628 FinalOutput =
nullptr;
5632 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5635 llvm::StringSet<> ArchNames;
5636 if (RawTriple.isOSBinFormatMachO())
5637 for (
const Arg *A :
C.getArgs())
5638 if (A->getOption().matches(options::OPT_arch))
5639 ArchNames.insert(A->getValue());
5642 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5643 for (
Action *A :
C.getActions()) {
5650 const char *LinkingOutput =
nullptr;
5653 LinkingOutput = FinalOutput->getValue();
5661 ArchNames.size() > 1 ||
5662 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
5663 LinkingOutput, CachedResults,
5670 for (
auto &J :
C.getJobs())
5671 J.InProcess =
false;
5678 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5679 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5684 const char *LinkingOutput =
nullptr;
5686 LinkingOutput = FinalOutput->getValue();
5693 using namespace llvm;
5696 <<
"output=" << LinkingOutput;
5697 outs() <<
", total="
5698 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5700 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5701 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5705 llvm::raw_string_ostream Out(Buffer);
5706 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5709 llvm::sys::printArg(Out, LinkingOutput,
true);
5710 Out <<
',' << ProcStat->TotalTime.count() <<
','
5711 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5716 llvm::sys::fs::OF_Append |
5717 llvm::sys::fs::OF_Text);
5722 llvm::errs() <<
"ERROR: Cannot lock file "
5724 <<
toString(L.takeError()) <<
"\n";
5735 bool ReportUnusedArguments =
5736 !Diags.hasErrorOccurred() &&
5737 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5740 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5742 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5745 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5746 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5748 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5752 return strstr(J.getCreator().getShortName(),
"assembler");
5754 for (Arg *A :
C.getArgs()) {
5758 if (!A->isClaimed()) {
5764 const Option &Opt = A->getOption();
5765 if (Opt.getKind() == Option::FlagClass) {
5766 bool DuplicateClaimed =
false;
5768 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5769 if (AA->isClaimed()) {
5770 DuplicateClaimed =
true;
5775 if (DuplicateClaimed)
5781 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5783 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5788 !
C.getActions().empty()) {
5789 Diag(diag::err_drv_unsupported_opt_for_target)
5791 }
else if (ReportUnusedArguments) {
5792 Diag(clang::diag::warn_drv_unused_argument)
5793 << A->getAsString(
C.getArgs());
5803class ToolSelector final {
5814 bool IsHostSelector;
5825 bool CanBeCollapsed =
true) {
5827 if (Inputs.size() != 1)
5830 Action *CurAction = *Inputs.begin();
5831 if (CanBeCollapsed &&
5837 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5841 if (!IsHostSelector) {
5842 if (OA->hasSingleDeviceDependence(
true)) {
5844 OA->getSingleDeviceDependence(
true);
5845 if (CanBeCollapsed &&
5848 SavedOffloadAction.push_back(OA);
5849 return dyn_cast<JobAction>(CurAction);
5851 }
else if (OA->hasHostDependence()) {
5852 CurAction = OA->getHostDependence();
5853 if (CanBeCollapsed &&
5856 SavedOffloadAction.push_back(OA);
5857 return dyn_cast<JobAction>(CurAction);
5862 return dyn_cast<JobAction>(CurAction);
5866 bool canCollapseAssembleAction()
const {
5867 return TC.useIntegratedAs() && !SaveTemps &&
5868 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5869 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5870 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5871 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5875 bool canCollapsePreprocessorAction()
const {
5876 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5877 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5878 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5883 struct JobActionInfo final {
5885 const JobAction *JA =
nullptr;
5893 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5894 ArrayRef<JobActionInfo> &ActionInfo,
5895 unsigned ElementNum) {
5896 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5897 for (
unsigned I = 0; I < ElementNum; ++I)
5898 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5899 ActionInfo[I].SavedOffloadAction.end());
5912 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5915 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5917 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5918 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5919 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5920 if (!AJ || !BJ || !CJ)
5924 const Tool *
T = TC.SelectTool(*CJ);
5931 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5937 const Tool *BT = TC.SelectTool(*BJ);
5942 if (!
T->hasIntegratedAssembler())
5945 Inputs = CJ->getInputs();
5946 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5950 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5953 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5955 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5956 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5961 const Tool *
T = TC.SelectTool(*BJ);
5965 if (!
T->hasIntegratedAssembler())
5968 Inputs = BJ->getInputs();
5969 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5973 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5976 if (ActionInfo.size() < 2)
5978 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5979 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5983 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5984 for (
auto &Input : AI.JA->getInputs())
5995 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5996 if (SaveTemps && !InputIsBitcode)
6000 const Tool *
T = TC.SelectTool(*CJ);
6007 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
6013 Inputs = CJ->getInputs();
6014 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
6023 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
6025 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
6031 for (Action *A : Inputs) {
6032 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
6034 NewInputs.push_back(A);
6040 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
6041 PreprocessJobOffloadActions.end());
6042 NewInputs.append(PJ->input_begin(), PJ->input_end());
6048 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
6050 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
6052 assert(BaseAction &&
"Invalid base action.");
6068 SmallVector<JobActionInfo, 5> ActionChain(1);
6069 ActionChain.back().JA = BaseAction;
6070 while (ActionChain.back().JA) {
6071 const Action *CurAction = ActionChain.back().JA;
6074 ActionChain.resize(ActionChain.size() + 1);
6075 JobActionInfo &AI = ActionChain.back();
6079 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
6083 ActionChain.pop_back();
6091 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
6092 CollapsedOffloadAction);
6094 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
6096 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
6102 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
6115 std::string TriplePlusArch = TC->
getTriple().normalize();
6117 TriplePlusArch +=
"-";
6120 TriplePlusArch +=
"-";
6122 return TriplePlusArch;
6127 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6128 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6131 std::pair<const Action *, std::string> ActionTC = {
6133 auto CachedResult = CachedResults.find(ActionTC);
6134 if (CachedResult != CachedResults.end()) {
6135 return CachedResult->second;
6138 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
6139 TargetDeviceOffloadKind);
6140 CachedResults[ActionTC] =
Result;
6145 const JobAction *JA,
const char *BaseInput,
6148 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6159 if (!
Arch.empty()) {
6160 OffloadingPrefix +=
"-";
6161 OffloadingPrefix +=
Arch.ArchName;
6164 C.getDriver().isSaveTempsEnabled()) {
6171 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6172 Path = A->getValue();
6173 if (llvm::sys::fs::is_directory(Path)) {
6175 ? llvm::sys::path::stem(
Result.getFilename())
6176 : llvm::sys::path::stem(BaseInput));
6177 Tmp += OffloadingPrefix;
6179 llvm::sys::path::append(Path, Tmp);
6182 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6185 Path = DumpDir->getValue();
6186 Path += llvm::sys::path::stem(BaseInput);
6187 Path += OffloadingPrefix;
6189 }
else if (!OffloadingPrefix.empty()) {
6193 TraceName += OffloadingPrefix;
6194 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6195 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6196 llvm::sys::path::append(Path, TraceName);
6199 Path =
Result.getFilename();
6200 llvm::sys::path::replace_extension(Path,
"json");
6203 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6204 C.addTimeTraceFile(ResultFile, JA);
6205 C.addResultFile(ResultFile, JA);
6210 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6211 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6214 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6218 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
6219 C.setCurrentBoundArch(BA);
6220 auto RestoreBoundArch =
6221 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
6224 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6225 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6257 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6259 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6260 BoundArch DepBoundArch) {
6262 !DepBoundArch.
empty(),
6263 LinkingOutput, CachedResults,
6273 OA->doOnEachDependence(
6274 BuildingForOffloadDevice,
6275 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6277 C, DepA, DepTC, DepBoundArch,
false,
6278 !DepBoundArch.
empty(), LinkingOutput,
6282 A = BuildingForOffloadDevice
6283 ? OA->getSingleDeviceDependence(
true)
6284 : OA->getHostDependence();
6288 std::pair<const Action *, std::string> ActionTC = {
6289 OA->getHostDependence(),
6291 auto It = CachedResults.find(ActionTC);
6292 if (It != CachedResults.end()) {
6294 Inputs.append(OffloadDependencesInputInfo);
6299 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6302 const Arg &Input = IA->getInputArg();
6304 if (Input.getOption().matches(options::OPT_INPUT)) {
6305 const char *
Name = Input.getValue();
6308 return {InputInfo(A, &Input,
"")};
6311 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6312 const ToolChain *TC;
6313 BoundArch ArchName = BAA->
getArch();
6315 if (!ArchName.
empty())
6316 TC = &getToolChain(
C.getArgs(),
6320 TC = &
C.getDefaultToolChain();
6323 MultipleArchs, LinkingOutput, CachedResults,
6324 TargetDeviceOffloadKind);
6335 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
6338 return {InputInfo()};
6342 for (
const auto *OA : CollapsedOffloadActions)
6344 BuildingForOffloadDevice,
6345 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6347 C, DepA, DepTC, DepBoundArch,
false,
6348 !DepBoundArch.
empty(), LinkingOutput,
6354 for (
const Action *Input : Inputs) {
6358 bool SubJobAtTopLevel =
6361 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6366 const char *BaseInput = InputInfos[0].getBaseInput();
6367 for (
auto &Info : InputInfos) {
6368 if (Info.isFilename()) {
6369 BaseInput = Info.getBaseInput();
6376 if (JA->
getType() == types::TY_dSYM)
6377 BaseInput = InputInfos[0].getFilename();
6380 if (!OffloadDependencesInputInfo.empty())
6381 InputInfos.append(OffloadDependencesInputInfo.begin(),
6382 OffloadDependencesInputInfo.end());
6385 llvm::Triple EffectiveTriple;
6386 const ToolChain &ToolTC =
T->getToolChain();
6387 const ArgList &Args =
6389 if (InputInfos.size() != 1) {
6394 EffectiveTriple = llvm::Triple(
6397 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6402 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6406 for (
auto &UI : UA->getDependentActionsInfo()) {
6408 "Unbundling with no offloading??");
6415 UI.DependentOffloadKind, UI.DependentToolChain->getTripleString(),
6417 auto CurI = InputInfo(
6426 UnbundlingResults.push_back(CurI);
6435 Arch = BoundArch(UI.DependentBoundArch);
6440 UI.DependentOffloadKind)}] = {
6446 std::pair<const Action *, std::string> ActionTC = {
6448 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6449 "Result does not exist??");
6450 Result = CachedResults[ActionTC].front();
6451 }
else if (JA->
getType() == types::TY_Nothing)
6452 Result = {InputInfo(A, BaseInput)};
6463 MultipleArchs, OffloadingPrefix),
6470 llvm::errs() <<
"# \"" <<
T->getToolChain().getEffectiveTriple().str()
6471 <<
'"' <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6472 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6473 llvm::errs() << InputInfos[i].getAsString();
6475 llvm::errs() <<
", ";
6477 if (UnbundlingResults.empty())
6478 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6480 llvm::errs() <<
"], outputs: [";
6481 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6482 llvm::errs() << UnbundlingResults[i].getAsString();
6484 llvm::errs() <<
", ";
6486 llvm::errs() <<
"] \n";
6489 if (UnbundlingResults.empty())
6490 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6492 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6493 Args, LinkingOutput);
6499 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6500 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6512 if (ArgValue.empty()) {
6514 Filename = BaseName;
6515 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6517 llvm::sys::path::append(Filename, BaseName);
6520 if (!llvm::sys::path::has_extension(ArgValue)) {
6525 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6530 llvm::sys::path::replace_extension(Filename, Extension);
6533 return Args.MakeArgString(Filename.c_str());
6548 StringRef Suffix,
bool MultipleArchs,
6549 StringRef BoundArchStr,
6550 bool NeedUniqueDirectory)
const {
6552 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6553 std::optional<std::string> CrashDirectory =
6555 ? std::string(A->getValue())
6556 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6557 if (CrashDirectory) {
6558 if (!
getVFS().exists(*CrashDirectory))
6559 llvm::sys::fs::create_directories(*CrashDirectory);
6561 llvm::sys::path::append(Path, Prefix);
6562 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6563 if (std::error_code EC =
6564 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6565 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6569 if (MultipleArchs && !BoundArchStr.empty()) {
6570 if (NeedUniqueDirectory) {
6572 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
6583 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6598 const char *BaseInput) {
6600 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6601 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6606 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6611 bool AtTopLevel,
bool MultipleArchs,
6612 StringRef OffloadingPrefix)
const {
6615 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6617 auto CreateTempOutputPath = [&](StringRef Prefix) {
6618 const char *Suffix =
6623 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
6624 const bool NeedUniqueDirectory =
6627 Triple.isOSDarwin();
6629 NeedUniqueDirectory);
6634 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
6635 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
6636 StringRef Filename = llvm::sys::path::filename(BaseInput);
6637 StringRef Stem = llvm::sys::path::stem(Filename);
6638 return CreateTempOutputPath(Stem);
6643 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6644 return C.addResultFile(FinalOutput->getValue(), &JA);
6648 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6650 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6652 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6653 NameArg = A->getValue();
6654 return C.addResultFile(
6664 if (JA.
getType() == types::TY_ModuleFile &&
6665 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6669 if (JA.
getType() == types::TY_PP_Asm &&
6670 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6671 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6674 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
6677 if ((JA.
getType() == types::TY_Object &&
6678 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6679 JA.
getType() == types::TY_DX_CONTAINER) {
6680 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6681 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6682 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6683 "expected DXIL or SPIR-V triple for HLSL output path");
6688 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6690 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
6691 StringRef
Name = llvm::sys::path::filename(BaseInput);
6692 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6698 if (JA.
getType() == types::TY_PP_Asm &&
6699 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6700 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6702 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6703 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6704 return C.addResultFile(
6709 if (JA.
getType() == types::TY_API_INFO &&
6710 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6711 C.getArgs().hasArg(options::OPT_o))
6712 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6713 <<
C.getArgs().getLastArgValue(options::OPT_o);
6720 bool SpecifiedModuleOutput =
6721 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6722 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6723 if (MultipleArchs && SpecifiedModuleOutput)
6724 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6729 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6730 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6736 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6738 StringRef
Name = llvm::sys::path::filename(BaseInput);
6739 return CreateTempOutputPath(
Name.split(
'.').first);
6748 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6753 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6754 llvm::sys::path::filename(BasePath));
6755 BaseName = ExternalPath;
6757 BaseName = BasePath;
6759 BaseName = llvm::sys::path::filename(BasePath);
6762 const char *NamedOutput;
6764 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6765 JA.
getType() == types::TY_LLVM_BC ||
6766 JA.
getType() == types::TY_LLVM_IR) &&
6767 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6771 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6775 }
else if (JA.
getType() == types::TY_Image &&
6776 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6777 options::OPT__SLASH_o)) {
6781 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6785 }
else if (JA.
getType() == types::TY_Image) {
6795 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6796 options::OPT_fno_gpu_rdc,
false);
6798 if (UseOutExtension) {
6800 llvm::sys::path::replace_extension(Output,
"");
6802 Output += OffloadingPrefix;
6803 if (MultipleArchs && !BoundArchStr.empty()) {
6805 Output.append(BoundArchStr);
6807 if (UseOutExtension)
6809 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6812 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6813 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6814 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6817 .getLastArg(options::OPT__SLASH_o)
6822 const char *Suffix =
6824 assert(Suffix &&
"All types used for output should have a suffix.");
6826 std::string::size_type End = std::string::npos;
6828 End = BaseName.rfind(
'.');
6830 Suffixed += OffloadingPrefix;
6831 if (MultipleArchs && !BoundArchStr.empty()) {
6833 Suffixed.append(BoundArchStr);
6838 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6839 const llvm::opt::DerivedArgList &Args) {
6846 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6848 Args.hasFlag(options::OPT_offload_new_driver,
6849 options::OPT_no_offload_new_driver,
true))) ||
6856 bool IsLinkerWrapper =
6858 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6859 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6860 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6862 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6866 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6870 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6871 JA.
getType() != types::TY_PCH) {
6872 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6874 llvm::sys::path::remove_filename(TempPath);
6875 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6876 llvm::sys::path::append(TempPath, OutputFileName);
6877 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6883 bool SameFile =
false;
6885 llvm::sys::fs::current_path(
Result);
6886 llvm::sys::path::append(
Result, BaseName);
6887 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6890 StringRef
Name = llvm::sys::path::filename(BaseInput);
6891 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6895 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6901 llvm::sys::path::remove_filename(BasePath);
6902 if (BasePath.empty())
6903 BasePath = NamedOutput;
6905 llvm::sys::path::append(BasePath, NamedOutput);
6906 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6909 return C.addResultFile(NamedOutput, &JA);
6915 -> std::optional<std::string> {
6918 for (
const auto &
Dir : P) {
6922 llvm::sys::path::append(P,
Name);
6923 if (llvm::sys::fs::exists(Twine(P)))
6924 return std::string(P);
6926 return std::nullopt;
6933 llvm::sys::path::append(R,
Name);
6934 if (llvm::sys::fs::exists(Twine(R)))
6935 return std::string(R);
6938 llvm::sys::path::append(P,
Name);
6939 if (llvm::sys::fs::exists(Twine(P)))
6940 return std::string(P);
6944 if (std::optional<std::string> IntrPath =
6947 llvm::sys::path::append(P,
Name);
6948 if (llvm::sys::fs::exists(P))
6949 return std::string(P);
6954 llvm::sys::path::append(D,
"..",
Name);
6955 if (llvm::sys::fs::exists(Twine(D)))
6956 return std::string(D);
6965 llvm::sys::path::append(R2,
"..",
"..",
Name);
6966 if (llvm::sys::fs::exists(Twine(R2)))
6967 return std::string(R2);
6969 return std::string(
Name);
6972void Driver::generatePrefixedToolNames(
6976 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6977 Names.emplace_back(
Tool);
6981 llvm::sys::path::append(Dir, Name);
6982 if (llvm::sys::fs::can_execute(Twine(Dir)))
6984 llvm::sys::path::remove_filename(Dir);
6990 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6995 if (llvm::sys::fs::is_directory(PrefixDir)) {
6998 return std::string(P);
7001 if (llvm::sys::fs::can_execute(Twine(P)))
7002 return std::string(P);
7007 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
7015 for (
const auto &Path : List) {
7018 return std::string(P);
7022 if (llvm::ErrorOr<std::string> P =
7023 llvm::sys::findProgramByName(TargetSpecificExecutable))
7027 return std::string(
Name);
7032 std::string error =
"<NOT PRESENT>";
7034 if (
C.getArgs().hasArg(options::OPT_nostdlib))
7039 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
7056 llvm::sys::path::remove_filename(path);
7057 llvm::sys::path::append(path,
"libc++.modules.json");
7058 if (TC.
getVFS().exists(path))
7059 return static_cast<std::string
>(path);
7064 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
7067 return evaluate(
"libc++.a").value_or(error);
7071 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
7075 llvm::sys::path::remove_filename(path);
7076 llvm::sys::path::append(path,
"libstdc++.modules.json");
7077 if (TC.
getVFS().exists(path))
7078 return static_cast<std::string
>(path);
7083 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
7086 return evaluate(
"libstdc++.a").value_or(error);
7095 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
7097 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7101 return std::string(Path);
7106 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
7108 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7112 return std::string(Path);
7117 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
7121 Output = FpArg->getValue();
7125 if (!llvm::sys::path::has_extension(Output))
7128 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
7129 Output = YcArg->getValue();
7132 llvm::sys::path::replace_extension(Output,
".pch");
7134 return std::string(Output);
7137const ToolChain &Driver::getOffloadToolChain(
7139 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
7140 std::unique_ptr<ToolChain> &TC =
7141 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
7142 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
7144 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
7147 switch (
Target.getOS()) {
7148 case llvm::Triple::CUDA:
7149 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7152 case llvm::Triple::AMDHSA:
7158 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
7159 HostTC.get(), Kind);
7167 switch (
Target.getArch()) {
7168 case llvm::Triple::amdgpu:
7169 case llvm::Triple::r600:
7170 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
7171 HostTC.get(), Kind);
7173 case llvm::Triple::spir:
7174 case llvm::Triple::spir64:
7175 case llvm::Triple::spirv:
7176 case llvm::Triple::spirv32:
7177 case llvm::Triple::spirv64:
7180 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
7184 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7188 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7192 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7206 return getToolChain(Args,
Target);
7210const ToolChain &Driver::getToolChain(
const ArgList &Args,
7211 const llvm::Triple &
Target)
const {
7213 auto &TC = ToolChains[
Target.str()];
7215 switch (
Target.getOS()) {
7216 case llvm::Triple::AIX:
7217 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7219 case llvm::Triple::Haiku:
7220 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7222 case llvm::Triple::Darwin:
7223 case llvm::Triple::MacOSX:
7224 case llvm::Triple::IOS:
7225 case llvm::Triple::TvOS:
7226 case llvm::Triple::WatchOS:
7227 case llvm::Triple::XROS:
7228 case llvm::Triple::DriverKit:
7229 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7231 case llvm::Triple::DragonFly:
7232 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7234 case llvm::Triple::OpenBSD:
7235 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7237 case llvm::Triple::NetBSD:
7238 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7240 case llvm::Triple::FreeBSD:
7242 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7245 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7247 case llvm::Triple::Linux:
7248 case llvm::Triple::ELFIAMCU:
7249 if (
Target.getArch() == llvm::Triple::hexagon)
7250 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7252 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7253 !
Target.hasEnvironment())
7254 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7257 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7259 else if (
Target.getArch() == llvm::Triple::ve)
7260 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7261 else if (
Target.isOHOSFamily())
7262 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7263 else if (
Target.isWALI())
7264 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7266 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7268 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7270 case llvm::Triple::Fuchsia:
7271 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7273 case llvm::Triple::Managarm:
7274 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7276 case llvm::Triple::Serenity:
7277 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7279 case llvm::Triple::Solaris:
7280 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7282 case llvm::Triple::CUDA:
7283 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7285 case llvm::Triple::AMDHSA: {
7286 if (
Target.getArch() == llvm::Triple::spirv64) {
7287 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7293 TC = std::make_unique<toolchains::AMDGPUToolChain>(
7295 ShouldLinkDeviceLibs);
7299 case llvm::Triple::AMDPAL:
7300 case llvm::Triple::Mesa3D:
7301 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7303 case llvm::Triple::UEFI:
7304 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7306 case llvm::Triple::Win32:
7307 switch (
Target.getEnvironment()) {
7309 if (
Target.isOSBinFormatELF())
7310 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7311 else if (
Target.isOSBinFormatMachO())
7312 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7314 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7316 case llvm::Triple::GNU:
7317 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7319 case llvm::Triple::Cygnus:
7320 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7322 case llvm::Triple::Itanium:
7323 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7326 case llvm::Triple::MSVC:
7327 case llvm::Triple::UnknownEnvironment:
7328 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7329 .starts_with_insensitive(
"bfd"))
7330 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7334 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7338 case llvm::Triple::PS4:
7339 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7341 case llvm::Triple::PS5:
7342 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7344 case llvm::Triple::Hurd:
7345 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7347 case llvm::Triple::LiteOS:
7348 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7350 case llvm::Triple::ZOS:
7351 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7353 case llvm::Triple::Vulkan:
7354 case llvm::Triple::ShaderModel:
7355 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7356 Target.getArch() == llvm::Triple::spirv64) &&
7358 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7360 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7362 case llvm::Triple::ChipStar:
7363 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7368 switch (
Target.getArch()) {
7369 case llvm::Triple::tce:
7370 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7372 case llvm::Triple::tcele:
7373 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7375 case llvm::Triple::tcele64:
7377 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7379 case llvm::Triple::hexagon:
7380 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7383 case llvm::Triple::lanai:
7384 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7386 case llvm::Triple::xcore:
7387 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7389 case llvm::Triple::wasm32:
7390 case llvm::Triple::wasm64:
7391 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7393 case llvm::Triple::avr:
7394 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7396 case llvm::Triple::msp430:
7397 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7399 case llvm::Triple::riscv32:
7400 case llvm::Triple::riscv64:
7401 case llvm::Triple::riscv32be:
7402 case llvm::Triple::riscv64be:
7403 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7405 case llvm::Triple::ve:
7406 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7408 case llvm::Triple::spirv32:
7409 case llvm::Triple::spirv64:
7410 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7412 case llvm::Triple::csky:
7413 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7415 case llvm::Triple::amdgpu:
7416 case llvm::Triple::r600:
7417 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7421 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7422 else if (
Target.isOSBinFormatELF())
7423 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7424 else if (
Target.isAppleFirmware())
7425 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7426 else if (
Target.isAppleMachO())
7427 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7428 else if (
Target.isOSBinFormatMachO())
7429 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7431 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7441 if (JA.
size() != 1 ||
7456 if (JA.
size() != 1 ||
7470 if (Args.hasArg(options::OPT_emit_static_lib))
7481 unsigned &Micro,
bool &HadExtra) {
7484 Major = Minor = Micro = 0;
7488 if (Str.consumeInteger(10, Major))
7492 if (!Str.consume_front(
"."))
7495 if (Str.consumeInteger(10, Minor))
7499 if (!Str.consume_front(
"."))
7502 if (Str.consumeInteger(10, Micro))
7520 unsigned CurDigit = 0;
7521 while (CurDigit < Digits.size()) {
7523 if (Str.consumeInteger(10, Digit))
7525 Digits[CurDigit] = Digit;
7528 if (!Str.consume_front(
"."))
7537llvm::opt::Visibility
7538Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7550const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7566 llvm_unreachable(
"Unhandled Mode");
7570 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7575 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7576 options::OPT_fno_save_optimization_record,
false))
7580 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7581 options::OPT_fno_save_optimization_record,
false))
7585 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7586 options::OPT_fno_save_optimization_record,
false))
7590 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7591 options::OPT_fno_save_optimization_record,
false))
7598 static StringRef OptName =
7600 llvm::StringRef Opt;
7601 for (StringRef Arg : Args) {
7602 if (!Arg.starts_with(OptName))
7608 return Opt.consume_front(OptName) ? Opt :
"";
7615 llvm::BumpPtrAllocator &Alloc,
7616 llvm::vfs::FileSystem *FS) {
7625 for (
const char *F : Args) {
7626 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7628 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7629 RSPQuoting = Windows;
7635 bool MarkEOLs = ClangCLMode;
7637 llvm::cl::TokenizerCallback Tokenizer;
7638 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7639 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7641 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7643 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7646 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7647 ECtx.setMarkEOLs(MarkEOLs);
7651 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7655 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7656 [](
const char *A) {
return A !=
nullptr; });
7657 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7660 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7661 Args.resize(newEnd - Args.begin());
7665 return llvm::Error::success();
7669 return SavedStrings.insert(S).first->getKeyData();
7703 llvm::StringSet<> &SavedStrings) {
7706 if (Edit[0] ==
'^') {
7707 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7708 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7709 Args.insert(Args.begin() + 1, Str);
7710 }
else if (Edit[0] ==
'+') {
7711 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7712 OS <<
"### Adding argument " << Str <<
" at end\n";
7713 Args.push_back(Str);
7714 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7715 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7716 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7717 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7718 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7720 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7722 if (Args[i] ==
nullptr)
7724 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7726 if (Repl != Args[i]) {
7727 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7731 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7732 auto Option = Edit.substr(1);
7733 for (
unsigned i = 1; i < Args.size();) {
7734 if (Option == Args[i]) {
7735 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7736 Args.erase(Args.begin() + i);
7737 if (Edit[0] ==
'X') {
7738 if (i < Args.size()) {
7739 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7740 Args.erase(Args.begin() + i);
7742 OS <<
"### Invalid X edit, end of command line!\n";
7747 }
else if (Edit[0] ==
'O') {
7748 for (
unsigned i = 1; i < Args.size();) {
7749 const char *A = Args[i];
7753 if (A[0] ==
'-' && A[1] ==
'O' &&
7754 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7755 (
'0' <= A[2] && A[2] <=
'9'))))) {
7756 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7757 Args.erase(Args.begin() + i);
7761 OS <<
"### Adding argument " << Edit <<
" at end\n";
7762 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7764 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7769 const char *OverrideStr,
7770 llvm::StringSet<> &SavedStrings,
7771 StringRef EnvVar, raw_ostream *OS) {
7773 OS = &llvm::nulls();
7775 if (OverrideStr[0] ==
'#') {
7777 OS = &llvm::nulls();
7780 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7784 const char *S = OverrideStr;
7786 const char *End = ::strchr(S,
' ');
7788 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static std::string getOffloadDeviceCC1ParallelJobGroup(const Command &Job)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static void printCXXStdlibIncludeDirs(const ToolChain &TC, const ArgList &Args)
static bool HasPreprocessOutput(const Action &JA)
std::multiset< llvm::Triple > TripleSet
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static const char BugReportMsg[]
static std::string GetTriplePlusArchString(const ToolChain *TC, BoundArch BA, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static void markOffloadDeviceCC1JobsForParallelExecution(Compilation &C)
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static bool isIncludeDirArg(StringRef Arg)
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef ArchName="")
Compute target triple from args.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static bool isOffloadDeviceCC1JobCandidate(Command &Job)
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static void claimAndDiagnoseOffloadJobs(const Driver &D, const ArgList &Args)
static bool shouldBundleHIPAsmWithNewDriver(const Compilation &C, const llvm::opt::DerivedArgList &Args, const Driver &D)
HIP non-RDC -S for AMDGCN: emit host and device assembly separately and bundle with clang-offload-bun...
static TripleSet inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static StringRef getTriple(const Command &Job)
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A processor an offloading action can target.
static constexpr OffloadArch getUnused()
static constexpr OffloadArch getGeneric()
static OffloadArch CudaDefault()
Default architectures used when the user does not specify one.
static OffloadArch HIPDefault()
static constexpr OffloadArch getUnknown()
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
BoundArch getOffloadingArch() const
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateDeviceOffloadInfo(OffloadKind OKind, BoundArch OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
void propagateHostOffloadInfo(unsigned OKinds, BoundArch OArch)
Append the host offload info of this action and propagate it to its dependences.
void setHostOffloadInfo(unsigned OKinds, BoundArch OArch)
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
void setBoundArch(BoundArch BA)
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
BoundArch getBoundArch() const
Return the bound architecture for this command, if any.
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
llvm::SmallVector< BoundArch > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction, ActionList *HIPAsmBundleDeviceOut=nullptr) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None, LTOKind TargetLTOMode=LTOK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, BoundArch BA, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
std::string Name
The name the driver was invoked as.
Driver(StringRef DriverExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, BoundArch BA, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArchStr={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
std::string DriverExecutable
The original path to the driver executable.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
const ActionList & getActions() const
Get each of the individual arrays.
void add(Action &A, const ToolChain &TC, BoundArch BA, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
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.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
llvm::Triple::SubArchType getOffloadArchSubArch(OffloadArch ID)
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.
OffloadArch getSubArchOffloadArch(llvm::Triple::SubArchType SubArch)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Represents a bound architecture for offload / multiple architecture compilation.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules