59#include "clang/Config/config.h"
76#include "llvm/ADT/ArrayRef.h"
77#include "llvm/ADT/STLExtras.h"
78#include "llvm/ADT/ScopeExit.h"
79#include "llvm/ADT/SmallSet.h"
80#include "llvm/ADT/SmallVector.h"
81#include "llvm/ADT/StringExtras.h"
82#include "llvm/ADT/StringRef.h"
83#include "llvm/ADT/StringSet.h"
84#include "llvm/ADT/StringSwitch.h"
85#include "llvm/Config/llvm-config.h"
86#include "llvm/MC/TargetRegistry.h"
87#include "llvm/Option/Arg.h"
88#include "llvm/Option/ArgList.h"
89#include "llvm/Option/OptSpecifier.h"
90#include "llvm/Option/OptTable.h"
91#include "llvm/Option/Option.h"
92#include "llvm/Support/CommandLine.h"
93#include "llvm/Support/ErrorHandling.h"
94#include "llvm/Support/ExitCodes.h"
95#include "llvm/Support/FileSystem.h"
96#include "llvm/Support/FileUtilities.h"
97#include "llvm/Support/FormatVariadic.h"
98#include "llvm/Support/IOSandbox.h"
99#include "llvm/Support/JSON.h"
100#include "llvm/Support/MD5.h"
101#include "llvm/Support/MemoryBuffer.h"
102#include "llvm/Support/Path.h"
103#include "llvm/Support/PrettyStackTrace.h"
104#include "llvm/Support/Process.h"
105#include "llvm/Support/Program.h"
106#include "llvm/Support/Regex.h"
107#include "llvm/Support/StringSaver.h"
108#include "llvm/Support/TarWriter.h"
109#include "llvm/Support/VirtualFileSystem.h"
110#include "llvm/Support/raw_ostream.h"
111#include "llvm/TargetParser/Host.h"
112#include "llvm/TargetParser/RISCVISAInfo.h"
125using namespace clang;
128template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
129 return llvm::any_of(Args, [&](Arg *A) {
130 return (A->getOption().matches(options::OPT_x) &&
132 (A->getOption().
getKind() == Option::InputClass &&
133 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
135 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
140 return Arg ==
"-internal-isystem" || Arg ==
"-internal-externc-isystem" ||
141 Arg ==
"-isystem" || Arg ==
"-cxx-isystem" || Arg ==
"-idirafter";
145 const ArgList &Args) {
146 ArgStringList CC1Args;
147 if (Args.hasArg(options::OPT_stdlibxx_isystem))
152 for (
size_t I = 0; I < CC1Args.size(); ++I) {
153 StringRef Arg(CC1Args[I]);
155 llvm::outs() << CC1Args[++I] <<
'\n';
161 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
162 StringRef UseCUIDStr = A->getValue();
163 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
164 .Case(
"hash", Kind::Hash)
165 .Case(
"random", Kind::Random)
166 .Case(
"none", Kind::None)
167 .Default(Kind::Invalid);
168 if (UseCUID == Kind::Invalid)
169 D.Diag(clang::diag::err_drv_invalid_value)
170 << A->getAsString(Args) << UseCUIDStr;
173 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
174 if (!FixedCUID.empty())
179 llvm::opt::DerivedArgList &Args)
const {
180 std::string CUID = FixedCUID.str();
183 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
187 llvm::MD5::MD5Result
Hash;
188 Hasher.update(InputFile);
189 for (
auto *A : Args) {
190 if (A->getOption().matches(options::OPT_INPUT))
192 Hasher.update(A->getAsString(Args));
195 CUID = llvm::utohexstr(
Hash.low(),
true);
203 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
204 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
210 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
211 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
212 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
215 this->VFS = llvm::vfs::getRealFileSystem();
220 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
223 llvm::sys::path::append(P,
SysRoot);
227#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
228 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
232 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
233 llvm::sys::path::remove_dots(configFileDir,
true);
237#if defined(CLANG_CONFIG_FILE_USER_DIR)
240 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
249void Driver::setDriverMode(StringRef
Value) {
250 static StringRef OptName =
251 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
252 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
253 .Case(
"gcc", GCCMode)
254 .Case(
"g++", GXXMode)
255 .Case(
"cpp", CPPMode)
257 .Case(
"flang", FlangMode)
258 .Case(
"dxc", DXCMode)
262 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
267 bool &ContainsError)
const {
268 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
269 ContainsError =
false;
271 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
272 unsigned MissingArgIndex, MissingArgCount;
273 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
274 MissingArgCount, VisibilityMask);
277 if (MissingArgCount) {
278 Diag(diag::err_drv_missing_argument)
279 << Args.getArgString(MissingArgIndex) << MissingArgCount;
281 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
286 for (
const Arg *A : Args) {
288 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
289 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
296 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
297 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
298 ContainsError |= Diags.getDiagnosticLevel(
299 diag::warn_drv_empty_joined_argument,
304 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
306 auto ArgString = A->getAsString(Args);
308 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
310 if (
getOpts().findExact(ArgString, Nearest,
312 DiagID = diag::err_drv_unknown_argument_with_suggestion;
313 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
315 DiagID = diag::err_drv_unknown_argument;
316 Diags.Report(DiagID) << ArgString;
319 llvm::opt::Visibility(
321 DiagID = diag::err_drv_unknown_argument_with_suggestion;
322 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
324 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
325 : diag::err_drv_unknown_argument;
326 Diags.Report(DiagID) << ArgString;
330 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
331 : diag::err_drv_unknown_argument_with_suggestion;
332 Diags.Report(DiagID) << ArgString << Nearest;
334 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
338 for (
const Arg *A : Args.filtered(options::OPT_o)) {
339 if (ArgStrings[A->getIndex()] == A->getSpelling())
343 std::string ArgString = ArgStrings[A->getIndex()];
345 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
346 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
347 << A->getAsString(Args) << Nearest;
357 Arg **FinalPhaseArg)
const {
358 Arg *PhaseArg =
nullptr;
362 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
374 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
377 options::OPT_fmodule_header_EQ))) {
380 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
381 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
383 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
384 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
385 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
386 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
387 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
388 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
389 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
390 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
394 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
398 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
401 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
409 *FinalPhaseArg = PhaseArg;
417 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
418 llvm::sys::fs::OF_Text);
419 llvm::FileRemover OutputRemover(OutputFile.c_str());
420 std::optional<llvm::StringRef> Redirects[] = {
426 std::string ErrorMessage;
427 int SecondsToWait = 60;
428 if (std::optional<std::string> Str =
429 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
430 if (!llvm::to_integer(*Str, SecondsToWait))
431 return llvm::createStringError(std::error_code(),
432 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
433 "an integer, got '" +
435 SecondsToWait = std::max(SecondsToWait, 0);
437 StringRef Executable = Args[0];
438 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
440 return llvm::createStringError(std::error_code(),
441 Executable +
": " + ErrorMessage);
443 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
444 llvm::MemoryBuffer::getFile(OutputFile.c_str());
446 return llvm::createStringError(OutputBuf.getError(),
447 "Failed to read stdout of " + Executable +
448 ": " + OutputBuf.getError().message());
449 return std::move(*OutputBuf);
453 StringRef
Value,
bool Claim) {
454 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
455 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
456 Args.AddSynthesizedArg(A);
462DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
463 const llvm::opt::OptTable &Opts =
getOpts();
464 DerivedArgList *DAL =
new DerivedArgList(Args);
466 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
467 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
468 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
469 bool IgnoreUnused =
false;
470 for (Arg *A : Args) {
474 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
478 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
479 IgnoreUnused =
false;
489 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
490 A->getOption().matches(options::OPT_Xlinker)) &&
491 A->containsValue(
"--no-demangle")) {
493 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
496 for (StringRef Val : A->getValues())
497 if (Val !=
"--no-demangle")
498 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
506 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
507 A->getNumValues() > 0 &&
508 (A->getValue(0) == StringRef(
"-MD") ||
509 A->getValue(0) == StringRef(
"-MMD"))) {
511 if (A->getValue(0) == StringRef(
"-MD"))
512 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
514 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
515 if (A->getNumValues() == 2)
516 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
521 if (A->getOption().matches(options::OPT_l)) {
522 StringRef
Value = A->getValue();
525 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
527 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
532 if (
Value ==
"cc_kext") {
533 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
539 if (A->getOption().matches(options::OPT__DASH_DASH)) {
541 for (StringRef Val : A->getValues())
550 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
551 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
554 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
555 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
559#if defined(HOST_LINK_VERSION)
560 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
561 strlen(HOST_LINK_VERSION) > 0) {
562 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
564 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
572 StringRef ArgTarget) {
574 static bool BeSilent =
false;
575 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
return v < 3; };
578 if (ArgTarget.equals_insensitive(
"CURRENT")) {
582 unsigned int Version = 0;
583 unsigned int Release = 0;
584 unsigned int Modification = 0;
586 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
587 llvm::Regex HexRegex(
590 "([0-9a-fA-F][0-9a-fA-F])"
591 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
594 if (ZOsvRegex.match(ArgTarget, &Matches)) {
595 Matches[1].getAsInteger(10, Version);
596 Matches[2].getAsInteger(10, Release);
598 if (IsTooOldToBeSupported(Version, Release)) {
600 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
603 }
else if (HexRegex.match(ArgTarget, &Matches)) {
604 Matches[1].getAsInteger(16, Version);
605 Matches[2].getAsInteger(16, Release);
606 Matches[3].getAsInteger(16, Modification);
607 if (IsTooOldToBeSupported(Version, Release)) {
609 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
615 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
620 llvm::VersionTuple
V(Version, Release, Modification);
621 llvm::VersionTuple TV =
Target.getOSVersion();
624 if (TV.empty() ||
V < TV) {
626 Str = llvm::Triple::getOSTypeName(
Target.getOS());
627 Str +=
V.getAsString();
641 StringRef ArchName =
"") {
643 if (
const Arg *A = Args.getLastArg(options::OPT_target))
644 TargetTriple = A->getValue();
646 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
651 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
655 if (
Target.isOSBinFormatMachO()) {
657 if (!ArchName.empty()) {
659 return llvm::Triple(
Target.normalize());
663 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
664 StringRef ArchName = A->getValue();
667 }
else if (!ArchName.empty()) {
668 Target.setArchName(ArchName);
674 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
675 options::OPT_mbig_endian)) {
676 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
677 ?
Target.getLittleEndianArchVariant()
678 :
Target.getBigEndianArchVariant();
679 if (
T.getArch() != llvm::Triple::UnknownArch) {
680 Target = llvm::Triple(
T.normalize());
681 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
686 if (
Target.getArch() == llvm::Triple::tce)
692 if (!Args.hasArg(options::OPT_target)) {
693 if (std::optional<std::string> ObjectModeValue =
694 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
695 StringRef ObjectMode = *ObjectModeValue;
696 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
699 const bool OtherAllowedMode =
700 ObjectMode ==
"32_64" || ObjectMode ==
"any";
701 if (ObjectMode ==
"64") {
702 AT =
Target.get64BitArchVariant().getArch();
703 }
else if (ObjectMode ==
"32") {
704 AT =
Target.get32BitArchVariant().getArch();
705 }
else if (!OtherAllowedMode) {
706 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
709 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
718 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
719 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
722 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
724 D.
Diag(diag::err_drv_unsupported_opt_for_target)
725 << A->getAsString(Args) <<
Target.str();
728 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
729 options::OPT_m32, options::OPT_m16,
730 options::OPT_maix32, options::OPT_maix64);
732 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
734 if (A->getOption().matches(options::OPT_m64) ||
735 A->getOption().matches(options::OPT_maix64)) {
736 AT =
Target.get64BitArchVariant().getArch();
737 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
738 Target.getEnvironment() == llvm::Triple::GNUT64)
739 Target.setEnvironment(llvm::Triple::GNU);
740 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
741 Target.setEnvironment(llvm::Triple::Musl);
742 }
else if (A->getOption().matches(options::OPT_mx32) &&
743 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
744 AT = llvm::Triple::x86_64;
745 if (
Target.getEnvironment() == llvm::Triple::Musl)
746 Target.setEnvironment(llvm::Triple::MuslX32);
748 Target.setEnvironment(llvm::Triple::GNUX32);
749 }
else if (A->getOption().matches(options::OPT_m32) ||
750 A->getOption().matches(options::OPT_maix32)) {
752 D.
Diag(diag::err_drv_unsupported_opt_for_target)
753 << A->getAsString(Args) <<
Target.str();
755 AT =
Target.get32BitArchVariant().getArch();
756 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
757 Target.setEnvironment(llvm::Triple::GNU);
758 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
759 Target.setEnvironment(llvm::Triple::Musl);
761 }
else if (A->getOption().matches(options::OPT_m16) &&
762 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
763 AT = llvm::Triple::x86;
764 Target.setEnvironment(llvm::Triple::CODE16);
767 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
769 if (
Target.isWindowsGNUEnvironment())
777 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
783 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
784 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
785 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
788 if (A && !A->getOption().matches(options::OPT_m32))
789 D.
Diag(diag::err_drv_argument_not_allowed_with)
790 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
792 Target.setArch(llvm::Triple::x86);
793 Target.setArchName(
"i586");
794 Target.setEnvironmentName(
"");
795 Target.setOS(llvm::Triple::ELFIAMCU);
796 Target.setVendor(llvm::Triple::Intel);
802 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
803 StringRef ABIName = A->getValue();
804 if (ABIName ==
"32") {
806 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
807 Target.getEnvironment() == llvm::Triple::GNUABIN32)
808 Target.setEnvironment(llvm::Triple::GNU);
809 }
else if (ABIName ==
"n32") {
811 if (
Target.getEnvironment() == llvm::Triple::GNU ||
812 Target.getEnvironment() == llvm::Triple::GNUT64 ||
813 Target.getEnvironment() == llvm::Triple::GNUABI64)
814 Target.setEnvironment(llvm::Triple::GNUABIN32);
815 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
816 Target.getEnvironment() == llvm::Triple::MuslABI64)
817 Target.setEnvironment(llvm::Triple::MuslABIN32);
818 }
else if (ABIName ==
"64") {
820 if (
Target.getEnvironment() == llvm::Triple::GNU ||
821 Target.getEnvironment() == llvm::Triple::GNUT64 ||
822 Target.getEnvironment() == llvm::Triple::GNUABIN32)
823 Target.setEnvironment(llvm::Triple::GNUABI64);
824 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
825 Target.getEnvironment() == llvm::Triple::MuslABIN32)
826 Target.setEnvironment(llvm::Triple::MuslABI64);
836 if (Args.hasArg(options::OPT_march_EQ) ||
837 Args.hasArg(options::OPT_mcpu_EQ)) {
839 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
841 if (!llvm::errorToBool(ISAInfo.takeError())) {
842 unsigned XLen = (*ISAInfo)->getXLen();
844 if (
Target.isLittleEndian())
845 Target.setArch(llvm::Triple::riscv32);
847 Target.setArch(llvm::Triple::riscv32be);
849 }
else if (XLen == 64) {
850 if (
Target.isLittleEndian())
851 Target.setArch(llvm::Triple::riscv64);
853 Target.setArch(llvm::Triple::riscv64be);
860 if (
Target.getArch() == llvm::Triple::riscv32be ||
861 Target.getArch() == llvm::Triple::riscv64be) {
862 static bool WarnedRISCVBE =
false;
863 if (!WarnedRISCVBE) {
864 D.
Diag(diag::warn_drv_riscv_be_experimental);
865 WarnedRISCVBE =
true;
874 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
876 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
878 RuntimeName = A->getValue();
880 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
888 Diag(diag::err_drv_unsupported_option_argument)
889 << A->getSpelling() << A->getValue();
892 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
901 StringRef Program =
C.getArgs().getLastArgValue(
902 options::OPT_offload_arch_tool_EQ,
"offload-arch");
905 if (llvm::ErrorOr<std::string> Executable =
906 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
909 Args.push_back(
"--only=amdgpu");
911 Args.push_back(
"--only=nvptx");
912 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
915 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
920 if ((*StdoutOrErr)->getBuffer().empty()) {
921 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
927 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
929 GPUArchs.push_back(
Arch.str());
931 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
942 std::set<std::string> Archs;
943 for (Arg *A :
C.getInputArgs()) {
944 for (StringRef
Arch : A->getValues()) {
945 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
946 if (
Arch ==
"native") {
948 Archs.insert(Str.str());
950 Archs.insert(
Arch.str());
952 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
956 Archs.erase(
Arch.str());
962 for (llvm::StringRef
Arch : Archs) {
969 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
974 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
979 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
983 if (ID.isUnknown() || ID.isUnused()) {
984 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
985 <<
"offload" <<
Arch;
989 llvm::Triple Triple =
995 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
996 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
997 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
998 C.getArgs().MakeArgString(Triple.getArchName()),
999 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1001 C.getArgs().append(A);
1002 C.getArgs().AddSynthesizedArg(A);
1004 auto It = Triples.lower_bound(Triple);
1005 if (It == Triples.end() || *It != Triple)
1006 Triples.insert(It, Triple);
1011 Triples.insert(llvm::Triple(
"amdgcn-amd-amdhsa"));
1013 llvm::Triple::ArchType
Arch =
1014 C.getDefaultToolChain().getTriple().isArch64Bit()
1015 ? llvm::Triple::nvptx64
1016 : llvm::Triple::nvptx;
1017 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1018 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1021 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1022 ? llvm::Triple::spirv64
1023 : llvm::Triple::spirv32));
1026 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1027 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1034 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1035 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1037 llvm::any_of(Inputs,
1038 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1043 (llvm::any_of(Inputs,
1044 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1047 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1048 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1050 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1051 options::OPT_fno_sycl,
false);
1052 bool IsOpenMPOffloading =
1054 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1055 options::OPT_fno_openmp,
false) &&
1056 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1057 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1058 !(IsCuda || IsHIP))));
1060 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1061 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1066 for (
const auto &[Active, Kind] : ActiveKinds)
1071 if (Kinds.size() > 1) {
1072 Diag(clang::diag::err_drv_mix_offload)
1079 if (IsCuda || IsHIP)
1086 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1087 std::vector<std::string> ArgValues =
1088 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1089 for (llvm::StringRef
Target : ArgValues) {
1093 if (ArgValues.empty())
1094 Diag(clang::diag::warn_drv_empty_joined_argument)
1096 .getLastArg(options::OPT_offload_targets_EQ)
1097 ->getAsString(
C.getInputArgs());
1104 llvm::StringMap<StringRef> FoundNormalizedTriples;
1105 for (
const llvm::Triple &
Target : Triples) {
1110 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1118 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1119 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1120 Diag(clang::diag::err_drv_argument_not_allowed_with)
1121 << IncompatArg->getSpelling() <<
"-fsycl";
1126 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1127 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1132 std::string NormalizedName =
Target.normalize();
1133 auto [TripleIt, Inserted] =
1134 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1136 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1137 <<
Target.str() << TripleIt->second;
1141 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1142 C.getDefaultToolChain().getTriple());
1146 auto &CudaInstallation =
1148 if (CudaInstallation.isValid())
1149 CudaInstallation.WarnIfUnsupportedVersion();
1152 C.addOffloadDeviceToolChain(&TC, Kind);
1157bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1162 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1166 if (!PathLIBEnv.empty()) {
1167 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1168 if (llvm::sys::fs::is_directory(PathLIBEnv))
1169 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1170 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1171 return readConfigFile(CustomizationFile, ExpCtx);
1172 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1177 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1178 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1179 return readConfigFile(CustomizationFile, ExpCtx);
1189 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1190 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1191 Copy->getValues() = Opt->getValues();
1192 if (Opt->isClaimed())
1194 Copy->setOwnsValues(Opt->getOwnsValues());
1195 Opt->setOwnsValues(
false);
1197 if (Opt->getAlias()) {
1198 const Arg *Alias = Opt->getAlias();
1199 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1200 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1201 Args.getArgString(Index), Index);
1202 AliasCopy->getValues() = Alias->getValues();
1203 AliasCopy->setOwnsValues(
false);
1204 if (Alias->isClaimed())
1206 Copy->setAlias(std::move(AliasCopy));
1210bool Driver::readConfigFile(StringRef
FileName,
1211 llvm::cl::ExpansionContext &ExpCtx) {
1215 Diag(diag::err_drv_cannot_open_config_file)
1216 <<
FileName << Status.getError().message();
1219 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1220 Diag(diag::err_drv_cannot_open_config_file)
1221 <<
FileName <<
"not a regular file";
1226 SmallVector<const char *, 32> NewCfgFileArgs;
1227 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1228 Diag(diag::err_drv_cannot_read_config_file)
1234 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1235 for (
const char *Opt : NewCfgFileArgs) {
1237 if (Opt[0] ==
'$' && Opt[1])
1238 NewCfgTailArgs.push_back(Opt + 1);
1240 NewCfgHeadArgs.push_back(Opt);
1244 llvm::SmallString<128> CfgFileName(
FileName);
1245 llvm::sys::path::native(CfgFileName);
1246 bool ContainErrors =
false;
1247 auto NewHeadOptions = std::make_unique<InputArgList>(
1251 auto NewTailOptions = std::make_unique<InputArgList>(
1258 for (Arg *A : *NewHeadOptions)
1260 for (Arg *A : *NewTailOptions)
1263 if (!CfgOptionsHead)
1264 CfgOptionsHead = std::move(NewHeadOptions);
1267 for (
auto *Opt : *NewHeadOptions)
1271 if (!CfgOptionsTail)
1272 CfgOptionsTail = std::move(NewTailOptions);
1275 for (
auto *Opt : *NewTailOptions)
1279 ConfigFiles.push_back(std::string(CfgFileName));
1283bool Driver::loadConfigFiles() {
1284 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1285 llvm::cl::tokenizeConfigFile, &
getVFS());
1289 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1290 SmallString<128> CfgDir;
1292 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1293 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1298 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1299 SmallString<128> CfgDir;
1300 llvm::sys::fs::expand_tilde(
1301 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1302 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1311 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1314 if (loadDefaultConfigFiles(ExpCtx))
1318 SmallString<128> CfgFilePath;
1320 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1323 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1324 CfgFilePath.assign(CfgFileName);
1325 if (llvm::sys::path::is_relative(CfgFilePath)) {
1326 if (
getVFS().makeAbsolute(CfgFilePath)) {
1327 Diag(diag::err_drv_cannot_open_config_file)
1328 << CfgFilePath <<
"cannot get absolute path";
1332 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1334 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1335 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1336 if (!SearchDir.empty())
1337 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1342 if (readConfigFile(CfgFilePath, ExpCtx))
1353 llvm::Triple Triple, std::string Suffix) {
1355 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1359 VersionTuple OSVersion = Triple.getOSVersion();
1360 if (!OSVersion.getMinor().has_value())
1363 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1367 if (OSVersion.getMajor() != 0) {
1368 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1369 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1375 Triple.setOSName(BaseOSName);
1376 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1379bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1382 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1386 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1389 std::string RealMode = getExecutableForDriverMode(Mode);
1390 llvm::Triple Triple;
1399 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1400 PrefixTriple.isOSUnknown())
1401 Triple = std::move(PrefixTriple);
1405 llvm::Triple RealTriple =
1407 if (Triple.str().empty()) {
1408 Triple = RealTriple;
1409 assert(!Triple.str().empty());
1414 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1428 SmallString<128> CfgFilePath;
1430 "-" + RealMode +
".cfg"))
1431 return readConfigFile(CfgFilePath, ExpCtx);
1435 if (TryModeSuffix) {
1438 return readConfigFile(CfgFilePath, ExpCtx);
1443 std::string CfgFileName = RealMode +
".cfg";
1444 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1445 if (readConfigFile(CfgFilePath, ExpCtx))
1447 }
else if (TryModeSuffix) {
1449 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1450 readConfigFile(CfgFilePath, ExpCtx))
1456 return readConfigFile(CfgFilePath, ExpCtx);
1464 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1473 if (!DriverMode.empty())
1474 setDriverMode(DriverMode);
1480 CLOptions = std::make_unique<InputArgList>(
1485 ContainsError = loadConfigFiles();
1486 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1487 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1491 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1493 if (HasConfigFileHead)
1494 for (
auto *Opt : *CLOptions)
1495 if (!Opt->getOption().matches(options::OPT_config))
1499 if (
IsCLMode() && !ContainsError) {
1501 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1503 CLModePassThroughArgList.push_back(A->getValue());
1506 if (!CLModePassThroughArgList.empty()) {
1509 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1514 for (
auto *Opt : *CLModePassThroughOptions)
1520 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1521 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1522 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1525 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1526 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1527 if (!VFS->exists(IncludeDir))
1528 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1533 bool CCCPrintPhases;
1536 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1537 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1540 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1541 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1544 Args.ClaimAllArgs(options::OPT_pipe);
1552 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1554 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1555 CCCGenericGCCName = A->getValue();
1558 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1562 if (Args.hasArg(options::OPT_fproc_stat_report))
1569 llvm::Triple
T(TargetTriple);
1570 T.setOS(llvm::Triple::Win32);
1571 T.setVendor(llvm::Triple::PC);
1572 T.setEnvironment(llvm::Triple::MSVC);
1573 T.setObjectFormat(llvm::Triple::COFF);
1574 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1575 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1576 TargetTriple =
T.str();
1579 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1580 StringRef TargetProfile = A->getValue();
1583 TargetTriple = *Triple;
1585 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1589 if (Args.hasArg(options::OPT_spirv)) {
1590 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1591 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1592 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1593 llvm::Triple
T(TargetTriple);
1596 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1598 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1599 TargetInfo = ValidTargets.find(A->getValue());
1601 Diag(diag::err_drv_invalid_value)
1602 << A->getAsString(Args) << A->getValue();
1608 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1609 TargetTriple =
T.str();
1613 Diag(diag::err_drv_dxc_missing_target_profile);
1617 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1618 TargetTriple = A->getValue();
1619 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1620 Dir = A->getValue();
1621 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1625 if (std::optional<std::string> CompilerPathValue =
1626 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1627 StringRef CompilerPath = *CompilerPathValue;
1628 while (!CompilerPath.empty()) {
1629 std::pair<StringRef, StringRef> Split =
1630 CompilerPath.split(llvm::sys::EnvPathSeparator);
1631 PrefixDirs.push_back(std::string(Split.first));
1632 CompilerPath = Split.second;
1635 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1637 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1640 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1643 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1644 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1645 .Case(
"cwd", SaveTempsCwd)
1646 .Case(
"obj", SaveTempsObj)
1647 .Default(SaveTempsCwd);
1650 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1651 options::OPT_offload_device_only,
1652 options::OPT_offload_host_device)) {
1653 if (A->getOption().matches(options::OPT_offload_host_only))
1654 Offload = OffloadHost;
1655 else if (A->getOption().matches(options::OPT_offload_device_only))
1656 Offload = OffloadDevice;
1658 Offload = OffloadHostDevice;
1662 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1663 StringRef
Name = A->getValue();
1664 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1665 .Case(
"off", EmbedNone)
1666 .Case(
"all", EmbedBitcode)
1667 .Case(
"bitcode", EmbedBitcode)
1668 .Case(
"marker", EmbedMarker)
1671 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1674 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1678 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1679 llvm::sys::fs::remove(A->getValue());
1685 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1687 !Args.hasArg(options::OPT_fmodules) && Std &&
1688 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1689 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1690 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1691 Std->containsValue(
"c++2d") || Std->containsValue(
"c++latest"));
1694 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1695 options::OPT_fmodule_header)) {
1697 ModulesModeCXX20 =
true;
1698 if (A->getOption().matches(options::OPT_fmodule_header))
1701 StringRef ArgName = A->getValue();
1702 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1707 Diags.Report(diag::err_drv_invalid_value)
1708 << A->getAsString(Args) << ArgName;
1714 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1715 std::make_unique<InputArgList>(std::move(Args));
1725 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1726 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1728 bool MLContainsError;
1729 auto MultilibMacroDefineList =
1731 MLMacroDefinesChar,
false, MLContainsError));
1732 if (!MLContainsError) {
1733 for (
auto *Opt : *MultilibMacroDefineList) {
1740 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1744 if (!Triple.isWasm()) {
1745 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1746 StringRef TripleObjectFormat =
1747 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1748 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1749 TripleVersionName != TripleObjectFormat) {
1750 Diags.Report(diag::err_drv_triple_version_invalid)
1752 ContainsError =
true;
1757 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1758 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1759 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1767 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1768 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1770 case llvm::Triple::arm:
1771 case llvm::Triple::armeb:
1772 case llvm::Triple::thumb:
1773 case llvm::Triple::thumbeb:
1774 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1775 Diag(diag::warn_target_unrecognized_env)
1777 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1780 case llvm::Triple::aarch64:
1781 case llvm::Triple::aarch64_be:
1782 case llvm::Triple::aarch64_32:
1783 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1784 Diag(diag::warn_target_unrecognized_env)
1786 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1803 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1804 if (HasConfigFileTail && Inputs.size()) {
1807 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1808 for (Arg *A : *CfgOptionsTail)
1809 TranslatedLinkerIns.append(A);
1810 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1817 bool UseModulesDriver =
C->getArgs().hasFlag(
1818 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1820 if (UseModulesDriver) {
1821 Diags.Report(diag::remark_performing_driver_managed_module_build);
1829 const auto StdModuleManifestPath =
1832 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1833 Diags.Report(diag::remark_modules_manifest_not_found);
1835 Diags.Report(diag::remark_using_modules_manifest)
1836 << StdModuleManifestPath;
1837 if (
auto ManifestOrErr =
1839 ModulesManifest = std::move(*ManifestOrErr);
1841 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1842 return !ModuleEntry.IsStdlib;
1847 llvm::handleAllErrors(
1848 ManifestOrErr.takeError(),
1849 [&](llvm::json::ParseError &Err) {
1850 Diags.Report(diag::err_modules_manifest_failed_parse)
1853 [&](llvm::FileError &Err) {
1854 Diags.Report(diag::err_cannot_open_file)
1855 << Err.getFileName() << Err.messageWithoutFileInfo();
1863 if (TC.
getTriple().isOSBinFormatMachO())
1868 if (CCCPrintPhases) {
1875 if (UseModulesDriver)
1882 llvm::opt::ArgStringList ASL;
1883 for (
const auto *A : Args) {
1887 while (A->getAlias())
1889 A->render(Args, ASL);
1892 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1893 if (I != ASL.begin())
1895 llvm::sys::printArg(OS, *I,
true);
1900bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1901 SmallString<128> &CrashDiagDir) {
1902 using namespace llvm::sys;
1903 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1904 "Only knows about .crash files on Darwin");
1906 auto BypassSandbox = sandbox::scopedDisable();
1911 path::home_directory(CrashDiagDir);
1912 if (CrashDiagDir.starts_with(
"/var/root"))
1914 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1922 fs::file_status FileStatus;
1923 TimePoint<> LastAccessTime;
1924 SmallString<128> CrashFilePath;
1927 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1928 File != FileEnd && !EC;
File.increment(EC)) {
1932 if (fs::status(
File->path(), FileStatus))
1934 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1935 llvm::MemoryBuffer::getFile(
File->path());
1940 StringRef
Data = CrashFile.get()->getBuffer();
1941 if (!
Data.starts_with(
"Process:"))
1944 size_t ParentProcPos =
Data.find(
"Parent Process:");
1945 if (ParentProcPos == StringRef::npos)
1947 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1948 if (LineEnd == StringRef::npos)
1950 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1951 int OpenBracket = -1, CloseBracket = -1;
1952 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1953 if (ParentProcess[i] ==
'[')
1955 if (ParentProcess[i] ==
']')
1961 if (OpenBracket < 0 || CloseBracket < 0 ||
1962 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1963 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1973 const auto FileAccessTime = FileStatus.getLastModificationTime();
1974 if (FileAccessTime > LastAccessTime) {
1975 CrashFilePath.assign(
File->path());
1976 LastAccessTime = FileAccessTime;
1981 if (!CrashFilePath.empty()) {
1982 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1992 "\n********************\n\n"
1993 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
2001 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2004 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
2007 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2008 Level = llvm::StringSwitch<unsigned>(A->getValue())
2010 .Case(
"compiler", 1)
2022 ArgStringList SavedTemps;
2024 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2025 if (!IsLLD || Level < 2)
2032 SavedTemps = std::move(
C.getTempFiles());
2033 assert(!
C.getTempFiles().size());
2050 C.initCompilationForDiagnostics();
2055 Command NewLLDInvocation = Cmd;
2056 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2057 StringRef ReproduceOption =
2058 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2061 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2065 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2067 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2068 Diag(clang::diag::note_drv_command_failed_diag_msg)
2069 <<
"\n\n********************";
2071 Report->TemporaryFiles.push_back(TmpName);
2079 ArgStringList IRInputs;
2080 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2081 bool IgnoreInput =
false;
2087 IRInputs.push_back(it->second->getValue());
2091 }
else if (!strcmp(it->second->getValue(),
"-")) {
2092 Diag(clang::diag::note_drv_command_failed_diag_msg)
2093 <<
"Error generating preprocessed source(s) - "
2094 "ignoring input from stdin.";
2099 it = Inputs.erase(it);
2106 if (Inputs.empty() && IRInputs.empty()) {
2107 Diag(clang::diag::note_drv_command_failed_diag_msg)
2108 <<
"Error generating preprocessed source(s) - "
2109 "no preprocessable inputs.";
2115 llvm::StringSet<> ArchNames;
2116 for (
const Arg *A :
C.getArgs()) {
2117 if (A->getOption().matches(options::OPT_arch)) {
2118 StringRef ArchName = A->getValue();
2119 ArchNames.insert(ArchName);
2122 if (ArchNames.size() > 1) {
2125 if (FailingArch.empty()) {
2126 Diag(clang::diag::note_drv_command_failed_diag_msg)
2127 <<
"Error generating preprocessed source(s) - cannot generate "
2128 "preprocessed source with multiple -arch options.";
2131 C.getArgs().eraseArg(options::OPT_arch);
2132 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2137 if (!Inputs.empty()) {
2140 const ToolChain &TC =
C.getDefaultToolChain();
2141 if (TC.
getTriple().isOSBinFormatMachO())
2150 Diag(clang::diag::note_drv_command_failed_diag_msg)
2151 <<
"Error generating preprocessed source(s).";
2156 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2159 if (!FailingCommands.empty()) {
2160 Diag(clang::diag::note_drv_command_failed_diag_msg)
2161 <<
"Error generating preprocessed source(s).";
2165 const ArgStringList &TempFiles =
C.getTempFiles();
2166 if (TempFiles.empty()) {
2167 Diag(clang::diag::note_drv_command_failed_diag_msg)
2168 <<
"Error generating preprocessed source(s).";
2174 const ArgStringList &Files =
C.getTempFiles();
2179 for (
auto const *Input : IRInputs) {
2183 StringRef extension = llvm::sys::path::extension(Input);
2184 if (!extension.empty())
2185 extension = extension.drop_front();
2187 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2188 llvm::sys::path::stem(Input), extension, FD, Path);
2190 Diag(clang::diag::note_drv_command_failed_diag_msg)
2191 <<
"Error generating run script: " <<
"Failed copying IR input files"
2192 <<
" " << EC.message();
2196 EC = llvm::sys::fs::copy_file(Input, FD);
2198 Diag(clang::diag::note_drv_command_failed_diag_msg)
2199 <<
"Error generating run script: " <<
"Failed copying IR input files"
2200 <<
" " << EC.message();
2204 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2211 for (std::string &TempFile : TempFiles) {
2213 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2215 Report->TemporaryFiles.push_back(TempFile);
2216 if (ReproCrashFilename.empty()) {
2217 ReproCrashFilename = TempFile;
2218 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2220 if (StringRef(TempFile).ends_with(
".cache")) {
2223 VFS = llvm::sys::path::filename(TempFile);
2224 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2228 for (
const char *TempFile : SavedTemps)
2229 TempFiles.push_back(TempFile);
2235 llvm::sys::path::replace_extension(Script,
"sh");
2237 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2238 llvm::sys::fs::FA_Write,
2239 llvm::sys::fs::OF_Text);
2241 Diag(clang::diag::note_drv_command_failed_diag_msg)
2242 <<
"Error generating run script: " << Script <<
" " << EC.message();
2245 <<
"# Driver args: ";
2247 ScriptOS <<
"# Original command: ";
2248 Cmd.
Print(ScriptOS,
"\n",
true);
2249 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2250 if (!AdditionalInformation.empty())
2251 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2254 Report->TemporaryFiles.push_back(std::string(Script));
2255 TempFiles.push_back(std::string(Script));
2258 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2261 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2262 StringRef CrashDiagnosticsTar = A->getValue();
2264 llvm::TarWriter::create(CrashDiagnosticsTar,
2265 llvm::sys::path::stem(CrashDiagnosticsTar));
2267 Diag(clang::diag::note_drv_command_failed_diag_msg)
2268 << (std::string(
"Error creating reproducer tarball: ") +
2269 llvm::toString(TarOrErr.takeError()));
2271 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2272 for (
const std::string &TempFile : TempFiles) {
2273 if (llvm::sys::fs::is_directory(TempFile)) {
2275 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2276 I != E && !EC; I.increment(EC)) {
2277 if (llvm::sys::fs::is_regular_file(I->path())) {
2278 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2282 llvm::sys::path::filename(TempFile);
2283 StringRef SubPath = I->path();
2284 if (SubPath.consume_front(TempFile)) {
2285 if (!SubPath.empty() &&
2286 llvm::sys::path::is_separator(SubPath.front())) {
2287 SubPath = SubPath.drop_front();
2289 llvm::sys::path::append(PathInTar, SubPath);
2290 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2293 Diag(clang::diag::note_drv_command_failed_diag_msg)
2294 << (std::string(
"Error reading file for tarball: ") +
2300 Diag(clang::diag::note_drv_command_failed_diag_msg)
2301 << (std::string(
"Error iterating directory for tarball: ") +
2302 TempFile +
" " + EC.message());
2305 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2307 Tar->append(llvm::sys::path::filename(TempFile),
2308 (*BufferOrErr)->getBuffer());
2310 Diag(clang::diag::note_drv_command_failed_diag_msg)
2311 << (std::string(
"Error reading file for tarball: ") + TempFile);
2315 Diag(clang::diag::note_drv_command_failed_diag_msg)
2316 << CrashDiagnosticsTar;
2321 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2323 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2324 Diag(clang::diag::note_drv_command_failed_diag_msg)
2325 << ReproCrashFilename.str();
2327 llvm::sys::path::append(CrashDiagDir,
Name);
2328 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2329 Diag(clang::diag::note_drv_command_failed_diag_msg)
2330 <<
"Crash backtrace is located in";
2331 Diag(clang::diag::note_drv_command_failed_diag_msg)
2332 << CrashDiagDir.str();
2333 Diag(clang::diag::note_drv_command_failed_diag_msg)
2334 <<
"(choose the .crash file that corresponds to your crash)";
2338 Diag(clang::diag::note_drv_command_failed_diag_msg)
2339 <<
"\n\n********************";
2349 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2360 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2361 if (
C.getArgs().hasArg(options::OPT_v))
2362 C.getJobs().Print(llvm::errs(),
"\n",
true);
2364 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2367 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2374 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2375 C.getJobs().Print(llvm::errs(),
"\n",
true);
2376 return Diags.hasErrorOccurred() ? 1 : 0;
2380 if (Diags.hasErrorOccurred())
2384 for (
auto &Job :
C.getJobs())
2385 setUpResponseFiles(
C, Job);
2387 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2390 if (FailingCommands.empty())
2396 for (
const auto &CmdPair : FailingCommands) {
2397 int CommandRes = CmdPair.first;
2398 const Command *FailingCommand = CmdPair.second;
2403 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2407 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2412 if (CommandRes == EX_IOERR) {
2432 if (CommandRes > 128 && CommandRes != 255)
2436 Diag(clang::diag::err_drv_command_signalled)
2439 Diag(clang::diag::err_drv_command_failed)
2447 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2449 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2463 const ToolChain &TC =
C.getDefaultToolChain();
2467 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2470 OS <<
"Thread model: " << A->getValue();
2476 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2481 if (!llvm::cl::getCompilerBuildConfig().empty())
2482 llvm::cl::printBuildConfig(OS);
2485 for (
auto ConfigFile : ConfigFiles)
2486 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2499 if (PassedFlags ==
"")
2503 std::vector<std::string> SuggestedCompletions;
2504 std::vector<std::string> Flags;
2516 const bool HasSpace = PassedFlags.ends_with(
",");
2520 StringRef TargetFlags = PassedFlags;
2521 while (TargetFlags !=
"") {
2523 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2524 Flags.push_back(std::string(CurFlag));
2529 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2532 const llvm::opt::OptTable &Opts =
getOpts();
2534 Cur = Flags.at(Flags.size() - 1);
2536 if (Flags.size() >= 2) {
2537 Prev = Flags.at(Flags.size() - 2);
2538 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2541 if (SuggestedCompletions.empty())
2542 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2549 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2550 llvm::outs() <<
'\n';
2556 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2560 SuggestedCompletions = Opts.findByPrefix(
2561 Cur, VisibilityMask,
2568 if (S.starts_with(Cur))
2569 SuggestedCompletions.push_back(std::string(S));
2576 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2577 if (
int X = A.compare_insensitive(B))
2579 return A.compare(B) > 0;
2582 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2589 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2590 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2594 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2597 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2601 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2606 if (
C.getArgs().hasArg(options::OPT_help) ||
2607 C.getArgs().hasArg(options::OPT__help_hidden)) {
2608 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2612 if (
C.getArgs().hasArg(options::OPT__version)) {
2619 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2620 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2621 if (ListExtractors || ListFormats) {
2629 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2634 if (
C.getArgs().hasArg(options::OPT_v) ||
2635 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2636 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2637 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2638 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2640 SuppressMissingInputWarning =
true;
2643 if (
C.getArgs().hasArg(options::OPT_v)) {
2645 llvm::errs() <<
"System configuration file directory: "
2648 llvm::errs() <<
"User configuration file directory: "
2652 const ToolChain &TC =
C.getDefaultToolChain();
2654 if (
C.getArgs().hasArg(options::OPT_v))
2657 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2662 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2663 llvm::outs() <<
"programs: =";
2664 bool separator =
false;
2668 llvm::outs() << llvm::sys::EnvPathSeparator;
2669 llvm::outs() << Path;
2674 llvm::outs() << llvm::sys::EnvPathSeparator;
2675 llvm::outs() << Path;
2678 llvm::outs() <<
"\n";
2681 StringRef sysroot =
C.getSysRoot();
2685 llvm::outs() << llvm::sys::EnvPathSeparator;
2688 llvm::outs() << sysroot << Path.substr(1);
2690 llvm::outs() << Path;
2692 llvm::outs() <<
"\n";
2696 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib)) {
2701 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib_include_dirs)) {
2706 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2712 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2713 for (
auto RuntimePath :
2715 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2716 llvm::outs() << *RuntimePath <<
'\n';
2720 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2724 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2726 for (std::size_t I = 0; I != Flags.size(); I += 2)
2727 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2733 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2734 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2738 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2739 StringRef ProgName = A->getValue();
2742 if (! ProgName.empty())
2745 llvm::outs() <<
"\n";
2749 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2750 StringRef PassedFlags = A->getValue();
2755 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2765 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2770 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2773 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2779 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2786 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2789 std::set<llvm::StringRef> SortedFlags;
2790 for (
const auto &FlagEntry : ExpandedFlags)
2791 SortedFlags.insert(FlagEntry.getKey());
2792 for (
auto Flag : SortedFlags)
2793 llvm::outs() << Flag <<
'\n';
2797 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2800 llvm::outs() <<
".\n";
2803 assert(Suffix.front() ==
'/');
2804 llvm::outs() << Suffix.substr(1) <<
"\n";
2810 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2815 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2817 llvm::outs() << Triple.getTriple() <<
"\n";
2821 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2822 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2839 std::map<Action *, unsigned> &Ids,
2841 if (
auto It = Ids.find(A); It != Ids.end())
2845 llvm::raw_string_ostream os(str);
2847 auto getSibIndent = [](
int K) -> Twine {
2851 Twine SibIndent =
Indent + getSibIndent(Kind);
2855 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2857 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2858 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2859 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2861 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2862 assert(TC &&
"Unknown host toolchain");
2877 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2885 const char *Prefix =
"{";
2886 for (
Action *PreRequisite : *AL) {
2887 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2898 std::string offload_str;
2899 llvm::raw_string_ostream offload_os(offload_str);
2903 offload_os <<
", (" << S;
2910 auto getSelfIndent = [](
int K) -> Twine {
2914 unsigned Id = Ids.size();
2916 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2925 std::map<Action *, unsigned> Ids;
2926 for (
Action *A :
C.getActions())
2942 DerivedArgList &Args =
C.getArgs();
2944 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2947 llvm::StringSet<> ArchNames;
2949 for (Arg *A : Args) {
2950 if (A->getOption().matches(options::OPT_arch)) {
2953 llvm::Triple::ArchType
Arch =
2955 if (
Arch == llvm::Triple::UnknownArch) {
2956 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2961 if (ArchNames.insert(A->getValue()).second)
2962 Archs.push_back(A->getValue());
2976 for (
Action* Act : SingleActions) {
2984 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2988 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2993 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2994 Actions.append(Inputs.begin(), Inputs.end());
2996 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2999 Arg *A = Args.getLastArg(options::OPT_g_Group);
3000 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
3001 !A->getOption().matches(options::OPT_gstabs);
3002 bool enablesPseudoProbe =
3003 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
3004 options::OPT_fno_pseudo_probe_for_profiling,
false);
3005 bool enablesDebugInfoForProfiling =
3006 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
3007 options::OPT_fno_debug_info_for_profiling,
false);
3008 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
3009 enablesDebugInfoForProfiling) &&
3017 if (Act->getType() == types::TY_Image) {
3019 Inputs.push_back(Actions.back());
3026 if (Args.hasArg(options::OPT_verify_debug_info)) {
3027 Action *LastAction = Actions.pop_back_val();
3029 LastAction, types::TY_Nothing));
3036 bool TypoCorrect)
const {
3048 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3049 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3061 std::string Nearest;
3062 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3063 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3064 <<
Value << Nearest;
3103 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3106 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3114 return types::TY_CXXUHeader;
3116 return types::TY_CXXSHeader;
3120 llvm_unreachable(
"should not be called in this case");
3122 return types::TY_CXXHUHeader;
3128 const llvm::opt::OptTable &Opts =
getOpts();
3132 types::ID InputType = types::TY_Nothing;
3133 Arg *InputTypeArg =
nullptr;
3136 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3137 options::OPT__SLASH_TP)) {
3138 InputTypeArg = TCTP;
3139 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3144 bool ShowNote =
false;
3146 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3148 Diag(clang::diag::warn_drv_overriding_option)
3149 <<
Previous->getSpelling() << A->getSpelling();
3155 Diag(clang::diag::note_drv_t_option_is_global);
3160 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3161 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3162 if (LastXArg && LastInputArg &&
3163 LastInputArg->getIndex() < LastXArg->getIndex())
3164 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3167 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3169 for (Arg *A : Args) {
3170 if (A->getOption().
getKind() == Option::InputClass) {
3171 const char *
Value = A->getValue();
3175 if (InputType == types::TY_Nothing) {
3178 InputTypeArg->claim();
3181 if (strcmp(
Value,
"-") == 0) {
3183 Ty = types::TY_Fortran;
3185 Ty = types::TY_HLSL;
3186 }
else if (IsSYCL) {
3196 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3197 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3198 : clang::diag::err_drv_unknown_stdin_type);
3207 if (
const char *Ext = strrchr(
Value,
'.'))
3216 Ty = types::TY_HLSL;
3218 Ty = types::TY_Object;
3229 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3230 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3231 << getTypeName(OldTy) << getTypeName(Ty);
3236 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3237 Ty == types::TY_Object)
3238 Ty = types::TY_LLVM_BC;
3246 if (Ty != types::TY_Object) {
3247 if (Args.hasArg(options::OPT_ObjC))
3248 Ty = types::TY_ObjC;
3249 else if (Args.hasArg(options::OPT_ObjCXX))
3250 Ty = types::TY_ObjCXX;
3257 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3261 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3262 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3265 const char *Ext = strrchr(
Value,
'.');
3267 Ty = types::TY_Object;
3271 InputTypeArg->claim();
3275 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3276 Args.hasArgNoClaim(options::OPT_hipstdpar))
3280 Inputs.push_back(std::make_pair(Ty, A));
3282 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3283 StringRef
Value = A->getValue();
3286 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3287 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3290 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3291 StringRef
Value = A->getValue();
3294 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3295 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3301 Inputs.push_back(std::make_pair(types::TY_Object, A));
3303 }
else if (A->getOption().matches(options::OPT_x)) {
3312 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3313 InputType = types::TY_Object;
3320 }
else if (A->getOption().getID() == options::OPT_U) {
3321 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3322 StringRef Val = A->getValue(0);
3323 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3325 Diag(diag::warn_slash_u_filename) << Val;
3326 Diag(diag::note_use_dashdash);
3330 if (
CCCIsCPP() && Inputs.empty()) {
3334 Inputs.push_back(std::make_pair(types::TY_C, A));
3341class OffloadingActionBuilder final {
3343 bool IsValid =
false;
3349 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3352 std::map<Action *, const Arg *> HostActionToInputArgMap;
3355 class DeviceActionBuilder {
3359 enum ActionBuilderReturnCode {
3377 const ToolChain *FatBinaryToolChain =
nullptr;
3380 DerivedArgList &Args;
3389 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3392 :
C(
C), Args(Args), Inputs(Inputs),
3393 AssociatedOffloadKind(AssociatedOffloadKind) {}
3394 virtual ~DeviceActionBuilder() {}
3399 virtual ActionBuilderReturnCode
3400 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3403 return ABRT_Inactive;
3408 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3409 return ABRT_Inactive;
3413 virtual void appendTopLevelActions(
ActionList &AL) {}
3416 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3419 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3422 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3426 virtual bool initialize() {
return false; }
3429 virtual bool canUseBundlerUnbundler()
const {
return false; }
3433 bool isValid() {
return !ToolChains.empty(); }
3437 return AssociatedOffloadKind;
3443 class CudaActionBuilderBase :
public DeviceActionBuilder {
3447 bool CompileHostOnly =
false;
3448 bool CompileDeviceOnly =
false;
3450 bool EmitAsm =
false;
3453 SmallVector<BoundArch, 4> GpuArchList;
3459 Action *CudaFatBinary =
nullptr;
3462 bool IsActive =
false;
3465 bool Relocatable =
false;
3471 const CUIDOptions &CUIDOpts;
3474 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3476 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3477 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3479 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3480 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3481 options::OPT_fno_gpu_rdc,
false);
3484 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3491 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3494 if (!(IA->getType() == types::TY_CUDA ||
3495 IA->getType() == types::TY_HIP ||
3496 IA->getType() == types::TY_PP_HIP)) {
3499 return ABRT_Inactive;
3506 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3508 if (CompileHostOnly)
3509 return ABRT_Success;
3512 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3513 : types::TY_CUDA_DEVICE;
3514 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3515 CudaDeviceActions.push_back(
3516 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3519 return ABRT_Success;
3523 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3527 if (UA->getType() == types::TY_Object && !Relocatable)
3528 return ABRT_Inactive;
3530 CudaDeviceActions.clear();
3532 std::string
FileName = IA->getInputArg().getAsString(Args);
3538 const StringRef LibFileExt =
".lib";
3539 if (IA->getType() == types::TY_Object &&
3540 (!llvm::sys::path::has_extension(
FileName) ||
3542 llvm::sys::path::extension(
FileName).drop_front()) !=
3544 llvm::sys::path::extension(
FileName) == LibFileExt))
3545 return ABRT_Inactive;
3547 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3548 CudaDeviceActions.push_back(UA);
3549 UA->registerDependentActionInfo(ToolChain,
Arch,
3550 AssociatedOffloadKind);
3553 return ABRT_Success;
3556 return IsActive ? ABRT_Success : ABRT_Inactive;
3559 void appendTopLevelActions(
ActionList &AL)
override {
3561 auto AddTopLevel = [&](Action *A, BoundArch BA,
const ToolChain *TC) {
3562 OffloadAction::DeviceDependences Dep;
3563 Dep.
add(*A, *TC, BA, AssociatedOffloadKind);
3564 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3568 if (CudaFatBinary) {
3569 AddTopLevel(CudaFatBinary, {}, FatBinaryToolChain);
3570 CudaDeviceActions.clear();
3571 CudaFatBinary =
nullptr;
3575 if (CudaDeviceActions.empty())
3581 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3582 "Expecting one action per GPU architecture.");
3583 assert(ToolChains.size() == GpuArchList.size() &&
3584 "Expecting to have a toolchain per GPU architecture");
3585 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3586 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3588 CudaDeviceActions.clear();
3591 bool initialize()
override {
3606 assert(HostTC &&
"No toolchain for host compilation.");
3611 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3616 std::set<std::pair<BoundArch, const ToolChain *>> GpuArchs;
3618 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3620 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3621 GpuArchs.insert({
Arch, I.second});
3625 for (
auto [
Arch, TC] : GpuArchs) {
3626 GpuArchList.push_back(
Arch);
3627 ToolChains.push_back(TC);
3630 FatBinaryToolChain = ToolChains.front();
3631 CompileHostOnly =
C.getDriver().offloadHostOnly();
3632 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3633 EmitAsm = Args.getLastArg(options::OPT_S);
3641 class CudaActionBuilder final :
public CudaActionBuilderBase {
3643 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3645 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3649 ActionBuilderReturnCode
3650 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3652 PhasesTy &Phases)
override {
3654 return ABRT_Inactive;
3658 if (CudaDeviceActions.empty())
3659 return ABRT_Success;
3661 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3662 "Expecting one action per GPU architecture.");
3663 assert(!CompileHostOnly &&
3664 "Not expecting CUDA actions in host-only compilation.");
3674 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3677 for (
auto Ph : Phases) {
3682 if (Ph > FinalPhase)
3685 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3700 Action *AssembleAction = CudaDeviceActions[I];
3701 assert(AssembleAction->
getType() == types::TY_Object);
3702 assert(AssembleAction->
getInputs().size() == 1);
3708 OffloadAction::DeviceDependences DDep;
3710 DeviceActions.push_back(
3711 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3716 if (!DeviceActions.empty()) {
3718 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3720 if (!CompileDeviceOnly) {
3721 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3725 CudaFatBinary =
nullptr;
3730 CudaDeviceActions.clear();
3734 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3739 return ABRT_Success;
3743 "instructions should only occur "
3744 "before the backend phase!");
3747 for (Action *&A : CudaDeviceActions)
3748 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3750 return ABRT_Success;
3755 class HIPActionBuilder final :
public CudaActionBuilderBase {
3757 SmallVector<ActionList, 8> DeviceLinkerInputs;
3763 std::optional<bool> BundleOutput;
3764 std::optional<bool> EmitReloc;
3767 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3769 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3773 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3774 options::OPT_fno_hip_emit_relocatable)) {
3775 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3776 options::OPT_fno_hip_emit_relocatable,
false);
3780 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3781 <<
"-fhip-emit-relocatable"
3785 if (!CompileDeviceOnly) {
3786 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3787 <<
"-fhip-emit-relocatable"
3788 <<
"--offload-device-only";
3793 if (Args.hasArg(options::OPT_gpu_bundle_output,
3794 options::OPT_no_gpu_bundle_output))
3795 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3796 options::OPT_no_gpu_bundle_output,
true) &&
3797 (!EmitReloc || !*EmitReloc);
3800 bool canUseBundlerUnbundler()
const override {
return true; }
3802 ActionBuilderReturnCode
3803 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3805 PhasesTy &Phases)
override {
3807 return ABRT_Inactive;
3813 if (CudaDeviceActions.empty())
3814 return ABRT_Success;
3817 CudaDeviceActions.size() == GpuArchList.size()) &&
3818 "Expecting one action per GPU architecture.");
3819 assert(!CompileHostOnly &&
3820 "Not expecting HIP actions in host-only compilation.");
3822 bool ShouldLink = !EmitReloc || !*EmitReloc;
3825 !EmitAsm && ShouldLink) {
3831 bool ExplicitOffloadLTO = Args.hasArg(options::OPT_foffload_lto,
3832 options::OPT_foffload_lto_EQ);
3833 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3834 if (ExplicitOffloadLTO &&
3835 ToolChains[I]->isUsingLTO(Args, AssociatedOffloadKind)) {
3839 AL.push_back(CudaDeviceActions[I]);
3842 CudaDeviceActions[I] =
3843 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3849 if (ToolChains[I]->
getTriple().isSPIRV() ||
3850 (ToolChains[I]->
getTriple().isAMDGCN() &&
3851 GpuArchList[I].ArchName == StringRef(
"amdgcnspirv"))) {
3855 types::ID Output = Args.hasArg(options::OPT_S)
3857 : types::TY_LLVM_BC;
3859 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3865 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3867 AssociatedOffloadKind);
3868 AL.push_back(AssembleAction);
3871 CudaDeviceActions[I] =
3872 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3881 OffloadAction::DeviceDependences DDep;
3882 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3883 AssociatedOffloadKind);
3884 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3885 DDep, CudaDeviceActions[I]->getType());
3888 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3890 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3891 types::TY_HIP_FATBIN);
3893 if (!CompileDeviceOnly) {
3894 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3895 AssociatedOffloadKind);
3898 CudaFatBinary =
nullptr;
3903 CudaDeviceActions.clear();
3906 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3909 return ABRT_Success;
3915 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3916 auto LI = DeviceLinkerInputs.begin();
3917 for (
auto *A : CudaDeviceActions) {
3924 CudaDeviceActions.clear();
3925 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3929 for (
unsigned I = 0, E = CudaDeviceActions.size(); I != E; ++I)
3930 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3931 C, Args, CurPhase, CudaDeviceActions[I], AssociatedOffloadKind,
3932 ToolChains[I]->getLTOMode(Args, AssociatedOffloadKind));
3934 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3936 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3937 OffloadAction::DeviceDependences DDep;
3938 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3939 AssociatedOffloadKind);
3940 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3941 DDep, CudaDeviceActions[I]->getType());
3944 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3945 CudaDeviceActions.clear();
3948 return (CompileDeviceOnly &&
3949 (CurPhase == FinalPhase ||
3955 void appendLinkDeviceActions(
ActionList &AL)
override {
3956 if (DeviceLinkerInputs.size() == 0)
3959 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3960 "Linker inputs and GPU arch list sizes do not match.");
3966 for (
auto &LI : DeviceLinkerInputs) {
3968 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3972 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3975 OffloadAction::DeviceDependences DeviceLinkDeps;
3976 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3977 AssociatedOffloadKind);
3978 Actions.push_back(
C.MakeAction<OffloadAction>(
3979 DeviceLinkDeps, DeviceLinkAction->getType()));
3982 DeviceLinkerInputs.clear();
3985 if (Args.hasArg(options::OPT_emit_llvm)) {
3993 OffloadAction::DeviceDependences DDeps;
3994 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3995 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3997 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3998 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain, {},
3999 AssociatedOffloadKind);
4002 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
4008 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
4010 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
4018 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
4024 bool ShouldUseBundler;
4027 OffloadingActionBuilder(Compilation &
C, DerivedArgList &Args,
4035 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
4038 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4046 unsigned ValidBuilders = 0u;
4047 unsigned ValidBuildersSupportingBundling = 0u;
4048 for (
auto *SB : SpecializedBuilders) {
4049 IsValid = IsValid && !SB->initialize();
4052 if (SB->isValid()) {
4054 if (SB->canUseBundlerUnbundler())
4055 ++ValidBuildersSupportingBundling;
4059 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4061 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4062 options::OPT_no_gpu_bundle_output,
true);
4065 ~OffloadingActionBuilder() {
4066 for (
auto *SB : SpecializedBuilders)
4071 void recordHostAction(Action *HostAction,
const Arg *InputArg) {
4072 assert(HostAction &&
"Invalid host action");
4073 assert(InputArg &&
"Invalid input argument");
4074 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4075 assert(Loc->second == InputArg &&
4076 "host action mapped to multiple input arguments");
4085 addDeviceDependencesToHostAction(Action *HostAction,
const Arg *InputArg,
4087 DeviceActionBuilder::PhasesTy &Phases) {
4091 if (SpecializedBuilders.empty())
4094 assert(HostAction &&
"Invalid host action!");
4095 recordHostAction(HostAction, InputArg);
4097 OffloadAction::DeviceDependences DDeps;
4100 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4101 unsigned InactiveBuilders = 0u;
4102 unsigned IgnoringBuilders = 0u;
4103 for (
auto *SB : SpecializedBuilders) {
4104 if (!SB->isValid()) {
4109 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4114 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4119 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4120 OffloadKind |= SB->getAssociatedOffloadKind();
4125 if (IgnoringBuilders &&
4126 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4134 OffloadAction::HostDependence HDep(
4137 return C.MakeAction<OffloadAction>(HDep, DDeps);
4143 bool addHostDependenceToDeviceActions(Action *&HostAction,
4144 const Arg *InputArg) {
4148 recordHostAction(HostAction, InputArg);
4157 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4159 HostAction->
getType() == types::TY_PP_HIP)) {
4160 auto UnbundlingHostAction =
4161 C.MakeAction<OffloadUnbundlingJobAction>(HostAction);
4162 UnbundlingHostAction->registerDependentActionInfo(
4165 HostAction = UnbundlingHostAction;
4166 recordHostAction(HostAction, InputArg);
4169 assert(HostAction &&
"Invalid host action!");
4172 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4173 for (
auto *SB : SpecializedBuilders) {
4177 auto RetCode = SB->addDeviceDependences(HostAction);
4181 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4182 "Host dependence not expected to be ignored.!");
4186 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4187 OffloadKind |= SB->getAssociatedOffloadKind();
4192 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4201 bool appendTopLevelActions(
ActionList &AL, Action *HostAction,
4202 const Arg *InputArg) {
4204 recordHostAction(HostAction, InputArg);
4208 for (
auto *SB : SpecializedBuilders) {
4211 SB->appendTopLevelActions(OffloadAL);
4218 if (CanUseBundler && ShouldUseBundler && HostAction &&
4219 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4221 OffloadAL.push_back(HostAction);
4225 assert(HostAction == AL.back() &&
"Host action not in the list??");
4226 HostAction =
C.MakeAction<OffloadBundlingJobAction>(OffloadAL);
4227 recordHostAction(HostAction, InputArg);
4228 AL.back() = HostAction;
4230 AL.append(OffloadAL.begin(), OffloadAL.end());
4240 void appendDeviceLinkActions(
ActionList &AL) {
4241 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4244 SB->appendLinkDeviceActions(AL);
4248 Action *makeHostLinkAction() {
4251 appendDeviceLinkActions(DeviceAL);
4252 if (DeviceAL.empty())
4256 Action* HA =
nullptr;
4257 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4260 HA = SB->appendLinkHostActions(DeviceAL);
4274 Action *processHostLinkAction(Action *HostAction) {
4276 OffloadAction::DeviceDependences DDeps;
4277 for (
auto *SB : SpecializedBuilders) {
4281 SB->appendLinkDependences(DDeps);
4285 unsigned ActiveOffloadKinds = 0u;
4286 for (
auto &I : InputArgToOffloadKindMap)
4287 ActiveOffloadKinds |= I.second;
4299 for (
auto *A : HostAction->
inputs()) {
4300 auto ArgLoc = HostActionToInputArgMap.find(A);
4301 if (ArgLoc == HostActionToInputArgMap.end())
4303 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4304 if (OFKLoc == InputArgToOffloadKindMap.end())
4314 OffloadAction::HostDependence HDep(
4316 {}, ActiveOffloadKinds);
4317 return C.MakeAction<OffloadAction>(HDep, DDeps);
4322void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4327 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4328 StringRef
V = A->getValue();
4329 if (Inputs.size() > 1 && !
V.empty() &&
4330 !llvm::sys::path::is_separator(
V.back())) {
4332 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4333 << A->getSpelling() <<
V;
4334 Args.eraseArg(options::OPT__SLASH_Fo);
4339 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4340 StringRef
V = A->getValue();
4341 if (Inputs.size() > 1 && !
V.empty() &&
4342 !llvm::sys::path::is_separator(
V.back())) {
4344 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4345 << A->getSpelling() <<
V;
4346 Args.eraseArg(options::OPT__SLASH_Fa);
4351 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4352 if (A->getValue()[0] ==
'\0') {
4354 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4355 Args.eraseArg(options::OPT__SLASH_o);
4360 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4361 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4362 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4363 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4364 Args.eraseArg(options::OPT__SLASH_Yc);
4365 Args.eraseArg(options::OPT__SLASH_Yu);
4366 YcArg = YuArg =
nullptr;
4368 if (YcArg && Inputs.size() > 1) {
4369 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4370 Args.eraseArg(options::OPT__SLASH_Yc);
4378 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4379 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4380 Args.AddFlagArg(
nullptr,
4381 getOpts().getOption(options::OPT_frtlib_add_rpath));
4385 if (Args.hasArg(options::OPT_emit_llvm) &&
4386 !Args.hasArg(options::OPT_hip_link) &&
4387 !
C.getDefaultToolChain().getTriple().isSPIRV())
4388 Diag(clang::diag::err_drv_emit_llvm_link);
4389 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4390 C.getDefaultToolChain().isUsingLTO(Args) &&
4391 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4392 .starts_with_insensitive(
"lld"))
4393 Diag(clang::diag::err_drv_lto_without_lld);
4399 if (!Args.hasArg(options::OPT_dumpdir)) {
4400 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4401 Arg *Arg = Args.MakeSeparateArg(
4402 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4404 (FinalOutput ? FinalOutput->getValue()
4416 Args.eraseArg(options::OPT__SLASH_Fp);
4417 Args.eraseArg(options::OPT__SLASH_Yc);
4418 Args.eraseArg(options::OPT__SLASH_Yu);
4419 YcArg = YuArg =
nullptr;
4422 if (Args.hasArg(options::OPT_include_pch) &&
4423 Args.hasArg(options::OPT_ignore_pch)) {
4427 Args.eraseArg(options::OPT_include_pch);
4430 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4431 for (
auto &I : Inputs) {
4433 const Arg *InputArg = I.second;
4438 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4442 if (InitialPhase > FinalPhase) {
4443 if (InputArg->isClaimed())
4450 if (Args.hasArg(options::OPT_Qunused_arguments))
4456 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4457 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4461 (Args.getLastArg(options::OPT__SLASH_EP,
4462 options::OPT__SLASH_P) ||
4463 Args.getLastArg(options::OPT_E) ||
4464 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4466 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4467 << InputArg->getAsString(Args) << !!FinalPhaseArg
4468 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4470 Diag(clang::diag::warn_drv_input_file_unused)
4471 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4473 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4482 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4483 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
4488 Actions.push_back(ClangClPch);
4500 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4501 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4510 const llvm::opt::DerivedArgList &Args,
4513 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4515 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4518 bool HasAMDGCNHIPDevice =
false;
4520 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4522 const llvm::Triple &Tr = TC->
getTriple();
4525 HasAMDGCNHIPDevice =
true;
4527 return HasAMDGCNHIPDevice;
4532 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4534 if (!SuppressMissingInputWarning && Inputs.empty()) {
4535 Diag(clang::diag::err_drv_no_input_files);
4539 handleArguments(
C, Args, Inputs, Actions);
4541 bool UseNewOffloadingDriver = Args.hasFlag(
4542 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4544 bool HIPRDCDeviceOnlyFatBin =
4547 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4549 !Args.hasArg(options::OPT_emit_llvm) &&
4550 Args.hasFlag(options::OPT_gpu_bundle_output,
4551 options::OPT_no_gpu_bundle_output,
true);
4554 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4555 !UseNewOffloadingDriver
4556 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4564 for (
auto &I : Inputs) {
4566 const Arg *InputArg = I.second;
4578 if (HIPRDCDeviceOnlyFatBin && InputType == types::TY_LLVM_BC) {
4579 LinkerInputs.push_back(Current);
4585 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4593 if (!UseNewOffloadingDriver)
4594 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4600 if (!UseNewOffloadingDriver)
4601 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4602 Current, InputArg, Phase, PL.back(), FullPL);
4608 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4611 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4612 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4614 LinkerInputs.push_back(Current);
4624 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4625 MergerInputs.push_back(Current);
4642 C.getDefaultToolChain().getLTOMode(Args));
4645 if (NewCurrent == Current)
4648 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4651 Current = NewCurrent;
4655 if (UseNewOffloadingDriver)
4657 &HIPAsmDeviceActions);
4660 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4664 if (Current->
getType() == types::TY_Nothing)
4670 if (Current && !HIPAsmDeviceActions.empty()) {
4671 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4673 BundleInputs.append(HIPAsmDeviceActions);
4674 BundleInputs.push_back(Current);
4680 Actions.push_back(Current);
4683 if (!UseNewOffloadingDriver)
4684 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4692 if (LinkerInputs.empty()) {
4695 if (!UseNewOffloadingDriver)
4696 OffloadBuilder->appendDeviceLinkActions(Actions);
4699 if (!LinkerInputs.empty()) {
4700 if (!UseNewOffloadingDriver)
4701 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4702 LinkerInputs.push_back(Wrapper);
4707 }
else if (UseNewOffloadingDriver ||
4708 Args.hasArg(options::OPT_offload_link)) {
4711 HIPRDCDeviceOnlyFatBin ? types::TY_HIP_FATBIN : types::TY_Image);
4718 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4719 C.getDefaultToolChain().getTriple().isSPIRV();
4720 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4724 if (!UseNewOffloadingDriver)
4725 LA = OffloadBuilder->processHostLinkAction(LA);
4726 Actions.push_back(LA);
4730 if (!MergerInputs.empty())
4734 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4741 for (
auto &I : Inputs) {
4743 const Arg *InputArg = I.second;
4748 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4749 InputType == types::TY_Asm)
4754 for (
auto Phase : PhaseList) {
4758 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4763 if (InputType == types::TY_Object)
4770 assert(Phase == PhaseList.back() &&
4771 "merging must be final compilation step.");
4772 MergerInputs.push_back(Current);
4781 Actions.push_back(Current);
4785 if (!MergerInputs.empty())
4790 for (
auto Opt : {options::OPT_print_supported_cpus,
4791 options::OPT_print_supported_extensions,
4792 options::OPT_print_enabled_extensions}) {
4799 if (Arg *A = Args.getLastArg(Opt)) {
4800 if (Opt == options::OPT_print_supported_extensions &&
4801 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4802 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4803 !
C.getDefaultToolChain().getTriple().isARM()) {
4804 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4805 <<
"--print-supported-extensions";
4808 if (Opt == options::OPT_print_enabled_extensions &&
4809 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4810 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4811 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4812 <<
"--print-enabled-extensions";
4819 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4822 for (
auto &I : Inputs)
4827 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4828 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4829 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4835 if (TC.requiresObjcopy(Args)) {
4836 Action *LastAction = Actions.back();
4838 if (LastAction->
getType() == types::TY_Object) {
4846 auto ValInfo = TC.getValidationInfo(Args);
4847 if (ValInfo.NeedsValidation) {
4848 Action *LastAction = Actions.back();
4849 if (LastAction->
getType() == types::TY_Object) {
4851 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4858 if (TC.requiresBinaryTranslation(Args)) {
4859 Action *LastAction = Actions.back();
4863 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4864 LastAction->
getType() == types::TY_Object)
4866 LastAction, types::TY_DX_CONTAINER));
4871 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4877 const llvm::opt::DerivedArgList &Args,
4879 const llvm::Triple &Triple) {
4884 if (Triple.isNVPTX() && (
Arch.isUnknown() || !
Arch.isNVPTX())) {
4885 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4886 <<
"CUDA" << ArchStr;
4888 }
else if (Triple.isAMDGPU() &&
4889 (
Arch.isUnknown() || (!
Arch.isAMDGPU() && !
Arch.isSPIRV()))) {
4890 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4891 <<
"HIP" << ArchStr;
4898 if (
Arch.isAMDGPU() ||
Arch.isSPIRV()) {
4899 llvm::StringMap<bool> Features;
4902 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4914static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4916 llvm::Triple Triple) {
4917 if (!Triple.isAMDGPU())
4918 return std::nullopt;
4920 std::set<StringRef> ArchSet;
4921 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4925llvm::SmallVector<BoundArch>
4929 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4930 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4931 options::OPT_no_offload_arch_EQ)) {
4932 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4934 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4936 :
"--no-offload-arch");
4939 llvm::DenseSet<StringRef> Archs;
4940 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
4943 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4944 for (StringRef
Arch : Arg->getValues()) {
4945 if (
Arch ==
"native" ||
Arch.empty()) {
4950 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4954 for (
auto ArchStr : *GPUsOrErr) {
4956 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4957 if (!CanonicalStr.empty())
4958 Archs.insert(CanonicalStr);
4963 StringRef CanonicalStr =
4965 if (!CanonicalStr.empty())
4966 Archs.insert(CanonicalStr);
4971 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4972 for (StringRef
Arch : Arg->getValues()) {
4973 if (
Arch ==
"all") {
4978 Archs.erase(ArchStr);
4984 if (
auto ConflictingArchs =
4986 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4987 << ConflictingArchs->first << ConflictingArchs->second;
4990 if (Archs.empty()) {
5000 Archs.insert(StringRef());
5003 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
5004 .getLastArg(options::OPT_march_EQ)) {
5005 Archs.insert(Arg->getValue());
5010 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
5011 <<
"--offload-arch";
5012 }
else if (!ArchsOrErr->empty()) {
5013 for (
auto Arch : *ArchsOrErr)
5014 Archs.insert(Args.MakeArgStringRef(
Arch));
5016 Archs.insert(StringRef());
5021 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
5022 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
5029 Result.reserve(Sorted.size());
5030 for (StringRef
Arch : Sorted)
5037 const InputTy &Input, StringRef CUID,
5047 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5049 bool HIPRelocatableObj =
5051 Args.hasFlag(options::OPT_fhip_emit_relocatable,
5052 options::OPT_fno_hip_emit_relocatable,
false);
5054 if (!HIPNoRDC && HIPRelocatableObj)
5055 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
5056 <<
"-fhip-emit-relocatable"
5060 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
5061 <<
"-fhip-emit-relocatable"
5062 <<
"--offload-device-only";
5080 auto TCRange =
C.getOffloadToolChains(Kind);
5081 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5082 ToolChains.push_back(TI->second);
5084 if (ToolChains.empty())
5088 const Arg *InputArg = Input.second;
5097 for (
const ToolChain *TC : ToolChains) {
5099 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5100 DeviceActions.push_back(
5101 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5105 if (DeviceActions.empty())
5111 HostAction->
getType() != types::TY_Nothing &&
5121 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5130 auto *TCAndArch = TCAndArchs.begin();
5131 for (
Action *&A : DeviceActions) {
5132 if (A->
getType() == types::TY_Nothing)
5139 TCAndArch->first->getLTOMode(Args, Kind));
5143 HostAction->
getType() != types::TY_Nothing) {
5150 TCAndArch->second, Kind);
5152 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5162 for (
Action *&A : DeviceActions) {
5167 OffloadTriple && OffloadTriple->isSPIRV() &&
5168 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5169 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5171 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5172 A->
getType() != types::TY_LTO_BC) ||
5179 auto *TCAndArch = TCAndArchs.begin();
5180 for (
Action *A : DeviceActions) {
5181 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5183 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5188 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5190 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
5199 bool ShouldBundleHIP =
5200 Args.hasFlag(options::OPT_gpu_bundle_output,
5201 options::OPT_no_gpu_bundle_output,
false) ||
5202 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5204 return A->
getType() != types::TY_Image;
5211 if (OffloadActions.empty())
5216 (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) ||
5217 Args.hasArg(options::OPT_cuda_emit_nvcc_abi))) {
5221 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5228 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5229 DDep.
add(*FatbinAction,
5232 }
else if (HIPNoRDC) {
5235 if (HIPAsmBundleDeviceOut &&
5237 for (
Action *OA : OffloadActions)
5238 HIPAsmBundleDeviceOut->push_back(OA);
5252 DDep.
add(*PackagerAction,
5261 {},
C.getActiveOffloadKinds());
5270 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5271 return A->
getType() == types::TY_Nothing;
5275 {}, SingleDeviceOutput ? DDep : DDeps);
5276 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5282 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5292 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5298 llvm_unreachable(
"link action invalid here.");
5300 llvm_unreachable(
"ifsmerge action invalid here.");
5305 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5306 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5307 OutputTy = types::TY_Dependencies;
5312 if (!Args.hasFlag(options::OPT_frewrite_includes,
5313 options::OPT_fno_rewrite_includes,
false) &&
5314 !Args.hasFlag(options::OPT_frewrite_imports,
5315 options::OPT_fno_rewrite_imports,
false) &&
5316 !Args.hasFlag(options::OPT_fdirectives_only,
5317 options::OPT_fno_directives_only,
false) &&
5321 "Cannot preprocess this input type!");
5327 if (Args.hasArg(options::OPT_extract_api))
5332 if (Input->
getType() == types::TY_CXXStdModule ||
5333 Input->
getType() == types::TY_PP_CXXStdModule)
5335 Input, getPrecompiledType(Input->
getType()));
5343 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5344 (Input->
getType() == driver::types::TY_CXXModule ||
5345 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5346 !Args.getLastArg(options::OPT__precompile) &&
5347 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5352 "Cannot precompile this input type!");
5356 const char *ModName =
nullptr;
5357 if (OutputTy == types::TY_PCH) {
5358 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5359 ModName = A->getValue();
5361 OutputTy = types::TY_ModuleFile;
5364 if (Args.hasArg(options::OPT_fsyntax_only)) {
5366 OutputTy = types::TY_Nothing;
5372 if (Args.hasArg(options::OPT_fsyntax_only))
5374 if (Args.hasArg(options::OPT_rewrite_objc))
5376 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5378 types::TY_RewrittenLegacyObjC);
5379 if (Args.hasArg(options::OPT__analyze))
5381 if (Args.hasArg(options::OPT_emit_ast))
5383 if (Args.hasArg(options::OPT_emit_cir))
5385 if (Args.hasArg(options::OPT_module_file_info))
5387 if (Args.hasArg(options::OPT_verify_pch))
5389 if (Args.hasArg(options::OPT_extract_api))
5396 if (!IsDeviceOffload) {
5398 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5399 !Args.hasArg(options::OPT_emit_llvm))
5400 Output = types::TY_PP_Asm;
5401 else if (Args.hasArg(options::OPT_S))
5402 Output = types::TY_LTO_IR;
5404 Output = types::TY_LTO_BC;
5408 if (Args.hasArg(options::OPT_emit_llvm)) {
5410 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5412 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5416 Output = types::TY_PP_Asm;
5417 }
else if (Args.hasArg(options::OPT_S)) {
5418 Output = types::TY_LTO_IR;
5420 Output = types::TY_LTO_BC;
5424 if (Args.hasArg(options::OPT_emit_llvm) ||
5427 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5436 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5437 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
5448 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5470 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
5490 if (!OffloadJobs.isValid())
5491 D.
Diag(diag::err_drv_invalid_int_value)
5492 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
5494 OffloadJobs.A->claim();
5498 bool FoundCandidate =
false;
5499 for (
auto &Job :
C.getJobs()) {
5503 Job.setOffloadDeviceParallelJobGroup(
5505 FoundCandidate =
true;
5513 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5515 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5535 unsigned NumOutputs = 0;
5536 unsigned NumIfsOutputs = 0;
5537 for (
const Action *A :
C.getActions()) {
5547 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
5548 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
5551 if (A->
getType() != types::TY_Nothing &&
5553 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5555 0 == NumIfsOutputs++) ||
5560 A->
getType() == types::TY_Nothing &&
5561 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5562 NumOutputs += A->
size();
5565 if (NumOutputs > 1) {
5566 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5567 FinalOutput =
nullptr;
5571 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5574 llvm::StringSet<> ArchNames;
5575 if (RawTriple.isOSBinFormatMachO())
5576 for (
const Arg *A :
C.getArgs())
5577 if (A->getOption().matches(options::OPT_arch))
5578 ArchNames.insert(A->getValue());
5581 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5582 for (
Action *A :
C.getActions()) {
5589 const char *LinkingOutput =
nullptr;
5592 LinkingOutput = FinalOutput->getValue();
5600 ArchNames.size() > 1 ||
5601 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
5602 LinkingOutput, CachedResults,
5609 for (
auto &J :
C.getJobs())
5610 J.InProcess =
false;
5615 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5616 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5621 const char *LinkingOutput =
nullptr;
5623 LinkingOutput = FinalOutput->getValue();
5630 using namespace llvm;
5633 <<
"output=" << LinkingOutput;
5634 outs() <<
", total="
5635 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5637 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5638 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5642 llvm::raw_string_ostream Out(Buffer);
5643 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5646 llvm::sys::printArg(Out, LinkingOutput,
true);
5647 Out <<
',' << ProcStat->TotalTime.count() <<
','
5648 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5653 llvm::sys::fs::OF_Append |
5654 llvm::sys::fs::OF_Text);
5659 llvm::errs() <<
"ERROR: Cannot lock file "
5661 <<
toString(L.takeError()) <<
"\n";
5672 bool ReportUnusedArguments =
5673 !Diags.hasErrorOccurred() &&
5674 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5677 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5679 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5682 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5683 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5685 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5689 return strstr(J.getCreator().getShortName(),
"assembler");
5691 for (Arg *A :
C.getArgs()) {
5695 if (!A->isClaimed()) {
5701 const Option &Opt = A->getOption();
5702 if (Opt.getKind() == Option::FlagClass) {
5703 bool DuplicateClaimed =
false;
5705 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5706 if (AA->isClaimed()) {
5707 DuplicateClaimed =
true;
5712 if (DuplicateClaimed)
5718 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5720 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5725 !
C.getActions().empty()) {
5726 Diag(diag::err_drv_unsupported_opt_for_target)
5728 }
else if (ReportUnusedArguments) {
5729 Diag(clang::diag::warn_drv_unused_argument)
5730 << A->getAsString(
C.getArgs());
5740class ToolSelector final {
5751 bool IsHostSelector;
5762 bool CanBeCollapsed =
true) {
5764 if (Inputs.size() != 1)
5767 Action *CurAction = *Inputs.begin();
5768 if (CanBeCollapsed &&
5774 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5778 if (!IsHostSelector) {
5779 if (OA->hasSingleDeviceDependence(
true)) {
5781 OA->getSingleDeviceDependence(
true);
5782 if (CanBeCollapsed &&
5785 SavedOffloadAction.push_back(OA);
5786 return dyn_cast<JobAction>(CurAction);
5788 }
else if (OA->hasHostDependence()) {
5789 CurAction = OA->getHostDependence();
5790 if (CanBeCollapsed &&
5793 SavedOffloadAction.push_back(OA);
5794 return dyn_cast<JobAction>(CurAction);
5799 return dyn_cast<JobAction>(CurAction);
5803 bool canCollapseAssembleAction()
const {
5804 return TC.useIntegratedAs() && !SaveTemps &&
5805 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5806 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5807 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5808 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5812 bool canCollapsePreprocessorAction()
const {
5813 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5814 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5815 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5820 struct JobActionInfo final {
5822 const JobAction *JA =
nullptr;
5830 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5831 ArrayRef<JobActionInfo> &ActionInfo,
5832 unsigned ElementNum) {
5833 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5834 for (
unsigned I = 0; I < ElementNum; ++I)
5835 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5836 ActionInfo[I].SavedOffloadAction.end());
5849 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5852 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5854 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5855 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5856 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5857 if (!AJ || !BJ || !CJ)
5861 const Tool *
T = TC.SelectTool(*CJ);
5868 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5874 const Tool *BT = TC.SelectTool(*BJ);
5879 if (!
T->hasIntegratedAssembler())
5882 Inputs = CJ->getInputs();
5883 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5887 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5890 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5892 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5893 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5898 const Tool *
T = TC.SelectTool(*BJ);
5902 if (!
T->hasIntegratedAssembler())
5905 Inputs = BJ->getInputs();
5906 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5910 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5913 if (ActionInfo.size() < 2)
5915 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5916 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5920 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5921 for (
auto &Input : AI.JA->getInputs())
5932 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5933 if (SaveTemps && !InputIsBitcode)
5937 const Tool *
T = TC.SelectTool(*CJ);
5944 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5950 Inputs = CJ->getInputs();
5951 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5960 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5962 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5968 for (Action *A : Inputs) {
5969 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5971 NewInputs.push_back(A);
5977 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5978 PreprocessJobOffloadActions.end());
5979 NewInputs.append(PJ->input_begin(), PJ->input_end());
5985 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5987 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5989 assert(BaseAction &&
"Invalid base action.");
6005 SmallVector<JobActionInfo, 5> ActionChain(1);
6006 ActionChain.back().JA = BaseAction;
6007 while (ActionChain.back().JA) {
6008 const Action *CurAction = ActionChain.back().JA;
6011 ActionChain.resize(ActionChain.size() + 1);
6012 JobActionInfo &AI = ActionChain.back();
6016 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
6020 ActionChain.pop_back();
6028 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
6029 CollapsedOffloadAction);
6031 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
6033 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
6039 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
6052 std::string TriplePlusArch = TC->
getTriple().normalize();
6054 TriplePlusArch +=
"-";
6057 TriplePlusArch +=
"-";
6059 return TriplePlusArch;
6064 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6065 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6068 std::pair<const Action *, std::string> ActionTC = {
6070 auto CachedResult = CachedResults.find(ActionTC);
6071 if (CachedResult != CachedResults.end()) {
6072 return CachedResult->second;
6075 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
6076 TargetDeviceOffloadKind);
6077 CachedResults[ActionTC] =
Result;
6082 const JobAction *JA,
const char *BaseInput,
6085 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6096 if (!
Arch.empty()) {
6097 OffloadingPrefix +=
"-";
6098 OffloadingPrefix +=
Arch.ArchName;
6101 C.getDriver().isSaveTempsEnabled()) {
6108 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6109 Path = A->getValue();
6110 if (llvm::sys::fs::is_directory(Path)) {
6112 ? llvm::sys::path::stem(
Result.getFilename())
6113 : llvm::sys::path::stem(BaseInput));
6114 Tmp += OffloadingPrefix;
6116 llvm::sys::path::append(Path, Tmp);
6119 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6122 Path = DumpDir->getValue();
6123 Path += llvm::sys::path::stem(BaseInput);
6124 Path += OffloadingPrefix;
6126 }
else if (!OffloadingPrefix.empty()) {
6130 TraceName += OffloadingPrefix;
6131 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6132 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6133 llvm::sys::path::append(Path, TraceName);
6136 Path =
Result.getFilename();
6137 llvm::sys::path::replace_extension(Path,
"json");
6140 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6141 C.addTimeTraceFile(ResultFile, JA);
6142 C.addResultFile(ResultFile, JA);
6147 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6148 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6151 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6155 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
6156 C.setCurrentBoundArch(BA);
6157 auto RestoreBoundArch =
6158 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
6161 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6162 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6194 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6196 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6197 BoundArch DepBoundArch) {
6199 !DepBoundArch.
empty(),
6200 LinkingOutput, CachedResults,
6210 OA->doOnEachDependence(
6211 BuildingForOffloadDevice,
6212 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6214 C, DepA, DepTC, DepBoundArch,
false,
6215 !DepBoundArch.
empty(), LinkingOutput,
6219 A = BuildingForOffloadDevice
6220 ? OA->getSingleDeviceDependence(
true)
6221 : OA->getHostDependence();
6225 std::pair<const Action *, std::string> ActionTC = {
6226 OA->getHostDependence(),
6228 auto It = CachedResults.find(ActionTC);
6229 if (It != CachedResults.end()) {
6231 Inputs.append(OffloadDependencesInputInfo);
6236 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6239 const Arg &Input = IA->getInputArg();
6241 if (Input.getOption().matches(options::OPT_INPUT)) {
6242 const char *
Name = Input.getValue();
6245 return {InputInfo(A, &Input,
"")};
6248 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6249 const ToolChain *TC;
6250 BoundArch ArchName = BAA->
getArch();
6252 if (!ArchName.
empty())
6253 TC = &getToolChain(
C.getArgs(),
6257 TC = &
C.getDefaultToolChain();
6260 MultipleArchs, LinkingOutput, CachedResults,
6261 TargetDeviceOffloadKind);
6272 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
6275 return {InputInfo()};
6279 for (
const auto *OA : CollapsedOffloadActions)
6281 BuildingForOffloadDevice,
6282 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6284 C, DepA, DepTC, DepBoundArch,
false,
6285 !DepBoundArch.
empty(), LinkingOutput,
6291 for (
const Action *Input : Inputs) {
6295 bool SubJobAtTopLevel =
6298 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6303 const char *BaseInput = InputInfos[0].getBaseInput();
6304 for (
auto &Info : InputInfos) {
6305 if (Info.isFilename()) {
6306 BaseInput = Info.getBaseInput();
6313 if (JA->
getType() == types::TY_dSYM)
6314 BaseInput = InputInfos[0].getFilename();
6317 if (!OffloadDependencesInputInfo.empty())
6318 InputInfos.append(OffloadDependencesInputInfo.begin(),
6319 OffloadDependencesInputInfo.end());
6322 llvm::Triple EffectiveTriple;
6323 const ToolChain &ToolTC =
T->getToolChain();
6324 const ArgList &Args =
6326 if (InputInfos.size() != 1) {
6331 EffectiveTriple = llvm::Triple(
6334 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6339 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6343 for (
auto &UI : UA->getDependentActionsInfo()) {
6345 "Unbundling with no offloading??");
6352 UI.DependentOffloadKind, UI.DependentToolChain->getTripleString(),
6354 auto CurI = InputInfo(
6363 UnbundlingResults.push_back(CurI);
6372 Arch = BoundArch(UI.DependentBoundArch);
6377 UI.DependentOffloadKind)}] = {
6383 std::pair<const Action *, std::string> ActionTC = {
6385 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6386 "Result does not exist??");
6387 Result = CachedResults[ActionTC].front();
6388 }
else if (JA->
getType() == types::TY_Nothing)
6389 Result = {InputInfo(A, BaseInput)};
6400 MultipleArchs, OffloadingPrefix),
6407 llvm::errs() <<
"# \"" <<
T->getToolChain().getEffectiveTriple().str()
6408 <<
'"' <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6409 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6410 llvm::errs() << InputInfos[i].getAsString();
6412 llvm::errs() <<
", ";
6414 if (UnbundlingResults.empty())
6415 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6417 llvm::errs() <<
"], outputs: [";
6418 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6419 llvm::errs() << UnbundlingResults[i].getAsString();
6421 llvm::errs() <<
", ";
6423 llvm::errs() <<
"] \n";
6426 if (UnbundlingResults.empty())
6427 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6429 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6430 Args, LinkingOutput);
6436 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6437 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6449 if (ArgValue.empty()) {
6451 Filename = BaseName;
6452 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6454 llvm::sys::path::append(Filename, BaseName);
6457 if (!llvm::sys::path::has_extension(ArgValue)) {
6462 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6467 llvm::sys::path::replace_extension(Filename, Extension);
6470 return Args.MakeArgString(Filename.c_str());
6485 StringRef Suffix,
bool MultipleArchs,
6486 StringRef BoundArchStr,
6487 bool NeedUniqueDirectory)
const {
6489 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6490 std::optional<std::string> CrashDirectory =
6492 ? std::string(A->getValue())
6493 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6494 if (CrashDirectory) {
6495 if (!
getVFS().exists(*CrashDirectory))
6496 llvm::sys::fs::create_directories(*CrashDirectory);
6498 llvm::sys::path::append(Path, Prefix);
6499 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6500 if (std::error_code EC =
6501 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6502 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6506 if (MultipleArchs && !BoundArchStr.empty()) {
6507 if (NeedUniqueDirectory) {
6509 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
6520 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6535 const char *BaseInput) {
6537 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6538 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6543 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6548 bool AtTopLevel,
bool MultipleArchs,
6549 StringRef OffloadingPrefix)
const {
6552 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6554 auto CreateTempOutputPath = [&](StringRef Prefix) {
6555 const char *Suffix =
6560 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
6561 const bool NeedUniqueDirectory =
6564 Triple.isOSDarwin();
6566 NeedUniqueDirectory);
6571 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
6572 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
6573 StringRef Filename = llvm::sys::path::filename(BaseInput);
6574 StringRef Stem = llvm::sys::path::stem(Filename);
6575 return CreateTempOutputPath(Stem);
6580 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6581 return C.addResultFile(FinalOutput->getValue(), &JA);
6585 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6587 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6589 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6590 NameArg = A->getValue();
6591 return C.addResultFile(
6601 if (JA.
getType() == types::TY_ModuleFile &&
6602 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6606 if (JA.
getType() == types::TY_PP_Asm &&
6607 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6608 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6611 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
6614 if ((JA.
getType() == types::TY_Object &&
6615 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6616 JA.
getType() == types::TY_DX_CONTAINER) {
6617 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6618 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6619 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6620 "expected DXIL or SPIR-V triple for HLSL output path");
6625 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6627 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
6628 StringRef
Name = llvm::sys::path::filename(BaseInput);
6629 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6635 if (JA.
getType() == types::TY_PP_Asm &&
6636 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6637 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6639 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6640 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6641 return C.addResultFile(
6646 if (JA.
getType() == types::TY_API_INFO &&
6647 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6648 C.getArgs().hasArg(options::OPT_o))
6649 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6650 <<
C.getArgs().getLastArgValue(options::OPT_o);
6657 bool SpecifiedModuleOutput =
6658 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6659 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6660 if (MultipleArchs && SpecifiedModuleOutput)
6661 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6666 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6667 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6673 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6675 StringRef
Name = llvm::sys::path::filename(BaseInput);
6676 return CreateTempOutputPath(
Name.split(
'.').first);
6685 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6690 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6691 llvm::sys::path::filename(BasePath));
6692 BaseName = ExternalPath;
6694 BaseName = BasePath;
6696 BaseName = llvm::sys::path::filename(BasePath);
6699 const char *NamedOutput;
6701 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6702 JA.
getType() == types::TY_LLVM_BC ||
6703 JA.
getType() == types::TY_LLVM_IR) &&
6704 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6708 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6712 }
else if (JA.
getType() == types::TY_Image &&
6713 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6714 options::OPT__SLASH_o)) {
6718 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6722 }
else if (JA.
getType() == types::TY_Image) {
6732 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6733 options::OPT_fno_gpu_rdc,
false);
6735 if (UseOutExtension) {
6737 llvm::sys::path::replace_extension(Output,
"");
6739 Output += OffloadingPrefix;
6740 if (MultipleArchs && !BoundArchStr.empty()) {
6742 Output.append(BoundArchStr);
6744 if (UseOutExtension)
6746 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6749 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6750 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6751 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6754 .getLastArg(options::OPT__SLASH_o)
6759 const char *Suffix =
6761 assert(Suffix &&
"All types used for output should have a suffix.");
6763 std::string::size_type End = std::string::npos;
6765 End = BaseName.rfind(
'.');
6767 Suffixed += OffloadingPrefix;
6768 if (MultipleArchs && !BoundArchStr.empty()) {
6770 Suffixed.append(BoundArchStr);
6775 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6776 const llvm::opt::DerivedArgList &Args) {
6783 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6785 Args.hasFlag(options::OPT_offload_new_driver,
6786 options::OPT_no_offload_new_driver,
true))) ||
6793 bool IsLinkerWrapper =
6795 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6796 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6797 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6799 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6803 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6807 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6808 JA.
getType() != types::TY_PCH) {
6809 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6811 llvm::sys::path::remove_filename(TempPath);
6812 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6813 llvm::sys::path::append(TempPath, OutputFileName);
6814 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6820 bool SameFile =
false;
6822 llvm::sys::fs::current_path(
Result);
6823 llvm::sys::path::append(
Result, BaseName);
6824 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6827 StringRef
Name = llvm::sys::path::filename(BaseInput);
6828 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6832 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6838 llvm::sys::path::remove_filename(BasePath);
6839 if (BasePath.empty())
6840 BasePath = NamedOutput;
6842 llvm::sys::path::append(BasePath, NamedOutput);
6843 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6846 return C.addResultFile(NamedOutput, &JA);
6852 -> std::optional<std::string> {
6855 for (
const auto &
Dir : P) {
6859 llvm::sys::path::append(P,
Name);
6860 if (llvm::sys::fs::exists(Twine(P)))
6861 return std::string(P);
6863 return std::nullopt;
6870 llvm::sys::path::append(R,
Name);
6871 if (llvm::sys::fs::exists(Twine(R)))
6872 return std::string(R);
6875 llvm::sys::path::append(P,
Name);
6876 if (llvm::sys::fs::exists(Twine(P)))
6877 return std::string(P);
6881 if (std::optional<std::string> IntrPath =
6884 llvm::sys::path::append(P,
Name);
6885 if (llvm::sys::fs::exists(P))
6886 return std::string(P);
6891 llvm::sys::path::append(D,
"..",
Name);
6892 if (llvm::sys::fs::exists(Twine(D)))
6893 return std::string(D);
6902 llvm::sys::path::append(R2,
"..",
"..",
Name);
6903 if (llvm::sys::fs::exists(Twine(R2)))
6904 return std::string(R2);
6906 return std::string(
Name);
6909void Driver::generatePrefixedToolNames(
6913 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6914 Names.emplace_back(
Tool);
6918 llvm::sys::path::append(Dir, Name);
6919 if (llvm::sys::fs::can_execute(Twine(Dir)))
6921 llvm::sys::path::remove_filename(Dir);
6927 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6932 if (llvm::sys::fs::is_directory(PrefixDir)) {
6935 return std::string(P);
6938 if (llvm::sys::fs::can_execute(Twine(P)))
6939 return std::string(P);
6944 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6952 for (
const auto &Path : List) {
6955 return std::string(P);
6959 if (llvm::ErrorOr<std::string> P =
6960 llvm::sys::findProgramByName(TargetSpecificExecutable))
6964 return std::string(
Name);
6969 std::string error =
"<NOT PRESENT>";
6971 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6976 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6993 llvm::sys::path::remove_filename(path);
6994 llvm::sys::path::append(path,
"libc++.modules.json");
6995 if (TC.
getVFS().exists(path))
6996 return static_cast<std::string
>(path);
7001 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
7004 return evaluate(
"libc++.a").value_or(error);
7008 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
7012 llvm::sys::path::remove_filename(path);
7013 llvm::sys::path::append(path,
"libstdc++.modules.json");
7014 if (TC.
getVFS().exists(path))
7015 return static_cast<std::string
>(path);
7020 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
7023 return evaluate(
"libstdc++.a").value_or(error);
7032 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
7034 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7038 return std::string(Path);
7043 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
7045 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7049 return std::string(Path);
7054 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
7058 Output = FpArg->getValue();
7062 if (!llvm::sys::path::has_extension(Output))
7065 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
7066 Output = YcArg->getValue();
7069 llvm::sys::path::replace_extension(Output,
".pch");
7071 return std::string(Output);
7074const ToolChain &Driver::getOffloadToolChain(
7076 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
7077 std::unique_ptr<ToolChain> &TC =
7078 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
7079 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
7081 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
7084 switch (
Target.getOS()) {
7085 case llvm::Triple::CUDA:
7086 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7089 case llvm::Triple::AMDHSA:
7094 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
7095 HostTC.get(), Kind);
7103 switch (
Target.getArch()) {
7104 case llvm::Triple::amdgpu:
7105 case llvm::Triple::r600:
7106 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
7107 HostTC.get(), Kind);
7109 case llvm::Triple::spir:
7110 case llvm::Triple::spir64:
7111 case llvm::Triple::spirv:
7112 case llvm::Triple::spirv32:
7113 case llvm::Triple::spirv64:
7116 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
7120 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7124 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7128 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7142 return getToolChain(Args,
Target);
7146const ToolChain &Driver::getToolChain(
const ArgList &Args,
7147 const llvm::Triple &
Target)
const {
7149 auto &TC = ToolChains[
Target.str()];
7151 switch (
Target.getOS()) {
7152 case llvm::Triple::AIX:
7153 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7155 case llvm::Triple::Haiku:
7156 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7158 case llvm::Triple::Darwin:
7159 case llvm::Triple::MacOSX:
7160 case llvm::Triple::IOS:
7161 case llvm::Triple::TvOS:
7162 case llvm::Triple::WatchOS:
7163 case llvm::Triple::XROS:
7164 case llvm::Triple::DriverKit:
7165 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7167 case llvm::Triple::DragonFly:
7168 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7170 case llvm::Triple::OpenBSD:
7171 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7173 case llvm::Triple::NetBSD:
7174 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7176 case llvm::Triple::FreeBSD:
7178 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7181 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7183 case llvm::Triple::Linux:
7184 case llvm::Triple::ELFIAMCU:
7185 if (
Target.getArch() == llvm::Triple::hexagon)
7186 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7188 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7189 !
Target.hasEnvironment())
7190 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7193 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7195 else if (
Target.getArch() == llvm::Triple::ve)
7196 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7197 else if (
Target.isOHOSFamily())
7198 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7199 else if (
Target.isWALI())
7200 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7202 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7204 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7206 case llvm::Triple::Fuchsia:
7207 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7209 case llvm::Triple::Managarm:
7210 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7212 case llvm::Triple::Serenity:
7213 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7215 case llvm::Triple::Solaris:
7216 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7218 case llvm::Triple::CUDA:
7219 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7221 case llvm::Triple::AMDHSA: {
7222 if (
Target.getArch() == llvm::Triple::spirv64) {
7223 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7229 TC = std::make_unique<toolchains::AMDGPUToolChain>(
7231 ShouldLinkDeviceLibs);
7235 case llvm::Triple::AMDPAL:
7236 case llvm::Triple::Mesa3D:
7237 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7239 case llvm::Triple::UEFI:
7240 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7242 case llvm::Triple::Win32:
7243 switch (
Target.getEnvironment()) {
7245 if (
Target.isOSBinFormatELF())
7246 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7247 else if (
Target.isOSBinFormatMachO())
7248 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7250 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7252 case llvm::Triple::GNU:
7253 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7255 case llvm::Triple::Cygnus:
7256 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7258 case llvm::Triple::Itanium:
7259 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7262 case llvm::Triple::MSVC:
7263 case llvm::Triple::UnknownEnvironment:
7264 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7265 .starts_with_insensitive(
"bfd"))
7266 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7270 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7274 case llvm::Triple::PS4:
7275 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7277 case llvm::Triple::PS5:
7278 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7280 case llvm::Triple::Hurd:
7281 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7283 case llvm::Triple::LiteOS:
7284 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7286 case llvm::Triple::ZOS:
7287 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7289 case llvm::Triple::Vulkan:
7290 case llvm::Triple::ShaderModel:
7291 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7292 Target.getArch() == llvm::Triple::spirv64) &&
7294 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7296 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7298 case llvm::Triple::ChipStar:
7299 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7304 switch (
Target.getArch()) {
7305 case llvm::Triple::tce:
7306 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7308 case llvm::Triple::tcele:
7309 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7311 case llvm::Triple::tcele64:
7313 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7315 case llvm::Triple::hexagon:
7316 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7319 case llvm::Triple::lanai:
7320 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7322 case llvm::Triple::xcore:
7323 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7325 case llvm::Triple::wasm32:
7326 case llvm::Triple::wasm64:
7327 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7329 case llvm::Triple::avr:
7330 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7332 case llvm::Triple::msp430:
7333 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7335 case llvm::Triple::riscv32:
7336 case llvm::Triple::riscv64:
7337 case llvm::Triple::riscv32be:
7338 case llvm::Triple::riscv64be:
7339 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7341 case llvm::Triple::ve:
7342 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7344 case llvm::Triple::spirv32:
7345 case llvm::Triple::spirv64:
7346 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7348 case llvm::Triple::csky:
7349 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7351 case llvm::Triple::amdgpu:
7352 case llvm::Triple::r600:
7353 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7357 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7358 else if (
Target.isOSBinFormatELF())
7359 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7360 else if (
Target.isAppleFirmware())
7361 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7362 else if (
Target.isAppleMachO())
7363 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7364 else if (
Target.isOSBinFormatMachO())
7365 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7367 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7377 if (JA.
size() != 1 ||
7392 if (JA.
size() != 1 ||
7406 if (Args.hasArg(options::OPT_emit_static_lib))
7417 unsigned &Micro,
bool &HadExtra) {
7420 Major = Minor = Micro = 0;
7424 if (Str.consumeInteger(10, Major))
7428 if (!Str.consume_front(
"."))
7431 if (Str.consumeInteger(10, Minor))
7435 if (!Str.consume_front(
"."))
7438 if (Str.consumeInteger(10, Micro))
7456 unsigned CurDigit = 0;
7457 while (CurDigit < Digits.size()) {
7459 if (Str.consumeInteger(10, Digit))
7461 Digits[CurDigit] = Digit;
7464 if (!Str.consume_front(
"."))
7473llvm::opt::Visibility
7474Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7486const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7502 llvm_unreachable(
"Unhandled Mode");
7506 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7511 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7512 options::OPT_fno_save_optimization_record,
false))
7516 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7517 options::OPT_fno_save_optimization_record,
false))
7521 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7522 options::OPT_fno_save_optimization_record,
false))
7526 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7527 options::OPT_fno_save_optimization_record,
false))
7534 static StringRef OptName =
7536 llvm::StringRef Opt;
7537 for (StringRef Arg : Args) {
7538 if (!Arg.starts_with(OptName))
7544 return Opt.consume_front(OptName) ? Opt :
"";
7551 llvm::BumpPtrAllocator &Alloc,
7552 llvm::vfs::FileSystem *FS) {
7561 for (
const char *F : Args) {
7562 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7564 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7565 RSPQuoting = Windows;
7571 bool MarkEOLs = ClangCLMode;
7573 llvm::cl::TokenizerCallback Tokenizer;
7574 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7575 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7577 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7579 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7582 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7583 ECtx.setMarkEOLs(MarkEOLs);
7587 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7591 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7592 [](
const char *A) {
return A !=
nullptr; });
7593 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7596 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7597 Args.resize(newEnd - Args.begin());
7601 return llvm::Error::success();
7605 return SavedStrings.insert(S).first->getKeyData();
7639 llvm::StringSet<> &SavedStrings) {
7642 if (Edit[0] ==
'^') {
7643 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7644 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7645 Args.insert(Args.begin() + 1, Str);
7646 }
else if (Edit[0] ==
'+') {
7647 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7648 OS <<
"### Adding argument " << Str <<
" at end\n";
7649 Args.push_back(Str);
7650 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7651 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7652 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7653 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7654 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7656 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7658 if (Args[i] ==
nullptr)
7660 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7662 if (Repl != Args[i]) {
7663 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7667 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7668 auto Option = Edit.substr(1);
7669 for (
unsigned i = 1; i < Args.size();) {
7670 if (Option == Args[i]) {
7671 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7672 Args.erase(Args.begin() + i);
7673 if (Edit[0] ==
'X') {
7674 if (i < Args.size()) {
7675 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7676 Args.erase(Args.begin() + i);
7678 OS <<
"### Invalid X edit, end of command line!\n";
7683 }
else if (Edit[0] ==
'O') {
7684 for (
unsigned i = 1; i < Args.size();) {
7685 const char *A = Args[i];
7689 if (A[0] ==
'-' && A[1] ==
'O' &&
7690 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7691 (
'0' <= A[2] && A[2] <=
'9'))))) {
7692 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7693 Args.erase(Args.begin() + i);
7697 OS <<
"### Adding argument " << Edit <<
" at end\n";
7698 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7700 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7705 const char *OverrideStr,
7706 llvm::StringSet<> &SavedStrings,
7707 StringRef EnvVar, raw_ostream *OS) {
7709 OS = &llvm::nulls();
7711 if (OverrideStr[0] ==
'#') {
7713 OS = &llvm::nulls();
7716 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7720 const char *S = OverrideStr;
7722 const char *End = ::strchr(S,
' ');
7724 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static std::string getOffloadDeviceCC1ParallelJobGroup(const Command &Job)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static void printCXXStdlibIncludeDirs(const ToolChain &TC, const ArgList &Args)
static bool HasPreprocessOutput(const Action &JA)
std::multiset< llvm::Triple > TripleSet
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static const char BugReportMsg[]
static std::string GetTriplePlusArchString(const ToolChain *TC, BoundArch BA, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static void markOffloadDeviceCC1JobsForParallelExecution(Compilation &C)
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static bool isIncludeDirArg(StringRef Arg)
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef ArchName="")
Compute target triple from args.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static bool isOffloadDeviceCC1JobCandidate(Command &Job)
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static void claimAndDiagnoseOffloadJobs(const Driver &D, const ArgList &Args)
static bool shouldBundleHIPAsmWithNewDriver(const Compilation &C, const llvm::opt::DerivedArgList &Args, const Driver &D)
HIP non-RDC -S for AMDGCN: emit host and device assembly separately and bundle with clang-offload-bun...
static TripleSet inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static StringRef getTriple(const Command &Job)
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A processor an offloading action can target.
static constexpr OffloadArch getUnused()
static constexpr OffloadArch getGeneric()
static OffloadArch CudaDefault()
Default architectures used when the user does not specify one.
static OffloadArch HIPDefault()
static constexpr OffloadArch getUnknown()
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
BoundArch getOffloadingArch() const
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateDeviceOffloadInfo(OffloadKind OKind, BoundArch OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
void propagateHostOffloadInfo(unsigned OKinds, BoundArch OArch)
Append the host offload info of this action and propagate it to its dependences.
void setHostOffloadInfo(unsigned OKinds, BoundArch OArch)
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
void setBoundArch(BoundArch BA)
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
BoundArch getBoundArch() const
Return the bound architecture for this command, if any.
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
llvm::SmallVector< BoundArch > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction, ActionList *HIPAsmBundleDeviceOut=nullptr) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None, LTOKind TargetLTOMode=LTOK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, BoundArch BA, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
std::string Name
The name the driver was invoked as.
Driver(StringRef DriverExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, BoundArch BA, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArchStr={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
std::string DriverExecutable
The original path to the driver executable.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
const ActionList & getActions() const
Get each of the individual arrays.
void add(Action &A, const ToolChain &TC, BoundArch BA, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
Set a ToolChain's effective triple.
void buildStdModuleManifestInputs(ArrayRef< StdModuleManifest::Module > ManifestEntries, Compilation &C, InputList &Inputs)
Constructs compilation inputs for each module listed in the provided Standard library module manifest...
void runModulesDriver(Compilation &C, ArrayRef< StdModuleManifest::Module > ManifestEntries)
Scans the compilation inputs for module dependencies and adjusts the compilation to build and supply ...
llvm::Expected< StdModuleManifest > readStdModuleManifest(llvm::StringRef ManifestPath, llvm::vfs::FileSystem &VFS)
Reads the Standard library module manifest at ManifestPath.
void diagnoseModulesDriverArgs(llvm::opt::DerivedArgList &DAL, DiagnosticsEngine &Diags)
Emits diagnostics for arguments incompatible with -fmodules-driver.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
bool isHLSL(ID Id)
isHLSL - Is this an HLSL input.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
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.
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Represents a bound architecture for offload / multiple architecture compilation.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules