58#include "clang/Config/config.h"
70#include "llvm/ADT/ArrayRef.h"
71#include "llvm/ADT/STLExtras.h"
72#include "llvm/ADT/SmallSet.h"
73#include "llvm/ADT/StringExtras.h"
74#include "llvm/ADT/StringRef.h"
75#include "llvm/ADT/StringSet.h"
76#include "llvm/ADT/StringSwitch.h"
77#include "llvm/Config/llvm-config.h"
78#include "llvm/MC/TargetRegistry.h"
79#include "llvm/Option/Arg.h"
80#include "llvm/Option/ArgList.h"
81#include "llvm/Option/OptSpecifier.h"
82#include "llvm/Option/OptTable.h"
83#include "llvm/Option/Option.h"
84#include "llvm/Support/CommandLine.h"
85#include "llvm/Support/ErrorHandling.h"
86#include "llvm/Support/ExitCodes.h"
87#include "llvm/Support/FileSystem.h"
88#include "llvm/Support/FileUtilities.h"
89#include "llvm/Support/FormatVariadic.h"
90#include "llvm/Support/MD5.h"
91#include "llvm/Support/Path.h"
92#include "llvm/Support/PrettyStackTrace.h"
93#include "llvm/Support/Process.h"
94#include "llvm/Support/Program.h"
95#include "llvm/Support/Regex.h"
96#include "llvm/Support/StringSaver.h"
97#include "llvm/Support/VirtualFileSystem.h"
98#include "llvm/Support/raw_ostream.h"
99#include "llvm/TargetParser/Host.h"
100#include "llvm/TargetParser/RISCVISAInfo.h"
112using namespace clang;
115template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
116 return llvm::any_of(Args, [&](Arg *A) {
117 return (A->getOption().matches(options::OPT_x) &&
119 (A->getOption().
getKind() == Option::InputClass &&
120 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
122 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
133 StringRef
Dir = llvm::sys::path::parent_path(BinaryPath);
136 StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
137 if (!ConfiguredResourceDir.empty()) {
140 if (llvm::sys::path::is_absolute(ConfiguredResourceDir))
141 P = ConfiguredResourceDir;
143 llvm::sys::path::append(P, ConfiguredResourceDir);
150 P = llvm::sys::path::parent_path(
Dir);
153 llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
154 CLANG_VERSION_MAJOR_STRING);
157 return std::string(P);
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),
212 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
213 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
214 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
217 this->VFS = llvm::vfs::getRealFileSystem();
222 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
225 llvm::sys::path::append(P,
SysRoot);
229#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
230 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
234 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
235 llvm::sys::path::remove_dots(configFileDir,
true);
239#if defined(CLANG_CONFIG_FILE_USER_DIR)
242 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
251void Driver::setDriverMode(StringRef
Value) {
252 static StringRef OptName =
253 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
254 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
255 .Case(
"gcc", GCCMode)
256 .Case(
"g++", GXXMode)
257 .Case(
"cpp", CPPMode)
259 .Case(
"flang", FlangMode)
260 .Case(
"dxc", DXCMode)
264 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
269 bool &ContainsError)
const {
270 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
271 ContainsError =
false;
273 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
274 unsigned MissingArgIndex, MissingArgCount;
275 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
276 MissingArgCount, VisibilityMask);
279 if (MissingArgCount) {
280 Diag(diag::err_drv_missing_argument)
281 << Args.getArgString(MissingArgIndex) << MissingArgCount;
283 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
288 for (
const Arg *A : Args) {
290 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
291 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
298 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
299 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
300 ContainsError |= Diags.getDiagnosticLevel(
301 diag::warn_drv_empty_joined_argument,
306 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
308 auto ArgString = A->getAsString(Args);
310 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
312 if (
getOpts().findExact(ArgString, Nearest,
314 DiagID = diag::err_drv_unknown_argument_with_suggestion;
315 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
317 DiagID = diag::err_drv_unknown_argument;
318 Diags.Report(DiagID) << ArgString;
321 llvm::opt::Visibility(
323 DiagID = diag::err_drv_unknown_argument_with_suggestion;
324 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
326 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
327 : diag::err_drv_unknown_argument;
328 Diags.Report(DiagID) << ArgString;
332 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
333 : diag::err_drv_unknown_argument_with_suggestion;
334 Diags.Report(DiagID) << ArgString << Nearest;
336 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
340 for (
const Arg *A : Args.filtered(options::OPT_o)) {
341 if (ArgStrings[A->getIndex()] == A->getSpelling())
345 std::string ArgString = ArgStrings[A->getIndex()];
347 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
348 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
349 << A->getAsString(Args) << Nearest;
359 Arg **FinalPhaseArg)
const {
360 Arg *PhaseArg =
nullptr;
364 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
374 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
377 options::OPT_fmodule_header_EQ))) {
380 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
381 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
383 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
384 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
385 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
386 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
387 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
388 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
389 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
390 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
394 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
398 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
401 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
409 *FinalPhaseArg = PhaseArg;
417 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
418 llvm::sys::fs::OF_Text);
419 llvm::FileRemover OutputRemover(OutputFile.c_str());
420 std::optional<llvm::StringRef> Redirects[] = {
426 std::string ErrorMessage;
427 int SecondsToWait = 60;
428 if (std::optional<std::string> Str =
429 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
430 if (!llvm::to_integer(*Str, SecondsToWait))
431 return llvm::createStringError(std::error_code(),
432 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
433 "an integer, got '" +
435 SecondsToWait = std::max(SecondsToWait, 0);
437 StringRef Executable = Args[0];
438 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
440 return llvm::createStringError(std::error_code(),
441 Executable +
": " + ErrorMessage);
443 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
444 llvm::MemoryBuffer::getFile(OutputFile.c_str());
446 return llvm::createStringError(OutputBuf.getError(),
447 "Failed to read stdout of " + Executable +
448 ": " + OutputBuf.getError().message());
449 return std::move(*OutputBuf);
453 StringRef
Value,
bool Claim =
true) {
454 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
455 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
456 Args.AddSynthesizedArg(A);
462DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
463 const llvm::opt::OptTable &Opts =
getOpts();
464 DerivedArgList *DAL =
new DerivedArgList(Args);
466 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
467 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
468 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
469 bool IgnoreUnused =
false;
470 for (Arg *A : Args) {
474 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
478 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
479 IgnoreUnused =
false;
489 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
490 A->getOption().matches(options::OPT_Xlinker)) &&
491 A->containsValue(
"--no-demangle")) {
493 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
496 for (StringRef Val : A->getValues())
497 if (Val !=
"--no-demangle")
498 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
506 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
507 A->getNumValues() > 0 &&
508 (A->getValue(0) == StringRef(
"-MD") ||
509 A->getValue(0) == StringRef(
"-MMD"))) {
511 if (A->getValue(0) == StringRef(
"-MD"))
512 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
514 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
515 if (A->getNumValues() == 2)
516 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
521 if (A->getOption().matches(options::OPT_l)) {
522 StringRef
Value = A->getValue();
525 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
527 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
532 if (
Value ==
"cc_kext") {
533 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
539 if (A->getOption().matches(options::OPT__DASH_DASH)) {
541 for (StringRef Val : A->getValues())
550 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
551 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
554 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
555 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
559#if defined(HOST_LINK_VERSION)
560 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
561 strlen(HOST_LINK_VERSION) > 0) {
562 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
564 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
572 StringRef ArgTarget) {
574 static bool BeSilent =
false;
575 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
576 return ((v < 2) || ((v == 2) && (r < 4)));
580 if (ArgTarget.equals_insensitive(
"CURRENT")) {
584 unsigned int Version = 0;
585 unsigned int Release = 0;
586 unsigned int Modification = 0;
588 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
589 llvm::Regex HexRegex(
592 "([0-9a-fA-F][0-9a-fA-F])"
593 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
596 if (ZOsvRegex.match(ArgTarget, &Matches)) {
597 Matches[1].getAsInteger(10, Version);
598 Matches[2].getAsInteger(10, Release);
600 if (IsTooOldToBeSupported(Version, Release)) {
602 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
605 }
else if (HexRegex.match(ArgTarget, &Matches)) {
606 Matches[1].getAsInteger(16, Version);
607 Matches[2].getAsInteger(16, Release);
608 Matches[3].getAsInteger(16, Modification);
609 if (IsTooOldToBeSupported(Version, Release)) {
611 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
617 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
622 llvm::VersionTuple
V(Version, Release, Modification);
623 llvm::VersionTuple TV =
Target.getOSVersion();
626 if (TV.empty() ||
V < TV) {
628 Str = llvm::Triple::getOSTypeName(
Target.getOS());
629 Str +=
V.getAsString();
642 StringRef TargetTriple,
644 StringRef DarwinArchName =
"") {
646 if (
const Arg *A = Args.getLastArg(options::OPT_target))
647 TargetTriple = A->getValue();
649 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
654 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
658 if (
Target.isOSBinFormatMachO()) {
660 if (!DarwinArchName.empty()) {
667 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
668 StringRef ArchName = A->getValue();
675 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
676 options::OPT_mbig_endian)) {
677 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
678 ?
Target.getLittleEndianArchVariant()
679 :
Target.getBigEndianArchVariant();
680 if (
T.getArch() != llvm::Triple::UnknownArch) {
682 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
687 if (
Target.getArch() == llvm::Triple::tce)
692 if (std::optional<std::string> ObjectModeValue =
693 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
694 StringRef ObjectMode = *ObjectModeValue;
695 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
697 if (ObjectMode ==
"64") {
698 AT =
Target.get64BitArchVariant().getArch();
699 }
else if (ObjectMode ==
"32") {
700 AT =
Target.get32BitArchVariant().getArch();
702 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
705 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
711 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
712 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
715 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
717 D.
Diag(diag::err_drv_unsupported_opt_for_target)
718 << A->getAsString(Args) <<
Target.str();
721 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
722 options::OPT_m32, options::OPT_m16,
723 options::OPT_maix32, options::OPT_maix64);
725 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
727 if (A->getOption().matches(options::OPT_m64) ||
728 A->getOption().matches(options::OPT_maix64)) {
729 AT =
Target.get64BitArchVariant().getArch();
730 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
731 Target.getEnvironment() == llvm::Triple::GNUT64)
732 Target.setEnvironment(llvm::Triple::GNU);
733 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
734 Target.setEnvironment(llvm::Triple::Musl);
735 }
else if (A->getOption().matches(options::OPT_mx32) &&
736 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
737 AT = llvm::Triple::x86_64;
738 if (
Target.getEnvironment() == llvm::Triple::Musl)
739 Target.setEnvironment(llvm::Triple::MuslX32);
741 Target.setEnvironment(llvm::Triple::GNUX32);
742 }
else if (A->getOption().matches(options::OPT_m32) ||
743 A->getOption().matches(options::OPT_maix32)) {
745 D.
Diag(diag::err_drv_unsupported_opt_for_target)
746 << A->getAsString(Args) <<
Target.str();
748 AT =
Target.get32BitArchVariant().getArch();
749 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
750 Target.setEnvironment(llvm::Triple::GNU);
751 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
752 Target.setEnvironment(llvm::Triple::Musl);
754 }
else if (A->getOption().matches(options::OPT_m16) &&
755 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
756 AT = llvm::Triple::x86;
757 Target.setEnvironment(llvm::Triple::CODE16);
760 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
762 if (
Target.isWindowsGNUEnvironment())
768 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
774 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
775 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
776 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
779 if (A && !A->getOption().matches(options::OPT_m32))
780 D.
Diag(diag::err_drv_argument_not_allowed_with)
781 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
783 Target.setArch(llvm::Triple::x86);
784 Target.setArchName(
"i586");
785 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
786 Target.setEnvironmentName(
"");
787 Target.setOS(llvm::Triple::ELFIAMCU);
788 Target.setVendor(llvm::Triple::UnknownVendor);
789 Target.setVendorName(
"intel");
795 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
796 StringRef ABIName = A->getValue();
797 if (ABIName ==
"32") {
799 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
800 Target.getEnvironment() == llvm::Triple::GNUABIN32)
801 Target.setEnvironment(llvm::Triple::GNU);
802 }
else if (ABIName ==
"n32") {
804 if (
Target.getEnvironment() == llvm::Triple::GNU ||
805 Target.getEnvironment() == llvm::Triple::GNUT64 ||
806 Target.getEnvironment() == llvm::Triple::GNUABI64)
807 Target.setEnvironment(llvm::Triple::GNUABIN32);
808 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
809 Target.getEnvironment() == llvm::Triple::MuslABI64)
810 Target.setEnvironment(llvm::Triple::MuslABIN32);
811 }
else if (ABIName ==
"64") {
813 if (
Target.getEnvironment() == llvm::Triple::GNU ||
814 Target.getEnvironment() == llvm::Triple::GNUT64 ||
815 Target.getEnvironment() == llvm::Triple::GNUABIN32)
816 Target.setEnvironment(llvm::Triple::GNUABI64);
817 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
818 Target.getEnvironment() == llvm::Triple::MuslABIN32)
819 Target.setEnvironment(llvm::Triple::MuslABI64);
827 if (Args.hasArg(options::OPT_march_EQ) ||
828 Args.hasArg(options::OPT_mcpu_EQ)) {
830 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
832 if (!llvm::errorToBool(ISAInfo.takeError())) {
833 unsigned XLen = (*ISAInfo)->getXLen();
835 Target.setArch(llvm::Triple::riscv32);
837 Target.setArch(llvm::Triple::riscv64);
849 OptSpecifier OptEq, OptSpecifier OptNeg) {
850 if (!Args.hasFlag(OptEq, OptNeg,
false))
853 const Arg *A = Args.getLastArg(OptEq);
854 StringRef LTOName = A->getValue();
862 D.
Diag(diag::err_drv_unsupported_option_argument)
863 << A->getSpelling() << A->getValue();
870void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
872 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
874 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
875 options::OPT_fno_offload_lto);
878 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
879 options::OPT_fno_openmp_target_jit,
false)) {
880 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
881 options::OPT_fno_offload_lto))
883 Diag(diag::err_drv_incompatible_options)
884 << A->getSpelling() <<
"-fopenmp-target-jit";
891 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
893 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
895 RuntimeName = A->getValue();
897 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
905 Diag(diag::err_drv_unsupported_option_argument)
906 << A->getSpelling() << A->getValue();
909 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
918 StringRef Program =
C.getArgs().getLastArgValue(
919 options::OPT_offload_arch_tool_EQ,
"offload-arch");
922 if (llvm::ErrorOr<std::string> Executable =
923 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
926 Args.push_back(
"--only=amdgpu");
928 Args.push_back(
"--only=nvptx");
929 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
932 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
937 if ((*StdoutOrErr)->getBuffer().empty()) {
938 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
944 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
946 GPUArchs.push_back(
Arch.str());
948 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
955static llvm::DenseSet<llvm::StringRef>
957 std::set<std::string> Archs;
958 for (Arg *A :
C.getInputArgs()) {
959 for (StringRef
Arch : A->getValues()) {
960 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
961 if (
Arch ==
"native") {
963 Archs.insert(Str.str());
965 Archs.insert(
Arch.str());
967 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
971 Archs.erase(
Arch.str());
976 llvm::DenseSet<llvm::StringRef> Triples;
977 for (llvm::StringRef
Arch : Archs) {
984 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
986 return llvm::DenseSet<llvm::StringRef>();
989 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
991 return llvm::DenseSet<llvm::StringRef>();
995 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
997 return llvm::DenseSet<llvm::StringRef>();
1000 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1001 <<
"offload" <<
Arch;
1002 return llvm::DenseSet<llvm::StringRef>();
1007 Triple =
"spirv64-amd-amdhsa";
1009 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
1010 ?
"nvptx64-nvidia-cuda"
1011 :
"nvptx-nvidia-cuda";
1013 Triple =
"amdgcn-amd-amdhsa";
1020 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1021 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1022 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1023 C.getArgs().MakeArgString(Triple.split(
"-").first),
1024 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1026 C.getArgs().append(A);
1027 C.getArgs().AddSynthesizedArg(A);
1028 Triples.insert(Triple);
1033 Triples.insert(
"amdgcn-amd-amdhsa");
1035 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1036 ?
"nvptx64-nvidia-cuda"
1037 :
"nvptx-nvidia-cuda");
1039 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1040 ?
"spirv64-unknown-unknown"
1041 :
"spirv32-unknown-unknown");
1044 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1045 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1052 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1053 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1055 llvm::any_of(Inputs,
1056 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1061 (llvm::any_of(Inputs,
1062 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1065 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1066 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1068 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1069 options::OPT_fno_sycl,
false);
1070 bool IsOpenMPOffloading =
1072 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1073 options::OPT_fno_openmp,
false) &&
1074 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1075 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1076 !(IsCuda || IsHIP))));
1078 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1079 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1084 for (
const auto &[Active, Kind] : ActiveKinds)
1089 if (Kinds.size() > 1) {
1090 Diag(clang::diag::err_drv_mix_offload)
1097 if (IsCuda || IsHIP)
1103 std::multiset<llvm::StringRef> Triples;
1104 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1105 std::vector<std::string> ArgValues =
1106 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1107 for (llvm::StringRef
Target : ArgValues)
1108 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1110 if (ArgValues.empty())
1111 Diag(clang::diag::warn_drv_empty_joined_argument)
1113 .getLastArg(options::OPT_offload_targets_EQ)
1114 ->getAsString(
C.getInputArgs());
1115 }
else if (Kinds.size() > 0) {
1118 Triples.insert(Derived.begin(), Derived.end());
1123 llvm::StringMap<StringRef> FoundNormalizedTriples;
1124 for (StringRef
Target : Triples) {
1129 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1137 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1138 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1139 Diag(clang::diag::err_drv_argument_not_allowed_with)
1140 << IncompatArg->getSpelling() <<
"-fsycl";
1148 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1149 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1153 std::string NormalizedName = TT.normalize();
1154 auto [TripleIt, Inserted] =
1155 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1157 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1158 <<
Target << TripleIt->second;
1162 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1163 C.getDefaultToolChain().getTriple());
1167 auto &CudaInstallation =
1169 if (CudaInstallation.isValid())
1170 CudaInstallation.WarnIfUnsupportedVersion();
1173 C.addOffloadDeviceToolChain(&TC, Kind);
1178bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1183 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1187 if (!PathLIBEnv.empty()) {
1188 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1189 if (llvm::sys::fs::is_directory(PathLIBEnv))
1190 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1191 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1192 return readConfigFile(CustomizationFile, ExpCtx);
1193 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1198 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1199 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1200 return readConfigFile(CustomizationFile, ExpCtx);
1210 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1211 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1212 Copy->getValues() = Opt->getValues();
1213 if (Opt->isClaimed())
1215 Copy->setOwnsValues(Opt->getOwnsValues());
1216 Opt->setOwnsValues(
false);
1218 if (Opt->getAlias()) {
1219 const Arg *Alias = Opt->getAlias();
1220 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1221 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1222 Args.getArgString(Index), Index);
1223 AliasCopy->getValues() = Alias->getValues();
1224 AliasCopy->setOwnsValues(
false);
1225 if (Alias->isClaimed())
1227 Copy->setAlias(std::move(AliasCopy));
1231bool Driver::readConfigFile(StringRef
FileName,
1232 llvm::cl::ExpansionContext &ExpCtx) {
1236 Diag(diag::err_drv_cannot_open_config_file)
1237 <<
FileName << Status.getError().message();
1240 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1241 Diag(diag::err_drv_cannot_open_config_file)
1242 <<
FileName <<
"not a regular file";
1247 SmallVector<const char *, 32> NewCfgFileArgs;
1248 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1249 Diag(diag::err_drv_cannot_read_config_file)
1255 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1256 for (
const char *Opt : NewCfgFileArgs) {
1258 if (Opt[0] ==
'$' && Opt[1])
1259 NewCfgTailArgs.push_back(Opt + 1);
1261 NewCfgHeadArgs.push_back(Opt);
1265 llvm::SmallString<128> CfgFileName(
FileName);
1266 llvm::sys::path::native(CfgFileName);
1267 bool ContainErrors =
false;
1268 auto NewHeadOptions = std::make_unique<InputArgList>(
1272 auto NewTailOptions = std::make_unique<InputArgList>(
1279 for (Arg *A : *NewHeadOptions)
1281 for (Arg *A : *NewTailOptions)
1284 if (!CfgOptionsHead)
1285 CfgOptionsHead = std::move(NewHeadOptions);
1288 for (
auto *Opt : *NewHeadOptions)
1292 if (!CfgOptionsTail)
1293 CfgOptionsTail = std::move(NewTailOptions);
1296 for (
auto *Opt : *NewTailOptions)
1300 ConfigFiles.push_back(std::string(CfgFileName));
1304bool Driver::loadConfigFiles() {
1305 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1306 llvm::cl::tokenizeConfigFile);
1307 ExpCtx.setVFS(&
getVFS());
1311 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1312 SmallString<128> CfgDir;
1314 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1315 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1320 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1321 SmallString<128> CfgDir;
1322 llvm::sys::fs::expand_tilde(
1323 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1324 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1333 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1336 if (loadDefaultConfigFiles(ExpCtx))
1340 SmallString<128> CfgFilePath;
1342 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1345 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1346 CfgFilePath.assign(CfgFileName);
1347 if (llvm::sys::path::is_relative(CfgFilePath)) {
1348 if (
getVFS().makeAbsolute(CfgFilePath)) {
1349 Diag(diag::err_drv_cannot_open_config_file)
1350 << CfgFilePath <<
"cannot get absolute path";
1354 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1356 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1357 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1358 if (!SearchDir.empty())
1359 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1364 if (readConfigFile(CfgFilePath, ExpCtx))
1375 llvm::Triple Triple, std::string Suffix) {
1377 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1381 VersionTuple OSVersion = Triple.getOSVersion();
1382 if (!OSVersion.getMinor().has_value())
1385 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1389 if (OSVersion.getMajor() != 0) {
1390 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1391 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1397 Triple.setOSName(BaseOSName);
1398 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1401bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1404 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1408 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1411 std::string RealMode = getExecutableForDriverMode(Mode);
1412 llvm::Triple Triple;
1421 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1422 PrefixTriple.isOSUnknown())
1423 Triple = PrefixTriple;
1427 llvm::Triple RealTriple =
1429 if (Triple.str().empty()) {
1430 Triple = RealTriple;
1431 assert(!Triple.str().empty());
1436 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1450 SmallString<128> CfgFilePath;
1452 "-" + RealMode +
".cfg"))
1453 return readConfigFile(CfgFilePath, ExpCtx);
1457 if (TryModeSuffix) {
1460 return readConfigFile(CfgFilePath, ExpCtx);
1465 std::string CfgFileName = RealMode +
".cfg";
1466 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1467 if (readConfigFile(CfgFilePath, ExpCtx))
1469 }
else if (TryModeSuffix) {
1471 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1472 readConfigFile(CfgFilePath, ExpCtx))
1478 return readConfigFile(CfgFilePath, ExpCtx);
1486 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1495 if (!DriverMode.empty())
1496 setDriverMode(DriverMode);
1502 CLOptions = std::make_unique<InputArgList>(
1507 ContainsError = loadConfigFiles();
1508 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1509 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1513 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1515 if (HasConfigFileHead)
1516 for (
auto *Opt : *CLOptions)
1517 if (!Opt->getOption().matches(options::OPT_config))
1521 if (
IsCLMode() && !ContainsError) {
1523 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1525 CLModePassThroughArgList.push_back(A->getValue());
1528 if (!CLModePassThroughArgList.empty()) {
1531 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1536 for (
auto *Opt : *CLModePassThroughOptions)
1542 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1543 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1544 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1547 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1548 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1549 if (!VFS->exists(IncludeDir))
1550 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1555 bool CCCPrintPhases;
1558 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1559 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1562 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1563 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1566 Args.ClaimAllArgs(options::OPT_pipe);
1574 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1576 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1577 CCCGenericGCCName = A->getValue();
1580 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1584 if (Args.hasArg(options::OPT_fproc_stat_report))
1591 llvm::Triple
T(TargetTriple);
1592 T.setOS(llvm::Triple::Win32);
1593 T.setVendor(llvm::Triple::PC);
1594 T.setEnvironment(llvm::Triple::MSVC);
1595 T.setObjectFormat(llvm::Triple::COFF);
1596 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1597 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1598 TargetTriple =
T.str();
1601 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1602 StringRef TargetProfile = A->getValue();
1605 TargetTriple = *Triple;
1607 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1611 if (Args.hasArg(options::OPT_spirv)) {
1612 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1613 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1614 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1615 llvm::Triple
T(TargetTriple);
1618 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1620 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1621 TargetInfo = ValidTargets.find(A->getValue());
1623 Diag(diag::err_drv_invalid_value)
1624 << A->getAsString(Args) << A->getValue();
1630 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1631 TargetTriple =
T.str();
1635 Diag(diag::err_drv_dxc_missing_target_profile);
1639 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1640 TargetTriple = A->getValue();
1641 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1642 Dir =
Dir = A->getValue();
1643 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1647 if (std::optional<std::string> CompilerPathValue =
1648 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1649 StringRef CompilerPath = *CompilerPathValue;
1650 while (!CompilerPath.empty()) {
1651 std::pair<StringRef, StringRef> Split =
1652 CompilerPath.split(llvm::sys::EnvPathSeparator);
1653 PrefixDirs.push_back(std::string(Split.first));
1654 CompilerPath = Split.second;
1657 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1659 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1662 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1665 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1666 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1667 .Case(
"cwd", SaveTempsCwd)
1668 .Case(
"obj", SaveTempsObj)
1669 .Default(SaveTempsCwd);
1672 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1673 options::OPT_offload_device_only,
1674 options::OPT_offload_host_device)) {
1675 if (A->getOption().matches(options::OPT_offload_host_only))
1676 Offload = OffloadHost;
1677 else if (A->getOption().matches(options::OPT_offload_device_only))
1678 Offload = OffloadDevice;
1680 Offload = OffloadHostDevice;
1686 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1687 StringRef
Name = A->getValue();
1688 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1689 .Case(
"off", EmbedNone)
1690 .Case(
"all", EmbedBitcode)
1691 .Case(
"bitcode", EmbedBitcode)
1692 .Case(
"marker", EmbedMarker)
1695 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1698 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1702 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1703 llvm::sys::fs::remove(A->getValue());
1709 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1711 !Args.hasArg(options::OPT_fmodules) && Std &&
1712 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1713 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1714 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1715 Std->containsValue(
"c++latest"));
1718 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1719 options::OPT_fmodule_header)) {
1721 ModulesModeCXX20 =
true;
1722 if (A->getOption().matches(options::OPT_fmodule_header))
1725 StringRef ArgName = A->getValue();
1726 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1731 Diags.Report(diag::err_drv_invalid_value)
1732 << A->getAsString(Args) << ArgName;
1738 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1739 std::make_unique<InputArgList>(std::move(Args));
1749 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1750 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1752 bool MLContainsError;
1753 auto MultilibMacroDefineList =
1755 MLMacroDefinesChar,
false, MLContainsError));
1756 if (!MLContainsError) {
1757 for (
auto *Opt : *MultilibMacroDefineList) {
1764 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1768 if (!Triple.isWasm()) {
1769 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1770 StringRef TripleObjectFormat =
1771 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1772 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1773 TripleVersionName != TripleObjectFormat) {
1774 Diags.Report(diag::err_drv_triple_version_invalid)
1776 ContainsError =
true;
1781 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1782 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1783 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1791 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1792 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1794 case llvm::Triple::arm:
1795 case llvm::Triple::armeb:
1796 case llvm::Triple::thumb:
1797 case llvm::Triple::thumbeb:
1798 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1799 Diag(diag::warn_target_unrecognized_env)
1801 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1804 case llvm::Triple::aarch64:
1805 case llvm::Triple::aarch64_be:
1806 case llvm::Triple::aarch64_32:
1807 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1808 Diag(diag::warn_target_unrecognized_env)
1810 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1827 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1828 if (HasConfigFileTail && Inputs.size()) {
1831 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1832 for (Arg *A : *CfgOptionsTail)
1833 TranslatedLinkerIns.append(A);
1834 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1843 if (TC.
getTriple().isOSBinFormatMachO())
1848 if (CCCPrintPhases) {
1859 llvm::opt::ArgStringList ASL;
1860 for (
const auto *A : Args) {
1864 while (A->getAlias())
1866 A->render(Args, ASL);
1869 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1870 if (I != ASL.begin())
1872 llvm::sys::printArg(OS, *I,
true);
1877bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1878 SmallString<128> &CrashDiagDir) {
1879 using namespace llvm::sys;
1880 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1881 "Only knows about .crash files on Darwin");
1886 path::home_directory(CrashDiagDir);
1887 if (CrashDiagDir.starts_with(
"/var/root"))
1889 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1897 fs::file_status FileStatus;
1898 TimePoint<> LastAccessTime;
1899 SmallString<128> CrashFilePath;
1902 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1903 File != FileEnd && !EC;
File.increment(EC)) {
1907 if (fs::status(
File->path(), FileStatus))
1909 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1910 llvm::MemoryBuffer::getFile(
File->path());
1915 StringRef
Data = CrashFile.get()->getBuffer();
1916 if (!
Data.starts_with(
"Process:"))
1919 size_t ParentProcPos =
Data.find(
"Parent Process:");
1920 if (ParentProcPos == StringRef::npos)
1922 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1923 if (LineEnd == StringRef::npos)
1925 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1926 int OpenBracket = -1, CloseBracket = -1;
1927 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1928 if (ParentProcess[i] ==
'[')
1930 if (ParentProcess[i] ==
']')
1936 if (OpenBracket < 0 || CloseBracket < 0 ||
1937 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1938 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1948 const auto FileAccessTime = FileStatus.getLastModificationTime();
1949 if (FileAccessTime > LastAccessTime) {
1950 CrashFilePath.assign(
File->path());
1951 LastAccessTime = FileAccessTime;
1956 if (!CrashFilePath.empty()) {
1957 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1967 "\n********************\n\n"
1968 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1969 "Preprocessed source(s) and associated run script(s) are located at:";
1977 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1981 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1982 Level = llvm::StringSwitch<unsigned>(A->getValue())
1984 .Case(
"compiler", 1)
1996 ArgStringList SavedTemps;
1998 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1999 if (!IsLLD || Level < 2)
2006 SavedTemps = std::move(
C.getTempFiles());
2007 assert(!
C.getTempFiles().size());
2024 C.initCompilationForDiagnostics();
2029 Command NewLLDInvocation = Cmd;
2030 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2031 StringRef ReproduceOption =
2032 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2035 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2039 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2041 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2042 Diag(clang::diag::note_drv_command_failed_diag_msg)
2043 <<
"\n\n********************";
2045 Report->TemporaryFiles.push_back(TmpName);
2053 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2054 bool IgnoreInput =
false;
2060 }
else if (!strcmp(it->second->getValue(),
"-")) {
2061 Diag(clang::diag::note_drv_command_failed_diag_msg)
2062 <<
"Error generating preprocessed source(s) - "
2063 "ignoring input from stdin.";
2068 it = Inputs.erase(it);
2075 if (Inputs.empty()) {
2076 Diag(clang::diag::note_drv_command_failed_diag_msg)
2077 <<
"Error generating preprocessed source(s) - "
2078 "no preprocessable inputs.";
2085 for (
const Arg *A :
C.getArgs()) {
2086 if (A->getOption().matches(options::OPT_arch)) {
2087 StringRef ArchName = A->getValue();
2092 Diag(clang::diag::note_drv_command_failed_diag_msg)
2093 <<
"Error generating preprocessed source(s) - cannot generate "
2094 "preprocessed source with multiple -arch options.";
2100 const ToolChain &TC =
C.getDefaultToolChain();
2101 if (TC.
getTriple().isOSBinFormatMachO())
2110 Diag(clang::diag::note_drv_command_failed_diag_msg)
2111 <<
"Error generating preprocessed source(s).";
2117 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2120 if (!FailingCommands.empty()) {
2121 Diag(clang::diag::note_drv_command_failed_diag_msg)
2122 <<
"Error generating preprocessed source(s).";
2126 const ArgStringList &TempFiles =
C.getTempFiles();
2127 if (TempFiles.empty()) {
2128 Diag(clang::diag::note_drv_command_failed_diag_msg)
2129 <<
"Error generating preprocessed source(s).";
2137 for (
const char *TempFile : TempFiles) {
2138 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2140 Report->TemporaryFiles.push_back(TempFile);
2141 if (ReproCrashFilename.empty()) {
2142 ReproCrashFilename = TempFile;
2143 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2145 if (StringRef(TempFile).ends_with(
".cache")) {
2148 VFS = llvm::sys::path::filename(TempFile);
2149 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2153 for (
const char *TempFile : SavedTemps)
2154 C.addTempFile(TempFile);
2160 llvm::sys::path::replace_extension(Script,
"sh");
2162 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2163 llvm::sys::fs::FA_Write,
2164 llvm::sys::fs::OF_Text);
2166 Diag(clang::diag::note_drv_command_failed_diag_msg)
2167 <<
"Error generating run script: " << Script <<
" " << EC.message();
2170 <<
"# Driver args: ";
2172 ScriptOS <<
"# Original command: ";
2173 Cmd.
Print(ScriptOS,
"\n",
true);
2174 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2175 if (!AdditionalInformation.empty())
2176 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2179 Report->TemporaryFiles.push_back(std::string(Script));
2180 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2184 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2186 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2187 Diag(clang::diag::note_drv_command_failed_diag_msg)
2188 << ReproCrashFilename.str();
2190 llvm::sys::path::append(CrashDiagDir,
Name);
2191 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2192 Diag(clang::diag::note_drv_command_failed_diag_msg)
2193 <<
"Crash backtrace is located in";
2194 Diag(clang::diag::note_drv_command_failed_diag_msg)
2195 << CrashDiagDir.str();
2196 Diag(clang::diag::note_drv_command_failed_diag_msg)
2197 <<
"(choose the .crash file that corresponds to your crash)";
2201 Diag(clang::diag::note_drv_command_failed_diag_msg)
2202 <<
"\n\n********************";
2212 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2223 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2224 if (
C.getArgs().hasArg(options::OPT_v))
2225 C.getJobs().Print(llvm::errs(),
"\n",
true);
2227 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2230 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2237 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2238 C.getJobs().Print(llvm::errs(),
"\n",
true);
2239 return Diags.hasErrorOccurred() ? 1 : 0;
2243 if (Diags.hasErrorOccurred())
2247 for (
auto &Job :
C.getJobs())
2248 setUpResponseFiles(
C, Job);
2250 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2253 if (FailingCommands.empty())
2259 for (
const auto &CmdPair : FailingCommands) {
2260 int CommandRes = CmdPair.first;
2261 const Command *FailingCommand = CmdPair.second;
2266 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2270 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2275 if (CommandRes == EX_IOERR) {
2292 Diag(clang::diag::err_drv_command_signalled)
2295 Diag(clang::diag::err_drv_command_failed)
2303 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2305 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2319 const ToolChain &TC =
C.getDefaultToolChain();
2323 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2326 OS <<
"Thread model: " << A->getValue();
2332 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2337 if (!llvm::cl::getCompilerBuildConfig().empty())
2338 llvm::cl::printBuildConfig(OS);
2341 for (
auto ConfigFile : ConfigFiles)
2342 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2355 if (PassedFlags ==
"")
2359 std::vector<std::string> SuggestedCompletions;
2360 std::vector<std::string> Flags;
2372 const bool HasSpace = PassedFlags.ends_with(
",");
2376 StringRef TargetFlags = PassedFlags;
2377 while (TargetFlags !=
"") {
2379 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2380 Flags.push_back(std::string(CurFlag));
2385 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2388 const llvm::opt::OptTable &Opts =
getOpts();
2390 Cur = Flags.at(Flags.size() - 1);
2392 if (Flags.size() >= 2) {
2393 Prev = Flags.at(Flags.size() - 2);
2394 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2397 if (SuggestedCompletions.empty())
2398 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2405 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2406 llvm::outs() <<
'\n';
2412 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2416 SuggestedCompletions = Opts.findByPrefix(
2417 Cur, VisibilityMask,
2424 if (S.starts_with(Cur))
2425 SuggestedCompletions.push_back(std::string(S));
2432 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2433 if (
int X = A.compare_insensitive(B))
2435 return A.compare(B) > 0;
2438 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2445 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2446 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2450 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2453 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2457 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2462 if (
C.getArgs().hasArg(options::OPT_help) ||
2463 C.getArgs().hasArg(options::OPT__help_hidden)) {
2464 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2468 if (
C.getArgs().hasArg(options::OPT__version)) {
2474 if (
C.getArgs().hasArg(options::OPT_v) ||
2475 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2476 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2477 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2478 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2480 SuppressMissingInputWarning =
true;
2483 if (
C.getArgs().hasArg(options::OPT_v)) {
2485 llvm::errs() <<
"System configuration file directory: "
2488 llvm::errs() <<
"User configuration file directory: "
2492 const ToolChain &TC =
C.getDefaultToolChain();
2494 if (
C.getArgs().hasArg(options::OPT_v))
2497 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2502 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2503 llvm::outs() <<
"programs: =";
2504 bool separator =
false;
2508 llvm::outs() << llvm::sys::EnvPathSeparator;
2509 llvm::outs() << Path;
2514 llvm::outs() << llvm::sys::EnvPathSeparator;
2515 llvm::outs() << Path;
2518 llvm::outs() <<
"\n";
2521 StringRef sysroot =
C.getSysRoot();
2525 llvm::outs() << llvm::sys::EnvPathSeparator;
2528 llvm::outs() << sysroot << Path.substr(1);
2530 llvm::outs() << Path;
2532 llvm::outs() <<
"\n";
2536 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2542 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2543 for (
auto RuntimePath :
2545 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2546 llvm::outs() << *RuntimePath <<
'\n';
2550 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2554 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2556 for (std::size_t I = 0; I != Flags.size(); I += 2)
2557 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2563 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2564 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2568 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2569 StringRef ProgName = A->getValue();
2572 if (! ProgName.empty())
2575 llvm::outs() <<
"\n";
2579 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2580 StringRef PassedFlags = A->getValue();
2585 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2599 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2602 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2608 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2615 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2618 std::set<llvm::StringRef> SortedFlags;
2619 for (
const auto &FlagEntry : ExpandedFlags)
2620 SortedFlags.insert(FlagEntry.getKey());
2621 for (
auto Flag : SortedFlags)
2622 llvm::outs() << Flag <<
'\n';
2626 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2629 llvm::outs() <<
".\n";
2632 assert(Suffix.front() ==
'/');
2633 llvm::outs() << Suffix.substr(1) <<
"\n";
2639 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2644 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2646 llvm::outs() << Triple.getTriple() <<
"\n";
2650 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2651 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2668 std::map<Action *, unsigned> &Ids,
2670 if (
auto It = Ids.find(A); It != Ids.end())
2674 llvm::raw_string_ostream os(str);
2676 auto getSibIndent = [](
int K) -> Twine {
2680 Twine SibIndent =
Indent + getSibIndent(Kind);
2684 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2686 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2687 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2688 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2690 OA->doOnEachDependence(
2692 assert(TC &&
"Unknown host toolchain");
2704 os <<
":" << BoundArch;
2707 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2715 const char *Prefix =
"{";
2716 for (
Action *PreRequisite : *AL) {
2717 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2728 std::string offload_str;
2729 llvm::raw_string_ostream offload_os(offload_str);
2733 offload_os <<
", (" << S;
2740 auto getSelfIndent = [](
int K) -> Twine {
2744 unsigned Id = Ids.size();
2746 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2755 std::map<Action *, unsigned> Ids;
2756 for (
Action *A :
C.getActions())
2772 DerivedArgList &Args =
C.getArgs();
2774 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2779 for (Arg *A : Args) {
2780 if (A->getOption().matches(options::OPT_arch)) {
2783 llvm::Triple::ArchType
Arch =
2785 if (
Arch == llvm::Triple::UnknownArch) {
2786 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2791 if (
ArchNames.insert(A->getValue()).second)
2792 Archs.push_back(A->getValue());
2806 for (
Action* Act : SingleActions) {
2814 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2818 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2823 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2824 Actions.append(Inputs.begin(), Inputs.end());
2826 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2829 Arg *A = Args.getLastArg(options::OPT_g_Group);
2830 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2831 !A->getOption().matches(options::OPT_gstabs);
2839 if (Act->getType() == types::TY_Image) {
2841 Inputs.push_back(Actions.back());
2848 if (Args.hasArg(options::OPT_verify_debug_info)) {
2849 Action *LastAction = Actions.pop_back_val();
2851 LastAction, types::TY_Nothing));
2870 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2871 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2883 std::string Nearest;
2884 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2885 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2886 <<
Value << Nearest;
2925 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2928 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2936 return types::TY_CXXUHeader;
2938 return types::TY_CXXSHeader;
2942 llvm_unreachable(
"should not be called in this case");
2944 return types::TY_CXXHUHeader;
2950 const llvm::opt::OptTable &Opts =
getOpts();
2954 types::ID InputType = types::TY_Nothing;
2955 Arg *InputTypeArg =
nullptr;
2958 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2959 options::OPT__SLASH_TP)) {
2960 InputTypeArg = TCTP;
2961 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2966 bool ShowNote =
false;
2968 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2970 Diag(clang::diag::warn_drv_overriding_option)
2971 <<
Previous->getSpelling() << A->getSpelling();
2977 Diag(clang::diag::note_drv_t_option_is_global);
2982 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2983 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2984 if (LastXArg && LastInputArg &&
2985 LastInputArg->getIndex() < LastXArg->getIndex())
2986 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2989 for (Arg *A : Args) {
2990 if (A->getOption().
getKind() == Option::InputClass) {
2991 const char *
Value = A->getValue();
2995 if (InputType == types::TY_Nothing) {
2998 InputTypeArg->claim();
3001 if (memcmp(
Value,
"-", 2) == 0) {
3003 Ty = types::TY_Fortran;
3005 Ty = types::TY_HLSL;
3014 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3015 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3016 : clang::diag::err_drv_unknown_stdin_type);
3025 if (
const char *Ext = strrchr(
Value,
'.'))
3034 Ty = types::TY_HLSL;
3036 Ty = types::TY_Object;
3047 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3048 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3049 << getTypeName(OldTy) << getTypeName(Ty);
3054 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3055 Ty == types::TY_Object)
3056 Ty = types::TY_LLVM_BC;
3064 if (Ty != types::TY_Object) {
3065 if (Args.hasArg(options::OPT_ObjC))
3066 Ty = types::TY_ObjC;
3067 else if (Args.hasArg(options::OPT_ObjCXX))
3068 Ty = types::TY_ObjCXX;
3075 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3079 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3080 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3083 const char *Ext = strrchr(
Value,
'.');
3085 Ty = types::TY_Object;
3089 InputTypeArg->claim();
3093 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3094 Args.hasArgNoClaim(options::OPT_hipstdpar))
3098 Inputs.push_back(std::make_pair(Ty, A));
3100 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3101 StringRef
Value = A->getValue();
3104 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3105 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3108 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3109 StringRef
Value = A->getValue();
3112 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3113 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3119 Inputs.push_back(std::make_pair(types::TY_Object, A));
3121 }
else if (A->getOption().matches(options::OPT_x)) {
3130 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3131 InputType = types::TY_Object;
3138 }
else if (A->getOption().getID() == options::OPT_U) {
3139 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3140 StringRef Val = A->getValue(0);
3141 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3143 Diag(diag::warn_slash_u_filename) << Val;
3144 Diag(diag::note_use_dashdash);
3148 if (
CCCIsCPP() && Inputs.empty()) {
3152 Inputs.push_back(std::make_pair(types::TY_C, A));
3159class OffloadingActionBuilder final {
3161 bool IsValid =
false;
3167 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3170 std::map<Action *, const Arg *> HostActionToInputArgMap;
3173 class DeviceActionBuilder {
3177 enum ActionBuilderReturnCode {
3196 DerivedArgList &Args;
3205 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3208 :
C(
C), Args(Args), Inputs(Inputs),
3209 AssociatedOffloadKind(AssociatedOffloadKind) {}
3210 virtual ~DeviceActionBuilder() {}
3215 virtual ActionBuilderReturnCode
3216 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3219 return ABRT_Inactive;
3224 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3225 return ABRT_Inactive;
3229 virtual void appendTopLevelActions(
ActionList &AL) {}
3232 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3235 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3238 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3245 virtual bool canUseBundlerUnbundler()
const {
return false; }
3249 bool isValid() {
return !ToolChains.empty(); }
3253 return AssociatedOffloadKind;
3259 class CudaActionBuilderBase :
public DeviceActionBuilder {
3263 bool CompileHostOnly =
false;
3264 bool CompileDeviceOnly =
false;
3266 bool EmitAsm =
false;
3276 TargetID(
const char *ID) :
ID(
ID) {}
3277 operator const char *() {
return ID; }
3278 operator StringRef() {
return StringRef(ID); }
3281 SmallVector<TargetID, 4> GpuArchList;
3287 Action *CudaFatBinary =
nullptr;
3290 bool IsActive =
false;
3293 bool Relocatable =
false;
3296 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3299 const CUIDOptions &CUIDOpts;
3302 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3305 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3306 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3308 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3309 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3310 options::OPT_fno_gpu_rdc,
false);
3313 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3320 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3323 if (!(IA->getType() == types::TY_CUDA ||
3324 IA->getType() == types::TY_HIP ||
3325 IA->getType() == types::TY_PP_HIP)) {
3328 return ABRT_Inactive;
3335 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3337 if (CompileHostOnly)
3338 return ABRT_Success;
3341 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3342 : types::TY_CUDA_DEVICE;
3343 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3344 CudaDeviceActions.push_back(
3345 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3348 return ABRT_Success;
3352 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3356 if (UA->getType() == types::TY_Object && !Relocatable)
3357 return ABRT_Inactive;
3359 CudaDeviceActions.clear();
3361 std::string
FileName = IA->getInputArg().getAsString(Args);
3367 const StringRef LibFileExt =
".lib";
3368 if (IA->getType() == types::TY_Object &&
3369 (!llvm::sys::path::has_extension(
FileName) ||
3371 llvm::sys::path::extension(
FileName).drop_front()) !=
3373 llvm::sys::path::extension(
FileName) == LibFileExt))
3374 return ABRT_Inactive;
3376 for (
auto Arch : GpuArchList) {
3377 CudaDeviceActions.push_back(UA);
3378 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3379 AssociatedOffloadKind);
3382 return ABRT_Success;
3385 return IsActive ? ABRT_Success : ABRT_Inactive;
3388 void appendTopLevelActions(
ActionList &AL)
override {
3390 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3391 OffloadAction::DeviceDependences Dep;
3392 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3393 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3397 if (CudaFatBinary) {
3398 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3399 CudaDeviceActions.clear();
3400 CudaFatBinary =
nullptr;
3404 if (CudaDeviceActions.empty())
3410 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3411 "Expecting one action per GPU architecture.");
3412 assert(ToolChains.size() == 1 &&
3413 "Expecting to have a single CUDA toolchain.");
3414 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3415 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3417 CudaDeviceActions.clear();
3420 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3438 assert(HostTC &&
"No toolchain for host compilation.");
3443 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3448 std::set<StringRef> GpuArchs;
3450 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3451 ToolChains.push_back(I.second);
3454 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3455 GpuArchs.insert(
Arch);
3459 for (
auto Arch : GpuArchs)
3460 GpuArchList.push_back(
Arch.data());
3462 CompileHostOnly =
C.getDriver().offloadHostOnly();
3463 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3464 EmitAsm = Args.getLastArg(options::OPT_S);
3472 class CudaActionBuilder final :
public CudaActionBuilderBase {
3474 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3476 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3477 DefaultOffloadArch = OffloadArch::CudaDefault;
3480 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3482 const std::set<StringRef> &GpuArchs)
override {
3483 return std::nullopt;
3486 ActionBuilderReturnCode
3487 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3489 PhasesTy &Phases)
override {
3491 return ABRT_Inactive;
3495 if (CudaDeviceActions.empty())
3496 return ABRT_Success;
3498 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3499 "Expecting one action per GPU architecture.");
3500 assert(!CompileHostOnly &&
3501 "Not expecting CUDA actions in host-only compilation.");
3511 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3514 for (
auto Ph : Phases) {
3519 if (Ph > FinalPhase)
3522 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3536 Action *AssembleAction = CudaDeviceActions[I];
3537 assert(AssembleAction->
getType() == types::TY_Object);
3538 assert(AssembleAction->
getInputs().size() == 1);
3544 OffloadAction::DeviceDependences DDep;
3546 DeviceActions.push_back(
3547 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3552 if (!DeviceActions.empty()) {
3554 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3556 if (!CompileDeviceOnly) {
3557 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3561 CudaFatBinary =
nullptr;
3566 CudaDeviceActions.clear();
3570 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3575 return ABRT_Success;
3579 "instructions should only occur "
3580 "before the backend phase!");
3583 for (Action *&A : CudaDeviceActions)
3584 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3586 return ABRT_Success;
3591 class HIPActionBuilder final :
public CudaActionBuilderBase {
3593 SmallVector<ActionList, 8> DeviceLinkerInputs;
3599 std::optional<bool> BundleOutput;
3600 std::optional<bool> EmitReloc;
3603 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3605 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3607 DefaultOffloadArch = OffloadArch::HIPDefault;
3609 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3610 options::OPT_fno_hip_emit_relocatable)) {
3611 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3612 options::OPT_fno_hip_emit_relocatable, false);
3616 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3617 <<
"-fhip-emit-relocatable"
3621 if (!CompileDeviceOnly) {
3622 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3623 <<
"-fhip-emit-relocatable"
3624 <<
"--offload-device-only";
3629 if (Args.hasArg(options::OPT_gpu_bundle_output,
3630 options::OPT_no_gpu_bundle_output))
3631 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3632 options::OPT_no_gpu_bundle_output,
true) &&
3633 (!EmitReloc || !*EmitReloc);
3636 bool canUseBundlerUnbundler()
const override {
return true; }
3638 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3640 const std::set<StringRef> &GpuArchs)
override {
3644 ActionBuilderReturnCode
3645 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3647 PhasesTy &Phases)
override {
3649 return ABRT_Inactive;
3655 if (CudaDeviceActions.empty())
3656 return ABRT_Success;
3659 CudaDeviceActions.size() == GpuArchList.size()) &&
3660 "Expecting one action per GPU architecture.");
3661 assert(!CompileHostOnly &&
3662 "Not expecting HIP actions in host-only compilation.");
3664 bool ShouldLink = !EmitReloc || !*EmitReloc;
3667 !EmitAsm && ShouldLink) {
3673 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3674 if (
C.getDriver().isUsingOffloadLTO()) {
3678 AL.push_back(CudaDeviceActions[I]);
3681 CudaDeviceActions[I] =
3682 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3688 if (ToolChains.front()->getTriple().isSPIRV() ||
3689 (ToolChains.front()->getTriple().isAMDGCN() &&
3690 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3694 types::ID Output = Args.hasArg(options::OPT_S)
3696 : types::TY_LLVM_BC;
3698 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3702 AssociatedOffloadKind);
3703 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3705 AssociatedOffloadKind);
3706 AL.push_back(AssembleAction);
3709 CudaDeviceActions[I] =
3710 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3719 OffloadAction::DeviceDependences DDep;
3720 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3721 AssociatedOffloadKind);
3722 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3723 DDep, CudaDeviceActions[I]->getType());
3726 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3728 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3729 types::TY_HIP_FATBIN);
3731 if (!CompileDeviceOnly) {
3732 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3733 AssociatedOffloadKind);
3736 CudaFatBinary =
nullptr;
3741 CudaDeviceActions.clear();
3744 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3747 return ABRT_Success;
3753 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3754 auto LI = DeviceLinkerInputs.begin();
3755 for (
auto *A : CudaDeviceActions) {
3762 CudaDeviceActions.clear();
3763 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3767 for (Action *&A : CudaDeviceActions)
3768 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3769 AssociatedOffloadKind);
3771 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3773 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3774 OffloadAction::DeviceDependences DDep;
3775 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3776 AssociatedOffloadKind);
3777 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3778 DDep, CudaDeviceActions[I]->getType());
3781 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3782 CudaDeviceActions.clear();
3785 return (CompileDeviceOnly &&
3786 (CurPhase == FinalPhase ||
3792 void appendLinkDeviceActions(
ActionList &AL)
override {
3793 if (DeviceLinkerInputs.size() == 0)
3796 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3797 "Linker inputs and GPU arch list sizes do not match.");
3803 for (
auto &LI : DeviceLinkerInputs) {
3805 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3809 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3812 OffloadAction::DeviceDependences DeviceLinkDeps;
3813 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3814 GpuArchList[I], AssociatedOffloadKind);
3815 Actions.push_back(
C.MakeAction<OffloadAction>(
3816 DeviceLinkDeps, DeviceLinkAction->getType()));
3819 DeviceLinkerInputs.clear();
3822 if (Args.hasArg(options::OPT_emit_llvm)) {
3830 OffloadAction::DeviceDependences DDeps;
3831 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3832 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3834 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3835 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3836 AssociatedOffloadKind);
3839 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3845 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3847 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3855 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3861 bool ShouldUseBundler;
3864 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3872 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3875 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3883 unsigned ValidBuilders = 0u;
3884 unsigned ValidBuildersSupportingBundling = 0u;
3885 for (
auto *SB : SpecializedBuilders) {
3886 IsValid = IsValid && !SB->initialize();
3889 if (SB->isValid()) {
3891 if (SB->canUseBundlerUnbundler())
3892 ++ValidBuildersSupportingBundling;
3896 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3898 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
3899 options::OPT_no_gpu_bundle_output,
true);
3902 ~OffloadingActionBuilder() {
3903 for (
auto *SB : SpecializedBuilders)
3908 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3909 assert(HostAction &&
"Invalid host action");
3910 assert(InputArg &&
"Invalid input argument");
3911 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3912 assert(Loc->second == InputArg &&
3913 "host action mapped to multiple input arguments");
3922 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3924 DeviceActionBuilder::PhasesTy &Phases) {
3928 if (SpecializedBuilders.empty())
3931 assert(HostAction &&
"Invalid host action!");
3932 recordHostAction(HostAction, InputArg);
3937 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3938 unsigned InactiveBuilders = 0u;
3939 unsigned IgnoringBuilders = 0u;
3940 for (
auto *SB : SpecializedBuilders) {
3941 if (!SB->isValid()) {
3946 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3951 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3956 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3957 OffloadKind |= SB->getAssociatedOffloadKind();
3962 if (IgnoringBuilders &&
3963 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3980 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3981 const Arg *InputArg) {
3985 recordHostAction(HostAction, InputArg);
3994 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3996 HostAction->
getType() == types::TY_PP_HIP)) {
3997 auto UnbundlingHostAction =
4002 HostAction = UnbundlingHostAction;
4003 recordHostAction(HostAction, InputArg);
4006 assert(HostAction &&
"Invalid host action!");
4009 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4010 for (
auto *SB : SpecializedBuilders) {
4014 auto RetCode = SB->addDeviceDependences(HostAction);
4018 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4019 "Host dependence not expected to be ignored.!");
4023 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4024 OffloadKind |= SB->getAssociatedOffloadKind();
4029 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4039 const Arg *InputArg) {
4041 recordHostAction(HostAction, InputArg);
4045 for (
auto *SB : SpecializedBuilders) {
4048 SB->appendTopLevelActions(OffloadAL);
4055 if (CanUseBundler && ShouldUseBundler && HostAction &&
4056 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4058 OffloadAL.push_back(HostAction);
4062 assert(HostAction == AL.back() &&
"Host action not in the list??");
4064 recordHostAction(HostAction, InputArg);
4065 AL.back() = HostAction;
4067 AL.append(OffloadAL.begin(), OffloadAL.end());
4077 void appendDeviceLinkActions(
ActionList &AL) {
4078 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4081 SB->appendLinkDeviceActions(AL);
4085 Action *makeHostLinkAction() {
4088 appendDeviceLinkActions(DeviceAL);
4089 if (DeviceAL.empty())
4094 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4097 HA = SB->appendLinkHostActions(DeviceAL);
4114 for (
auto *SB : SpecializedBuilders) {
4118 SB->appendLinkDependences(DDeps);
4122 unsigned ActiveOffloadKinds = 0u;
4123 for (
auto &I : InputArgToOffloadKindMap)
4124 ActiveOffloadKinds |= I.second;
4136 for (
auto *A : HostAction->
inputs()) {
4137 auto ArgLoc = HostActionToInputArgMap.find(A);
4138 if (ArgLoc == HostActionToInputArgMap.end())
4140 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4141 if (OFKLoc == InputArgToOffloadKindMap.end())
4153 nullptr, ActiveOffloadKinds);
4159void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4160 const InputList &Inputs,
4164 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4165 StringRef
V = A->getValue();
4166 if (Inputs.size() > 1 && !
V.empty() &&
4167 !llvm::sys::path::is_separator(
V.back())) {
4169 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4170 << A->getSpelling() <<
V;
4171 Args.eraseArg(options::OPT__SLASH_Fo);
4176 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4177 StringRef
V = A->getValue();
4178 if (Inputs.size() > 1 && !
V.empty() &&
4179 !llvm::sys::path::is_separator(
V.back())) {
4181 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4182 << A->getSpelling() <<
V;
4183 Args.eraseArg(options::OPT__SLASH_Fa);
4188 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4189 if (A->getValue()[0] ==
'\0') {
4191 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4192 Args.eraseArg(options::OPT__SLASH_o);
4197 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4198 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4199 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4200 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4201 Args.eraseArg(options::OPT__SLASH_Yc);
4202 Args.eraseArg(options::OPT__SLASH_Yu);
4203 YcArg = YuArg =
nullptr;
4205 if (YcArg && Inputs.size() > 1) {
4206 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4207 Args.eraseArg(options::OPT__SLASH_Yc);
4211 if (Args.hasArgNoClaim(options::OPT_fmodules_driver))
4213 if (!ModulesModeCXX20 && !Args.hasArgNoClaim(options::OPT_fmodules))
4214 Args.eraseArg(options::OPT_fmodules_driver);
4220 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4221 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4222 Args.AddFlagArg(
nullptr,
4223 getOpts().getOption(options::OPT_frtlib_add_rpath));
4226 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4227 Diag(clang::diag::err_drv_emit_llvm_link);
4228 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4230 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4231 .starts_with_insensitive(
"lld"))
4232 Diag(clang::diag::err_drv_lto_without_lld);
4238 if (!Args.hasArg(options::OPT_dumpdir)) {
4239 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4240 Arg *Arg = Args.MakeSeparateArg(
4241 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4243 (FinalOutput ? FinalOutput->getValue()
4255 Args.eraseArg(options::OPT__SLASH_Fp);
4256 Args.eraseArg(options::OPT__SLASH_Yc);
4257 Args.eraseArg(options::OPT__SLASH_Yu);
4258 YcArg = YuArg =
nullptr;
4261 if (Args.hasArg(options::OPT_include_pch) &&
4262 Args.hasArg(options::OPT_ignore_pch)) {
4266 Args.eraseArg(options::OPT_include_pch);
4269 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4270 for (
auto &I : Inputs) {
4272 const Arg *InputArg = I.second;
4277 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4281 if (InitialPhase > FinalPhase) {
4282 if (InputArg->isClaimed())
4289 if (Args.hasArg(options::OPT_Qunused_arguments))
4295 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4296 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4300 (Args.getLastArg(options::OPT__SLASH_EP,
4301 options::OPT__SLASH_P) ||
4302 Args.getLastArg(options::OPT_E) ||
4303 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4305 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4306 << InputArg->getAsString(Args) << !!FinalPhaseArg
4307 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4309 Diag(clang::diag::warn_drv_input_file_unused)
4310 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4312 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4321 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4325 Actions.push_back(ClangClPch);
4337 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4338 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4343 const auto IsTypeCXXModule = [](
const auto &Input) ->
bool {
4344 const auto TypeID = Input.first;
4345 return (TypeID == types::TY_CXXModule);
4347 return llvm::any_of(Inputs, IsTypeCXXModule);
4351Driver::ScanInputsForCXX20ModulesUsage(
const InputList &Inputs)
const {
4352 const auto CXXInputs = llvm::make_filter_range(
4353 Inputs, [](
const auto &Input) {
return types::isCXX(Input.first); });
4354 for (
const auto &Input : CXXInputs) {
4355 StringRef Filename = Input.second->getSpelling();
4356 auto ErrOrBuffer = VFS->getBufferForFile(Filename);
4358 return ErrOrBuffer.getError();
4359 const auto Buffer = std::move(*ErrOrBuffer);
4362 Diags.Report(diag::remark_found_cxx20_module_usage) << Filename;
4371 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4373 if (!SuppressMissingInputWarning && Inputs.empty()) {
4374 Diag(clang::diag::err_drv_no_input_files);
4378 handleArguments(
C, Args, Inputs, Actions);
4380 if (Args.hasFlag(options::OPT_fmodules_driver,
4381 options::OPT_fno_modules_driver,
false)) {
4386 if (!UsesCXXModules) {
4387 const auto ErrOrScanResult = ScanInputsForCXX20ModulesUsage(Inputs);
4388 if (!ErrOrScanResult) {
4389 Diags.Report(diag::err_cannot_open_file)
4390 << ErrOrScanResult.getError().message();
4393 UsesCXXModules = *ErrOrScanResult;
4395 if (UsesCXXModules || Args.hasArg(options::OPT_fmodules))
4396 BuildDriverManagedModuleBuildActions(
C, Args, Inputs, Actions);
4400 BuildDefaultActions(
C, Args, Inputs, Actions);
4403void Driver::BuildDefaultActions(
Compilation &
C, DerivedArgList &Args,
4404 const InputList &Inputs,
4407 bool UseNewOffloadingDriver =
4410 Args.hasFlag(options::OPT_foffload_via_llvm,
4411 options::OPT_fno_offload_via_llvm,
false) ||
4412 Args.hasFlag(options::OPT_offload_new_driver,
4413 options::OPT_no_offload_new_driver,
4417 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4418 !UseNewOffloadingDriver
4419 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4427 for (
auto &I : Inputs) {
4429 const Arg *InputArg = I.second;
4442 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4448 if (!UseNewOffloadingDriver)
4449 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4455 if (!UseNewOffloadingDriver)
4456 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4457 Current, InputArg, Phase, PL.back(), FullPL);
4463 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4466 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4467 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4469 LinkerInputs.push_back(Current);
4479 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4480 MergerInputs.push_back(Current);
4498 if (NewCurrent == Current)
4501 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4502 ExtractAPIAction = EAA;
4504 Current = NewCurrent;
4508 if (UseNewOffloadingDriver)
4512 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4516 if (Current->
getType() == types::TY_Nothing)
4522 Actions.push_back(Current);
4525 if (!UseNewOffloadingDriver)
4526 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4534 if (LinkerInputs.empty()) {
4537 if (!UseNewOffloadingDriver)
4538 OffloadBuilder->appendDeviceLinkActions(Actions);
4541 if (!LinkerInputs.empty()) {
4542 if (!UseNewOffloadingDriver)
4543 if (Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4544 LinkerInputs.push_back(Wrapper);
4548 LA =
C.MakeAction<StaticLibJobAction>(LinkerInputs, types::TY_Image);
4549 }
else if (UseNewOffloadingDriver ||
4550 Args.hasArg(options::OPT_offload_link)) {
4551 LA =
C.MakeAction<LinkerWrapperJobAction>(LinkerInputs, types::TY_Image);
4555 LA =
C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image);
4557 if (!UseNewOffloadingDriver)
4558 LA = OffloadBuilder->processHostLinkAction(LA);
4559 Actions.push_back(LA);
4563 if (!MergerInputs.empty())
4565 C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
4567 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4574 for (
auto &I : Inputs) {
4576 const Arg *InputArg = I.second;
4581 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4582 InputType == types::TY_Asm)
4585 Action *Current =
C.MakeAction<InputAction>(*InputArg, InputType);
4587 for (
auto Phase : PhaseList) {
4591 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4596 if (InputType == types::TY_Object)
4599 Current =
C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);
4603 assert(Phase == PhaseList.back() &&
4604 "merging must be final compilation step.");
4605 MergerInputs.push_back(Current);
4614 Actions.push_back(Current);
4618 if (!MergerInputs.empty())
4620 C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
4623 for (
auto Opt : {options::OPT_print_supported_cpus,
4624 options::OPT_print_supported_extensions,
4625 options::OPT_print_enabled_extensions}) {
4632 if (Arg *A = Args.getLastArg(Opt)) {
4633 if (Opt == options::OPT_print_supported_extensions &&
4634 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4635 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4636 !
C.getDefaultToolChain().getTriple().isARM()) {
4637 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4638 <<
"--print-supported-extensions";
4641 if (Opt == options::OPT_print_enabled_extensions &&
4642 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4643 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4644 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4645 <<
"--print-enabled-extensions";
4651 Action *InputAc =
C.MakeAction<InputAction>(
4652 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4654 C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
4655 for (
auto &I : Inputs)
4660 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4662 static_cast<const toolchains::HLSLToolChain &
>(
C.getDefaultToolChain());
4666 if (TC.requiresObjcopy(Args)) {
4667 Action *LastAction = Actions.back();
4669 if (LastAction->
getType() == types::TY_Object)
4671 C.MakeAction<ObjcopyJobAction>(LastAction, types::TY_Object));
4675 if (TC.requiresValidation(Args)) {
4676 Action *LastAction = Actions.back();
4677 Actions.push_back(
C.MakeAction<BinaryAnalyzeJobAction>(
4678 LastAction, types::TY_DX_CONTAINER));
4682 if (TC.requiresBinaryTranslation(Args)) {
4683 Action *LastAction = Actions.back();
4687 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4688 LastAction->
getType() == types::TY_Object)
4689 Actions.push_back(
C.MakeAction<BinaryTranslatorJobAction>(
4690 LastAction, types::TY_DX_CONTAINER));
4695 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4698void Driver::BuildDriverManagedModuleBuildActions(
4699 Compilation &
C, llvm::opt::DerivedArgList &Args,
const InputList &Inputs,
4701 Diags.Report(diag::remark_performing_driver_managed_module_build);
4707 const llvm::opt::DerivedArgList &Args,
4709 const llvm::Triple &Triple) {
4714 if (Triple.isNVPTX() &&
4716 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4717 <<
"CUDA" << ArchStr;
4719 }
else if (Triple.isAMDGPU() &&
4721 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4722 <<
"HIP" << ArchStr;
4730 llvm::StringMap<bool> Features;
4733 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4745static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4747 llvm::Triple Triple) {
4748 if (!Triple.isAMDGPU())
4749 return std::nullopt;
4751 std::set<StringRef> ArchSet;
4752 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4756llvm::SmallVector<StringRef>
4760 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4761 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4762 options::OPT_no_offload_arch_EQ)) {
4763 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4765 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4767 :
"--no-offload-arch");
4770 llvm::DenseSet<StringRef> Archs;
4771 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4774 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4775 for (StringRef
Arch : Arg->getValues()) {
4776 if (
Arch ==
"native" ||
Arch.empty()) {
4780 << llvm::Triple::getArchTypeName(TC.
getArch())
4781 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4785 for (
auto ArchStr : *GPUsOrErr) {
4787 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4788 if (!CanonicalStr.empty())
4789 Archs.insert(CanonicalStr);
4794 StringRef CanonicalStr =
4796 if (!CanonicalStr.empty())
4797 Archs.insert(CanonicalStr);
4802 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4803 for (StringRef
Arch : Arg->getValues()) {
4804 if (
Arch ==
"all") {
4809 Archs.erase(ArchStr);
4815 if (
auto ConflictingArchs =
4817 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4818 << ConflictingArchs->first << ConflictingArchs->second;
4821 if (Archs.empty()) {
4829 Archs.insert(StringRef());
4832 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4833 .getLastArg(options::OPT_march_EQ)) {
4834 Archs.insert(Arg->getValue());
4839 << llvm::Triple::getArchTypeName(TC.
getArch())
4840 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4841 }
else if (!ArchsOrErr->empty()) {
4842 for (
auto Arch : *ArchsOrErr)
4843 Archs.insert(Args.MakeArgStringRef(
Arch));
4845 Archs.insert(StringRef());
4850 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4851 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4859 llvm::opt::DerivedArgList &Args,
4860 const InputTy &Input, StringRef CUID,
4861 Action *HostAction)
const {
4869 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4871 bool HIPRelocatableObj =
4873 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4874 options::OPT_fno_hip_emit_relocatable,
false);
4876 if (!HIPNoRDC && HIPRelocatableObj)
4877 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4878 <<
"-fhip-emit-relocatable"
4882 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4883 <<
"-fhip-emit-relocatable"
4884 <<
"--offload-device-only";
4902 auto TCRange =
C.getOffloadToolChains(Kind);
4903 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4904 ToolChains.push_back(TI->second);
4906 if (ToolChains.empty())
4910 const Arg *InputArg = Input.second;
4919 for (
const ToolChain *TC : ToolChains) {
4921 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4922 DeviceActions.push_back(
4923 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4927 if (DeviceActions.empty())
4933 HostAction->
getType() != types::TY_Nothing &&
4943 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4952 auto *TCAndArch = TCAndArchs.begin();
4953 for (
Action *&A : DeviceActions) {
4954 if (A->
getType() == types::TY_Nothing)
4964 HostAction->
getType() != types::TY_Nothing) {
4971 TCAndArch->second.data(), Kind);
4973 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4983 for (
Action *&A : DeviceActions) {
4988 llvm::Triple::OSType::AMDHSA &&
4990 if ((A->
getType() != types::TY_Object && !IsAMDGCNSPIRV &&
4991 A->
getType() != types::TY_LTO_BC) ||
4998 auto *TCAndArch = TCAndArchs.begin();
4999 for (
Action *A : DeviceActions) {
5000 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5002 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5007 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5009 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5018 bool ShouldBundleHIP =
5019 Args.hasFlag(options::OPT_gpu_bundle_output,
5020 options::OPT_no_gpu_bundle_output,
false) ||
5022 llvm::none_of(OffloadActions, [](
Action *A) {
5023 return A->
getType() != types::TY_Image;
5030 if (OffloadActions.empty())
5035 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5039 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5046 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5047 DDep.
add(*FatbinAction,
5050 }
else if (HIPNoRDC) {
5062 DDep.
add(*PackagerAction,
5071 nullptr,
C.getActiveOffloadKinds());
5080 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5081 return A->
getType() == types::TY_Nothing;
5085 nullptr, SingleDeviceOutput ? DDep : DDeps);
5086 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5092 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5102 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5108 llvm_unreachable(
"link action invalid here.");
5110 llvm_unreachable(
"ifsmerge action invalid here.");
5115 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5116 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5117 OutputTy = types::TY_Dependencies;
5122 if (!Args.hasFlag(options::OPT_frewrite_includes,
5123 options::OPT_fno_rewrite_includes,
false) &&
5124 !Args.hasFlag(options::OPT_frewrite_imports,
5125 options::OPT_fno_rewrite_imports,
false) &&
5126 !Args.hasFlag(options::OPT_fdirectives_only,
5127 options::OPT_fno_directives_only,
false) &&
5131 "Cannot preprocess this input type!");
5137 if (Args.hasArg(options::OPT_extract_api))
5144 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5145 (Input->
getType() == driver::types::TY_CXXModule ||
5146 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5147 !Args.getLastArg(options::OPT__precompile))
5152 "Cannot precompile this input type!");
5156 const char *ModName =
nullptr;
5157 if (OutputTy == types::TY_PCH) {
5158 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5159 ModName = A->getValue();
5161 OutputTy = types::TY_ModuleFile;
5164 if (Args.hasArg(options::OPT_fsyntax_only)) {
5166 OutputTy = types::TY_Nothing;
5172 if (Args.hasArg(options::OPT_fsyntax_only))
5174 if (Args.hasArg(options::OPT_rewrite_objc))
5176 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5178 types::TY_RewrittenLegacyObjC);
5179 if (Args.hasArg(options::OPT__analyze))
5181 if (Args.hasArg(options::OPT_emit_ast))
5183 if (Args.hasArg(options::OPT_emit_cir))
5185 if (Args.hasArg(options::OPT_module_file_info))
5187 if (Args.hasArg(options::OPT_verify_pch))
5189 if (Args.hasArg(options::OPT_extract_api))
5197 Args.hasFlag(options::OPT_offload_new_driver,
5198 options::OPT_no_offload_new_driver,
false) &&
5204 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5205 !Args.hasArg(options::OPT_emit_llvm))
5206 Output = types::TY_PP_Asm;
5207 else if (Args.hasArg(options::OPT_S))
5208 Output = types::TY_LTO_IR;
5210 Output = types::TY_LTO_BC;
5215 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5218 if (Args.hasArg(options::OPT_emit_llvm) ||
5224 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5226 (Args.hasFlag(options::OPT_offload_new_driver,
5227 options::OPT_no_offload_new_driver,
false) &&
5234 Args.hasArg(options::OPT_S) &&
5238 !Args.hasFlag(options::OPT_offload_new_driver,
5239 options::OPT_no_offload_new_driver,
5242 : types::TY_LLVM_BC;
5251 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5255 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5257 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5277 unsigned NumOutputs = 0;
5278 unsigned NumIfsOutputs = 0;
5279 for (
const Action *A :
C.getActions()) {
5282 if (A->
getType() == types::TY_DX_CONTAINER &&
5287 if (A->
getType() != types::TY_Nothing &&
5289 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5291 0 == NumIfsOutputs++) ||
5296 A->
getType() == types::TY_Nothing &&
5297 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5298 NumOutputs += A->
size();
5301 if (NumOutputs > 1) {
5302 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5303 FinalOutput =
nullptr;
5307 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5311 if (RawTriple.isOSBinFormatMachO())
5312 for (
const Arg *A :
C.getArgs())
5313 if (A->getOption().matches(options::OPT_arch))
5317 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5318 for (
Action *A :
C.getActions()) {
5325 const char *LinkingOutput =
nullptr;
5328 LinkingOutput = FinalOutput->getValue();
5337 LinkingOutput, CachedResults,
5344 for (
auto &J :
C.getJobs())
5345 J.InProcess =
false;
5348 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5349 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5354 const char *LinkingOutput =
nullptr;
5356 LinkingOutput = FinalOutput->getValue();
5363 using namespace llvm;
5366 <<
"output=" << LinkingOutput;
5367 outs() <<
", total="
5368 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5370 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5371 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5375 llvm::raw_string_ostream Out(Buffer);
5376 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5379 llvm::sys::printArg(Out, LinkingOutput,
true);
5380 Out <<
',' << ProcStat->TotalTime.count() <<
','
5381 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5386 llvm::sys::fs::OF_Append |
5387 llvm::sys::fs::OF_Text);
5392 llvm::errs() <<
"ERROR: Cannot lock file "
5394 <<
toString(L.takeError()) <<
"\n";
5405 bool ReportUnusedArguments =
5406 !Diags.hasErrorOccurred() &&
5407 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5410 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5412 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5415 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5416 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5418 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5422 return strstr(J.getCreator().getShortName(),
"assembler");
5424 for (Arg *A :
C.getArgs()) {
5428 if (!A->isClaimed()) {
5434 const Option &Opt = A->getOption();
5435 if (Opt.getKind() == Option::FlagClass) {
5436 bool DuplicateClaimed =
false;
5438 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5439 if (AA->isClaimed()) {
5440 DuplicateClaimed =
true;
5445 if (DuplicateClaimed)
5451 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5453 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5458 !
C.getActions().empty()) {
5459 Diag(diag::err_drv_unsupported_opt_for_target)
5461 }
else if (ReportUnusedArguments) {
5462 Diag(clang::diag::warn_drv_unused_argument)
5463 << A->getAsString(
C.getArgs());
5473class ToolSelector final {
5484 bool IsHostSelector;
5495 bool CanBeCollapsed =
true) {
5497 if (Inputs.size() != 1)
5500 Action *CurAction = *Inputs.begin();
5501 if (CanBeCollapsed &&
5507 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5511 if (!IsHostSelector) {
5512 if (OA->hasSingleDeviceDependence(
true)) {
5514 OA->getSingleDeviceDependence(
true);
5515 if (CanBeCollapsed &&
5518 SavedOffloadAction.push_back(OA);
5519 return dyn_cast<JobAction>(CurAction);
5521 }
else if (OA->hasHostDependence()) {
5522 CurAction = OA->getHostDependence();
5523 if (CanBeCollapsed &&
5526 SavedOffloadAction.push_back(OA);
5527 return dyn_cast<JobAction>(CurAction);
5532 return dyn_cast<JobAction>(CurAction);
5536 bool canCollapseAssembleAction()
const {
5537 return TC.useIntegratedAs() && !SaveTemps &&
5538 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5539 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5540 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5541 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5545 bool canCollapsePreprocessorAction()
const {
5546 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5547 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5548 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5553 struct JobActionInfo final {
5555 const JobAction *JA =
nullptr;
5563 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5564 ArrayRef<JobActionInfo> &ActionInfo,
5565 unsigned ElementNum) {
5566 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5567 for (
unsigned I = 0; I < ElementNum; ++I)
5568 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5569 ActionInfo[I].SavedOffloadAction.end());
5582 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5585 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5587 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5588 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5589 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5590 if (!AJ || !BJ || !CJ)
5594 const Tool *
T = TC.SelectTool(*CJ);
5601 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5607 const Tool *BT = TC.SelectTool(*BJ);
5612 if (!
T->hasIntegratedAssembler())
5615 Inputs = CJ->getInputs();
5616 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5620 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5623 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5625 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5626 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5631 const Tool *
T = TC.SelectTool(*BJ);
5635 if (!
T->hasIntegratedAssembler())
5638 Inputs = BJ->getInputs();
5639 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5643 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5646 if (ActionInfo.size() < 2)
5648 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5649 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5653 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5654 for (
auto &Input : AI.JA->getInputs())
5665 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5666 if (SaveTemps && !InputIsBitcode)
5670 const Tool *
T = TC.SelectTool(*CJ);
5677 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5683 Inputs = CJ->getInputs();
5684 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5693 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5695 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5701 for (Action *A : Inputs) {
5702 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5704 NewInputs.push_back(A);
5710 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5711 PreprocessJobOffloadActions.end());
5712 NewInputs.append(PJ->input_begin(), PJ->input_end());
5718 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5720 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5722 assert(BaseAction &&
"Invalid base action.");
5738 SmallVector<JobActionInfo, 5> ActionChain(1);
5739 ActionChain.back().JA = BaseAction;
5740 while (ActionChain.back().JA) {
5741 const Action *CurAction = ActionChain.back().JA;
5744 ActionChain.resize(ActionChain.size() + 1);
5745 JobActionInfo &AI = ActionChain.back();
5749 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5753 ActionChain.pop_back();
5761 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5762 CollapsedOffloadAction);
5764 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5766 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5772 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5784 StringRef BoundArch,
5786 std::string TriplePlusArch = TC->
getTriple().normalize();
5787 if (!BoundArch.empty()) {
5788 TriplePlusArch +=
"-";
5789 TriplePlusArch += BoundArch;
5791 TriplePlusArch +=
"-";
5793 return TriplePlusArch;
5798 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5799 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5802 std::pair<const Action *, std::string> ActionTC = {
5804 auto CachedResult = CachedResults.find(ActionTC);
5805 if (CachedResult != CachedResults.end()) {
5806 return CachedResult->second;
5809 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5810 CachedResults, TargetDeviceOffloadKind);
5811 CachedResults[ActionTC] =
Result;
5816 const JobAction *JA,
const char *BaseInput,
5819 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5823 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5824 Path = A->getValue();
5825 if (llvm::sys::fs::is_directory(Path)) {
5827 llvm::sys::path::replace_extension(Tmp,
"json");
5828 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5831 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5834 Path = DumpDir->getValue();
5835 Path += llvm::sys::path::filename(BaseInput);
5837 Path = Result.getFilename();
5839 llvm::sys::path::replace_extension(Path,
"json");
5841 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5842 C.addTimeTraceFile(ResultFile, JA);
5843 C.addResultFile(ResultFile, JA);
5848 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5849 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5852 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5855 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5856 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5888 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5890 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5891 const char *DepBoundArch) {
5894 LinkingOutput, CachedResults,
5904 OA->doOnEachDependence(
5905 BuildingForOffloadDevice,
5906 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5908 C, DepA, DepTC, DepBoundArch,
false,
5909 !!DepBoundArch, LinkingOutput, CachedResults,
5913 A = BuildingForOffloadDevice
5914 ? OA->getSingleDeviceDependence(
true)
5915 : OA->getHostDependence();
5919 std::pair<const Action *, std::string> ActionTC = {
5920 OA->getHostDependence(),
5922 auto It = CachedResults.find(ActionTC);
5923 if (It != CachedResults.end()) {
5925 Inputs.append(OffloadDependencesInputInfo);
5930 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5933 const Arg &Input = IA->getInputArg();
5935 if (Input.getOption().matches(options::OPT_INPUT)) {
5936 const char *
Name = Input.getValue();
5939 return {InputInfo(A, &Input,
"")};
5942 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5943 const ToolChain *TC;
5946 if (!ArchName.empty())
5947 TC = &getToolChain(
C.getArgs(),
5949 C.getArgs(), ArchName));
5951 TC = &
C.getDefaultToolChain();
5954 MultipleArchs, LinkingOutput, CachedResults,
5955 TargetDeviceOffloadKind);
5966 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5969 return {InputInfo()};
5973 for (
const auto *OA : CollapsedOffloadActions)
5975 BuildingForOffloadDevice,
5976 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5978 C, DepA, DepTC, DepBoundArch,
false,
5979 !!DepBoundArch, LinkingOutput, CachedResults,
5985 for (
const Action *Input : Inputs) {
5989 bool SubJobAtTopLevel =
5992 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5997 const char *BaseInput = InputInfos[0].getBaseInput();
5998 for (
auto &Info : InputInfos) {
5999 if (Info.isFilename()) {
6000 BaseInput = Info.getBaseInput();
6007 if (JA->
getType() == types::TY_dSYM)
6008 BaseInput = InputInfos[0].getFilename();
6011 if (!OffloadDependencesInputInfo.empty())
6012 InputInfos.append(OffloadDependencesInputInfo.begin(),
6013 OffloadDependencesInputInfo.end());
6016 llvm::Triple EffectiveTriple;
6017 const ToolChain &ToolTC =
T->getToolChain();
6018 const ArgList &Args =
6020 if (InputInfos.size() != 1) {
6024 EffectiveTriple = llvm::Triple(
6027 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6032 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6036 for (
auto &UI : UA->getDependentActionsInfo()) {
6038 "Unbundling with no offloading??");
6045 UI.DependentOffloadKind,
6046 UI.DependentToolChain->getTriple().normalize(),
6048 auto CurI = InputInfo(
6057 UnbundlingResults.push_back(CurI);
6066 Arch = UI.DependentBoundArch;
6071 UI.DependentOffloadKind)}] = {
6077 std::pair<const Action *, std::string> ActionTC = {
6079 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6080 "Result does not exist??");
6081 Result = CachedResults[ActionTC].front();
6082 }
else if (JA->
getType() == types::TY_Nothing)
6083 Result = {InputInfo(A, BaseInput)};
6093 AtTopLevel, MultipleArchs,
6096 if (
T->canEmitIR() && OffloadingPrefix.empty())
6101 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
6102 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6103 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6104 llvm::errs() << InputInfos[i].getAsString();
6106 llvm::errs() <<
", ";
6108 if (UnbundlingResults.empty())
6109 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6111 llvm::errs() <<
"], outputs: [";
6112 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6113 llvm::errs() << UnbundlingResults[i].getAsString();
6115 llvm::errs() <<
", ";
6117 llvm::errs() <<
"] \n";
6120 if (UnbundlingResults.empty())
6121 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6123 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6124 Args, LinkingOutput);
6130 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6131 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6143 if (ArgValue.empty()) {
6145 Filename = BaseName;
6146 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6148 llvm::sys::path::append(Filename, BaseName);
6151 if (!llvm::sys::path::has_extension(ArgValue)) {
6156 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6161 llvm::sys::path::replace_extension(Filename, Extension);
6164 return Args.MakeArgString(Filename.c_str());
6179 StringRef Suffix,
bool MultipleArchs,
6180 StringRef BoundArch,
6181 bool NeedUniqueDirectory)
const {
6183 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6184 std::optional<std::string> CrashDirectory =
6186 ? std::string(A->getValue())
6187 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6188 if (CrashDirectory) {
6189 if (!
getVFS().exists(*CrashDirectory))
6190 llvm::sys::fs::create_directories(*CrashDirectory);
6192 llvm::sys::path::append(Path, Prefix);
6193 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6194 if (std::error_code EC =
6195 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6196 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6200 if (MultipleArchs && !BoundArch.empty()) {
6201 if (NeedUniqueDirectory) {
6203 llvm::sys::path::append(TmpName,
6204 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6214 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6229 const char *BaseInput) {
6231 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6232 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6237 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6241 const char *BaseInput,
6242 StringRef OrigBoundArch,
bool AtTopLevel,
6244 StringRef OffloadingPrefix)
const {
6245 std::string BoundArch = OrigBoundArch.str();
6246 if (is_style_windows(llvm::sys::path::Style::native)) {
6249 llvm::replace(BoundArch,
':',
'@');
6252 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6255 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6256 return C.addResultFile(FinalOutput->getValue(), &JA);
6260 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6262 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6264 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6265 NameArg = A->getValue();
6266 return C.addResultFile(
6276 if (JA.
getType() == types::TY_ModuleFile &&
6277 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6281 if (JA.
getType() == types::TY_PP_Asm &&
6282 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6283 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6286 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6289 if ((JA.
getType() == types::TY_Object &&
6290 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6291 JA.
getType() == types::TY_DX_CONTAINER) {
6292 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6296 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6298 C.getDefaultToolChain());
6301 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6302 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6303 StringRef
Name = llvm::sys::path::filename(BaseInput);
6304 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6310 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6311 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6315 if (JA.
getType() == types::TY_PP_Asm &&
6316 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6317 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6319 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6320 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6321 return C.addResultFile(
6326 if (JA.
getType() == types::TY_API_INFO &&
6327 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6328 C.getArgs().hasArg(options::OPT_o))
6329 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6330 <<
C.getArgs().getLastArgValue(options::OPT_o);
6337 bool SpecifiedModuleOutput =
6338 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6339 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6340 if (MultipleArchs && SpecifiedModuleOutput)
6341 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6346 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6347 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6353 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6355 StringRef
Name = llvm::sys::path::filename(BaseInput);
6356 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6357 const char *Suffix =
6362 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6363 bool NeedUniqueDirectory =
6366 Triple.isOSDarwin();
6367 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6368 NeedUniqueDirectory);
6377 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6382 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6383 llvm::sys::path::filename(BasePath));
6384 BaseName = ExternalPath;
6386 BaseName = BasePath;
6388 BaseName = llvm::sys::path::filename(BasePath);
6391 const char *NamedOutput;
6393 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6394 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6398 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6402 }
else if (JA.
getType() == types::TY_Image &&
6403 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6404 options::OPT__SLASH_o)) {
6408 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6412 }
else if (JA.
getType() == types::TY_Image) {
6422 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6423 options::OPT_fno_gpu_rdc,
false);
6425 if (UseOutExtension) {
6427 llvm::sys::path::replace_extension(Output,
"");
6429 Output += OffloadingPrefix;
6430 if (MultipleArchs && !BoundArch.empty()) {
6432 Output.append(BoundArch);
6434 if (UseOutExtension)
6436 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6439 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6440 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6441 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6444 .getLastArg(options::OPT__SLASH_o)
6449 const char *Suffix =
6451 assert(Suffix &&
"All types used for output should have a suffix.");
6453 std::string::size_type End = std::string::npos;
6455 End = BaseName.rfind(
'.');
6457 Suffixed += OffloadingPrefix;
6458 if (MultipleArchs && !BoundArch.empty()) {
6460 Suffixed.append(BoundArch);
6465 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6466 const llvm::opt::DerivedArgList &Args) {
6473 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6481 bool IsLinkerWrapper =
6483 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6484 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6485 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6487 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6491 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6495 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6496 JA.
getType() != types::TY_PCH) {
6497 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6499 llvm::sys::path::remove_filename(TempPath);
6500 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6501 llvm::sys::path::append(TempPath, OutputFileName);
6502 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6508 bool SameFile =
false;
6510 llvm::sys::fs::current_path(
Result);
6511 llvm::sys::path::append(
Result, BaseName);
6512 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6515 StringRef
Name = llvm::sys::path::filename(BaseInput);
6516 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6520 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6526 llvm::sys::path::remove_filename(BasePath);
6527 if (BasePath.empty())
6528 BasePath = NamedOutput;
6530 llvm::sys::path::append(BasePath, NamedOutput);
6531 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6534 return C.addResultFile(NamedOutput, &JA);
6540 -> std::optional<std::string> {
6543 for (
const auto &
Dir : P) {
6547 llvm::sys::path::append(P,
Name);
6548 if (llvm::sys::fs::exists(Twine(P)))
6549 return std::string(P);
6551 return std::nullopt;
6558 llvm::sys::path::append(R,
Name);
6559 if (llvm::sys::fs::exists(Twine(R)))
6560 return std::string(R);
6563 llvm::sys::path::append(P,
Name);
6564 if (llvm::sys::fs::exists(Twine(P)))
6565 return std::string(P);
6568 llvm::sys::path::append(D,
"..",
Name);
6569 if (llvm::sys::fs::exists(Twine(D)))
6570 return std::string(D);
6579 llvm::sys::path::append(R2,
"..",
"..",
Name);
6580 if (llvm::sys::fs::exists(Twine(R2)))
6581 return std::string(R2);
6583 return std::string(
Name);
6586void Driver::generatePrefixedToolNames(
6590 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6591 Names.emplace_back(
Tool);
6595 llvm::sys::path::append(Dir, Name);
6596 if (llvm::sys::fs::can_execute(Twine(Dir)))
6598 llvm::sys::path::remove_filename(Dir);
6604 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6609 if (llvm::sys::fs::is_directory(PrefixDir)) {
6612 return std::string(P);
6615 if (llvm::sys::fs::can_execute(Twine(P)))
6616 return std::string(P);
6621 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6629 for (
const auto &Path : List) {
6632 return std::string(P);
6636 if (llvm::ErrorOr<std::string> P =
6637 llvm::sys::findProgramByName(TargetSpecificExecutable))
6641 return std::string(
Name);
6646 std::string error =
"<NOT PRESENT>";
6648 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6653 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6670 llvm::sys::path::remove_filename(path);
6671 llvm::sys::path::append(path,
"libc++.modules.json");
6672 if (TC.
getVFS().exists(path))
6673 return static_cast<std::string
>(path);
6678 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6681 return evaluate(
"libc++.a").value_or(error);
6685 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6689 llvm::sys::path::remove_filename(path);
6690 llvm::sys::path::append(path,
"libstdc++.modules.json");
6691 if (TC.
getVFS().exists(path))
6692 return static_cast<std::string
>(path);
6697 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6700 return evaluate(
"libstdc++.a").value_or(error);
6709 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6711 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6715 return std::string(Path);
6720 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6722 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6726 return std::string(Path);
6731 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6735 Output = FpArg->getValue();
6739 if (!llvm::sys::path::has_extension(Output))
6742 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6743 Output = YcArg->getValue();
6746 llvm::sys::path::replace_extension(Output,
".pch");
6748 return std::string(Output);
6751const ToolChain &Driver::getOffloadToolChain(
6753 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6754 std::unique_ptr<ToolChain> &TC =
6755 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6756 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6758 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6761 switch (
Target.getOS()) {
6762 case llvm::Triple::CUDA:
6763 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6766 case llvm::Triple::AMDHSA:
6768 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6771 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6780 switch (
Target.getArch()) {
6781 case llvm::Triple::spir:
6782 case llvm::Triple::spir64:
6783 case llvm::Triple::spirv:
6784 case llvm::Triple::spirv32:
6785 case llvm::Triple::spirv64:
6788 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6792 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6796 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6800 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6814 return getToolChain(Args,
Target);
6818const ToolChain &Driver::getToolChain(
const ArgList &Args,
6819 const llvm::Triple &
Target)
const {
6821 auto &TC = ToolChains[
Target.str()];
6823 switch (
Target.getOS()) {
6824 case llvm::Triple::AIX:
6825 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6827 case llvm::Triple::Haiku:
6828 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6830 case llvm::Triple::Darwin:
6831 case llvm::Triple::MacOSX:
6832 case llvm::Triple::IOS:
6833 case llvm::Triple::TvOS:
6834 case llvm::Triple::WatchOS:
6835 case llvm::Triple::XROS:
6836 case llvm::Triple::DriverKit:
6837 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6839 case llvm::Triple::DragonFly:
6840 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6842 case llvm::Triple::OpenBSD:
6843 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6845 case llvm::Triple::NetBSD:
6846 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6848 case llvm::Triple::FreeBSD:
6850 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6853 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6855 case llvm::Triple::Linux:
6856 case llvm::Triple::ELFIAMCU:
6857 if (
Target.getArch() == llvm::Triple::hexagon)
6858 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6860 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6861 !
Target.hasEnvironment())
6862 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6865 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6867 else if (
Target.getArch() == llvm::Triple::ve)
6868 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6869 else if (
Target.isOHOSFamily())
6870 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6871 else if (
Target.isWALI())
6872 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6874 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6876 case llvm::Triple::Fuchsia:
6877 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6879 case llvm::Triple::Managarm:
6880 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6882 case llvm::Triple::Solaris:
6883 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6885 case llvm::Triple::CUDA:
6886 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6888 case llvm::Triple::AMDHSA: {
6889 if (
Target.getArch() == llvm::Triple::spirv64) {
6890 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6895 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6897 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6902 case llvm::Triple::AMDPAL:
6903 case llvm::Triple::Mesa3D:
6904 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6906 case llvm::Triple::UEFI:
6907 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6909 case llvm::Triple::Win32:
6910 switch (
Target.getEnvironment()) {
6912 if (
Target.isOSBinFormatELF())
6913 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6914 else if (
Target.isOSBinFormatMachO())
6915 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6917 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6919 case llvm::Triple::GNU:
6920 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6922 case llvm::Triple::Cygnus:
6923 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6925 case llvm::Triple::Itanium:
6926 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6929 case llvm::Triple::MSVC:
6930 case llvm::Triple::UnknownEnvironment:
6931 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6932 .starts_with_insensitive(
"bfd"))
6933 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6937 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6941 case llvm::Triple::PS4:
6942 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6944 case llvm::Triple::PS5:
6945 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6947 case llvm::Triple::Hurd:
6948 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6950 case llvm::Triple::LiteOS:
6951 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6953 case llvm::Triple::ZOS:
6954 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6956 case llvm::Triple::Vulkan:
6957 case llvm::Triple::ShaderModel:
6958 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6963 switch (
Target.getArch()) {
6964 case llvm::Triple::tce:
6965 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6967 case llvm::Triple::tcele:
6968 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6970 case llvm::Triple::hexagon:
6971 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6974 case llvm::Triple::lanai:
6975 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6977 case llvm::Triple::xcore:
6978 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6980 case llvm::Triple::wasm32:
6981 case llvm::Triple::wasm64:
6982 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6984 case llvm::Triple::avr:
6985 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6987 case llvm::Triple::msp430:
6988 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6990 case llvm::Triple::riscv32:
6991 case llvm::Triple::riscv64:
6992 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6994 case llvm::Triple::ve:
6995 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6997 case llvm::Triple::spirv32:
6998 case llvm::Triple::spirv64:
6999 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7001 case llvm::Triple::csky:
7002 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7006 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7007 else if (
Target.isOSBinFormatELF())
7008 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7009 else if (
Target.isAppleMachO())
7010 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7011 else if (
Target.isOSBinFormatMachO())
7012 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7014 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7024 if (JA.
size() != 1 ||
7039 if (JA.
size() != 1 ||
7053 if (Args.hasArg(options::OPT_emit_static_lib))
7064 unsigned &Micro,
bool &HadExtra) {
7067 Major = Minor = Micro = 0;
7071 if (Str.consumeInteger(10, Major))
7075 if (!Str.consume_front(
"."))
7078 if (Str.consumeInteger(10, Minor))
7082 if (!Str.consume_front(
"."))
7085 if (Str.consumeInteger(10, Micro))
7103 unsigned CurDigit = 0;
7104 while (CurDigit < Digits.size()) {
7106 if (Str.consumeInteger(10, Digit))
7108 Digits[CurDigit] = Digit;
7111 if (!Str.consume_front(
"."))
7120llvm::opt::Visibility
7121Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7134const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7150 llvm_unreachable(
"Unhandled Mode");
7154 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7159 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7160 options::OPT_fno_save_optimization_record,
false))
7164 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7165 options::OPT_fno_save_optimization_record,
false))
7169 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7170 options::OPT_fno_save_optimization_record,
false))
7174 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7175 options::OPT_fno_save_optimization_record,
false))
7182 static StringRef OptName =
7184 llvm::StringRef Opt;
7185 for (StringRef Arg : Args) {
7186 if (!Arg.starts_with(OptName))
7192 return Opt.consume_front(OptName) ? Opt :
"";
7199 llvm::BumpPtrAllocator &Alloc,
7200 llvm::vfs::FileSystem *FS) {
7209 for (
const char *F : Args) {
7210 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7212 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7213 RSPQuoting = Windows;
7219 bool MarkEOLs = ClangCLMode;
7221 llvm::cl::TokenizerCallback Tokenizer;
7222 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7223 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7225 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7227 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7230 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7231 ECtx.setMarkEOLs(MarkEOLs);
7235 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7239 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7240 [](
const char *A) {
return A !=
nullptr; });
7241 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7244 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7245 Args.resize(newEnd - Args.begin());
7249 return llvm::Error::success();
7253 return SavedStrings.insert(S).first->getKeyData();
7287 llvm::StringSet<> &SavedStrings) {
7290 if (Edit[0] ==
'^') {
7291 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7292 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7293 Args.insert(Args.begin() + 1, Str);
7294 }
else if (Edit[0] ==
'+') {
7295 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7296 OS <<
"### Adding argument " << Str <<
" at end\n";
7297 Args.push_back(Str);
7298 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7299 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7300 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7301 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7302 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7304 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7306 if (Args[i] ==
nullptr)
7308 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7310 if (Repl != Args[i]) {
7311 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7315 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7316 auto Option = Edit.substr(1);
7317 for (
unsigned i = 1; i < Args.size();) {
7318 if (Option == Args[i]) {
7319 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7320 Args.erase(Args.begin() + i);
7321 if (Edit[0] ==
'X') {
7322 if (i < Args.size()) {
7323 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7324 Args.erase(Args.begin() + i);
7326 OS <<
"### Invalid X edit, end of command line!\n";
7331 }
else if (Edit[0] ==
'O') {
7332 for (
unsigned i = 1; i < Args.size();) {
7333 const char *A = Args[i];
7337 if (A[0] ==
'-' && A[1] ==
'O' &&
7338 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7339 (
'0' <= A[2] && A[2] <=
'9'))))) {
7340 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7341 Args.erase(Args.begin() + i);
7345 OS <<
"### Adding argument " << Edit <<
" at end\n";
7346 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7348 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7353 const char *OverrideStr,
7354 llvm::StringSet<> &SavedStrings,
7355 StringRef EnvVar, raw_ostream *OS) {
7357 OS = &llvm::nulls();
7359 if (OverrideStr[0] ==
'#') {
7361 OS = &llvm::nulls();
7364 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7368 const char *S = OverrideStr;
7370 const char *End = ::strchr(S,
' ');
7372 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static bool hasCXXModuleInputType(const Driver::InputList &Inputs)
static llvm::DenseSet< llvm::StringRef > inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
static const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static bool 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)
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static bool hasFlag(SVal val, ProgramStateRef state)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
static std::string GetResourcesPath(StringRef BinaryPath)
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
llvm::SmallVector< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
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.
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.
bool isCXX(ID Id)
isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
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.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
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.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
bool scanInputForCXX20ModulesUsage(StringRef Source)
Scan an input source buffer for C++20 named module usage.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
const FunctionProtoType * T
static bool IsNVIDIAOffloadArch(OffloadArch A)
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)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.