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;
359 Arg **FinalPhaseArg)
const {
360 Arg *PhaseArg =
nullptr;
364 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
374 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
376 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
378 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
379 options::OPT_fmodule_header_EQ))) {
382 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
383 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
385 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
386 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
387 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
388 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
389 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
390 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
391 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
392 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
396 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
400 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
403 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
409 bool AnyPhase =
false;
410 for (
auto &I : Inputs) {
412 const Arg *InputArg = I.second;
424 if (LastPL > FinalPhase)
435 *FinalPhaseArg = PhaseArg;
443 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
444 llvm::sys::fs::OF_Text);
445 llvm::FileRemover OutputRemover(OutputFile.c_str());
446 std::optional<llvm::StringRef> Redirects[] = {
452 std::string ErrorMessage;
453 int SecondsToWait = 60;
454 if (std::optional<std::string> Str =
455 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
456 if (!llvm::to_integer(*Str, SecondsToWait))
457 return llvm::createStringError(std::error_code(),
458 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
459 "an integer, got '" +
461 SecondsToWait = std::max(SecondsToWait, 0);
463 StringRef Executable = Args[0];
464 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
466 return llvm::createStringError(std::error_code(),
467 Executable +
": " + ErrorMessage);
469 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
470 llvm::MemoryBuffer::getFile(OutputFile.c_str());
472 return llvm::createStringError(OutputBuf.getError(),
473 "Failed to read stdout of " + Executable +
474 ": " + OutputBuf.getError().message());
475 return std::move(*OutputBuf);
479 StringRef
Value,
bool Claim) {
480 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
481 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
482 Args.AddSynthesizedArg(A);
488DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
489 const llvm::opt::OptTable &Opts =
getOpts();
490 DerivedArgList *DAL =
new DerivedArgList(Args);
492 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
493 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
494 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
495 bool IgnoreUnused =
false;
496 for (Arg *A : Args) {
500 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
504 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
505 IgnoreUnused =
false;
515 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
516 A->getOption().matches(options::OPT_Xlinker)) &&
517 A->containsValue(
"--no-demangle")) {
519 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
522 for (StringRef Val : A->getValues())
523 if (Val !=
"--no-demangle")
524 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
532 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
533 A->getNumValues() > 0 &&
534 (A->getValue(0) == StringRef(
"-MD") ||
535 A->getValue(0) == StringRef(
"-MMD"))) {
537 if (A->getValue(0) == StringRef(
"-MD"))
538 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
540 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
541 if (A->getNumValues() == 2)
542 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
547 if (A->getOption().matches(options::OPT_l)) {
548 StringRef
Value = A->getValue();
551 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
553 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
558 if (
Value ==
"cc_kext") {
559 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
565 if (A->getOption().matches(options::OPT__DASH_DASH)) {
567 for (StringRef Val : A->getValues())
576 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
577 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
580 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
581 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
585#if defined(HOST_LINK_VERSION)
586 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
587 strlen(HOST_LINK_VERSION) > 0) {
588 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
590 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
598 StringRef ArgTarget) {
600 static bool BeSilent =
false;
601 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
return v < 3; };
604 if (ArgTarget.equals_insensitive(
"CURRENT")) {
608 unsigned int Version = 0;
609 unsigned int Release = 0;
610 unsigned int Modification = 0;
612 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
613 llvm::Regex HexRegex(
616 "([0-9a-fA-F][0-9a-fA-F])"
617 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
620 if (ZOsvRegex.match(ArgTarget, &Matches)) {
621 Matches[1].getAsInteger(10, Version);
622 Matches[2].getAsInteger(10, Release);
624 if (IsTooOldToBeSupported(Version, Release)) {
626 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
629 }
else if (HexRegex.match(ArgTarget, &Matches)) {
630 Matches[1].getAsInteger(16, Version);
631 Matches[2].getAsInteger(16, Release);
632 Matches[3].getAsInteger(16, Modification);
633 if (IsTooOldToBeSupported(Version, Release)) {
635 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
641 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
646 llvm::VersionTuple
V(Version, Release, Modification);
647 llvm::VersionTuple TV =
Target.getOSVersion();
650 if (TV.empty() ||
V < TV) {
652 Str = llvm::Triple::getOSTypeName(
Target.getOS());
653 Str +=
V.getAsString();
667 StringRef ArchName =
"") {
669 if (
const Arg *A = Args.getLastArg(options::OPT_target))
670 TargetTriple = A->getValue();
672 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
677 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
681 if (
Target.isOSBinFormatMachO()) {
683 if (!ArchName.empty()) {
685 return llvm::Triple(
Target.normalize());
689 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
690 StringRef ArchName = A->getValue();
693 }
else if (!ArchName.empty()) {
694 Target.setArchName(ArchName);
700 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
701 options::OPT_mbig_endian)) {
702 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
703 ?
Target.getLittleEndianArchVariant()
704 :
Target.getBigEndianArchVariant();
705 if (
T.getArch() != llvm::Triple::UnknownArch) {
706 Target = llvm::Triple(
T.normalize());
707 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
712 if (
Target.getArch() == llvm::Triple::tce)
718 if (!Args.hasArg(options::OPT_target)) {
719 if (std::optional<std::string> ObjectModeValue =
720 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
721 StringRef ObjectMode = *ObjectModeValue;
722 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
725 if (ObjectMode ==
"64") {
726 AT =
Target.get64BitArchVariant().getArch();
727 }
else if (ObjectMode ==
"32" || ObjectMode ==
"32_64" ||
728 ObjectMode ==
"any") {
730 if (Args.hasArg(options::OPT_maix64, options::OPT_m64))
731 AT =
Target.get64BitArchVariant().getArch();
733 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
735 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
739 const bool OtherAllowedMode =
740 ObjectMode ==
"32_64" || ObjectMode ==
"any";
741 if (ObjectMode ==
"64")
742 AT =
Target.get64BitArchVariant().getArch();
743 else if (ObjectMode ==
"32")
744 AT =
Target.get32BitArchVariant().getArch();
745 else if (!OtherAllowedMode)
746 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
749 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
754 !Args.hasArg(options::OPT_maix64, options::OPT_m64)) {
757 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
763 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
764 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
767 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
769 D.
Diag(diag::err_drv_unsupported_opt_for_target)
770 << A->getAsString(Args) <<
Target.str();
773 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
774 options::OPT_m32, options::OPT_m16,
775 options::OPT_maix32, options::OPT_maix64);
777 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
779 if (A->getOption().matches(options::OPT_m64) ||
780 A->getOption().matches(options::OPT_maix64)) {
781 AT =
Target.get64BitArchVariant().getArch();
782 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
783 Target.getEnvironment() == llvm::Triple::GNUT64)
784 Target.setEnvironment(llvm::Triple::GNU);
785 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
786 Target.setEnvironment(llvm::Triple::Musl);
787 }
else if (A->getOption().matches(options::OPT_mx32) &&
788 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
789 AT = llvm::Triple::x86_64;
790 if (
Target.getEnvironment() == llvm::Triple::Musl)
791 Target.setEnvironment(llvm::Triple::MuslX32);
793 Target.setEnvironment(llvm::Triple::GNUX32);
794 }
else if (A->getOption().matches(options::OPT_m32) ||
795 A->getOption().matches(options::OPT_maix32)) {
798 D.
Diag(diag::err_drv_compile_mode_unsupported_aix);
800 D.
Diag(diag::err_drv_unsupported_opt_for_target)
801 << A->getAsString(Args) <<
Target.str();
804 AT =
Target.get32BitArchVariant().getArch();
805 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
806 Target.setEnvironment(llvm::Triple::GNU);
807 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
808 Target.setEnvironment(llvm::Triple::Musl);
810 }
else if (A->getOption().matches(options::OPT_m16) &&
811 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
812 AT = llvm::Triple::x86;
813 Target.setEnvironment(llvm::Triple::CODE16);
816 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
818 if (
Target.isWindowsGNUEnvironment())
826 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
832 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
833 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
834 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
837 if (A && !A->getOption().matches(options::OPT_m32))
838 D.
Diag(diag::err_drv_argument_not_allowed_with)
839 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
841 Target.setArch(llvm::Triple::x86);
842 Target.setArchName(
"i586");
843 Target.setEnvironmentName(
"");
844 Target.setOS(llvm::Triple::ELFIAMCU);
845 Target.setVendor(llvm::Triple::Intel);
851 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
852 StringRef ABIName = A->getValue();
853 if (ABIName ==
"32") {
855 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
856 Target.getEnvironment() == llvm::Triple::GNUABIN32)
857 Target.setEnvironment(llvm::Triple::GNU);
858 }
else if (ABIName ==
"n32") {
860 if (
Target.getEnvironment() == llvm::Triple::GNU ||
861 Target.getEnvironment() == llvm::Triple::GNUT64 ||
862 Target.getEnvironment() == llvm::Triple::GNUABI64)
863 Target.setEnvironment(llvm::Triple::GNUABIN32);
864 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
865 Target.getEnvironment() == llvm::Triple::MuslABI64)
866 Target.setEnvironment(llvm::Triple::MuslABIN32);
867 }
else if (ABIName ==
"64") {
869 if (
Target.getEnvironment() == llvm::Triple::GNU ||
870 Target.getEnvironment() == llvm::Triple::GNUT64 ||
871 Target.getEnvironment() == llvm::Triple::GNUABIN32)
872 Target.setEnvironment(llvm::Triple::GNUABI64);
873 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
874 Target.getEnvironment() == llvm::Triple::MuslABIN32)
875 Target.setEnvironment(llvm::Triple::MuslABI64);
885 if (Args.hasArg(options::OPT_march_EQ) ||
886 Args.hasArg(options::OPT_mcpu_EQ)) {
888 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
890 if (!llvm::errorToBool(ISAInfo.takeError())) {
891 unsigned XLen = (*ISAInfo)->getXLen();
893 if (
Target.isLittleEndian())
894 Target.setArch(llvm::Triple::riscv32);
896 Target.setArch(llvm::Triple::riscv32be);
898 }
else if (XLen == 64) {
899 if (
Target.isLittleEndian())
900 Target.setArch(llvm::Triple::riscv64);
902 Target.setArch(llvm::Triple::riscv64be);
909 if (
Target.getArch() == llvm::Triple::riscv32be ||
910 Target.getArch() == llvm::Triple::riscv64be) {
911 static bool WarnedRISCVBE =
false;
912 if (!WarnedRISCVBE) {
913 D.
Diag(diag::warn_drv_riscv_be_experimental);
914 WarnedRISCVBE =
true;
923 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
925 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
927 RuntimeName = A->getValue();
929 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
937 Diag(diag::err_drv_unsupported_option_argument)
938 << A->getSpelling() << A->getValue();
941 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
950 StringRef Program =
C.getArgs().getLastArgValue(
951 options::OPT_offload_arch_tool_EQ,
"offload-arch");
954 if (llvm::ErrorOr<std::string> Executable =
955 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
957 bool UsesLLVMOffloading =
958 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
959 options::OPT_fno_offload_via_llvm,
false);
960 if (!UsesLLVMOffloading) {
962 Args.push_back(
"--only=amdgpu");
964 Args.push_back(
"--only=nvptx");
966 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
969 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
974 if ((*StdoutOrErr)->getBuffer().empty()) {
975 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
981 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
983 GPUArchs.push_back(
Arch.str());
985 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
996 std::set<std::string> Archs;
997 for (Arg *A :
C.getInputArgs()) {
998 for (StringRef
Arch : A->getValues()) {
999 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
1000 if (
Arch ==
"native") {
1002 Archs.insert(Str.str());
1004 Archs.insert(
Arch.str());
1006 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
1010 Archs.erase(
Arch.str());
1016 for (llvm::StringRef
Arch : Archs) {
1018 if (ID.isUnknown()) {
1019 llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
1020 llvm::Triple::AMD, llvm::Triple::AMDHSA);
1024 bool UsesLLVMOffloading =
1025 C.getArgs().hasFlag(options::OPT_foffload_via_llvm,
1026 options::OPT_fno_offload_via_llvm,
false);
1027 if (!UsesLLVMOffloading) {
1028 if (Kind ==
Action::OFK_HIP && !ID.isAMDGPU() && !ID.isAMDGCNSPIRV()) {
1029 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1034 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1040 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1044 if (ID.isUnknown() || ID.isUnused()) {
1045 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1046 <<
"offload" <<
Arch;
1050 llvm::Triple Triple =
1052 if (UsesLLVMOffloading)
1053 Triple.setEnvironment(llvm::Triple::LLVM);
1058 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1059 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1060 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1061 C.getArgs().MakeArgString(Triple.getArchName()),
1062 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1064 C.getArgs().append(A);
1065 C.getArgs().AddSynthesizedArg(A);
1067 auto It = Triples.lower_bound(Triple);
1068 if (It == Triples.end() || *It != Triple)
1069 Triples.insert(It, Triple);
1074 Triples.insert(llvm::Triple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch,
1075 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1077 llvm::Triple::ArchType
Arch =
1078 C.getDefaultToolChain().getTriple().isArch64Bit()
1079 ? llvm::Triple::nvptx64
1080 : llvm::Triple::nvptx;
1081 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1082 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1085 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1086 ? llvm::Triple::spirv64
1087 : llvm::Triple::spirv32));
1090 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1091 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1099 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1103 (llvm::any_of(Inputs,
1104 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1107 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1108 C.getInputArgs().hasArg(options::OPT_hipstdpar));
1109 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1110 options::OPT_fno_sycl,
false);
1111 bool IsOpenMPOffloading =
1112 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1113 options::OPT_fno_openmp,
false) &&
1114 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1115 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1116 !(IsCuda || IsHIP))));
1118 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1119 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1124 for (
const auto &[Active, Kind] : ActiveKinds)
1129 if (Kinds.size() > 1) {
1130 Diag(clang::diag::err_drv_mix_offload)
1137 if (IsCuda || IsHIP)
1144 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1145 std::vector<std::string> ArgValues =
1146 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1147 for (llvm::StringRef
Target : ArgValues) {
1151 if (ArgValues.empty())
1152 Diag(clang::diag::warn_drv_empty_joined_argument)
1154 .getLastArg(options::OPT_offload_targets_EQ)
1155 ->getAsString(
C.getInputArgs());
1162 llvm::StringMap<StringRef> FoundNormalizedTriples;
1163 for (
const llvm::Triple &
Target : Triples) {
1168 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1176 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1177 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1178 Diag(clang::diag::err_drv_argument_not_allowed_with)
1179 << IncompatArg->getSpelling() <<
"-fsycl";
1184 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1185 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1190 std::string NormalizedName =
Target.normalize();
1191 auto [TripleIt, Inserted] =
1192 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1194 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1195 <<
Target.str() << TripleIt->second;
1199 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1200 C.getDefaultToolChain().getTriple());
1204 auto &CudaInstallation =
1206 if (CudaInstallation.isValid())
1207 CudaInstallation.WarnIfUnsupportedVersion();
1210 C.addOffloadDeviceToolChain(&TC, Kind);
1218 const Arg *RDCArg =
C.getInputArgs().getLastArg(options::OPT_fgpu_rdc,
1219 options::OPT_fno_gpu_rdc);
1220 if (RDCArg && RDCArg->getOption().matches(options::OPT_fno_gpu_rdc)) {
1222 if (std::distance(TCRange.first, TCRange.second) > 1)
1223 Diag(clang::diag::err_drv_sycl_no_rdc_multiple_targets)
1224 << RDCArg->getAsString(
C.getInputArgs());
1229bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1234 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1238 if (!PathLIBEnv.empty()) {
1239 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1240 if (llvm::sys::fs::is_directory(PathLIBEnv))
1241 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1242 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1243 return readConfigFile(CustomizationFile, ExpCtx);
1244 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1249 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1250 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1251 return readConfigFile(CustomizationFile, ExpCtx);
1261 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1262 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1263 Copy->getValues() = Opt->getValues();
1264 if (Opt->isClaimed())
1266 Copy->setOwnsValues(Opt->getOwnsValues());
1267 Opt->setOwnsValues(
false);
1269 if (Opt->getAlias()) {
1270 const Arg *Alias = Opt->getAlias();
1271 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1272 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1273 Args.getArgString(Index), Index);
1274 AliasCopy->getValues() = Alias->getValues();
1275 AliasCopy->setOwnsValues(
false);
1276 if (Alias->isClaimed())
1278 Copy->setAlias(std::move(AliasCopy));
1282bool Driver::readConfigFile(StringRef
FileName,
1283 llvm::cl::ExpansionContext &ExpCtx) {
1287 Diag(diag::err_drv_cannot_open_config_file)
1288 <<
FileName << Status.getError().message();
1291 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1292 Diag(diag::err_drv_cannot_open_config_file)
1293 <<
FileName <<
"not a regular file";
1298 SmallVector<const char *, 32> NewCfgFileArgs;
1299 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1300 Diag(diag::err_drv_cannot_read_config_file)
1306 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1307 for (
const char *Opt : NewCfgFileArgs) {
1309 if (Opt[0] ==
'$' && Opt[1])
1310 NewCfgTailArgs.push_back(Opt + 1);
1312 NewCfgHeadArgs.push_back(Opt);
1316 llvm::SmallString<128> CfgFileName(
FileName);
1317 llvm::sys::path::native(CfgFileName);
1318 bool ContainErrors =
false;
1319 auto NewHeadOptions = std::make_unique<InputArgList>(
1323 auto NewTailOptions = std::make_unique<InputArgList>(
1330 for (Arg *A : *NewHeadOptions)
1332 for (Arg *A : *NewTailOptions)
1335 if (!CfgOptionsHead)
1336 CfgOptionsHead = std::move(NewHeadOptions);
1339 for (
auto *Opt : *NewHeadOptions)
1343 if (!CfgOptionsTail)
1344 CfgOptionsTail = std::move(NewTailOptions);
1347 for (
auto *Opt : *NewTailOptions)
1351 ConfigFiles.push_back(std::string(CfgFileName));
1355bool Driver::loadConfigFiles() {
1356 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1357 llvm::cl::tokenizeConfigFile, &
getVFS());
1361 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1362 SmallString<128> CfgDir;
1364 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1365 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1370 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1371 SmallString<128> CfgDir;
1372 llvm::sys::fs::expand_tilde(
1373 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1374 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1383 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1386 if (loadDefaultConfigFiles(ExpCtx))
1390 SmallString<128> CfgFilePath;
1392 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1395 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1396 CfgFilePath.assign(CfgFileName);
1397 if (llvm::sys::path::is_relative(CfgFilePath)) {
1398 if (
getVFS().makeAbsolute(CfgFilePath)) {
1399 Diag(diag::err_drv_cannot_open_config_file)
1400 << CfgFilePath <<
"cannot get absolute path";
1404 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1406 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1407 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1408 if (!SearchDir.empty())
1409 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1414 if (readConfigFile(CfgFilePath, ExpCtx))
1425 llvm::Triple Triple, std::string Suffix) {
1427 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1431 VersionTuple OSVersion = Triple.getOSVersion();
1432 if (!OSVersion.getMinor().has_value())
1435 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1439 if (OSVersion.getMajor() != 0) {
1440 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1441 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1447 Triple.setOSName(BaseOSName);
1448 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1451bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1454 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1458 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1461 std::string RealMode = getExecutableForDriverMode(Mode);
1462 llvm::Triple Triple;
1471 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1472 PrefixTriple.isOSUnknown())
1473 Triple = std::move(PrefixTriple);
1477 llvm::Triple RealTriple =
1479 if (Triple.str().empty()) {
1480 Triple = RealTriple;
1481 assert(!Triple.str().empty());
1486 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1500 SmallString<128> CfgFilePath;
1502 "-" + RealMode +
".cfg"))
1503 return readConfigFile(CfgFilePath, ExpCtx);
1507 if (TryModeSuffix) {
1510 return readConfigFile(CfgFilePath, ExpCtx);
1515 std::string CfgFileName = RealMode +
".cfg";
1516 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1517 if (readConfigFile(CfgFilePath, ExpCtx))
1519 }
else if (TryModeSuffix) {
1521 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1522 readConfigFile(CfgFilePath, ExpCtx))
1528 return readConfigFile(CfgFilePath, ExpCtx);
1536 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1545 if (!DriverMode.empty())
1546 setDriverMode(DriverMode);
1552 CLOptions = std::make_unique<InputArgList>(
1557 ContainsError = loadConfigFiles();
1558 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1559 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1563 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1565 if (HasConfigFileHead)
1566 for (
auto *Opt : *CLOptions)
1567 if (!Opt->getOption().matches(options::OPT_config))
1571 if (
IsCLMode() && !ContainsError) {
1573 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1575 CLModePassThroughArgList.push_back(A->getValue());
1578 if (!CLModePassThroughArgList.empty()) {
1581 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1586 for (
auto *Opt : *CLModePassThroughOptions)
1592 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1593 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1594 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1597 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1598 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1599 if (!VFS->exists(IncludeDir))
1600 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1605 bool CCCPrintPhases;
1608 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1609 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1612 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1613 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1616 Args.ClaimAllArgs(options::OPT_pipe);
1624 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1626 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1627 CCCGenericGCCName = A->getValue();
1630 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1634 if (Args.hasArg(options::OPT_fproc_stat_report))
1641 llvm::Triple
T(TargetTriple);
1642 T.setOS(llvm::Triple::Win32);
1643 T.setVendor(llvm::Triple::PC);
1644 T.setEnvironment(llvm::Triple::MSVC);
1645 T.setObjectFormat(llvm::Triple::COFF);
1646 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1647 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1648 TargetTriple =
T.str();
1651 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1652 StringRef TargetProfile = A->getValue();
1655 TargetTriple = *Triple;
1657 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1661 if (Args.hasArg(options::OPT_spirv)) {
1662 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1663 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1664 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1665 llvm::Triple
T(TargetTriple);
1668 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1670 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1671 TargetInfo = ValidTargets.find(A->getValue());
1673 Diag(diag::err_drv_invalid_value)
1674 << A->getAsString(Args) << A->getValue();
1680 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1681 TargetTriple =
T.str();
1685 Diag(diag::err_drv_dxc_missing_target_profile);
1689 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1690 TargetTriple = A->getValue();
1691 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1692 Dir = A->getValue();
1693 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1697 if (std::optional<std::string> CompilerPathValue =
1698 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1699 StringRef CompilerPath = *CompilerPathValue;
1700 while (!CompilerPath.empty()) {
1701 std::pair<StringRef, StringRef> Split =
1702 CompilerPath.split(llvm::sys::EnvPathSeparator);
1703 PrefixDirs.push_back(std::string(Split.first));
1704 CompilerPath = Split.second;
1707 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1709 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1712 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1715 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1716 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1717 .Case(
"cwd", SaveTempsCwd)
1718 .Case(
"obj", SaveTempsObj)
1719 .Default(SaveTempsCwd);
1722 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1723 options::OPT_offload_device_only,
1724 options::OPT_offload_host_device)) {
1725 if (A->getOption().matches(options::OPT_offload_host_only))
1726 Offload = OffloadHost;
1727 else if (A->getOption().matches(options::OPT_offload_device_only))
1728 Offload = OffloadDevice;
1730 Offload = OffloadHostDevice;
1734 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1735 StringRef
Name = A->getValue();
1736 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1737 .Case(
"off", EmbedNone)
1738 .Case(
"all", EmbedBitcode)
1739 .Case(
"bitcode", EmbedBitcode)
1740 .Case(
"marker", EmbedMarker)
1743 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1746 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1750 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1751 llvm::sys::fs::remove(A->getValue());
1757 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1759 !Args.hasArg(options::OPT_fmodules) && Std &&
1760 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1761 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1762 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1763 Std->containsValue(
"c++2d") || Std->containsValue(
"c++latest"));
1766 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1767 options::OPT_fmodule_header)) {
1769 ModulesModeCXX20 =
true;
1770 if (A->getOption().matches(options::OPT_fmodule_header))
1773 StringRef ArgName = A->getValue();
1774 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1779 Diags.Report(diag::err_drv_invalid_value)
1780 << A->getAsString(Args) << ArgName;
1786 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1787 std::make_unique<InputArgList>(std::move(Args));
1797 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1798 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1800 bool MLContainsError;
1801 auto MultilibMacroDefineList =
1803 MLMacroDefinesChar,
false, MLContainsError));
1804 if (!MLContainsError) {
1805 for (
auto *Opt : *MultilibMacroDefineList) {
1812 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1816 if (!Triple.isWasm()) {
1817 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1818 StringRef TripleObjectFormat =
1819 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1820 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1821 TripleVersionName != TripleObjectFormat) {
1822 Diags.Report(diag::err_drv_triple_version_invalid)
1824 ContainsError =
true;
1829 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1830 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1831 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1839 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1840 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1842 case llvm::Triple::arm:
1843 case llvm::Triple::armeb:
1844 case llvm::Triple::thumb:
1845 case llvm::Triple::thumbeb:
1846 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1847 Diag(diag::warn_target_unrecognized_env)
1849 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1852 case llvm::Triple::aarch64:
1853 case llvm::Triple::aarch64_be:
1854 case llvm::Triple::aarch64_32:
1855 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1856 Diag(diag::warn_target_unrecognized_env)
1858 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1875 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1876 if (HasConfigFileTail && Inputs.size()) {
1878 if (
getFinalPhase(*TranslatedArgs, Inputs, &FinalPhaseArg) ==
1880 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1881 for (Arg *A : *CfgOptionsTail)
1882 TranslatedLinkerIns.append(A);
1883 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1890 bool UseModulesDriver =
C->getArgs().hasFlag(
1891 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1893 if (UseModulesDriver) {
1894 Diags.Report(diag::remark_performing_driver_managed_module_build);
1902 const auto StdModuleManifestPath =
1905 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1906 Diags.Report(diag::remark_modules_manifest_not_found);
1908 Diags.Report(diag::remark_using_modules_manifest)
1909 << StdModuleManifestPath;
1910 if (
auto ManifestOrErr =
1912 ModulesManifest = std::move(*ManifestOrErr);
1914 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1915 return !ModuleEntry.IsStdlib;
1920 llvm::handleAllErrors(
1921 ManifestOrErr.takeError(),
1922 [&](llvm::json::ParseError &Err) {
1923 Diags.Report(diag::err_modules_manifest_failed_parse)
1926 [&](llvm::FileError &Err) {
1927 Diags.Report(diag::err_cannot_open_file)
1928 << Err.getFileName() << Err.messageWithoutFileInfo();
1936 if (TC.
getTriple().isOSBinFormatMachO())
1941 if (CCCPrintPhases) {
1948 if (UseModulesDriver)
1955 llvm::opt::ArgStringList ASL;
1956 for (
const auto *A : Args) {
1960 while (A->getAlias())
1962 A->render(Args, ASL);
1965 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1966 if (I != ASL.begin())
1968 llvm::sys::printArg(OS, *I,
true);
1973bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1974 SmallString<128> &CrashDiagDir) {
1975 using namespace llvm::sys;
1976 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1977 "Only knows about .crash files on Darwin");
1979 auto BypassSandbox = sandbox::scopedDisable();
1984 path::home_directory(CrashDiagDir);
1985 if (CrashDiagDir.starts_with(
"/var/root"))
1987 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1995 fs::file_status FileStatus;
1996 TimePoint<> LastAccessTime;
1997 SmallString<128> CrashFilePath;
2000 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
2001 File != FileEnd && !EC;
File.increment(EC)) {
2005 if (fs::status(
File->path(), FileStatus))
2007 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
2008 llvm::MemoryBuffer::getFile(
File->path());
2013 StringRef
Data = CrashFile.get()->getBuffer();
2014 if (!
Data.starts_with(
"Process:"))
2017 size_t ParentProcPos =
Data.find(
"Parent Process:");
2018 if (ParentProcPos == StringRef::npos)
2020 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
2021 if (LineEnd == StringRef::npos)
2023 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
2024 int OpenBracket = -1, CloseBracket = -1;
2025 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
2026 if (ParentProcess[i] ==
'[')
2028 if (ParentProcess[i] ==
']')
2034 if (OpenBracket < 0 || CloseBracket < 0 ||
2035 ParentProcess.slice(OpenBracket + 1, CloseBracket)
2036 .getAsInteger(10, CrashPID) || CrashPID != PID) {
2046 const auto FileAccessTime = FileStatus.getLastModificationTime();
2047 if (FileAccessTime > LastAccessTime) {
2048 CrashFilePath.assign(
File->path());
2049 LastAccessTime = FileAccessTime;
2054 if (!CrashFilePath.empty()) {
2055 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2065 "\n********************\n\n"
2066 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
2074 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2077 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
2080 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2081 Level = llvm::StringSwitch<unsigned>(A->getValue())
2083 .Case(
"compiler", 1)
2095 ArgStringList SavedTemps;
2097 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2098 if (!IsLLD || Level < 2)
2105 SavedTemps = std::move(
C.getTempFiles());
2106 assert(!
C.getTempFiles().size());
2123 C.initCompilationForDiagnostics();
2128 Command NewLLDInvocation = Cmd;
2129 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2130 StringRef ReproduceOption =
2131 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2134 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2138 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2140 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2141 Diag(clang::diag::note_drv_command_failed_diag_msg)
2142 <<
"\n\n********************";
2144 Report->TemporaryFiles.push_back(TmpName);
2152 ArgStringList IRInputs;
2153 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2154 bool IgnoreInput =
false;
2160 IRInputs.push_back(it->second->getValue());
2164 }
else if (!strcmp(it->second->getValue(),
"-")) {
2165 Diag(clang::diag::note_drv_command_failed_diag_msg)
2166 <<
"Error generating preprocessed source(s) - "
2167 "ignoring input from stdin.";
2172 it = Inputs.erase(it);
2179 if (Inputs.empty() && IRInputs.empty()) {
2180 Diag(clang::diag::note_drv_command_failed_diag_msg)
2181 <<
"Error generating preprocessed source(s) - "
2182 "no preprocessable inputs.";
2188 llvm::StringSet<> ArchNames;
2189 for (
const Arg *A :
C.getArgs()) {
2190 if (A->getOption().matches(options::OPT_arch)) {
2191 StringRef ArchName = A->getValue();
2192 ArchNames.insert(ArchName);
2195 if (ArchNames.size() > 1) {
2198 if (FailingArch.empty()) {
2199 Diag(clang::diag::note_drv_command_failed_diag_msg)
2200 <<
"Error generating preprocessed source(s) - cannot generate "
2201 "preprocessed source with multiple -arch options.";
2204 C.getArgs().eraseArg(options::OPT_arch);
2205 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2210 if (!Inputs.empty()) {
2213 const ToolChain &TC =
C.getDefaultToolChain();
2214 if (TC.
getTriple().isOSBinFormatMachO())
2223 Diag(clang::diag::note_drv_command_failed_diag_msg)
2224 <<
"Error generating preprocessed source(s).";
2229 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2232 if (!FailingCommands.empty()) {
2233 Diag(clang::diag::note_drv_command_failed_diag_msg)
2234 <<
"Error generating preprocessed source(s).";
2238 const ArgStringList &TempFiles =
C.getTempFiles();
2239 if (TempFiles.empty()) {
2240 Diag(clang::diag::note_drv_command_failed_diag_msg)
2241 <<
"Error generating preprocessed source(s).";
2247 const ArgStringList &Files =
C.getTempFiles();
2252 for (
auto const *Input : IRInputs) {
2256 StringRef extension = llvm::sys::path::extension(Input);
2257 if (!extension.empty())
2258 extension = extension.drop_front();
2260 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2261 llvm::sys::path::stem(Input), extension, FD, Path);
2263 Diag(clang::diag::note_drv_command_failed_diag_msg)
2264 <<
"Error generating run script: " <<
"Failed copying IR input files"
2265 <<
" " << EC.message();
2269 EC = llvm::sys::fs::copy_file(Input, FD);
2271 Diag(clang::diag::note_drv_command_failed_diag_msg)
2272 <<
"Error generating run script: " <<
"Failed copying IR input files"
2273 <<
" " << EC.message();
2277 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2284 for (std::string &TempFile : TempFiles) {
2286 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2288 Report->TemporaryFiles.push_back(TempFile);
2289 if (ReproCrashFilename.empty()) {
2290 ReproCrashFilename = TempFile;
2291 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2293 if (StringRef(TempFile).ends_with(
".cache")) {
2296 VFS = llvm::sys::path::filename(TempFile);
2297 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2301 for (
const char *TempFile : SavedTemps)
2302 TempFiles.push_back(TempFile);
2308 llvm::sys::path::replace_extension(Script,
"sh");
2310 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2311 llvm::sys::fs::FA_Write,
2312 llvm::sys::fs::OF_Text);
2314 Diag(clang::diag::note_drv_command_failed_diag_msg)
2315 <<
"Error generating run script: " << Script <<
" " << EC.message();
2318 <<
"# Driver args: ";
2320 ScriptOS <<
"# Original command: ";
2321 Cmd.
Print(ScriptOS,
"\n",
true);
2322 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2323 if (!AdditionalInformation.empty())
2324 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2327 Report->TemporaryFiles.push_back(std::string(Script));
2328 TempFiles.push_back(std::string(Script));
2331 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2334 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2335 StringRef CrashDiagnosticsTar = A->getValue();
2337 llvm::TarWriter::create(CrashDiagnosticsTar,
2338 llvm::sys::path::stem(CrashDiagnosticsTar));
2340 Diag(clang::diag::note_drv_command_failed_diag_msg)
2341 << (std::string(
"Error creating reproducer tarball: ") +
2342 llvm::toString(TarOrErr.takeError()));
2344 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2345 for (
const std::string &TempFile : TempFiles) {
2346 if (llvm::sys::fs::is_directory(TempFile)) {
2348 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2349 I != E && !EC; I.increment(EC)) {
2350 if (llvm::sys::fs::is_regular_file(I->path())) {
2351 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2355 llvm::sys::path::filename(TempFile);
2356 StringRef SubPath = I->path();
2357 if (SubPath.consume_front(TempFile)) {
2358 if (!SubPath.empty() &&
2359 llvm::sys::path::is_separator(SubPath.front())) {
2360 SubPath = SubPath.drop_front();
2362 llvm::sys::path::append(PathInTar, SubPath);
2363 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2366 Diag(clang::diag::note_drv_command_failed_diag_msg)
2367 << (std::string(
"Error reading file for tarball: ") +
2373 Diag(clang::diag::note_drv_command_failed_diag_msg)
2374 << (std::string(
"Error iterating directory for tarball: ") +
2375 TempFile +
" " + EC.message());
2378 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2380 Tar->append(llvm::sys::path::filename(TempFile),
2381 (*BufferOrErr)->getBuffer());
2383 Diag(clang::diag::note_drv_command_failed_diag_msg)
2384 << (std::string(
"Error reading file for tarball: ") + TempFile);
2388 Diag(clang::diag::note_drv_command_failed_diag_msg)
2389 << CrashDiagnosticsTar;
2394 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2396 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2397 Diag(clang::diag::note_drv_command_failed_diag_msg)
2398 << ReproCrashFilename.str();
2400 llvm::sys::path::append(CrashDiagDir,
Name);
2401 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2402 Diag(clang::diag::note_drv_command_failed_diag_msg)
2403 <<
"Crash backtrace is located in";
2404 Diag(clang::diag::note_drv_command_failed_diag_msg)
2405 << CrashDiagDir.str();
2406 Diag(clang::diag::note_drv_command_failed_diag_msg)
2407 <<
"(choose the .crash file that corresponds to your crash)";
2411 Diag(clang::diag::note_drv_command_failed_diag_msg)
2412 <<
"\n\n********************";
2422 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2433 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2434 if (
C.getArgs().hasArg(options::OPT_v))
2435 C.getJobs().Print(llvm::errs(),
"\n",
true);
2437 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2440 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2447 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2448 C.getJobs().Print(llvm::errs(),
"\n",
true);
2449 return Diags.hasErrorOccurred() ? 1 : 0;
2453 if (Diags.hasErrorOccurred())
2457 for (
auto &Job :
C.getJobs())
2458 setUpResponseFiles(
C, Job);
2460 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2463 if (FailingCommands.empty())
2469 for (
const auto &CmdPair : FailingCommands) {
2470 int CommandRes = CmdPair.first;
2471 const Command *FailingCommand = CmdPair.second;
2476 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2480 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2485 if (CommandRes == EX_IOERR) {
2505 if (CommandRes > 128 && CommandRes != 255)
2509 Diag(clang::diag::err_drv_command_signalled)
2512 Diag(clang::diag::err_drv_command_failed)
2520 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2522 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2536 const ToolChain &TC =
C.getDefaultToolChain();
2540 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2543 OS <<
"Thread model: " << A->getValue();
2549 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2554 if (!llvm::cl::getCompilerBuildConfig().empty())
2555 llvm::cl::printBuildConfig(OS);
2558 for (
auto ConfigFile : ConfigFiles)
2559 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2572 if (PassedFlags ==
"")
2576 std::vector<std::string> SuggestedCompletions;
2577 std::vector<std::string> Flags;
2589 const bool HasSpace = PassedFlags.ends_with(
",");
2593 StringRef TargetFlags = PassedFlags;
2594 while (TargetFlags !=
"") {
2596 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2597 Flags.push_back(std::string(CurFlag));
2602 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2605 const llvm::opt::OptTable &Opts =
getOpts();
2607 Cur = Flags.at(Flags.size() - 1);
2609 if (Flags.size() >= 2) {
2610 Prev = Flags.at(Flags.size() - 2);
2611 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2614 if (SuggestedCompletions.empty())
2615 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2622 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2623 llvm::outs() <<
'\n';
2629 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2633 SuggestedCompletions = Opts.findByPrefix(
2634 Cur, VisibilityMask,
2641 if (S.starts_with(Cur))
2642 SuggestedCompletions.push_back(std::string(S));
2649 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2650 if (
int X = A.compare_insensitive(B))
2652 return A.compare(B) > 0;
2655 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2662 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2663 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2667 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2670 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2674 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2679 if (
C.getArgs().hasArg(options::OPT_help) ||
2680 C.getArgs().hasArg(options::OPT__help_hidden)) {
2681 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2685 if (
C.getArgs().hasArg(options::OPT__version)) {
2692 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2693 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2694 if (ListExtractors || ListFormats) {
2702 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2707 if (
C.getArgs().hasArg(options::OPT_v) ||
2708 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2709 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2710 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2711 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2713 SuppressMissingInputWarning =
true;
2716 if (
C.getArgs().hasArg(options::OPT_v)) {
2718 llvm::errs() <<
"System configuration file directory: "
2721 llvm::errs() <<
"User configuration file directory: "
2725 const ToolChain &TC =
C.getDefaultToolChain();
2727 if (
C.getArgs().hasArg(options::OPT_v))
2730 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2735 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2736 llvm::outs() <<
"programs: =";
2737 bool separator =
false;
2741 llvm::outs() << llvm::sys::EnvPathSeparator;
2742 llvm::outs() << Path;
2747 llvm::outs() << llvm::sys::EnvPathSeparator;
2748 llvm::outs() << Path;
2751 llvm::outs() <<
"\n";
2754 StringRef sysroot =
C.getSysRoot();
2758 llvm::outs() << llvm::sys::EnvPathSeparator;
2761 llvm::outs() << sysroot << Path.substr(1);
2763 llvm::outs() << Path;
2765 llvm::outs() <<
"\n";
2769 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib)) {
2774 if (
C.getArgs().hasArg(options::OPT_print_cxx_stdlib_include_dirs)) {
2779 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2785 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2786 for (
auto RuntimePath :
2788 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2789 llvm::outs() << *RuntimePath <<
'\n';
2793 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2797 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2799 for (std::size_t I = 0; I != Flags.size(); I += 2)
2800 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2806 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2807 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2811 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2812 StringRef ProgName = A->getValue();
2815 if (! ProgName.empty())
2818 llvm::outs() <<
"\n";
2822 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2823 StringRef PassedFlags = A->getValue();
2828 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2838 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2843 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2846 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2852 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2859 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2862 std::set<llvm::StringRef> SortedFlags;
2863 for (
const auto &FlagEntry : ExpandedFlags)
2864 SortedFlags.insert(FlagEntry.getKey());
2865 for (
auto Flag : SortedFlags)
2866 llvm::outs() << Flag <<
'\n';
2870 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2873 llvm::outs() <<
".\n";
2876 assert(Suffix.front() ==
'/');
2877 llvm::outs() << Suffix.substr(1) <<
"\n";
2883 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2888 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2890 llvm::outs() << Triple.getTriple() <<
"\n";
2894 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2895 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2912 std::map<Action *, unsigned> &Ids,
2914 if (
auto It = Ids.find(A); It != Ids.end())
2918 llvm::raw_string_ostream os(str);
2920 auto getSibIndent = [](
int K) -> Twine {
2924 Twine SibIndent =
Indent + getSibIndent(Kind);
2928 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2930 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2931 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2932 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2934 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2935 assert(TC &&
"Unknown host toolchain");
2950 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2958 const char *Prefix =
"{";
2959 for (
Action *PreRequisite : *AL) {
2960 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2971 std::string offload_str;
2972 llvm::raw_string_ostream offload_os(offload_str);
2976 offload_os <<
", (" << S;
2983 auto getSelfIndent = [](
int K) -> Twine {
2987 unsigned Id = Ids.size();
2989 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2998 std::map<Action *, unsigned> Ids;
2999 for (
Action *A :
C.getActions())
3015 DerivedArgList &Args =
C.getArgs();
3017 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
3020 llvm::StringSet<> ArchNames;
3022 for (Arg *A : Args) {
3023 if (A->getOption().matches(options::OPT_arch)) {
3026 llvm::Triple::ArchType
Arch =
3028 if (
Arch == llvm::Triple::UnknownArch) {
3029 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
3034 if (ArchNames.insert(A->getValue()).second)
3035 Archs.push_back(A->getValue());
3049 for (
Action* Act : SingleActions) {
3057 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
3061 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
3066 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
3067 Actions.append(Inputs.begin(), Inputs.end());
3069 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
3072 Arg *A = Args.getLastArg(options::OPT_g_Group);
3073 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
3074 !A->getOption().matches(options::OPT_gstabs);
3075 bool enablesPseudoProbe =
3076 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
3077 options::OPT_fno_pseudo_probe_for_profiling,
false);
3078 bool enablesDebugInfoForProfiling =
3079 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
3080 options::OPT_fno_debug_info_for_profiling,
false);
3081 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
3082 enablesDebugInfoForProfiling) &&
3090 if (Act->getType() == types::TY_Image) {
3092 Inputs.push_back(Actions.back());
3099 if (Args.hasArg(options::OPT_verify_debug_info)) {
3100 Action *LastAction = Actions.pop_back_val();
3102 LastAction, types::TY_Nothing));
3109 bool TypoCorrect)
const {
3121 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3122 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3134 std::string Nearest;
3135 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3136 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3137 <<
Value << Nearest;
3176 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3179 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3187 return types::TY_CXXUHeader;
3189 return types::TY_CXXSHeader;
3193 llvm_unreachable(
"should not be called in this case");
3195 return types::TY_CXXHUHeader;
3201 const llvm::opt::OptTable &Opts =
getOpts();
3205 types::ID InputType = types::TY_Nothing;
3206 Arg *InputTypeArg =
nullptr;
3209 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3210 options::OPT__SLASH_TP)) {
3211 InputTypeArg = TCTP;
3212 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3217 bool ShowNote =
false;
3219 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3221 Diag(clang::diag::warn_drv_overriding_option)
3222 <<
Previous->getSpelling() << A->getSpelling();
3228 Diag(clang::diag::note_drv_t_option_is_global);
3233 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3234 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3235 if (LastXArg && LastInputArg &&
3236 LastInputArg->getIndex() < LastXArg->getIndex())
3237 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3240 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3242 for (Arg *A : Args) {
3243 if (A->getOption().
getKind() == Option::InputClass) {
3244 const char *
Value = A->getValue();
3248 if (InputType == types::TY_Nothing) {
3251 InputTypeArg->claim();
3254 if (strcmp(
Value,
"-") == 0) {
3256 Ty = types::TY_Fortran;
3258 Ty = types::TY_HLSL;
3259 }
else if (IsSYCL) {
3269 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3270 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3271 : clang::diag::err_drv_unknown_stdin_type);
3280 if (
const char *Ext = strrchr(
Value,
'.'))
3289 Ty = types::TY_HLSL;
3291 Ty = types::TY_Object;
3302 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3303 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3304 << getTypeName(OldTy) << getTypeName(Ty);
3309 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3310 Ty == types::TY_Object)
3311 Ty = types::TY_LLVM_BC;
3319 if (Ty != types::TY_Object) {
3320 if (Args.hasArg(options::OPT_ObjC))
3321 Ty = types::TY_ObjC;
3322 else if (Args.hasArg(options::OPT_ObjCXX))
3323 Ty = types::TY_ObjCXX;
3330 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3334 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3335 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3338 const char *Ext = strrchr(
Value,
'.');
3340 Ty = types::TY_Object;
3344 InputTypeArg->claim();
3348 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3349 Args.hasArgNoClaim(options::OPT_hipstdpar))
3353 Inputs.push_back(std::make_pair(Ty, A));
3355 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3356 StringRef
Value = A->getValue();
3359 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3360 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3363 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3364 StringRef
Value = A->getValue();
3367 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3368 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3374 Inputs.push_back(std::make_pair(types::TY_Object, A));
3376 }
else if (A->getOption().matches(options::OPT_x)) {
3385 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3386 InputType = types::TY_Object;
3393 }
else if (A->getOption().getID() == options::OPT_U) {
3394 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3395 StringRef Val = A->getValue(0);
3396 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3398 Diag(diag::warn_slash_u_filename) << Val;
3399 Diag(diag::note_use_dashdash);
3403 if (
CCCIsCPP() && Inputs.empty()) {
3407 Inputs.push_back(std::make_pair(types::TY_C, A));
3411void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3416 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
3417 StringRef
V = A->getValue();
3418 if (Inputs.size() > 1 && !
V.empty() &&
3419 !llvm::sys::path::is_separator(
V.back())) {
3421 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3422 << A->getSpelling() <<
V;
3423 Args.eraseArg(options::OPT__SLASH_Fo);
3428 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
3429 StringRef
V = A->getValue();
3430 if (Inputs.size() > 1 && !
V.empty() &&
3431 !llvm::sys::path::is_separator(
V.back())) {
3433 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3434 << A->getSpelling() <<
V;
3435 Args.eraseArg(options::OPT__SLASH_Fa);
3440 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
3441 if (A->getValue()[0] ==
'\0') {
3443 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
3444 Args.eraseArg(options::OPT__SLASH_o);
3449 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3450 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3451 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3452 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3453 Args.eraseArg(options::OPT__SLASH_Yc);
3454 Args.eraseArg(options::OPT__SLASH_Yu);
3455 YcArg = YuArg =
nullptr;
3457 if (YcArg && Inputs.size() > 1) {
3458 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3459 Args.eraseArg(options::OPT__SLASH_Yc);
3467 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3468 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3469 Args.AddFlagArg(
nullptr,
3470 getOpts().getOption(options::OPT_frtlib_add_rpath));
3474 if (Args.hasArg(options::OPT_emit_llvm) &&
3475 !Args.hasArg(options::OPT_hip_link) &&
3476 !
C.getDefaultToolChain().getTriple().isSPIRV())
3477 Diag(clang::diag::err_drv_emit_llvm_link);
3478 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
3479 C.getDefaultToolChain().isUsingLTO(Args) &&
3480 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
3481 .starts_with_insensitive(
"lld"))
3482 Diag(clang::diag::err_drv_lto_without_lld);
3488 if (!Args.hasArg(options::OPT_dumpdir)) {
3489 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
3490 Arg *Arg = Args.MakeSeparateArg(
3491 nullptr,
getOpts().getOption(options::OPT_dumpdir),
3493 (FinalOutput ? FinalOutput->getValue()
3505 Args.eraseArg(options::OPT__SLASH_Fp);
3506 Args.eraseArg(options::OPT__SLASH_Yc);
3507 Args.eraseArg(options::OPT__SLASH_Yu);
3508 YcArg = YuArg =
nullptr;
3511 if (Args.hasArg(options::OPT_include_pch) &&
3512 Args.hasArg(options::OPT_ignore_pch)) {
3516 Args.eraseArg(options::OPT_include_pch);
3519 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
3520 for (
auto &I : Inputs) {
3522 const Arg *InputArg = I.second;
3527 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
3531 if (InitialPhase > FinalPhase) {
3532 if (InputArg->isClaimed())
3539 if (Args.hasArg(options::OPT_Qunused_arguments))
3545 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3546 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3550 (Args.getLastArg(options::OPT__SLASH_EP,
3551 options::OPT__SLASH_P) ||
3552 Args.getLastArg(options::OPT_E) ||
3553 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3555 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3556 << InputArg->getAsString(Args) << !!FinalPhaseArg
3557 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
3559 Diag(clang::diag::warn_drv_input_file_unused)
3560 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3562 << (FinalPhaseArg ? FinalPhaseArg->getSpelling() :
"");
3571 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
3572 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
3577 Actions.push_back(ClangClPch);
3589 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3590 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3598 const llvm::opt::DerivedArgList &Args,
3601 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
3603 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
3606 bool HasAMDGCNHIPDevice =
false;
3608 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
3610 const llvm::Triple &Tr = TC->
getTriple();
3613 HasAMDGCNHIPDevice =
true;
3615 return HasAMDGCNHIPDevice;
3620 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
3622 if (!SuppressMissingInputWarning && Inputs.empty()) {
3623 Diag(clang::diag::err_drv_no_input_files);
3627 handleArguments(
C, Args, Inputs, Actions);
3632 if (Arg *A = Args.getLastArg(options::OPT_no_offload_new_driver))
3633 Diag(clang::diag::warn_drv_deprecated_custom)
3634 << A->getAsString(Args)
3635 <<
"the legacy offloading driver has been removed";
3636 Args.ClaimAllArgs(options::OPT_no_offload_new_driver);
3637 Args.ClaimAllArgs(options::OPT_offload_new_driver);
3639 bool HIPRDCDeviceOnlyFatBin =
3641 Args.hasArg(options::OPT_hip_link) &&
3642 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
3644 !Args.hasArg(options::OPT_emit_llvm) &&
3645 Args.hasFlag(options::OPT_gpu_bundle_output,
3646 options::OPT_no_gpu_bundle_output,
true);
3653 for (
auto &I : Inputs) {
3655 const Arg *InputArg = I.second;
3667 if (HIPRDCDeviceOnlyFatBin && InputType == types::TY_LLVM_BC) {
3668 LinkerInputs.push_back(Current);
3674 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
3686 assert(Phase == PL.back() &&
"linking must be final compilation step.");
3689 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
3690 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
3692 LinkerInputs.push_back(Current);
3702 assert(Phase == PL.back() &&
"merging must be final compilation step.");
3703 MergerInputs.push_back(Current);
3720 C.getDefaultToolChain().getLTOMode(Args));
3723 if (NewCurrent == Current)
3726 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
3729 Current = NewCurrent;
3734 &HIPAsmDeviceActions);
3736 if (Current->
getType() == types::TY_Nothing)
3742 if (Current && !HIPAsmDeviceActions.empty()) {
3744 BundleInputs.append(HIPAsmDeviceActions);
3745 BundleInputs.push_back(Current);
3751 Actions.push_back(Current);
3758 if (!LinkerInputs.empty()) {
3764 Args.hasArg(options::OPT_offload_link)) {
3767 HIPRDCDeviceOnlyFatBin ? types::TY_HIP_FATBIN : types::TY_Image);
3774 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
3775 C.getDefaultToolChain().getTriple().isSPIRV();
3776 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
3780 Actions.push_back(LA);
3784 if (!MergerInputs.empty())
3788 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
3795 for (
auto &I : Inputs) {
3797 const Arg *InputArg = I.second;
3802 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
3803 InputType == types::TY_Asm)
3808 for (
auto Phase : PhaseList) {
3812 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
3817 if (InputType == types::TY_Object)
3824 assert(Phase == PhaseList.back() &&
3825 "merging must be final compilation step.");
3826 MergerInputs.push_back(Current);
3835 Actions.push_back(Current);
3839 if (!MergerInputs.empty())
3844 for (
auto Opt : {options::OPT_print_supported_cpus,
3845 options::OPT_print_supported_extensions,
3846 options::OPT_print_enabled_extensions}) {
3853 if (Arg *A = Args.getLastArg(Opt)) {
3854 if (Opt == options::OPT_print_supported_extensions &&
3855 !
C.getDefaultToolChain().getTriple().isRISCV() &&
3856 !
C.getDefaultToolChain().getTriple().isAArch64() &&
3857 !
C.getDefaultToolChain().getTriple().isARM()) {
3858 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
3859 <<
"--print-supported-extensions";
3862 if (Opt == options::OPT_print_enabled_extensions &&
3863 !
C.getDefaultToolChain().getTriple().isRISCV() &&
3864 !
C.getDefaultToolChain().getTriple().isAArch64()) {
3865 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
3866 <<
"--print-enabled-extensions";
3873 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
3876 for (
auto &I : Inputs)
3881 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
3882 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
3883 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
3889 if (TC.requiresObjcopy(Args)) {
3890 Action *LastAction = Actions.back();
3892 if (LastAction->
getType() == types::TY_Object) {
3900 auto ValInfo = TC.getValidationInfo(Args);
3901 if (ValInfo.NeedsValidation) {
3902 Action *LastAction = Actions.back();
3903 if (LastAction->
getType() == types::TY_Object) {
3905 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
3912 if (TC.requiresBinaryTranslation(Args)) {
3913 Action *LastAction = Actions.back();
3917 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
3918 LastAction->
getType() == types::TY_Object)
3920 LastAction, types::TY_DX_CONTAINER));
3925 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
3931 const llvm::opt::DerivedArgList &Args,
3933 const llvm::Triple &Triple) {
3938 if (Triple.isNVPTX() && (
Arch.isUnknown() || !
Arch.isNVPTX())) {
3939 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3940 <<
"CUDA" << ArchStr;
3942 }
else if (Triple.isAMDGPU()) {
3943 if (
Arch.isUnknown() || (!
Arch.isAMDGPU() && !
Arch.isAMDGCNSPIRV())) {
3944 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
3945 <<
"HIP" << ArchStr;
3949 if (Triple.getSubArch() != llvm::Triple::NoSubArch) {
3951 if (ArchSubArch != Triple.getSubArch() &&
3952 llvm::AMDGPU::getMajorSubArch(ArchSubArch) != Triple.getSubArch()) {
3953 C.getDriver().Diag(clang::diag::err_target_unsupported_arch)
3954 << ArchStr << Triple.getArchName();
3963 if (
Arch.isAMDGPU() ||
Arch.isAMDGCNSPIRV()) {
3964 llvm::StringMap<bool> Features;
3967 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
3979static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3981 llvm::Triple Triple) {
3982 if (!Triple.isAMDGPU())
3983 return std::nullopt;
3985 std::set<StringRef> ArchSet;
3986 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
3990llvm::SmallVector<BoundArch>
3994 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3995 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3996 options::OPT_no_offload_arch_EQ)) {
3997 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3999 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4001 :
"--no-offload-arch");
4004 llvm::DenseSet<StringRef> Archs;
4005 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
4008 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4009 for (StringRef
Arch : Arg->getValues()) {
4010 if (
Arch ==
"native" ||
Arch.empty()) {
4015 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4019 for (
auto ArchStr : *GPUsOrErr) {
4021 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4022 if (!CanonicalStr.empty())
4023 Archs.insert(CanonicalStr);
4028 StringRef CanonicalStr =
4030 if (!CanonicalStr.empty())
4031 Archs.insert(CanonicalStr);
4036 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4037 for (StringRef
Arch : Arg->getValues()) {
4038 if (
Arch ==
"all") {
4043 Archs.erase(ArchStr);
4049 if (
auto ConflictingArchs =
4051 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4052 << ConflictingArchs->first << ConflictingArchs->second;
4055 bool HasSubArch = TC.
getTriple().isAMDGCN() &&
4056 TC.
getTriple().getSubArch() != llvm::Triple::NoSubArch;
4057 if (Archs.empty() && !HasSubArch) {
4067 Archs.insert(StringRef());
4070 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
4071 .getLastArg(options::OPT_march_EQ)) {
4072 Archs.insert(Arg->getValue());
4077 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4078 <<
"--offload-arch";
4079 }
else if (!ArchsOrErr->empty()) {
4080 for (
auto Arch : *ArchsOrErr)
4081 Archs.insert(Args.MakeArgStringRef(
Arch));
4083 Archs.insert(StringRef());
4087 }
else if (Archs.empty() && HasSubArch) {
4094 llvm::StringRef ArchStr = TripleOffloadArch.
isUnknown()
4097 StringRef CanonicalStr =
4099 if (!CanonicalStr.empty())
4100 Archs.insert(CanonicalStr);
4103 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4104 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4111 Result.reserve(Sorted.size());
4112 for (StringRef
Arch : Sorted)
4119 const InputTy &Input, StringRef CUID,
4129 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4134 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4137 bool HIPRelocatableObj =
4139 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4140 options::OPT_fno_hip_emit_relocatable,
false);
4142 if (!HIPNoRDC && HIPRelocatableObj)
4143 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4144 <<
"-fhip-emit-relocatable"
4148 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4149 <<
"-fhip-emit-relocatable"
4150 <<
"--offload-device-only";
4158 bool UsesLLVMOffloading = Args.hasArg(
4159 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
4171 auto TCRange =
C.getOffloadToolChains(Kind);
4172 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4173 ToolChains.push_back(TI->second);
4175 if (ToolChains.empty())
4179 const Arg *InputArg = Input.second;
4188 for (
const ToolChain *TC : ToolChains) {
4190 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4191 DeviceActions.push_back(
4192 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4196 if (DeviceActions.empty())
4202 HostAction->
getType() != types::TY_Nothing &&
4212 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4221 auto *TCAndArch = TCAndArchs.begin();
4222 for (
Action *&A : DeviceActions) {
4223 if (A->
getType() == types::TY_Nothing)
4230 TCAndArch->first->getLTOMode(Args, Kind));
4234 HostAction->
getType() != types::TY_Nothing) {
4241 TCAndArch->second, Kind);
4243 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4253 for (
Action *&A : DeviceActions) {
4258 OffloadTriple && OffloadTriple->isSPIRV() &&
4259 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
4260 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
4262 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
4263 A->
getType() != types::TY_LTO_BC) ||
4270 auto *TCAndArch = TCAndArchs.begin();
4271 for (
Action *A : DeviceActions) {
4272 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4274 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
4281 A->
getType() == types::TY_Object &&
4282 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4284 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
4293 bool ShouldBundleHIP =
4294 Args.hasFlag(options::OPT_gpu_bundle_output,
4295 options::OPT_no_gpu_bundle_output,
false) ||
4296 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
4298 return A->
getType() != types::TY_Image;
4309 if (OffloadActions.empty())
4314 (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) ||
4315 Args.hasArg(options::OPT_cuda_emit_nvcc_abi))) {
4319 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4326 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4327 DDep.
add(*FatbinAction,
4330 }
else if ((!UsesLLVMOffloading && HIPNoRDC) || SYCLNoRDC) {
4333 if (HIPNoRDC && HIPAsmBundleDeviceOut &&
4335 for (
Action *OA : OffloadActions)
4336 HIPAsmBundleDeviceOut->push_back(OA);
4349 SYCLNoRDC ? types::TY_SYCL_FATBIN : types::TY_HIP_FATBIN;
4352 DDep.
add(*PackagerAction, *
C.getOffloadToolChains(Kind).first->second,
4360 {},
C.getActiveOffloadKinds());
4369 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4370 return A->
getType() == types::TY_Nothing;
4374 {}, SingleDeviceOutput ? DDep : DDeps);
4375 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4381 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4391 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4397 llvm_unreachable(
"link action invalid here.");
4399 llvm_unreachable(
"ifsmerge action invalid here.");
4404 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4405 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4406 OutputTy = types::TY_Dependencies;
4411 if (!Args.hasFlag(options::OPT_frewrite_includes,
4412 options::OPT_fno_rewrite_includes,
false) &&
4413 !Args.hasFlag(options::OPT_frewrite_imports,
4414 options::OPT_fno_rewrite_imports,
false) &&
4415 !Args.hasFlag(options::OPT_fdirectives_only,
4416 options::OPT_fno_directives_only,
false) &&
4420 "Cannot preprocess this input type!");
4426 if (Args.hasArg(options::OPT_extract_api))
4431 if (Input->
getType() == types::TY_CXXStdModule ||
4432 Input->
getType() == types::TY_PP_CXXStdModule)
4434 Input, getPrecompiledType(Input->
getType()));
4442 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
4443 (Input->
getType() == driver::types::TY_CXXModule ||
4444 Input->
getType() == driver::types::TY_PP_CXXModule) &&
4445 !Args.getLastArg(options::OPT__precompile) &&
4446 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
4451 "Cannot precompile this input type!");
4455 const char *ModName =
nullptr;
4456 if (OutputTy == types::TY_PCH) {
4457 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4458 ModName = A->getValue();
4460 OutputTy = types::TY_ModuleFile;
4463 if (Args.hasArg(options::OPT_fsyntax_only)) {
4465 OutputTy = types::TY_Nothing;
4471 if (Args.hasArg(options::OPT_fsyntax_only))
4473 if (Args.hasArg(options::OPT_rewrite_objc))
4475 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4477 types::TY_RewrittenLegacyObjC);
4478 if (Args.hasArg(options::OPT__analyze))
4480 if (Args.hasArg(options::OPT_emit_ast))
4482 if (Args.hasArg(options::OPT_emit_cir))
4484 if (Args.hasArg(options::OPT_module_file_info))
4486 if (Args.hasArg(options::OPT_verify_pch))
4488 if (Args.hasArg(options::OPT_extract_api))
4495 if (!IsDeviceOffload) {
4497 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4498 !Args.hasArg(options::OPT_emit_llvm))
4499 Output = types::TY_PP_Asm;
4500 else if (Args.hasArg(options::OPT_S))
4501 Output = types::TY_LTO_IR;
4503 Output = types::TY_LTO_BC;
4507 if (Args.hasArg(options::OPT_emit_llvm)) {
4509 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4511 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4515 Output = types::TY_PP_Asm;
4516 }
else if (Args.hasArg(options::OPT_S)) {
4517 Output = types::TY_LTO_IR;
4519 Output = types::TY_LTO_BC;
4523 if (Args.hasArg(options::OPT_emit_llvm) ||
4526 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
4535 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
4536 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
4547 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4569 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
4589 if (!OffloadJobs.isValid())
4590 D.
Diag(diag::err_drv_invalid_int_value)
4591 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
4593 OffloadJobs.A->claim();
4597 for (
auto &Job :
C.getJobs()) {
4601 Job.setOffloadDeviceParallelJobGroup(
4607 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4609 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4629 unsigned NumOutputs = 0;
4630 unsigned NumIfsOutputs = 0;
4631 for (
const Action *A :
C.getActions()) {
4641 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
4642 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
4645 if (A->
getType() != types::TY_Nothing &&
4647 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4649 0 == NumIfsOutputs++) ||
4654 A->
getType() == types::TY_Nothing &&
4655 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4656 NumOutputs += A->
size();
4659 if (NumOutputs > 1) {
4660 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4661 FinalOutput =
nullptr;
4665 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4668 llvm::StringSet<> ArchNames;
4669 if (RawTriple.isOSBinFormatMachO())
4670 for (
const Arg *A :
C.getArgs())
4671 if (A->getOption().matches(options::OPT_arch))
4672 ArchNames.insert(A->getValue());
4675 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4676 for (
Action *A :
C.getActions()) {
4683 const char *LinkingOutput =
nullptr;
4686 LinkingOutput = FinalOutput->getValue();
4694 ArchNames.size() > 1 ||
4695 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
4696 LinkingOutput, CachedResults,
4703 for (
auto &J :
C.getJobs())
4704 J.InProcess =
false;
4711 C.setPostCallback([=](
const Command &Cmd,
int Res) {
4712 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4717 const char *LinkingOutput =
nullptr;
4719 LinkingOutput = FinalOutput->getValue();
4726 using namespace llvm;
4729 <<
"output=" << LinkingOutput;
4730 outs() <<
", total="
4731 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4733 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4734 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4738 llvm::raw_string_ostream Out(Buffer);
4739 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
4742 llvm::sys::printArg(Out, LinkingOutput,
true);
4743 Out <<
',' << ProcStat->TotalTime.count() <<
','
4744 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4749 llvm::sys::fs::OF_Append |
4750 llvm::sys::fs::OF_Text);
4755 llvm::errs() <<
"ERROR: Cannot lock file "
4757 <<
toString(L.takeError()) <<
"\n";
4768 bool ReportUnusedArguments =
4769 !Diags.hasErrorOccurred() &&
4770 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
4773 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
4775 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
4778 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
4779 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
4781 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
4785 return strstr(J.getCreator().getShortName(),
"assembler");
4787 for (Arg *A :
C.getArgs()) {
4791 if (!A->isClaimed()) {
4797 const Option &Opt = A->getOption();
4798 if (Opt.getKind() == Option::FlagClass) {
4799 bool DuplicateClaimed =
false;
4801 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
4802 if (AA->isClaimed()) {
4803 DuplicateClaimed =
true;
4808 if (DuplicateClaimed)
4814 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
4816 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
4821 !
C.getActions().empty()) {
4822 Diag(diag::err_drv_unsupported_opt_for_target)
4824 }
else if (ReportUnusedArguments) {
4825 Diag(clang::diag::warn_drv_unused_argument)
4826 << A->getAsString(
C.getArgs());
4836class ToolSelector final {
4847 bool IsHostSelector;
4858 bool CanBeCollapsed =
true) {
4860 if (Inputs.size() != 1)
4863 Action *CurAction = *Inputs.begin();
4864 if (CanBeCollapsed &&
4870 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
4874 if (!IsHostSelector) {
4875 if (OA->hasSingleDeviceDependence(
true)) {
4877 OA->getSingleDeviceDependence(
true);
4878 if (CanBeCollapsed &&
4881 SavedOffloadAction.push_back(OA);
4882 return dyn_cast<JobAction>(CurAction);
4884 }
else if (OA->hasHostDependence()) {
4885 CurAction = OA->getHostDependence();
4886 if (CanBeCollapsed &&
4889 SavedOffloadAction.push_back(OA);
4890 return dyn_cast<JobAction>(CurAction);
4895 return dyn_cast<JobAction>(CurAction);
4899 bool canCollapseAssembleAction()
const {
4900 return TC.useIntegratedAs() && !SaveTemps &&
4901 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
4902 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
4903 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
4904 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
4908 bool canCollapsePreprocessorAction()
const {
4909 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
4910 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
4911 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
4916 struct JobActionInfo final {
4918 const JobAction *JA =
nullptr;
4926 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
4927 ArrayRef<JobActionInfo> &ActionInfo,
4928 unsigned ElementNum) {
4929 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
4930 for (
unsigned I = 0; I < ElementNum; ++I)
4931 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
4932 ActionInfo[I].SavedOffloadAction.end());
4945 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
4948 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
4950 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4951 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4952 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
4953 if (!AJ || !BJ || !CJ)
4957 const Tool *
T = TC.SelectTool(*CJ);
4964 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
4970 const Tool *BT = TC.SelectTool(*BJ);
4975 if (!
T->hasIntegratedAssembler())
4978 Inputs = CJ->getInputs();
4979 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4983 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
4986 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
4988 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4989 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4994 const Tool *
T = TC.SelectTool(*BJ);
4998 if (!
T->hasIntegratedAssembler())
5001 Inputs = BJ->getInputs();
5002 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5006 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5009 if (ActionInfo.size() < 2)
5011 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5012 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5016 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5017 for (
auto &Input : AI.JA->getInputs())
5028 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5029 if (SaveTemps && !InputIsBitcode)
5033 const Tool *
T = TC.SelectTool(*CJ);
5040 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5046 Inputs = CJ->getInputs();
5047 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5056 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5058 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5064 for (Action *A : Inputs) {
5065 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5067 NewInputs.push_back(A);
5073 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5074 PreprocessJobOffloadActions.end());
5075 NewInputs.append(PJ->input_begin(), PJ->input_end());
5081 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5083 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5085 assert(BaseAction &&
"Invalid base action.");
5101 SmallVector<JobActionInfo, 5> ActionChain(1);
5102 ActionChain.back().JA = BaseAction;
5103 while (ActionChain.back().JA) {
5104 const Action *CurAction = ActionChain.back().JA;
5107 ActionChain.resize(ActionChain.size() + 1);
5108 JobActionInfo &AI = ActionChain.back();
5112 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5116 ActionChain.pop_back();
5124 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5125 CollapsedOffloadAction);
5127 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5129 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5135 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5148 std::string TriplePlusArch = TC->
getTriple().normalize();
5150 TriplePlusArch +=
"-";
5153 TriplePlusArch +=
"-";
5155 return TriplePlusArch;
5160 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5161 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5164 std::pair<const Action *, std::string> ActionTC = {
5166 auto CachedResult = CachedResults.find(ActionTC);
5167 if (CachedResult != CachedResults.end()) {
5168 return CachedResult->second;
5171 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
5172 TargetDeviceOffloadKind);
5173 CachedResults[ActionTC] =
Result;
5178 const JobAction *JA,
const char *BaseInput,
5181 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5192 if (!
Arch.empty()) {
5193 OffloadingPrefix +=
"-";
5194 OffloadingPrefix +=
Arch.ArchName;
5197 C.getDriver().isSaveTempsEnabled()) {
5204 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5205 Path = A->getValue();
5206 if (llvm::sys::fs::is_directory(Path)) {
5208 ? llvm::sys::path::stem(
Result.getFilename())
5209 : llvm::sys::path::stem(BaseInput));
5210 Tmp += OffloadingPrefix;
5212 llvm::sys::path::append(Path, Tmp);
5215 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5218 Path = DumpDir->getValue();
5219 Path += llvm::sys::path::stem(BaseInput);
5220 Path += OffloadingPrefix;
5222 }
else if (!OffloadingPrefix.empty()) {
5226 TraceName += OffloadingPrefix;
5227 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
5228 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
5229 llvm::sys::path::append(Path, TraceName);
5232 Path =
Result.getFilename();
5233 llvm::sys::path::replace_extension(Path,
"json");
5236 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5237 C.addTimeTraceFile(ResultFile, JA);
5238 C.addResultFile(ResultFile, JA);
5243 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5244 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5247 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5251 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
5252 C.setCurrentBoundArch(BA);
5253 auto RestoreBoundArch =
5254 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
5257 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5258 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5290 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5292 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5293 BoundArch DepBoundArch) {
5295 !DepBoundArch.
empty(),
5296 LinkingOutput, CachedResults,
5306 OA->doOnEachDependence(
5307 BuildingForOffloadDevice,
5308 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5310 C, DepA, DepTC, DepBoundArch,
false,
5311 !DepBoundArch.
empty(), LinkingOutput,
5315 A = BuildingForOffloadDevice
5316 ? OA->getSingleDeviceDependence(
true)
5317 : OA->getHostDependence();
5321 std::pair<const Action *, std::string> ActionTC = {
5322 OA->getHostDependence(),
5324 auto It = CachedResults.find(ActionTC);
5325 if (It != CachedResults.end()) {
5327 Inputs.append(OffloadDependencesInputInfo);
5332 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5335 const Arg &Input = IA->getInputArg();
5337 if (Input.getOption().matches(options::OPT_INPUT)) {
5338 const char *
Name = Input.getValue();
5341 return {InputInfo(A, &Input,
"")};
5344 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5345 const ToolChain *TC;
5346 BoundArch ArchName = BAA->
getArch();
5348 if (!ArchName.
empty())
5349 TC = &getToolChain(
C.getArgs(),
5353 TC = &
C.getDefaultToolChain();
5356 MultipleArchs, LinkingOutput, CachedResults,
5357 TargetDeviceOffloadKind);
5368 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5371 return {InputInfo()};
5375 for (
const auto *OA : CollapsedOffloadActions)
5377 BuildingForOffloadDevice,
5378 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
5380 C, DepA, DepTC, DepBoundArch,
false,
5381 !DepBoundArch.
empty(), LinkingOutput,
5387 for (
const Action *Input : Inputs) {
5391 bool SubJobAtTopLevel =
5394 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5399 const char *BaseInput = InputInfos[0].getBaseInput();
5400 for (
auto &Info : InputInfos) {
5401 if (Info.isFilename()) {
5402 BaseInput = Info.getBaseInput();
5409 if (JA->
getType() == types::TY_dSYM)
5410 BaseInput = InputInfos[0].getFilename();
5413 if (!OffloadDependencesInputInfo.empty())
5414 InputInfos.append(OffloadDependencesInputInfo.begin(),
5415 OffloadDependencesInputInfo.end());
5418 llvm::Triple EffectiveTriple;
5419 const ToolChain &ToolTC =
T->getToolChain();
5420 const ArgList &Args =
5422 if (InputInfos.size() != 1) {
5427 EffectiveTriple = llvm::Triple(
5430 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
5434 if (JA->
getType() == types::TY_Nothing)
5435 Result = {InputInfo(A, BaseInput)};
5446 MultipleArchs, OffloadingPrefix),
5453 llvm::errs() <<
"# \"" <<
T->getToolChain().getEffectiveTriple().str()
5454 <<
'"' <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5455 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5456 llvm::errs() << InputInfos[i].getAsString();
5458 llvm::errs() <<
", ";
5460 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5462 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5468 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5469 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5481 if (ArgValue.empty()) {
5483 Filename = BaseName;
5484 }
else if (llvm::sys::path::is_separator(Filename.back())) {
5486 llvm::sys::path::append(Filename, BaseName);
5489 if (!llvm::sys::path::has_extension(ArgValue)) {
5494 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5499 llvm::sys::path::replace_extension(Filename, Extension);
5502 return Args.MakeArgString(Filename.c_str());
5517 StringRef Suffix,
bool MultipleArchs,
5518 StringRef BoundArchStr,
5519 bool NeedUniqueDirectory)
const {
5521 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5522 std::optional<std::string> CrashDirectory =
5524 ? std::string(A->getValue())
5525 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5526 if (CrashDirectory) {
5527 if (!
getVFS().exists(*CrashDirectory))
5528 llvm::sys::fs::create_directories(*CrashDirectory);
5530 llvm::sys::path::append(Path, Prefix);
5531 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5532 if (std::error_code EC =
5533 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
5534 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5538 if (MultipleArchs && !BoundArchStr.empty()) {
5539 if (NeedUniqueDirectory) {
5541 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
5552 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5567 const char *BaseInput) {
5569 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5570 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5575 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5580 bool AtTopLevel,
bool MultipleArchs,
5581 StringRef OffloadingPrefix)
const {
5584 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5586 auto CreateTempOutputPath = [&](StringRef Prefix) {
5587 const char *Suffix =
5592 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
5593 const bool NeedUniqueDirectory =
5596 Triple.isOSDarwin();
5598 NeedUniqueDirectory);
5603 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
5604 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
5605 StringRef Filename = llvm::sys::path::filename(BaseInput);
5606 StringRef Stem = llvm::sys::path::stem(Filename);
5607 return CreateTempOutputPath(Stem);
5612 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5613 return C.addResultFile(FinalOutput->getValue(), &JA);
5617 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5619 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5621 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5622 NameArg = A->getValue();
5623 return C.addResultFile(
5633 if (JA.
getType() == types::TY_ModuleFile &&
5634 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5638 if (JA.
getType() == types::TY_PP_Asm &&
5639 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5640 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5643 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
5646 if ((JA.
getType() == types::TY_Object &&
5647 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
5648 JA.
getType() == types::TY_DX_CONTAINER) {
5649 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5650 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
5651 C.getDefaultToolChain().getTriple().isSPIRV()) &&
5652 "expected DXIL or SPIR-V triple for HLSL output path");
5657 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
5659 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
5660 StringRef
Name = llvm::sys::path::filename(BaseInput);
5661 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5667 if (JA.
getType() == types::TY_PP_Asm &&
5668 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5669 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5671 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5672 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5673 return C.addResultFile(
5678 if (JA.
getType() == types::TY_API_INFO &&
5679 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5680 C.getArgs().hasArg(options::OPT_o))
5681 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5682 <<
C.getArgs().getLastArgValue(options::OPT_o);
5689 bool SpecifiedModuleOutput =
5690 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5691 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5692 if (MultipleArchs && SpecifiedModuleOutput)
5693 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5698 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5699 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
5705 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5707 StringRef
Name = llvm::sys::path::filename(BaseInput);
5708 return CreateTempOutputPath(
Name.split(
'.').first);
5717 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
5722 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
5723 llvm::sys::path::filename(BasePath));
5724 BaseName = ExternalPath;
5726 BaseName = BasePath;
5728 BaseName = llvm::sys::path::filename(BasePath);
5731 const char *NamedOutput;
5733 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
5734 JA.
getType() == types::TY_LLVM_BC ||
5735 JA.
getType() == types::TY_LLVM_IR) &&
5736 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
5740 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
5744 }
else if (JA.
getType() == types::TY_Image &&
5745 C.getArgs().hasArg(options::OPT__SLASH_Fe,
5746 options::OPT__SLASH_o)) {
5750 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
5754 }
else if (JA.
getType() == types::TY_Image) {
5764 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
5765 options::OPT_fno_gpu_rdc,
false);
5767 if (UseOutExtension) {
5769 llvm::sys::path::replace_extension(Output,
"");
5771 Output += OffloadingPrefix;
5772 if (MultipleArchs && !BoundArchStr.empty()) {
5774 Output.append(BoundArchStr);
5776 if (UseOutExtension)
5778 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
5781 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
5782 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
5783 C.getArgs().hasArg(options::OPT__SLASH_o)) {
5786 .getLastArg(options::OPT__SLASH_o)
5791 const char *Suffix =
5793 assert(Suffix &&
"All types used for output should have a suffix.");
5795 std::string::size_type End = std::string::npos;
5797 End = BaseName.rfind(
'.');
5799 Suffixed += OffloadingPrefix;
5800 if (MultipleArchs && !BoundArchStr.empty()) {
5802 Suffixed.append(BoundArchStr);
5807 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
5808 const llvm::opt::DerivedArgList &Args) {
5821 bool IsLinkerWrapper =
5823 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
5824 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
5825 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
5827 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
5831 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
5835 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
5836 JA.
getType() != types::TY_PCH) {
5837 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5839 llvm::sys::path::remove_filename(TempPath);
5840 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
5841 llvm::sys::path::append(TempPath, OutputFileName);
5842 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
5848 bool SameFile =
false;
5850 llvm::sys::fs::current_path(
Result);
5851 llvm::sys::path::append(
Result, BaseName);
5852 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
5855 StringRef
Name = llvm::sys::path::filename(BaseInput);
5856 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5860 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5866 llvm::sys::path::remove_filename(BasePath);
5867 if (BasePath.empty())
5868 BasePath = NamedOutput;
5870 llvm::sys::path::append(BasePath, NamedOutput);
5871 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
5874 return C.addResultFile(NamedOutput, &JA);
5880 -> std::optional<std::string> {
5883 for (
const auto &
Dir : P) {
5887 llvm::sys::path::append(P,
Name);
5888 if (llvm::sys::fs::exists(Twine(P)))
5889 return std::string(P);
5891 return std::nullopt;
5898 llvm::sys::path::append(R,
Name);
5899 if (llvm::sys::fs::exists(Twine(R)))
5900 return std::string(R);
5903 llvm::sys::path::append(P,
Name);
5904 if (llvm::sys::fs::exists(Twine(P)))
5905 return std::string(P);
5909 if (std::optional<std::string> IntrPath =
5912 llvm::sys::path::append(P,
Name);
5913 if (llvm::sys::fs::exists(P))
5914 return std::string(P);
5919 llvm::sys::path::append(D,
"..",
Name);
5920 if (llvm::sys::fs::exists(Twine(D)))
5921 return std::string(D);
5930 llvm::sys::path::append(R2,
"..",
"..",
Name);
5931 if (llvm::sys::fs::exists(Twine(R2)))
5932 return std::string(R2);
5934 return std::string(
Name);
5937void Driver::generatePrefixedToolNames(
5941 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
5942 Names.emplace_back(
Tool);
5946 llvm::sys::path::append(Dir, Name);
5947 if (llvm::sys::fs::can_execute(Twine(Dir)))
5949 llvm::sys::path::remove_filename(Dir);
5955 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
5960 if (llvm::sys::fs::is_directory(PrefixDir)) {
5963 return std::string(P);
5966 if (llvm::sys::fs::can_execute(Twine(P)))
5967 return std::string(P);
5972 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
5980 for (
const auto &Path : List) {
5983 return std::string(P);
5987 if (llvm::ErrorOr<std::string> P =
5988 llvm::sys::findProgramByName(TargetSpecificExecutable))
5992 return std::string(
Name);
5997 std::string error =
"<NOT PRESENT>";
5999 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6004 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6021 llvm::sys::path::remove_filename(path);
6022 llvm::sys::path::append(path,
"libc++.modules.json");
6023 if (TC.
getVFS().exists(path))
6024 return static_cast<std::string
>(path);
6029 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6032 return evaluate(
"libc++.a").value_or(error);
6036 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6040 llvm::sys::path::remove_filename(path);
6041 llvm::sys::path::append(path,
"libstdc++.modules.json");
6042 if (TC.
getVFS().exists(path))
6043 return static_cast<std::string
>(path);
6048 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6051 return evaluate(
"libstdc++.a").value_or(error);
6060 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6062 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6066 return std::string(Path);
6071 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6073 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6077 return std::string(Path);
6082 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6086 Output = FpArg->getValue();
6090 if (!llvm::sys::path::has_extension(Output))
6093 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6094 Output = YcArg->getValue();
6097 llvm::sys::path::replace_extension(Output,
".pch");
6099 return std::string(Output);
6102const ToolChain &Driver::getOffloadToolChain(
6104 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6105 std::unique_ptr<ToolChain> &TC =
6106 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6107 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6109 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6112 switch (
Target.getOS()) {
6113 case llvm::Triple::CUDA:
6114 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6117 case llvm::Triple::AMDHSA:
6123 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6124 HostTC.get(), Kind);
6132 switch (
Target.getArch()) {
6133 case llvm::Triple::amdgpu:
6134 case llvm::Triple::r600:
6135 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
6136 HostTC.get(), Kind);
6138 case llvm::Triple::spir:
6139 case llvm::Triple::spir64:
6140 case llvm::Triple::spirv:
6141 case llvm::Triple::spirv32:
6142 case llvm::Triple::spirv64:
6145 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6149 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6153 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6157 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6171 return getToolChain(Args,
Target);
6175const ToolChain &Driver::getToolChain(
const ArgList &Args,
6176 const llvm::Triple &
Target)
const {
6178 auto &TC = ToolChains[
Target.str()];
6180 switch (
Target.getOS()) {
6181 case llvm::Triple::AIX:
6182 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6184 case llvm::Triple::Haiku:
6185 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6187 case llvm::Triple::Darwin:
6188 case llvm::Triple::MacOSX:
6189 case llvm::Triple::IOS:
6190 case llvm::Triple::TvOS:
6191 case llvm::Triple::WatchOS:
6192 case llvm::Triple::XROS:
6193 case llvm::Triple::DriverKit:
6194 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6196 case llvm::Triple::DragonFly:
6197 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6199 case llvm::Triple::OpenBSD:
6200 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6202 case llvm::Triple::NetBSD:
6203 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6205 case llvm::Triple::FreeBSD:
6207 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6210 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6212 case llvm::Triple::Linux:
6213 case llvm::Triple::ELFIAMCU:
6214 if (
Target.getArch() == llvm::Triple::hexagon)
6215 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6217 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6218 !
Target.hasEnvironment())
6219 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6222 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6224 else if (
Target.getArch() == llvm::Triple::ve)
6225 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6226 else if (
Target.isOHOSFamily())
6227 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6228 else if (
Target.isWALI())
6229 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6231 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6233 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6235 case llvm::Triple::Fuchsia:
6236 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6238 case llvm::Triple::Managarm:
6239 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6241 case llvm::Triple::Serenity:
6242 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
6244 case llvm::Triple::Solaris:
6245 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6247 case llvm::Triple::CUDA:
6248 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6250 case llvm::Triple::AMDHSA: {
6251 if (
Target.getArch() == llvm::Triple::spirv64) {
6252 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6258 TC = std::make_unique<toolchains::AMDGPUToolChain>(
6260 ShouldLinkDeviceLibs);
6264 case llvm::Triple::AMDPAL:
6265 case llvm::Triple::Mesa3D:
6266 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6268 case llvm::Triple::UEFI:
6269 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6271 case llvm::Triple::Win32:
6272 switch (
Target.getEnvironment()) {
6274 if (
Target.isOSBinFormatELF())
6275 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6276 else if (
Target.isOSBinFormatMachO())
6277 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6279 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6281 case llvm::Triple::GNU:
6282 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6284 case llvm::Triple::Cygnus:
6285 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6287 case llvm::Triple::Itanium:
6288 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6291 case llvm::Triple::MSVC:
6292 case llvm::Triple::UnknownEnvironment:
6293 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6294 .starts_with_insensitive(
"bfd"))
6295 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6299 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6303 case llvm::Triple::PS4:
6304 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6306 case llvm::Triple::PS5:
6307 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6309 case llvm::Triple::Hurd:
6310 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6312 case llvm::Triple::LiteOS:
6313 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6315 case llvm::Triple::ZOS:
6316 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6318 case llvm::Triple::Vulkan:
6319 case llvm::Triple::ShaderModel:
6320 if ((
Target.getArch() == llvm::Triple::spirv32 ||
6321 Target.getArch() == llvm::Triple::spirv64) &&
6323 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6325 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6327 case llvm::Triple::ChipStar:
6328 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
6333 switch (
Target.getArch()) {
6334 case llvm::Triple::tce:
6335 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6337 case llvm::Triple::tcele:
6338 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6340 case llvm::Triple::tcele64:
6342 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
6344 case llvm::Triple::hexagon:
6345 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6348 case llvm::Triple::lanai:
6349 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6351 case llvm::Triple::xcore:
6352 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6354 case llvm::Triple::wasm32:
6355 case llvm::Triple::wasm64:
6356 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6358 case llvm::Triple::avr:
6359 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6361 case llvm::Triple::msp430:
6362 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6364 case llvm::Triple::riscv32:
6365 case llvm::Triple::riscv64:
6366 case llvm::Triple::riscv32be:
6367 case llvm::Triple::riscv64be:
6368 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6370 case llvm::Triple::ve:
6371 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6373 case llvm::Triple::spirv32:
6374 case llvm::Triple::spirv64:
6375 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6377 case llvm::Triple::csky:
6378 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6380 case llvm::Triple::amdgpu:
6381 case llvm::Triple::r600:
6382 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6386 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6387 else if (
Target.isOSBinFormatELF())
6388 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6389 else if (
Target.isAppleFirmware())
6390 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6391 else if (
Target.isAppleMachO())
6392 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6393 else if (
Target.isOSBinFormatMachO())
6394 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6396 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6406 if (JA.
size() != 1 ||
6421 if (JA.
size() != 1 ||
6435 if (Args.hasArg(options::OPT_emit_static_lib))
6446 unsigned &Micro,
bool &HadExtra) {
6449 Major = Minor = Micro = 0;
6453 if (Str.consumeInteger(10, Major))
6457 if (!Str.consume_front(
"."))
6460 if (Str.consumeInteger(10, Minor))
6464 if (!Str.consume_front(
"."))
6467 if (Str.consumeInteger(10, Micro))
6485 unsigned CurDigit = 0;
6486 while (CurDigit < Digits.size()) {
6488 if (Str.consumeInteger(10, Digit))
6490 Digits[CurDigit] = Digit;
6493 if (!Str.consume_front(
"."))
6502llvm::opt::Visibility
6503Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6515const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6531 llvm_unreachable(
"Unhandled Mode");
6535 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6540 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6541 options::OPT_fno_save_optimization_record,
false))
6545 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6546 options::OPT_fno_save_optimization_record,
false))
6550 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6551 options::OPT_fno_save_optimization_record,
false))
6555 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6556 options::OPT_fno_save_optimization_record,
false))
6563 static StringRef OptName =
6565 llvm::StringRef Opt;
6566 for (StringRef Arg : Args) {
6567 if (!Arg.starts_with(OptName))
6573 return Opt.consume_front(OptName) ? Opt :
"";
6580 llvm::BumpPtrAllocator &Alloc,
6581 llvm::vfs::FileSystem *FS) {
6590 for (
const char *F : Args) {
6591 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6593 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6594 RSPQuoting = Windows;
6600 bool MarkEOLs = ClangCLMode;
6602 llvm::cl::TokenizerCallback Tokenizer;
6603 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
6604 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6606 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6608 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6611 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6612 ECtx.setMarkEOLs(MarkEOLs);
6616 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6620 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6621 [](
const char *A) {
return A !=
nullptr; });
6622 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6625 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6626 Args.resize(newEnd - Args.begin());
6630 return llvm::Error::success();
6634 return SavedStrings.insert(S).first->getKeyData();
6668 llvm::StringSet<> &SavedStrings) {
6671 if (Edit[0] ==
'^') {
6672 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6673 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6674 Args.insert(Args.begin() + 1, Str);
6675 }
else if (Edit[0] ==
'+') {
6676 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6677 OS <<
"### Adding argument " << Str <<
" at end\n";
6678 Args.push_back(Str);
6679 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6680 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6681 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6682 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6683 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6685 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6687 if (Args[i] ==
nullptr)
6689 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6691 if (Repl != Args[i]) {
6692 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6696 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6697 auto Option = Edit.substr(1);
6698 for (
unsigned i = 1; i < Args.size();) {
6699 if (Option == Args[i]) {
6700 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6701 Args.erase(Args.begin() + i);
6702 if (Edit[0] ==
'X') {
6703 if (i < Args.size()) {
6704 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6705 Args.erase(Args.begin() + i);
6707 OS <<
"### Invalid X edit, end of command line!\n";
6712 }
else if (Edit[0] ==
'O') {
6713 for (
unsigned i = 1; i < Args.size();) {
6714 const char *A = Args[i];
6718 if (A[0] ==
'-' && A[1] ==
'O' &&
6719 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6720 (
'0' <= A[2] && A[2] <=
'9'))))) {
6721 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6722 Args.erase(Args.begin() + i);
6726 OS <<
"### Adding argument " << Edit <<
" at end\n";
6727 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6729 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6734 const char *OverrideStr,
6735 llvm::StringSet<> &SavedStrings,
6736 StringRef EnvVar, raw_ostream *OS) {
6738 OS = &llvm::nulls();
6740 if (OverrideStr[0] ==
'#') {
6742 OS = &llvm::nulls();
6745 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
6749 const char *S = OverrideStr;
6751 const char *End = ::strchr(S,
' ');
6753 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)
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.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::ArrayRef< InputTy >, llvm::opt::Arg **FinalPhaseArg=nullptr) const
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