59#include "clang/Config/config.h"
75#include "llvm/ADT/ArrayRef.h"
76#include "llvm/ADT/STLExtras.h"
77#include "llvm/ADT/SmallSet.h"
78#include "llvm/ADT/SmallVector.h"
79#include "llvm/ADT/StringExtras.h"
80#include "llvm/ADT/StringRef.h"
81#include "llvm/ADT/StringSet.h"
82#include "llvm/ADT/StringSwitch.h"
83#include "llvm/Config/llvm-config.h"
84#include "llvm/MC/TargetRegistry.h"
85#include "llvm/Option/Arg.h"
86#include "llvm/Option/ArgList.h"
87#include "llvm/Option/OptSpecifier.h"
88#include "llvm/Option/OptTable.h"
89#include "llvm/Option/Option.h"
90#include "llvm/Support/CommandLine.h"
91#include "llvm/Support/ErrorHandling.h"
92#include "llvm/Support/ExitCodes.h"
93#include "llvm/Support/FileSystem.h"
94#include "llvm/Support/FileUtilities.h"
95#include "llvm/Support/FormatVariadic.h"
96#include "llvm/Support/IOSandbox.h"
97#include "llvm/Support/JSON.h"
98#include "llvm/Support/MD5.h"
99#include "llvm/Support/Path.h"
100#include "llvm/Support/PrettyStackTrace.h"
101#include "llvm/Support/Process.h"
102#include "llvm/Support/Program.h"
103#include "llvm/Support/Regex.h"
104#include "llvm/Support/StringSaver.h"
105#include "llvm/Support/VirtualFileSystem.h"
106#include "llvm/Support/raw_ostream.h"
107#include "llvm/TargetParser/Host.h"
108#include "llvm/TargetParser/RISCVISAInfo.h"
121using namespace clang;
124template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
125 return llvm::any_of(Args, [&](Arg *A) {
126 return (A->getOption().matches(options::OPT_x) &&
128 (A->getOption().
getKind() == Option::InputClass &&
129 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
131 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
137 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
138 StringRef UseCUIDStr = A->getValue();
139 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
140 .Case(
"hash", Kind::Hash)
141 .Case(
"random", Kind::Random)
142 .Case(
"none", Kind::None)
143 .Default(Kind::Invalid);
144 if (UseCUID == Kind::Invalid)
145 D.Diag(clang::diag::err_drv_invalid_value)
146 << A->getAsString(Args) << UseCUIDStr;
149 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
150 if (!FixedCUID.empty())
155 llvm::opt::DerivedArgList &Args)
const {
156 std::string CUID = FixedCUID.str();
159 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
163 llvm::MD5::MD5Result
Hash;
164 Hasher.update(InputFile);
165 for (
auto *A : Args) {
166 if (A->getOption().matches(options::OPT_INPUT))
168 Hasher.update(A->getAsString(Args));
171 CUID = llvm::utohexstr(
Hash.low(),
true);
179 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
180 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
187 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
188 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
189 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
192 this->VFS = llvm::vfs::getRealFileSystem();
197 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
200 llvm::sys::path::append(P,
SysRoot);
204#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
205 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
209 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
210 llvm::sys::path::remove_dots(configFileDir,
true);
214#if defined(CLANG_CONFIG_FILE_USER_DIR)
217 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
226void Driver::setDriverMode(StringRef
Value) {
227 static StringRef OptName =
228 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
229 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
230 .Case(
"gcc", GCCMode)
231 .Case(
"g++", GXXMode)
232 .Case(
"cpp", CPPMode)
234 .Case(
"flang", FlangMode)
235 .Case(
"dxc", DXCMode)
239 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
244 bool &ContainsError)
const {
245 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
246 ContainsError =
false;
248 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
249 unsigned MissingArgIndex, MissingArgCount;
250 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
251 MissingArgCount, VisibilityMask);
254 if (MissingArgCount) {
255 Diag(diag::err_drv_missing_argument)
256 << Args.getArgString(MissingArgIndex) << MissingArgCount;
258 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
263 for (
const Arg *A : Args) {
265 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
266 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
273 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
274 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
275 ContainsError |= Diags.getDiagnosticLevel(
276 diag::warn_drv_empty_joined_argument,
281 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
283 auto ArgString = A->getAsString(Args);
285 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
287 if (
getOpts().findExact(ArgString, Nearest,
289 DiagID = diag::err_drv_unknown_argument_with_suggestion;
290 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
292 DiagID = diag::err_drv_unknown_argument;
293 Diags.Report(DiagID) << ArgString;
296 llvm::opt::Visibility(
298 DiagID = diag::err_drv_unknown_argument_with_suggestion;
299 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
301 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
302 : diag::err_drv_unknown_argument;
303 Diags.Report(DiagID) << ArgString;
307 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
308 : diag::err_drv_unknown_argument_with_suggestion;
309 Diags.Report(DiagID) << ArgString << Nearest;
311 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
315 for (
const Arg *A : Args.filtered(options::OPT_o)) {
316 if (ArgStrings[A->getIndex()] == A->getSpelling())
320 std::string ArgString = ArgStrings[A->getIndex()];
322 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
323 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
324 << A->getAsString(Args) << Nearest;
334 Arg **FinalPhaseArg)
const {
335 Arg *PhaseArg =
nullptr;
339 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
340 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
341 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
342 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
349 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
351 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
352 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
353 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
354 options::OPT_fmodule_header_EQ))) {
357 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
360 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
361 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
375 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
378 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
386 *FinalPhaseArg = PhaseArg;
394 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
395 llvm::sys::fs::OF_Text);
396 llvm::FileRemover OutputRemover(OutputFile.c_str());
397 std::optional<llvm::StringRef> Redirects[] = {
403 std::string ErrorMessage;
404 int SecondsToWait = 60;
405 if (std::optional<std::string> Str =
406 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
407 if (!llvm::to_integer(*Str, SecondsToWait))
408 return llvm::createStringError(std::error_code(),
409 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
410 "an integer, got '" +
412 SecondsToWait = std::max(SecondsToWait, 0);
414 StringRef Executable = Args[0];
415 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
417 return llvm::createStringError(std::error_code(),
418 Executable +
": " + ErrorMessage);
420 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
421 llvm::MemoryBuffer::getFile(OutputFile.c_str());
423 return llvm::createStringError(OutputBuf.getError(),
424 "Failed to read stdout of " + Executable +
425 ": " + OutputBuf.getError().message());
426 return std::move(*OutputBuf);
430 StringRef
Value,
bool Claim) {
431 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
432 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
433 Args.AddSynthesizedArg(A);
439DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
440 const llvm::opt::OptTable &Opts =
getOpts();
441 DerivedArgList *DAL =
new DerivedArgList(Args);
443 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
444 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
445 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
446 bool IgnoreUnused =
false;
447 for (Arg *A : Args) {
451 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
455 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
456 IgnoreUnused =
false;
466 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
467 A->getOption().matches(options::OPT_Xlinker)) &&
468 A->containsValue(
"--no-demangle")) {
470 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
473 for (StringRef Val : A->getValues())
474 if (Val !=
"--no-demangle")
475 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
483 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
484 A->getNumValues() > 0 &&
485 (A->getValue(0) == StringRef(
"-MD") ||
486 A->getValue(0) == StringRef(
"-MMD"))) {
488 if (A->getValue(0) == StringRef(
"-MD"))
489 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
491 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
492 if (A->getNumValues() == 2)
493 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
498 if (A->getOption().matches(options::OPT_l)) {
499 StringRef
Value = A->getValue();
502 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
504 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
509 if (
Value ==
"cc_kext") {
510 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
516 if (A->getOption().matches(options::OPT__DASH_DASH)) {
518 for (StringRef Val : A->getValues())
527 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
528 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
531 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
532 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
536#if defined(HOST_LINK_VERSION)
537 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
538 strlen(HOST_LINK_VERSION) > 0) {
539 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
541 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
549 StringRef ArgTarget) {
551 static bool BeSilent =
false;
552 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
553 return ((v < 2) || ((v == 2) && (r < 4)));
557 if (ArgTarget.equals_insensitive(
"CURRENT")) {
561 unsigned int Version = 0;
562 unsigned int Release = 0;
563 unsigned int Modification = 0;
565 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
566 llvm::Regex HexRegex(
569 "([0-9a-fA-F][0-9a-fA-F])"
570 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
573 if (ZOsvRegex.match(ArgTarget, &Matches)) {
574 Matches[1].getAsInteger(10, Version);
575 Matches[2].getAsInteger(10, Release);
577 if (IsTooOldToBeSupported(Version, Release)) {
579 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
582 }
else if (HexRegex.match(ArgTarget, &Matches)) {
583 Matches[1].getAsInteger(16, Version);
584 Matches[2].getAsInteger(16, Release);
585 Matches[3].getAsInteger(16, Modification);
586 if (IsTooOldToBeSupported(Version, Release)) {
588 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
594 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
599 llvm::VersionTuple
V(Version, Release, Modification);
600 llvm::VersionTuple TV =
Target.getOSVersion();
603 if (TV.empty() ||
V < TV) {
605 Str = llvm::Triple::getOSTypeName(
Target.getOS());
606 Str +=
V.getAsString();
619 StringRef TargetTriple,
621 StringRef DarwinArchName =
"") {
623 if (
const Arg *A = Args.getLastArg(options::OPT_target))
624 TargetTriple = A->getValue();
626 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
631 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
635 if (
Target.isOSBinFormatMachO()) {
637 if (!DarwinArchName.empty()) {
644 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
645 StringRef ArchName = A->getValue();
652 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
653 options::OPT_mbig_endian)) {
654 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
655 ?
Target.getLittleEndianArchVariant()
656 :
Target.getBigEndianArchVariant();
657 if (T.getArch() != llvm::Triple::UnknownArch) {
659 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
664 if (
Target.getArch() == llvm::Triple::tce)
669 if (std::optional<std::string> ObjectModeValue =
670 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
671 StringRef ObjectMode = *ObjectModeValue;
672 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
674 if (ObjectMode ==
"64") {
675 AT =
Target.get64BitArchVariant().getArch();
676 }
else if (ObjectMode ==
"32") {
677 AT =
Target.get32BitArchVariant().getArch();
679 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
682 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
688 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
689 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
692 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
694 D.
Diag(diag::err_drv_unsupported_opt_for_target)
695 << A->getAsString(Args) <<
Target.str();
698 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
699 options::OPT_m32, options::OPT_m16,
700 options::OPT_maix32, options::OPT_maix64);
702 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
704 if (A->getOption().matches(options::OPT_m64) ||
705 A->getOption().matches(options::OPT_maix64)) {
706 AT =
Target.get64BitArchVariant().getArch();
707 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
708 Target.getEnvironment() == llvm::Triple::GNUT64)
709 Target.setEnvironment(llvm::Triple::GNU);
710 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
711 Target.setEnvironment(llvm::Triple::Musl);
712 }
else if (A->getOption().matches(options::OPT_mx32) &&
713 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
714 AT = llvm::Triple::x86_64;
715 if (
Target.getEnvironment() == llvm::Triple::Musl)
716 Target.setEnvironment(llvm::Triple::MuslX32);
718 Target.setEnvironment(llvm::Triple::GNUX32);
719 }
else if (A->getOption().matches(options::OPT_m32) ||
720 A->getOption().matches(options::OPT_maix32)) {
722 D.
Diag(diag::err_drv_unsupported_opt_for_target)
723 << A->getAsString(Args) <<
Target.str();
725 AT =
Target.get32BitArchVariant().getArch();
726 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
727 Target.setEnvironment(llvm::Triple::GNU);
728 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
729 Target.setEnvironment(llvm::Triple::Musl);
731 }
else if (A->getOption().matches(options::OPT_m16) &&
732 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
733 AT = llvm::Triple::x86;
734 Target.setEnvironment(llvm::Triple::CODE16);
737 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
739 if (
Target.isWindowsGNUEnvironment())
745 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
751 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
752 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
753 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
756 if (A && !A->getOption().matches(options::OPT_m32))
757 D.
Diag(diag::err_drv_argument_not_allowed_with)
758 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
760 Target.setArch(llvm::Triple::x86);
761 Target.setArchName(
"i586");
762 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
763 Target.setEnvironmentName(
"");
764 Target.setOS(llvm::Triple::ELFIAMCU);
765 Target.setVendor(llvm::Triple::UnknownVendor);
766 Target.setVendorName(
"intel");
772 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
773 StringRef ABIName = A->getValue();
774 if (ABIName ==
"32") {
776 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
777 Target.getEnvironment() == llvm::Triple::GNUABIN32)
778 Target.setEnvironment(llvm::Triple::GNU);
779 }
else if (ABIName ==
"n32") {
781 if (
Target.getEnvironment() == llvm::Triple::GNU ||
782 Target.getEnvironment() == llvm::Triple::GNUT64 ||
783 Target.getEnvironment() == llvm::Triple::GNUABI64)
784 Target.setEnvironment(llvm::Triple::GNUABIN32);
785 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
786 Target.getEnvironment() == llvm::Triple::MuslABI64)
787 Target.setEnvironment(llvm::Triple::MuslABIN32);
788 }
else if (ABIName ==
"64") {
790 if (
Target.getEnvironment() == llvm::Triple::GNU ||
791 Target.getEnvironment() == llvm::Triple::GNUT64 ||
792 Target.getEnvironment() == llvm::Triple::GNUABIN32)
793 Target.setEnvironment(llvm::Triple::GNUABI64);
794 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
795 Target.getEnvironment() == llvm::Triple::MuslABIN32)
796 Target.setEnvironment(llvm::Triple::MuslABI64);
804 if (Args.hasArg(options::OPT_march_EQ) ||
805 Args.hasArg(options::OPT_mcpu_EQ)) {
807 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
809 if (!llvm::errorToBool(ISAInfo.takeError())) {
810 unsigned XLen = (*ISAInfo)->getXLen();
812 if (
Target.isLittleEndian())
813 Target.setArch(llvm::Triple::riscv32);
815 Target.setArch(llvm::Triple::riscv32be);
816 }
else if (XLen == 64) {
817 if (
Target.isLittleEndian())
818 Target.setArch(llvm::Triple::riscv64);
820 Target.setArch(llvm::Triple::riscv64be);
826 if (
Target.getArch() == llvm::Triple::riscv32be ||
827 Target.getArch() == llvm::Triple::riscv64be) {
828 static bool WarnedRISCVBE =
false;
829 if (!WarnedRISCVBE) {
830 D.
Diag(diag::warn_drv_riscv_be_experimental);
831 WarnedRISCVBE =
true;
842 OptSpecifier OptEq, OptSpecifier OptNeg) {
843 if (!Args.hasFlag(OptEq, OptNeg,
false))
846 const Arg *A = Args.getLastArg(OptEq);
847 StringRef LTOName = A->getValue();
855 D.
Diag(diag::err_drv_unsupported_option_argument)
856 << A->getSpelling() << A->getValue();
863void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
865 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
867 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
868 options::OPT_fno_offload_lto);
871 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
872 options::OPT_fno_openmp_target_jit,
false)) {
873 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
874 options::OPT_fno_offload_lto))
876 Diag(diag::err_drv_incompatible_options)
877 << A->getSpelling() <<
"-fopenmp-target-jit";
884 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
886 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
888 RuntimeName = A->getValue();
890 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
898 Diag(diag::err_drv_unsupported_option_argument)
899 << A->getSpelling() << A->getValue();
902 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
911 StringRef Program =
C.getArgs().getLastArgValue(
912 options::OPT_offload_arch_tool_EQ,
"offload-arch");
915 if (llvm::ErrorOr<std::string> Executable =
916 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
919 Args.push_back(
"--only=amdgpu");
921 Args.push_back(
"--only=nvptx");
922 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
925 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
930 if ((*StdoutOrErr)->getBuffer().empty()) {
931 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
937 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
939 GPUArchs.push_back(
Arch.str());
941 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
948static llvm::DenseSet<llvm::StringRef>
950 std::set<std::string> Archs;
951 for (Arg *A :
C.getInputArgs()) {
952 for (StringRef
Arch : A->getValues()) {
953 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
954 if (
Arch ==
"native") {
956 Archs.insert(Str.str());
958 Archs.insert(
Arch.str());
960 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
964 Archs.erase(
Arch.str());
969 llvm::DenseSet<llvm::StringRef> Triples;
970 for (llvm::StringRef
Arch : Archs) {
977 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
979 return llvm::DenseSet<llvm::StringRef>();
982 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
984 return llvm::DenseSet<llvm::StringRef>();
988 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
990 return llvm::DenseSet<llvm::StringRef>();
993 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
994 <<
"offload" <<
Arch;
995 return llvm::DenseSet<llvm::StringRef>();
1000 Triple =
"spirv64-amd-amdhsa";
1002 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
1003 ?
"nvptx64-nvidia-cuda"
1004 :
"nvptx-nvidia-cuda";
1006 Triple =
"amdgcn-amd-amdhsa";
1013 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1014 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1015 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1016 C.getArgs().MakeArgString(Triple.split(
"-").first),
1017 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1019 C.getArgs().append(A);
1020 C.getArgs().AddSynthesizedArg(A);
1021 Triples.insert(Triple);
1026 Triples.insert(
"amdgcn-amd-amdhsa");
1028 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1029 ?
"nvptx64-nvidia-cuda"
1030 :
"nvptx-nvidia-cuda");
1032 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1033 ?
"spirv64-unknown-unknown"
1034 :
"spirv32-unknown-unknown");
1037 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1038 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1045 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1046 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1048 llvm::any_of(Inputs,
1049 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1054 (llvm::any_of(Inputs,
1055 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1058 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1059 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1061 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1062 options::OPT_fno_sycl,
false);
1063 bool IsOpenMPOffloading =
1065 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1066 options::OPT_fno_openmp,
false) &&
1067 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1068 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1069 !(IsCuda || IsHIP))));
1071 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1072 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1077 for (
const auto &[Active, Kind] : ActiveKinds)
1082 if (Kinds.size() > 1) {
1083 Diag(clang::diag::err_drv_mix_offload)
1090 if (IsCuda || IsHIP)
1096 std::multiset<llvm::StringRef> Triples;
1097 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1098 std::vector<std::string> ArgValues =
1099 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1100 for (llvm::StringRef
Target : ArgValues)
1101 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1103 if (ArgValues.empty())
1104 Diag(clang::diag::warn_drv_empty_joined_argument)
1106 .getLastArg(options::OPT_offload_targets_EQ)
1107 ->getAsString(
C.getInputArgs());
1108 }
else if (Kinds.size() > 0) {
1111 Triples.insert(Derived.begin(), Derived.end());
1116 llvm::StringMap<StringRef> FoundNormalizedTriples;
1117 for (StringRef
Target : Triples) {
1122 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1130 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1131 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1132 Diag(clang::diag::err_drv_argument_not_allowed_with)
1133 << IncompatArg->getSpelling() <<
"-fsycl";
1141 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1142 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1146 std::string NormalizedName = TT.normalize();
1147 auto [TripleIt, Inserted] =
1148 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1150 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1151 <<
Target << TripleIt->second;
1155 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1156 C.getDefaultToolChain().getTriple());
1160 auto &CudaInstallation =
1162 if (CudaInstallation.isValid())
1163 CudaInstallation.WarnIfUnsupportedVersion();
1166 C.addOffloadDeviceToolChain(&TC, Kind);
1171bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1176 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1180 if (!PathLIBEnv.empty()) {
1181 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1182 if (llvm::sys::fs::is_directory(PathLIBEnv))
1183 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1184 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1185 return readConfigFile(CustomizationFile, ExpCtx);
1186 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1191 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1192 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1193 return readConfigFile(CustomizationFile, ExpCtx);
1203 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1204 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1205 Copy->getValues() = Opt->getValues();
1206 if (Opt->isClaimed())
1208 Copy->setOwnsValues(Opt->getOwnsValues());
1209 Opt->setOwnsValues(
false);
1211 if (Opt->getAlias()) {
1212 const Arg *Alias = Opt->getAlias();
1213 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1214 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1215 Args.getArgString(Index), Index);
1216 AliasCopy->getValues() = Alias->getValues();
1217 AliasCopy->setOwnsValues(
false);
1218 if (Alias->isClaimed())
1220 Copy->setAlias(std::move(AliasCopy));
1224bool Driver::readConfigFile(StringRef
FileName,
1225 llvm::cl::ExpansionContext &ExpCtx) {
1229 Diag(diag::err_drv_cannot_open_config_file)
1230 <<
FileName << Status.getError().message();
1233 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1234 Diag(diag::err_drv_cannot_open_config_file)
1235 <<
FileName <<
"not a regular file";
1240 SmallVector<const char *, 32> NewCfgFileArgs;
1241 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1242 Diag(diag::err_drv_cannot_read_config_file)
1248 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1249 for (
const char *Opt : NewCfgFileArgs) {
1251 if (Opt[0] ==
'$' && Opt[1])
1252 NewCfgTailArgs.push_back(Opt + 1);
1254 NewCfgHeadArgs.push_back(Opt);
1258 llvm::SmallString<128> CfgFileName(
FileName);
1259 llvm::sys::path::native(CfgFileName);
1260 bool ContainErrors =
false;
1261 auto NewHeadOptions = std::make_unique<InputArgList>(
1265 auto NewTailOptions = std::make_unique<InputArgList>(
1272 for (Arg *A : *NewHeadOptions)
1274 for (Arg *A : *NewTailOptions)
1277 if (!CfgOptionsHead)
1278 CfgOptionsHead = std::move(NewHeadOptions);
1281 for (
auto *Opt : *NewHeadOptions)
1285 if (!CfgOptionsTail)
1286 CfgOptionsTail = std::move(NewTailOptions);
1289 for (
auto *Opt : *NewTailOptions)
1293 ConfigFiles.push_back(std::string(CfgFileName));
1297bool Driver::loadConfigFiles() {
1298 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1299 llvm::cl::tokenizeConfigFile, &
getVFS());
1303 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1304 SmallString<128> CfgDir;
1306 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1307 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1312 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1313 SmallString<128> CfgDir;
1314 llvm::sys::fs::expand_tilde(
1315 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1316 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1325 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1328 if (loadDefaultConfigFiles(ExpCtx))
1332 SmallString<128> CfgFilePath;
1334 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1337 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1338 CfgFilePath.assign(CfgFileName);
1339 if (llvm::sys::path::is_relative(CfgFilePath)) {
1340 if (
getVFS().makeAbsolute(CfgFilePath)) {
1341 Diag(diag::err_drv_cannot_open_config_file)
1342 << CfgFilePath <<
"cannot get absolute path";
1346 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1348 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1349 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1350 if (!SearchDir.empty())
1351 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1356 if (readConfigFile(CfgFilePath, ExpCtx))
1367 llvm::Triple Triple, std::string Suffix) {
1369 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1373 VersionTuple OSVersion = Triple.getOSVersion();
1374 if (!OSVersion.getMinor().has_value())
1377 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1381 if (OSVersion.getMajor() != 0) {
1382 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1383 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1389 Triple.setOSName(BaseOSName);
1390 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1393bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1396 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1400 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1403 std::string RealMode = getExecutableForDriverMode(Mode);
1404 llvm::Triple Triple;
1413 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1414 PrefixTriple.isOSUnknown())
1415 Triple = std::move(PrefixTriple);
1419 llvm::Triple RealTriple =
1421 if (Triple.str().empty()) {
1422 Triple = RealTriple;
1423 assert(!Triple.str().empty());
1428 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1442 SmallString<128> CfgFilePath;
1444 "-" + RealMode +
".cfg"))
1445 return readConfigFile(CfgFilePath, ExpCtx);
1449 if (TryModeSuffix) {
1452 return readConfigFile(CfgFilePath, ExpCtx);
1457 std::string CfgFileName = RealMode +
".cfg";
1458 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1459 if (readConfigFile(CfgFilePath, ExpCtx))
1461 }
else if (TryModeSuffix) {
1463 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1464 readConfigFile(CfgFilePath, ExpCtx))
1470 return readConfigFile(CfgFilePath, ExpCtx);
1478 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1487 if (!DriverMode.empty())
1488 setDriverMode(DriverMode);
1494 CLOptions = std::make_unique<InputArgList>(
1499 ContainsError = loadConfigFiles();
1500 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1501 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1505 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1507 if (HasConfigFileHead)
1508 for (
auto *Opt : *CLOptions)
1509 if (!Opt->getOption().matches(options::OPT_config))
1513 if (
IsCLMode() && !ContainsError) {
1515 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1517 CLModePassThroughArgList.push_back(A->getValue());
1520 if (!CLModePassThroughArgList.empty()) {
1523 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1528 for (
auto *Opt : *CLModePassThroughOptions)
1534 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1535 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1536 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1539 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1540 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1541 if (!VFS->exists(IncludeDir))
1542 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1547 bool CCCPrintPhases;
1550 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1551 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1554 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1555 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1558 Args.ClaimAllArgs(options::OPT_pipe);
1566 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1568 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1569 CCCGenericGCCName = A->getValue();
1572 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1576 if (Args.hasArg(options::OPT_fproc_stat_report))
1583 llvm::Triple T(TargetTriple);
1584 T.setOS(llvm::Triple::Win32);
1585 T.setVendor(llvm::Triple::PC);
1586 T.setEnvironment(llvm::Triple::MSVC);
1587 T.setObjectFormat(llvm::Triple::COFF);
1588 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1589 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1590 TargetTriple = T.str();
1593 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1594 StringRef TargetProfile = A->getValue();
1597 TargetTriple = *Triple;
1599 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1603 if (Args.hasArg(options::OPT_spirv)) {
1604 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1605 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1606 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1607 llvm::Triple T(TargetTriple);
1610 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1612 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1613 TargetInfo = ValidTargets.find(A->getValue());
1615 Diag(diag::err_drv_invalid_value)
1616 << A->getAsString(Args) << A->getValue();
1622 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1623 TargetTriple = T.str();
1627 Diag(diag::err_drv_dxc_missing_target_profile);
1631 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1632 TargetTriple = A->getValue();
1633 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1634 Dir =
Dir = A->getValue();
1635 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1639 if (std::optional<std::string> CompilerPathValue =
1640 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1641 StringRef CompilerPath = *CompilerPathValue;
1642 while (!CompilerPath.empty()) {
1643 std::pair<StringRef, StringRef> Split =
1644 CompilerPath.split(llvm::sys::EnvPathSeparator);
1645 PrefixDirs.push_back(std::string(Split.first));
1646 CompilerPath = Split.second;
1649 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1651 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1654 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1657 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1658 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1659 .Case(
"cwd", SaveTempsCwd)
1660 .Case(
"obj", SaveTempsObj)
1661 .Default(SaveTempsCwd);
1664 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1665 options::OPT_offload_device_only,
1666 options::OPT_offload_host_device)) {
1667 if (A->getOption().matches(options::OPT_offload_host_only))
1668 Offload = OffloadHost;
1669 else if (A->getOption().matches(options::OPT_offload_device_only))
1670 Offload = OffloadDevice;
1672 Offload = OffloadHostDevice;
1678 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1679 StringRef
Name = A->getValue();
1680 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1681 .Case(
"off", EmbedNone)
1682 .Case(
"all", EmbedBitcode)
1683 .Case(
"bitcode", EmbedBitcode)
1684 .Case(
"marker", EmbedMarker)
1687 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1690 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1694 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1695 llvm::sys::fs::remove(A->getValue());
1701 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1703 !Args.hasArg(options::OPT_fmodules) && Std &&
1704 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1705 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1706 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1707 Std->containsValue(
"c++latest"));
1710 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1711 options::OPT_fmodule_header)) {
1713 ModulesModeCXX20 =
true;
1714 if (A->getOption().matches(options::OPT_fmodule_header))
1717 StringRef ArgName = A->getValue();
1718 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1723 Diags.Report(diag::err_drv_invalid_value)
1724 << A->getAsString(Args) << ArgName;
1730 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1731 std::make_unique<InputArgList>(std::move(Args));
1741 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1742 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1744 bool MLContainsError;
1745 auto MultilibMacroDefineList =
1747 MLMacroDefinesChar,
false, MLContainsError));
1748 if (!MLContainsError) {
1749 for (
auto *Opt : *MultilibMacroDefineList) {
1756 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1760 if (!Triple.isWasm()) {
1761 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1762 StringRef TripleObjectFormat =
1763 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1764 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1765 TripleVersionName != TripleObjectFormat) {
1766 Diags.Report(diag::err_drv_triple_version_invalid)
1768 ContainsError =
true;
1773 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1774 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1775 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1783 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1784 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1786 case llvm::Triple::arm:
1787 case llvm::Triple::armeb:
1788 case llvm::Triple::thumb:
1789 case llvm::Triple::thumbeb:
1790 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1791 Diag(diag::warn_target_unrecognized_env)
1793 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1796 case llvm::Triple::aarch64:
1797 case llvm::Triple::aarch64_be:
1798 case llvm::Triple::aarch64_32:
1799 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1800 Diag(diag::warn_target_unrecognized_env)
1802 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1819 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1820 if (HasConfigFileTail && Inputs.size()) {
1823 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1824 for (Arg *A : *CfgOptionsTail)
1825 TranslatedLinkerIns.append(A);
1826 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1833 bool UseModulesDriver =
C->getArgs().hasFlag(
1834 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1836 if (UseModulesDriver) {
1837 Diags.Report(diag::remark_performing_driver_managed_module_build);
1843 const auto StdModuleManifestPath =
1846 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1847 Diags.Report(diag::remark_modules_manifest_not_found);
1849 Diags.Report(diag::remark_using_modules_manifest)
1850 << StdModuleManifestPath;
1851 if (
auto ManifestOrErr =
1853 ModulesManifest = std::move(*ManifestOrErr);
1855 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1856 return !ModuleEntry.IsStdlib;
1861 llvm::handleAllErrors(
1862 ManifestOrErr.takeError(),
1863 [&](llvm::json::ParseError &Err) {
1864 Diags.Report(diag::err_modules_manifest_failed_parse)
1867 [&](llvm::FileError &Err) {
1868 Diags.Report(diag::err_cannot_open_file)
1869 << Err.getFileName() << Err.messageWithoutFileInfo();
1877 if (TC.
getTriple().isOSBinFormatMachO())
1882 if (CCCPrintPhases) {
1889 if (UseModulesDriver)
1896 llvm::opt::ArgStringList ASL;
1897 for (
const auto *A : Args) {
1901 while (A->getAlias())
1903 A->render(Args, ASL);
1906 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1907 if (I != ASL.begin())
1909 llvm::sys::printArg(OS, *I,
true);
1914bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1915 SmallString<128> &CrashDiagDir) {
1916 using namespace llvm::sys;
1917 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1918 "Only knows about .crash files on Darwin");
1920 auto BypassSandbox = sandbox::scopedDisable();
1925 path::home_directory(CrashDiagDir);
1926 if (CrashDiagDir.starts_with(
"/var/root"))
1928 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1936 fs::file_status FileStatus;
1937 TimePoint<> LastAccessTime;
1938 SmallString<128> CrashFilePath;
1941 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1942 File != FileEnd && !EC;
File.increment(EC)) {
1946 if (fs::status(
File->path(), FileStatus))
1948 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1949 llvm::MemoryBuffer::getFile(
File->path());
1954 StringRef
Data = CrashFile.get()->getBuffer();
1955 if (!
Data.starts_with(
"Process:"))
1958 size_t ParentProcPos =
Data.find(
"Parent Process:");
1959 if (ParentProcPos == StringRef::npos)
1961 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1962 if (LineEnd == StringRef::npos)
1964 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1965 int OpenBracket = -1, CloseBracket = -1;
1966 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1967 if (ParentProcess[i] ==
'[')
1969 if (ParentProcess[i] ==
']')
1975 if (OpenBracket < 0 || CloseBracket < 0 ||
1976 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1977 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1987 const auto FileAccessTime = FileStatus.getLastModificationTime();
1988 if (FileAccessTime > LastAccessTime) {
1989 CrashFilePath.assign(
File->path());
1990 LastAccessTime = FileAccessTime;
1995 if (!CrashFilePath.empty()) {
1996 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2006 "\n********************\n\n"
2007 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2008 "Preprocessed source(s) and associated run script(s) are located at:";
2016 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2020 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2021 Level = llvm::StringSwitch<unsigned>(A->getValue())
2023 .Case(
"compiler", 1)
2035 ArgStringList SavedTemps;
2037 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2038 if (!IsLLD || Level < 2)
2045 SavedTemps = std::move(
C.getTempFiles());
2046 assert(!
C.getTempFiles().size());
2063 C.initCompilationForDiagnostics();
2068 Command NewLLDInvocation = Cmd;
2069 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2070 StringRef ReproduceOption =
2071 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2074 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2078 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2080 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2081 Diag(clang::diag::note_drv_command_failed_diag_msg)
2082 <<
"\n\n********************";
2084 Report->TemporaryFiles.push_back(TmpName);
2092 ArgStringList IRInputs;
2093 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2094 bool IgnoreInput =
false;
2100 IRInputs.push_back(it->second->getValue());
2104 }
else if (!strcmp(it->second->getValue(),
"-")) {
2105 Diag(clang::diag::note_drv_command_failed_diag_msg)
2106 <<
"Error generating preprocessed source(s) - "
2107 "ignoring input from stdin.";
2112 it = Inputs.erase(it);
2119 if (Inputs.empty() && IRInputs.empty()) {
2120 Diag(clang::diag::note_drv_command_failed_diag_msg)
2121 <<
"Error generating preprocessed source(s) - "
2122 "no preprocessable inputs.";
2129 for (
const Arg *A :
C.getArgs()) {
2130 if (A->getOption().matches(options::OPT_arch)) {
2131 StringRef ArchName = A->getValue();
2136 Diag(clang::diag::note_drv_command_failed_diag_msg)
2137 <<
"Error generating preprocessed source(s) - cannot generate "
2138 "preprocessed source with multiple -arch options.";
2143 if (!Inputs.empty()) {
2146 const ToolChain &TC =
C.getDefaultToolChain();
2147 if (TC.
getTriple().isOSBinFormatMachO())
2156 Diag(clang::diag::note_drv_command_failed_diag_msg)
2157 <<
"Error generating preprocessed source(s).";
2162 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2165 if (!FailingCommands.empty()) {
2166 Diag(clang::diag::note_drv_command_failed_diag_msg)
2167 <<
"Error generating preprocessed source(s).";
2171 const ArgStringList &TempFiles =
C.getTempFiles();
2172 if (TempFiles.empty()) {
2173 Diag(clang::diag::note_drv_command_failed_diag_msg)
2174 <<
"Error generating preprocessed source(s).";
2180 const ArgStringList &Files =
C.getTempFiles();
2185 for (
auto const *Input : IRInputs) {
2189 StringRef extension = llvm::sys::path::extension(Input);
2190 if (!extension.empty())
2191 extension = extension.drop_front();
2193 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2194 llvm::sys::path::stem(Input), extension, FD, Path);
2196 Diag(clang::diag::note_drv_command_failed_diag_msg)
2197 <<
"Error generating run script: " <<
"Failed copying IR input files"
2198 <<
" " << EC.message();
2202 EC = llvm::sys::fs::copy_file(Input, FD);
2204 Diag(clang::diag::note_drv_command_failed_diag_msg)
2205 <<
"Error generating run script: " <<
"Failed copying IR input files"
2206 <<
" " << EC.message();
2210 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2217 for (std::string &TempFile : TempFiles) {
2218 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2220 Report->TemporaryFiles.push_back(TempFile);
2221 if (ReproCrashFilename.empty()) {
2222 ReproCrashFilename = TempFile;
2223 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2225 if (StringRef(TempFile).ends_with(
".cache")) {
2228 VFS = llvm::sys::path::filename(TempFile);
2229 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2233 for (
const char *TempFile : SavedTemps)
2234 TempFiles.push_back(TempFile);
2240 llvm::sys::path::replace_extension(Script,
"sh");
2242 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2243 llvm::sys::fs::FA_Write,
2244 llvm::sys::fs::OF_Text);
2246 Diag(clang::diag::note_drv_command_failed_diag_msg)
2247 <<
"Error generating run script: " << Script <<
" " << EC.message();
2250 <<
"# Driver args: ";
2252 ScriptOS <<
"# Original command: ";
2253 Cmd.
Print(ScriptOS,
"\n",
true);
2254 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2255 if (!AdditionalInformation.empty())
2256 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2259 Report->TemporaryFiles.push_back(std::string(Script));
2260 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2264 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2266 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2267 Diag(clang::diag::note_drv_command_failed_diag_msg)
2268 << ReproCrashFilename.str();
2270 llvm::sys::path::append(CrashDiagDir,
Name);
2271 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2272 Diag(clang::diag::note_drv_command_failed_diag_msg)
2273 <<
"Crash backtrace is located in";
2274 Diag(clang::diag::note_drv_command_failed_diag_msg)
2275 << CrashDiagDir.str();
2276 Diag(clang::diag::note_drv_command_failed_diag_msg)
2277 <<
"(choose the .crash file that corresponds to your crash)";
2281 Diag(clang::diag::note_drv_command_failed_diag_msg)
2282 <<
"\n\n********************";
2292 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2303 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2304 if (
C.getArgs().hasArg(options::OPT_v))
2305 C.getJobs().Print(llvm::errs(),
"\n",
true);
2307 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2310 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2317 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2318 C.getJobs().Print(llvm::errs(),
"\n",
true);
2319 return Diags.hasErrorOccurred() ? 1 : 0;
2323 if (Diags.hasErrorOccurred())
2327 for (
auto &Job :
C.getJobs())
2328 setUpResponseFiles(
C, Job);
2330 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2333 if (FailingCommands.empty())
2339 for (
const auto &CmdPair : FailingCommands) {
2340 int CommandRes = CmdPair.first;
2341 const Command *FailingCommand = CmdPair.second;
2346 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2350 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2355 if (CommandRes == EX_IOERR) {
2375 if (CommandRes > 128 && CommandRes != 255)
2379 Diag(clang::diag::err_drv_command_signalled)
2382 Diag(clang::diag::err_drv_command_failed)
2390 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2392 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2406 const ToolChain &TC =
C.getDefaultToolChain();
2410 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2413 OS <<
"Thread model: " << A->getValue();
2419 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2424 if (!llvm::cl::getCompilerBuildConfig().empty())
2425 llvm::cl::printBuildConfig(OS);
2428 for (
auto ConfigFile : ConfigFiles)
2429 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2442 if (PassedFlags ==
"")
2446 std::vector<std::string> SuggestedCompletions;
2447 std::vector<std::string> Flags;
2459 const bool HasSpace = PassedFlags.ends_with(
",");
2463 StringRef TargetFlags = PassedFlags;
2464 while (TargetFlags !=
"") {
2466 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2467 Flags.push_back(std::string(CurFlag));
2472 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2475 const llvm::opt::OptTable &Opts =
getOpts();
2477 Cur = Flags.at(Flags.size() - 1);
2479 if (Flags.size() >= 2) {
2480 Prev = Flags.at(Flags.size() - 2);
2481 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2484 if (SuggestedCompletions.empty())
2485 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2492 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2493 llvm::outs() <<
'\n';
2499 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2503 SuggestedCompletions = Opts.findByPrefix(
2504 Cur, VisibilityMask,
2511 if (S.starts_with(Cur))
2512 SuggestedCompletions.push_back(std::string(S));
2519 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2520 if (
int X = A.compare_insensitive(B))
2522 return A.compare(B) > 0;
2525 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2532 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2533 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2537 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2540 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2544 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2549 if (
C.getArgs().hasArg(options::OPT_help) ||
2550 C.getArgs().hasArg(options::OPT__help_hidden)) {
2551 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2555 if (
C.getArgs().hasArg(options::OPT__version)) {
2562 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2563 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2564 if (ListExtractors || ListFormats) {
2572 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2577 if (
C.getArgs().hasArg(options::OPT_v) ||
2578 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2579 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2580 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2581 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2583 SuppressMissingInputWarning =
true;
2586 if (
C.getArgs().hasArg(options::OPT_v)) {
2588 llvm::errs() <<
"System configuration file directory: "
2591 llvm::errs() <<
"User configuration file directory: "
2595 const ToolChain &TC =
C.getDefaultToolChain();
2597 if (
C.getArgs().hasArg(options::OPT_v))
2600 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2605 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2606 llvm::outs() <<
"programs: =";
2607 bool separator =
false;
2611 llvm::outs() << llvm::sys::EnvPathSeparator;
2612 llvm::outs() << Path;
2617 llvm::outs() << llvm::sys::EnvPathSeparator;
2618 llvm::outs() << Path;
2621 llvm::outs() <<
"\n";
2624 StringRef sysroot =
C.getSysRoot();
2628 llvm::outs() << llvm::sys::EnvPathSeparator;
2631 llvm::outs() << sysroot << Path.substr(1);
2633 llvm::outs() << Path;
2635 llvm::outs() <<
"\n";
2639 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2645 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2646 for (
auto RuntimePath :
2648 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2649 llvm::outs() << *RuntimePath <<
'\n';
2653 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2657 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2659 for (std::size_t I = 0; I != Flags.size(); I += 2)
2660 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2666 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2667 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2671 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2672 StringRef ProgName = A->getValue();
2675 if (! ProgName.empty())
2678 llvm::outs() <<
"\n";
2682 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2683 StringRef PassedFlags = A->getValue();
2688 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2702 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2705 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2711 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2718 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2721 std::set<llvm::StringRef> SortedFlags;
2722 for (
const auto &FlagEntry : ExpandedFlags)
2723 SortedFlags.insert(FlagEntry.getKey());
2724 for (
auto Flag : SortedFlags)
2725 llvm::outs() << Flag <<
'\n';
2729 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2732 llvm::outs() <<
".\n";
2735 assert(Suffix.front() ==
'/');
2736 llvm::outs() << Suffix.substr(1) <<
"\n";
2742 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2747 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2749 llvm::outs() << Triple.getTriple() <<
"\n";
2753 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2754 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2771 std::map<Action *, unsigned> &Ids,
2773 if (
auto It = Ids.find(A); It != Ids.end())
2777 llvm::raw_string_ostream os(str);
2779 auto getSibIndent = [](
int K) -> Twine {
2783 Twine SibIndent =
Indent + getSibIndent(Kind);
2787 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2789 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2790 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2791 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2793 OA->doOnEachDependence(
2795 assert(TC &&
"Unknown host toolchain");
2807 os <<
":" << BoundArch;
2810 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2818 const char *Prefix =
"{";
2819 for (
Action *PreRequisite : *AL) {
2820 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2831 std::string offload_str;
2832 llvm::raw_string_ostream offload_os(offload_str);
2836 offload_os <<
", (" << S;
2843 auto getSelfIndent = [](
int K) -> Twine {
2847 unsigned Id = Ids.size();
2849 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2858 std::map<Action *, unsigned> Ids;
2859 for (
Action *A :
C.getActions())
2875 DerivedArgList &Args =
C.getArgs();
2877 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2882 for (Arg *A : Args) {
2883 if (A->getOption().matches(options::OPT_arch)) {
2886 llvm::Triple::ArchType
Arch =
2888 if (
Arch == llvm::Triple::UnknownArch) {
2889 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2894 if (
ArchNames.insert(A->getValue()).second)
2895 Archs.push_back(A->getValue());
2909 for (
Action* Act : SingleActions) {
2917 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2921 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2926 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2927 Actions.append(Inputs.begin(), Inputs.end());
2929 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2932 Arg *A = Args.getLastArg(options::OPT_g_Group);
2933 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2934 !A->getOption().matches(options::OPT_gstabs);
2942 if (Act->getType() == types::TY_Image) {
2944 Inputs.push_back(Actions.back());
2951 if (Args.hasArg(options::OPT_verify_debug_info)) {
2952 Action *LastAction = Actions.pop_back_val();
2954 LastAction, types::TY_Nothing));
2961 bool TypoCorrect)
const {
2973 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2974 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2986 std::string Nearest;
2987 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2988 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2989 <<
Value << Nearest;
3028 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3031 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3039 return types::TY_CXXUHeader;
3041 return types::TY_CXXSHeader;
3045 llvm_unreachable(
"should not be called in this case");
3047 return types::TY_CXXHUHeader;
3053 const llvm::opt::OptTable &Opts =
getOpts();
3057 types::ID InputType = types::TY_Nothing;
3058 Arg *InputTypeArg =
nullptr;
3061 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3062 options::OPT__SLASH_TP)) {
3063 InputTypeArg = TCTP;
3064 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3069 bool ShowNote =
false;
3071 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3073 Diag(clang::diag::warn_drv_overriding_option)
3074 <<
Previous->getSpelling() << A->getSpelling();
3080 Diag(clang::diag::note_drv_t_option_is_global);
3085 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3086 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3087 if (LastXArg && LastInputArg &&
3088 LastInputArg->getIndex() < LastXArg->getIndex())
3089 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3092 for (Arg *A : Args) {
3093 if (A->getOption().
getKind() == Option::InputClass) {
3094 const char *
Value = A->getValue();
3098 if (InputType == types::TY_Nothing) {
3101 InputTypeArg->claim();
3104 if (strcmp(
Value,
"-") == 0) {
3106 Ty = types::TY_Fortran;
3108 Ty = types::TY_HLSL;
3117 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3118 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3119 : clang::diag::err_drv_unknown_stdin_type);
3128 if (
const char *Ext = strrchr(
Value,
'.'))
3137 Ty = types::TY_HLSL;
3139 Ty = types::TY_Object;
3150 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3151 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3152 << getTypeName(OldTy) << getTypeName(Ty);
3157 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3158 Ty == types::TY_Object)
3159 Ty = types::TY_LLVM_BC;
3167 if (Ty != types::TY_Object) {
3168 if (Args.hasArg(options::OPT_ObjC))
3169 Ty = types::TY_ObjC;
3170 else if (Args.hasArg(options::OPT_ObjCXX))
3171 Ty = types::TY_ObjCXX;
3178 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3182 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3183 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3186 const char *Ext = strrchr(
Value,
'.');
3188 Ty = types::TY_Object;
3192 InputTypeArg->claim();
3196 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3197 Args.hasArgNoClaim(options::OPT_hipstdpar))
3201 Inputs.push_back(std::make_pair(Ty, A));
3203 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3204 StringRef
Value = A->getValue();
3207 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3208 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3211 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3212 StringRef
Value = A->getValue();
3215 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3216 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3222 Inputs.push_back(std::make_pair(types::TY_Object, A));
3224 }
else if (A->getOption().matches(options::OPT_x)) {
3233 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3234 InputType = types::TY_Object;
3241 }
else if (A->getOption().getID() == options::OPT_U) {
3242 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3243 StringRef Val = A->getValue(0);
3244 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3246 Diag(diag::warn_slash_u_filename) << Val;
3247 Diag(diag::note_use_dashdash);
3251 if (
CCCIsCPP() && Inputs.empty()) {
3255 Inputs.push_back(std::make_pair(types::TY_C, A));
3262class OffloadingActionBuilder final {
3264 bool IsValid =
false;
3270 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3273 std::map<Action *, const Arg *> HostActionToInputArgMap;
3276 class DeviceActionBuilder {
3280 enum ActionBuilderReturnCode {
3299 DerivedArgList &Args;
3308 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3311 :
C(
C), Args(Args), Inputs(Inputs),
3312 AssociatedOffloadKind(AssociatedOffloadKind) {}
3313 virtual ~DeviceActionBuilder() {}
3318 virtual ActionBuilderReturnCode
3319 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3322 return ABRT_Inactive;
3327 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3328 return ABRT_Inactive;
3332 virtual void appendTopLevelActions(
ActionList &AL) {}
3335 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3338 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3341 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3348 virtual bool canUseBundlerUnbundler()
const {
return false; }
3352 bool isValid() {
return !ToolChains.empty(); }
3356 return AssociatedOffloadKind;
3362 class CudaActionBuilderBase :
public DeviceActionBuilder {
3366 bool CompileHostOnly =
false;
3367 bool CompileDeviceOnly =
false;
3369 bool EmitAsm =
false;
3379 TargetID(
const char *ID) :
ID(
ID) {}
3380 operator const char *() {
return ID; }
3381 operator StringRef() {
return StringRef(ID); }
3384 SmallVector<TargetID, 4> GpuArchList;
3390 Action *CudaFatBinary =
nullptr;
3393 bool IsActive =
false;
3396 bool Relocatable =
false;
3399 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3402 const CUIDOptions &CUIDOpts;
3405 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3407 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3408 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3410 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3411 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3412 options::OPT_fno_gpu_rdc,
false);
3415 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3422 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3425 if (!(IA->getType() == types::TY_CUDA ||
3426 IA->getType() == types::TY_HIP ||
3427 IA->getType() == types::TY_PP_HIP)) {
3430 return ABRT_Inactive;
3437 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3439 if (CompileHostOnly)
3440 return ABRT_Success;
3443 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3444 : types::TY_CUDA_DEVICE;
3445 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3446 CudaDeviceActions.push_back(
3447 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3450 return ABRT_Success;
3454 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3458 if (UA->getType() == types::TY_Object && !Relocatable)
3459 return ABRT_Inactive;
3461 CudaDeviceActions.clear();
3463 std::string
FileName = IA->getInputArg().getAsString(Args);
3469 const StringRef LibFileExt =
".lib";
3470 if (IA->getType() == types::TY_Object &&
3471 (!llvm::sys::path::has_extension(
FileName) ||
3473 llvm::sys::path::extension(
FileName).drop_front()) !=
3475 llvm::sys::path::extension(
FileName) == LibFileExt))
3476 return ABRT_Inactive;
3478 for (
auto Arch : GpuArchList) {
3479 CudaDeviceActions.push_back(UA);
3480 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3481 AssociatedOffloadKind);
3484 return ABRT_Success;
3487 return IsActive ? ABRT_Success : ABRT_Inactive;
3490 void appendTopLevelActions(
ActionList &AL)
override {
3492 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3493 OffloadAction::DeviceDependences Dep;
3494 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3495 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3499 if (CudaFatBinary) {
3500 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3501 CudaDeviceActions.clear();
3502 CudaFatBinary =
nullptr;
3506 if (CudaDeviceActions.empty())
3512 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3513 "Expecting one action per GPU architecture.");
3514 assert(ToolChains.size() == 1 &&
3515 "Expecting to have a single CUDA toolchain.");
3516 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3517 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3519 CudaDeviceActions.clear();
3522 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3540 assert(HostTC &&
"No toolchain for host compilation.");
3545 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3550 std::set<StringRef> GpuArchs;
3552 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3553 ToolChains.push_back(I.second);
3556 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3557 GpuArchs.insert(
Arch);
3561 for (
auto Arch : GpuArchs)
3562 GpuArchList.push_back(
Arch.data());
3564 CompileHostOnly =
C.getDriver().offloadHostOnly();
3565 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3566 EmitAsm = Args.getLastArg(options::OPT_S);
3574 class CudaActionBuilder final :
public CudaActionBuilderBase {
3576 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3578 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3579 DefaultOffloadArch = OffloadArch::CudaDefault;
3582 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3584 const std::set<StringRef> &GpuArchs)
override {
3585 return std::nullopt;
3588 ActionBuilderReturnCode
3589 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3591 PhasesTy &Phases)
override {
3593 return ABRT_Inactive;
3597 if (CudaDeviceActions.empty())
3598 return ABRT_Success;
3600 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3601 "Expecting one action per GPU architecture.");
3602 assert(!CompileHostOnly &&
3603 "Not expecting CUDA actions in host-only compilation.");
3613 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3616 for (
auto Ph : Phases) {
3621 if (Ph > FinalPhase)
3624 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3638 Action *AssembleAction = CudaDeviceActions[I];
3639 assert(AssembleAction->
getType() == types::TY_Object);
3640 assert(AssembleAction->
getInputs().size() == 1);
3646 OffloadAction::DeviceDependences DDep;
3648 DeviceActions.push_back(
3649 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3654 if (!DeviceActions.empty()) {
3656 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3658 if (!CompileDeviceOnly) {
3659 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3663 CudaFatBinary =
nullptr;
3668 CudaDeviceActions.clear();
3672 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3677 return ABRT_Success;
3681 "instructions should only occur "
3682 "before the backend phase!");
3685 for (Action *&A : CudaDeviceActions)
3686 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3688 return ABRT_Success;
3693 class HIPActionBuilder final :
public CudaActionBuilderBase {
3695 SmallVector<ActionList, 8> DeviceLinkerInputs;
3701 std::optional<bool> BundleOutput;
3702 std::optional<bool> EmitReloc;
3705 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3707 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3709 DefaultOffloadArch = OffloadArch::HIPDefault;
3711 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3712 options::OPT_fno_hip_emit_relocatable)) {
3713 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3714 options::OPT_fno_hip_emit_relocatable, false);
3718 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3719 <<
"-fhip-emit-relocatable"
3723 if (!CompileDeviceOnly) {
3724 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3725 <<
"-fhip-emit-relocatable"
3726 <<
"--offload-device-only";
3731 if (Args.hasArg(options::OPT_gpu_bundle_output,
3732 options::OPT_no_gpu_bundle_output))
3733 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3734 options::OPT_no_gpu_bundle_output,
true) &&
3735 (!EmitReloc || !*EmitReloc);
3738 bool canUseBundlerUnbundler()
const override {
return true; }
3740 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3742 const std::set<StringRef> &GpuArchs)
override {
3746 ActionBuilderReturnCode
3747 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3749 PhasesTy &Phases)
override {
3751 return ABRT_Inactive;
3757 if (CudaDeviceActions.empty())
3758 return ABRT_Success;
3761 CudaDeviceActions.size() == GpuArchList.size()) &&
3762 "Expecting one action per GPU architecture.");
3763 assert(!CompileHostOnly &&
3764 "Not expecting HIP actions in host-only compilation.");
3766 bool ShouldLink = !EmitReloc || !*EmitReloc;
3769 !EmitAsm && ShouldLink) {
3775 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3776 if (
C.getDriver().isUsingOffloadLTO()) {
3780 AL.push_back(CudaDeviceActions[I]);
3783 CudaDeviceActions[I] =
3784 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3790 if (ToolChains.front()->getTriple().isSPIRV() ||
3791 (ToolChains.front()->getTriple().isAMDGCN() &&
3792 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3796 types::ID Output = Args.hasArg(options::OPT_S)
3798 : types::TY_LLVM_BC;
3800 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3804 AssociatedOffloadKind);
3805 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3807 AssociatedOffloadKind);
3808 AL.push_back(AssembleAction);
3811 CudaDeviceActions[I] =
3812 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3821 OffloadAction::DeviceDependences DDep;
3822 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3823 AssociatedOffloadKind);
3824 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3825 DDep, CudaDeviceActions[I]->getType());
3828 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3830 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3831 types::TY_HIP_FATBIN);
3833 if (!CompileDeviceOnly) {
3834 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3835 AssociatedOffloadKind);
3838 CudaFatBinary =
nullptr;
3843 CudaDeviceActions.clear();
3846 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3849 return ABRT_Success;
3855 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3856 auto LI = DeviceLinkerInputs.begin();
3857 for (
auto *A : CudaDeviceActions) {
3864 CudaDeviceActions.clear();
3865 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3869 for (Action *&A : CudaDeviceActions)
3870 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3871 AssociatedOffloadKind);
3873 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3875 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3876 OffloadAction::DeviceDependences DDep;
3877 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3878 AssociatedOffloadKind);
3879 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3880 DDep, CudaDeviceActions[I]->getType());
3883 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3884 CudaDeviceActions.clear();
3887 return (CompileDeviceOnly &&
3888 (CurPhase == FinalPhase ||
3894 void appendLinkDeviceActions(
ActionList &AL)
override {
3895 if (DeviceLinkerInputs.size() == 0)
3898 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3899 "Linker inputs and GPU arch list sizes do not match.");
3905 for (
auto &LI : DeviceLinkerInputs) {
3907 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3911 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3914 OffloadAction::DeviceDependences DeviceLinkDeps;
3915 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3916 GpuArchList[I], AssociatedOffloadKind);
3917 Actions.push_back(
C.MakeAction<OffloadAction>(
3918 DeviceLinkDeps, DeviceLinkAction->getType()));
3921 DeviceLinkerInputs.clear();
3924 if (Args.hasArg(options::OPT_emit_llvm)) {
3932 OffloadAction::DeviceDependences DDeps;
3933 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3934 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3936 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3937 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3938 AssociatedOffloadKind);
3941 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3947 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3949 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3957 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3963 bool ShouldUseBundler;
3966 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3974 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3977 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3985 unsigned ValidBuilders = 0u;
3986 unsigned ValidBuildersSupportingBundling = 0u;
3987 for (
auto *SB : SpecializedBuilders) {
3988 IsValid = IsValid && !SB->initialize();
3991 if (SB->isValid()) {
3993 if (SB->canUseBundlerUnbundler())
3994 ++ValidBuildersSupportingBundling;
3998 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4000 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4001 options::OPT_no_gpu_bundle_output,
true);
4004 ~OffloadingActionBuilder() {
4005 for (
auto *SB : SpecializedBuilders)
4010 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4011 assert(HostAction &&
"Invalid host action");
4012 assert(InputArg &&
"Invalid input argument");
4013 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4014 assert(Loc->second == InputArg &&
4015 "host action mapped to multiple input arguments");
4024 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4026 DeviceActionBuilder::PhasesTy &Phases) {
4030 if (SpecializedBuilders.empty())
4033 assert(HostAction &&
"Invalid host action!");
4034 recordHostAction(HostAction, InputArg);
4039 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4040 unsigned InactiveBuilders = 0u;
4041 unsigned IgnoringBuilders = 0u;
4042 for (
auto *SB : SpecializedBuilders) {
4043 if (!SB->isValid()) {
4048 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4053 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4058 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4059 OffloadKind |= SB->getAssociatedOffloadKind();
4064 if (IgnoringBuilders &&
4065 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4082 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4083 const Arg *InputArg) {
4087 recordHostAction(HostAction, InputArg);
4096 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4098 HostAction->
getType() == types::TY_PP_HIP)) {
4099 auto UnbundlingHostAction =
4104 HostAction = UnbundlingHostAction;
4105 recordHostAction(HostAction, InputArg);
4108 assert(HostAction &&
"Invalid host action!");
4111 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4112 for (
auto *SB : SpecializedBuilders) {
4116 auto RetCode = SB->addDeviceDependences(HostAction);
4120 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4121 "Host dependence not expected to be ignored.!");
4125 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4126 OffloadKind |= SB->getAssociatedOffloadKind();
4131 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4141 const Arg *InputArg) {
4143 recordHostAction(HostAction, InputArg);
4147 for (
auto *SB : SpecializedBuilders) {
4150 SB->appendTopLevelActions(OffloadAL);
4157 if (CanUseBundler && ShouldUseBundler && HostAction &&
4158 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4160 OffloadAL.push_back(HostAction);
4164 assert(HostAction == AL.back() &&
"Host action not in the list??");
4166 recordHostAction(HostAction, InputArg);
4167 AL.back() = HostAction;
4169 AL.append(OffloadAL.begin(), OffloadAL.end());
4179 void appendDeviceLinkActions(
ActionList &AL) {
4180 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4183 SB->appendLinkDeviceActions(AL);
4187 Action *makeHostLinkAction() {
4190 appendDeviceLinkActions(DeviceAL);
4191 if (DeviceAL.empty())
4196 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4199 HA = SB->appendLinkHostActions(DeviceAL);
4216 for (
auto *SB : SpecializedBuilders) {
4220 SB->appendLinkDependences(DDeps);
4224 unsigned ActiveOffloadKinds = 0u;
4225 for (
auto &I : InputArgToOffloadKindMap)
4226 ActiveOffloadKinds |= I.second;
4238 for (
auto *A : HostAction->
inputs()) {
4239 auto ArgLoc = HostActionToInputArgMap.find(A);
4240 if (ArgLoc == HostActionToInputArgMap.end())
4242 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4243 if (OFKLoc == InputArgToOffloadKindMap.end())
4255 nullptr, ActiveOffloadKinds);
4261void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4266 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4267 StringRef
V = A->getValue();
4268 if (Inputs.size() > 1 && !
V.empty() &&
4269 !llvm::sys::path::is_separator(
V.back())) {
4271 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4272 << A->getSpelling() <<
V;
4273 Args.eraseArg(options::OPT__SLASH_Fo);
4278 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4279 StringRef
V = A->getValue();
4280 if (Inputs.size() > 1 && !
V.empty() &&
4281 !llvm::sys::path::is_separator(
V.back())) {
4283 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4284 << A->getSpelling() <<
V;
4285 Args.eraseArg(options::OPT__SLASH_Fa);
4290 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4291 if (A->getValue()[0] ==
'\0') {
4293 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4294 Args.eraseArg(options::OPT__SLASH_o);
4299 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4300 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4301 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4302 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4303 Args.eraseArg(options::OPT__SLASH_Yc);
4304 Args.eraseArg(options::OPT__SLASH_Yu);
4305 YcArg = YuArg =
nullptr;
4307 if (YcArg && Inputs.size() > 1) {
4308 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4309 Args.eraseArg(options::OPT__SLASH_Yc);
4317 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4318 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4319 Args.AddFlagArg(
nullptr,
4320 getOpts().getOption(options::OPT_frtlib_add_rpath));
4324 if (Args.hasArg(options::OPT_emit_llvm) &&
4325 !Args.hasArg(options::OPT_hip_link) &&
4326 !
C.getDefaultToolChain().getTriple().isSPIRV())
4327 Diag(clang::diag::err_drv_emit_llvm_link);
4328 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4330 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4331 .starts_with_insensitive(
"lld"))
4332 Diag(clang::diag::err_drv_lto_without_lld);
4338 if (!Args.hasArg(options::OPT_dumpdir)) {
4339 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4340 Arg *Arg = Args.MakeSeparateArg(
4341 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4343 (FinalOutput ? FinalOutput->getValue()
4355 Args.eraseArg(options::OPT__SLASH_Fp);
4356 Args.eraseArg(options::OPT__SLASH_Yc);
4357 Args.eraseArg(options::OPT__SLASH_Yu);
4358 YcArg = YuArg =
nullptr;
4361 if (Args.hasArg(options::OPT_include_pch) &&
4362 Args.hasArg(options::OPT_ignore_pch)) {
4366 Args.eraseArg(options::OPT_include_pch);
4369 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4370 for (
auto &I : Inputs) {
4372 const Arg *InputArg = I.second;
4377 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4381 if (InitialPhase > FinalPhase) {
4382 if (InputArg->isClaimed())
4389 if (Args.hasArg(options::OPT_Qunused_arguments))
4395 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4396 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4400 (Args.getLastArg(options::OPT__SLASH_EP,
4401 options::OPT__SLASH_P) ||
4402 Args.getLastArg(options::OPT_E) ||
4403 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4405 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4406 << InputArg->getAsString(Args) << !!FinalPhaseArg
4407 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4409 Diag(clang::diag::warn_drv_input_file_unused)
4410 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4412 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4421 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4425 Actions.push_back(ClangClPch);
4437 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4438 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4444 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4446 if (!SuppressMissingInputWarning && Inputs.empty()) {
4447 Diag(clang::diag::err_drv_no_input_files);
4451 handleArguments(
C, Args, Inputs, Actions);
4453 bool UseNewOffloadingDriver = Args.hasFlag(
4454 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4458 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4459 !UseNewOffloadingDriver
4460 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4468 for (
auto &I : Inputs) {
4470 const Arg *InputArg = I.second;
4483 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4489 if (!UseNewOffloadingDriver)
4490 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4496 if (!UseNewOffloadingDriver)
4497 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4498 Current, InputArg, Phase, PL.back(), FullPL);
4504 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4507 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4508 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4510 LinkerInputs.push_back(Current);
4520 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4521 MergerInputs.push_back(Current);
4539 if (NewCurrent == Current)
4542 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4545 Current = NewCurrent;
4549 if (UseNewOffloadingDriver)
4553 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4557 if (Current->
getType() == types::TY_Nothing)
4563 Actions.push_back(Current);
4566 if (!UseNewOffloadingDriver)
4567 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4575 if (LinkerInputs.empty()) {
4578 if (!UseNewOffloadingDriver)
4579 OffloadBuilder->appendDeviceLinkActions(Actions);
4582 if (!LinkerInputs.empty()) {
4583 if (!UseNewOffloadingDriver)
4584 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4585 LinkerInputs.push_back(Wrapper);
4590 }
else if (UseNewOffloadingDriver ||
4591 Args.hasArg(options::OPT_offload_link)) {
4599 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4600 C.getDefaultToolChain().getTriple().isSPIRV();
4601 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4605 if (!UseNewOffloadingDriver)
4606 LA = OffloadBuilder->processHostLinkAction(LA);
4607 Actions.push_back(LA);
4611 if (!MergerInputs.empty())
4615 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4622 for (
auto &I : Inputs) {
4624 const Arg *InputArg = I.second;
4629 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4630 InputType == types::TY_Asm)
4635 for (
auto Phase : PhaseList) {
4639 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4644 if (InputType == types::TY_Object)
4651 assert(Phase == PhaseList.back() &&
4652 "merging must be final compilation step.");
4653 MergerInputs.push_back(Current);
4662 Actions.push_back(Current);
4666 if (!MergerInputs.empty())
4671 for (
auto Opt : {options::OPT_print_supported_cpus,
4672 options::OPT_print_supported_extensions,
4673 options::OPT_print_enabled_extensions}) {
4680 if (Arg *A = Args.getLastArg(Opt)) {
4681 if (Opt == options::OPT_print_supported_extensions &&
4682 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4683 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4684 !
C.getDefaultToolChain().getTriple().isARM()) {
4685 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4686 <<
"--print-supported-extensions";
4689 if (Opt == options::OPT_print_enabled_extensions &&
4690 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4691 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4692 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4693 <<
"--print-enabled-extensions";
4700 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4703 for (
auto &I : Inputs)
4708 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4714 if (TC.requiresObjcopy(Args)) {
4715 Action *LastAction = Actions.back();
4717 if (LastAction->
getType() == types::TY_Object)
4723 if (TC.requiresValidation(Args)) {
4724 Action *LastAction = Actions.back();
4726 LastAction, types::TY_DX_CONTAINER));
4730 if (TC.requiresBinaryTranslation(Args)) {
4731 Action *LastAction = Actions.back();
4735 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4736 LastAction->
getType() == types::TY_Object)
4738 LastAction, types::TY_DX_CONTAINER));
4743 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4749 const llvm::opt::DerivedArgList &Args,
4751 const llvm::Triple &Triple) {
4756 if (Triple.isNVPTX() &&
4758 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4759 <<
"CUDA" << ArchStr;
4761 }
else if (Triple.isAMDGPU() &&
4763 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4764 <<
"HIP" << ArchStr;
4772 llvm::StringMap<bool> Features;
4775 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4787static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4789 llvm::Triple Triple) {
4790 if (!Triple.isAMDGPU())
4791 return std::nullopt;
4793 std::set<StringRef> ArchSet;
4794 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4798llvm::SmallVector<StringRef>
4802 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4803 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4804 options::OPT_no_offload_arch_EQ)) {
4805 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4807 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4809 :
"--no-offload-arch");
4812 llvm::DenseSet<StringRef> Archs;
4813 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4816 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4817 for (StringRef
Arch : Arg->getValues()) {
4818 if (
Arch ==
"native" ||
Arch.empty()) {
4822 << llvm::Triple::getArchTypeName(TC.
getArch())
4823 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4827 for (
auto ArchStr : *GPUsOrErr) {
4829 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4830 if (!CanonicalStr.empty())
4831 Archs.insert(CanonicalStr);
4836 StringRef CanonicalStr =
4838 if (!CanonicalStr.empty())
4839 Archs.insert(CanonicalStr);
4844 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4845 for (StringRef
Arch : Arg->getValues()) {
4846 if (
Arch ==
"all") {
4851 Archs.erase(ArchStr);
4857 if (
auto ConflictingArchs =
4859 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4860 << ConflictingArchs->first << ConflictingArchs->second;
4863 if (Archs.empty()) {
4871 Archs.insert(StringRef());
4874 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4875 .getLastArg(options::OPT_march_EQ)) {
4876 Archs.insert(Arg->getValue());
4881 << llvm::Triple::getArchTypeName(TC.
getArch())
4882 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4883 }
else if (!ArchsOrErr->empty()) {
4884 for (
auto Arch : *ArchsOrErr)
4885 Archs.insert(Args.MakeArgStringRef(
Arch));
4887 Archs.insert(StringRef());
4892 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4893 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4901 llvm::opt::DerivedArgList &Args,
4902 const InputTy &Input, StringRef CUID,
4903 Action *HostAction)
const {
4911 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4913 bool HIPRelocatableObj =
4915 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4916 options::OPT_fno_hip_emit_relocatable,
false);
4918 if (!HIPNoRDC && HIPRelocatableObj)
4919 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4920 <<
"-fhip-emit-relocatable"
4924 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4925 <<
"-fhip-emit-relocatable"
4926 <<
"--offload-device-only";
4944 auto TCRange =
C.getOffloadToolChains(Kind);
4945 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4946 ToolChains.push_back(TI->second);
4948 if (ToolChains.empty())
4952 const Arg *InputArg = Input.second;
4961 for (
const ToolChain *TC : ToolChains) {
4963 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4964 DeviceActions.push_back(
4965 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4969 if (DeviceActions.empty())
4975 HostAction->
getType() != types::TY_Nothing &&
4985 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4994 auto *TCAndArch = TCAndArchs.begin();
4995 for (
Action *&A : DeviceActions) {
4996 if (A->
getType() == types::TY_Nothing)
5006 HostAction->
getType() != types::TY_Nothing) {
5013 TCAndArch->second.data(), Kind);
5015 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5025 for (
Action *&A : DeviceActions) {
5030 OffloadTriple && OffloadTriple->isSPIRV() &&
5031 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5032 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5033 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5034 options::OPT_no_use_spirv_backend,
5041 bool IsAMDGCNSPIRVWithBackend =
5042 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5045 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5046 A->
getType() != types::TY_LTO_BC) ||
5054 auto *TCAndArch = TCAndArchs.begin();
5055 for (
Action *A : DeviceActions) {
5056 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5058 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5063 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5065 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5074 bool ShouldBundleHIP =
5075 Args.hasFlag(options::OPT_gpu_bundle_output,
5076 options::OPT_no_gpu_bundle_output,
false) ||
5077 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5079 return A->
getType() != types::TY_Image;
5086 if (OffloadActions.empty())
5091 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5095 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5102 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5103 DDep.
add(*FatbinAction,
5106 }
else if (HIPNoRDC) {
5118 DDep.
add(*PackagerAction,
5127 nullptr,
C.getActiveOffloadKinds());
5136 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5137 return A->
getType() == types::TY_Nothing;
5141 nullptr, SingleDeviceOutput ? DDep : DDeps);
5142 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5148 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5158 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5164 llvm_unreachable(
"link action invalid here.");
5166 llvm_unreachable(
"ifsmerge action invalid here.");
5171 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5172 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5173 OutputTy = types::TY_Dependencies;
5178 if (!Args.hasFlag(options::OPT_frewrite_includes,
5179 options::OPT_fno_rewrite_includes,
false) &&
5180 !Args.hasFlag(options::OPT_frewrite_imports,
5181 options::OPT_fno_rewrite_imports,
false) &&
5182 !Args.hasFlag(options::OPT_fdirectives_only,
5183 options::OPT_fno_directives_only,
false) &&
5187 "Cannot preprocess this input type!");
5193 if (Args.hasArg(options::OPT_extract_api))
5202 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5203 (Input->
getType() == driver::types::TY_CXXModule ||
5204 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5205 !Args.getLastArg(options::OPT__precompile) &&
5206 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5211 "Cannot precompile this input type!");
5215 const char *ModName =
nullptr;
5216 if (OutputTy == types::TY_PCH) {
5217 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5218 ModName = A->getValue();
5220 OutputTy = types::TY_ModuleFile;
5223 if (Args.hasArg(options::OPT_fsyntax_only)) {
5225 OutputTy = types::TY_Nothing;
5231 if (Args.hasArg(options::OPT_fsyntax_only))
5233 if (Args.hasArg(options::OPT_rewrite_objc))
5235 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5237 types::TY_RewrittenLegacyObjC);
5238 if (Args.hasArg(options::OPT__analyze))
5240 if (Args.hasArg(options::OPT_emit_ast))
5242 if (Args.hasArg(options::OPT_emit_cir))
5244 if (Args.hasArg(options::OPT_module_file_info))
5246 if (Args.hasArg(options::OPT_verify_pch))
5248 if (Args.hasArg(options::OPT_extract_api))
5257 Args.hasFlag(options::OPT_offload_new_driver,
5258 options::OPT_no_offload_new_driver,
5265 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5266 !Args.hasArg(options::OPT_emit_llvm))
5267 Output = types::TY_PP_Asm;
5268 else if (Args.hasArg(options::OPT_S))
5269 Output = types::TY_LTO_IR;
5271 Output = types::TY_LTO_BC;
5276 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5279 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5280 options::OPT_no_use_spirv_backend,
5288 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5290 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5292 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5294 auto &DefaultToolChain =
C.getDefaultToolChain();
5295 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5300 bool EmitBitcodeForNonOffloadAMDSPIRV =
5301 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5302 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5303 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5305 if (Args.hasArg(options::OPT_emit_llvm) ||
5306 EmitBitcodeForNonOffloadAMDSPIRV ||
5312 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5313 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5315 (Args.hasFlag(options::OPT_offload_new_driver,
5316 options::OPT_no_offload_new_driver,
5324 Args.hasArg(options::OPT_S) &&
5328 !Args.hasFlag(options::OPT_offload_new_driver,
5329 options::OPT_no_offload_new_driver,
5330 C.getActiveOffloadKinds() !=
5333 : types::TY_LLVM_BC;
5346 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5355 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5359 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5361 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5381 unsigned NumOutputs = 0;
5382 unsigned NumIfsOutputs = 0;
5383 for (
const Action *A :
C.getActions()) {
5386 if (A->
getType() == types::TY_DX_CONTAINER &&
5391 if (A->
getType() != types::TY_Nothing &&
5393 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5395 0 == NumIfsOutputs++) ||
5400 A->
getType() == types::TY_Nothing &&
5401 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5402 NumOutputs += A->
size();
5405 if (NumOutputs > 1) {
5406 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5407 FinalOutput =
nullptr;
5411 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5415 if (RawTriple.isOSBinFormatMachO())
5416 for (
const Arg *A :
C.getArgs())
5417 if (A->getOption().matches(options::OPT_arch))
5421 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5422 for (
Action *A :
C.getActions()) {
5429 const char *LinkingOutput =
nullptr;
5432 LinkingOutput = FinalOutput->getValue();
5441 LinkingOutput, CachedResults,
5448 for (
auto &J :
C.getJobs())
5449 J.InProcess =
false;
5452 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5453 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5458 const char *LinkingOutput =
nullptr;
5460 LinkingOutput = FinalOutput->getValue();
5467 using namespace llvm;
5470 <<
"output=" << LinkingOutput;
5471 outs() <<
", total="
5472 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5474 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5475 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5479 llvm::raw_string_ostream Out(Buffer);
5480 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5483 llvm::sys::printArg(Out, LinkingOutput,
true);
5484 Out <<
',' << ProcStat->TotalTime.count() <<
','
5485 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5490 llvm::sys::fs::OF_Append |
5491 llvm::sys::fs::OF_Text);
5496 llvm::errs() <<
"ERROR: Cannot lock file "
5498 <<
toString(L.takeError()) <<
"\n";
5509 bool ReportUnusedArguments =
5510 !Diags.hasErrorOccurred() &&
5511 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5514 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5516 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5519 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5520 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5522 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5526 return strstr(J.getCreator().getShortName(),
"assembler");
5528 for (Arg *A :
C.getArgs()) {
5532 if (!A->isClaimed()) {
5538 const Option &Opt = A->getOption();
5539 if (Opt.getKind() == Option::FlagClass) {
5540 bool DuplicateClaimed =
false;
5542 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5543 if (AA->isClaimed()) {
5544 DuplicateClaimed =
true;
5549 if (DuplicateClaimed)
5555 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5557 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5562 !
C.getActions().empty()) {
5563 Diag(diag::err_drv_unsupported_opt_for_target)
5565 }
else if (ReportUnusedArguments) {
5566 Diag(clang::diag::warn_drv_unused_argument)
5567 << A->getAsString(
C.getArgs());
5577class ToolSelector final {
5588 bool IsHostSelector;
5599 bool CanBeCollapsed =
true) {
5601 if (Inputs.size() != 1)
5604 Action *CurAction = *Inputs.begin();
5605 if (CanBeCollapsed &&
5611 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5615 if (!IsHostSelector) {
5616 if (OA->hasSingleDeviceDependence(
true)) {
5618 OA->getSingleDeviceDependence(
true);
5619 if (CanBeCollapsed &&
5622 SavedOffloadAction.push_back(OA);
5623 return dyn_cast<JobAction>(CurAction);
5625 }
else if (OA->hasHostDependence()) {
5626 CurAction = OA->getHostDependence();
5627 if (CanBeCollapsed &&
5630 SavedOffloadAction.push_back(OA);
5631 return dyn_cast<JobAction>(CurAction);
5636 return dyn_cast<JobAction>(CurAction);
5640 bool canCollapseAssembleAction()
const {
5641 return TC.useIntegratedAs() && !SaveTemps &&
5642 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5643 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5644 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5645 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5649 bool canCollapsePreprocessorAction()
const {
5650 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5651 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5652 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5657 struct JobActionInfo final {
5659 const JobAction *JA =
nullptr;
5667 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5668 ArrayRef<JobActionInfo> &ActionInfo,
5669 unsigned ElementNum) {
5670 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5671 for (
unsigned I = 0; I < ElementNum; ++I)
5672 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5673 ActionInfo[I].SavedOffloadAction.end());
5686 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5689 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5691 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5692 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5693 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5694 if (!AJ || !BJ || !CJ)
5698 const Tool *T = TC.SelectTool(*CJ);
5711 const Tool *BT = TC.SelectTool(*BJ);
5719 Inputs = CJ->getInputs();
5720 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5724 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5727 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5729 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5730 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5735 const Tool *T = TC.SelectTool(*BJ);
5742 Inputs = BJ->getInputs();
5743 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5747 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5750 if (ActionInfo.size() < 2)
5752 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5753 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5757 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5758 for (
auto &Input : AI.JA->getInputs())
5769 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5770 if (SaveTemps && !InputIsBitcode)
5774 const Tool *T = TC.SelectTool(*CJ);
5787 Inputs = CJ->getInputs();
5788 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5797 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5805 for (Action *A : Inputs) {
5806 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5808 NewInputs.push_back(A);
5814 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5815 PreprocessJobOffloadActions.end());
5816 NewInputs.append(PJ->input_begin(), PJ->input_end());
5822 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5824 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5826 assert(BaseAction &&
"Invalid base action.");
5842 SmallVector<JobActionInfo, 5> ActionChain(1);
5843 ActionChain.back().JA = BaseAction;
5844 while (ActionChain.back().JA) {
5845 const Action *CurAction = ActionChain.back().JA;
5848 ActionChain.resize(ActionChain.size() + 1);
5849 JobActionInfo &AI = ActionChain.back();
5853 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5857 ActionChain.pop_back();
5865 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5866 CollapsedOffloadAction);
5868 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5870 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5876 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5888 StringRef BoundArch,
5890 std::string TriplePlusArch = TC->
getTriple().normalize();
5891 if (!BoundArch.empty()) {
5892 TriplePlusArch +=
"-";
5893 TriplePlusArch += BoundArch;
5895 TriplePlusArch +=
"-";
5897 return TriplePlusArch;
5902 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5903 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5906 std::pair<const Action *, std::string> ActionTC = {
5908 auto CachedResult = CachedResults.find(ActionTC);
5909 if (CachedResult != CachedResults.end()) {
5910 return CachedResult->second;
5913 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5914 CachedResults, TargetDeviceOffloadKind);
5915 CachedResults[ActionTC] =
Result;
5920 const JobAction *JA,
const char *BaseInput,
5923 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5934 OffloadingPrefix +=
"-";
5935 OffloadingPrefix +=
Arch;
5938 C.getDriver().isSaveTempsEnabled()) {
5945 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5946 Path = A->getValue();
5947 if (llvm::sys::fs::is_directory(Path)) {
5949 ? llvm::sys::path::stem(Result.getFilename())
5950 : llvm::sys::path::stem(BaseInput));
5951 Tmp += OffloadingPrefix;
5953 llvm::sys::path::append(Path, Tmp);
5956 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5959 Path = DumpDir->getValue();
5960 Path += llvm::sys::path::stem(BaseInput);
5961 Path += OffloadingPrefix;
5962 }
else if (!OffloadingPrefix.empty()) {
5966 TraceName += OffloadingPrefix;
5967 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
5968 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
5969 llvm::sys::path::append(Path, TraceName);
5971 Path = Result.getFilename();
5973 llvm::sys::path::replace_extension(Path,
"json");
5975 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5976 C.addTimeTraceFile(ResultFile, JA);
5977 C.addResultFile(ResultFile, JA);
5982 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5983 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5986 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5989 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5990 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6022 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6024 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6025 const char *DepBoundArch) {
6028 LinkingOutput, CachedResults,
6038 OA->doOnEachDependence(
6039 BuildingForOffloadDevice,
6040 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6042 C, DepA, DepTC, DepBoundArch,
false,
6043 !!DepBoundArch, LinkingOutput, CachedResults,
6047 A = BuildingForOffloadDevice
6048 ? OA->getSingleDeviceDependence(
true)
6049 : OA->getHostDependence();
6053 std::pair<const Action *, std::string> ActionTC = {
6054 OA->getHostDependence(),
6056 auto It = CachedResults.find(ActionTC);
6057 if (It != CachedResults.end()) {
6059 Inputs.append(OffloadDependencesInputInfo);
6064 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6067 const Arg &Input = IA->getInputArg();
6069 if (Input.getOption().matches(options::OPT_INPUT)) {
6070 const char *
Name = Input.getValue();
6073 return {InputInfo(A, &Input,
"")};
6076 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6077 const ToolChain *TC;
6080 if (!ArchName.empty())
6081 TC = &getToolChain(
C.getArgs(),
6083 C.getArgs(), ArchName));
6085 TC = &
C.getDefaultToolChain();
6088 MultipleArchs, LinkingOutput, CachedResults,
6089 TargetDeviceOffloadKind);
6100 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6103 return {InputInfo()};
6107 for (
const auto *OA : CollapsedOffloadActions)
6109 BuildingForOffloadDevice,
6110 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6112 C, DepA, DepTC, DepBoundArch,
false,
6113 !!DepBoundArch, LinkingOutput, CachedResults,
6119 for (
const Action *Input : Inputs) {
6123 bool SubJobAtTopLevel =
6126 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6131 const char *BaseInput = InputInfos[0].getBaseInput();
6132 for (
auto &Info : InputInfos) {
6133 if (Info.isFilename()) {
6134 BaseInput = Info.getBaseInput();
6141 if (JA->
getType() == types::TY_dSYM)
6142 BaseInput = InputInfos[0].getFilename();
6145 if (!OffloadDependencesInputInfo.empty())
6146 InputInfos.append(OffloadDependencesInputInfo.begin(),
6147 OffloadDependencesInputInfo.end());
6150 llvm::Triple EffectiveTriple;
6152 const ArgList &Args =
6154 if (InputInfos.size() != 1) {
6158 EffectiveTriple = llvm::Triple(
6161 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6166 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6170 for (
auto &UI : UA->getDependentActionsInfo()) {
6172 "Unbundling with no offloading??");
6179 UI.DependentOffloadKind,
6180 UI.DependentToolChain->getTriple().normalize(),
6182 auto CurI = InputInfo(
6191 UnbundlingResults.push_back(CurI);
6200 Arch = UI.DependentBoundArch;
6205 UI.DependentOffloadKind)}] = {
6211 std::pair<const Action *, std::string> ActionTC = {
6213 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6214 "Result does not exist??");
6215 Result = CachedResults[ActionTC].front();
6216 }
else if (JA->
getType() == types::TY_Nothing)
6217 Result = {InputInfo(A, BaseInput)};
6227 AtTopLevel, MultipleArchs,
6236 <<
" - \"" << T->
getName() <<
"\", inputs: [";
6237 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6238 llvm::errs() << InputInfos[i].getAsString();
6240 llvm::errs() <<
", ";
6242 if (UnbundlingResults.empty())
6243 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6245 llvm::errs() <<
"], outputs: [";
6246 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6247 llvm::errs() << UnbundlingResults[i].getAsString();
6249 llvm::errs() <<
", ";
6251 llvm::errs() <<
"] \n";
6254 if (UnbundlingResults.empty())
6258 Args, LinkingOutput);
6264 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6265 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6277 if (ArgValue.empty()) {
6279 Filename = BaseName;
6280 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6282 llvm::sys::path::append(Filename, BaseName);
6285 if (!llvm::sys::path::has_extension(ArgValue)) {
6290 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6295 llvm::sys::path::replace_extension(Filename, Extension);
6298 return Args.MakeArgString(Filename.c_str());
6313 StringRef Suffix,
bool MultipleArchs,
6314 StringRef BoundArch,
6315 bool NeedUniqueDirectory)
const {
6317 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6318 std::optional<std::string> CrashDirectory =
6320 ? std::string(A->getValue())
6321 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6322 if (CrashDirectory) {
6323 if (!
getVFS().exists(*CrashDirectory))
6324 llvm::sys::fs::create_directories(*CrashDirectory);
6326 llvm::sys::path::append(Path, Prefix);
6327 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6328 if (std::error_code EC =
6329 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6330 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6334 if (MultipleArchs && !BoundArch.empty()) {
6335 if (NeedUniqueDirectory) {
6337 llvm::sys::path::append(TmpName,
6338 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6348 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6363 const char *BaseInput) {
6365 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6366 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6371 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6375 const char *BaseInput,
6376 StringRef OrigBoundArch,
bool AtTopLevel,
6378 StringRef OffloadingPrefix)
const {
6381 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6384 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6385 return C.addResultFile(FinalOutput->getValue(), &JA);
6389 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6391 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6393 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6394 NameArg = A->getValue();
6395 return C.addResultFile(
6405 if (JA.
getType() == types::TY_ModuleFile &&
6406 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6410 if (JA.
getType() == types::TY_PP_Asm &&
6411 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6412 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6415 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6418 if ((JA.
getType() == types::TY_Object &&
6419 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6420 JA.
getType() == types::TY_DX_CONTAINER) {
6421 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6425 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6427 C.getDefaultToolChain());
6430 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6431 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6432 StringRef
Name = llvm::sys::path::filename(BaseInput);
6433 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6439 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6440 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6444 if (JA.
getType() == types::TY_PP_Asm &&
6445 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6446 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6448 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6449 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6450 return C.addResultFile(
6455 if (JA.
getType() == types::TY_API_INFO &&
6456 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6457 C.getArgs().hasArg(options::OPT_o))
6458 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6459 <<
C.getArgs().getLastArgValue(options::OPT_o);
6466 bool SpecifiedModuleOutput =
6467 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6468 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6469 if (MultipleArchs && SpecifiedModuleOutput)
6470 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6475 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6476 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6482 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6484 StringRef
Name = llvm::sys::path::filename(BaseInput);
6485 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6486 const char *Suffix =
6491 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6492 bool NeedUniqueDirectory =
6495 Triple.isOSDarwin();
6496 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6497 NeedUniqueDirectory);
6506 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6511 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6512 llvm::sys::path::filename(BasePath));
6513 BaseName = ExternalPath;
6515 BaseName = BasePath;
6517 BaseName = llvm::sys::path::filename(BasePath);
6520 const char *NamedOutput;
6522 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6523 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6527 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6531 }
else if (JA.
getType() == types::TY_Image &&
6532 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6533 options::OPT__SLASH_o)) {
6537 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6541 }
else if (JA.
getType() == types::TY_Image) {
6551 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6552 options::OPT_fno_gpu_rdc,
false);
6554 if (UseOutExtension) {
6556 llvm::sys::path::replace_extension(Output,
"");
6558 Output += OffloadingPrefix;
6559 if (MultipleArchs && !BoundArch.empty()) {
6561 Output.append(BoundArch);
6563 if (UseOutExtension)
6565 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6568 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6569 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6570 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6573 .getLastArg(options::OPT__SLASH_o)
6578 const char *Suffix =
6580 assert(Suffix &&
"All types used for output should have a suffix.");
6582 std::string::size_type End = std::string::npos;
6584 End = BaseName.rfind(
'.');
6586 Suffixed += OffloadingPrefix;
6587 if (MultipleArchs && !BoundArch.empty()) {
6589 Suffixed.append(BoundArch);
6594 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6595 const llvm::opt::DerivedArgList &Args) {
6602 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6604 Args.hasFlag(options::OPT_offload_new_driver,
6605 options::OPT_no_offload_new_driver,
true))) ||
6612 bool IsLinkerWrapper =
6614 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6615 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6616 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6618 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6622 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6626 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6627 JA.
getType() != types::TY_PCH) {
6628 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6630 llvm::sys::path::remove_filename(TempPath);
6631 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6632 llvm::sys::path::append(TempPath, OutputFileName);
6633 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6639 bool SameFile =
false;
6641 llvm::sys::fs::current_path(
Result);
6642 llvm::sys::path::append(
Result, BaseName);
6643 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6646 StringRef
Name = llvm::sys::path::filename(BaseInput);
6647 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6651 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6657 llvm::sys::path::remove_filename(BasePath);
6658 if (BasePath.empty())
6659 BasePath = NamedOutput;
6661 llvm::sys::path::append(BasePath, NamedOutput);
6662 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6665 return C.addResultFile(NamedOutput, &JA);
6671 -> std::optional<std::string> {
6674 for (
const auto &
Dir : P) {
6678 llvm::sys::path::append(P,
Name);
6679 if (llvm::sys::fs::exists(Twine(P)))
6680 return std::string(P);
6682 return std::nullopt;
6689 llvm::sys::path::append(R,
Name);
6690 if (llvm::sys::fs::exists(Twine(R)))
6691 return std::string(R);
6694 llvm::sys::path::append(P,
Name);
6695 if (llvm::sys::fs::exists(Twine(P)))
6696 return std::string(P);
6699 llvm::sys::path::append(D,
"..",
Name);
6700 if (llvm::sys::fs::exists(Twine(D)))
6701 return std::string(D);
6710 llvm::sys::path::append(R2,
"..",
"..",
Name);
6711 if (llvm::sys::fs::exists(Twine(R2)))
6712 return std::string(R2);
6714 return std::string(
Name);
6717void Driver::generatePrefixedToolNames(
6721 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6722 Names.emplace_back(
Tool);
6726 llvm::sys::path::append(Dir, Name);
6727 if (llvm::sys::fs::can_execute(Twine(Dir)))
6729 llvm::sys::path::remove_filename(Dir);
6735 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6740 if (llvm::sys::fs::is_directory(PrefixDir)) {
6743 return std::string(P);
6746 if (llvm::sys::fs::can_execute(Twine(P)))
6747 return std::string(P);
6752 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6760 for (
const auto &Path : List) {
6763 return std::string(P);
6767 if (llvm::ErrorOr<std::string> P =
6768 llvm::sys::findProgramByName(TargetSpecificExecutable))
6772 return std::string(
Name);
6777 std::string error =
"<NOT PRESENT>";
6779 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6784 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6801 llvm::sys::path::remove_filename(path);
6802 llvm::sys::path::append(path,
"libc++.modules.json");
6803 if (TC.
getVFS().exists(path))
6804 return static_cast<std::string
>(path);
6809 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6812 return evaluate(
"libc++.a").value_or(error);
6816 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6820 llvm::sys::path::remove_filename(path);
6821 llvm::sys::path::append(path,
"libstdc++.modules.json");
6822 if (TC.
getVFS().exists(path))
6823 return static_cast<std::string
>(path);
6828 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6831 return evaluate(
"libstdc++.a").value_or(error);
6840 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6842 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6846 return std::string(Path);
6851 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6853 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6857 return std::string(Path);
6862 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6866 Output = FpArg->getValue();
6870 if (!llvm::sys::path::has_extension(Output))
6873 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6874 Output = YcArg->getValue();
6877 llvm::sys::path::replace_extension(Output,
".pch");
6879 return std::string(Output);
6882const ToolChain &Driver::getOffloadToolChain(
6884 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6885 std::unique_ptr<ToolChain> &TC =
6886 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6887 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6889 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6892 switch (
Target.getOS()) {
6893 case llvm::Triple::CUDA:
6894 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6897 case llvm::Triple::AMDHSA:
6899 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6902 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6911 switch (
Target.getArch()) {
6912 case llvm::Triple::spir:
6913 case llvm::Triple::spir64:
6914 case llvm::Triple::spirv:
6915 case llvm::Triple::spirv32:
6916 case llvm::Triple::spirv64:
6919 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6923 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6927 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6931 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6945 return getToolChain(Args,
Target);
6949const ToolChain &Driver::getToolChain(
const ArgList &Args,
6950 const llvm::Triple &
Target)
const {
6952 auto &TC = ToolChains[
Target.str()];
6954 switch (
Target.getOS()) {
6955 case llvm::Triple::AIX:
6956 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6958 case llvm::Triple::Haiku:
6959 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6961 case llvm::Triple::Darwin:
6962 case llvm::Triple::MacOSX:
6963 case llvm::Triple::IOS:
6964 case llvm::Triple::TvOS:
6965 case llvm::Triple::WatchOS:
6966 case llvm::Triple::XROS:
6967 case llvm::Triple::DriverKit:
6968 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6970 case llvm::Triple::DragonFly:
6971 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6973 case llvm::Triple::OpenBSD:
6974 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6976 case llvm::Triple::NetBSD:
6977 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6979 case llvm::Triple::FreeBSD:
6981 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6984 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6986 case llvm::Triple::Linux:
6987 case llvm::Triple::ELFIAMCU:
6988 if (
Target.getArch() == llvm::Triple::hexagon)
6989 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6991 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6992 !
Target.hasEnvironment())
6993 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6996 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6998 else if (
Target.getArch() == llvm::Triple::ve)
6999 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7000 else if (
Target.isOHOSFamily())
7001 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7002 else if (
Target.isWALI())
7003 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7005 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7007 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7009 case llvm::Triple::Fuchsia:
7010 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7012 case llvm::Triple::Managarm:
7013 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7015 case llvm::Triple::Solaris:
7016 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7018 case llvm::Triple::CUDA:
7019 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7021 case llvm::Triple::AMDHSA: {
7022 if (
Target.getArch() == llvm::Triple::spirv64) {
7023 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7028 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7030 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7035 case llvm::Triple::AMDPAL:
7036 case llvm::Triple::Mesa3D:
7037 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7039 case llvm::Triple::UEFI:
7040 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7042 case llvm::Triple::Win32:
7043 switch (
Target.getEnvironment()) {
7045 if (
Target.isOSBinFormatELF())
7046 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7047 else if (
Target.isOSBinFormatMachO())
7048 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7050 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7052 case llvm::Triple::GNU:
7053 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7055 case llvm::Triple::Cygnus:
7056 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7058 case llvm::Triple::Itanium:
7059 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7062 case llvm::Triple::MSVC:
7063 case llvm::Triple::UnknownEnvironment:
7064 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7065 .starts_with_insensitive(
"bfd"))
7066 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7070 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7074 case llvm::Triple::PS4:
7075 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7077 case llvm::Triple::PS5:
7078 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7080 case llvm::Triple::Hurd:
7081 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7083 case llvm::Triple::LiteOS:
7084 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7086 case llvm::Triple::ZOS:
7087 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7089 case llvm::Triple::Vulkan:
7090 case llvm::Triple::ShaderModel:
7091 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7093 case llvm::Triple::ChipStar:
7094 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7099 switch (
Target.getArch()) {
7100 case llvm::Triple::tce:
7101 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7103 case llvm::Triple::tcele:
7104 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7106 case llvm::Triple::hexagon:
7107 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7110 case llvm::Triple::lanai:
7111 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7113 case llvm::Triple::xcore:
7114 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7116 case llvm::Triple::wasm32:
7117 case llvm::Triple::wasm64:
7118 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7120 case llvm::Triple::avr:
7121 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7123 case llvm::Triple::msp430:
7124 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7126 case llvm::Triple::riscv32:
7127 case llvm::Triple::riscv64:
7128 case llvm::Triple::riscv32be:
7129 case llvm::Triple::riscv64be:
7130 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7132 case llvm::Triple::ve:
7133 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7135 case llvm::Triple::spirv32:
7136 case llvm::Triple::spirv64:
7137 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7139 case llvm::Triple::csky:
7140 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7144 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7145 else if (
Target.isOSBinFormatELF())
7146 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7147 else if (
Target.isAppleFirmware())
7148 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7149 else if (
Target.isAppleMachO())
7150 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7151 else if (
Target.isOSBinFormatMachO())
7152 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7154 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7164 if (JA.
size() != 1 ||
7179 if (JA.
size() != 1 ||
7193 if (Args.hasArg(options::OPT_emit_static_lib))
7204 unsigned &Micro,
bool &HadExtra) {
7207 Major = Minor = Micro = 0;
7211 if (Str.consumeInteger(10, Major))
7215 if (!Str.consume_front(
"."))
7218 if (Str.consumeInteger(10, Minor))
7222 if (!Str.consume_front(
"."))
7225 if (Str.consumeInteger(10, Micro))
7243 unsigned CurDigit = 0;
7244 while (CurDigit < Digits.size()) {
7246 if (Str.consumeInteger(10, Digit))
7248 Digits[CurDigit] = Digit;
7251 if (!Str.consume_front(
"."))
7260llvm::opt::Visibility
7261Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7274const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7290 llvm_unreachable(
"Unhandled Mode");
7294 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7299 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7300 options::OPT_fno_save_optimization_record,
false))
7304 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7305 options::OPT_fno_save_optimization_record,
false))
7309 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7310 options::OPT_fno_save_optimization_record,
false))
7314 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7315 options::OPT_fno_save_optimization_record,
false))
7322 static StringRef OptName =
7324 llvm::StringRef Opt;
7325 for (StringRef Arg : Args) {
7326 if (!Arg.starts_with(OptName))
7332 return Opt.consume_front(OptName) ? Opt :
"";
7339 llvm::BumpPtrAllocator &Alloc,
7340 llvm::vfs::FileSystem *FS) {
7349 for (
const char *F : Args) {
7350 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7352 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7353 RSPQuoting = Windows;
7359 bool MarkEOLs = ClangCLMode;
7361 llvm::cl::TokenizerCallback Tokenizer;
7362 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7363 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7365 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7367 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7370 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7371 ECtx.setMarkEOLs(MarkEOLs);
7375 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7379 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7380 [](
const char *A) {
return A !=
nullptr; });
7381 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7384 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7385 Args.resize(newEnd - Args.begin());
7389 return llvm::Error::success();
7393 return SavedStrings.insert(S).first->getKeyData();
7427 llvm::StringSet<> &SavedStrings) {
7430 if (Edit[0] ==
'^') {
7431 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7432 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7433 Args.insert(Args.begin() + 1, Str);
7434 }
else if (Edit[0] ==
'+') {
7435 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7436 OS <<
"### Adding argument " << Str <<
" at end\n";
7437 Args.push_back(Str);
7438 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7439 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7440 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7441 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7442 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7444 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7446 if (Args[i] ==
nullptr)
7448 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7450 if (Repl != Args[i]) {
7451 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7455 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7456 auto Option = Edit.substr(1);
7457 for (
unsigned i = 1; i < Args.size();) {
7458 if (Option == Args[i]) {
7459 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7460 Args.erase(Args.begin() + i);
7461 if (Edit[0] ==
'X') {
7462 if (i < Args.size()) {
7463 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7464 Args.erase(Args.begin() + i);
7466 OS <<
"### Invalid X edit, end of command line!\n";
7471 }
else if (Edit[0] ==
'O') {
7472 for (
unsigned i = 1; i < Args.size();) {
7473 const char *A = Args[i];
7477 if (A[0] ==
'-' && A[1] ==
'O' &&
7478 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7479 (
'0' <= A[2] && A[2] <=
'9'))))) {
7480 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7481 Args.erase(Args.begin() + i);
7485 OS <<
"### Adding argument " << Edit <<
" at end\n";
7486 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7488 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7493 const char *OverrideStr,
7494 llvm::StringSet<> &SavedStrings,
7495 StringRef EnvVar, raw_ostream *OS) {
7497 OS = &llvm::nulls();
7499 if (OverrideStr[0] ==
'#') {
7501 OS = &llvm::nulls();
7504 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7508 const char *S = OverrideStr;
7510 const char *End = ::strchr(S,
' ');
7512 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
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 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 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
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
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.
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(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
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.
void buildStdModuleManifestInputs(ArrayRef< StdModuleManifest::Module > ManifestEntries, Compilation &C, InputList &Inputs)
Constructs compilation inputs for each module listed in the provided Standard library module manifest...
void runModulesDriver(Compilation &C, ArrayRef< StdModuleManifest::Module > ManifestEntries)
Scans the compilation inputs for module dependencies and adjusts the compilation to build and supply ...
llvm::Expected< StdModuleManifest > readStdModuleManifest(llvm::StringRef ManifestPath, llvm::vfs::FileSystem &VFS)
Reads the Standard library module manifest at ManifestPath.
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.
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 ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules