59#include "clang/Config/config.h"
76#include "llvm/ADT/ArrayRef.h"
77#include "llvm/ADT/STLExtras.h"
78#include "llvm/ADT/ScopeExit.h"
79#include "llvm/ADT/SmallSet.h"
80#include "llvm/ADT/SmallVector.h"
81#include "llvm/ADT/StringExtras.h"
82#include "llvm/ADT/StringRef.h"
83#include "llvm/ADT/StringSet.h"
84#include "llvm/ADT/StringSwitch.h"
85#include "llvm/Config/llvm-config.h"
86#include "llvm/MC/TargetRegistry.h"
87#include "llvm/Option/Arg.h"
88#include "llvm/Option/ArgList.h"
89#include "llvm/Option/OptSpecifier.h"
90#include "llvm/Option/OptTable.h"
91#include "llvm/Option/Option.h"
92#include "llvm/Support/CommandLine.h"
93#include "llvm/Support/ErrorHandling.h"
94#include "llvm/Support/ExitCodes.h"
95#include "llvm/Support/FileSystem.h"
96#include "llvm/Support/FileUtilities.h"
97#include "llvm/Support/FormatVariadic.h"
98#include "llvm/Support/IOSandbox.h"
99#include "llvm/Support/JSON.h"
100#include "llvm/Support/MD5.h"
101#include "llvm/Support/MemoryBuffer.h"
102#include "llvm/Support/Path.h"
103#include "llvm/Support/PrettyStackTrace.h"
104#include "llvm/Support/Process.h"
105#include "llvm/Support/Program.h"
106#include "llvm/Support/Regex.h"
107#include "llvm/Support/StringSaver.h"
108#include "llvm/Support/TarWriter.h"
109#include "llvm/Support/VirtualFileSystem.h"
110#include "llvm/Support/raw_ostream.h"
111#include "llvm/TargetParser/Host.h"
112#include "llvm/TargetParser/RISCVISAInfo.h"
125using namespace clang;
128template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
129 return llvm::any_of(Args, [&](Arg *A) {
130 return (A->getOption().matches(options::OPT_x) &&
132 (A->getOption().
getKind() == Option::InputClass &&
133 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
135 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
140 return Arg ==
"-internal-isystem" || Arg ==
"-internal-externc-isystem" ||
141 Arg ==
"-isystem" || Arg ==
"-cxx-isystem" || Arg ==
"-idirafter";
145 const ArgList &Args) {
146 ArgStringList CC1Args;
147 if (Args.hasArg(options::OPT_stdlibxx_isystem))
152 for (
size_t I = 0; I < CC1Args.size(); ++I) {
153 StringRef Arg(CC1Args[I]);
155 llvm::outs() << CC1Args[++I] <<
'\n';
161 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
162 StringRef UseCUIDStr = A->getValue();
163 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
164 .Case(
"hash", Kind::Hash)
165 .Case(
"random", Kind::Random)
166 .Case(
"none", Kind::None)
167 .Default(Kind::Invalid);
168 if (UseCUID == Kind::Invalid)
169 D.Diag(clang::diag::err_drv_invalid_value)
170 << A->getAsString(Args) << UseCUIDStr;
173 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
174 if (!FixedCUID.empty())
179 llvm::opt::DerivedArgList &Args)
const {
180 std::string CUID = FixedCUID.str();
183 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
187 llvm::MD5::MD5Result
Hash;
188 Hasher.update(InputFile);
189 for (
auto *A : Args) {
190 if (A->getOption().matches(options::OPT_INPUT))
192 Hasher.update(A->getAsString(Args));
195 CUID = llvm::utohexstr(
Hash.low(),
true);
203 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
204 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
210 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
211 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
212 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
215 this->VFS = llvm::vfs::getRealFileSystem();
220 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
223 llvm::sys::path::append(P,
SysRoot);
227#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
228 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
232 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
233 llvm::sys::path::remove_dots(configFileDir,
true);
237#if defined(CLANG_CONFIG_FILE_USER_DIR)
240 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
249void Driver::setDriverMode(StringRef
Value) {
250 static StringRef OptName =
251 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
252 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
253 .Case(
"gcc", GCCMode)
254 .Case(
"g++", GXXMode)
255 .Case(
"cpp", CPPMode)
257 .Case(
"flang", FlangMode)
258 .Case(
"dxc", DXCMode)
262 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
267 bool &ContainsError)
const {
268 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
269 ContainsError =
false;
271 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
272 unsigned MissingArgIndex, MissingArgCount;
273 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
274 MissingArgCount, VisibilityMask);
277 if (MissingArgCount) {
278 Diag(diag::err_drv_missing_argument)
279 << Args.getArgString(MissingArgIndex) << MissingArgCount;
281 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
286 for (
const Arg *A : Args) {
288 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
289 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
296 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
297 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
298 ContainsError |= Diags.getDiagnosticLevel(
299 diag::warn_drv_empty_joined_argument,
304 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
306 auto ArgString = A->getAsString(Args);
308 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
310 if (
getOpts().findExact(ArgString, Nearest,
312 DiagID = diag::err_drv_unknown_argument_with_suggestion;
313 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
315 DiagID = diag::err_drv_unknown_argument;
316 Diags.Report(DiagID) << ArgString;
319 llvm::opt::Visibility(
321 DiagID = diag::err_drv_unknown_argument_with_suggestion;
322 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
324 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
325 : diag::err_drv_unknown_argument;
326 Diags.Report(DiagID) << ArgString;
330 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
331 : diag::err_drv_unknown_argument_with_suggestion;
332 Diags.Report(DiagID) << ArgString << Nearest;
334 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
338 for (
const Arg *A : Args.filtered(options::OPT_o)) {
339 if (ArgStrings[A->getIndex()] == A->getSpelling())
343 std::string ArgString = ArgStrings[A->getIndex()];
345 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
346 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
347 << A->getAsString(Args) << Nearest;
357 Arg **FinalPhaseArg)
const {
358 Arg *PhaseArg =
nullptr;
362 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
374 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
377 options::OPT_fmodule_header_EQ))) {
380 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
381 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
383 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
384 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
385 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
386 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
387 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
388 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
389 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
390 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
394 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
398 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
401 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
409 *FinalPhaseArg = PhaseArg;
417 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
418 llvm::sys::fs::OF_Text);
419 llvm::FileRemover OutputRemover(OutputFile.c_str());
420 std::optional<llvm::StringRef> Redirects[] = {
426 std::string ErrorMessage;
427 int SecondsToWait = 60;
428 if (std::optional<std::string> Str =
429 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
430 if (!llvm::to_integer(*Str, SecondsToWait))
431 return llvm::createStringError(std::error_code(),
432 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
433 "an integer, got '" +
435 SecondsToWait = std::max(SecondsToWait, 0);
437 StringRef Executable = Args[0];
438 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
440 return llvm::createStringError(std::error_code(),
441 Executable +
": " + ErrorMessage);
443 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
444 llvm::MemoryBuffer::getFile(OutputFile.c_str());
446 return llvm::createStringError(OutputBuf.getError(),
447 "Failed to read stdout of " + Executable +
448 ": " + OutputBuf.getError().message());
449 return std::move(*OutputBuf);
453 StringRef
Value,
bool Claim) {
454 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
455 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
456 Args.AddSynthesizedArg(A);
462DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
463 const llvm::opt::OptTable &Opts =
getOpts();
464 DerivedArgList *DAL =
new DerivedArgList(Args);
466 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
467 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
468 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
469 bool IgnoreUnused =
false;
470 for (Arg *A : Args) {
474 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
478 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
479 IgnoreUnused =
false;
489 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
490 A->getOption().matches(options::OPT_Xlinker)) &&
491 A->containsValue(
"--no-demangle")) {
493 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
496 for (StringRef Val : A->getValues())
497 if (Val !=
"--no-demangle")
498 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
506 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
507 A->getNumValues() > 0 &&
508 (A->getValue(0) == StringRef(
"-MD") ||
509 A->getValue(0) == StringRef(
"-MMD"))) {
511 if (A->getValue(0) == StringRef(
"-MD"))
512 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
514 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
515 if (A->getNumValues() == 2)
516 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
521 if (A->getOption().matches(options::OPT_l)) {
522 StringRef
Value = A->getValue();
525 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
527 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
532 if (
Value ==
"cc_kext") {
533 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
539 if (A->getOption().matches(options::OPT__DASH_DASH)) {
541 for (StringRef Val : A->getValues())
550 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
551 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
554 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
555 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
559#if defined(HOST_LINK_VERSION)
560 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
561 strlen(HOST_LINK_VERSION) > 0) {
562 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
564 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
572 StringRef ArgTarget) {
574 static bool BeSilent =
false;
575 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
return v < 3; };
578 if (ArgTarget.equals_insensitive(
"CURRENT")) {
582 unsigned int Version = 0;
583 unsigned int Release = 0;
584 unsigned int Modification = 0;
586 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
587 llvm::Regex HexRegex(
590 "([0-9a-fA-F][0-9a-fA-F])"
591 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
594 if (ZOsvRegex.match(ArgTarget, &Matches)) {
595 Matches[1].getAsInteger(10, Version);
596 Matches[2].getAsInteger(10, Release);
598 if (IsTooOldToBeSupported(Version, Release)) {
600 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
603 }
else if (HexRegex.match(ArgTarget, &Matches)) {
604 Matches[1].getAsInteger(16, Version);
605 Matches[2].getAsInteger(16, Release);
606 Matches[3].getAsInteger(16, Modification);
607 if (IsTooOldToBeSupported(Version, Release)) {
609 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
615 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
620 llvm::VersionTuple
V(Version, Release, Modification);
621 llvm::VersionTuple TV =
Target.getOSVersion();
624 if (TV.empty() ||
V < TV) {
626 Str = llvm::Triple::getOSTypeName(
Target.getOS());
627 Str +=
V.getAsString();
641 StringRef ArchName =
"") {
643 if (
const Arg *A = Args.getLastArg(options::OPT_target))
644 TargetTriple = A->getValue();
646 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
651 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
655 if (
Target.isOSBinFormatMachO()) {
657 if (!ArchName.empty()) {
659 return llvm::Triple(
Target.normalize());
663 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
664 StringRef ArchName = A->getValue();
667 }
else if (!ArchName.empty()) {
668 Target.setArchName(ArchName);
674 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
675 options::OPT_mbig_endian)) {
676 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
677 ?
Target.getLittleEndianArchVariant()
678 :
Target.getBigEndianArchVariant();
679 if (
T.getArch() != llvm::Triple::UnknownArch) {
680 Target = llvm::Triple(
T.normalize());
681 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
686 if (
Target.getArch() == llvm::Triple::tce)
692 if (!Args.hasArg(options::OPT_target)) {
693 if (std::optional<std::string> ObjectModeValue =
694 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
695 StringRef ObjectMode = *ObjectModeValue;
696 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
699 if (ObjectMode ==
"64") {
700 AT =
Target.get64BitArchVariant().getArch();
701 }
else if (ObjectMode ==
"32" || ObjectMode ==
"32_64" ||
702 ObjectMode ==
"any") {
704 if (Args.hasArg(options::OPT_maix64, options::OPT_m64))
705 AT =
Target.get64BitArchVariant().getArch();
707 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
709 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
713 const bool OtherAllowedMode =
714 ObjectMode ==
"32_64" || ObjectMode ==
"any";
715 if (ObjectMode ==
"64")
716 AT =
Target.get64BitArchVariant().getArch();
717 else if (ObjectMode ==
"32")
718 AT =
Target.get32BitArchVariant().getArch();
719 else if (!OtherAllowedMode)
720 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
723 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
728 !Args.hasArg(options::OPT_maix64, options::OPT_m64)) {
731 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
737 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
738 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
741 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
743 D.
Diag(diag::err_drv_unsupported_opt_for_target)
744 << A->getAsString(Args) <<
Target.str();
747 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
748 options::OPT_m32, options::OPT_m16,
749 options::OPT_maix32, options::OPT_maix64);
751 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
753 if (A->getOption().matches(options::OPT_m64) ||
754 A->getOption().matches(options::OPT_maix64)) {
755 AT =
Target.get64BitArchVariant().getArch();
756 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
757 Target.getEnvironment() == llvm::Triple::GNUT64)
758 Target.setEnvironment(llvm::Triple::GNU);
759 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
760 Target.setEnvironment(llvm::Triple::Musl);
761 }
else if (A->getOption().matches(options::OPT_mx32) &&
762 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
763 AT = llvm::Triple::x86_64;
764 if (
Target.getEnvironment() == llvm::Triple::Musl)
765 Target.setEnvironment(llvm::Triple::MuslX32);
767 Target.setEnvironment(llvm::Triple::GNUX32);
768 }
else if (A->getOption().matches(options::OPT_m32) ||
769 A->getOption().matches(options::OPT_maix32)) {
772 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
774 D.
Diag(diag::err_drv_unsupported_opt_for_target)
775 << A->getAsString(Args) <<
Target.str();
778 AT =
Target.get32BitArchVariant().getArch();
779 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
780 Target.setEnvironment(llvm::Triple::GNU);
781 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
782 Target.setEnvironment(llvm::Triple::Musl);
784 }
else if (A->getOption().matches(options::OPT_m16) &&
785 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
786 AT = llvm::Triple::x86;
787 Target.setEnvironment(llvm::Triple::CODE16);
790 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
792 if (
Target.isWindowsGNUEnvironment())
800 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
806 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
807 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
808 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
811 if (A && !A->getOption().matches(options::OPT_m32))
812 D.
Diag(diag::err_drv_argument_not_allowed_with)
813 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
815 Target.setArch(llvm::Triple::x86);
816 Target.setArchName(
"i586");
817 Target.setEnvironmentName(
"");
818 Target.setOS(llvm::Triple::ELFIAMCU);
819 Target.setVendor(llvm::Triple::Intel);
825 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
826 StringRef ABIName = A->getValue();
827 if (ABIName ==
"32") {
829 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
830 Target.getEnvironment() == llvm::Triple::GNUABIN32)
831 Target.setEnvironment(llvm::Triple::GNU);
832 }
else if (ABIName ==
"n32") {
834 if (
Target.getEnvironment() == llvm::Triple::GNU ||
835 Target.getEnvironment() == llvm::Triple::GNUT64 ||
836 Target.getEnvironment() == llvm::Triple::GNUABI64)
837 Target.setEnvironment(llvm::Triple::GNUABIN32);
838 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
839 Target.getEnvironment() == llvm::Triple::MuslABI64)
840 Target.setEnvironment(llvm::Triple::MuslABIN32);
841 }
else if (ABIName ==
"64") {
843 if (
Target.getEnvironment() == llvm::Triple::GNU ||
844 Target.getEnvironment() == llvm::Triple::GNUT64 ||
845 Target.getEnvironment() == llvm::Triple::GNUABIN32)
846 Target.setEnvironment(llvm::Triple::GNUABI64);
847 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
848 Target.getEnvironment() == llvm::Triple::MuslABIN32)
849 Target.setEnvironment(llvm::Triple::MuslABI64);
859 if (Args.hasArg(options::OPT_march_EQ) ||
860 Args.hasArg(options::OPT_mcpu_EQ)) {
862 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
864 if (!llvm::errorToBool(ISAInfo.takeError())) {
865 unsigned XLen = (*ISAInfo)->getXLen();
867 if (
Target.isLittleEndian())
868 Target.setArch(llvm::Triple::riscv32);
870 Target.setArch(llvm::Triple::riscv32be);
872 }
else if (XLen == 64) {
873 if (
Target.isLittleEndian())
874 Target.setArch(llvm::Triple::riscv64);
876 Target.setArch(llvm::Triple::riscv64be);
883 if (
Target.getArch() == llvm::Triple::riscv32be ||
884 Target.getArch() == llvm::Triple::riscv64be) {
885 static bool WarnedRISCVBE =
false;
886 if (!WarnedRISCVBE) {
887 D.
Diag(diag::warn_drv_riscv_be_experimental);
888 WarnedRISCVBE =
true;
897 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
899 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
901 RuntimeName = A->getValue();
903 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
911 Diag(diag::err_drv_unsupported_option_argument)
912 << A->getSpelling() << A->getValue();
915 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
924 StringRef Program =
C.getArgs().getLastArgValue(
925 options::OPT_offload_arch_tool_EQ,
"offload-arch");
928 if (llvm::ErrorOr<std::string> Executable =
929 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
931 bool UsesLLVMOffloading =
932 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
933 options::OPT_fno_offload_via_llvm,
false);
934 if (!UsesLLVMOffloading) {
936 Args.push_back(
"--only=amdgpu");
938 Args.push_back(
"--only=nvptx");
940 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
943 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
948 if ((*StdoutOrErr)->getBuffer().empty()) {
949 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
955 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
957 GPUArchs.push_back(
Arch.str());
959 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
970 std::set<std::string> Archs;
971 for (Arg *A :
C.getInputArgs()) {
972 for (StringRef
Arch : A->getValues()) {
973 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
974 if (
Arch ==
"native") {
976 Archs.insert(Str.str());
978 Archs.insert(
Arch.str());
980 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
984 Archs.erase(
Arch.str());
990 for (llvm::StringRef
Arch : Archs) {
992 if (ID.isUnknown()) {
993 llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
994 llvm::Triple::AMD, llvm::Triple::AMDHSA);
998 bool UsesLLVMOffloading =
999 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
1000 options::OPT_fno_offload_via_llvm,
false);
1001 if (!UsesLLVMOffloading) {
1002 if (Kind ==
Action::OFK_HIP && !ID.isAMDGPU() && !ID.isAMDGCNSPIRV()) {
1003 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1008 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1014 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1018 if (ID.isUnknown() || ID.isUnused()) {
1019 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1020 <<
"offload" <<
Arch;
1024 llvm::Triple Triple =
1026 if (UsesLLVMOffloading)
1027 Triple.setEnvironment(llvm::Triple::LLVM);
1032 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1033 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1034 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1035 C.getArgs().MakeArgString(Triple.getArchName()),
1036 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1038 C.getArgs().append(A);
1039 C.getArgs().AddSynthesizedArg(A);
1041 auto It = Triples.lower_bound(Triple);
1042 if (It == Triples.end() || *It != Triple)
1043 Triples.insert(It, Triple);
1048 Triples.insert(llvm::Triple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
1049 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1051 llvm::Triple::ArchType
Arch =
1052 C.getDefaultToolChain().getTriple().isArch64Bit()
1053 ? llvm::Triple::nvptx64
1054 : llvm::Triple::nvptx;
1055 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1056 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1059 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1060 ? llvm::Triple::spirv64
1061 : llvm::Triple::spirv32));
1064 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1065 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1073 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1077 (llvm::any_of(Inputs,
1078 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1081 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1082 C.getInputArgs().hasArg(options::OPT_hipstdpar));
1083 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1084 options::OPT_fno_sycl,
false);
1085 bool IsOpenMPOffloading =
1086 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1087 options::OPT_fno_openmp,
false) &&
1088 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1089 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1090 !(IsCuda || IsHIP))));
1092 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1093 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1098 for (
const auto &[Active, Kind] : ActiveKinds)
1103 if (Kinds.size() > 1) {
1104 Diag(clang::diag::err_drv_mix_offload)
1111 if (IsCuda || IsHIP)
1118 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1119 std::vector<std::string> ArgValues =
1120 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1121 for (llvm::StringRef
Target : ArgValues) {
1125 if (ArgValues.empty())
1126 Diag(clang::diag::warn_drv_empty_joined_argument)
1128 .getLastArg(options::OPT_offload_targets_EQ)
1129 ->getAsString(
C.getInputArgs());
1136 llvm::StringMap<StringRef> FoundNormalizedTriples;
1137 for (
const llvm::Triple &
Target : Triples) {
1142 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1150 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1151 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1152 Diag(clang::diag::err_drv_argument_not_allowed_with)
1153 << IncompatArg->getSpelling() <<
"-fsycl";
1158 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1159 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1164 std::string NormalizedName =
Target.normalize();
1165 auto [TripleIt, Inserted] =
1166 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1168 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1169 <<
Target.str() << TripleIt->second;
1173 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1174 C.getDefaultToolChain().getTriple());
1178 auto &CudaInstallation =
1180 if (CudaInstallation.isValid())
1181 CudaInstallation.WarnIfUnsupportedVersion();
1184 C.addOffloadDeviceToolChain(&TC, Kind);
1192 const Arg *RDCArg =
C.getInputArgs().getLastArg(options::OPT_fgpu_rdc,
1193 options::OPT_fno_gpu_rdc);
1194 if (RDCArg && RDCArg->getOption().matches(options::OPT_fno_gpu_rdc)) {
1196 if (std::distance(TCRange.first, TCRange.second) > 1)
1197 Diag(clang::diag::err_drv_sycl_no_rdc_multiple_targets)
1198 << RDCArg->getAsString(
C.getInputArgs());
1203bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1208 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1212 if (!PathLIBEnv.empty()) {
1213 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1214 if (llvm::sys::fs::is_directory(PathLIBEnv))
1215 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1216 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1217 return readConfigFile(CustomizationFile, ExpCtx);
1218 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1223 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1224 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1225 return readConfigFile(CustomizationFile, ExpCtx);
1235 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1236 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1237 Copy->getValues() = Opt->getValues();
1238 if (Opt->isClaimed())
1240 Copy->setOwnsValues(Opt->getOwnsValues());
1241 Opt->setOwnsValues(
false);
1243 if (Opt->getAlias()) {
1244 const Arg *Alias = Opt->getAlias();
1245 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1246 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1247 Args.getArgString(Index), Index);
1248 AliasCopy->getValues() = Alias->getValues();
1249 AliasCopy->setOwnsValues(
false);
1250 if (Alias->isClaimed())
1252 Copy->setAlias(std::move(AliasCopy));
1256bool Driver::readConfigFile(StringRef
FileName,
1257 llvm::cl::ExpansionContext &ExpCtx) {
1261 Diag(diag::err_drv_cannot_open_config_file)
1262 <<
FileName << Status.getError().message();
1265 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1266 Diag(diag::err_drv_cannot_open_config_file)
1267 <<
FileName <<
"not a regular file";
1272 SmallVector<const char *, 32> NewCfgFileArgs;
1273 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1274 Diag(diag::err_drv_cannot_read_config_file)
1280 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1281 for (
const char *Opt : NewCfgFileArgs) {
1283 if (Opt[0] ==
'$' && Opt[1])
1284 NewCfgTailArgs.push_back(Opt + 1);
1286 NewCfgHeadArgs.push_back(Opt);
1290 llvm::SmallString<128> CfgFileName(
FileName);
1291 llvm::sys::path::native(CfgFileName);
1292 bool ContainErrors =
false;
1293 auto NewHeadOptions = std::make_unique<InputArgList>(
1297 auto NewTailOptions = std::make_unique<InputArgList>(
1304 for (Arg *A : *NewHeadOptions)
1306 for (Arg *A : *NewTailOptions)
1309 if (!CfgOptionsHead)
1310 CfgOptionsHead = std::move(NewHeadOptions);
1313 for (
auto *Opt : *NewHeadOptions)
1317 if (!CfgOptionsTail)
1318 CfgOptionsTail = std::move(NewTailOptions);
1321 for (
auto *Opt : *NewTailOptions)
1325 ConfigFiles.push_back(std::string(CfgFileName));
1329bool Driver::loadConfigFiles() {
1330 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1331 llvm::cl::tokenizeConfigFile, &
getVFS());
1335 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1336 SmallString<128> CfgDir;
1338 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1339 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1344 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1345 SmallString<128> CfgDir;
1346 llvm::sys::fs::expand_tilde(
1347 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1348 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1357 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1360 if (loadDefaultConfigFiles(ExpCtx))
1364 SmallString<128> CfgFilePath;
1366 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1369 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1370 CfgFilePath.assign(CfgFileName);
1371 if (llvm::sys::path::is_relative(CfgFilePath)) {
1372 if (
getVFS().makeAbsolute(CfgFilePath)) {
1373 Diag(diag::err_drv_cannot_open_config_file)
1374 << CfgFilePath <<
"cannot get absolute path";
1378 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1380 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1381 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1382 if (!SearchDir.empty())
1383 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1388 if (readConfigFile(CfgFilePath, ExpCtx))
1399 llvm::Triple Triple, std::string Suffix) {
1401 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1405 VersionTuple OSVersion = Triple.getOSVersion();
1406 if (!OSVersion.getMinor().has_value())
1409 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1413 if (OSVersion.getMajor() != 0) {
1414 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1415 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1421 Triple.setOSName(BaseOSName);
1422 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1425bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1428 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1432 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1435 std::string RealMode = getExecutableForDriverMode(Mode);
1436 llvm::Triple Triple;
1445 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1446 PrefixTriple.isOSUnknown())
1447 Triple = std::move(PrefixTriple);
1451 llvm::Triple RealTriple =
1453 if (Triple.str().empty()) {
1454 Triple = RealTriple;
1455 assert(!Triple.str().empty());
1460 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1474 SmallString<128> CfgFilePath;
1476 "-" + RealMode +
".cfg"))
1477 return readConfigFile(CfgFilePath, ExpCtx);
1481 if (TryModeSuffix) {
1484 return readConfigFile(CfgFilePath, ExpCtx);
1489 std::string CfgFileName = RealMode +
".cfg";
1490 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1491 if (readConfigFile(CfgFilePath, ExpCtx))
1493 }
else if (TryModeSuffix) {
1495 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1496 readConfigFile(CfgFilePath, ExpCtx))
1502 return readConfigFile(CfgFilePath, ExpCtx);
1510 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1519 if (!DriverMode.empty())
1520 setDriverMode(DriverMode);
1526 CLOptions = std::make_unique<InputArgList>(
1531 ContainsError = loadConfigFiles();
1532 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1533 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1537 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1539 if (HasConfigFileHead)
1540 for (
auto *Opt : *CLOptions)
1541 if (!Opt->getOption().matches(options::OPT_config))
1545 if (
IsCLMode() && !ContainsError) {
1547 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1549 CLModePassThroughArgList.push_back(A->getValue());
1552 if (!CLModePassThroughArgList.empty()) {
1555 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1560 for (
auto *Opt : *CLModePassThroughOptions)
1566 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1567 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1568 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1571 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1572 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1573 if (!VFS->exists(IncludeDir))
1574 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1579 bool CCCPrintPhases;
1582 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1583 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1586 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1587 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1590 Args.ClaimAllArgs(options::OPT_pipe);
1598 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1600 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1601 CCCGenericGCCName = A->getValue();
1604 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1608 if (Args.hasArg(options::OPT_fproc_stat_report))
1615 llvm::Triple
T(TargetTriple);
1616 T.setOS(llvm::Triple::Win32);
1617 T.setVendor(llvm::Triple::PC);
1618 T.setEnvironment(llvm::Triple::MSVC);
1619 T.setObjectFormat(llvm::Triple::COFF);
1620 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1621 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1622 TargetTriple =
T.str();
1625 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1626 StringRef TargetProfile = A->getValue();
1629 TargetTriple = *Triple;
1631 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1635 if (Args.hasArg(options::OPT_spirv)) {
1636 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1637 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1638 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1639 llvm::Triple
T(TargetTriple);
1642 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1644 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1645 TargetInfo = ValidTargets.find(A->getValue());
1647 Diag(diag::err_drv_invalid_value)
1648 << A->getAsString(Args) << A->getValue();
1654 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1655 TargetTriple =
T.str();
1659 Diag(diag::err_drv_dxc_missing_target_profile);
1663 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1664 TargetTriple = A->getValue();
1665 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1666 Dir = A->getValue();
1667 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1671 if (std::optional<std::string> CompilerPathValue =
1672 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1673 StringRef CompilerPath = *CompilerPathValue;
1674 while (!CompilerPath.empty()) {
1675 std::pair<StringRef, StringRef> Split =
1676 CompilerPath.split(llvm::sys::EnvPathSeparator);
1677 PrefixDirs.push_back(std::string(Split.first));
1678 CompilerPath = Split.second;
1681 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1683 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1686 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1689 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1690 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1691 .Case(
"cwd", SaveTempsCwd)
1692 .Case(
"obj", SaveTempsObj)
1693 .Default(SaveTempsCwd);
1696 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1697 options::OPT_offload_device_only,
1698 options::OPT_offload_host_device)) {
1699 if (A->getOption().matches(options::OPT_offload_host_only))
1700 Offload = OffloadHost;
1701 else if (A->getOption().matches(options::OPT_offload_device_only))
1702 Offload = OffloadDevice;
1704 Offload = OffloadHostDevice;
1708 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1709 StringRef
Name = A->getValue();
1710 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1711 .Case(
"off", EmbedNone)
1712 .Case(
"all", EmbedBitcode)
1713 .Case(
"bitcode", EmbedBitcode)
1714 .Case(
"marker", EmbedMarker)
1717 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1720 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1724 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1725 llvm::sys::fs::remove(A->getValue());
1731 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1733 !Args.hasArg(options::OPT_fmodules) && Std &&
1734 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1735 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1736 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1737 Std->containsValue(
"c++2d") || Std->containsValue(
"c++latest"));
1740 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1741 options::OPT_fmodule_header)) {
1743 ModulesModeCXX20 =
true;
1744 if (A->getOption().matches(options::OPT_fmodule_header))
1747 StringRef ArgName = A->getValue();
1748 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1753 Diags.Report(diag::err_drv_invalid_value)
1754 << A->getAsString(Args) << ArgName;
1760 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1761 std::make_unique<InputArgList>(std::move(Args));
1771 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1772 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1774 bool MLContainsError;
1775 auto MultilibMacroDefineList =
1777 MLMacroDefinesChar,
false, MLContainsError));
1778 if (!MLContainsError) {
1779 for (
auto *Opt : *MultilibMacroDefineList) {
1786 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1790 if (!Triple.isWasm()) {
1791 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1792 StringRef TripleObjectFormat =
1793 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1794 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1795 TripleVersionName != TripleObjectFormat) {
1796 Diags.Report(diag::err_drv_triple_version_invalid)
1798 ContainsError =
true;
1803 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1804 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1805 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1813 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1814 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1816 case llvm::Triple::arm:
1817 case llvm::Triple::armeb:
1818 case llvm::Triple::thumb:
1819 case llvm::Triple::thumbeb:
1820 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1821 Diag(diag::warn_target_unrecognized_env)
1823 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1826 case llvm::Triple::aarch64:
1827 case llvm::Triple::aarch64_be:
1828 case llvm::Triple::aarch64_32:
1829 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1830 Diag(diag::warn_target_unrecognized_env)
1832 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1849 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1850 if (HasConfigFileTail && Inputs.size()) {
1853 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1854 for (Arg *A : *CfgOptionsTail)
1855 TranslatedLinkerIns.append(A);
1856 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1863 bool UseModulesDriver =
C->getArgs().hasFlag(
1864 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1866 if (UseModulesDriver) {
1867 Diags.Report(diag::remark_performing_driver_managed_module_build);
1875 const auto StdModuleManifestPath =
1878 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1879 Diags.Report(diag::remark_modules_manifest_not_found);
1881 Diags.Report(diag::remark_using_modules_manifest)
1882 << StdModuleManifestPath;
1883 if (
auto ManifestOrErr =
1885 ModulesManifest = std::move(*ManifestOrErr);
1887 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1888 return !ModuleEntry.IsStdlib;
1893 llvm::handleAllErrors(
1894 ManifestOrErr.takeError(),
1895 [&](llvm::json::ParseError &Err) {
1896 Diags.Report(diag::err_modules_manifest_failed_parse)
1899 [&](llvm::FileError &Err) {
1900 Diags.Report(diag::err_cannot_open_file)
1901 << Err.getFileName() << Err.messageWithoutFileInfo();
1909 if (TC.
getTriple().isOSBinFormatMachO())
1914 if (CCCPrintPhases) {
1921 if (UseModulesDriver)
1928 llvm::opt::ArgStringList ASL;
1929 for (
const auto *A : Args) {
1933 while (A->getAlias())
1935 A->render(Args, ASL);
1938 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1939 if (I != ASL.begin())
1941 llvm::sys::printArg(OS, *I,
true);
1946bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1947 SmallString<128> &CrashDiagDir) {
1948 using namespace llvm::sys;
1949 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1950 "Only knows about .crash files on Darwin");
1952 auto BypassSandbox = sandbox::scopedDisable();
1957 path::home_directory(CrashDiagDir);
1958 if (CrashDiagDir.starts_with(
"/var/root"))
1960 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1968 fs::file_status FileStatus;
1969 TimePoint<> LastAccessTime;
1970 SmallString<128> CrashFilePath;
1973 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1974 File != FileEnd && !EC;
File.increment(EC)) {
1978 if (fs::status(
File->path(), FileStatus))
1980 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1981 llvm::MemoryBuffer::getFile(
File->path());
1986 StringRef
Data = CrashFile.get()->getBuffer();
1987 if (!
Data.starts_with(
"Process:"))
1990 size_t ParentProcPos =
Data.find(
"Parent Process:");
1991 if (ParentProcPos == StringRef::npos)
1993 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1994 if (LineEnd == StringRef::npos)
1996 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1997 int OpenBracket = -1, CloseBracket = -1;
1998 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1999 if (ParentProcess[i] ==
'[')
2001 if (ParentProcess[i] ==
']')
2007 if (OpenBracket < 0 || CloseBracket < 0 ||
2008 ParentProcess.slice(OpenBracket + 1, CloseBracket)
2009 .getAsInteger(10, CrashPID) || CrashPID != PID) {
2019 const auto FileAccessTime = FileStatus.getLastModificationTime();
2020 if (FileAccessTime > LastAccessTime) {
2021 CrashFilePath.assign(
File->path());
2022 LastAccessTime = FileAccessTime;
2027 if (!CrashFilePath.empty()) {
2028 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2038 "\n********************\n\n"
2039 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
2047 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2050 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
2053 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2054 Level = llvm::StringSwitch<unsigned>(A->getValue())
2056 .Case(
"compiler", 1)
2068 ArgStringList SavedTemps;
2070 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2071 if (!IsLLD || Level < 2)
2078 SavedTemps = std::move(
C.getTempFiles());
2079 assert(!
C.getTempFiles().size());
2096 C.initCompilationForDiagnostics();
2101 Command NewLLDInvocation = Cmd;
2102 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2103 StringRef ReproduceOption =
2104 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2107 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2111 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2113 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2114 Diag(clang::diag::note_drv_command_failed_diag_msg)
2115 <<
"\n\n********************";
2117 Report->TemporaryFiles.push_back(TmpName);
2125 ArgStringList IRInputs;
2126 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2127 bool IgnoreInput =
false;
2133 IRInputs.push_back(it->second->getValue());
2137 }
else if (!strcmp(it->second->getValue(),
"-")) {
2138 Diag(clang::diag::note_drv_command_failed_diag_msg)
2139 <<
"Error generating preprocessed source(s) - "
2140 "ignoring input from stdin.";
2145 it = Inputs.erase(it);
2152 if (Inputs.empty() && IRInputs.empty()) {
2153 Diag(clang::diag::note_drv_command_failed_diag_msg)
2154 <<
"Error generating preprocessed source(s) - "
2155 "no preprocessable inputs.";
2161 llvm::StringSet<> ArchNames;
2162 for (
const Arg *A :
C.getArgs()) {
2163 if (A->getOption().matches(options::OPT_arch)) {
2164 StringRef ArchName = A->getValue();
2165 ArchNames.insert(ArchName);
2168 if (ArchNames.size() > 1) {
2171 if (FailingArch.empty()) {
2172 Diag(clang::diag::note_drv_command_failed_diag_msg)
2173 <<
"Error generating preprocessed source(s) - cannot generate "
2174 "preprocessed source with multiple -arch options.";
2177 C.getArgs().eraseArg(options::OPT_arch);
2178 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2183 if (!Inputs.empty()) {
2186 const ToolChain &TC =
C.getDefaultToolChain();
2187 if (TC.
getTriple().isOSBinFormatMachO())
2196 Diag(clang::diag::note_drv_command_failed_diag_msg)
2197 <<
"Error generating preprocessed source(s).";
2202 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2205 if (!FailingCommands.empty()) {
2206 Diag(clang::diag::note_drv_command_failed_diag_msg)
2207 <<
"Error generating preprocessed source(s).";
2211 const ArgStringList &TempFiles =
C.getTempFiles();
2212 if (TempFiles.empty()) {
2213 Diag(clang::diag::note_drv_command_failed_diag_msg)
2214 <<
"Error generating preprocessed source(s).";
2220 const ArgStringList &Files =
C.getTempFiles();
2225 for (
auto const *Input : IRInputs) {
2229 StringRef extension = llvm::sys::path::extension(Input);
2230 if (!extension.empty())
2231 extension = extension.drop_front();
2233 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2234 llvm::sys::path::stem(Input), extension, FD, Path);
2236 Diag(clang::diag::note_drv_command_failed_diag_msg)
2237 <<
"Error generating run script: " <<
"Failed copying IR input files"
2238 <<
" " << EC.message();
2242 EC = llvm::sys::fs::copy_file(Input, FD);
2244 Diag(clang::diag::note_drv_command_failed_diag_msg)
2245 <<
"Error generating run script: " <<
"Failed copying IR input files"
2246 <<
" " << EC.message();
2250 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2257 for (std::string &TempFile : TempFiles) {
2259 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2261 Report->TemporaryFiles.push_back(TempFile);
2262 if (ReproCrashFilename.empty()) {
2263 ReproCrashFilename = TempFile;
2264 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2266 if (StringRef(TempFile).ends_with(
".cache")) {
2269 VFS = llvm::sys::path::filename(TempFile);
2270 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2274 for (
const char *TempFile : SavedTemps)
2275 TempFiles.push_back(TempFile);
2281 llvm::sys::path::replace_extension(Script,
"sh");
2283 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2284 llvm::sys::fs::FA_Write,
2285 llvm::sys::fs::OF_Text);
2287 Diag(clang::diag::note_drv_command_failed_diag_msg)
2288 <<
"Error generating run script: " << Script <<
" " << EC.message();
2291 <<
"# Driver args: ";
2293 ScriptOS <<
"# Original command: ";
2294 Cmd.
Print(ScriptOS,
"\n",
true);
2295 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2296 if (!AdditionalInformation.empty())
2297 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2300 Report->TemporaryFiles.push_back(std::string(Script));
2301 TempFiles.push_back(std::string(Script));
2304 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2307 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2308 StringRef CrashDiagnosticsTar = A->getValue();
2310 llvm::TarWriter::create(CrashDiagnosticsTar,
2311 llvm::sys::path::stem(CrashDiagnosticsTar));
2313 Diag(clang::diag::note_drv_command_failed_diag_msg)
2314 << (std::string(
"Error creating reproducer tarball: ") +
2315 llvm::toString(TarOrErr.takeError()));
2317 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2318 for (
const std::string &TempFile : TempFiles) {
2319 if (llvm::sys::fs::is_directory(TempFile)) {
2321 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2322 I != E && !EC; I.increment(EC)) {
2323 if (llvm::sys::fs::is_regular_file(I->path())) {
2324 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2328 llvm::sys::path::filename(TempFile);
2329 StringRef SubPath = I->path();
2330 if (SubPath.consume_front(TempFile)) {
2331 if (!SubPath.empty() &&
2332 llvm::sys::path::is_separator(SubPath.front())) {
2333 SubPath = SubPath.drop_front();
2335 llvm::sys::path::append(PathInTar, SubPath);
2336 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2339 Diag(clang::diag::note_drv_command_failed_diag_msg)
2340 << (std::string(
"Error reading file for tarball: ") +
2346 Diag(clang::diag::note_drv_command_failed_diag_msg)
2347 << (std::string(
"Error iterating directory for tarball: ") +
2348 TempFile +
" " + EC.message());
2351 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2353 Tar->append(llvm::sys::path::filename(TempFile),
2354 (*BufferOrErr)->getBuffer());
2356 Diag(clang::diag::note_drv_command_failed_diag_msg)
2357 << (std::string(
"Error reading file for tarball: ") + TempFile);
2361 Diag(clang::diag::note_drv_command_failed_diag_msg)
2362 << CrashDiagnosticsTar;
2367 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2369 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2370 Diag(clang::diag::note_drv_command_failed_diag_msg)
2371 << ReproCrashFilename.str();
2373 llvm::sys::path::append(CrashDiagDir,
Name);
2374 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2375 Diag(clang::diag::note_drv_command_failed_diag_msg)
2376 <<
"Crash backtrace is located in";
2377 Diag(clang::diag::note_drv_command_failed_diag_msg)
2378 << CrashDiagDir.str();
2379 Diag(clang::diag::note_drv_command_failed_diag_msg)
2380 <<
"(choose the .crash file that corresponds to your crash)";
2384 Diag(clang::diag::note_drv_command_failed_diag_msg)
2385 <<
"\n\n********************";
2395 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2406 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2407 if (
C.getArgs().hasArg(options::OPT_v))
2408 C.getJobs().Print(llvm::errs(),
"\n",
true);
2410 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2413 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2420 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2421 C.getJobs().Print(llvm::errs(),
"\n",
true);
2422 return Diags.hasErrorOccurred() ? 1 : 0;
2426 if (Diags.hasErrorOccurred())
2430 for (
auto &Job :
C.getJobs())
2431 setUpResponseFiles(
C, Job);
2433 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2436 if (FailingCommands.empty())
2442 for (
const auto &CmdPair : FailingCommands) {
2443 int CommandRes = CmdPair.first;
2444 const Command *FailingCommand = CmdPair.second;
2449 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2453 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2458 if (CommandRes == EX_IOERR) {
2478 if (CommandRes > 128 && CommandRes != 255)
2482 Diag(clang::diag::err_drv_command_signalled)
2485 Diag(clang::diag::err_drv_command_failed)
2493 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2495 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2509 const ToolChain &TC =
C.getDefaultToolChain();
2513 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2516 OS <<
"Thread model: " << A->getValue();
2522 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2527 if (!llvm::cl::getCompilerBuildConfig().empty())
2528 llvm::cl::printBuildConfig(OS);
2531 for (
auto ConfigFile : ConfigFiles)
2532 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2545 if (PassedFlags ==
"")
2549 std::vector<std::string> SuggestedCompletions;
2550 std::vector<std::string> Flags;
2562 const bool HasSpace = PassedFlags.ends_with(
",");
2566 StringRef TargetFlags = PassedFlags;
2567 while (TargetFlags !=
"") {
2569 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2570 Flags.push_back(std::string(CurFlag));
2575 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2578 const llvm::opt::OptTable &Opts =
getOpts();
2580 Cur = Flags.at(Flags.size() - 1);
2582 if (Flags.size() >= 2) {
2583 Prev = Flags.at(Flags.size() - 2);
2584 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2587 if (SuggestedCompletions.empty())
2588 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2595 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2596 llvm::outs() <<
'\n';
2602 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2606 SuggestedCompletions = Opts.findByPrefix(
2607 Cur, VisibilityMask,
2614 if (S.starts_with(Cur))
2615 SuggestedCompletions.push_back(std::string(S));
2622 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2623 if (
int X = A.compare_insensitive(B))
2625 return A.compare(B) > 0;
2628 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2635 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2636 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2640 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2643 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2647 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2652 if (
C.getArgs().hasArg(options::OPT_help) ||
2653 C.getArgs().hasArg(options::OPT__help_hidden)) {
2654 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2658 if (
C.getArgs().hasArg(options::OPT__version)) {
2665 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2666 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2667 if (ListExtractors || ListFormats) {
2675 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2680 if (
C.getArgs().hasArg(options::OPT_v) ||
2681 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2682 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2683 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2684 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2686 SuppressMissingInputWarning =
true;
2689 if (
C.getArgs().hasArg(options::OPT_v)) {
2691 llvm::errs() <<
"System configuration file directory: "
2694 llvm::errs() <<
"User configuration file directory: "
2698 const ToolChain &TC =
C.getDefaultToolChain();
2700 if (
C.getArgs().hasArg(options::OPT_v))
2703 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2708 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2709 llvm::outs() <<
"programs: =";
2710 bool separator =
false;
2714 llvm::outs() << llvm::sys::EnvPathSeparator;
2715 llvm::outs() << Path;
2720 llvm::outs() << llvm::sys::EnvPathSeparator;
2721 llvm::outs() << Path;
2724 llvm::outs() <<
"\n";
2727 StringRef sysroot =
C.getSysRoot();
2731 llvm::outs() << llvm::sys::EnvPathSeparator;
2734 llvm::outs() << sysroot << Path.substr(1);
2736 llvm::outs() << Path;
2738 llvm::outs() <<
"\n";
2742 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib)) {
2747 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib_include_dirs)) {
2752 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2758 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2759 for (
auto RuntimePath :
2761 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2762 llvm::outs() << *RuntimePath <<
'\n';
2766 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2770 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2772 for (std::size_t I = 0; I != Flags.size(); I += 2)
2773 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2779 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2780 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2784 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2785 StringRef ProgName = A->getValue();
2788 if (! ProgName.empty())
2791 llvm::outs() <<
"\n";
2795 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2796 StringRef PassedFlags = A->getValue();
2801 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2811 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2816 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2819 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2825 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2832 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2835 std::set<llvm::StringRef> SortedFlags;
2836 for (
const auto &FlagEntry : ExpandedFlags)
2837 SortedFlags.insert(FlagEntry.getKey());
2838 for (
auto Flag : SortedFlags)
2839 llvm::outs() << Flag <<
'\n';
2843 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2846 llvm::outs() <<
".\n";
2849 assert(Suffix.front() ==
'/');
2850 llvm::outs() << Suffix.substr(1) <<
"\n";
2856 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2861 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2863 llvm::outs() << Triple.getTriple() <<
"\n";
2867 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2868 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2885 std::map<Action *, unsigned> &Ids,
2887 if (
auto It = Ids.find(A); It != Ids.end())
2891 llvm::raw_string_ostream os(str);
2893 auto getSibIndent = [](
int K) -> Twine {
2897 Twine SibIndent =
Indent + getSibIndent(Kind);
2901 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2903 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2904 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2905 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2907 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2908 assert(TC &&
"Unknown host toolchain");
2923 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2931 const char *Prefix =
"{";
2932 for (
Action *PreRequisite : *AL) {
2933 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2944 std::string offload_str;
2945 llvm::raw_string_ostream offload_os(offload_str);
2949 offload_os <<
", (" << S;
2956 auto getSelfIndent = [](
int K) -> Twine {
2960 unsigned Id = Ids.size();
2962 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2971 std::map<Action *, unsigned> Ids;
2972 for (
Action *A :
C.getActions())
2988 DerivedArgList &Args =
C.getArgs();
2990 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2993 llvm::StringSet<> ArchNames;
2995 for (Arg *A : Args) {
2996 if (A->getOption().matches(options::OPT_arch)) {
2999 llvm::Triple::ArchType
Arch =
3001 if (
Arch == llvm::Triple::UnknownArch) {
3002 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
3007 if (ArchNames.insert(A->getValue()).second)
3008 Archs.push_back(A->getValue());
3022 for (
Action* Act : SingleActions) {
3030 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
3034 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
3039 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
3040 Actions.append(Inputs.begin(), Inputs.end());
3042 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
3045 Arg *A = Args.getLastArg(options::OPT_g_Group);
3046 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
3047 !A->getOption().matches(options::OPT_gstabs);
3048 bool enablesPseudoProbe =
3049 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
3050 options::OPT_fno_pseudo_probe_for_profiling,
false);
3051 bool enablesDebugInfoForProfiling =
3052 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
3053 options::OPT_fno_debug_info_for_profiling,
false);
3054 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
3055 enablesDebugInfoForProfiling) &&
3063 if (Act->getType() == types::TY_Image) {
3065 Inputs.push_back(Actions.back());
3072 if (Args.hasArg(options::OPT_verify_debug_info)) {
3073 Action *LastAction = Actions.pop_back_val();
3075 LastAction, types::TY_Nothing));
3082 bool TypoCorrect)
const {
3094 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3095 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3107 std::string Nearest;
3108 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3109 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3110 <<
Value << Nearest;
3149 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3152 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3160 return types::TY_CXXUHeader;
3162 return types::TY_CXXSHeader;
3166 llvm_unreachable(
"should not be called in this case");
3168 return types::TY_CXXHUHeader;
3174 const llvm::opt::OptTable &Opts =
getOpts();
3178 types::ID InputType = types::TY_Nothing;
3179 Arg *InputTypeArg =
nullptr;
3182 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3183 options::OPT__SLASH_TP)) {
3184 InputTypeArg = TCTP;
3185 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3190 bool ShowNote =
false;
3192 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3194 Diag(clang::diag::warn_drv_overriding_option)
3195 <<
Previous->getSpelling() << A->getSpelling();
3201 Diag(clang::diag::note_drv_t_option_is_global);
3206 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3207 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3208 if (LastXArg && LastInputArg &&
3209 LastInputArg->getIndex() < LastXArg->getIndex())
3210 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3213 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3215 for (Arg *A : Args) {
3216 if (A->getOption().
getKind() == Option::InputClass) {
3217 const char *
Value = A->getValue();
3221 if (InputType == types::TY_Nothing) {
3224 InputTypeArg->claim();
3227 if (strcmp(
Value,
"-") == 0) {
3229 Ty = types::TY_Fortran;
3231 Ty = types::TY_HLSL;
3232 }
else if (IsSYCL) {
3242 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3243 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3244 : clang::diag::err_drv_unknown_stdin_type);
3253 if (
const char *Ext = strrchr(
Value,
'.'))
3262 Ty = types::TY_HLSL;
3264 Ty = types::TY_Object;
3275 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3276 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3277 << getTypeName(OldTy) << getTypeName(Ty);
3282 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3283 Ty == types::TY_Object)
3284 Ty = types::TY_LLVM_BC;
3292 if (Ty != types::TY_Object) {
3293 if (Args.hasArg(options::OPT_ObjC))
3294 Ty = types::TY_ObjC;
3295 else if (Args.hasArg(options::OPT_ObjCXX))
3296 Ty = types::TY_ObjCXX;
3303 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3307 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3308 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3311 const char *Ext = strrchr(
Value,
'.');
3313 Ty = types::TY_Object;
3317 InputTypeArg->claim();
3321 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3322 Args.hasArgNoClaim(options::OPT_hipstdpar))
3326 Inputs.push_back(std::make_pair(Ty, A));
3328 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3329 StringRef
Value = A->getValue();
3332 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3333 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3336 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3337 StringRef
Value = A->getValue();
3340 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3341 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3347 Inputs.push_back(std::make_pair(types::TY_Object, A));
3349 }
else if (A->getOption().matches(options::OPT_x)) {
3358 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3359 InputType = types::TY_Object;
3366 }
else if (A->getOption().getID() == options::OPT_U) {
3367 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3368 StringRef Val = A->getValue(0);
3369 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3371 Diag(diag::warn_slash_u_filename) << Val;
3372 Diag(diag::note_use_dashdash);
3376 if (
CCCIsCPP() && Inputs.empty()) {
3380 Inputs.push_back(std::make_pair(types::TY_C, A));
3384void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3389 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
3390 StringRef
V = A->getValue();
3391 if (Inputs.size() > 1 && !
V.empty() &&
3392 !llvm::sys::path::is_separator(
V.back())) {
3394 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3395 << A->getSpelling() <<
V;
3396 Args.eraseArg(options::OPT__SLASH_Fo);
3401 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
3402 StringRef
V = A->getValue();
3403 if (Inputs.size() > 1 && !
V.empty() &&
3404 !llvm::sys::path::is_separator(
V.back())) {
3406 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3407 << A->getSpelling() <<
V;
3408 Args.eraseArg(options::OPT__SLASH_Fa);
3413 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
3414 if (A->getValue()[0] ==
'\0') {
3416 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
3417 Args.eraseArg(options::OPT__SLASH_o);
3422 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3423 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3424 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3425 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3426 Args.eraseArg(options::OPT__SLASH_Yc);
3427 Args.eraseArg(options::OPT__SLASH_Yu);
3428 YcArg = YuArg =
nullptr;
3430 if (YcArg && Inputs.size() > 1) {
3431 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3432 Args.eraseArg(options::OPT__SLASH_Yc);
3440 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3441 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3442 Args.AddFlagArg(
nullptr,
3443 getOpts().getOption(options::OPT_frtlib_add_rpath));
3447 if (Args.hasArg(options::OPT_emit_llvm) &&
3448 !Args.hasArg(options::OPT_hip_link) &&
3449 !
C.getDefaultToolChain().getTriple().isSPIRV())
3450 Diag(clang::diag::err_drv_emit_llvm_link);
3451 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
3452 C.getDefaultToolChain().isUsingLTO(Args) &&
3453 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
3454 .starts_with_insensitive(
"lld"))
3455 Diag(clang::diag::err_drv_lto_without_lld);
3461 if (!Args.hasArg(options::OPT_dumpdir)) {
3462 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
3463 Arg *Arg = Args.MakeSeparateArg(
3464 nullptr,
getOpts().getOption(options::OPT_dumpdir),
3466 (FinalOutput ? FinalOutput->getValue()
3478 Args.eraseArg(options::OPT__SLASH_Fp);
3479 Args.eraseArg(options::OPT__SLASH_Yc);
3480 Args.eraseArg(options::OPT__SLASH_Yu);
3481 YcArg = YuArg =
nullptr;
3484 if (Args.hasArg(options::OPT_include_pch) &&
3485 Args.hasArg(options::OPT_ignore_pch)) {
3489 Args.eraseArg(options::OPT_include_pch);
3492 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
3493 for (
auto &I : Inputs) {
3495 const Arg *InputArg = I.second;
3500 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
3504 if (InitialPhase > FinalPhase) {
3505 if (InputArg->isClaimed())
3512 if (Args.hasArg(options::OPT_Qunused_arguments))
3518 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3519 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3523 (Args.getLastArg(options::OPT__SLASH_EP,
3524 options::OPT__SLASH_P) ||
3525 Args.getLastArg(options::OPT_E) ||
3526 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3528 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3529 << InputArg->getAsString(Args) << !FinalPhaseArg
3530 << (FinalPhaseArg ? FinalPhaseArg->getSpelling() :
"");
3532 Diag(clang::diag::warn_drv_input_file_unused)
3533 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3535 << (FinalPhaseArg ? FinalPhaseArg->getSpelling() :
"");
3544 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
3545 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
3550 Actions.push_back(ClangClPch);
3562 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3563 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3571 const llvm::opt::DerivedArgList &Args,
3574 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
3576 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
3579 bool HasAMDGCNHIPDevice =
false;
3581 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
3583 const llvm::Triple &Tr = TC->
getTriple();
3586 HasAMDGCNHIPDevice =
true;
3588 return HasAMDGCNHIPDevice;
3593 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
3595 if (!SuppressMissingInputWarning && Inputs.empty()) {
3596 Diag(clang::diag::err_drv_no_input_files);
3600 handleArguments(
C, Args, Inputs, Actions);
3605 if (Arg *A = Args.getLastArg(options::OPT_no_offload_new_driver))
3606 Diag(clang::diag::warn_drv_deprecated_custom)
3607 << A->getAsString(Args)
3608 <<
"the legacy offloading driver has been removed";
3609 Args.ClaimAllArgs(options::OPT_no_offload_new_driver);
3610 Args.ClaimAllArgs(options::OPT_offload_new_driver);
3612 bool HIPRDCDeviceOnlyFatBin =
3614 Args.hasArg(options::OPT_hip_link) &&
3615 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
3617 !Args.hasArg(options::OPT_emit_llvm) &&
3618 Args.hasFlag(options::OPT_gpu_bundle_output,
3619 options::OPT_no_gpu_bundle_output,
true);
3626 for (
auto &I : Inputs) {
3628 const Arg *InputArg = I.second;
3640 if (HIPRDCDeviceOnlyFatBin && InputType == types::TY_LLVM_BC) {
3641 LinkerInputs.push_back(Current);
3647 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
3659 assert(Phase == PL.back() &&
"linking must be final compilation step.");
3662 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
3663 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
3665 LinkerInputs.push_back(Current);
3675 assert(Phase == PL.back() &&
"merging must be final compilation step.");
3676 MergerInputs.push_back(Current);
3693 C.getDefaultToolChain().getLTOMode(Args));
3696 if (NewCurrent == Current)
3699 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
3702 Current = NewCurrent;
3707 &HIPAsmDeviceActions);
3709 if (Current->
getType() == types::TY_Nothing)
3715 if (Current && !HIPAsmDeviceActions.empty()) {
3717 BundleInputs.append(HIPAsmDeviceActions);
3718 BundleInputs.push_back(Current);
3724 Actions.push_back(Current);
3731 if (!LinkerInputs.empty()) {
3737 Args.hasArg(options::OPT_offload_link)) {
3740 HIPRDCDeviceOnlyFatBin ? types::TY_HIP_FATBIN : types::TY_Image);
3747 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
3748 C.getDefaultToolChain().getTriple().isSPIRV();
3749 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
3753 Actions.push_back(LA);
3757 if (!MergerInputs.empty())
3761 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
3768 for (
auto &I : Inputs) {
3770 const Arg *InputArg = I.second;
3775 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
3776 InputType == types::TY_Asm)
3781 for (
auto Phase : PhaseList) {
3785 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
3790 if (InputType == types::TY_Object)
3797 assert(Phase == PhaseList.back() &&
3798 "merging must be final compilation step.");
3799 MergerInputs.push_back(Current);
3808 Actions.push_back(Current);
3812 if (!MergerInputs.empty())
3817 for (
auto Opt : {options::OPT_print_supported_cpus,
3818 options::OPT_print_supported_extensions,
3819 options::OPT_print_enabled_extensions}) {
3826 if (Arg *A = Args.getLastArg(Opt)) {
3827 if (Opt == options::OPT_print_supported_extensions &&
3828 !
C.getDefaultToolChain().getTriple().isRISCV() &&
3829 !
C.getDefaultToolChain().getTriple().isAArch64() &&
3830 !
C.getDefaultToolChain().getTriple().isARM()) {
3831 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
3832 <<
"--print-supported-extensions";
3835 if (Opt == options::OPT_print_enabled_extensions &&
3836 !
C.getDefaultToolChain().getTriple().isRISCV() &&
3837 !
C.getDefaultToolChain().getTriple().isAArch64()) {
3838 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
3839 <<
"--print-enabled-extensions";
3846 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
3849 for (
auto &I : Inputs)
3854 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
3855 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
3856 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
3862 if (TC.requiresObjcopy(Args)) {
3863 Action *LastAction = Actions.back();
3865 if (LastAction->
getType() == types::TY_Object) {
3873 auto ValInfo = TC.getValidationInfo(Args);
3874 if (ValInfo.NeedsValidation) {
3875 Action *LastAction = Actions.back();
3876 if (LastAction->
getType() == types::TY_Object) {
3878 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
3885 if (TC.requiresBinaryTranslation(Args)) {
3886 Action *LastAction = Actions.back();
3890 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
3891 LastAction->
getType() == types::TY_Object)
3893 LastAction, types::TY_DX_CONTAINER));
3898 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
3904 const llvm::opt::DerivedArgList &Args,
3906 const llvm::Triple &Triple) {
3911 if (Triple.isNVPTX() && (
Arch.isUnknown() || !
Arch.isNVPTX())) {
3912 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3913 <<
"CUDA" << ArchStr;
3915 }
else if (Triple.isAMDGPU()) {
3916 if (
Arch.isUnknown() || (!
Arch.isAMDGPU() && !
Arch.isAMDGCNSPIRV())) {
3917 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3918 <<
"HIP" << ArchStr;
3922 if (Triple.getSubArch() != llvm::Triple::NoSubArch) {
3924 if (ArchSubArch != Triple.getSubArch() &&
3925 llvm::AMDGPU::getMajorSubArch(ArchSubArch) != Triple.getSubArch()) {
3926 C.getDriver().Diag(clang::diag::err_target_unsupported_arch)
3927 << ArchStr << Triple.getArchName();
3936 if (
Arch.isAMDGPU() ||
Arch.isAMDGCNSPIRV()) {
3937 llvm::StringMap<bool> Features;
3940 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
3952static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3954 llvm::Triple Triple) {
3955 if (!Triple.isAMDGPU())
3956 return std::nullopt;
3958 std::set<StringRef> ArchSet;
3959 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
3963llvm::SmallVector<BoundArch>
3967 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3968 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3969 options::OPT_no_offload_arch_EQ)) {
3970 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3972 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
3974 :
"--no-offload-arch");
3977 llvm::DenseSet<StringRef> Archs;
3978 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
3981 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
3982 for (StringRef
Arch : Arg->getValues()) {
3983 if (
Arch ==
"native" ||
Arch.empty()) {
3988 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3992 for (
auto ArchStr : *GPUsOrErr) {
3994 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
3995 if (!CanonicalStr.empty())
3996 Archs.insert(CanonicalStr);
4001 StringRef CanonicalStr =
4003 if (!CanonicalStr.empty())
4004 Archs.insert(CanonicalStr);
4009 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4010 for (StringRef
Arch : Arg->getValues()) {
4011 if (
Arch ==
"all") {
4016 Archs.erase(ArchStr);
4022 if (
auto ConflictingArchs =
4024 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4025 << ConflictingArchs->first << ConflictingArchs->second;
4028 bool HasSubArch = TC.
getTriple().isAMDGCN() &&
4029 TC.
getTriple().getSubArch() != llvm::Triple::NoSubArch;
4030 if (Archs.empty() && !HasSubArch) {
4040 Archs.insert(StringRef());
4043 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
4044 .getLastArg(options::OPT_march_EQ)) {
4045 Archs.insert(Arg->getValue());
4050 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4051 <<
"--offload-arch";
4052 }
else if (!ArchsOrErr->empty()) {
4053 for (
auto Arch : *ArchsOrErr)
4054 Archs.insert(Args.MakeArgStringRef(
Arch));
4056 Archs.insert(StringRef());
4060 }
else if (Archs.empty() && HasSubArch) {
4067 llvm::StringRef ArchStr = TripleOffloadArch.
isUnknown()
4070 StringRef CanonicalStr =
4072 if (!CanonicalStr.empty())
4073 Archs.insert(CanonicalStr);
4076 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4077 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4084 Result.reserve(Sorted.size());
4085 for (StringRef
Arch : Sorted)
4092 const InputTy &Input, StringRef CUID,
4102 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4107 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4110 bool HIPRelocatableObj =
4112 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4113 options::OPT_fno_hip_emit_relocatable,
false);
4115 if (!HIPNoRDC && HIPRelocatableObj)
4116 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4117 <<
"-fhip-emit-relocatable"
4121 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4122 <<
"-fhip-emit-relocatable"
4123 <<
"--offload-device-only";
4131 bool UsesLLVMOffloading = Args.hasArg(
4132 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
4144 auto TCRange =
C.getOffloadToolChains(Kind);
4145 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4146 ToolChains.push_back(TI->second);
4148 if (ToolChains.empty())
4152 const Arg *InputArg = Input.second;
4161 for (
const ToolChain *TC : ToolChains) {
4163 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4164 DeviceActions.push_back(
4165 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4169 if (DeviceActions.empty())
4175 HostAction->
getType() != types::TY_Nothing &&
4185 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4194 auto *TCAndArch = TCAndArchs.begin();
4195 for (
Action *&A : DeviceActions) {
4196 if (A->
getType() == types::TY_Nothing)
4203 TCAndArch->first->getLTOMode(Args, Kind));
4207 HostAction->
getType() != types::TY_Nothing) {
4214 TCAndArch->second, Kind);
4216 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4226 for (
Action *&A : DeviceActions) {
4231 OffloadTriple && OffloadTriple->isSPIRV() &&
4232 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
4233 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
4235 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
4236 A->
getType() != types::TY_LTO_BC) ||
4243 auto *TCAndArch = TCAndArchs.begin();
4244 for (
Action *A : DeviceActions) {
4245 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4247 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4254 A->
getType() == types::TY_Object &&
4255 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4257 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
4266 bool ShouldBundleHIP =
4267 Args.hasFlag(options::OPT_gpu_bundle_output,
4268 options::OPT_no_gpu_bundle_output,
false) ||
4269 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
4271 return A->
getType() != types::TY_Image;
4282 if (OffloadActions.empty())
4287 (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) ||
4288 Args.hasArg(options::OPT_cuda_emit_nvcc_abi))) {
4292 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4299 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4300 DDep.
add(*FatbinAction,
4303 }
else if ((!UsesLLVMOffloading && HIPNoRDC) || SYCLNoRDC) {
4306 if (HIPNoRDC && HIPAsmBundleDeviceOut &&
4308 for (
Action *OA : OffloadActions)
4309 HIPAsmBundleDeviceOut->push_back(OA);
4322 SYCLNoRDC ? types::TY_SYCL_FATBIN : types::TY_HIP_FATBIN;
4325 DDep.
add(*PackagerAction, *
C.getOffloadToolChains(Kind).first->second,
4333 {},
C.getActiveOffloadKinds());
4342 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4343 return A->
getType() == types::TY_Nothing;
4347 {}, SingleDeviceOutput ? DDep : DDeps);
4348 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4354 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4364 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4370 llvm_unreachable(
"link action invalid here.");
4372 llvm_unreachable(
"ifsmerge action invalid here.");
4377 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4378 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4379 OutputTy = types::TY_Dependencies;
4384 if (!Args.hasFlag(options::OPT_frewrite_includes,
4385 options::OPT_fno_rewrite_includes,
false) &&
4386 !Args.hasFlag(options::OPT_frewrite_imports,
4387 options::OPT_fno_rewrite_imports,
false) &&
4388 !Args.hasFlag(options::OPT_fdirectives_only,
4389 options::OPT_fno_directives_only,
false) &&
4393 "Cannot preprocess this input type!");
4399 if (Args.hasArg(options::OPT_extract_api))
4404 if (Input->
getType() == types::TY_CXXStdModule ||
4405 Input->
getType() == types::TY_PP_CXXStdModule)
4407 Input, getPrecompiledType(Input->
getType()));
4415 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
4416 (Input->
getType() == driver::types::TY_CXXModule ||
4417 Input->
getType() == driver::types::TY_PP_CXXModule) &&
4418 !Args.getLastArg(options::OPT__precompile) &&
4419 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
4424 "Cannot precompile this input type!");
4428 const char *ModName =
nullptr;
4429 if (OutputTy == types::TY_PCH) {
4430 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4431 ModName = A->getValue();
4433 OutputTy = types::TY_ModuleFile;
4436 if (Args.hasArg(options::OPT_fsyntax_only)) {
4438 OutputTy = types::TY_Nothing;
4444 if (Args.hasArg(options::OPT_fsyntax_only))
4446 if (Args.hasArg(options::OPT_rewrite_objc))
4448 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4450 types::TY_RewrittenLegacyObjC);
4451 if (Args.hasArg(options::OPT__analyze))
4453 if (Args.hasArg(options::OPT_emit_ast))
4455 if (Args.hasArg(options::OPT_emit_cir)) {
4458 if (Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S))
4462 if (Args.hasArg(options::OPT_module_file_info))
4464 if (Args.hasArg(options::OPT_verify_pch))
4466 if (Args.hasArg(options::OPT_extract_api))
4473 if (!IsDeviceOffload) {
4475 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4476 !Args.hasArg(options::OPT_emit_llvm))
4477 Output = types::TY_PP_Asm;
4478 else if (Args.hasArg(options::OPT_S))
4479 Output = types::TY_LTO_IR;
4481 Output = types::TY_LTO_BC;
4485 if (Args.hasArg(options::OPT_emit_llvm)) {
4487 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4489 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4493 Output = types::TY_PP_Asm;
4494 }
else if (Args.hasArg(options::OPT_S)) {
4495 Output = types::TY_LTO_IR;
4497 Output = types::TY_LTO_BC;
4503 if (Args.hasArg(options::OPT_emit_llvm) ||
4507 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4516 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
4517 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
4528 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4550 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
4570 if (!OffloadJobs.isValid())
4571 D.
Diag(diag::err_drv_invalid_int_value)
4572 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
4574 OffloadJobs.A->claim();
4578 for (
auto &Job :
C.getJobs()) {
4582 Job.setOffloadDeviceParallelJobGroup(
4588 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4590 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4610 unsigned NumOutputs = 0;
4611 unsigned NumIfsOutputs = 0;
4612 for (
const Action *A :
C.getActions()) {
4622 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
4623 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
4626 if (A->
getType() != types::TY_Nothing &&
4628 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4630 0 == NumIfsOutputs++) ||
4635 A->
getType() == types::TY_Nothing &&
4636 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4637 NumOutputs += A->
size();
4640 if (NumOutputs > 1) {
4641 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4642 FinalOutput =
nullptr;
4646 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4649 llvm::StringSet<> ArchNames;
4650 if (RawTriple.isOSBinFormatMachO())
4651 for (
const Arg *A :
C.getArgs())
4652 if (A->getOption().matches(options::OPT_arch))
4653 ArchNames.insert(A->getValue());
4656 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4657 for (
Action *A :
C.getActions()) {
4664 const char *LinkingOutput =
nullptr;
4667 LinkingOutput = FinalOutput->getValue();
4675 ArchNames.size() > 1 ||
4676 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
4677 LinkingOutput, CachedResults,
4684 for (
auto &J :
C.getJobs())
4685 J.InProcess =
false;
4692 C.setPostCallback([=](
const Command &Cmd,
int Res) {
4693 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4698 const char *LinkingOutput =
nullptr;
4700 LinkingOutput = FinalOutput->getValue();
4707 using namespace llvm;
4710 <<
"output=" << LinkingOutput;
4711 outs() <<
", total="
4712 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4714 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4715 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4719 llvm::raw_string_ostream Out(Buffer);
4720 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
4723 llvm::sys::printArg(Out, LinkingOutput,
true);
4724 Out <<
',' << ProcStat->TotalTime.count() <<
','
4725 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4730 llvm::sys::fs::OF_Append |
4731 llvm::sys::fs::OF_Text);
4736 llvm::errs() <<
"ERROR: Cannot lock file "
4738 <<
toString(L.takeError()) <<
"\n";
4749 bool ReportUnusedArguments =
4750 !Diags.hasErrorOccurred() &&
4751 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
4754 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
4756 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
4759 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
4760 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
4762 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
4766 return strstr(J.getCreator().getShortName(),
"assembler");
4768 for (Arg *A :
C.getArgs()) {
4772 if (!A->isClaimed()) {
4778 const Option &Opt = A->getOption();
4779 if (Opt.getKind() == Option::FlagClass) {
4780 bool DuplicateClaimed =
false;
4782 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
4783 if (AA->isClaimed()) {
4784 DuplicateClaimed =
true;
4789 if (DuplicateClaimed)
4795 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
4797 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
4802 !
C.getActions().empty()) {
4803 Diag(diag::err_drv_unsupported_opt_for_target)
4805 }
else if (ReportUnusedArguments) {
4806 Diag(clang::diag::warn_drv_unused_argument)
4807 << A->getAsString(
C.getArgs());
4817class ToolSelector final {
4828 bool IsHostSelector;
4839 bool CanBeCollapsed =
true) {
4841 if (Inputs.size() != 1)
4844 Action *CurAction = *Inputs.begin();
4845 if (CanBeCollapsed &&
4851 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
4855 if (!IsHostSelector) {
4856 if (OA->hasSingleDeviceDependence(
true)) {
4858 OA->getSingleDeviceDependence(
true);
4859 if (CanBeCollapsed &&
4862 SavedOffloadAction.push_back(OA);
4863 return dyn_cast<JobAction>(CurAction);
4865 }
else if (OA->hasHostDependence()) {
4866 CurAction = OA->getHostDependence();
4867 if (CanBeCollapsed &&
4870 SavedOffloadAction.push_back(OA);
4871 return dyn_cast<JobAction>(CurAction);
4876 return dyn_cast<JobAction>(CurAction);
4880 bool canCollapseAssembleAction()
const {
4881 return TC.useIntegratedAs() && !SaveTemps &&
4882 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
4883 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
4884 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
4885 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
4889 bool canCollapsePreprocessorAction()
const {
4890 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
4891 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
4892 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
4897 struct JobActionInfo final {
4899 const JobAction *JA =
nullptr;
4907 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
4908 ArrayRef<JobActionInfo> &ActionInfo,
4909 unsigned ElementNum) {
4910 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
4911 for (
unsigned I = 0; I < ElementNum; ++I)
4912 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
4913 ActionInfo[I].SavedOffloadAction.end());
4926 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
4929 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
4931 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4932 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4933 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
4934 if (!AJ || !BJ || !CJ)
4938 const Tool *
T = TC.SelectTool(*CJ);
4945 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
4951 const Tool *BT = TC.SelectTool(*BJ);
4956 if (!
T->hasIntegratedAssembler())
4959 Inputs = CJ->getInputs();
4960 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4964 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
4967 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
4969 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4970 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4975 const Tool *
T = TC.SelectTool(*BJ);
4979 if (!
T->hasIntegratedAssembler())
4982 Inputs = BJ->getInputs();
4983 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4987 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
4990 if (ActionInfo.size() < 2)
4992 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
4993 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
4997 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
4998 for (
auto &Input : AI.JA->getInputs())
5009 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5010 if (SaveTemps && !InputIsBitcode)
5014 const Tool *
T = TC.SelectTool(*CJ);
5021 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5027 Inputs = CJ->getInputs();
5028 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5037 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5039 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5045 for (Action *A : Inputs) {
5046 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5048 NewInputs.push_back(A);
5054 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5055 PreprocessJobOffloadActions.end());
5056 NewInputs.append(PJ->input_begin(), PJ->input_end());
5062 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5064 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5066 assert(BaseAction &&
"Invalid base action.");
5082 SmallVector<JobActionInfo, 5> ActionChain(1);
5083 ActionChain.back().JA = BaseAction;
5084 while (ActionChain.back().JA) {
5085 const Action *CurAction = ActionChain.back().JA;
5088 ActionChain.resize(ActionChain.size() + 1);
5089 JobActionInfo &AI = ActionChain.back();
5093 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5097 ActionChain.pop_back();
5105 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5106 CollapsedOffloadAction);
5108 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5110 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5116 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5129 std::string TriplePlusArch = TC->
getTriple().normalize();
5131 TriplePlusArch +=
"-";
5134 TriplePlusArch +=
"-";
5136 return TriplePlusArch;
5141 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5142 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5145 std::pair<const Action *, std::string> ActionTC = {
5147 auto CachedResult = CachedResults.find(ActionTC);
5148 if (CachedResult != CachedResults.end()) {
5149 return CachedResult->second;
5152 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
5153 TargetDeviceOffloadKind);
5154 CachedResults[ActionTC] =
Result;
5159 const JobAction *JA,
const char *BaseInput,
5162 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5173 if (!
Arch.empty()) {
5174 OffloadingPrefix +=
"-";
5175 OffloadingPrefix +=
Arch.ArchName;
5178 C.getDriver().isSaveTempsEnabled()) {
5185 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5186 Path = A->getValue();
5187 if (llvm::sys::fs::is_directory(Path)) {
5189 ? llvm::sys::path::stem(
Result.getFilename())
5190 : llvm::sys::path::stem(BaseInput));
5191 Tmp += OffloadingPrefix;
5193 llvm::sys::path::append(Path, Tmp);
5196 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5199 Path = DumpDir->getValue();
5200 Path += llvm::sys::path::stem(BaseInput);
5201 Path += OffloadingPrefix;
5203 }
else if (!OffloadingPrefix.empty()) {
5207 TraceName += OffloadingPrefix;
5208 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
5209 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
5210 llvm::sys::path::append(Path, TraceName);
5213 Path =
Result.getFilename();
5214 llvm::sys::path::replace_extension(Path,
"json");
5217 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5218 C.addTimeTraceFile(ResultFile, JA);
5219 C.addResultFile(ResultFile, JA);
5224 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5225 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5228 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5232 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
5233 C.setCurrentBoundArch(BA);
5234 auto RestoreBoundArch =
5235 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
5238 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5239 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5271 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5273 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5274 BoundArch DepBoundArch) {
5276 !DepBoundArch.
empty(),
5277 LinkingOutput, CachedResults,
5287 OA->doOnEachDependence(
5288 BuildingForOffloadDevice,
5289 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5291 C, DepA, DepTC, DepBoundArch,
false,
5292 !DepBoundArch.
empty(), LinkingOutput,
5296 A = BuildingForOffloadDevice
5297 ? OA->getSingleDeviceDependence(
true)
5298 : OA->getHostDependence();
5302 std::pair<const Action *, std::string> ActionTC = {
5303 OA->getHostDependence(),
5305 auto It = CachedResults.find(ActionTC);
5306 if (It != CachedResults.end()) {
5308 Inputs.append(OffloadDependencesInputInfo);
5313 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5316 const Arg &Input = IA->getInputArg();
5318 if (Input.getOption().matches(options::OPT_INPUT)) {
5319 const char *
Name = Input.getValue();
5322 return {InputInfo(A, &Input,
"")};
5325 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5326 const ToolChain *TC;
5327 BoundArch ArchName = BAA->
getArch();
5329 if (!ArchName.
empty())
5330 TC = &getToolChain(
C.getArgs(),
5334 TC = &
C.getDefaultToolChain();
5337 MultipleArchs, LinkingOutput, CachedResults,
5338 TargetDeviceOffloadKind);
5351 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5354 return {InputInfo()};
5358 for (
const auto *OA : CollapsedOffloadActions)
5360 BuildingForOffloadDevice,
5361 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5363 C, DepA, DepTC, DepBoundArch,
false,
5364 !DepBoundArch.
empty(), LinkingOutput,
5370 for (
const Action *Input : Inputs) {
5374 bool SubJobAtTopLevel =
5377 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5382 const char *BaseInput = InputInfos[0].getBaseInput();
5383 for (
auto &Info : InputInfos) {
5384 if (Info.isFilename()) {
5385 BaseInput = Info.getBaseInput();
5392 if (JA->
getType() == types::TY_dSYM)
5393 BaseInput = InputInfos[0].getFilename();
5396 if (!OffloadDependencesInputInfo.empty())
5397 InputInfos.append(OffloadDependencesInputInfo.begin(),
5398 OffloadDependencesInputInfo.end());
5401 llvm::Triple EffectiveTriple;
5402 const ToolChain &ToolTC =
T->getToolChain();
5403 const ArgList &Args =
5405 if (InputInfos.size() != 1) {
5410 EffectiveTriple = llvm::Triple(
5413 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
5417 if (JA->
getType() == types::TY_Nothing)
5418 Result = {InputInfo(A, BaseInput)};
5429 MultipleArchs, OffloadingPrefix),
5436 llvm::errs() <<
"# \"" <<
T->getToolChain().getEffectiveTriple().str()
5437 <<
'"' <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5438 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5439 llvm::errs() << InputInfos[i].getAsString();
5441 llvm::errs() <<
", ";
5443 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5445 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5451 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5452 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5464 if (ArgValue.empty()) {
5466 Filename = BaseName;
5467 }
else if (llvm::sys::path::is_separator(Filename.back())) {
5469 llvm::sys::path::append(Filename, BaseName);
5472 if (!llvm::sys::path::has_extension(ArgValue)) {
5477 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5482 llvm::sys::path::replace_extension(Filename, Extension);
5485 return Args.MakeArgString(Filename.c_str());
5500 StringRef Suffix,
bool MultipleArchs,
5501 StringRef BoundArchStr,
5502 bool NeedUniqueDirectory)
const {
5504 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5505 std::optional<std::string> CrashDirectory =
5507 ? std::string(A->getValue())
5508 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5509 if (CrashDirectory) {
5510 if (!
getVFS().exists(*CrashDirectory))
5511 llvm::sys::fs::create_directories(*CrashDirectory);
5513 llvm::sys::path::append(Path, Prefix);
5514 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5515 if (std::error_code EC =
5516 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
5517 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5521 if (MultipleArchs && !BoundArchStr.empty()) {
5522 if (NeedUniqueDirectory) {
5524 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
5535 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5550 const char *BaseInput) {
5552 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5553 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5558 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5563 bool AtTopLevel,
bool MultipleArchs,
5564 StringRef OffloadingPrefix)
const {
5567 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5569 auto CreateTempOutputPath = [&](StringRef Prefix) {
5570 const char *Suffix =
5575 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
5576 const bool NeedUniqueDirectory =
5579 Triple.isOSDarwin();
5581 NeedUniqueDirectory);
5586 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
5587 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
5588 StringRef Filename = llvm::sys::path::filename(BaseInput);
5589 StringRef Stem = llvm::sys::path::stem(Filename);
5590 return CreateTempOutputPath(Stem);
5595 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5596 return C.addResultFile(FinalOutput->getValue(), &JA);
5600 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5602 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5604 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5605 NameArg = A->getValue();
5606 return C.addResultFile(
5616 if (JA.
getType() == types::TY_ModuleFile &&
5617 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5621 if (JA.
getType() == types::TY_PP_Asm &&
5622 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5623 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5626 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
5629 if ((JA.
getType() == types::TY_Object &&
5630 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
5631 JA.
getType() == types::TY_DX_CONTAINER) {
5632 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5633 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
5634 C.getDefaultToolChain().getTriple().isSPIRV()) &&
5635 "expected DXIL or SPIR-V triple for HLSL output path");
5640 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
5642 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
5643 StringRef
Name = llvm::sys::path::filename(BaseInput);
5644 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5650 if (JA.
getType() == types::TY_PP_Asm &&
5651 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5652 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5654 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5655 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5656 return C.addResultFile(
5661 if (JA.
getType() == types::TY_API_INFO &&
5662 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5663 C.getArgs().hasArg(options::OPT_o))
5664 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5665 <<
C.getArgs().getLastArgValue(options::OPT_o);
5672 bool SpecifiedModuleOutput =
5673 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5674 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5675 if (MultipleArchs && SpecifiedModuleOutput)
5676 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5681 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5682 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
5688 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5690 StringRef
Name = llvm::sys::path::filename(BaseInput);
5691 return CreateTempOutputPath(
Name.split(
'.').first);
5700 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
5705 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
5706 llvm::sys::path::filename(BasePath));
5707 BaseName = ExternalPath;
5709 BaseName = BasePath;
5711 BaseName = llvm::sys::path::filename(BasePath);
5714 const char *NamedOutput;
5716 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
5717 JA.
getType() == types::TY_LLVM_BC ||
5718 JA.
getType() == types::TY_LLVM_IR) &&
5719 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
5723 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
5727 }
else if (JA.
getType() == types::TY_Image &&
5728 C.getArgs().hasArg(options::OPT__SLASH_Fe,
5729 options::OPT__SLASH_o)) {
5733 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
5737 }
else if (JA.
getType() == types::TY_Image) {
5747 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
5748 options::OPT_fno_gpu_rdc,
false);
5750 if (UseOutExtension) {
5752 llvm::sys::path::replace_extension(Output,
"");
5754 Output += OffloadingPrefix;
5755 if (MultipleArchs && !BoundArchStr.empty()) {
5757 Output.append(BoundArchStr);
5759 if (UseOutExtension)
5761 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
5764 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
5765 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
5766 C.getArgs().hasArg(options::OPT__SLASH_o)) {
5769 .getLastArg(options::OPT__SLASH_o)
5774 const char *Suffix =
5776 assert(Suffix &&
"All types used for output should have a suffix.");
5778 std::string::size_type End = std::string::npos;
5780 End = BaseName.rfind(
'.');
5782 Suffixed += OffloadingPrefix;
5783 if (MultipleArchs && !BoundArchStr.empty()) {
5785 Suffixed.append(BoundArchStr);
5790 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
5791 const llvm::opt::DerivedArgList &Args) {
5804 bool IsLinkerWrapper =
5806 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
5807 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
5808 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
5810 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
5814 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
5818 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
5819 JA.
getType() != types::TY_PCH) {
5820 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5822 llvm::sys::path::remove_filename(TempPath);
5823 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
5824 llvm::sys::path::append(TempPath, OutputFileName);
5825 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
5831 bool SameFile =
false;
5833 llvm::sys::fs::current_path(
Result);
5834 llvm::sys::path::append(
Result, BaseName);
5835 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
5838 StringRef
Name = llvm::sys::path::filename(BaseInput);
5839 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5843 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5849 llvm::sys::path::remove_filename(BasePath);
5850 if (BasePath.empty())
5851 BasePath = NamedOutput;
5853 llvm::sys::path::append(BasePath, NamedOutput);
5854 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
5857 return C.addResultFile(NamedOutput, &JA);
5863 -> std::optional<std::string> {
5866 for (
const auto &
Dir : P) {
5870 llvm::sys::path::append(P,
Name);
5871 if (llvm::sys::fs::exists(Twine(P)))
5872 return std::string(P);
5874 return std::nullopt;
5881 llvm::sys::path::append(R,
Name);
5882 if (llvm::sys::fs::exists(Twine(R)))
5883 return std::string(R);
5886 llvm::sys::path::append(P,
Name);
5887 if (llvm::sys::fs::exists(Twine(P)))
5888 return std::string(P);
5892 if (std::optional<std::string> IntrPath =
5895 llvm::sys::path::append(P,
Name);
5896 if (llvm::sys::fs::exists(P))
5897 return std::string(P);
5902 llvm::sys::path::append(D,
"..",
Name);
5903 if (llvm::sys::fs::exists(Twine(D)))
5904 return std::string(D);
5913 llvm::sys::path::append(R2,
"..",
"..",
Name);
5914 if (llvm::sys::fs::exists(Twine(R2)))
5915 return std::string(R2);
5917 return std::string(
Name);
5920void Driver::generatePrefixedToolNames(
5924 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
5925 Names.emplace_back(
Tool);
5929 llvm::sys::path::append(Dir, Name);
5930 if (llvm::sys::fs::can_execute(Twine(Dir)))
5932 llvm::sys::path::remove_filename(Dir);
5938 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
5943 if (llvm::sys::fs::is_directory(PrefixDir)) {
5946 return std::string(P);
5949 if (llvm::sys::fs::can_execute(Twine(P)))
5950 return std::string(P);
5955 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
5963 for (
const auto &Path : List) {
5966 return std::string(P);
5970 if (llvm::ErrorOr<std::string> P =
5971 llvm::sys::findProgramByName(TargetSpecificExecutable))
5975 return std::string(
Name);
5980 std::string error =
"<NOT PRESENT>";
5982 if (
C.getArgs().hasArg(options::OPT_nostdlib))
5987 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6004 llvm::sys::path::remove_filename(path);
6005 llvm::sys::path::append(path,
"libc++.modules.json");
6006 if (TC.
getVFS().exists(path))
6007 return static_cast<std::string
>(path);
6012 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6015 return evaluate(
"libc++.a").value_or(error);
6019 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6023 llvm::sys::path::remove_filename(path);
6024 llvm::sys::path::append(path,
"libstdc++.modules.json");
6025 if (TC.
getVFS().exists(path))
6026 return static_cast<std::string
>(path);
6031 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6034 return evaluate(
"libstdc++.a").value_or(error);
6043 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6045 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6049 return std::string(Path);
6054 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6056 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6060 return std::string(Path);
6065 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6069 Output = FpArg->getValue();
6073 if (!llvm::sys::path::has_extension(Output))
6076 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6077 Output = YcArg->getValue();
6080 llvm::sys::path::replace_extension(Output,
".pch");
6082 return std::string(Output);
6085const ToolChain &Driver::getOffloadToolChain(
6087 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6088 std::unique_ptr<ToolChain> &TC =
6089 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6090 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6092 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6095 switch (
Target.getOS()) {
6096 case llvm::Triple::CUDA:
6097 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6100 case llvm::Triple::AMDHSA:
6106 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6107 HostTC.get(), Kind);
6115 switch (
Target.getArch()) {
6116 case llvm::Triple::amdgpu:
6117 case llvm::Triple::r600:
6118 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6119 HostTC.get(), Kind);
6121 case llvm::Triple::spir:
6122 case llvm::Triple::spir64:
6123 case llvm::Triple::spirv:
6124 case llvm::Triple::spirv32:
6125 case llvm::Triple::spirv64:
6128 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6132 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6136 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6140 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6154 return getToolChain(Args,
Target);
6158const ToolChain &Driver::getToolChain(
const ArgList &Args,
6159 const llvm::Triple &
Target)
const {
6161 auto &TC = ToolChains[
Target.str()];
6163 switch (
Target.getOS()) {
6164 case llvm::Triple::AIX:
6165 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6167 case llvm::Triple::Haiku:
6168 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6170 case llvm::Triple::Darwin:
6171 case llvm::Triple::MacOSX:
6172 case llvm::Triple::IOS:
6173 case llvm::Triple::TvOS:
6174 case llvm::Triple::WatchOS:
6175 case llvm::Triple::XROS:
6176 case llvm::Triple::DriverKit:
6177 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6179 case llvm::Triple::DragonFly:
6180 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6182 case llvm::Triple::OpenBSD:
6183 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6185 case llvm::Triple::NetBSD:
6186 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6188 case llvm::Triple::FreeBSD:
6190 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6193 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6195 case llvm::Triple::Linux:
6196 case llvm::Triple::ELFIAMCU:
6197 if (
Target.getArch() == llvm::Triple::hexagon)
6198 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6200 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6201 !
Target.hasEnvironment())
6202 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6205 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6207 else if (
Target.getArch() == llvm::Triple::ve)
6208 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6209 else if (
Target.isOHOSFamily())
6210 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6211 else if (
Target.isWALI())
6212 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6214 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6216 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6218 case llvm::Triple::Fuchsia:
6219 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6221 case llvm::Triple::Managarm:
6222 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6224 case llvm::Triple::Serenity:
6225 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
6227 case llvm::Triple::Solaris:
6228 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6230 case llvm::Triple::CUDA:
6231 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6233 case llvm::Triple::AMDHSA: {
6234 if (
Target.getArch() == llvm::Triple::spirv64) {
6235 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6241 TC = std::make_unique<toolchains::AMDGPUToolChain>(
6243 ShouldLinkDeviceLibs);
6247 case llvm::Triple::AMDPAL:
6248 case llvm::Triple::Mesa3D:
6249 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6251 case llvm::Triple::UEFI:
6252 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6254 case llvm::Triple::Win32:
6255 switch (
Target.getEnvironment()) {
6257 if (
Target.isOSBinFormatELF())
6258 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6259 else if (
Target.isOSBinFormatMachO())
6260 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6262 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6264 case llvm::Triple::GNU:
6265 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6267 case llvm::Triple::Cygnus:
6268 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6270 case llvm::Triple::Itanium:
6271 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6274 case llvm::Triple::MSVC:
6275 case llvm::Triple::UnknownEnvironment:
6276 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6277 .starts_with_insensitive(
"bfd"))
6278 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6282 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6286 case llvm::Triple::PS4:
6287 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6289 case llvm::Triple::PS5:
6290 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6292 case llvm::Triple::Hurd:
6293 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6295 case llvm::Triple::LiteOS:
6296 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6298 case llvm::Triple::ZOS:
6299 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6301 case llvm::Triple::Vulkan:
6302 case llvm::Triple::ShaderModel:
6303 if ((
Target.getArch() == llvm::Triple::spirv32 ||
6304 Target.getArch() == llvm::Triple::spirv64) &&
6306 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6308 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6310 case llvm::Triple::ChipStar:
6311 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
6316 switch (
Target.getArch()) {
6317 case llvm::Triple::tce:
6318 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6320 case llvm::Triple::tcele:
6321 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6323 case llvm::Triple::tcele64:
6325 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
6327 case llvm::Triple::hexagon:
6328 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6331 case llvm::Triple::lanai:
6332 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6334 case llvm::Triple::xcore:
6335 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6337 case llvm::Triple::wasm32:
6338 case llvm::Triple::wasm64:
6339 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6341 case llvm::Triple::avr:
6342 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6344 case llvm::Triple::msp430:
6345 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6347 case llvm::Triple::riscv32:
6348 case llvm::Triple::riscv64:
6349 case llvm::Triple::riscv32be:
6350 case llvm::Triple::riscv64be:
6351 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6353 case llvm::Triple::ve:
6354 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6356 case llvm::Triple::spirv32:
6357 case llvm::Triple::spirv64:
6358 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6360 case llvm::Triple::csky:
6361 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6363 case llvm::Triple::amdgpu:
6364 case llvm::Triple::r600:
6365 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6369 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6370 else if (
Target.isOSBinFormatELF())
6371 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6372 else if (
Target.isAppleFirmware())
6373 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6374 else if (
Target.isAppleMachO())
6375 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6376 else if (
Target.isOSBinFormatMachO())
6377 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6379 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6389 if (JA.
size() != 1 ||
6404 if (JA.
size() != 1 ||
6418 if (Args.hasArg(options::OPT_emit_static_lib))
6429 unsigned &Micro,
bool &HadExtra) {
6432 Major = Minor = Micro = 0;
6436 if (Str.consumeInteger(10, Major))
6440 if (!Str.consume_front(
"."))
6443 if (Str.consumeInteger(10, Minor))
6447 if (!Str.consume_front(
"."))
6450 if (Str.consumeInteger(10, Micro))
6468 unsigned CurDigit = 0;
6469 while (CurDigit < Digits.size()) {
6471 if (Str.consumeInteger(10, Digit))
6473 Digits[CurDigit] = Digit;
6476 if (!Str.consume_front(
"."))
6485llvm::opt::Visibility
6486Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6498const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6514 llvm_unreachable(
"Unhandled Mode");
6518 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6523 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6524 options::OPT_fno_save_optimization_record,
false))
6528 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6529 options::OPT_fno_save_optimization_record,
false))
6533 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6534 options::OPT_fno_save_optimization_record,
false))
6538 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6539 options::OPT_fno_save_optimization_record,
false))
6546 static StringRef OptName =
6548 llvm::StringRef Opt;
6549 for (StringRef Arg : Args) {
6550 if (!Arg.starts_with(OptName))
6556 return Opt.consume_front(OptName) ? Opt :
"";
6563 llvm::BumpPtrAllocator &Alloc,
6564 llvm::vfs::FileSystem *FS) {
6573 for (
const char *F : Args) {
6574 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6576 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6577 RSPQuoting = Windows;
6583 bool MarkEOLs = ClangCLMode;
6585 llvm::cl::TokenizerCallback Tokenizer;
6586 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
6587 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6589 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6591 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6594 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6595 ECtx.setMarkEOLs(MarkEOLs);
6599 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6603 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6604 [](
const char *A) {
return A !=
nullptr; });
6605 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6608 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6609 Args.resize(newEnd - Args.begin());
6613 return llvm::Error::success();
6617 return SavedStrings.insert(S).first->getKeyData();
6651 llvm::StringSet<> &SavedStrings) {
6654 if (Edit[0] ==
'^') {
6655 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6656 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6657 Args.insert(Args.begin() + 1, Str);
6658 }
else if (Edit[0] ==
'+') {
6659 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6660 OS <<
"### Adding argument " << Str <<
" at end\n";
6661 Args.push_back(Str);
6662 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6663 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6664 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6665 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6666 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6668 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6670 if (Args[i] ==
nullptr)
6672 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6674 if (Repl != Args[i]) {
6675 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6679 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6680 auto Option = Edit.substr(1);
6681 for (
unsigned i = 1; i < Args.size();) {
6682 if (Option == Args[i]) {
6683 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6684 Args.erase(Args.begin() + i);
6685 if (Edit[0] ==
'X') {
6686 if (i < Args.size()) {
6687 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6688 Args.erase(Args.begin() + i);
6690 OS <<
"### Invalid X edit, end of command line!\n";
6695 }
else if (Edit[0] ==
'O') {
6696 for (
unsigned i = 1; i < Args.size();) {
6697 const char *A = Args[i];
6701 if (A[0] ==
'-' && A[1] ==
'O' &&
6702 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6703 (
'0' <= A[2] && A[2] <=
'9'))))) {
6704 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6705 Args.erase(Args.begin() + i);
6709 OS <<
"### Adding argument " << Edit <<
" at end\n";
6710 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6712 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6717 const char *OverrideStr,
6718 llvm::StringSet<> &SavedStrings,
6719 StringRef EnvVar, raw_ostream *OS) {
6721 OS = &llvm::nulls();
6723 if (OverrideStr[0] ==
'#') {
6725 OS = &llvm::nulls();
6728 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
6732 const char *S = OverrideStr;
6734 const char *End = ::strchr(S,
' ');
6736 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static std::string getOffloadDeviceCC1ParallelJobGroup(const Command &Job)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static void printCXXStdlibIncludeDirs(const ToolChain &TC, const ArgList &Args)
static bool HasPreprocessOutput(const Action &JA)
std::multiset< llvm::Triple > TripleSet
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static const char BugReportMsg[]
static std::string GetTriplePlusArchString(const ToolChain *TC, BoundArch BA, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static void markOffloadDeviceCC1JobsForParallelExecution(Compilation &C)
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static bool isIncludeDirArg(StringRef Arg)
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef ArchName="")
Compute target triple from args.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static bool shouldBundleHIPAsm(const Compilation &C, const llvm::opt::DerivedArgList &Args, const Driver &D)
HIP non-RDC -S for AMDGCN: emit host and device assembly separately and bundle with clang-offload-bun...
static bool isOffloadDeviceCC1JobCandidate(Command &Job)
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static void claimAndDiagnoseOffloadJobs(const Driver &D, const ArgList &Args)
static TripleSet inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A processor an offloading action can target.
static constexpr OffloadArch getUnused()
static constexpr OffloadArch getGeneric()
static OffloadArch CudaDefault()
Default architectures used when the user does not specify one.
static OffloadArch HIPDefault()
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
BoundArch getOffloadingArch() const
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateDeviceOffloadInfo(OffloadKind OKind, BoundArch OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
void propagateHostOffloadInfo(unsigned OKinds, BoundArch OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
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.
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
llvm::Triple::SubArchType getOffloadArchSubArch(OffloadArch ID)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
OffloadArch getSubArchOffloadArch(llvm::Triple::SubArchType SubArch)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Represents a bound architecture for offload / multiple architecture compilation.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules