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->getOption().
getName() :
"");
3532 Diag(clang::diag::warn_drv_input_file_unused)
3533 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3535 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
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))
4457 if (Args.hasArg(options::OPT_module_file_info))
4459 if (Args.hasArg(options::OPT_verify_pch))
4461 if (Args.hasArg(options::OPT_extract_api))
4468 if (!IsDeviceOffload) {
4470 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4471 !Args.hasArg(options::OPT_emit_llvm))
4472 Output = types::TY_PP_Asm;
4473 else if (Args.hasArg(options::OPT_S))
4474 Output = types::TY_LTO_IR;
4476 Output = types::TY_LTO_BC;
4480 if (Args.hasArg(options::OPT_emit_llvm)) {
4482 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4484 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4488 Output = types::TY_PP_Asm;
4489 }
else if (Args.hasArg(options::OPT_S)) {
4490 Output = types::TY_LTO_IR;
4492 Output = types::TY_LTO_BC;
4496 if (Args.hasArg(options::OPT_emit_llvm) ||
4499 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4508 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
4509 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
4520 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4542 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
4562 if (!OffloadJobs.isValid())
4563 D.
Diag(diag::err_drv_invalid_int_value)
4564 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
4566 OffloadJobs.A->claim();
4570 for (
auto &Job :
C.getJobs()) {
4574 Job.setOffloadDeviceParallelJobGroup(
4580 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4582 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4602 unsigned NumOutputs = 0;
4603 unsigned NumIfsOutputs = 0;
4604 for (
const Action *A :
C.getActions()) {
4614 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
4615 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
4618 if (A->
getType() != types::TY_Nothing &&
4620 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4622 0 == NumIfsOutputs++) ||
4627 A->
getType() == types::TY_Nothing &&
4628 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4629 NumOutputs += A->
size();
4632 if (NumOutputs > 1) {
4633 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4634 FinalOutput =
nullptr;
4638 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4641 llvm::StringSet<> ArchNames;
4642 if (RawTriple.isOSBinFormatMachO())
4643 for (
const Arg *A :
C.getArgs())
4644 if (A->getOption().matches(options::OPT_arch))
4645 ArchNames.insert(A->getValue());
4648 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4649 for (
Action *A :
C.getActions()) {
4656 const char *LinkingOutput =
nullptr;
4659 LinkingOutput = FinalOutput->getValue();
4667 ArchNames.size() > 1 ||
4668 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
4669 LinkingOutput, CachedResults,
4676 for (
auto &J :
C.getJobs())
4677 J.InProcess =
false;
4684 C.setPostCallback([=](
const Command &Cmd,
int Res) {
4685 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4690 const char *LinkingOutput =
nullptr;
4692 LinkingOutput = FinalOutput->getValue();
4699 using namespace llvm;
4702 <<
"output=" << LinkingOutput;
4703 outs() <<
", total="
4704 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4706 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4707 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4711 llvm::raw_string_ostream Out(Buffer);
4712 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
4715 llvm::sys::printArg(Out, LinkingOutput,
true);
4716 Out <<
',' << ProcStat->TotalTime.count() <<
','
4717 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4722 llvm::sys::fs::OF_Append |
4723 llvm::sys::fs::OF_Text);
4728 llvm::errs() <<
"ERROR: Cannot lock file "
4730 <<
toString(L.takeError()) <<
"\n";
4741 bool ReportUnusedArguments =
4742 !Diags.hasErrorOccurred() &&
4743 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
4746 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
4748 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
4751 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
4752 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
4754 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
4758 return strstr(J.getCreator().getShortName(),
"assembler");
4760 for (Arg *A :
C.getArgs()) {
4764 if (!A->isClaimed()) {
4770 const Option &Opt = A->getOption();
4771 if (Opt.getKind() == Option::FlagClass) {
4772 bool DuplicateClaimed =
false;
4774 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
4775 if (AA->isClaimed()) {
4776 DuplicateClaimed =
true;
4781 if (DuplicateClaimed)
4787 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
4789 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
4794 !
C.getActions().empty()) {
4795 Diag(diag::err_drv_unsupported_opt_for_target)
4797 }
else if (ReportUnusedArguments) {
4798 Diag(clang::diag::warn_drv_unused_argument)
4799 << A->getAsString(
C.getArgs());
4809class ToolSelector final {
4820 bool IsHostSelector;
4831 bool CanBeCollapsed =
true) {
4833 if (Inputs.size() != 1)
4836 Action *CurAction = *Inputs.begin();
4837 if (CanBeCollapsed &&
4843 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
4847 if (!IsHostSelector) {
4848 if (OA->hasSingleDeviceDependence(
true)) {
4850 OA->getSingleDeviceDependence(
true);
4851 if (CanBeCollapsed &&
4854 SavedOffloadAction.push_back(OA);
4855 return dyn_cast<JobAction>(CurAction);
4857 }
else if (OA->hasHostDependence()) {
4858 CurAction = OA->getHostDependence();
4859 if (CanBeCollapsed &&
4862 SavedOffloadAction.push_back(OA);
4863 return dyn_cast<JobAction>(CurAction);
4868 return dyn_cast<JobAction>(CurAction);
4872 bool canCollapseAssembleAction()
const {
4873 return TC.useIntegratedAs() && !SaveTemps &&
4874 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
4875 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
4876 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
4877 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
4881 bool canCollapsePreprocessorAction()
const {
4882 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
4883 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
4884 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
4889 struct JobActionInfo final {
4891 const JobAction *JA =
nullptr;
4899 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
4900 ArrayRef<JobActionInfo> &ActionInfo,
4901 unsigned ElementNum) {
4902 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
4903 for (
unsigned I = 0; I < ElementNum; ++I)
4904 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
4905 ActionInfo[I].SavedOffloadAction.end());
4918 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
4921 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
4923 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4924 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4925 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
4926 if (!AJ || !BJ || !CJ)
4930 const Tool *
T = TC.SelectTool(*CJ);
4937 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
4943 const Tool *BT = TC.SelectTool(*BJ);
4948 if (!
T->hasIntegratedAssembler())
4951 Inputs = CJ->getInputs();
4952 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4956 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
4959 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
4961 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4962 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4967 const Tool *
T = TC.SelectTool(*BJ);
4971 if (!
T->hasIntegratedAssembler())
4974 Inputs = BJ->getInputs();
4975 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4979 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
4982 if (ActionInfo.size() < 2)
4984 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
4985 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
4989 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
4990 for (
auto &Input : AI.JA->getInputs())
5001 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5002 if (SaveTemps && !InputIsBitcode)
5006 const Tool *
T = TC.SelectTool(*CJ);
5013 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5019 Inputs = CJ->getInputs();
5020 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5029 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5031 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5037 for (Action *A : Inputs) {
5038 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5040 NewInputs.push_back(A);
5046 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5047 PreprocessJobOffloadActions.end());
5048 NewInputs.append(PJ->input_begin(), PJ->input_end());
5054 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5056 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5058 assert(BaseAction &&
"Invalid base action.");
5074 SmallVector<JobActionInfo, 5> ActionChain(1);
5075 ActionChain.back().JA = BaseAction;
5076 while (ActionChain.back().JA) {
5077 const Action *CurAction = ActionChain.back().JA;
5080 ActionChain.resize(ActionChain.size() + 1);
5081 JobActionInfo &AI = ActionChain.back();
5085 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5089 ActionChain.pop_back();
5097 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5098 CollapsedOffloadAction);
5100 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5102 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5108 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5121 std::string TriplePlusArch = TC->
getTriple().normalize();
5123 TriplePlusArch +=
"-";
5126 TriplePlusArch +=
"-";
5128 return TriplePlusArch;
5133 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5134 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5137 std::pair<const Action *, std::string> ActionTC = {
5139 auto CachedResult = CachedResults.find(ActionTC);
5140 if (CachedResult != CachedResults.end()) {
5141 return CachedResult->second;
5144 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
5145 TargetDeviceOffloadKind);
5146 CachedResults[ActionTC] =
Result;
5151 const JobAction *JA,
const char *BaseInput,
5154 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5165 if (!
Arch.empty()) {
5166 OffloadingPrefix +=
"-";
5167 OffloadingPrefix +=
Arch.ArchName;
5170 C.getDriver().isSaveTempsEnabled()) {
5177 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5178 Path = A->getValue();
5179 if (llvm::sys::fs::is_directory(Path)) {
5181 ? llvm::sys::path::stem(
Result.getFilename())
5182 : llvm::sys::path::stem(BaseInput));
5183 Tmp += OffloadingPrefix;
5185 llvm::sys::path::append(Path, Tmp);
5188 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5191 Path = DumpDir->getValue();
5192 Path += llvm::sys::path::stem(BaseInput);
5193 Path += OffloadingPrefix;
5195 }
else if (!OffloadingPrefix.empty()) {
5199 TraceName += OffloadingPrefix;
5200 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
5201 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
5202 llvm::sys::path::append(Path, TraceName);
5205 Path =
Result.getFilename();
5206 llvm::sys::path::replace_extension(Path,
"json");
5209 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5210 C.addTimeTraceFile(ResultFile, JA);
5211 C.addResultFile(ResultFile, JA);
5216 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5217 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5220 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5224 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
5225 C.setCurrentBoundArch(BA);
5226 auto RestoreBoundArch =
5227 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
5230 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5231 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5263 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5265 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5266 BoundArch DepBoundArch) {
5268 !DepBoundArch.
empty(),
5269 LinkingOutput, CachedResults,
5279 OA->doOnEachDependence(
5280 BuildingForOffloadDevice,
5281 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5283 C, DepA, DepTC, DepBoundArch,
false,
5284 !DepBoundArch.
empty(), LinkingOutput,
5288 A = BuildingForOffloadDevice
5289 ? OA->getSingleDeviceDependence(
true)
5290 : OA->getHostDependence();
5294 std::pair<const Action *, std::string> ActionTC = {
5295 OA->getHostDependence(),
5297 auto It = CachedResults.find(ActionTC);
5298 if (It != CachedResults.end()) {
5300 Inputs.append(OffloadDependencesInputInfo);
5305 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5308 const Arg &Input = IA->getInputArg();
5310 if (Input.getOption().matches(options::OPT_INPUT)) {
5311 const char *
Name = Input.getValue();
5314 return {InputInfo(A, &Input,
"")};
5317 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5318 const ToolChain *TC;
5319 BoundArch ArchName = BAA->
getArch();
5321 if (!ArchName.
empty())
5322 TC = &getToolChain(
C.getArgs(),
5326 TC = &
C.getDefaultToolChain();
5329 MultipleArchs, LinkingOutput, CachedResults,
5330 TargetDeviceOffloadKind);
5341 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5344 return {InputInfo()};
5348 for (
const auto *OA : CollapsedOffloadActions)
5350 BuildingForOffloadDevice,
5351 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5353 C, DepA, DepTC, DepBoundArch,
false,
5354 !DepBoundArch.
empty(), LinkingOutput,
5360 for (
const Action *Input : Inputs) {
5364 bool SubJobAtTopLevel =
5367 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5372 const char *BaseInput = InputInfos[0].getBaseInput();
5373 for (
auto &Info : InputInfos) {
5374 if (Info.isFilename()) {
5375 BaseInput = Info.getBaseInput();
5382 if (JA->
getType() == types::TY_dSYM)
5383 BaseInput = InputInfos[0].getFilename();
5386 if (!OffloadDependencesInputInfo.empty())
5387 InputInfos.append(OffloadDependencesInputInfo.begin(),
5388 OffloadDependencesInputInfo.end());
5391 llvm::Triple EffectiveTriple;
5392 const ToolChain &ToolTC =
T->getToolChain();
5393 const ArgList &Args =
5395 if (InputInfos.size() != 1) {
5400 EffectiveTriple = llvm::Triple(
5403 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
5407 if (JA->
getType() == types::TY_Nothing)
5408 Result = {InputInfo(A, BaseInput)};
5419 MultipleArchs, OffloadingPrefix),
5426 llvm::errs() <<
"# \"" <<
T->getToolChain().getEffectiveTriple().str()
5427 <<
'"' <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5428 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5429 llvm::errs() << InputInfos[i].getAsString();
5431 llvm::errs() <<
", ";
5433 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5435 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5441 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5442 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5454 if (ArgValue.empty()) {
5456 Filename = BaseName;
5457 }
else if (llvm::sys::path::is_separator(Filename.back())) {
5459 llvm::sys::path::append(Filename, BaseName);
5462 if (!llvm::sys::path::has_extension(ArgValue)) {
5467 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5472 llvm::sys::path::replace_extension(Filename, Extension);
5475 return Args.MakeArgString(Filename.c_str());
5490 StringRef Suffix,
bool MultipleArchs,
5491 StringRef BoundArchStr,
5492 bool NeedUniqueDirectory)
const {
5494 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5495 std::optional<std::string> CrashDirectory =
5497 ? std::string(A->getValue())
5498 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5499 if (CrashDirectory) {
5500 if (!
getVFS().exists(*CrashDirectory))
5501 llvm::sys::fs::create_directories(*CrashDirectory);
5503 llvm::sys::path::append(Path, Prefix);
5504 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5505 if (std::error_code EC =
5506 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
5507 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5511 if (MultipleArchs && !BoundArchStr.empty()) {
5512 if (NeedUniqueDirectory) {
5514 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
5525 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5540 const char *BaseInput) {
5542 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5543 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5548 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5553 bool AtTopLevel,
bool MultipleArchs,
5554 StringRef OffloadingPrefix)
const {
5557 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5559 auto CreateTempOutputPath = [&](StringRef Prefix) {
5560 const char *Suffix =
5565 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
5566 const bool NeedUniqueDirectory =
5569 Triple.isOSDarwin();
5571 NeedUniqueDirectory);
5576 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
5577 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
5578 StringRef Filename = llvm::sys::path::filename(BaseInput);
5579 StringRef Stem = llvm::sys::path::stem(Filename);
5580 return CreateTempOutputPath(Stem);
5585 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5586 return C.addResultFile(FinalOutput->getValue(), &JA);
5590 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5592 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5594 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5595 NameArg = A->getValue();
5596 return C.addResultFile(
5606 if (JA.
getType() == types::TY_ModuleFile &&
5607 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5611 if (JA.
getType() == types::TY_PP_Asm &&
5612 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5613 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5616 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
5619 if ((JA.
getType() == types::TY_Object &&
5620 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
5621 JA.
getType() == types::TY_DX_CONTAINER) {
5622 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5623 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
5624 C.getDefaultToolChain().getTriple().isSPIRV()) &&
5625 "expected DXIL or SPIR-V triple for HLSL output path");
5630 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
5632 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
5633 StringRef
Name = llvm::sys::path::filename(BaseInput);
5634 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5640 if (JA.
getType() == types::TY_PP_Asm &&
5641 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5642 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5644 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5645 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5646 return C.addResultFile(
5651 if (JA.
getType() == types::TY_API_INFO &&
5652 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5653 C.getArgs().hasArg(options::OPT_o))
5654 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5655 <<
C.getArgs().getLastArgValue(options::OPT_o);
5662 bool SpecifiedModuleOutput =
5663 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5664 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5665 if (MultipleArchs && SpecifiedModuleOutput)
5666 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5671 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5672 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
5678 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5680 StringRef
Name = llvm::sys::path::filename(BaseInput);
5681 return CreateTempOutputPath(
Name.split(
'.').first);
5690 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
5695 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
5696 llvm::sys::path::filename(BasePath));
5697 BaseName = ExternalPath;
5699 BaseName = BasePath;
5701 BaseName = llvm::sys::path::filename(BasePath);
5704 const char *NamedOutput;
5706 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
5707 JA.
getType() == types::TY_LLVM_BC ||
5708 JA.
getType() == types::TY_LLVM_IR) &&
5709 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
5713 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
5717 }
else if (JA.
getType() == types::TY_Image &&
5718 C.getArgs().hasArg(options::OPT__SLASH_Fe,
5719 options::OPT__SLASH_o)) {
5723 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
5727 }
else if (JA.
getType() == types::TY_Image) {
5737 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
5738 options::OPT_fno_gpu_rdc,
false);
5740 if (UseOutExtension) {
5742 llvm::sys::path::replace_extension(Output,
"");
5744 Output += OffloadingPrefix;
5745 if (MultipleArchs && !BoundArchStr.empty()) {
5747 Output.append(BoundArchStr);
5749 if (UseOutExtension)
5751 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
5754 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
5755 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
5756 C.getArgs().hasArg(options::OPT__SLASH_o)) {
5759 .getLastArg(options::OPT__SLASH_o)
5764 const char *Suffix =
5766 assert(Suffix &&
"All types used for output should have a suffix.");
5768 std::string::size_type End = std::string::npos;
5770 End = BaseName.rfind(
'.');
5772 Suffixed += OffloadingPrefix;
5773 if (MultipleArchs && !BoundArchStr.empty()) {
5775 Suffixed.append(BoundArchStr);
5780 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
5781 const llvm::opt::DerivedArgList &Args) {
5794 bool IsLinkerWrapper =
5796 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
5797 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
5798 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
5800 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
5804 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
5808 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
5809 JA.
getType() != types::TY_PCH) {
5810 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5812 llvm::sys::path::remove_filename(TempPath);
5813 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
5814 llvm::sys::path::append(TempPath, OutputFileName);
5815 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
5821 bool SameFile =
false;
5823 llvm::sys::fs::current_path(
Result);
5824 llvm::sys::path::append(
Result, BaseName);
5825 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
5828 StringRef
Name = llvm::sys::path::filename(BaseInput);
5829 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5833 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5839 llvm::sys::path::remove_filename(BasePath);
5840 if (BasePath.empty())
5841 BasePath = NamedOutput;
5843 llvm::sys::path::append(BasePath, NamedOutput);
5844 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
5847 return C.addResultFile(NamedOutput, &JA);
5853 -> std::optional<std::string> {
5856 for (
const auto &
Dir : P) {
5860 llvm::sys::path::append(P,
Name);
5861 if (llvm::sys::fs::exists(Twine(P)))
5862 return std::string(P);
5864 return std::nullopt;
5871 llvm::sys::path::append(R,
Name);
5872 if (llvm::sys::fs::exists(Twine(R)))
5873 return std::string(R);
5876 llvm::sys::path::append(P,
Name);
5877 if (llvm::sys::fs::exists(Twine(P)))
5878 return std::string(P);
5882 if (std::optional<std::string> IntrPath =
5885 llvm::sys::path::append(P,
Name);
5886 if (llvm::sys::fs::exists(P))
5887 return std::string(P);
5892 llvm::sys::path::append(D,
"..",
Name);
5893 if (llvm::sys::fs::exists(Twine(D)))
5894 return std::string(D);
5903 llvm::sys::path::append(R2,
"..",
"..",
Name);
5904 if (llvm::sys::fs::exists(Twine(R2)))
5905 return std::string(R2);
5907 return std::string(
Name);
5910void Driver::generatePrefixedToolNames(
5914 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
5915 Names.emplace_back(
Tool);
5919 llvm::sys::path::append(Dir, Name);
5920 if (llvm::sys::fs::can_execute(Twine(Dir)))
5922 llvm::sys::path::remove_filename(Dir);
5928 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
5933 if (llvm::sys::fs::is_directory(PrefixDir)) {
5936 return std::string(P);
5939 if (llvm::sys::fs::can_execute(Twine(P)))
5940 return std::string(P);
5945 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
5953 for (
const auto &Path : List) {
5956 return std::string(P);
5960 if (llvm::ErrorOr<std::string> P =
5961 llvm::sys::findProgramByName(TargetSpecificExecutable))
5965 return std::string(
Name);
5970 std::string error =
"<NOT PRESENT>";
5972 if (
C.getArgs().hasArg(options::OPT_nostdlib))
5977 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
5994 llvm::sys::path::remove_filename(path);
5995 llvm::sys::path::append(path,
"libc++.modules.json");
5996 if (TC.
getVFS().exists(path))
5997 return static_cast<std::string
>(path);
6002 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6005 return evaluate(
"libc++.a").value_or(error);
6009 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6013 llvm::sys::path::remove_filename(path);
6014 llvm::sys::path::append(path,
"libstdc++.modules.json");
6015 if (TC.
getVFS().exists(path))
6016 return static_cast<std::string
>(path);
6021 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6024 return evaluate(
"libstdc++.a").value_or(error);
6033 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6035 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6039 return std::string(Path);
6044 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6046 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6050 return std::string(Path);
6055 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6059 Output = FpArg->getValue();
6063 if (!llvm::sys::path::has_extension(Output))
6066 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6067 Output = YcArg->getValue();
6070 llvm::sys::path::replace_extension(Output,
".pch");
6072 return std::string(Output);
6075const ToolChain &Driver::getOffloadToolChain(
6077 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6078 std::unique_ptr<ToolChain> &TC =
6079 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6080 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6082 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6085 switch (
Target.getOS()) {
6086 case llvm::Triple::CUDA:
6087 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6090 case llvm::Triple::AMDHSA:
6096 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6097 HostTC.get(), Kind);
6105 switch (
Target.getArch()) {
6106 case llvm::Triple::amdgpu:
6107 case llvm::Triple::r600:
6108 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6109 HostTC.get(), Kind);
6111 case llvm::Triple::spir:
6112 case llvm::Triple::spir64:
6113 case llvm::Triple::spirv:
6114 case llvm::Triple::spirv32:
6115 case llvm::Triple::spirv64:
6118 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6122 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6126 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6130 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6144 return getToolChain(Args,
Target);
6148const ToolChain &Driver::getToolChain(
const ArgList &Args,
6149 const llvm::Triple &
Target)
const {
6151 auto &TC = ToolChains[
Target.str()];
6153 switch (
Target.getOS()) {
6154 case llvm::Triple::AIX:
6155 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6157 case llvm::Triple::Haiku:
6158 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6160 case llvm::Triple::Darwin:
6161 case llvm::Triple::MacOSX:
6162 case llvm::Triple::IOS:
6163 case llvm::Triple::TvOS:
6164 case llvm::Triple::WatchOS:
6165 case llvm::Triple::XROS:
6166 case llvm::Triple::DriverKit:
6167 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6169 case llvm::Triple::DragonFly:
6170 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6172 case llvm::Triple::OpenBSD:
6173 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6175 case llvm::Triple::NetBSD:
6176 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6178 case llvm::Triple::FreeBSD:
6180 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6183 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6185 case llvm::Triple::Linux:
6186 case llvm::Triple::ELFIAMCU:
6187 if (
Target.getArch() == llvm::Triple::hexagon)
6188 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6190 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6191 !
Target.hasEnvironment())
6192 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6195 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6197 else if (
Target.getArch() == llvm::Triple::ve)
6198 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6199 else if (
Target.isOHOSFamily())
6200 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6201 else if (
Target.isWALI())
6202 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6204 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6206 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6208 case llvm::Triple::Fuchsia:
6209 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6211 case llvm::Triple::Managarm:
6212 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6214 case llvm::Triple::Serenity:
6215 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
6217 case llvm::Triple::Solaris:
6218 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6220 case llvm::Triple::CUDA:
6221 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6223 case llvm::Triple::AMDHSA: {
6224 if (
Target.getArch() == llvm::Triple::spirv64) {
6225 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6231 TC = std::make_unique<toolchains::AMDGPUToolChain>(
6233 ShouldLinkDeviceLibs);
6237 case llvm::Triple::AMDPAL:
6238 case llvm::Triple::Mesa3D:
6239 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6241 case llvm::Triple::UEFI:
6242 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6244 case llvm::Triple::Win32:
6245 switch (
Target.getEnvironment()) {
6247 if (
Target.isOSBinFormatELF())
6248 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6249 else if (
Target.isOSBinFormatMachO())
6250 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6252 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6254 case llvm::Triple::GNU:
6255 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6257 case llvm::Triple::Cygnus:
6258 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6260 case llvm::Triple::Itanium:
6261 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6264 case llvm::Triple::MSVC:
6265 case llvm::Triple::UnknownEnvironment:
6266 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6267 .starts_with_insensitive(
"bfd"))
6268 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6272 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6276 case llvm::Triple::PS4:
6277 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6279 case llvm::Triple::PS5:
6280 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6282 case llvm::Triple::Hurd:
6283 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6285 case llvm::Triple::LiteOS:
6286 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6288 case llvm::Triple::ZOS:
6289 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6291 case llvm::Triple::Vulkan:
6292 case llvm::Triple::ShaderModel:
6293 if ((
Target.getArch() == llvm::Triple::spirv32 ||
6294 Target.getArch() == llvm::Triple::spirv64) &&
6296 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6298 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6300 case llvm::Triple::ChipStar:
6301 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
6306 switch (
Target.getArch()) {
6307 case llvm::Triple::tce:
6308 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6310 case llvm::Triple::tcele:
6311 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6313 case llvm::Triple::tcele64:
6315 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
6317 case llvm::Triple::hexagon:
6318 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6321 case llvm::Triple::lanai:
6322 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6324 case llvm::Triple::xcore:
6325 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6327 case llvm::Triple::wasm32:
6328 case llvm::Triple::wasm64:
6329 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6331 case llvm::Triple::avr:
6332 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6334 case llvm::Triple::msp430:
6335 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6337 case llvm::Triple::riscv32:
6338 case llvm::Triple::riscv64:
6339 case llvm::Triple::riscv32be:
6340 case llvm::Triple::riscv64be:
6341 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6343 case llvm::Triple::ve:
6344 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6346 case llvm::Triple::spirv32:
6347 case llvm::Triple::spirv64:
6348 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6350 case llvm::Triple::csky:
6351 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6353 case llvm::Triple::amdgpu:
6354 case llvm::Triple::r600:
6355 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6359 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6360 else if (
Target.isOSBinFormatELF())
6361 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6362 else if (
Target.isAppleFirmware())
6363 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6364 else if (
Target.isAppleMachO())
6365 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6366 else if (
Target.isOSBinFormatMachO())
6367 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6369 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6379 if (JA.
size() != 1 ||
6394 if (JA.
size() != 1 ||
6408 if (Args.hasArg(options::OPT_emit_static_lib))
6419 unsigned &Micro,
bool &HadExtra) {
6422 Major = Minor = Micro = 0;
6426 if (Str.consumeInteger(10, Major))
6430 if (!Str.consume_front(
"."))
6433 if (Str.consumeInteger(10, Minor))
6437 if (!Str.consume_front(
"."))
6440 if (Str.consumeInteger(10, Micro))
6458 unsigned CurDigit = 0;
6459 while (CurDigit < Digits.size()) {
6461 if (Str.consumeInteger(10, Digit))
6463 Digits[CurDigit] = Digit;
6466 if (!Str.consume_front(
"."))
6475llvm::opt::Visibility
6476Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6488const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6504 llvm_unreachable(
"Unhandled Mode");
6508 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6513 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6514 options::OPT_fno_save_optimization_record,
false))
6518 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6519 options::OPT_fno_save_optimization_record,
false))
6523 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6524 options::OPT_fno_save_optimization_record,
false))
6528 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6529 options::OPT_fno_save_optimization_record,
false))
6536 static StringRef OptName =
6538 llvm::StringRef Opt;
6539 for (StringRef Arg : Args) {
6540 if (!Arg.starts_with(OptName))
6546 return Opt.consume_front(OptName) ? Opt :
"";
6553 llvm::BumpPtrAllocator &Alloc,
6554 llvm::vfs::FileSystem *FS) {
6563 for (
const char *F : Args) {
6564 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6566 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6567 RSPQuoting = Windows;
6573 bool MarkEOLs = ClangCLMode;
6575 llvm::cl::TokenizerCallback Tokenizer;
6576 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
6577 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6579 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6581 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6584 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6585 ECtx.setMarkEOLs(MarkEOLs);
6589 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6593 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6594 [](
const char *A) {
return A !=
nullptr; });
6595 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6598 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6599 Args.resize(newEnd - Args.begin());
6603 return llvm::Error::success();
6607 return SavedStrings.insert(S).first->getKeyData();
6641 llvm::StringSet<> &SavedStrings) {
6644 if (Edit[0] ==
'^') {
6645 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6646 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6647 Args.insert(Args.begin() + 1, Str);
6648 }
else if (Edit[0] ==
'+') {
6649 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6650 OS <<
"### Adding argument " << Str <<
" at end\n";
6651 Args.push_back(Str);
6652 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6653 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6654 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6655 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6656 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6658 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6660 if (Args[i] ==
nullptr)
6662 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6664 if (Repl != Args[i]) {
6665 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6669 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6670 auto Option = Edit.substr(1);
6671 for (
unsigned i = 1; i < Args.size();) {
6672 if (Option == Args[i]) {
6673 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6674 Args.erase(Args.begin() + i);
6675 if (Edit[0] ==
'X') {
6676 if (i < Args.size()) {
6677 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6678 Args.erase(Args.begin() + i);
6680 OS <<
"### Invalid X edit, end of command line!\n";
6685 }
else if (Edit[0] ==
'O') {
6686 for (
unsigned i = 1; i < Args.size();) {
6687 const char *A = Args[i];
6691 if (A[0] ==
'-' && A[1] ==
'O' &&
6692 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6693 (
'0' <= A[2] && A[2] <=
'9'))))) {
6694 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6695 Args.erase(Args.begin() + i);
6699 OS <<
"### Adding argument " << Edit <<
" at end\n";
6700 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6702 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6707 const char *OverrideStr,
6708 llvm::StringSet<> &SavedStrings,
6709 StringRef EnvVar, raw_ostream *OS) {
6711 OS = &llvm::nulls();
6713 if (OverrideStr[0] ==
'#') {
6715 OS = &llvm::nulls();
6718 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
6722 const char *S = OverrideStr;
6724 const char *End = ::strchr(S,
' ');
6726 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.
StringRef getName(const HeaderType T)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
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