60#include "clang/Config/config.h"
77#include "llvm/ADT/ArrayRef.h"
78#include "llvm/ADT/STLExtras.h"
79#include "llvm/ADT/ScopeExit.h"
80#include "llvm/ADT/SmallSet.h"
81#include "llvm/ADT/SmallVector.h"
82#include "llvm/ADT/StringExtras.h"
83#include "llvm/ADT/StringRef.h"
84#include "llvm/ADT/StringSet.h"
85#include "llvm/ADT/StringSwitch.h"
86#include "llvm/Config/llvm-config.h"
87#include "llvm/MC/TargetRegistry.h"
88#include "llvm/Option/Arg.h"
89#include "llvm/Option/ArgList.h"
90#include "llvm/Option/OptSpecifier.h"
91#include "llvm/Option/OptTable.h"
92#include "llvm/Option/Option.h"
93#include "llvm/Support/CommandLine.h"
94#include "llvm/Support/ErrorHandling.h"
95#include "llvm/Support/ExitCodes.h"
96#include "llvm/Support/FileSystem.h"
97#include "llvm/Support/FileUtilities.h"
98#include "llvm/Support/FormatVariadic.h"
99#include "llvm/Support/IOSandbox.h"
100#include "llvm/Support/JSON.h"
101#include "llvm/Support/MD5.h"
102#include "llvm/Support/MemoryBuffer.h"
103#include "llvm/Support/Path.h"
104#include "llvm/Support/PrettyStackTrace.h"
105#include "llvm/Support/Process.h"
106#include "llvm/Support/Program.h"
107#include "llvm/Support/Regex.h"
108#include "llvm/Support/StringSaver.h"
109#include "llvm/Support/TarWriter.h"
110#include "llvm/Support/VirtualFileSystem.h"
111#include "llvm/Support/raw_ostream.h"
112#include "llvm/TargetParser/Host.h"
113#include "llvm/TargetParser/RISCVISAInfo.h"
126using namespace clang;
129template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
130 return llvm::any_of(Args, [&](Arg *A) {
131 return (A->getOption().matches(options::OPT_x) &&
133 (A->getOption().
getKind() == Option::InputClass &&
134 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
136 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
141 return Arg ==
"-internal-isystem" || Arg ==
"-internal-externc-isystem" ||
142 Arg ==
"-isystem" || Arg ==
"-cxx-isystem" || Arg ==
"-idirafter";
146 const ArgList &Args) {
147 ArgStringList CC1Args;
148 if (Args.hasArg(options::OPT_stdlibxx_isystem))
153 for (
size_t I = 0; I < CC1Args.size(); ++I) {
154 StringRef Arg(CC1Args[I]);
156 llvm::outs() << CC1Args[++I] <<
'\n';
162 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
163 StringRef UseCUIDStr = A->getValue();
164 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
165 .Case(
"hash", Kind::Hash)
166 .Case(
"random", Kind::Random)
167 .Case(
"none", Kind::None)
168 .Default(Kind::Invalid);
169 if (UseCUID == Kind::Invalid)
170 D.Diag(clang::diag::err_drv_invalid_value)
171 << A->getAsString(Args) << UseCUIDStr;
174 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
175 if (!FixedCUID.empty())
180 llvm::opt::DerivedArgList &Args)
const {
181 std::string CUID = FixedCUID.str();
184 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
188 llvm::MD5::MD5Result
Hash;
189 Hasher.update(InputFile);
190 for (
auto *A : Args) {
191 if (A->getOption().matches(options::OPT_INPUT))
193 Hasher.update(A->getAsString(Args));
196 CUID = llvm::utohexstr(
Hash.low(),
true);
204 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
205 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
211 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
212 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
213 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
216 this->VFS = llvm::vfs::getRealFileSystem();
221 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
224 llvm::sys::path::append(P,
SysRoot);
228#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
229 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
233 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
234 llvm::sys::path::remove_dots(configFileDir,
true);
238#if defined(CLANG_CONFIG_FILE_USER_DIR)
241 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
250void Driver::setDriverMode(StringRef
Value) {
251 static StringRef OptName =
252 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
253 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
254 .Case(
"gcc", GCCMode)
255 .Case(
"g++", GXXMode)
256 .Case(
"cpp", CPPMode)
258 .Case(
"flang", FlangMode)
259 .Case(
"dxc", DXCMode)
263 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
268 bool &ContainsError)
const {
269 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
270 ContainsError =
false;
272 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
273 unsigned MissingArgIndex, MissingArgCount;
274 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
275 MissingArgCount, VisibilityMask);
278 if (MissingArgCount) {
279 Diag(diag::err_drv_missing_argument)
280 << Args.getArgString(MissingArgIndex) << MissingArgCount;
282 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
287 for (
const Arg *A : Args) {
289 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
290 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
297 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
298 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
299 ContainsError |= Diags.getDiagnosticLevel(
300 diag::warn_drv_empty_joined_argument,
305 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
307 auto ArgString = A->getAsString(Args);
309 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
311 if (
getOpts().findExact(ArgString, Nearest,
313 DiagID = diag::err_drv_unknown_argument_with_suggestion;
314 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
316 DiagID = diag::err_drv_unknown_argument;
317 Diags.Report(DiagID) << ArgString;
320 llvm::opt::Visibility(
322 DiagID = diag::err_drv_unknown_argument_with_suggestion;
323 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
325 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
326 : diag::err_drv_unknown_argument;
327 Diags.Report(DiagID) << ArgString;
331 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
332 : diag::err_drv_unknown_argument_with_suggestion;
333 Diags.Report(DiagID) << ArgString << Nearest;
335 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
339 for (
const Arg *A : Args.filtered(options::OPT_o)) {
340 if (ArgStrings[A->getIndex()] == A->getSpelling())
344 std::string ArgString = ArgStrings[A->getIndex()];
346 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
347 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
348 << A->getAsString(Args) << Nearest;
358 Arg **FinalPhaseArg)
const {
359 Arg *PhaseArg =
nullptr;
363 if (
CCCIsCPP() || (PhaseArg = Args.getLastArg(options::OPT_E)) ||
364 (PhaseArg = Args.getLastArg(options::OPT__SLASH_EP)) ||
365 (PhaseArg = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
372 }
else if ((PhaseArg = Args.getLastArg(options::OPT__precompile)) ||
374 Args.getLastArg(options::OPT__precompile_reduced_bmi)) ||
375 (PhaseArg = Args.getLastArg(options::OPT_extract_api)) ||
376 (PhaseArg = Args.getLastArg(options::OPT_fmodule_header,
377 options::OPT_fmodule_header_EQ))) {
380 }
else if ((PhaseArg = Args.getLastArg(options::OPT_fsyntax_only)) ||
381 (PhaseArg = Args.getLastArg(options::OPT_print_supported_cpus)) ||
383 Args.getLastArg(options::OPT_print_enabled_extensions)) ||
384 (PhaseArg = Args.getLastArg(options::OPT_module_file_info)) ||
385 (PhaseArg = Args.getLastArg(options::OPT_verify_pch)) ||
386 (PhaseArg = Args.getLastArg(options::OPT_rewrite_objc)) ||
387 (PhaseArg = Args.getLastArg(options::OPT_rewrite_legacy_objc)) ||
388 (PhaseArg = Args.getLastArg(options::OPT__analyze)) ||
389 (PhaseArg = Args.getLastArg(options::OPT_emit_cir)) ||
390 (PhaseArg = Args.getLastArg(options::OPT_emit_ast))) {
394 }
else if ((PhaseArg = Args.getLastArg(options::OPT_S))) {
398 }
else if ((PhaseArg = Args.getLastArg(options::OPT_c))) {
401 }
else if ((PhaseArg = Args.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,
463 const llvm::Triple &Triple)
const {
464 const llvm::opt::OptTable &Opts =
getOpts();
465 DerivedArgList *DAL =
new DerivedArgList(Args);
467 std::optional<ClangCLArgs> CLArgs;
469 CLArgs.emplace(Args, Triple);
471 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
472 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
473 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
474 bool IgnoreUnused =
false;
475 for (Arg *A : Args) {
479 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
483 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
484 IgnoreUnused =
false;
488 if (CLArgs && CLArgs->translateArg(A, *DAL))
492 if ((CLArgs || Triple.isWindowsMSVCEnvironment()) &&
493 A->getOption().matches(options::OPT_D)) {
496 if (
Value == A->getValue())
499 DAL->AddJoinedArg(A, Opts.getOption(options::OPT_D),
Value);
509 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
510 A->getOption().matches(options::OPT_Xlinker)) &&
511 A->containsValue(
"--no-demangle")) {
513 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
516 for (StringRef Val : A->getValues())
517 if (Val !=
"--no-demangle")
518 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
526 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
527 A->getNumValues() > 0 &&
528 (A->getValue(0) == StringRef(
"-MD") ||
529 A->getValue(0) == StringRef(
"-MMD"))) {
531 if (A->getValue(0) == StringRef(
"-MD"))
532 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
534 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
535 if (A->getNumValues() == 2)
536 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
541 if (A->getOption().matches(options::OPT_l)) {
542 StringRef
Value = A->getValue();
545 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
547 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
552 if (
Value ==
"cc_kext") {
553 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
559 if (A->getOption().matches(options::OPT__DASH_DASH)) {
561 for (StringRef Val : A->getValues())
570 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
571 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
574 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
575 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
579#if defined(HOST_LINK_VERSION)
580 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
581 strlen(HOST_LINK_VERSION) > 0) {
582 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
584 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
592 StringRef ArgTarget) {
594 static bool BeSilent =
false;
595 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
return v < 3; };
598 if (ArgTarget.equals_insensitive(
"CURRENT")) {
602 unsigned int Version = 0;
603 unsigned int Release = 0;
604 unsigned int Modification = 0;
606 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
607 llvm::Regex HexRegex(
610 "([0-9a-fA-F][0-9a-fA-F])"
611 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
614 if (ZOsvRegex.match(ArgTarget, &Matches)) {
615 Matches[1].getAsInteger(10, Version);
616 Matches[2].getAsInteger(10, Release);
618 if (IsTooOldToBeSupported(Version, Release)) {
620 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
623 }
else if (HexRegex.match(ArgTarget, &Matches)) {
624 Matches[1].getAsInteger(16, Version);
625 Matches[2].getAsInteger(16, Release);
626 Matches[3].getAsInteger(16, Modification);
627 if (IsTooOldToBeSupported(Version, Release)) {
629 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
635 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
640 llvm::VersionTuple
V(Version, Release, Modification);
641 llvm::VersionTuple TV =
Target.getOSVersion();
644 if (TV.empty() ||
V < TV) {
646 Str = llvm::Triple::getOSTypeName(
Target.getOS());
647 Str +=
V.getAsString();
661 StringRef ArchName =
"") {
663 if (
const Arg *A = Args.getLastArg(options::OPT_target))
664 TargetTriple = A->getValue();
666 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
671 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
675 if (
Target.isOSBinFormatMachO()) {
677 if (!ArchName.empty()) {
679 return llvm::Triple(
Target.normalize());
683 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
684 StringRef ArchName = A->getValue();
687 }
else if (!ArchName.empty()) {
688 Target.setArchName(ArchName);
694 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
695 options::OPT_mbig_endian)) {
696 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
697 ?
Target.getLittleEndianArchVariant()
698 :
Target.getBigEndianArchVariant();
699 if (
T.getArch() != llvm::Triple::UnknownArch) {
700 Target = llvm::Triple(
T.normalize());
701 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
706 if (
Target.getArch() == llvm::Triple::tce)
712 if (!Args.hasArg(options::OPT_target)) {
713 if (std::optional<std::string> ObjectModeValue =
714 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
715 StringRef ObjectMode = *ObjectModeValue;
716 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
719 if (ObjectMode ==
"64") {
720 AT =
Target.get64BitArchVariant().getArch();
721 }
else if (ObjectMode ==
"32" || ObjectMode ==
"32_64" ||
722 ObjectMode ==
"any") {
724 if (Args.hasArg(options::OPT_maix64, options::OPT_m64))
725 AT =
Target.get64BitArchVariant().getArch();
727 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
729 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
733 const bool OtherAllowedMode =
734 ObjectMode ==
"32_64" || ObjectMode ==
"any";
735 if (ObjectMode ==
"64")
736 AT =
Target.get64BitArchVariant().getArch();
737 else if (ObjectMode ==
"32")
738 AT =
Target.get32BitArchVariant().getArch();
739 else if (!OtherAllowedMode)
740 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
743 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
748 !Args.hasArg(options::OPT_maix64, options::OPT_m64)) {
751 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
758 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64 &&
759 Target.getArch() != llvm::Triple::aarch64)
760 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
763 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
765 D.
Diag(diag::err_drv_unsupported_opt_for_target)
766 << A->getAsString(Args) <<
Target.str();
769 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
770 options::OPT_m32, options::OPT_m16,
771 options::OPT_maix32, options::OPT_maix64);
773 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
775 if (A->getOption().matches(options::OPT_m64) ||
776 A->getOption().matches(options::OPT_maix64)) {
777 AT =
Target.get64BitArchVariant().getArch();
778 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
779 Target.getEnvironment() == llvm::Triple::GNUT64)
780 Target.setEnvironment(llvm::Triple::GNU);
781 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
782 Target.setEnvironment(llvm::Triple::Musl);
783 }
else if (A->getOption().matches(options::OPT_mx32) &&
784 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
785 AT = llvm::Triple::x86_64;
786 if (
Target.getEnvironment() == llvm::Triple::Musl)
787 Target.setEnvironment(llvm::Triple::MuslX32);
789 Target.setEnvironment(llvm::Triple::GNUX32);
790 }
else if (A->getOption().matches(options::OPT_m32) ||
791 A->getOption().matches(options::OPT_maix32)) {
794 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
796 D.
Diag(diag::err_drv_unsupported_opt_for_target)
797 << A->getAsString(Args) <<
Target.str();
800 AT =
Target.get32BitArchVariant().getArch();
801 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
802 Target.setEnvironment(llvm::Triple::GNU);
803 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
804 Target.setEnvironment(llvm::Triple::Musl);
806 }
else if (A->getOption().matches(options::OPT_m16) &&
807 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
808 AT = llvm::Triple::x86;
809 Target.setEnvironment(llvm::Triple::CODE16);
812 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
814 if (
Target.isWindowsGNUEnvironment())
822 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
828 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
829 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
830 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
833 if (A && !A->getOption().matches(options::OPT_m32))
834 D.
Diag(diag::err_drv_argument_not_allowed_with)
835 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
837 Target.setArch(llvm::Triple::x86);
838 Target.setArchName(
"i586");
839 Target.setEnvironmentName(
"");
840 Target.setOS(llvm::Triple::ELFIAMCU);
841 Target.setVendor(llvm::Triple::Intel);
847 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
848 StringRef ABIName = A->getValue();
849 if (ABIName ==
"32") {
851 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
852 Target.getEnvironment() == llvm::Triple::GNUABIN32)
853 Target.setEnvironment(llvm::Triple::GNU);
854 }
else if (ABIName ==
"n32") {
856 if (
Target.getEnvironment() == llvm::Triple::GNU ||
857 Target.getEnvironment() == llvm::Triple::GNUT64 ||
858 Target.getEnvironment() == llvm::Triple::GNUABI64)
859 Target.setEnvironment(llvm::Triple::GNUABIN32);
860 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
861 Target.getEnvironment() == llvm::Triple::MuslABI64)
862 Target.setEnvironment(llvm::Triple::MuslABIN32);
863 }
else if (ABIName ==
"64") {
865 if (
Target.getEnvironment() == llvm::Triple::GNU ||
866 Target.getEnvironment() == llvm::Triple::GNUT64 ||
867 Target.getEnvironment() == llvm::Triple::GNUABIN32)
868 Target.setEnvironment(llvm::Triple::GNUABI64);
869 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
870 Target.getEnvironment() == llvm::Triple::MuslABIN32)
871 Target.setEnvironment(llvm::Triple::MuslABI64);
881 if (Args.hasArg(options::OPT_march_EQ) ||
882 Args.hasArg(options::OPT_mcpu_EQ)) {
884 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
886 if (!llvm::errorToBool(ISAInfo.takeError())) {
887 unsigned XLen = (*ISAInfo)->getXLen();
889 if (
Target.isLittleEndian())
890 Target.setArch(llvm::Triple::riscv32);
892 Target.setArch(llvm::Triple::riscv32be);
894 }
else if (XLen == 64) {
895 if (
Target.isLittleEndian())
896 Target.setArch(llvm::Triple::riscv64);
898 Target.setArch(llvm::Triple::riscv64be);
905 if (
Target.getArch() == llvm::Triple::riscv32be ||
906 Target.getArch() == llvm::Triple::riscv64be) {
907 static bool WarnedRISCVBE =
false;
908 if (!WarnedRISCVBE) {
909 D.
Diag(diag::warn_drv_riscv_be_experimental);
910 WarnedRISCVBE =
true;
919 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
921 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
923 RuntimeName = A->getValue();
925 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
933 Diag(diag::err_drv_unsupported_option_argument)
934 << A->getSpelling() << A->getValue();
937 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
946 StringRef Program =
C.getArgs().getLastArgValue(
947 options::OPT_offload_arch_tool_EQ,
"offload-arch");
950 if (llvm::ErrorOr<std::string> Executable =
951 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
953 bool UsesLLVMOffloading =
954 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
955 options::OPT_fno_offload_via_llvm,
false);
956 if (!UsesLLVMOffloading) {
958 Args.push_back(
"--only=amdgpu");
960 Args.push_back(
"--only=nvptx");
962 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
965 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
970 if ((*StdoutOrErr)->getBuffer().empty()) {
971 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
977 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
979 GPUArchs.push_back(
Arch.str());
981 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
992 std::set<std::string> Archs;
993 for (Arg *A :
C.getInputArgs()) {
994 for (StringRef
Arch : A->getValues()) {
995 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
996 if (
Arch ==
"native") {
998 Archs.insert(Str.str());
1000 Archs.insert(
Arch.str());
1002 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
1006 Archs.erase(
Arch.str());
1012 for (llvm::StringRef
Arch : Archs) {
1014 if (ID.isUnknown()) {
1015 llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
1016 llvm::Triple::AMD, llvm::Triple::AMDHSA);
1020 bool UsesLLVMOffloading =
1021 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
1022 options::OPT_fno_offload_via_llvm,
false);
1023 if (!UsesLLVMOffloading) {
1024 if (Kind ==
Action::OFK_HIP && !ID.isAMDGPU() && !ID.isAMDGCNSPIRV()) {
1025 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1030 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1036 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1040 if (ID.isUnknown() || ID.isUnused()) {
1041 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1042 <<
"offload" <<
Arch;
1046 llvm::Triple Triple =
1048 if (UsesLLVMOffloading)
1049 Triple.setEnvironment(llvm::Triple::LLVM);
1054 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1055 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1056 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1057 C.getArgs().MakeArgString(Triple.getArchName()),
1058 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1060 C.getArgs().append(A);
1061 C.getArgs().AddSynthesizedArg(A);
1063 auto It = Triples.lower_bound(Triple);
1064 if (It == Triples.end() || *It != Triple)
1065 Triples.insert(It, Triple);
1070 Triples.insert(llvm::Triple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
1071 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1073 llvm::Triple::ArchType
Arch =
1074 C.getDefaultToolChain().getTriple().isArch64Bit()
1075 ? llvm::Triple::nvptx64
1076 : llvm::Triple::nvptx;
1077 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1078 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1081 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1082 ? llvm::Triple::spirv64
1083 : llvm::Triple::spirv32));
1086 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1087 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1095 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1099 (llvm::any_of(Inputs,
1100 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1103 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1104 C.getInputArgs().hasArg(options::OPT_hipstdpar));
1105 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1106 options::OPT_fno_sycl,
false);
1107 bool IsOpenMPOffloading =
1108 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1109 options::OPT_fno_openmp,
false) &&
1110 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1111 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1112 !(IsCuda || IsHIP))));
1114 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1115 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1120 for (
const auto &[Active, Kind] : ActiveKinds)
1125 if (Kinds.size() > 1) {
1126 Diag(clang::diag::err_drv_mix_offload)
1133 if (IsCuda || IsHIP)
1140 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1141 std::vector<std::string> ArgValues =
1142 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1143 for (llvm::StringRef
Target : ArgValues) {
1147 if (ArgValues.empty())
1148 Diag(clang::diag::warn_drv_empty_joined_argument)
1150 .getLastArg(options::OPT_offload_targets_EQ)
1151 ->getAsString(
C.getInputArgs());
1158 llvm::StringMap<StringRef> FoundNormalizedTriples;
1159 for (
const llvm::Triple &
Target : Triples) {
1164 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1172 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1173 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1174 Diag(clang::diag::err_drv_argument_not_allowed_with)
1175 << IncompatArg->getSpelling() <<
"-fsycl";
1180 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1181 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1186 std::string NormalizedName =
Target.normalize();
1187 auto [TripleIt, Inserted] =
1188 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1190 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1191 <<
Target.str() << TripleIt->second;
1195 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1196 C.getDefaultToolChain().getTriple());
1200 auto &CudaInstallation =
1202 if (CudaInstallation.isValid())
1203 CudaInstallation.WarnIfUnsupportedVersion();
1206 C.addOffloadDeviceToolChain(&TC, Kind);
1214 const Arg *RDCArg =
C.getInputArgs().getLastArg(options::OPT_fgpu_rdc,
1215 options::OPT_fno_gpu_rdc);
1216 if (RDCArg && RDCArg->getOption().matches(options::OPT_fno_gpu_rdc)) {
1218 if (std::distance(TCRange.first, TCRange.second) > 1)
1219 Diag(clang::diag::err_drv_sycl_no_rdc_multiple_targets)
1220 << RDCArg->getAsString(
C.getInputArgs());
1225bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1230 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1234 if (!PathLIBEnv.empty()) {
1235 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1236 if (llvm::sys::fs::is_directory(PathLIBEnv))
1237 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1238 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1239 return readConfigFile(CustomizationFile, ExpCtx);
1240 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1245 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1246 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1247 return readConfigFile(CustomizationFile, ExpCtx);
1257 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1258 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1259 Copy->getValues() = Opt->getValues();
1260 if (Opt->isClaimed())
1262 Copy->setOwnsValues(Opt->getOwnsValues());
1263 Opt->setOwnsValues(
false);
1265 if (Opt->getAlias()) {
1266 const Arg *Alias = Opt->getAlias();
1267 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1268 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1269 Args.getArgString(Index), Index);
1270 AliasCopy->getValues() = Alias->getValues();
1271 AliasCopy->setOwnsValues(
false);
1272 if (Alias->isClaimed())
1274 Copy->setAlias(std::move(AliasCopy));
1278bool Driver::readConfigFile(StringRef
FileName,
1279 llvm::cl::ExpansionContext &ExpCtx) {
1283 Diag(diag::err_drv_cannot_open_config_file)
1284 <<
FileName << Status.getError().message();
1287 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1288 Diag(diag::err_drv_cannot_open_config_file)
1289 <<
FileName <<
"not a regular file";
1294 SmallVector<const char *, 32> NewCfgFileArgs;
1295 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1296 Diag(diag::err_drv_cannot_read_config_file)
1302 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1303 for (
const char *Opt : NewCfgFileArgs) {
1305 if (Opt[0] ==
'$' && Opt[1])
1306 NewCfgTailArgs.push_back(Opt + 1);
1308 NewCfgHeadArgs.push_back(Opt);
1312 llvm::SmallString<128> CfgFileName(
FileName);
1313 llvm::sys::path::native(CfgFileName);
1314 bool ContainErrors =
false;
1315 auto NewHeadOptions = std::make_unique<InputArgList>(
1319 auto NewTailOptions = std::make_unique<InputArgList>(
1326 for (Arg *A : *NewHeadOptions)
1328 for (Arg *A : *NewTailOptions)
1331 if (!CfgOptionsHead)
1332 CfgOptionsHead = std::move(NewHeadOptions);
1335 for (
auto *Opt : *NewHeadOptions)
1339 if (!CfgOptionsTail)
1340 CfgOptionsTail = std::move(NewTailOptions);
1343 for (
auto *Opt : *NewTailOptions)
1347 ConfigFiles.push_back(std::string(CfgFileName));
1351bool Driver::loadConfigFiles() {
1352 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1353 llvm::cl::tokenizeConfigFile, &
getVFS());
1357 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1358 SmallString<128> CfgDir;
1360 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1361 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1366 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1367 SmallString<128> CfgDir;
1368 llvm::sys::fs::expand_tilde(
1369 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1370 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1379 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1382 if (loadDefaultConfigFiles(ExpCtx))
1386 SmallString<128> CfgFilePath;
1388 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1391 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1392 CfgFilePath.assign(CfgFileName);
1393 if (llvm::sys::path::is_relative(CfgFilePath)) {
1394 if (
getVFS().makeAbsolute(CfgFilePath)) {
1395 Diag(diag::err_drv_cannot_open_config_file)
1396 << CfgFilePath <<
"cannot get absolute path";
1400 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1402 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1403 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1404 if (!SearchDir.empty())
1405 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1410 if (readConfigFile(CfgFilePath, ExpCtx))
1421 llvm::Triple Triple, std::string Suffix) {
1423 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1427 VersionTuple OSVersion = Triple.getOSVersion();
1428 if (!OSVersion.getMinor().has_value())
1431 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1435 if (OSVersion.getMajor() != 0) {
1436 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1437 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1443 Triple.setOSName(BaseOSName);
1444 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1447bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1450 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1454 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1457 std::string RealMode = getExecutableForDriverMode(Mode);
1458 llvm::Triple Triple;
1467 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1468 PrefixTriple.isOSUnknown())
1469 Triple = std::move(PrefixTriple);
1473 llvm::Triple RealTriple =
1475 if (Triple.str().empty()) {
1476 Triple = RealTriple;
1477 assert(!Triple.str().empty());
1482 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1496 SmallString<128> CfgFilePath;
1498 "-" + RealMode +
".cfg"))
1499 return readConfigFile(CfgFilePath, ExpCtx);
1503 if (TryModeSuffix) {
1506 return readConfigFile(CfgFilePath, ExpCtx);
1511 std::string CfgFileName = RealMode +
".cfg";
1512 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1513 if (readConfigFile(CfgFilePath, ExpCtx))
1515 }
else if (TryModeSuffix) {
1517 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1518 readConfigFile(CfgFilePath, ExpCtx))
1524 return readConfigFile(CfgFilePath, ExpCtx);
1532 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1541 if (!DriverMode.empty())
1542 setDriverMode(DriverMode);
1548 CLOptions = std::make_unique<InputArgList>(
1553 ContainsError = loadConfigFiles();
1554 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1555 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1559 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1561 if (HasConfigFileHead)
1562 for (
auto *Opt : *CLOptions)
1563 if (!Opt->getOption().matches(options::OPT_config))
1567 if (
IsCLMode() && !ContainsError) {
1569 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1571 CLModePassThroughArgList.push_back(A->getValue());
1574 if (!CLModePassThroughArgList.empty()) {
1577 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1582 for (
auto *Opt : *CLModePassThroughOptions)
1588 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1589 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1590 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1593 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1594 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1595 if (!VFS->exists(IncludeDir))
1596 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1601 bool CCCPrintPhases;
1604 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1605 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1608 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1609 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1612 Args.ClaimAllArgs(options::OPT_pipe);
1620 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1622 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1623 CCCGenericGCCName = A->getValue();
1626 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1630 if (Args.hasArg(options::OPT_fproc_stat_report))
1637 llvm::Triple
T(TargetTriple);
1638 T.setOS(llvm::Triple::Win32);
1639 T.setVendor(llvm::Triple::PC);
1640 T.setEnvironment(llvm::Triple::MSVC);
1641 T.setObjectFormat(llvm::Triple::COFF);
1642 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1643 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1644 TargetTriple =
T.str();
1647 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1648 StringRef TargetProfile = A->getValue();
1651 TargetTriple = *Triple;
1653 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1657 if (Args.hasArg(options::OPT_spirv)) {
1658 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1659 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1660 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1661 llvm::Triple
T(TargetTriple);
1664 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1666 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1667 TargetInfo = ValidTargets.find(A->getValue());
1669 Diag(diag::err_drv_invalid_value)
1670 << A->getAsString(Args) << A->getValue();
1676 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1677 TargetTriple =
T.str();
1681 Diag(diag::err_drv_dxc_missing_target_profile);
1685 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1686 TargetTriple = A->getValue();
1687 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1688 Dir = A->getValue();
1689 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1693 if (std::optional<std::string> CompilerPathValue =
1694 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1695 StringRef CompilerPath = *CompilerPathValue;
1696 while (!CompilerPath.empty()) {
1697 std::pair<StringRef, StringRef> Split =
1698 CompilerPath.split(llvm::sys::EnvPathSeparator);
1699 PrefixDirs.push_back(std::string(Split.first));
1700 CompilerPath = Split.second;
1703 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1705 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1708 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1711 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1712 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1713 .Case(
"cwd", SaveTempsCwd)
1714 .Case(
"obj", SaveTempsObj)
1715 .Default(SaveTempsCwd);
1718 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1719 options::OPT_offload_device_only,
1720 options::OPT_offload_host_device)) {
1721 if (A->getOption().matches(options::OPT_offload_host_only))
1722 Offload = OffloadHost;
1723 else if (A->getOption().matches(options::OPT_offload_device_only))
1724 Offload = OffloadDevice;
1726 Offload = OffloadHostDevice;
1730 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1731 StringRef
Name = A->getValue();
1732 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1733 .Case(
"off", EmbedNone)
1734 .Case(
"all", EmbedBitcode)
1735 .Case(
"bitcode", EmbedBitcode)
1736 .Case(
"marker", EmbedMarker)
1739 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1742 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1746 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1747 llvm::sys::fs::remove(A->getValue());
1753 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1755 !Args.hasArg(options::OPT_fmodules) && Std &&
1756 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1757 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1758 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1759 Std->containsValue(
"c++2d") || Std->containsValue(
"c++latest"));
1762 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1763 options::OPT_fmodule_header)) {
1765 ModulesModeCXX20 =
true;
1766 if (A->getOption().matches(options::OPT_fmodule_header))
1769 StringRef ArgName = A->getValue();
1770 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1775 Diags.Report(diag::err_drv_invalid_value)
1776 << A->getAsString(Args) << ArgName;
1782 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1783 std::make_unique<InputArgList>(std::move(Args));
1793 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1794 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1796 bool MLContainsError;
1797 auto MultilibMacroDefineList =
1799 MLMacroDefinesChar,
false, MLContainsError));
1800 if (!MLContainsError) {
1801 for (
auto *Opt : *MultilibMacroDefineList) {
1808 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs, TC.
getTriple());
1812 if (!Triple.isWasm()) {
1813 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1814 StringRef TripleObjectFormat =
1815 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1816 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1817 TripleVersionName != TripleObjectFormat) {
1818 Diags.Report(diag::err_drv_triple_version_invalid)
1820 ContainsError =
true;
1825 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1826 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1827 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1835 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1836 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1838 case llvm::Triple::arm:
1839 case llvm::Triple::armeb:
1840 case llvm::Triple::thumb:
1841 case llvm::Triple::thumbeb:
1842 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1843 Diag(diag::warn_target_unrecognized_env)
1845 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1848 case llvm::Triple::aarch64:
1849 case llvm::Triple::aarch64_be:
1850 case llvm::Triple::aarch64_32:
1851 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1852 Diag(diag::warn_target_unrecognized_env)
1854 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1871 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1872 if (HasConfigFileTail && Inputs.size()) {
1875 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1876 for (Arg *A : *CfgOptionsTail)
1877 TranslatedLinkerIns.append(A);
1878 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1885 bool UseModulesDriver =
C->getArgs().hasFlag(
1886 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1888 if (UseModulesDriver) {
1889 Diags.Report(diag::remark_performing_driver_managed_module_build);
1897 const auto StdModuleManifestPath =
1900 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1901 Diags.Report(diag::remark_modules_manifest_not_found);
1903 Diags.Report(diag::remark_using_modules_manifest)
1904 << StdModuleManifestPath;
1905 if (
auto ManifestOrErr =
1907 ModulesManifest = std::move(*ManifestOrErr);
1909 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1910 return !ModuleEntry.IsStdlib;
1915 llvm::handleAllErrors(
1916 ManifestOrErr.takeError(),
1917 [&](llvm::json::ParseError &Err) {
1918 Diags.Report(diag::err_modules_manifest_failed_parse)
1921 [&](llvm::FileError &Err) {
1922 Diags.Report(diag::err_cannot_open_file)
1923 << Err.getFileName() << Err.messageWithoutFileInfo();
1931 if (TC.
getTriple().isOSBinFormatMachO())
1936 if (CCCPrintPhases) {
1943 if (UseModulesDriver)
1950 llvm::opt::ArgStringList ASL;
1951 for (
const auto *A : Args) {
1955 while (A->getAlias())
1957 A->render(Args, ASL);
1960 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1961 if (I != ASL.begin())
1963 llvm::sys::printArg(OS, *I,
true);
1968bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1969 SmallString<128> &CrashDiagDir) {
1970 using namespace llvm::sys;
1971 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1972 "Only knows about .crash files on Darwin");
1974 auto BypassSandbox = sandbox::scopedDisable();
1979 path::home_directory(CrashDiagDir);
1980 if (CrashDiagDir.starts_with(
"/var/root"))
1982 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1990 fs::file_status FileStatus;
1991 TimePoint<> LastAccessTime;
1992 SmallString<128> CrashFilePath;
1995 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1996 File != FileEnd && !EC;
File.increment(EC)) {
2000 if (fs::status(
File->path(), FileStatus))
2002 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
2003 llvm::MemoryBuffer::getFile(
File->path());
2008 StringRef
Data = CrashFile.get()->getBuffer();
2009 if (!
Data.starts_with(
"Process:"))
2012 size_t ParentProcPos =
Data.find(
"Parent Process:");
2013 if (ParentProcPos == StringRef::npos)
2015 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
2016 if (LineEnd == StringRef::npos)
2018 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
2019 int OpenBracket = -1, CloseBracket = -1;
2020 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
2021 if (ParentProcess[i] ==
'[')
2023 if (ParentProcess[i] ==
']')
2029 if (OpenBracket < 0 || CloseBracket < 0 ||
2030 ParentProcess.slice(OpenBracket + 1, CloseBracket)
2031 .getAsInteger(10, CrashPID) || CrashPID != PID) {
2041 const auto FileAccessTime = FileStatus.getLastModificationTime();
2042 if (FileAccessTime > LastAccessTime) {
2043 CrashFilePath.assign(
File->path());
2044 LastAccessTime = FileAccessTime;
2049 if (!CrashFilePath.empty()) {
2050 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2060 "\n********************\n\n"
2061 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
2069 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2072 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
2075 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2076 Level = llvm::StringSwitch<unsigned>(A->getValue())
2078 .Case(
"compiler", 1)
2090 ArgStringList SavedTemps;
2092 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2093 if (!IsLLD || Level < 2)
2100 SavedTemps = std::move(
C.getTempFiles());
2101 assert(!
C.getTempFiles().size());
2118 C.initCompilationForDiagnostics();
2123 Command NewLLDInvocation = Cmd;
2124 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2125 StringRef ReproduceOption =
2126 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2129 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2133 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2135 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2136 Diag(clang::diag::note_drv_command_failed_diag_msg)
2137 <<
"\n\n********************";
2139 Report->TemporaryFiles.push_back(TmpName);
2147 ArgStringList IRInputs;
2148 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2149 bool IgnoreInput =
false;
2155 IRInputs.push_back(it->second->getValue());
2159 }
else if (!strcmp(it->second->getValue(),
"-")) {
2160 Diag(clang::diag::note_drv_command_failed_diag_msg)
2161 <<
"Error generating preprocessed source(s) - "
2162 "ignoring input from stdin.";
2167 it = Inputs.erase(it);
2174 if (Inputs.empty() && IRInputs.empty()) {
2175 Diag(clang::diag::note_drv_command_failed_diag_msg)
2176 <<
"Error generating preprocessed source(s) - "
2177 "no preprocessable inputs.";
2183 llvm::StringSet<> ArchNames;
2184 for (
const Arg *A :
C.getArgs()) {
2185 if (A->getOption().matches(options::OPT_arch)) {
2186 StringRef ArchName = A->getValue();
2187 ArchNames.insert(ArchName);
2190 if (ArchNames.size() > 1) {
2193 if (FailingArch.empty()) {
2194 Diag(clang::diag::note_drv_command_failed_diag_msg)
2195 <<
"Error generating preprocessed source(s) - cannot generate "
2196 "preprocessed source with multiple -arch options.";
2199 C.getArgs().eraseArg(options::OPT_arch);
2200 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2205 if (!Inputs.empty()) {
2208 const ToolChain &TC =
C.getDefaultToolChain();
2209 if (TC.
getTriple().isOSBinFormatMachO())
2218 Diag(clang::diag::note_drv_command_failed_diag_msg)
2219 <<
"Error generating preprocessed source(s).";
2224 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2227 if (!FailingCommands.empty()) {
2228 Diag(clang::diag::note_drv_command_failed_diag_msg)
2229 <<
"Error generating preprocessed source(s).";
2233 const ArgStringList &TempFiles =
C.getTempFiles();
2234 if (TempFiles.empty()) {
2235 Diag(clang::diag::note_drv_command_failed_diag_msg)
2236 <<
"Error generating preprocessed source(s).";
2242 const ArgStringList &Files =
C.getTempFiles();
2247 for (
auto const *Input : IRInputs) {
2251 StringRef extension = llvm::sys::path::extension(Input);
2252 if (!extension.empty())
2253 extension = extension.drop_front();
2255 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2256 llvm::sys::path::stem(Input), extension, FD, Path);
2258 Diag(clang::diag::note_drv_command_failed_diag_msg)
2259 <<
"Error generating run script: " <<
"Failed copying IR input files"
2260 <<
" " << EC.message();
2264 EC = llvm::sys::fs::copy_file(Input, FD);
2266 Diag(clang::diag::note_drv_command_failed_diag_msg)
2267 <<
"Error generating run script: " <<
"Failed copying IR input files"
2268 <<
" " << EC.message();
2272 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2279 for (std::string &TempFile : TempFiles) {
2281 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2283 Report->TemporaryFiles.push_back(TempFile);
2284 if (ReproCrashFilename.empty()) {
2285 ReproCrashFilename = TempFile;
2286 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2288 if (StringRef(TempFile).ends_with(
".cache")) {
2291 VFS = llvm::sys::path::filename(TempFile);
2292 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2296 for (
const char *TempFile : SavedTemps)
2297 TempFiles.push_back(TempFile);
2303 llvm::sys::path::replace_extension(Script,
"sh");
2305 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2306 llvm::sys::fs::FA_Write,
2307 llvm::sys::fs::OF_Text);
2309 Diag(clang::diag::note_drv_command_failed_diag_msg)
2310 <<
"Error generating run script: " << Script <<
" " << EC.message();
2313 <<
"# Driver args: ";
2315 ScriptOS <<
"# Original command: ";
2316 Cmd.
Print(ScriptOS,
"\n",
true);
2317 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2318 if (!AdditionalInformation.empty())
2319 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2322 Report->TemporaryFiles.push_back(std::string(Script));
2323 TempFiles.push_back(std::string(Script));
2326 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2329 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2330 StringRef CrashDiagnosticsTar = A->getValue();
2332 llvm::TarWriter::create(CrashDiagnosticsTar,
2333 llvm::sys::path::stem(CrashDiagnosticsTar));
2335 Diag(clang::diag::note_drv_command_failed_diag_msg)
2336 << (std::string(
"Error creating reproducer tarball: ") +
2337 llvm::toString(TarOrErr.takeError()));
2339 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2340 for (
const std::string &TempFile : TempFiles) {
2341 if (llvm::sys::fs::is_directory(TempFile)) {
2343 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2344 I != E && !EC; I.increment(EC)) {
2345 if (llvm::sys::fs::is_regular_file(I->path())) {
2346 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2350 llvm::sys::path::filename(TempFile);
2351 StringRef SubPath = I->path();
2352 if (SubPath.consume_front(TempFile)) {
2353 if (!SubPath.empty() &&
2354 llvm::sys::path::is_separator(SubPath.front())) {
2355 SubPath = SubPath.drop_front();
2357 llvm::sys::path::append(PathInTar, SubPath);
2358 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2361 Diag(clang::diag::note_drv_command_failed_diag_msg)
2362 << (std::string(
"Error reading file for tarball: ") +
2368 Diag(clang::diag::note_drv_command_failed_diag_msg)
2369 << (std::string(
"Error iterating directory for tarball: ") +
2370 TempFile +
" " + EC.message());
2373 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2375 Tar->append(llvm::sys::path::filename(TempFile),
2376 (*BufferOrErr)->getBuffer());
2378 Diag(clang::diag::note_drv_command_failed_diag_msg)
2379 << (std::string(
"Error reading file for tarball: ") + TempFile);
2383 Diag(clang::diag::note_drv_command_failed_diag_msg)
2384 << CrashDiagnosticsTar;
2389 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2391 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2392 Diag(clang::diag::note_drv_command_failed_diag_msg)
2393 << ReproCrashFilename.str();
2395 llvm::sys::path::append(CrashDiagDir,
Name);
2396 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2397 Diag(clang::diag::note_drv_command_failed_diag_msg)
2398 <<
"Crash backtrace is located in";
2399 Diag(clang::diag::note_drv_command_failed_diag_msg)
2400 << CrashDiagDir.str();
2401 Diag(clang::diag::note_drv_command_failed_diag_msg)
2402 <<
"(choose the .crash file that corresponds to your crash)";
2406 Diag(clang::diag::note_drv_command_failed_diag_msg)
2407 <<
"\n\n********************";
2417 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2428 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2429 if (
C.getArgs().hasArg(options::OPT_v))
2430 C.getJobs().Print(llvm::errs(),
"\n",
true);
2432 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2435 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2442 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2443 C.getJobs().Print(llvm::errs(),
"\n",
true);
2444 return Diags.hasErrorOccurred() ? 1 : 0;
2448 if (Diags.hasErrorOccurred())
2452 for (
auto &Job :
C.getJobs())
2453 setUpResponseFiles(
C, Job);
2455 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2458 if (FailingCommands.empty())
2464 for (
const auto &CmdPair : FailingCommands) {
2465 int CommandRes = CmdPair.first;
2466 const Command *FailingCommand = CmdPair.second;
2471 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2475 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2480 if (CommandRes == EX_IOERR) {
2500 if (CommandRes > 128 && CommandRes != 255)
2504 Diag(clang::diag::err_drv_command_signalled)
2507 Diag(clang::diag::err_drv_command_failed)
2515 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2517 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2531 const ToolChain &TC =
C.getDefaultToolChain();
2535 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2538 OS <<
"Thread model: " << A->getValue();
2544 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2549 if (!llvm::cl::getCompilerBuildConfig().empty())
2550 llvm::cl::printBuildConfig(OS);
2553 for (
auto ConfigFile : ConfigFiles)
2554 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2567 if (PassedFlags ==
"")
2571 std::vector<std::string> SuggestedCompletions;
2572 std::vector<std::string> Flags;
2584 const bool HasSpace = PassedFlags.ends_with(
",");
2588 StringRef TargetFlags = PassedFlags;
2589 while (TargetFlags !=
"") {
2591 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2592 Flags.push_back(std::string(CurFlag));
2597 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2600 const llvm::opt::OptTable &Opts =
getOpts();
2602 Cur = Flags.at(Flags.size() - 1);
2604 if (Flags.size() >= 2) {
2605 Prev = Flags.at(Flags.size() - 2);
2606 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2609 if (SuggestedCompletions.empty())
2610 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2617 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2618 llvm::outs() <<
'\n';
2624 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2628 SuggestedCompletions = Opts.findByPrefix(
2629 Cur, VisibilityMask,
2636 if (S.starts_with(Cur))
2637 SuggestedCompletions.push_back(std::string(S));
2644 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2645 if (
int X = A.compare_insensitive(B))
2647 return A.compare(B) > 0;
2650 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2657 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2658 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2662 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2665 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2669 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2674 if (
C.getArgs().hasArg(options::OPT_help) ||
2675 C.getArgs().hasArg(options::OPT__help_hidden)) {
2676 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2680 if (
C.getArgs().hasArg(options::OPT__version)) {
2687 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2688 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2689 if (ListExtractors || ListFormats) {
2697 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2702 if (
C.getArgs().hasArg(options::OPT_v) ||
2703 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2704 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2705 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2706 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2708 SuppressMissingInputWarning =
true;
2711 if (
C.getArgs().hasArg(options::OPT_v)) {
2713 llvm::errs() <<
"System configuration file directory: "
2716 llvm::errs() <<
"User configuration file directory: "
2720 const ToolChain &TC =
C.getDefaultToolChain();
2722 if (
C.getArgs().hasArg(options::OPT_v))
2725 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2730 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2731 llvm::outs() <<
"programs: =";
2732 bool separator =
false;
2736 llvm::outs() << llvm::sys::EnvPathSeparator;
2737 llvm::outs() << Path;
2742 llvm::outs() << llvm::sys::EnvPathSeparator;
2743 llvm::outs() << Path;
2746 llvm::outs() <<
"\n";
2749 StringRef sysroot =
C.getSysRoot();
2753 llvm::outs() << llvm::sys::EnvPathSeparator;
2756 llvm::outs() << sysroot << Path.substr(1);
2758 llvm::outs() << Path;
2760 llvm::outs() <<
"\n";
2764 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib)) {
2769 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib_include_dirs)) {
2774 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2780 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2781 for (
auto RuntimePath :
2783 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2784 llvm::outs() << *RuntimePath <<
'\n';
2788 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2792 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2794 for (std::size_t I = 0; I != Flags.size(); I += 2)
2795 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2801 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2802 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2806 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2807 StringRef ProgName = A->getValue();
2810 if (! ProgName.empty())
2813 llvm::outs() <<
"\n";
2817 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2818 StringRef PassedFlags = A->getValue();
2823 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2833 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2838 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2841 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2847 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2854 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2857 std::set<llvm::StringRef> SortedFlags;
2858 for (
const auto &FlagEntry : ExpandedFlags)
2859 SortedFlags.insert(FlagEntry.getKey());
2860 for (
auto Flag : SortedFlags)
2861 llvm::outs() << Flag <<
'\n';
2865 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2868 llvm::outs() <<
".\n";
2871 assert(Suffix.front() ==
'/');
2872 llvm::outs() << Suffix.substr(1) <<
"\n";
2878 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2883 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2885 llvm::outs() << Triple.getTriple() <<
"\n";
2889 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2890 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2907 std::map<Action *, unsigned> &Ids,
2909 if (
auto It = Ids.find(A); It != Ids.end())
2913 llvm::raw_string_ostream os(str);
2915 auto getSibIndent = [](
int K) -> Twine {
2919 Twine SibIndent =
Indent + getSibIndent(Kind);
2923 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2925 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2926 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2927 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2929 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2930 assert(TC &&
"Unknown host toolchain");
2945 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2953 const char *Prefix =
"{";
2954 for (
Action *PreRequisite : *AL) {
2955 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2966 std::string offload_str;
2967 llvm::raw_string_ostream offload_os(offload_str);
2971 offload_os <<
", (" << S;
2978 auto getSelfIndent = [](
int K) -> Twine {
2982 unsigned Id = Ids.size();
2984 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2993 std::map<Action *, unsigned> Ids;
2994 for (
Action *A :
C.getActions())
3010 DerivedArgList &Args =
C.getArgs();
3012 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
3015 llvm::StringSet<> ArchNames;
3017 for (Arg *A : Args) {
3018 if (A->getOption().matches(options::OPT_arch)) {
3021 llvm::Triple::ArchType
Arch =
3023 if (
Arch == llvm::Triple::UnknownArch) {
3024 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
3029 if (ArchNames.insert(A->getValue()).second)
3030 Archs.push_back(A->getValue());
3044 for (
Action* Act : SingleActions) {
3052 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
3056 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
3061 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
3062 Actions.append(Inputs.begin(), Inputs.end());
3064 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
3067 Arg *A = Args.getLastArg(options::OPT_g_Group);
3068 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
3069 !A->getOption().matches(options::OPT_gstabs);
3070 bool enablesPseudoProbe =
3071 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
3072 options::OPT_fno_pseudo_probe_for_profiling,
false);
3073 bool enablesDebugInfoForProfiling =
3074 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
3075 options::OPT_fno_debug_info_for_profiling,
false);
3076 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
3077 enablesDebugInfoForProfiling) &&
3085 if (Act->getType() == types::TY_Image) {
3087 Inputs.push_back(Actions.back());
3094 if (Args.hasArg(options::OPT_verify_debug_info)) {
3095 Action *LastAction = Actions.pop_back_val();
3097 LastAction, types::TY_Nothing));
3104 bool TypoCorrect)
const {
3116 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3117 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3129 std::string Nearest;
3130 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3131 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3132 <<
Value << Nearest;
3171 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3174 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3182 return types::TY_CXXUHeader;
3184 return types::TY_CXXSHeader;
3188 llvm_unreachable(
"should not be called in this case");
3190 return types::TY_CXXHUHeader;
3196 const llvm::opt::OptTable &Opts =
getOpts();
3200 types::ID InputType = types::TY_Nothing;
3201 Arg *InputTypeArg =
nullptr;
3204 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3205 options::OPT__SLASH_TP)) {
3206 InputTypeArg = TCTP;
3207 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3212 bool ShowNote =
false;
3214 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3216 Diag(clang::diag::warn_drv_overriding_option)
3217 <<
Previous->getSpelling() << A->getSpelling();
3223 Diag(clang::diag::note_drv_t_option_is_global);
3228 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3229 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3230 if (LastXArg && LastInputArg &&
3231 LastInputArg->getIndex() < LastXArg->getIndex())
3232 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3235 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3237 for (Arg *A : Args) {
3238 if (A->getOption().
getKind() == Option::InputClass) {
3239 const char *
Value = A->getValue();
3243 if (InputType == types::TY_Nothing) {
3246 InputTypeArg->claim();
3249 if (strcmp(
Value,
"-") == 0) {
3251 Ty = types::TY_Fortran;
3253 Ty = types::TY_HLSL;
3254 }
else if (IsSYCL) {
3264 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3265 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3266 : clang::diag::err_drv_unknown_stdin_type);
3275 if (
const char *Ext = strrchr(
Value,
'.'))
3284 Ty = types::TY_HLSL;
3286 Ty = types::TY_Object;
3297 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3298 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3299 << getTypeName(OldTy) << getTypeName(Ty);
3304 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3305 Ty == types::TY_Object)
3306 Ty = types::TY_LLVM_BC;
3314 if (Ty != types::TY_Object) {
3315 if (Args.hasArg(options::OPT_ObjC))
3316 Ty = types::TY_ObjC;
3317 else if (Args.hasArg(options::OPT_ObjCXX))
3318 Ty = types::TY_ObjCXX;
3325 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3329 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3330 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3333 const char *Ext = strrchr(
Value,
'.');
3335 Ty = types::TY_Object;
3339 InputTypeArg->claim();
3343 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3344 Args.hasArgNoClaim(options::OPT_hipstdpar))
3348 Inputs.push_back(std::make_pair(Ty, A));
3350 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3351 StringRef
Value = A->getValue();
3354 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3355 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3358 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3359 StringRef
Value = A->getValue();
3362 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3363 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3369 Inputs.push_back(std::make_pair(types::TY_Object, A));
3371 }
else if (A->getOption().matches(options::OPT_x)) {
3380 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3381 InputType = types::TY_Object;
3388 }
else if (A->getOption().getID() == options::OPT_U) {
3389 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3390 StringRef Val = A->getValue(0);
3391 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3393 Diag(diag::warn_slash_u_filename) << Val;
3394 Diag(diag::note_use_dashdash);
3398 if (
CCCIsCPP() && Inputs.empty()) {
3402 Inputs.push_back(std::make_pair(types::TY_C, A));
3406void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3411 if (Arg *FoArg = Args.getLastArg(options::OPT__SLASH_Fo),
3412 *FaArg = Args.getLastArg(options::OPT__SLASH_Fa);
3415 unsigned NumCompiledInputs = llvm::count_if(
3416 Inputs, [](
const InputTy &I) {
return I.first != types::TY_Object; });
3418 for (Arg *A : {FoArg, FaArg}) {
3421 StringRef
V = A->getValue();
3422 if (NumCompiledInputs > 1 && !
V.empty() &&
3423 !llvm::sys::path::is_separator(
V.back())) {
3425 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3426 << A->getSpelling() <<
V;
3427 Args.eraseArg(A->getOption().getID());
3433 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
3434 if (A->getValue()[0] ==
'\0') {
3436 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
3437 Args.eraseArg(options::OPT__SLASH_o);
3442 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3443 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3444 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3445 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3446 Args.eraseArg(options::OPT__SLASH_Yc);
3447 Args.eraseArg(options::OPT__SLASH_Yu);
3448 YcArg = YuArg =
nullptr;
3450 if (YcArg && Inputs.size() > 1) {
3451 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3452 Args.eraseArg(options::OPT__SLASH_Yc);
3460 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3461 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3462 Args.AddFlagArg(
nullptr,
3463 getOpts().getOption(options::OPT_frtlib_add_rpath));
3467 if (Args.hasArg(options::OPT_emit_llvm) &&
3468 !Args.hasArg(options::OPT_hip_link) &&
3469 !
C.getDefaultToolChain().getTriple().isSPIRV())
3470 Diag(clang::diag::err_drv_emit_llvm_link);
3471 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
3472 C.getDefaultToolChain().isUsingLTO(Args) &&
3473 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
3474 .starts_with_insensitive(
"lld"))
3475 Diag(clang::diag::err_drv_lto_without_lld);
3481 if (!Args.hasArg(options::OPT_dumpdir)) {
3482 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
3483 Arg *Arg = Args.MakeSeparateArg(
3484 nullptr,
getOpts().getOption(options::OPT_dumpdir),
3486 (FinalOutput ? FinalOutput->getValue()
3498 Args.eraseArg(options::OPT__SLASH_Fp);
3499 Args.eraseArg(options::OPT__SLASH_Yc);
3500 Args.eraseArg(options::OPT__SLASH_Yu);
3501 YcArg = YuArg =
nullptr;
3504 if (Args.hasArg(options::OPT_include_pch) &&
3505 Args.hasArg(options::OPT_ignore_pch)) {
3509 Args.eraseArg(options::OPT_include_pch);
3512 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
3513 for (
auto &I : Inputs) {
3515 const Arg *InputArg = I.second;
3520 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
3524 if (InitialPhase > FinalPhase) {
3525 if (InputArg->isClaimed())
3532 if (Args.hasArg(options::OPT_Qunused_arguments))
3538 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3539 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3543 (Args.getLastArg(options::OPT__SLASH_EP,
3544 options::OPT__SLASH_P) ||
3545 Args.getLastArg(options::OPT_E) ||
3546 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3548 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3549 << InputArg->getAsString(Args) << !FinalPhaseArg
3550 << (FinalPhaseArg ? FinalPhaseArg->getSpelling() :
"");
3552 Diag(clang::diag::warn_drv_input_file_unused)
3553 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3555 << (FinalPhaseArg ? FinalPhaseArg->getSpelling() :
"");
3564 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
3565 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
3570 Actions.push_back(ClangClPch);
3582 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3583 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3591 const llvm::opt::DerivedArgList &Args,
3594 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
3596 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
3599 bool HasAMDGCNHIPDevice =
false;
3601 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
3603 const llvm::Triple &Tr = TC->
getTriple();
3606 HasAMDGCNHIPDevice =
true;
3608 return HasAMDGCNHIPDevice;
3613 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
3615 if (!SuppressMissingInputWarning && Inputs.empty()) {
3616 Diag(clang::diag::err_drv_no_input_files);
3620 handleArguments(
C, Args, Inputs, Actions);
3625 if (Arg *A = Args.getLastArg(options::OPT_no_offload_new_driver))
3626 Diag(clang::diag::warn_drv_deprecated_custom)
3627 << A->getAsString(Args)
3628 <<
"the legacy offloading driver has been removed";
3629 Args.ClaimAllArgs(options::OPT_no_offload_new_driver);
3630 Args.ClaimAllArgs(options::OPT_offload_new_driver);
3632 bool HIPRDCDeviceOnlyFatBin =
3634 Args.hasArg(options::OPT_hip_link) &&
3635 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
3637 !Args.hasArg(options::OPT_emit_llvm) &&
3638 Args.hasFlag(options::OPT_gpu_bundle_output,
3639 options::OPT_no_gpu_bundle_output,
true);
3646 for (
auto &I : Inputs) {
3648 const Arg *InputArg = I.second;
3660 if (HIPRDCDeviceOnlyFatBin && InputType == types::TY_LLVM_BC) {
3661 LinkerInputs.push_back(Current);
3667 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
3679 assert(Phase == PL.back() &&
"linking must be final compilation step.");
3682 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
3683 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
3685 LinkerInputs.push_back(Current);
3695 assert(Phase == PL.back() &&
"merging must be final compilation step.");
3696 MergerInputs.push_back(Current);
3713 C.getDefaultToolChain().getLTOMode(Args));
3716 if (NewCurrent == Current)
3719 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
3722 Current = NewCurrent;
3727 &HIPAsmDeviceActions);
3729 if (Current->
getType() == types::TY_Nothing)
3735 if (Current && !HIPAsmDeviceActions.empty()) {
3737 BundleInputs.append(HIPAsmDeviceActions);
3738 BundleInputs.push_back(Current);
3744 Actions.push_back(Current);
3751 if (!LinkerInputs.empty()) {
3757 Args.hasArg(options::OPT_offload_link)) {
3760 HIPRDCDeviceOnlyFatBin ? types::TY_HIP_FATBIN : types::TY_Image);
3767 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
3768 C.getDefaultToolChain().getTriple().isSPIRV();
3769 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
3773 Actions.push_back(LA);
3777 if (!MergerInputs.empty())
3781 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
3788 for (
auto &I : Inputs) {
3790 const Arg *InputArg = I.second;
3795 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
3796 InputType == types::TY_Asm)
3801 for (
auto Phase : PhaseList) {
3805 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
3810 if (InputType == types::TY_Object)
3817 assert(Phase == PhaseList.back() &&
3818 "merging must be final compilation step.");
3819 MergerInputs.push_back(Current);
3828 Actions.push_back(Current);
3832 if (!MergerInputs.empty())
3837 for (
auto Opt : {options::OPT_print_supported_cpus,
3838 options::OPT_print_supported_extensions,
3839 options::OPT_print_enabled_extensions}) {
3846 if (Arg *A = Args.getLastArg(Opt)) {
3847 if (Opt == options::OPT_print_supported_extensions &&
3848 !
C.getDefaultToolChain().getTriple().isRISCV() &&
3849 !
C.getDefaultToolChain().getTriple().isAArch64() &&
3850 !
C.getDefaultToolChain().getTriple().isARM()) {
3851 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
3852 <<
"--print-supported-extensions";
3855 if (Opt == options::OPT_print_enabled_extensions &&
3856 !
C.getDefaultToolChain().getTriple().isRISCV() &&
3857 !
C.getDefaultToolChain().getTriple().isAArch64()) {
3858 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
3859 <<
"--print-enabled-extensions";
3866 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
3869 for (
auto &I : Inputs)
3874 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
3875 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
3876 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
3882 if (TC.requiresObjcopy(Args)) {
3883 Action *LastAction = Actions.back();
3885 if (LastAction->
getType() == types::TY_Object) {
3893 auto ValInfo = TC.getValidationInfo(Args);
3894 if (ValInfo.NeedsValidation) {
3895 Action *LastAction = Actions.back();
3896 if (LastAction->
getType() == types::TY_Object) {
3898 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
3905 if (TC.requiresBinaryTranslation(Args)) {
3906 Action *LastAction = Actions.back();
3910 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
3911 LastAction->
getType() == types::TY_Object)
3913 LastAction, types::TY_DX_CONTAINER));
3918 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
3924 const llvm::opt::DerivedArgList &Args,
3926 const llvm::Triple &Triple) {
3931 if (Triple.isNVPTX() && (
Arch.isUnknown() || !
Arch.isNVPTX())) {
3932 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3933 <<
"CUDA" << ArchStr;
3935 }
else if (Triple.isAMDGPU()) {
3936 if (
Arch.isUnknown() || (!
Arch.isAMDGPU() && !
Arch.isAMDGCNSPIRV())) {
3937 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3938 <<
"HIP" << ArchStr;
3942 if (Triple.getSubArch() != llvm::Triple::NoSubArch) {
3944 if (ArchSubArch != Triple.getSubArch() &&
3945 llvm::AMDGPU::getMajorSubArch(ArchSubArch) != Triple.getSubArch()) {
3946 C.getDriver().Diag(clang::diag::err_target_unsupported_arch)
3947 << ArchStr << Triple.getArchName();
3951 }
else if (Triple.isSPIRV() && ArchStr.starts_with(
"igca")) {
3953 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3954 <<
"IGCA" << ArchStr;
3962 if (
Arch.isAMDGPU() ||
Arch.isAMDGCNSPIRV()) {
3965 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
3968 return Args.MakeArgStringRef(*TargetID);
3977static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3979 llvm::Triple Triple) {
3980 if (!Triple.isAMDGPU())
3981 return std::nullopt;
3983 std::set<StringRef> ArchSet;
3984 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
3988llvm::SmallVector<BoundArch>
3992 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3993 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3994 options::OPT_no_offload_arch_EQ)) {
3995 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3997 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
3999 :
"--no-offload-arch");
4002 llvm::DenseSet<StringRef> Archs;
4003 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
4006 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4007 for (StringRef
Arch : Arg->getValues()) {
4008 if (
Arch ==
"native" ||
Arch.empty()) {
4013 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4017 for (
auto ArchStr : *GPUsOrErr) {
4019 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4020 if (!CanonicalStr.empty())
4021 Archs.insert(CanonicalStr);
4026 StringRef CanonicalStr =
4028 if (!CanonicalStr.empty())
4029 Archs.insert(CanonicalStr);
4034 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4035 for (StringRef
Arch : Arg->getValues()) {
4036 if (
Arch ==
"all") {
4041 Archs.erase(ArchStr);
4047 if (
auto ConflictingArchs =
4049 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4050 << ConflictingArchs->first << ConflictingArchs->second;
4053 bool HasSubArch = TC.
getTriple().isAMDGCN() &&
4054 TC.
getTriple().getSubArch() != llvm::Triple::NoSubArch;
4055 if (Archs.empty() && !HasSubArch) {
4065 Archs.insert(StringRef());
4068 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
4069 .getLastArg(options::OPT_march_EQ)) {
4070 Archs.insert(Arg->getValue());
4075 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4076 <<
"--offload-arch";
4077 }
else if (!ArchsOrErr->empty()) {
4078 for (
auto Arch : *ArchsOrErr)
4079 Archs.insert(Args.MakeArgStringRef(
Arch));
4081 Archs.insert(StringRef());
4085 }
else if (Archs.empty() && HasSubArch) {
4092 llvm::StringRef ArchStr = TripleOffloadArch.
isUnknown()
4095 StringRef CanonicalStr =
4097 if (!CanonicalStr.empty())
4098 Archs.insert(CanonicalStr);
4101 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4102 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4109 Result.reserve(Sorted.size());
4110 for (StringRef
Arch : Sorted)
4117 const InputTy &Input, StringRef CUID,
4127 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4132 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4135 bool HIPRelocatableObj =
4137 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4138 options::OPT_fno_hip_emit_relocatable,
false);
4140 if (!HIPNoRDC && HIPRelocatableObj)
4141 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4142 <<
"-fhip-emit-relocatable"
4146 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4147 <<
"-fhip-emit-relocatable"
4148 <<
"--offload-device-only";
4156 bool UsesLLVMOffloading = Args.hasArg(
4157 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
4169 auto TCRange =
C.getOffloadToolChains(Kind);
4170 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4171 ToolChains.push_back(TI->second);
4173 if (ToolChains.empty())
4177 const Arg *InputArg = Input.second;
4186 for (
const ToolChain *TC : ToolChains) {
4188 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4189 DeviceActions.push_back(
4190 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4194 if (DeviceActions.empty())
4200 HostAction->
getType() != types::TY_Nothing &&
4210 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4219 auto *TCAndArch = TCAndArchs.begin();
4220 for (
Action *&A : DeviceActions) {
4221 if (A->
getType() == types::TY_Nothing)
4228 TCAndArch->first->getLTOMode(Args, Kind));
4232 HostAction->
getType() != types::TY_Nothing) {
4239 TCAndArch->second, Kind);
4241 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4251 for (
Action *&A : DeviceActions) {
4256 OffloadTriple && OffloadTriple->isSPIRV() &&
4257 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
4258 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
4260 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
4261 A->
getType() != types::TY_LTO_BC) ||
4268 auto *TCAndArch = TCAndArchs.begin();
4269 for (
Action *A : DeviceActions) {
4270 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4272 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4279 A->
getType() == types::TY_Object &&
4280 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4282 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
4291 bool ShouldBundleHIP =
4292 Args.hasFlag(options::OPT_gpu_bundle_output,
4293 options::OPT_no_gpu_bundle_output,
false) ||
4294 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
4296 return A->
getType() != types::TY_Image;
4307 if (OffloadActions.empty())
4312 (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) ||
4313 Args.hasArg(options::OPT_cuda_emit_nvcc_abi))) {
4317 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4324 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4325 DDep.
add(*FatbinAction,
4328 }
else if ((!UsesLLVMOffloading && HIPNoRDC) || SYCLNoRDC) {
4331 if (HIPNoRDC && HIPAsmBundleDeviceOut &&
4333 for (
Action *OA : OffloadActions)
4334 HIPAsmBundleDeviceOut->push_back(OA);
4347 SYCLNoRDC ? types::TY_SYCL_FATBIN : types::TY_HIP_FATBIN;
4350 DDep.
add(*PackagerAction, *
C.getOffloadToolChains(Kind).first->second,
4358 {},
C.getActiveOffloadKinds());
4367 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4368 return A->
getType() == types::TY_Nothing;
4372 {}, SingleDeviceOutput ? DDep : DDeps);
4373 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4379 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4389 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4395 llvm_unreachable(
"link action invalid here.");
4397 llvm_unreachable(
"ifsmerge action invalid here.");
4402 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4403 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4404 OutputTy = types::TY_Dependencies;
4409 if (!Args.hasFlag(options::OPT_frewrite_includes,
4410 options::OPT_fno_rewrite_includes,
false) &&
4411 !Args.hasFlag(options::OPT_frewrite_imports,
4412 options::OPT_fno_rewrite_imports,
false) &&
4413 !Args.hasFlag(options::OPT_fdirectives_only,
4414 options::OPT_fno_directives_only,
false) &&
4418 "Cannot preprocess this input type!");
4424 if (Args.hasArg(options::OPT_extract_api))
4429 if (Input->
getType() == types::TY_CXXStdModule ||
4430 Input->
getType() == types::TY_PP_CXXStdModule)
4432 Input, getPrecompiledType(Input->
getType()));
4440 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
4441 (Input->
getType() == driver::types::TY_CXXModule ||
4442 Input->
getType() == driver::types::TY_PP_CXXModule) &&
4443 !Args.getLastArg(options::OPT__precompile) &&
4444 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
4449 "Cannot precompile this input type!");
4453 const char *ModName =
nullptr;
4454 if (OutputTy == types::TY_PCH) {
4455 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4456 ModName = A->getValue();
4458 OutputTy = types::TY_ModuleFile;
4461 if (Args.hasArg(options::OPT_fsyntax_only)) {
4463 OutputTy = types::TY_Nothing;
4469 if (Args.hasArg(options::OPT_fsyntax_only))
4471 if (Args.hasArg(options::OPT_rewrite_objc))
4473 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4475 types::TY_RewrittenLegacyObjC);
4476 if (Args.hasArg(options::OPT__analyze))
4478 if (Args.hasArg(options::OPT_emit_ast))
4480 if (Args.hasArg(options::OPT_emit_cir)) {
4483 if (Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S))
4487 if (Args.hasArg(options::OPT_module_file_info))
4489 if (Args.hasArg(options::OPT_verify_pch))
4491 if (Args.hasArg(options::OPT_extract_api))
4498 if (!IsDeviceOffload) {
4500 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4501 !Args.hasArg(options::OPT_emit_llvm))
4502 Output = types::TY_PP_Asm;
4503 else if (Args.hasArg(options::OPT_S))
4504 Output = types::TY_LTO_IR;
4506 Output = types::TY_LTO_BC;
4510 if (Args.hasArg(options::OPT_emit_llvm)) {
4512 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4514 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4518 Output = types::TY_PP_Asm;
4519 }
else if (Args.hasArg(options::OPT_S)) {
4520 Output = types::TY_LTO_IR;
4522 Output = types::TY_LTO_BC;
4528 if (Args.hasArg(options::OPT_emit_llvm) ||
4532 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4541 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
4542 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
4553 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4576 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
4596 if (!OffloadJobs.isValid())
4597 D.
Diag(diag::err_drv_invalid_int_value)
4598 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
4600 OffloadJobs.A->claim();
4604 for (
auto &Job :
C.getJobs()) {
4608 Job.setOffloadDeviceParallelJobGroup(
4614 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4616 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4636 unsigned NumOutputs = 0;
4637 unsigned NumIfsOutputs = 0;
4638 for (
const Action *A :
C.getActions()) {
4648 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
4649 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
4652 if (A->
getType() != types::TY_Nothing &&
4654 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4656 0 == NumIfsOutputs++) ||
4661 A->
getType() == types::TY_Nothing &&
4662 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4663 NumOutputs += A->
size();
4666 if (NumOutputs > 1) {
4667 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4668 FinalOutput =
nullptr;
4672 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4675 llvm::StringSet<> ArchNames;
4676 if (RawTriple.isOSBinFormatMachO())
4677 for (
const Arg *A :
C.getArgs())
4678 if (A->getOption().matches(options::OPT_arch))
4679 ArchNames.insert(A->getValue());
4682 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4683 for (
Action *A :
C.getActions()) {
4690 const char *LinkingOutput =
nullptr;
4693 LinkingOutput = FinalOutput->getValue();
4701 ArchNames.size() > 1 ||
4702 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
4703 LinkingOutput, CachedResults,
4710 for (
auto &J :
C.getJobs())
4711 J.InProcess =
false;
4718 C.setPostCallback([=](
const Command &Cmd,
int Res) {
4719 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4724 const char *LinkingOutput =
nullptr;
4726 LinkingOutput = FinalOutput->getValue();
4733 using namespace llvm;
4736 <<
"output=" << LinkingOutput;
4737 outs() <<
", total="
4738 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4740 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4741 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4745 llvm::raw_string_ostream Out(Buffer);
4746 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
4749 llvm::sys::printArg(Out, LinkingOutput,
true);
4750 Out <<
',' << ProcStat->TotalTime.count() <<
','
4751 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4756 llvm::sys::fs::OF_Append |
4757 llvm::sys::fs::OF_Text);
4762 llvm::errs() <<
"ERROR: Cannot lock file "
4764 <<
toString(L.takeError()) <<
"\n";
4775 bool ReportUnusedArguments =
4776 !Diags.hasErrorOccurred() &&
4777 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
4780 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
4782 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
4785 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
4786 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
4788 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
4792 return strstr(J.getCreator().getShortName(),
"assembler");
4794 for (Arg *A :
C.getArgs()) {
4798 if (!A->isClaimed()) {
4804 const Option &Opt = A->getOption();
4805 if (Opt.getKind() == Option::FlagClass) {
4806 bool DuplicateClaimed =
false;
4808 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
4809 if (AA->isClaimed()) {
4810 DuplicateClaimed =
true;
4815 if (DuplicateClaimed)
4821 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
4823 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
4828 !
C.getActions().empty()) {
4829 Diag(diag::err_drv_unsupported_opt_for_target)
4831 }
else if (ReportUnusedArguments) {
4832 Diag(clang::diag::warn_drv_unused_argument)
4833 << A->getAsString(
C.getArgs());
4843class ToolSelector final {
4854 bool IsHostSelector;
4865 bool CanBeCollapsed =
true) {
4867 if (Inputs.size() != 1)
4870 Action *CurAction = *Inputs.begin();
4871 if (CanBeCollapsed &&
4877 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
4881 if (!IsHostSelector) {
4882 if (OA->hasSingleDeviceDependence(
true)) {
4884 OA->getSingleDeviceDependence(
true);
4885 if (CanBeCollapsed &&
4888 SavedOffloadAction.push_back(OA);
4889 return dyn_cast<JobAction>(CurAction);
4891 }
else if (OA->hasHostDependence()) {
4892 CurAction = OA->getHostDependence();
4893 if (CanBeCollapsed &&
4896 SavedOffloadAction.push_back(OA);
4897 return dyn_cast<JobAction>(CurAction);
4902 return dyn_cast<JobAction>(CurAction);
4906 bool canCollapseAssembleAction()
const {
4907 return TC.useIntegratedAs() && !SaveTemps &&
4908 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
4909 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
4910 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
4911 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
4915 bool canCollapsePreprocessorAction()
const {
4916 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
4917 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
4918 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
4923 struct JobActionInfo final {
4925 const JobAction *JA =
nullptr;
4933 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
4934 ArrayRef<JobActionInfo> &ActionInfo,
4935 unsigned ElementNum) {
4936 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
4937 for (
unsigned I = 0; I < ElementNum; ++I)
4938 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
4939 ActionInfo[I].SavedOffloadAction.end());
4952 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
4955 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
4957 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4958 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4959 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
4960 if (!AJ || !BJ || !CJ)
4964 const Tool *
T = TC.SelectTool(*CJ);
4971 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
4977 const Tool *BT = TC.SelectTool(*BJ);
4982 if (!
T->hasIntegratedAssembler())
4985 Inputs = CJ->getInputs();
4986 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4990 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
4993 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
4995 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4996 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5001 const Tool *
T = TC.SelectTool(*BJ);
5005 if (!
T->hasIntegratedAssembler())
5008 Inputs = BJ->getInputs();
5009 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5013 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5016 if (ActionInfo.size() < 2)
5018 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5019 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5023 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5024 for (
auto &Input : AI.JA->getInputs())
5035 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5036 if (SaveTemps && !InputIsBitcode)
5040 const Tool *
T = TC.SelectTool(*CJ);
5047 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5053 Inputs = CJ->getInputs();
5054 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5063 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5065 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5071 for (Action *A : Inputs) {
5072 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5074 NewInputs.push_back(A);
5080 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5081 PreprocessJobOffloadActions.end());
5082 NewInputs.append(PJ->input_begin(), PJ->input_end());
5088 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5090 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5092 assert(BaseAction &&
"Invalid base action.");
5108 SmallVector<JobActionInfo, 5> ActionChain(1);
5109 ActionChain.back().JA = BaseAction;
5110 while (ActionChain.back().JA) {
5111 const Action *CurAction = ActionChain.back().JA;
5114 ActionChain.resize(ActionChain.size() + 1);
5115 JobActionInfo &AI = ActionChain.back();
5119 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5123 ActionChain.pop_back();
5131 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5132 CollapsedOffloadAction);
5134 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5136 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5142 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5155 std::string TriplePlusArch = TC->
getTriple().normalize();
5157 TriplePlusArch +=
"-";
5160 TriplePlusArch +=
"-";
5162 return TriplePlusArch;
5167 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5168 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5171 std::pair<const Action *, std::string> ActionTC = {
5173 auto CachedResult = CachedResults.find(ActionTC);
5174 if (CachedResult != CachedResults.end()) {
5175 return CachedResult->second;
5178 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
5179 TargetDeviceOffloadKind);
5180 CachedResults[ActionTC] =
Result;
5185 const JobAction *JA,
const char *BaseInput,
5188 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5199 if (!
Arch.empty()) {
5200 OffloadingPrefix +=
"-";
5201 OffloadingPrefix +=
Arch.ArchName;
5204 C.getDriver().isSaveTempsEnabled()) {
5210 StringRef DefaultExt =
".json";
5211 StringRef DefaultExtNoDot =
"json";
5212 if (
const Arg *CompressArg =
5213 Args.getLastArgNoClaim(options::OPT_ftime_trace_compress_EQ)) {
5214 if (StringRef(CompressArg->getValue()) ==
"zstd") {
5215 DefaultExt =
".json.zst";
5216 DefaultExtNoDot =
"json.zst";
5221 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5222 Path = A->getValue();
5223 if (llvm::sys::fs::is_directory(Path)) {
5225 ? llvm::sys::path::stem(
Result.getFilename())
5226 : llvm::sys::path::stem(BaseInput));
5227 Tmp += OffloadingPrefix;
5229 llvm::sys::path::append(Path, Tmp);
5232 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5235 Path = DumpDir->getValue();
5236 Path += llvm::sys::path::stem(BaseInput);
5237 Path += OffloadingPrefix;
5239 }
else if (!OffloadingPrefix.empty()) {
5243 TraceName += OffloadingPrefix;
5244 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
5245 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
5246 llvm::sys::path::append(Path, TraceName);
5249 Path =
Result.getFilename();
5250 llvm::sys::path::replace_extension(Path, DefaultExtNoDot);
5253 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5254 C.addTimeTraceFile(ResultFile, JA);
5255 C.addResultFile(ResultFile, JA);
5260 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5261 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5264 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5268 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
5269 C.setCurrentBoundArch(BA);
5270 auto RestoreBoundArch =
5271 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
5274 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5275 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5307 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5309 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5310 BoundArch DepBoundArch) {
5312 !DepBoundArch.
empty(),
5313 LinkingOutput, CachedResults,
5323 OA->doOnEachDependence(
5324 BuildingForOffloadDevice,
5325 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5327 C, DepA, DepTC, DepBoundArch,
false,
5328 !DepBoundArch.
empty(), LinkingOutput,
5332 A = BuildingForOffloadDevice
5333 ? OA->getSingleDeviceDependence(
true)
5334 : OA->getHostDependence();
5338 std::pair<const Action *, std::string> ActionTC = {
5339 OA->getHostDependence(),
5341 auto It = CachedResults.find(ActionTC);
5342 if (It != CachedResults.end()) {
5344 Inputs.append(OffloadDependencesInputInfo);
5349 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5352 const Arg &Input = IA->getInputArg();
5354 if (Input.getOption().matches(options::OPT_INPUT)) {
5355 const char *
Name = Input.getValue();
5358 return {InputInfo(A, &Input,
"")};
5361 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5362 const ToolChain *TC;
5363 BoundArch ArchName = BAA->
getArch();
5365 if (!ArchName.
empty())
5366 TC = &getToolChain(
C.getArgs(),
5370 TC = &
C.getDefaultToolChain();
5373 MultipleArchs, LinkingOutput, CachedResults,
5374 TargetDeviceOffloadKind);
5387 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5390 return {InputInfo()};
5394 for (
const auto *OA : CollapsedOffloadActions)
5396 BuildingForOffloadDevice,
5397 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5399 C, DepA, DepTC, DepBoundArch,
false,
5400 !DepBoundArch.
empty(), LinkingOutput,
5406 for (
const Action *Input : Inputs) {
5410 bool SubJobAtTopLevel =
5413 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5418 const char *BaseInput = InputInfos[0].getBaseInput();
5419 for (
auto &Info : InputInfos) {
5420 if (Info.isFilename()) {
5421 BaseInput = Info.getBaseInput();
5428 if (JA->
getType() == types::TY_dSYM)
5429 BaseInput = InputInfos[0].getFilename();
5432 if (!OffloadDependencesInputInfo.empty())
5433 InputInfos.append(OffloadDependencesInputInfo.begin(),
5434 OffloadDependencesInputInfo.end());
5437 llvm::Triple EffectiveTriple;
5438 const ToolChain &ToolTC =
T->getToolChain();
5439 const ArgList &Args =
5441 if (InputInfos.size() != 1) {
5446 EffectiveTriple = llvm::Triple(
5449 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
5453 if (JA->
getType() == types::TY_Nothing)
5454 Result = {InputInfo(A, BaseInput)};
5465 MultipleArchs, OffloadingPrefix),
5472 llvm::errs() <<
"# \"" <<
T->getToolChain().getEffectiveTriple().str()
5473 <<
'"' <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5474 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5475 llvm::errs() << InputInfos[i].getAsString();
5477 llvm::errs() <<
", ";
5479 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5481 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5487 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5488 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5500 if (ArgValue.empty()) {
5502 Filename = BaseName;
5503 }
else if (llvm::sys::path::is_separator(Filename.back())) {
5505 llvm::sys::path::append(Filename, BaseName);
5508 if (!llvm::sys::path::has_extension(ArgValue)) {
5513 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5518 llvm::sys::path::replace_extension(Filename, Extension);
5521 return Args.MakeArgString(Filename.c_str());
5536 StringRef Suffix,
bool MultipleArchs,
5537 StringRef BoundArchStr,
5538 bool NeedUniqueDirectory)
const {
5540 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5541 std::optional<std::string> CrashDirectory =
5543 ? std::string(A->getValue())
5544 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5545 if (CrashDirectory) {
5546 if (!
getVFS().exists(*CrashDirectory))
5547 llvm::sys::fs::create_directories(*CrashDirectory);
5549 llvm::sys::path::append(Path, Prefix);
5550 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5551 if (std::error_code EC =
5552 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
5553 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5557 if (MultipleArchs && !BoundArchStr.empty()) {
5558 if (NeedUniqueDirectory) {
5560 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
5571 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5586 const char *BaseInput) {
5588 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5589 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5594 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5599 bool AtTopLevel,
bool MultipleArchs,
5600 StringRef OffloadingPrefix)
const {
5603 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5605 auto CreateTempOutputPath = [&](StringRef Prefix) {
5606 const char *Suffix =
5611 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
5612 const bool NeedUniqueDirectory =
5615 Triple.isOSDarwin();
5617 NeedUniqueDirectory);
5622 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
5623 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
5624 StringRef Filename = llvm::sys::path::filename(BaseInput);
5625 StringRef Stem = llvm::sys::path::stem(Filename);
5626 return CreateTempOutputPath(Stem);
5631 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5632 return C.addResultFile(FinalOutput->getValue(), &JA);
5636 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5638 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5640 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5641 NameArg = A->getValue();
5642 return C.addResultFile(
5652 if (JA.
getType() == types::TY_ModuleFile &&
5653 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5657 if (JA.
getType() == types::TY_PP_Asm &&
5658 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5659 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5662 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
5665 if ((JA.
getType() == types::TY_Object &&
5666 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
5667 JA.
getType() == types::TY_DX_CONTAINER) {
5668 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5669 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
5670 C.getDefaultToolChain().getTriple().isSPIRV()) &&
5671 "expected DXIL or SPIR-V triple for HLSL output path");
5676 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
5678 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
5679 StringRef
Name = llvm::sys::path::filename(BaseInput);
5680 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5686 if (JA.
getType() == types::TY_PP_Asm &&
5687 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5688 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5690 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5691 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5692 return C.addResultFile(
5697 if (JA.
getType() == types::TY_API_INFO &&
5698 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5699 C.getArgs().hasArg(options::OPT_o))
5700 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5701 <<
C.getArgs().getLastArgValue(options::OPT_o);
5708 bool SpecifiedModuleOutput =
5709 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5710 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5711 if (MultipleArchs && SpecifiedModuleOutput)
5712 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5717 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5718 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
5724 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5726 StringRef
Name = llvm::sys::path::filename(BaseInput);
5727 return CreateTempOutputPath(
Name.split(
'.').first);
5736 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
5741 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
5742 llvm::sys::path::filename(BasePath));
5743 BaseName = ExternalPath;
5745 BaseName = BasePath;
5747 BaseName = llvm::sys::path::filename(BasePath);
5750 const char *NamedOutput;
5752 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
5753 JA.
getType() == types::TY_LLVM_BC ||
5754 JA.
getType() == types::TY_LLVM_IR) &&
5755 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
5759 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
5763 }
else if (JA.
getType() == types::TY_Image &&
5764 C.getArgs().hasArg(options::OPT__SLASH_Fe,
5765 options::OPT__SLASH_o)) {
5769 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
5773 }
else if (JA.
getType() == types::TY_Image) {
5783 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
5784 options::OPT_fno_gpu_rdc,
false);
5786 if (UseOutExtension) {
5788 llvm::sys::path::replace_extension(Output,
"");
5790 Output += OffloadingPrefix;
5791 if (MultipleArchs && !BoundArchStr.empty()) {
5793 Output.append(BoundArchStr);
5795 if (UseOutExtension)
5797 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
5800 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
5801 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
5802 C.getArgs().hasArg(options::OPT__SLASH_o)) {
5805 .getLastArg(options::OPT__SLASH_o)
5810 const char *Suffix =
5812 assert(Suffix &&
"All types used for output should have a suffix.");
5814 std::string::size_type End = std::string::npos;
5816 End = BaseName.rfind(
'.');
5818 Suffixed += OffloadingPrefix;
5819 if (MultipleArchs && !BoundArchStr.empty()) {
5821 Suffixed.append(BoundArchStr);
5826 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
5827 const llvm::opt::DerivedArgList &Args) {
5840 bool IsLinkerWrapper =
5842 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
5843 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
5844 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
5846 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
5850 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
5854 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
5855 JA.
getType() != types::TY_PCH) {
5856 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5858 llvm::sys::path::remove_filename(TempPath);
5859 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
5860 llvm::sys::path::append(TempPath, OutputFileName);
5861 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
5870 bool SameFile =
false;
5871 llvm::sys::fs::equivalent(BaseInput, NamedOutput, SameFile);
5873 StringRef
Name = llvm::sys::path::filename(BaseInput);
5874 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5878 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5884 llvm::sys::path::remove_filename(BasePath);
5885 if (BasePath.empty())
5886 BasePath = NamedOutput;
5888 llvm::sys::path::append(BasePath, NamedOutput);
5889 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
5892 return C.addResultFile(NamedOutput, &JA);
5898 -> std::optional<std::string> {
5901 for (
const auto &
Dir : P) {
5905 llvm::sys::path::append(P,
Name);
5906 if (llvm::sys::fs::exists(Twine(P)))
5907 return std::string(P);
5909 return std::nullopt;
5916 llvm::sys::path::append(R,
Name);
5917 if (llvm::sys::fs::exists(Twine(R)))
5918 return std::string(R);
5921 llvm::sys::path::append(P,
Name);
5922 if (llvm::sys::fs::exists(Twine(P)))
5923 return std::string(P);
5927 if (std::optional<std::string> IntrPath =
5930 llvm::sys::path::append(P,
Name);
5931 if (llvm::sys::fs::exists(P))
5932 return std::string(P);
5937 llvm::sys::path::append(D,
"..",
Name);
5938 if (llvm::sys::fs::exists(Twine(D)))
5939 return std::string(D);
5948 llvm::sys::path::append(R2,
"..",
"..",
Name);
5949 if (llvm::sys::fs::exists(Twine(R2)))
5950 return std::string(R2);
5952 return std::string(
Name);
5955void Driver::generatePrefixedToolNames(
5959 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
5960 Names.emplace_back(
Tool);
5964 llvm::sys::path::append(Dir, Name);
5965 if (llvm::sys::fs::can_execute(Twine(Dir)))
5967 llvm::sys::path::remove_filename(Dir);
5973 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
5978 if (llvm::sys::fs::is_directory(PrefixDir)) {
5981 return std::string(P);
5984 if (llvm::sys::fs::can_execute(Twine(P)))
5985 return std::string(P);
5990 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
5998 for (
const auto &Path : List) {
6001 return std::string(P);
6005 if (llvm::ErrorOr<std::string> P =
6006 llvm::sys::findProgramByName(TargetSpecificExecutable))
6010 return std::string(
Name);
6015 std::string error =
"<NOT PRESENT>";
6017 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6022 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6039 llvm::sys::path::remove_filename(path);
6040 llvm::sys::path::append(path,
"libc++.modules.json");
6041 if (TC.
getVFS().exists(path))
6042 return static_cast<std::string
>(path);
6047 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6050 return evaluate(
"libc++.a").value_or(error);
6054 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6058 llvm::sys::path::remove_filename(path);
6059 llvm::sys::path::append(path,
"libstdc++.modules.json");
6060 if (TC.
getVFS().exists(path))
6061 return static_cast<std::string
>(path);
6066 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6069 return evaluate(
"libstdc++.a").value_or(error);
6078 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6080 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6084 return std::string(Path);
6089 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6091 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6095 return std::string(Path);
6100 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6104 Output = FpArg->getValue();
6108 if (!llvm::sys::path::has_extension(Output))
6111 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6112 Output = YcArg->getValue();
6115 llvm::sys::path::replace_extension(Output,
".pch");
6117 return std::string(Output);
6120const ToolChain &Driver::getOffloadToolChain(
6122 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6123 std::unique_ptr<ToolChain> &TC =
6124 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6125 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6127 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6130 switch (
Target.getOS()) {
6131 case llvm::Triple::CUDA:
6132 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6135 case llvm::Triple::AMDHSA:
6141 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6142 HostTC.get(), Kind);
6150 switch (
Target.getArch()) {
6151 case llvm::Triple::amdgpu:
6152 case llvm::Triple::r600:
6153 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6154 HostTC.get(), Kind);
6156 case llvm::Triple::spir:
6157 case llvm::Triple::spir64:
6158 case llvm::Triple::spirv:
6159 case llvm::Triple::spirv32:
6160 case llvm::Triple::spirv64:
6163 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6167 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6171 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6175 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6189 return getToolChain(Args,
Target);
6193const ToolChain &Driver::getToolChain(
const ArgList &Args,
6194 const llvm::Triple &
Target)
const {
6196 auto &TC = ToolChains[
Target.str()];
6198 switch (
Target.getOS()) {
6199 case llvm::Triple::AIX:
6200 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6202 case llvm::Triple::Haiku:
6203 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6205 case llvm::Triple::Darwin:
6206 case llvm::Triple::MacOSX:
6207 case llvm::Triple::IOS:
6208 case llvm::Triple::TvOS:
6209 case llvm::Triple::WatchOS:
6210 case llvm::Triple::XROS:
6211 case llvm::Triple::DriverKit:
6212 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6214 case llvm::Triple::DragonFly:
6215 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6217 case llvm::Triple::OpenBSD:
6218 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6220 case llvm::Triple::NetBSD:
6221 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6223 case llvm::Triple::FreeBSD:
6225 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6228 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6230 case llvm::Triple::Linux:
6231 case llvm::Triple::ELFIAMCU:
6232 if (
Target.getArch() == llvm::Triple::hexagon)
6233 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6235 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6236 !
Target.hasEnvironment())
6237 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6240 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6242 else if (
Target.getArch() == llvm::Triple::ve)
6243 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6244 else if (
Target.isOHOSFamily())
6245 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6246 else if (
Target.isWALI())
6247 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6249 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6251 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6253 case llvm::Triple::Fuchsia:
6254 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6256 case llvm::Triple::Managarm:
6257 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6259 case llvm::Triple::Serenity:
6260 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
6262 case llvm::Triple::Solaris:
6263 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6265 case llvm::Triple::CUDA:
6266 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6268 case llvm::Triple::AMDHSA: {
6269 if (
Target.getArch() == llvm::Triple::spirv64) {
6270 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6276 TC = std::make_unique<toolchains::AMDGPUToolChain>(
6278 ShouldLinkDeviceLibs);
6282 case llvm::Triple::AMDPAL:
6283 case llvm::Triple::Mesa3D:
6284 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6286 case llvm::Triple::UEFI:
6287 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6289 case llvm::Triple::Win32:
6290 switch (
Target.getEnvironment()) {
6292 if (
Target.isOSBinFormatELF())
6293 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6294 else if (
Target.isOSBinFormatMachO())
6295 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6297 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6299 case llvm::Triple::GNU:
6300 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6302 case llvm::Triple::Cygnus:
6303 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6305 case llvm::Triple::Itanium:
6306 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6309 case llvm::Triple::MSVC:
6310 case llvm::Triple::UnknownEnvironment:
6311 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6312 .starts_with_insensitive(
"bfd"))
6313 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6317 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6321 case llvm::Triple::PS4:
6322 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6324 case llvm::Triple::PS5:
6325 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6327 case llvm::Triple::Hurd:
6328 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6330 case llvm::Triple::LiteOS:
6331 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6333 case llvm::Triple::ZOS:
6334 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6336 case llvm::Triple::Vulkan:
6337 case llvm::Triple::ShaderModel:
6338 if ((
Target.getArch() == llvm::Triple::spirv32 ||
6339 Target.getArch() == llvm::Triple::spirv64) &&
6341 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6343 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6345 case llvm::Triple::ChipStar:
6346 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
6351 switch (
Target.getArch()) {
6352 case llvm::Triple::tce:
6353 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6355 case llvm::Triple::tcele:
6356 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6358 case llvm::Triple::tcele64:
6360 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
6362 case llvm::Triple::hexagon:
6363 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6366 case llvm::Triple::lanai:
6367 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6369 case llvm::Triple::xcore:
6370 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6372 case llvm::Triple::wasm32:
6373 case llvm::Triple::wasm64:
6374 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6376 case llvm::Triple::avr:
6377 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6379 case llvm::Triple::msp430:
6380 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6382 case llvm::Triple::riscv32:
6383 case llvm::Triple::riscv64:
6384 case llvm::Triple::riscv32be:
6385 case llvm::Triple::riscv64be:
6386 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6388 case llvm::Triple::ve:
6389 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6391 case llvm::Triple::spirv32:
6392 case llvm::Triple::spirv64:
6393 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6395 case llvm::Triple::csky:
6396 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6398 case llvm::Triple::amdgpu:
6399 case llvm::Triple::r600:
6400 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6404 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6405 else if (
Target.isOSBinFormatELF())
6406 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6407 else if (
Target.isAppleFirmware())
6408 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6409 else if (
Target.isAppleMachO())
6410 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6411 else if (
Target.isOSBinFormatMachO())
6412 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6414 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6424 if (JA.
size() != 1 ||
6439 if (JA.
size() != 1 ||
6453 if (Args.hasArg(options::OPT_emit_static_lib))
6464 unsigned &Micro,
bool &HadExtra) {
6467 Major = Minor = Micro = 0;
6471 if (Str.consumeInteger(10, Major))
6475 if (!Str.consume_front(
"."))
6478 if (Str.consumeInteger(10, Minor))
6482 if (!Str.consume_front(
"."))
6485 if (Str.consumeInteger(10, Micro))
6503 unsigned CurDigit = 0;
6504 while (CurDigit < Digits.size()) {
6506 if (Str.consumeInteger(10, Digit))
6508 Digits[CurDigit] = Digit;
6511 if (!Str.consume_front(
"."))
6520llvm::opt::Visibility
6521Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6533const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6549 llvm_unreachable(
"Unhandled Mode");
6553 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6558 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6559 options::OPT_fno_save_optimization_record,
false))
6563 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6564 options::OPT_fno_save_optimization_record,
false))
6568 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6569 options::OPT_fno_save_optimization_record,
false))
6573 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6574 options::OPT_fno_save_optimization_record,
false))
6581 static StringRef OptName =
6583 llvm::StringRef Opt;
6584 for (StringRef Arg : Args) {
6585 if (!Arg.starts_with(OptName))
6591 return Opt.consume_front(OptName) ? Opt :
"";
6598 llvm::BumpPtrAllocator &Alloc,
6599 llvm::vfs::FileSystem *FS) {
6608 for (
const char *F : Args) {
6609 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6611 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6612 RSPQuoting = Windows;
6618 bool MarkEOLs = ClangCLMode;
6620 llvm::cl::TokenizerCallback Tokenizer;
6621 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
6622 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6624 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6626 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6629 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6630 ECtx.setMarkEOLs(MarkEOLs);
6634 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6638 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6639 [](
const char *A) {
return A !=
nullptr; });
6640 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6643 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6644 Args.resize(newEnd - Args.begin());
6648 return llvm::Error::success();
6652 return SavedStrings.insert(S).first->getKeyData();
6686 llvm::StringSet<> &SavedStrings) {
6689 if (Edit[0] ==
'^') {
6690 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6691 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6692 Args.insert(Args.begin() + 1, Str);
6693 }
else if (Edit[0] ==
'+') {
6694 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6695 OS <<
"### Adding argument " << Str <<
" at end\n";
6696 Args.push_back(Str);
6697 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6698 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6699 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6700 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6701 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6703 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6705 if (Args[i] ==
nullptr)
6707 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6709 if (Repl != Args[i]) {
6710 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6714 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6715 auto Option = Edit.substr(1);
6716 for (
unsigned i = 1; i < Args.size();) {
6717 if (Option == Args[i]) {
6718 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6719 Args.erase(Args.begin() + i);
6720 if (Edit[0] ==
'X') {
6721 if (i < Args.size()) {
6722 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6723 Args.erase(Args.begin() + i);
6725 OS <<
"### Invalid X edit, end of command line!\n";
6730 }
else if (Edit[0] ==
'O') {
6731 for (
unsigned i = 1; i < Args.size();) {
6732 const char *A = Args[i];
6736 if (A[0] ==
'-' && A[1] ==
'O' &&
6737 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6738 (
'0' <= A[2] && A[2] <=
'9'))))) {
6739 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6740 Args.erase(Args.begin() + i);
6744 OS <<
"### Adding argument " << Edit <<
" at end\n";
6745 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6747 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6752 const char *OverrideStr,
6753 llvm::StringSet<> &SavedStrings,
6754 StringRef EnvVar, raw_ostream *OS) {
6756 OS = &llvm::nulls();
6758 if (OverrideStr[0] ==
'#') {
6760 OS = &llvm::nulls();
6763 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
6767 const char *S = OverrideStr;
6769 const char *End = ::strchr(S,
' ');
6771 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 shouldBundleHIPAsm(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 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 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
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()
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.
@ 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
static const char * translateMacroDefinition(const char *Value, const llvm::opt::ArgList &Args)
Normalize MSVC's '#' macro separator, also used by Clang targeting MSVC and by arguments parsed after...
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)
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
phases::ID getFinalPhase(const llvm::opt::ArgList &Args, llvm::opt::Arg **FinalPhaseArg=nullptr) 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.
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())))
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