60#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/Path.h"
102#include "llvm/Support/PrettyStackTrace.h"
103#include "llvm/Support/Process.h"
104#include "llvm/Support/Program.h"
105#include "llvm/Support/Regex.h"
106#include "llvm/Support/StringSaver.h"
107#include "llvm/Support/VirtualFileSystem.h"
108#include "llvm/Support/raw_ostream.h"
109#include "llvm/TargetParser/Host.h"
110#include "llvm/TargetParser/RISCVISAInfo.h"
123using namespace clang;
126template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
127 return llvm::any_of(Args, [&](Arg *A) {
128 return (A->getOption().matches(options::OPT_x) &&
130 (A->getOption().
getKind() == Option::InputClass &&
131 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
133 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
139 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
140 StringRef UseCUIDStr = A->getValue();
141 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
142 .Case(
"hash", Kind::Hash)
143 .Case(
"random", Kind::Random)
144 .Case(
"none", Kind::None)
145 .Default(Kind::Invalid);
146 if (UseCUID == Kind::Invalid)
147 D.Diag(clang::diag::err_drv_invalid_value)
148 << A->getAsString(Args) << UseCUIDStr;
151 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
152 if (!FixedCUID.empty())
157 llvm::opt::DerivedArgList &Args)
const {
158 std::string CUID = FixedCUID.str();
161 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
165 llvm::MD5::MD5Result
Hash;
166 Hasher.update(InputFile);
167 for (
auto *A : Args) {
168 if (A->getOption().matches(options::OPT_INPUT))
170 Hasher.update(A->getAsString(Args));
173 CUID = llvm::utohexstr(
Hash.low(),
true);
181 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
182 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
189 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
190 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
191 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
194 this->VFS = llvm::vfs::getRealFileSystem();
199 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
202 llvm::sys::path::append(P,
SysRoot);
206#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
207 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
211 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
212 llvm::sys::path::remove_dots(configFileDir,
true);
216#if defined(CLANG_CONFIG_FILE_USER_DIR)
219 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
228void Driver::setDriverMode(StringRef
Value) {
229 static StringRef OptName =
230 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
231 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
232 .Case(
"gcc", GCCMode)
233 .Case(
"g++", GXXMode)
234 .Case(
"cpp", CPPMode)
236 .Case(
"flang", FlangMode)
237 .Case(
"dxc", DXCMode)
241 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
246 bool &ContainsError)
const {
247 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
248 ContainsError =
false;
250 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
251 unsigned MissingArgIndex, MissingArgCount;
252 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
253 MissingArgCount, VisibilityMask);
256 if (MissingArgCount) {
257 Diag(diag::err_drv_missing_argument)
258 << Args.getArgString(MissingArgIndex) << MissingArgCount;
260 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
265 for (
const Arg *A : Args) {
267 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
268 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
275 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
276 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
277 ContainsError |= Diags.getDiagnosticLevel(
278 diag::warn_drv_empty_joined_argument,
283 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
285 auto ArgString = A->getAsString(Args);
287 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
289 if (
getOpts().findExact(ArgString, Nearest,
291 DiagID = diag::err_drv_unknown_argument_with_suggestion;
292 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
294 DiagID = diag::err_drv_unknown_argument;
295 Diags.Report(DiagID) << ArgString;
298 llvm::opt::Visibility(
300 DiagID = diag::err_drv_unknown_argument_with_suggestion;
301 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
303 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
304 : diag::err_drv_unknown_argument;
305 Diags.Report(DiagID) << ArgString;
309 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
310 : diag::err_drv_unknown_argument_with_suggestion;
311 Diags.Report(DiagID) << ArgString << Nearest;
313 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
317 for (
const Arg *A : Args.filtered(options::OPT_o)) {
318 if (ArgStrings[A->getIndex()] == A->getSpelling())
322 std::string ArgString = ArgStrings[A->getIndex()];
324 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
325 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
326 << A->getAsString(Args) << Nearest;
336 Arg **FinalPhaseArg)
const {
337 Arg *PhaseArg =
nullptr;
341 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
342 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
343 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
344 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
351 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
353 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
356 options::OPT_fmodule_header_EQ))) {
359 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
362 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
368 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
369 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
373 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
377 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
380 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
388 *FinalPhaseArg = PhaseArg;
396 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
397 llvm::sys::fs::OF_Text);
398 llvm::FileRemover OutputRemover(OutputFile.c_str());
399 std::optional<llvm::StringRef> Redirects[] = {
405 std::string ErrorMessage;
406 int SecondsToWait = 60;
407 if (std::optional<std::string> Str =
408 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
409 if (!llvm::to_integer(*Str, SecondsToWait))
410 return llvm::createStringError(std::error_code(),
411 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
412 "an integer, got '" +
414 SecondsToWait = std::max(SecondsToWait, 0);
416 StringRef Executable = Args[0];
417 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
419 return llvm::createStringError(std::error_code(),
420 Executable +
": " + ErrorMessage);
422 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
423 llvm::MemoryBuffer::getFile(OutputFile.c_str());
425 return llvm::createStringError(OutputBuf.getError(),
426 "Failed to read stdout of " + Executable +
427 ": " + OutputBuf.getError().message());
428 return std::move(*OutputBuf);
432 StringRef
Value,
bool Claim) {
433 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
434 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
435 Args.AddSynthesizedArg(A);
441DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
442 const llvm::opt::OptTable &Opts =
getOpts();
443 DerivedArgList *DAL =
new DerivedArgList(Args);
445 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
446 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
447 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
448 bool IgnoreUnused =
false;
449 for (Arg *A : Args) {
453 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
457 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
458 IgnoreUnused =
false;
468 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
469 A->getOption().matches(options::OPT_Xlinker)) &&
470 A->containsValue(
"--no-demangle")) {
472 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
475 for (StringRef Val : A->getValues())
476 if (Val !=
"--no-demangle")
477 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
485 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
486 A->getNumValues() > 0 &&
487 (A->getValue(0) == StringRef(
"-MD") ||
488 A->getValue(0) == StringRef(
"-MMD"))) {
490 if (A->getValue(0) == StringRef(
"-MD"))
491 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
493 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
494 if (A->getNumValues() == 2)
495 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
500 if (A->getOption().matches(options::OPT_l)) {
501 StringRef
Value = A->getValue();
504 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
506 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
511 if (
Value ==
"cc_kext") {
512 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
518 if (A->getOption().matches(options::OPT__DASH_DASH)) {
520 for (StringRef Val : A->getValues())
529 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
530 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
533 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
534 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
538#if defined(HOST_LINK_VERSION)
539 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
540 strlen(HOST_LINK_VERSION) > 0) {
541 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
543 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
551 StringRef ArgTarget) {
553 static bool BeSilent =
false;
554 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
555 return ((v < 2) || ((v == 2) && (r < 4)));
559 if (ArgTarget.equals_insensitive(
"CURRENT")) {
563 unsigned int Version = 0;
564 unsigned int Release = 0;
565 unsigned int Modification = 0;
567 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
568 llvm::Regex HexRegex(
571 "([0-9a-fA-F][0-9a-fA-F])"
572 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
575 if (ZOsvRegex.match(ArgTarget, &Matches)) {
576 Matches[1].getAsInteger(10, Version);
577 Matches[2].getAsInteger(10, Release);
579 if (IsTooOldToBeSupported(Version, Release)) {
581 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
584 }
else if (HexRegex.match(ArgTarget, &Matches)) {
585 Matches[1].getAsInteger(16, Version);
586 Matches[2].getAsInteger(16, Release);
587 Matches[3].getAsInteger(16, Modification);
588 if (IsTooOldToBeSupported(Version, Release)) {
590 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
596 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
601 llvm::VersionTuple
V(Version, Release, Modification);
602 llvm::VersionTuple TV =
Target.getOSVersion();
605 if (TV.empty() ||
V < TV) {
607 Str = llvm::Triple::getOSTypeName(
Target.getOS());
608 Str +=
V.getAsString();
621 StringRef TargetTriple,
623 StringRef DarwinArchName =
"") {
625 if (
const Arg *A = Args.getLastArg(options::OPT_target))
626 TargetTriple = A->getValue();
628 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
633 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
637 if (
Target.isOSBinFormatMachO()) {
639 if (!DarwinArchName.empty()) {
646 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
647 StringRef ArchName = A->getValue();
654 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
655 options::OPT_mbig_endian)) {
656 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
657 ?
Target.getLittleEndianArchVariant()
658 :
Target.getBigEndianArchVariant();
659 if (T.getArch() != llvm::Triple::UnknownArch) {
661 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
666 if (
Target.getArch() == llvm::Triple::tce)
672 if (!Args.hasArg(options::OPT_target)) {
673 if (std::optional<std::string> ObjectModeValue =
674 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
675 StringRef ObjectMode = *ObjectModeValue;
676 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
678 if (ObjectMode ==
"64") {
679 AT =
Target.get64BitArchVariant().getArch();
680 }
else if (ObjectMode ==
"32") {
681 AT =
Target.get32BitArchVariant().getArch();
683 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
686 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
693 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
694 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
697 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
699 D.
Diag(diag::err_drv_unsupported_opt_for_target)
700 << A->getAsString(Args) <<
Target.str();
703 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
704 options::OPT_m32, options::OPT_m16,
705 options::OPT_maix32, options::OPT_maix64);
707 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
709 if (A->getOption().matches(options::OPT_m64) ||
710 A->getOption().matches(options::OPT_maix64)) {
711 AT =
Target.get64BitArchVariant().getArch();
712 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
713 Target.getEnvironment() == llvm::Triple::GNUT64)
714 Target.setEnvironment(llvm::Triple::GNU);
715 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
716 Target.setEnvironment(llvm::Triple::Musl);
717 }
else if (A->getOption().matches(options::OPT_mx32) &&
718 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
719 AT = llvm::Triple::x86_64;
720 if (
Target.getEnvironment() == llvm::Triple::Musl)
721 Target.setEnvironment(llvm::Triple::MuslX32);
723 Target.setEnvironment(llvm::Triple::GNUX32);
724 }
else if (A->getOption().matches(options::OPT_m32) ||
725 A->getOption().matches(options::OPT_maix32)) {
727 D.
Diag(diag::err_drv_unsupported_opt_for_target)
728 << A->getAsString(Args) <<
Target.str();
730 AT =
Target.get32BitArchVariant().getArch();
731 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
732 Target.setEnvironment(llvm::Triple::GNU);
733 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
734 Target.setEnvironment(llvm::Triple::Musl);
736 }
else if (A->getOption().matches(options::OPT_m16) &&
737 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
738 AT = llvm::Triple::x86;
739 Target.setEnvironment(llvm::Triple::CODE16);
742 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
744 if (
Target.isWindowsGNUEnvironment())
750 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
756 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
757 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
758 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
761 if (A && !A->getOption().matches(options::OPT_m32))
762 D.
Diag(diag::err_drv_argument_not_allowed_with)
763 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
765 Target.setArch(llvm::Triple::x86);
766 Target.setArchName(
"i586");
767 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
768 Target.setEnvironmentName(
"");
769 Target.setOS(llvm::Triple::ELFIAMCU);
770 Target.setVendor(llvm::Triple::UnknownVendor);
771 Target.setVendorName(
"intel");
777 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
778 StringRef ABIName = A->getValue();
779 if (ABIName ==
"32") {
781 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
782 Target.getEnvironment() == llvm::Triple::GNUABIN32)
783 Target.setEnvironment(llvm::Triple::GNU);
784 }
else if (ABIName ==
"n32") {
786 if (
Target.getEnvironment() == llvm::Triple::GNU ||
787 Target.getEnvironment() == llvm::Triple::GNUT64 ||
788 Target.getEnvironment() == llvm::Triple::GNUABI64)
789 Target.setEnvironment(llvm::Triple::GNUABIN32);
790 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
791 Target.getEnvironment() == llvm::Triple::MuslABI64)
792 Target.setEnvironment(llvm::Triple::MuslABIN32);
793 }
else if (ABIName ==
"64") {
795 if (
Target.getEnvironment() == llvm::Triple::GNU ||
796 Target.getEnvironment() == llvm::Triple::GNUT64 ||
797 Target.getEnvironment() == llvm::Triple::GNUABIN32)
798 Target.setEnvironment(llvm::Triple::GNUABI64);
799 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
800 Target.getEnvironment() == llvm::Triple::MuslABIN32)
801 Target.setEnvironment(llvm::Triple::MuslABI64);
809 if (Args.hasArg(options::OPT_march_EQ) ||
810 Args.hasArg(options::OPT_mcpu_EQ)) {
812 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
814 if (!llvm::errorToBool(ISAInfo.takeError())) {
815 unsigned XLen = (*ISAInfo)->getXLen();
817 if (
Target.isLittleEndian())
818 Target.setArch(llvm::Triple::riscv32);
820 Target.setArch(llvm::Triple::riscv32be);
821 }
else if (XLen == 64) {
822 if (
Target.isLittleEndian())
823 Target.setArch(llvm::Triple::riscv64);
825 Target.setArch(llvm::Triple::riscv64be);
831 if (
Target.getArch() == llvm::Triple::riscv32be ||
832 Target.getArch() == llvm::Triple::riscv64be) {
833 static bool WarnedRISCVBE =
false;
834 if (!WarnedRISCVBE) {
835 D.
Diag(diag::warn_drv_riscv_be_experimental);
836 WarnedRISCVBE =
true;
847 OptSpecifier OptEq, OptSpecifier OptNeg) {
848 if (!Args.hasFlag(OptEq, OptNeg,
false))
851 const Arg *A = Args.getLastArg(OptEq);
852 StringRef LTOName = A->getValue();
860 D.
Diag(diag::err_drv_unsupported_option_argument)
861 << A->getSpelling() << A->getValue();
868void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
870 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
872 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
873 options::OPT_fno_offload_lto);
876 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
877 options::OPT_fno_openmp_target_jit,
false)) {
878 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
879 options::OPT_fno_offload_lto))
881 Diag(diag::err_drv_incompatible_options)
882 << A->getSpelling() <<
"-fopenmp-target-jit";
889 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
891 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
893 RuntimeName = A->getValue();
895 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
903 Diag(diag::err_drv_unsupported_option_argument)
904 << A->getSpelling() << A->getValue();
907 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
916 StringRef Program =
C.getArgs().getLastArgValue(
917 options::OPT_offload_arch_tool_EQ,
"offload-arch");
920 if (llvm::ErrorOr<std::string> Executable =
921 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
924 Args.push_back(
"--only=amdgpu");
926 Args.push_back(
"--only=nvptx");
927 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
930 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
935 if ((*StdoutOrErr)->getBuffer().empty()) {
936 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
942 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
944 GPUArchs.push_back(
Arch.str());
946 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
957 std::set<std::string> Archs;
958 for (Arg *A :
C.getInputArgs()) {
959 for (StringRef
Arch : A->getValues()) {
960 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
961 if (
Arch ==
"native") {
963 Archs.insert(Str.str());
965 Archs.insert(
Arch.str());
967 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
971 Archs.erase(
Arch.str());
977 for (llvm::StringRef
Arch : Archs) {
981 llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
982 llvm::Triple::AMD, llvm::Triple::AMDHSA),
986 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
991 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
997 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1002 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1003 <<
"offload" <<
Arch;
1007 llvm::Triple Triple =
1013 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1014 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1015 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1016 C.getArgs().MakeArgString(Triple.getArchName()),
1017 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1019 C.getArgs().append(A);
1020 C.getArgs().AddSynthesizedArg(A);
1022 auto It = Triples.lower_bound(Triple);
1023 if (It == Triples.end() || *It != Triple)
1024 Triples.insert(It, Triple);
1029 Triples.insert(llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
1030 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1032 llvm::Triple::ArchType
Arch =
1033 C.getDefaultToolChain().getTriple().isArch64Bit()
1034 ? llvm::Triple::nvptx64
1035 : llvm::Triple::nvptx;
1036 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1037 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1040 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1041 ? llvm::Triple::spirv64
1042 : llvm::Triple::spirv32));
1045 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1046 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1053 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1054 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1056 llvm::any_of(Inputs,
1057 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1062 (llvm::any_of(Inputs,
1063 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1066 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1067 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1069 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1070 options::OPT_fno_sycl,
false);
1071 bool IsOpenMPOffloading =
1073 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1074 options::OPT_fno_openmp,
false) &&
1075 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1076 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1077 !(IsCuda || IsHIP))));
1079 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1080 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1085 for (
const auto &[Active, Kind] : ActiveKinds)
1090 if (Kinds.size() > 1) {
1091 Diag(clang::diag::err_drv_mix_offload)
1098 if (IsCuda || IsHIP)
1105 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1106 std::vector<std::string> ArgValues =
1107 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1108 for (llvm::StringRef
Target : ArgValues) {
1112 if (ArgValues.empty())
1113 Diag(clang::diag::warn_drv_empty_joined_argument)
1115 .getLastArg(options::OPT_offload_targets_EQ)
1116 ->getAsString(
C.getInputArgs());
1123 llvm::StringMap<StringRef> FoundNormalizedTriples;
1124 for (
const llvm::Triple &
Target : Triples) {
1129 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1137 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1138 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1139 Diag(clang::diag::err_drv_argument_not_allowed_with)
1140 << IncompatArg->getSpelling() <<
"-fsycl";
1145 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1146 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1151 std::string NormalizedName =
Target.normalize();
1152 auto [TripleIt, Inserted] =
1153 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1155 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1156 <<
Target.str() << TripleIt->second;
1160 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1161 C.getDefaultToolChain().getTriple());
1165 auto &CudaInstallation =
1167 if (CudaInstallation.isValid())
1168 CudaInstallation.WarnIfUnsupportedVersion();
1171 C.addOffloadDeviceToolChain(&TC, Kind);
1176bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1181 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1185 if (!PathLIBEnv.empty()) {
1186 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1187 if (llvm::sys::fs::is_directory(PathLIBEnv))
1188 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1189 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1190 return readConfigFile(CustomizationFile, ExpCtx);
1191 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1196 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1197 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1198 return readConfigFile(CustomizationFile, ExpCtx);
1208 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1209 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1210 Copy->getValues() = Opt->getValues();
1211 if (Opt->isClaimed())
1213 Copy->setOwnsValues(Opt->getOwnsValues());
1214 Opt->setOwnsValues(
false);
1216 if (Opt->getAlias()) {
1217 const Arg *Alias = Opt->getAlias();
1218 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1219 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1220 Args.getArgString(Index), Index);
1221 AliasCopy->getValues() = Alias->getValues();
1222 AliasCopy->setOwnsValues(
false);
1223 if (Alias->isClaimed())
1225 Copy->setAlias(std::move(AliasCopy));
1229bool Driver::readConfigFile(StringRef
FileName,
1230 llvm::cl::ExpansionContext &ExpCtx) {
1234 Diag(diag::err_drv_cannot_open_config_file)
1235 <<
FileName << Status.getError().message();
1238 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1239 Diag(diag::err_drv_cannot_open_config_file)
1240 <<
FileName <<
"not a regular file";
1245 SmallVector<const char *, 32> NewCfgFileArgs;
1246 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1247 Diag(diag::err_drv_cannot_read_config_file)
1253 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1254 for (
const char *Opt : NewCfgFileArgs) {
1256 if (Opt[0] ==
'$' && Opt[1])
1257 NewCfgTailArgs.push_back(Opt + 1);
1259 NewCfgHeadArgs.push_back(Opt);
1263 llvm::SmallString<128> CfgFileName(
FileName);
1264 llvm::sys::path::native(CfgFileName);
1265 bool ContainErrors =
false;
1266 auto NewHeadOptions = std::make_unique<InputArgList>(
1270 auto NewTailOptions = std::make_unique<InputArgList>(
1277 for (Arg *A : *NewHeadOptions)
1279 for (Arg *A : *NewTailOptions)
1282 if (!CfgOptionsHead)
1283 CfgOptionsHead = std::move(NewHeadOptions);
1286 for (
auto *Opt : *NewHeadOptions)
1290 if (!CfgOptionsTail)
1291 CfgOptionsTail = std::move(NewTailOptions);
1294 for (
auto *Opt : *NewTailOptions)
1298 ConfigFiles.push_back(std::string(CfgFileName));
1302bool Driver::loadConfigFiles() {
1303 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1304 llvm::cl::tokenizeConfigFile, &
getVFS());
1308 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1309 SmallString<128> CfgDir;
1311 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1312 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1317 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1318 SmallString<128> CfgDir;
1319 llvm::sys::fs::expand_tilde(
1320 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1321 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1330 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1333 if (loadDefaultConfigFiles(ExpCtx))
1337 SmallString<128> CfgFilePath;
1339 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1342 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1343 CfgFilePath.assign(CfgFileName);
1344 if (llvm::sys::path::is_relative(CfgFilePath)) {
1345 if (
getVFS().makeAbsolute(CfgFilePath)) {
1346 Diag(diag::err_drv_cannot_open_config_file)
1347 << CfgFilePath <<
"cannot get absolute path";
1351 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1353 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1354 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1355 if (!SearchDir.empty())
1356 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1361 if (readConfigFile(CfgFilePath, ExpCtx))
1372 llvm::Triple Triple, std::string Suffix) {
1374 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1378 VersionTuple OSVersion = Triple.getOSVersion();
1379 if (!OSVersion.getMinor().has_value())
1382 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1386 if (OSVersion.getMajor() != 0) {
1387 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1388 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1394 Triple.setOSName(BaseOSName);
1395 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1398bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1401 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1405 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1408 std::string RealMode = getExecutableForDriverMode(Mode);
1409 llvm::Triple Triple;
1418 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1419 PrefixTriple.isOSUnknown())
1420 Triple = std::move(PrefixTriple);
1424 llvm::Triple RealTriple =
1426 if (Triple.str().empty()) {
1427 Triple = RealTriple;
1428 assert(!Triple.str().empty());
1433 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1447 SmallString<128> CfgFilePath;
1449 "-" + RealMode +
".cfg"))
1450 return readConfigFile(CfgFilePath, ExpCtx);
1454 if (TryModeSuffix) {
1457 return readConfigFile(CfgFilePath, ExpCtx);
1462 std::string CfgFileName = RealMode +
".cfg";
1463 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1464 if (readConfigFile(CfgFilePath, ExpCtx))
1466 }
else if (TryModeSuffix) {
1468 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1469 readConfigFile(CfgFilePath, ExpCtx))
1475 return readConfigFile(CfgFilePath, ExpCtx);
1483 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1492 if (!DriverMode.empty())
1493 setDriverMode(DriverMode);
1499 CLOptions = std::make_unique<InputArgList>(
1504 ContainsError = loadConfigFiles();
1505 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1506 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1510 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1512 if (HasConfigFileHead)
1513 for (
auto *Opt : *CLOptions)
1514 if (!Opt->getOption().matches(options::OPT_config))
1518 if (
IsCLMode() && !ContainsError) {
1520 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1522 CLModePassThroughArgList.push_back(A->getValue());
1525 if (!CLModePassThroughArgList.empty()) {
1528 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1533 for (
auto *Opt : *CLModePassThroughOptions)
1539 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1540 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1541 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1544 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1545 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1546 if (!VFS->exists(IncludeDir))
1547 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1552 bool CCCPrintPhases;
1555 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1556 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1559 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1560 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1563 Args.ClaimAllArgs(options::OPT_pipe);
1571 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1573 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1574 CCCGenericGCCName = A->getValue();
1577 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1581 if (Args.hasArg(options::OPT_fproc_stat_report))
1588 llvm::Triple T(TargetTriple);
1589 T.setOS(llvm::Triple::Win32);
1590 T.setVendor(llvm::Triple::PC);
1591 T.setEnvironment(llvm::Triple::MSVC);
1592 T.setObjectFormat(llvm::Triple::COFF);
1593 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1594 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1595 TargetTriple = T.str();
1598 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1599 StringRef TargetProfile = A->getValue();
1602 TargetTriple = *Triple;
1604 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1608 if (Args.hasArg(options::OPT_spirv)) {
1609 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1610 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1611 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1612 llvm::Triple T(TargetTriple);
1615 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1617 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1618 TargetInfo = ValidTargets.find(A->getValue());
1620 Diag(diag::err_drv_invalid_value)
1621 << A->getAsString(Args) << A->getValue();
1627 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1628 TargetTriple = T.str();
1632 Diag(diag::err_drv_dxc_missing_target_profile);
1636 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1637 TargetTriple = A->getValue();
1638 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1639 Dir = A->getValue();
1640 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1644 if (std::optional<std::string> CompilerPathValue =
1645 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1646 StringRef CompilerPath = *CompilerPathValue;
1647 while (!CompilerPath.empty()) {
1648 std::pair<StringRef, StringRef> Split =
1649 CompilerPath.split(llvm::sys::EnvPathSeparator);
1650 PrefixDirs.push_back(std::string(Split.first));
1651 CompilerPath = Split.second;
1654 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1656 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1659 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1662 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1663 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1664 .Case(
"cwd", SaveTempsCwd)
1665 .Case(
"obj", SaveTempsObj)
1666 .Default(SaveTempsCwd);
1669 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1670 options::OPT_offload_device_only,
1671 options::OPT_offload_host_device)) {
1672 if (A->getOption().matches(options::OPT_offload_host_only))
1673 Offload = OffloadHost;
1674 else if (A->getOption().matches(options::OPT_offload_device_only))
1675 Offload = OffloadDevice;
1677 Offload = OffloadHostDevice;
1683 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1684 StringRef
Name = A->getValue();
1685 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1686 .Case(
"off", EmbedNone)
1687 .Case(
"all", EmbedBitcode)
1688 .Case(
"bitcode", EmbedBitcode)
1689 .Case(
"marker", EmbedMarker)
1692 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1695 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1699 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1700 llvm::sys::fs::remove(A->getValue());
1706 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1708 !Args.hasArg(options::OPT_fmodules) && Std &&
1709 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1710 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1711 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1712 Std->containsValue(
"c++latest"));
1715 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1716 options::OPT_fmodule_header)) {
1718 ModulesModeCXX20 =
true;
1719 if (A->getOption().matches(options::OPT_fmodule_header))
1722 StringRef ArgName = A->getValue();
1723 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1728 Diags.Report(diag::err_drv_invalid_value)
1729 << A->getAsString(Args) << ArgName;
1735 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1736 std::make_unique<InputArgList>(std::move(Args));
1746 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1747 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1749 bool MLContainsError;
1750 auto MultilibMacroDefineList =
1752 MLMacroDefinesChar,
false, MLContainsError));
1753 if (!MLContainsError) {
1754 for (
auto *Opt : *MultilibMacroDefineList) {
1761 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1765 if (!Triple.isWasm()) {
1766 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1767 StringRef TripleObjectFormat =
1768 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1769 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1770 TripleVersionName != TripleObjectFormat) {
1771 Diags.Report(diag::err_drv_triple_version_invalid)
1773 ContainsError =
true;
1778 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1779 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1780 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1788 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1789 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1791 case llvm::Triple::arm:
1792 case llvm::Triple::armeb:
1793 case llvm::Triple::thumb:
1794 case llvm::Triple::thumbeb:
1795 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1796 Diag(diag::warn_target_unrecognized_env)
1798 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1801 case llvm::Triple::aarch64:
1802 case llvm::Triple::aarch64_be:
1803 case llvm::Triple::aarch64_32:
1804 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1805 Diag(diag::warn_target_unrecognized_env)
1807 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1824 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1825 if (HasConfigFileTail && Inputs.size()) {
1828 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1829 for (Arg *A : *CfgOptionsTail)
1830 TranslatedLinkerIns.append(A);
1831 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1838 bool UseModulesDriver =
C->getArgs().hasFlag(
1839 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1841 if (UseModulesDriver) {
1842 Diags.Report(diag::remark_performing_driver_managed_module_build);
1850 const auto StdModuleManifestPath =
1853 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1854 Diags.Report(diag::remark_modules_manifest_not_found);
1856 Diags.Report(diag::remark_using_modules_manifest)
1857 << StdModuleManifestPath;
1858 if (
auto ManifestOrErr =
1860 ModulesManifest = std::move(*ManifestOrErr);
1862 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1863 return !ModuleEntry.IsStdlib;
1868 llvm::handleAllErrors(
1869 ManifestOrErr.takeError(),
1870 [&](llvm::json::ParseError &Err) {
1871 Diags.Report(diag::err_modules_manifest_failed_parse)
1874 [&](llvm::FileError &Err) {
1875 Diags.Report(diag::err_cannot_open_file)
1876 << Err.getFileName() << Err.messageWithoutFileInfo();
1884 if (TC.
getTriple().isOSBinFormatMachO())
1889 if (CCCPrintPhases) {
1896 if (UseModulesDriver)
1903 llvm::opt::ArgStringList ASL;
1904 for (
const auto *A : Args) {
1908 while (A->getAlias())
1910 A->render(Args, ASL);
1913 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1914 if (I != ASL.begin())
1916 llvm::sys::printArg(OS, *I,
true);
1921bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1922 SmallString<128> &CrashDiagDir) {
1923 using namespace llvm::sys;
1924 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1925 "Only knows about .crash files on Darwin");
1927 auto BypassSandbox = sandbox::scopedDisable();
1932 path::home_directory(CrashDiagDir);
1933 if (CrashDiagDir.starts_with(
"/var/root"))
1935 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1943 fs::file_status FileStatus;
1944 TimePoint<> LastAccessTime;
1945 SmallString<128> CrashFilePath;
1948 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1949 File != FileEnd && !EC;
File.increment(EC)) {
1953 if (fs::status(
File->path(), FileStatus))
1955 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1956 llvm::MemoryBuffer::getFile(
File->path());
1961 StringRef
Data = CrashFile.get()->getBuffer();
1962 if (!
Data.starts_with(
"Process:"))
1965 size_t ParentProcPos =
Data.find(
"Parent Process:");
1966 if (ParentProcPos == StringRef::npos)
1968 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1969 if (LineEnd == StringRef::npos)
1971 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1972 int OpenBracket = -1, CloseBracket = -1;
1973 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1974 if (ParentProcess[i] ==
'[')
1976 if (ParentProcess[i] ==
']')
1982 if (OpenBracket < 0 || CloseBracket < 0 ||
1983 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1984 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1994 const auto FileAccessTime = FileStatus.getLastModificationTime();
1995 if (FileAccessTime > LastAccessTime) {
1996 CrashFilePath.assign(
File->path());
1997 LastAccessTime = FileAccessTime;
2002 if (!CrashFilePath.empty()) {
2003 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2013 "\n********************\n\n"
2014 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2015 "Preprocessed source(s) and associated run script(s) are located at:";
2023 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2027 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2028 Level = llvm::StringSwitch<unsigned>(A->getValue())
2030 .Case(
"compiler", 1)
2042 ArgStringList SavedTemps;
2044 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2045 if (!IsLLD || Level < 2)
2052 SavedTemps = std::move(
C.getTempFiles());
2053 assert(!
C.getTempFiles().size());
2070 C.initCompilationForDiagnostics();
2075 Command NewLLDInvocation = Cmd;
2076 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2077 StringRef ReproduceOption =
2078 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2081 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2085 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2087 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2088 Diag(clang::diag::note_drv_command_failed_diag_msg)
2089 <<
"\n\n********************";
2091 Report->TemporaryFiles.push_back(TmpName);
2099 ArgStringList IRInputs;
2100 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2101 bool IgnoreInput =
false;
2107 IRInputs.push_back(it->second->getValue());
2111 }
else if (!strcmp(it->second->getValue(),
"-")) {
2112 Diag(clang::diag::note_drv_command_failed_diag_msg)
2113 <<
"Error generating preprocessed source(s) - "
2114 "ignoring input from stdin.";
2119 it = Inputs.erase(it);
2126 if (Inputs.empty() && IRInputs.empty()) {
2127 Diag(clang::diag::note_drv_command_failed_diag_msg)
2128 <<
"Error generating preprocessed source(s) - "
2129 "no preprocessable inputs.";
2136 for (
const Arg *A :
C.getArgs()) {
2137 if (A->getOption().matches(options::OPT_arch)) {
2138 StringRef ArchName = A->getValue();
2145 if (FailingArch.empty()) {
2146 Diag(clang::diag::note_drv_command_failed_diag_msg)
2147 <<
"Error generating preprocessed source(s) - cannot generate "
2148 "preprocessed source with multiple -arch options.";
2151 C.getArgs().eraseArg(options::OPT_arch);
2152 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2157 if (!Inputs.empty()) {
2160 const ToolChain &TC =
C.getDefaultToolChain();
2161 if (TC.
getTriple().isOSBinFormatMachO())
2170 Diag(clang::diag::note_drv_command_failed_diag_msg)
2171 <<
"Error generating preprocessed source(s).";
2176 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2179 if (!FailingCommands.empty()) {
2180 Diag(clang::diag::note_drv_command_failed_diag_msg)
2181 <<
"Error generating preprocessed source(s).";
2185 const ArgStringList &TempFiles =
C.getTempFiles();
2186 if (TempFiles.empty()) {
2187 Diag(clang::diag::note_drv_command_failed_diag_msg)
2188 <<
"Error generating preprocessed source(s).";
2194 const ArgStringList &Files =
C.getTempFiles();
2199 for (
auto const *Input : IRInputs) {
2203 StringRef extension = llvm::sys::path::extension(Input);
2204 if (!extension.empty())
2205 extension = extension.drop_front();
2207 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2208 llvm::sys::path::stem(Input), extension, FD, Path);
2210 Diag(clang::diag::note_drv_command_failed_diag_msg)
2211 <<
"Error generating run script: " <<
"Failed copying IR input files"
2212 <<
" " << EC.message();
2216 EC = llvm::sys::fs::copy_file(Input, FD);
2218 Diag(clang::diag::note_drv_command_failed_diag_msg)
2219 <<
"Error generating run script: " <<
"Failed copying IR input files"
2220 <<
" " << EC.message();
2224 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2231 for (std::string &TempFile : TempFiles) {
2232 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2234 Report->TemporaryFiles.push_back(TempFile);
2235 if (ReproCrashFilename.empty()) {
2236 ReproCrashFilename = TempFile;
2237 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2239 if (StringRef(TempFile).ends_with(
".cache")) {
2242 VFS = llvm::sys::path::filename(TempFile);
2243 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2247 for (
const char *TempFile : SavedTemps)
2248 TempFiles.push_back(TempFile);
2254 llvm::sys::path::replace_extension(Script,
"sh");
2256 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2257 llvm::sys::fs::FA_Write,
2258 llvm::sys::fs::OF_Text);
2260 Diag(clang::diag::note_drv_command_failed_diag_msg)
2261 <<
"Error generating run script: " << Script <<
" " << EC.message();
2264 <<
"# Driver args: ";
2266 ScriptOS <<
"# Original command: ";
2267 Cmd.
Print(ScriptOS,
"\n",
true);
2268 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2269 if (!AdditionalInformation.empty())
2270 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2273 Report->TemporaryFiles.push_back(std::string(Script));
2274 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2278 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2280 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2281 Diag(clang::diag::note_drv_command_failed_diag_msg)
2282 << ReproCrashFilename.str();
2284 llvm::sys::path::append(CrashDiagDir,
Name);
2285 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2286 Diag(clang::diag::note_drv_command_failed_diag_msg)
2287 <<
"Crash backtrace is located in";
2288 Diag(clang::diag::note_drv_command_failed_diag_msg)
2289 << CrashDiagDir.str();
2290 Diag(clang::diag::note_drv_command_failed_diag_msg)
2291 <<
"(choose the .crash file that corresponds to your crash)";
2295 Diag(clang::diag::note_drv_command_failed_diag_msg)
2296 <<
"\n\n********************";
2306 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2317 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2318 if (
C.getArgs().hasArg(options::OPT_v))
2319 C.getJobs().Print(llvm::errs(),
"\n",
true);
2321 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2324 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2331 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2332 C.getJobs().Print(llvm::errs(),
"\n",
true);
2333 return Diags.hasErrorOccurred() ? 1 : 0;
2337 if (Diags.hasErrorOccurred())
2341 for (
auto &Job :
C.getJobs())
2342 setUpResponseFiles(
C, Job);
2344 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2347 if (FailingCommands.empty())
2353 for (
const auto &CmdPair : FailingCommands) {
2354 int CommandRes = CmdPair.first;
2355 const Command *FailingCommand = CmdPair.second;
2360 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2364 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2369 if (CommandRes == EX_IOERR) {
2389 if (CommandRes > 128 && CommandRes != 255)
2393 Diag(clang::diag::err_drv_command_signalled)
2396 Diag(clang::diag::err_drv_command_failed)
2404 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2406 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2420 const ToolChain &TC =
C.getDefaultToolChain();
2424 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2427 OS <<
"Thread model: " << A->getValue();
2433 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2438 if (!llvm::cl::getCompilerBuildConfig().empty())
2439 llvm::cl::printBuildConfig(OS);
2442 for (
auto ConfigFile : ConfigFiles)
2443 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2456 if (PassedFlags ==
"")
2460 std::vector<std::string> SuggestedCompletions;
2461 std::vector<std::string> Flags;
2473 const bool HasSpace = PassedFlags.ends_with(
",");
2477 StringRef TargetFlags = PassedFlags;
2478 while (TargetFlags !=
"") {
2480 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2481 Flags.push_back(std::string(CurFlag));
2486 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2489 const llvm::opt::OptTable &Opts =
getOpts();
2491 Cur = Flags.at(Flags.size() - 1);
2493 if (Flags.size() >= 2) {
2494 Prev = Flags.at(Flags.size() - 2);
2495 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2498 if (SuggestedCompletions.empty())
2499 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2506 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2507 llvm::outs() <<
'\n';
2513 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2517 SuggestedCompletions = Opts.findByPrefix(
2518 Cur, VisibilityMask,
2525 if (S.starts_with(Cur))
2526 SuggestedCompletions.push_back(std::string(S));
2533 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2534 if (
int X = A.compare_insensitive(B))
2536 return A.compare(B) > 0;
2539 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2546 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2547 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2551 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2554 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2558 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2563 if (
C.getArgs().hasArg(options::OPT_help) ||
2564 C.getArgs().hasArg(options::OPT__help_hidden)) {
2565 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2569 if (
C.getArgs().hasArg(options::OPT__version)) {
2576 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2577 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2578 if (ListExtractors || ListFormats) {
2586 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2591 if (
C.getArgs().hasArg(options::OPT_v) ||
2592 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2593 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2594 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2595 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2597 SuppressMissingInputWarning =
true;
2600 if (
C.getArgs().hasArg(options::OPT_v)) {
2602 llvm::errs() <<
"System configuration file directory: "
2605 llvm::errs() <<
"User configuration file directory: "
2609 const ToolChain &TC =
C.getDefaultToolChain();
2611 if (
C.getArgs().hasArg(options::OPT_v))
2614 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2619 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2620 llvm::outs() <<
"programs: =";
2621 bool separator =
false;
2625 llvm::outs() << llvm::sys::EnvPathSeparator;
2626 llvm::outs() << Path;
2631 llvm::outs() << llvm::sys::EnvPathSeparator;
2632 llvm::outs() << Path;
2635 llvm::outs() <<
"\n";
2638 StringRef sysroot =
C.getSysRoot();
2642 llvm::outs() << llvm::sys::EnvPathSeparator;
2645 llvm::outs() << sysroot << Path.substr(1);
2647 llvm::outs() << Path;
2649 llvm::outs() <<
"\n";
2653 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2659 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2660 for (
auto RuntimePath :
2662 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2663 llvm::outs() << *RuntimePath <<
'\n';
2667 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2671 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2673 for (std::size_t I = 0; I != Flags.size(); I += 2)
2674 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2680 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2681 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2685 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2686 StringRef ProgName = A->getValue();
2689 if (! ProgName.empty())
2692 llvm::outs() <<
"\n";
2696 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2697 StringRef PassedFlags = A->getValue();
2702 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2716 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2719 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2725 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2732 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2735 std::set<llvm::StringRef> SortedFlags;
2736 for (
const auto &FlagEntry : ExpandedFlags)
2737 SortedFlags.insert(FlagEntry.getKey());
2738 for (
auto Flag : SortedFlags)
2739 llvm::outs() << Flag <<
'\n';
2743 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2746 llvm::outs() <<
".\n";
2749 assert(Suffix.front() ==
'/');
2750 llvm::outs() << Suffix.substr(1) <<
"\n";
2756 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2761 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2763 llvm::outs() << Triple.getTriple() <<
"\n";
2767 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2768 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2785 std::map<Action *, unsigned> &Ids,
2787 if (
auto It = Ids.find(A); It != Ids.end())
2791 llvm::raw_string_ostream os(str);
2793 auto getSibIndent = [](
int K) -> Twine {
2797 Twine SibIndent =
Indent + getSibIndent(Kind);
2801 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2803 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2804 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2805 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2807 OA->doOnEachDependence(
2809 assert(TC &&
"Unknown host toolchain");
2821 os <<
":" << BoundArch;
2824 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2832 const char *Prefix =
"{";
2833 for (
Action *PreRequisite : *AL) {
2834 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2845 std::string offload_str;
2846 llvm::raw_string_ostream offload_os(offload_str);
2850 offload_os <<
", (" << S;
2857 auto getSelfIndent = [](
int K) -> Twine {
2861 unsigned Id = Ids.size();
2863 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2872 std::map<Action *, unsigned> Ids;
2873 for (
Action *A :
C.getActions())
2889 DerivedArgList &Args =
C.getArgs();
2891 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2896 for (Arg *A : Args) {
2897 if (A->getOption().matches(options::OPT_arch)) {
2900 llvm::Triple::ArchType
Arch =
2902 if (
Arch == llvm::Triple::UnknownArch) {
2903 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2908 if (
ArchNames.insert(A->getValue()).second)
2909 Archs.push_back(A->getValue());
2923 for (
Action* Act : SingleActions) {
2931 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2935 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2940 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2941 Actions.append(Inputs.begin(), Inputs.end());
2943 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2946 Arg *A = Args.getLastArg(options::OPT_g_Group);
2947 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2948 !A->getOption().matches(options::OPT_gstabs);
2949 bool enablesPseudoProbe =
2950 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2951 options::OPT_fno_pseudo_probe_for_profiling,
false);
2952 bool enablesDebugInfoForProfiling =
2953 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2954 options::OPT_fno_debug_info_for_profiling,
false);
2955 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2956 enablesDebugInfoForProfiling) &&
2964 if (Act->getType() == types::TY_Image) {
2966 Inputs.push_back(Actions.back());
2973 if (Args.hasArg(options::OPT_verify_debug_info)) {
2974 Action *LastAction = Actions.pop_back_val();
2976 LastAction, types::TY_Nothing));
2983 bool TypoCorrect)
const {
2995 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2996 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3008 std::string Nearest;
3009 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3010 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3011 <<
Value << Nearest;
3050 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3053 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3061 return types::TY_CXXUHeader;
3063 return types::TY_CXXSHeader;
3067 llvm_unreachable(
"should not be called in this case");
3069 return types::TY_CXXHUHeader;
3075 const llvm::opt::OptTable &Opts =
getOpts();
3079 types::ID InputType = types::TY_Nothing;
3080 Arg *InputTypeArg =
nullptr;
3083 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3084 options::OPT__SLASH_TP)) {
3085 InputTypeArg = TCTP;
3086 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3091 bool ShowNote =
false;
3093 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3095 Diag(clang::diag::warn_drv_overriding_option)
3096 <<
Previous->getSpelling() << A->getSpelling();
3102 Diag(clang::diag::note_drv_t_option_is_global);
3107 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3108 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3109 if (LastXArg && LastInputArg &&
3110 LastInputArg->getIndex() < LastXArg->getIndex())
3111 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3114 for (Arg *A : Args) {
3115 if (A->getOption().
getKind() == Option::InputClass) {
3116 const char *
Value = A->getValue();
3120 if (InputType == types::TY_Nothing) {
3123 InputTypeArg->claim();
3126 if (strcmp(
Value,
"-") == 0) {
3128 Ty = types::TY_Fortran;
3130 Ty = types::TY_HLSL;
3139 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3140 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3141 : clang::diag::err_drv_unknown_stdin_type);
3150 if (
const char *Ext = strrchr(
Value,
'.'))
3159 Ty = types::TY_HLSL;
3161 Ty = types::TY_Object;
3172 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3173 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3174 << getTypeName(OldTy) << getTypeName(Ty);
3179 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3180 Ty == types::TY_Object)
3181 Ty = types::TY_LLVM_BC;
3189 if (Ty != types::TY_Object) {
3190 if (Args.hasArg(options::OPT_ObjC))
3191 Ty = types::TY_ObjC;
3192 else if (Args.hasArg(options::OPT_ObjCXX))
3193 Ty = types::TY_ObjCXX;
3200 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3204 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3205 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3208 const char *Ext = strrchr(
Value,
'.');
3210 Ty = types::TY_Object;
3214 InputTypeArg->claim();
3218 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3219 Args.hasArgNoClaim(options::OPT_hipstdpar))
3223 Inputs.push_back(std::make_pair(Ty, A));
3225 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3226 StringRef
Value = A->getValue();
3229 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3230 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3233 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3234 StringRef
Value = A->getValue();
3237 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3238 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3244 Inputs.push_back(std::make_pair(types::TY_Object, A));
3246 }
else if (A->getOption().matches(options::OPT_x)) {
3255 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3256 InputType = types::TY_Object;
3263 }
else if (A->getOption().getID() == options::OPT_U) {
3264 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3265 StringRef Val = A->getValue(0);
3266 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3268 Diag(diag::warn_slash_u_filename) << Val;
3269 Diag(diag::note_use_dashdash);
3273 if (
CCCIsCPP() && Inputs.empty()) {
3277 Inputs.push_back(std::make_pair(types::TY_C, A));
3284class OffloadingActionBuilder final {
3286 bool IsValid =
false;
3292 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3295 std::map<Action *, const Arg *> HostActionToInputArgMap;
3298 class DeviceActionBuilder {
3302 enum ActionBuilderReturnCode {
3320 const ToolChain *FatBinaryToolChain =
nullptr;
3323 DerivedArgList &Args;
3332 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3335 :
C(
C), Args(Args), Inputs(Inputs),
3336 AssociatedOffloadKind(AssociatedOffloadKind) {}
3337 virtual ~DeviceActionBuilder() {}
3342 virtual ActionBuilderReturnCode
3343 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3346 return ABRT_Inactive;
3351 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3352 return ABRT_Inactive;
3356 virtual void appendTopLevelActions(
ActionList &AL) {}
3359 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3362 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3365 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3372 virtual bool canUseBundlerUnbundler()
const {
return false; }
3376 bool isValid() {
return !ToolChains.empty(); }
3380 return AssociatedOffloadKind;
3386 class CudaActionBuilderBase :
public DeviceActionBuilder {
3390 bool CompileHostOnly =
false;
3391 bool CompileDeviceOnly =
false;
3393 bool EmitAsm =
false;
3403 TargetID(
const char *ID) :
ID(
ID) {}
3404 operator const char *() {
return ID; }
3405 operator StringRef() {
return StringRef(ID); }
3408 SmallVector<TargetID, 4> GpuArchList;
3414 Action *CudaFatBinary =
nullptr;
3417 bool IsActive =
false;
3420 bool Relocatable =
false;
3423 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3426 const CUIDOptions &CUIDOpts;
3429 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3431 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3432 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3434 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3435 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3436 options::OPT_fno_gpu_rdc,
false);
3439 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3446 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3449 if (!(IA->getType() == types::TY_CUDA ||
3450 IA->getType() == types::TY_HIP ||
3451 IA->getType() == types::TY_PP_HIP)) {
3454 return ABRT_Inactive;
3461 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3463 if (CompileHostOnly)
3464 return ABRT_Success;
3467 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3468 : types::TY_CUDA_DEVICE;
3469 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3470 CudaDeviceActions.push_back(
3471 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3474 return ABRT_Success;
3478 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3482 if (UA->getType() == types::TY_Object && !Relocatable)
3483 return ABRT_Inactive;
3485 CudaDeviceActions.clear();
3487 std::string
FileName = IA->getInputArg().getAsString(Args);
3493 const StringRef LibFileExt =
".lib";
3494 if (IA->getType() == types::TY_Object &&
3495 (!llvm::sys::path::has_extension(
FileName) ||
3497 llvm::sys::path::extension(
FileName).drop_front()) !=
3499 llvm::sys::path::extension(
FileName) == LibFileExt))
3500 return ABRT_Inactive;
3502 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3503 CudaDeviceActions.push_back(UA);
3504 UA->registerDependentActionInfo(ToolChain,
Arch,
3505 AssociatedOffloadKind);
3508 return ABRT_Success;
3511 return IsActive ? ABRT_Success : ABRT_Inactive;
3514 void appendTopLevelActions(
ActionList &AL)
override {
3516 auto AddTopLevel = [&](Action *A, TargetID TargetID,
3517 const ToolChain *TC) {
3518 OffloadAction::DeviceDependences Dep;
3519 Dep.
add(*A, *TC, TargetID, AssociatedOffloadKind);
3520 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3524 if (CudaFatBinary) {
3525 AddTopLevel(CudaFatBinary, OffloadArch::Unused, FatBinaryToolChain);
3526 CudaDeviceActions.clear();
3527 CudaFatBinary =
nullptr;
3531 if (CudaDeviceActions.empty())
3537 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3538 "Expecting one action per GPU architecture.");
3539 assert(ToolChains.size() == GpuArchList.size() &&
3540 "Expecting to have a toolchain per GPU architecture");
3541 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3542 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3544 CudaDeviceActions.clear();
3547 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3565 assert(HostTC &&
"No toolchain for host compilation.");
3570 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3575 std::set<std::pair<StringRef, const ToolChain *>> GpuArchs;
3577 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3579 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3580 GpuArchs.insert({
Arch, I.second});
3584 for (
auto [
Arch, TC] : GpuArchs) {
3585 GpuArchList.push_back(
Arch.data());
3586 ToolChains.push_back(TC);
3589 FatBinaryToolChain = ToolChains.front();
3590 CompileHostOnly =
C.getDriver().offloadHostOnly();
3591 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3592 EmitAsm = Args.getLastArg(options::OPT_S);
3600 class CudaActionBuilder final :
public CudaActionBuilderBase {
3602 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3604 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3605 DefaultOffloadArch = OffloadArch::CudaDefault;
3608 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3610 const std::set<StringRef> &GpuArchs)
override {
3611 return std::nullopt;
3614 ActionBuilderReturnCode
3615 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3617 PhasesTy &Phases)
override {
3619 return ABRT_Inactive;
3623 if (CudaDeviceActions.empty())
3624 return ABRT_Success;
3626 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3627 "Expecting one action per GPU architecture.");
3628 assert(!CompileHostOnly &&
3629 "Not expecting CUDA actions in host-only compilation.");
3639 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3642 for (
auto Ph : Phases) {
3647 if (Ph > FinalPhase)
3650 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3664 Action *AssembleAction = CudaDeviceActions[I];
3665 assert(AssembleAction->
getType() == types::TY_Object);
3666 assert(AssembleAction->
getInputs().size() == 1);
3672 OffloadAction::DeviceDependences DDep;
3674 DeviceActions.push_back(
3675 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3680 if (!DeviceActions.empty()) {
3682 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3684 if (!CompileDeviceOnly) {
3685 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3689 CudaFatBinary =
nullptr;
3694 CudaDeviceActions.clear();
3698 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3703 return ABRT_Success;
3707 "instructions should only occur "
3708 "before the backend phase!");
3711 for (Action *&A : CudaDeviceActions)
3712 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3714 return ABRT_Success;
3719 class HIPActionBuilder final :
public CudaActionBuilderBase {
3721 SmallVector<ActionList, 8> DeviceLinkerInputs;
3727 std::optional<bool> BundleOutput;
3728 std::optional<bool> EmitReloc;
3731 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3733 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3735 DefaultOffloadArch = OffloadArch::HIPDefault;
3737 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3738 options::OPT_fno_hip_emit_relocatable)) {
3739 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3740 options::OPT_fno_hip_emit_relocatable, false);
3744 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3745 <<
"-fhip-emit-relocatable"
3749 if (!CompileDeviceOnly) {
3750 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3751 <<
"-fhip-emit-relocatable"
3752 <<
"--offload-device-only";
3757 if (Args.hasArg(options::OPT_gpu_bundle_output,
3758 options::OPT_no_gpu_bundle_output))
3759 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3760 options::OPT_no_gpu_bundle_output,
true) &&
3761 (!EmitReloc || !*EmitReloc);
3764 bool canUseBundlerUnbundler()
const override {
return true; }
3766 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3768 const std::set<StringRef> &GpuArchs)
override {
3772 ActionBuilderReturnCode
3773 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3775 PhasesTy &Phases)
override {
3777 return ABRT_Inactive;
3783 if (CudaDeviceActions.empty())
3784 return ABRT_Success;
3787 CudaDeviceActions.size() == GpuArchList.size()) &&
3788 "Expecting one action per GPU architecture.");
3789 assert(!CompileHostOnly &&
3790 "Not expecting HIP actions in host-only compilation.");
3792 bool ShouldLink = !EmitReloc || !*EmitReloc;
3795 !EmitAsm && ShouldLink) {
3801 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3802 if (
C.getDriver().isUsingOffloadLTO()) {
3806 AL.push_back(CudaDeviceActions[I]);
3809 CudaDeviceActions[I] =
3810 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3816 if (ToolChains[I]->
getTriple().isSPIRV() ||
3817 (ToolChains[I]->
getTriple().isAMDGCN() &&
3818 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3822 types::ID Output = Args.hasArg(options::OPT_S)
3824 : types::TY_LLVM_BC;
3826 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3830 AssociatedOffloadKind);
3831 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3833 AssociatedOffloadKind);
3834 AL.push_back(AssembleAction);
3837 CudaDeviceActions[I] =
3838 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3847 OffloadAction::DeviceDependences DDep;
3848 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3849 AssociatedOffloadKind);
3850 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3851 DDep, CudaDeviceActions[I]->getType());
3854 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3856 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3857 types::TY_HIP_FATBIN);
3859 if (!CompileDeviceOnly) {
3860 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3861 AssociatedOffloadKind);
3864 CudaFatBinary =
nullptr;
3869 CudaDeviceActions.clear();
3872 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3875 return ABRT_Success;
3881 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3882 auto LI = DeviceLinkerInputs.begin();
3883 for (
auto *A : CudaDeviceActions) {
3890 CudaDeviceActions.clear();
3891 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3895 for (Action *&A : CudaDeviceActions)
3896 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3897 AssociatedOffloadKind);
3899 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3901 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3902 OffloadAction::DeviceDependences DDep;
3903 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3904 AssociatedOffloadKind);
3905 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3906 DDep, CudaDeviceActions[I]->getType());
3909 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3910 CudaDeviceActions.clear();
3913 return (CompileDeviceOnly &&
3914 (CurPhase == FinalPhase ||
3920 void appendLinkDeviceActions(
ActionList &AL)
override {
3921 if (DeviceLinkerInputs.size() == 0)
3924 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3925 "Linker inputs and GPU arch list sizes do not match.");
3931 for (
auto &LI : DeviceLinkerInputs) {
3933 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3937 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3940 OffloadAction::DeviceDependences DeviceLinkDeps;
3941 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3942 AssociatedOffloadKind);
3943 Actions.push_back(
C.MakeAction<OffloadAction>(
3944 DeviceLinkDeps, DeviceLinkAction->getType()));
3947 DeviceLinkerInputs.clear();
3950 if (Args.hasArg(options::OPT_emit_llvm)) {
3958 OffloadAction::DeviceDependences DDeps;
3959 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3960 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3962 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3963 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain,
nullptr,
3964 AssociatedOffloadKind);
3967 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3973 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3975 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3983 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3989 bool ShouldUseBundler;
3992 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
4000 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
4003 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4011 unsigned ValidBuilders = 0u;
4012 unsigned ValidBuildersSupportingBundling = 0u;
4013 for (
auto *SB : SpecializedBuilders) {
4014 IsValid = IsValid && !SB->initialize();
4017 if (SB->isValid()) {
4019 if (SB->canUseBundlerUnbundler())
4020 ++ValidBuildersSupportingBundling;
4024 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4026 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4027 options::OPT_no_gpu_bundle_output,
true);
4030 ~OffloadingActionBuilder() {
4031 for (
auto *SB : SpecializedBuilders)
4036 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4037 assert(HostAction &&
"Invalid host action");
4038 assert(InputArg &&
"Invalid input argument");
4039 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4040 assert(Loc->second == InputArg &&
4041 "host action mapped to multiple input arguments");
4050 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4052 DeviceActionBuilder::PhasesTy &Phases) {
4056 if (SpecializedBuilders.empty())
4059 assert(HostAction &&
"Invalid host action!");
4060 recordHostAction(HostAction, InputArg);
4065 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4066 unsigned InactiveBuilders = 0u;
4067 unsigned IgnoringBuilders = 0u;
4068 for (
auto *SB : SpecializedBuilders) {
4069 if (!SB->isValid()) {
4074 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4079 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4084 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4085 OffloadKind |= SB->getAssociatedOffloadKind();
4090 if (IgnoringBuilders &&
4091 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4108 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4109 const Arg *InputArg) {
4113 recordHostAction(HostAction, InputArg);
4122 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4124 HostAction->
getType() == types::TY_PP_HIP)) {
4125 auto UnbundlingHostAction =
4130 HostAction = UnbundlingHostAction;
4131 recordHostAction(HostAction, InputArg);
4134 assert(HostAction &&
"Invalid host action!");
4137 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4138 for (
auto *SB : SpecializedBuilders) {
4142 auto RetCode = SB->addDeviceDependences(HostAction);
4146 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4147 "Host dependence not expected to be ignored.!");
4151 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4152 OffloadKind |= SB->getAssociatedOffloadKind();
4157 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4167 const Arg *InputArg) {
4169 recordHostAction(HostAction, InputArg);
4173 for (
auto *SB : SpecializedBuilders) {
4176 SB->appendTopLevelActions(OffloadAL);
4183 if (CanUseBundler && ShouldUseBundler && HostAction &&
4184 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4186 OffloadAL.push_back(HostAction);
4190 assert(HostAction == AL.back() &&
"Host action not in the list??");
4192 recordHostAction(HostAction, InputArg);
4193 AL.back() = HostAction;
4195 AL.append(OffloadAL.begin(), OffloadAL.end());
4205 void appendDeviceLinkActions(
ActionList &AL) {
4206 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4209 SB->appendLinkDeviceActions(AL);
4213 Action *makeHostLinkAction() {
4216 appendDeviceLinkActions(DeviceAL);
4217 if (DeviceAL.empty())
4222 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4225 HA = SB->appendLinkHostActions(DeviceAL);
4242 for (
auto *SB : SpecializedBuilders) {
4246 SB->appendLinkDependences(DDeps);
4250 unsigned ActiveOffloadKinds = 0u;
4251 for (
auto &I : InputArgToOffloadKindMap)
4252 ActiveOffloadKinds |= I.second;
4264 for (
auto *A : HostAction->
inputs()) {
4265 auto ArgLoc = HostActionToInputArgMap.find(A);
4266 if (ArgLoc == HostActionToInputArgMap.end())
4268 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4269 if (OFKLoc == InputArgToOffloadKindMap.end())
4281 nullptr, ActiveOffloadKinds);
4287void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4292 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4293 StringRef
V = A->getValue();
4294 if (Inputs.size() > 1 && !
V.empty() &&
4295 !llvm::sys::path::is_separator(
V.back())) {
4297 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4298 << A->getSpelling() <<
V;
4299 Args.eraseArg(options::OPT__SLASH_Fo);
4304 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4305 StringRef
V = A->getValue();
4306 if (Inputs.size() > 1 && !
V.empty() &&
4307 !llvm::sys::path::is_separator(
V.back())) {
4309 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4310 << A->getSpelling() <<
V;
4311 Args.eraseArg(options::OPT__SLASH_Fa);
4316 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4317 if (A->getValue()[0] ==
'\0') {
4319 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4320 Args.eraseArg(options::OPT__SLASH_o);
4325 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4326 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4327 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4328 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4329 Args.eraseArg(options::OPT__SLASH_Yc);
4330 Args.eraseArg(options::OPT__SLASH_Yu);
4331 YcArg = YuArg =
nullptr;
4333 if (YcArg && Inputs.size() > 1) {
4334 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4335 Args.eraseArg(options::OPT__SLASH_Yc);
4343 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4344 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4345 Args.AddFlagArg(
nullptr,
4346 getOpts().getOption(options::OPT_frtlib_add_rpath));
4350 if (Args.hasArg(options::OPT_emit_llvm) &&
4351 !Args.hasArg(options::OPT_hip_link) &&
4352 !
C.getDefaultToolChain().getTriple().isSPIRV())
4353 Diag(clang::diag::err_drv_emit_llvm_link);
4354 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4356 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4357 .starts_with_insensitive(
"lld"))
4358 Diag(clang::diag::err_drv_lto_without_lld);
4364 if (!Args.hasArg(options::OPT_dumpdir)) {
4365 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4366 Arg *Arg = Args.MakeSeparateArg(
4367 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4369 (FinalOutput ? FinalOutput->getValue()
4381 Args.eraseArg(options::OPT__SLASH_Fp);
4382 Args.eraseArg(options::OPT__SLASH_Yc);
4383 Args.eraseArg(options::OPT__SLASH_Yu);
4384 YcArg = YuArg =
nullptr;
4387 if (Args.hasArg(options::OPT_include_pch) &&
4388 Args.hasArg(options::OPT_ignore_pch)) {
4392 Args.eraseArg(options::OPT_include_pch);
4395 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4396 for (
auto &I : Inputs) {
4398 const Arg *InputArg = I.second;
4403 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4407 if (InitialPhase > FinalPhase) {
4408 if (InputArg->isClaimed())
4415 if (Args.hasArg(options::OPT_Qunused_arguments))
4421 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4422 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4426 (Args.getLastArg(options::OPT__SLASH_EP,
4427 options::OPT__SLASH_P) ||
4428 Args.getLastArg(options::OPT_E) ||
4429 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4431 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4432 << InputArg->getAsString(Args) << !!FinalPhaseArg
4433 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4435 Diag(clang::diag::warn_drv_input_file_unused)
4436 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4438 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4447 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4451 Actions.push_back(ClangClPch);
4463 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4464 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4473 const llvm::opt::DerivedArgList &Args,
4476 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4478 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4481 bool HasAMDGCNHIPDevice =
false;
4483 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4485 const llvm::Triple &Tr = TC->
getTriple();
4488 HasAMDGCNHIPDevice =
true;
4490 return HasAMDGCNHIPDevice;
4495 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4497 if (!SuppressMissingInputWarning && Inputs.empty()) {
4498 Diag(clang::diag::err_drv_no_input_files);
4502 handleArguments(
C, Args, Inputs, Actions);
4504 bool UseNewOffloadingDriver = Args.hasFlag(
4505 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4509 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4510 !UseNewOffloadingDriver
4511 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4519 for (
auto &I : Inputs) {
4521 const Arg *InputArg = I.second;
4534 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4542 if (!UseNewOffloadingDriver)
4543 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4549 if (!UseNewOffloadingDriver)
4550 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4551 Current, InputArg, Phase, PL.back(), FullPL);
4557 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4560 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4561 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4563 LinkerInputs.push_back(Current);
4573 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4574 MergerInputs.push_back(Current);
4592 if (NewCurrent == Current)
4595 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4598 Current = NewCurrent;
4602 if (UseNewOffloadingDriver)
4604 &HIPAsmDeviceActions);
4607 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4611 if (Current->
getType() == types::TY_Nothing)
4617 if (Current && !HIPAsmDeviceActions.empty()) {
4618 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4620 BundleInputs.append(HIPAsmDeviceActions);
4621 BundleInputs.push_back(Current);
4627 Actions.push_back(Current);
4630 if (!UseNewOffloadingDriver)
4631 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4639 if (LinkerInputs.empty()) {
4642 if (!UseNewOffloadingDriver)
4643 OffloadBuilder->appendDeviceLinkActions(Actions);
4646 if (!LinkerInputs.empty()) {
4647 if (!UseNewOffloadingDriver)
4648 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4649 LinkerInputs.push_back(Wrapper);
4654 }
else if (UseNewOffloadingDriver ||
4655 Args.hasArg(options::OPT_offload_link)) {
4663 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4664 C.getDefaultToolChain().getTriple().isSPIRV();
4665 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4669 if (!UseNewOffloadingDriver)
4670 LA = OffloadBuilder->processHostLinkAction(LA);
4671 Actions.push_back(LA);
4675 if (!MergerInputs.empty())
4679 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4686 for (
auto &I : Inputs) {
4688 const Arg *InputArg = I.second;
4693 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4694 InputType == types::TY_Asm)
4699 for (
auto Phase : PhaseList) {
4703 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4708 if (InputType == types::TY_Object)
4715 assert(Phase == PhaseList.back() &&
4716 "merging must be final compilation step.");
4717 MergerInputs.push_back(Current);
4726 Actions.push_back(Current);
4730 if (!MergerInputs.empty())
4735 for (
auto Opt : {options::OPT_print_supported_cpus,
4736 options::OPT_print_supported_extensions,
4737 options::OPT_print_enabled_extensions}) {
4744 if (Arg *A = Args.getLastArg(Opt)) {
4745 if (Opt == options::OPT_print_supported_extensions &&
4746 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4747 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4748 !
C.getDefaultToolChain().getTriple().isARM()) {
4749 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4750 <<
"--print-supported-extensions";
4753 if (Opt == options::OPT_print_enabled_extensions &&
4754 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4755 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4756 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4757 <<
"--print-enabled-extensions";
4764 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4767 for (
auto &I : Inputs)
4772 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4773 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4774 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4780 if (TC.requiresObjcopy(Args)) {
4781 Action *LastAction = Actions.back();
4783 if (LastAction->
getType() == types::TY_Object)
4789 auto ValInfo = TC.getValidationInfo(Args);
4790 if (ValInfo.NeedsValidation) {
4791 Action *LastAction = Actions.back();
4792 if (LastAction->
getType() == types::TY_Object) {
4794 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4801 if (TC.requiresBinaryTranslation(Args)) {
4802 Action *LastAction = Actions.back();
4806 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4807 LastAction->
getType() == types::TY_Object)
4809 LastAction, types::TY_DX_CONTAINER));
4814 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4820 const llvm::opt::DerivedArgList &Args,
4822 const llvm::Triple &Triple) {
4827 if (Triple.isNVPTX() &&
4829 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4830 <<
"CUDA" << ArchStr;
4832 }
else if (Triple.isAMDGPU() &&
4834 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4835 <<
"HIP" << ArchStr;
4843 llvm::StringMap<bool> Features;
4846 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4858static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4860 llvm::Triple Triple) {
4861 if (!Triple.isAMDGPU())
4862 return std::nullopt;
4864 std::set<StringRef> ArchSet;
4865 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4869llvm::SmallVector<StringRef>
4873 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4874 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4875 options::OPT_no_offload_arch_EQ)) {
4876 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4878 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4880 :
"--no-offload-arch");
4883 llvm::DenseSet<StringRef> Archs;
4884 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4887 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4888 for (StringRef
Arch : Arg->getValues()) {
4889 if (
Arch ==
"native" ||
Arch.empty()) {
4894 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4898 for (
auto ArchStr : *GPUsOrErr) {
4900 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4901 if (!CanonicalStr.empty())
4902 Archs.insert(CanonicalStr);
4907 StringRef CanonicalStr =
4909 if (!CanonicalStr.empty())
4910 Archs.insert(CanonicalStr);
4915 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4916 for (StringRef
Arch : Arg->getValues()) {
4917 if (
Arch ==
"all") {
4922 Archs.erase(ArchStr);
4928 if (
auto ConflictingArchs =
4930 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4931 << ConflictingArchs->first << ConflictingArchs->second;
4934 if (Archs.empty()) {
4944 Archs.insert(StringRef());
4947 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4948 .getLastArg(options::OPT_march_EQ)) {
4949 Archs.insert(Arg->getValue());
4954 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4955 <<
"--offload-arch";
4956 }
else if (!ArchsOrErr->empty()) {
4957 for (
auto Arch : *ArchsOrErr)
4958 Archs.insert(Args.MakeArgStringRef(
Arch));
4960 Archs.insert(StringRef());
4965 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4966 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4975 const InputTy &Input, StringRef CUID,
4985 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4987 bool HIPRelocatableObj =
4989 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4990 options::OPT_fno_hip_emit_relocatable,
false);
4992 if (!HIPNoRDC && HIPRelocatableObj)
4993 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4994 <<
"-fhip-emit-relocatable"
4998 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4999 <<
"-fhip-emit-relocatable"
5000 <<
"--offload-device-only";
5018 auto TCRange =
C.getOffloadToolChains(Kind);
5019 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5020 ToolChains.push_back(TI->second);
5022 if (ToolChains.empty())
5026 const Arg *InputArg = Input.second;
5035 for (
const ToolChain *TC : ToolChains) {
5037 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5038 DeviceActions.push_back(
5039 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5043 if (DeviceActions.empty())
5049 HostAction->
getType() != types::TY_Nothing &&
5059 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5068 auto *TCAndArch = TCAndArchs.begin();
5069 for (
Action *&A : DeviceActions) {
5070 if (A->
getType() == types::TY_Nothing)
5080 HostAction->
getType() != types::TY_Nothing) {
5087 TCAndArch->second.data(), Kind);
5089 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5099 for (
Action *&A : DeviceActions) {
5104 OffloadTriple && OffloadTriple->isSPIRV() &&
5105 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5106 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5107 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5108 options::OPT_no_use_spirv_backend,
5115 bool IsAMDGCNSPIRVWithBackend =
5116 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5119 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5120 A->
getType() != types::TY_LTO_BC) ||
5128 auto *TCAndArch = TCAndArchs.begin();
5129 for (
Action *A : DeviceActions) {
5130 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5132 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5137 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5139 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5148 bool ShouldBundleHIP =
5149 Args.hasFlag(options::OPT_gpu_bundle_output,
5150 options::OPT_no_gpu_bundle_output,
false) ||
5151 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5153 return A->
getType() != types::TY_Image;
5160 if (OffloadActions.empty())
5165 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5169 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5176 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5177 DDep.
add(*FatbinAction,
5180 }
else if (HIPNoRDC) {
5183 if (HIPAsmBundleDeviceOut &&
5185 for (
Action *OA : OffloadActions)
5186 HIPAsmBundleDeviceOut->push_back(OA);
5200 DDep.
add(*PackagerAction,
5209 nullptr,
C.getActiveOffloadKinds());
5218 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5219 return A->
getType() == types::TY_Nothing;
5223 nullptr, SingleDeviceOutput ? DDep : DDeps);
5224 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5230 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5240 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5246 llvm_unreachable(
"link action invalid here.");
5248 llvm_unreachable(
"ifsmerge action invalid here.");
5253 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5254 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5255 OutputTy = types::TY_Dependencies;
5260 if (!Args.hasFlag(options::OPT_frewrite_includes,
5261 options::OPT_fno_rewrite_includes,
false) &&
5262 !Args.hasFlag(options::OPT_frewrite_imports,
5263 options::OPT_fno_rewrite_imports,
false) &&
5264 !Args.hasFlag(options::OPT_fdirectives_only,
5265 options::OPT_fno_directives_only,
false) &&
5269 "Cannot preprocess this input type!");
5275 if (Args.hasArg(options::OPT_extract_api))
5284 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5285 (Input->
getType() == driver::types::TY_CXXModule ||
5286 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5287 !Args.getLastArg(options::OPT__precompile) &&
5288 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5293 "Cannot precompile this input type!");
5297 const char *ModName =
nullptr;
5298 if (OutputTy == types::TY_PCH) {
5299 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5300 ModName = A->getValue();
5302 OutputTy = types::TY_ModuleFile;
5305 if (Args.hasArg(options::OPT_fsyntax_only)) {
5307 OutputTy = types::TY_Nothing;
5313 if (Args.hasArg(options::OPT_fsyntax_only))
5315 if (Args.hasArg(options::OPT_rewrite_objc))
5317 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5319 types::TY_RewrittenLegacyObjC);
5320 if (Args.hasArg(options::OPT__analyze))
5322 if (Args.hasArg(options::OPT_emit_ast))
5324 if (Args.hasArg(options::OPT_emit_cir))
5326 if (Args.hasArg(options::OPT_module_file_info))
5328 if (Args.hasArg(options::OPT_verify_pch))
5330 if (Args.hasArg(options::OPT_extract_api))
5339 Args.hasFlag(options::OPT_offload_new_driver,
5340 options::OPT_no_offload_new_driver,
5343 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm)))
5348 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5349 !Args.hasArg(options::OPT_emit_llvm))
5350 Output = types::TY_PP_Asm;
5351 else if (Args.hasArg(options::OPT_S))
5352 Output = types::TY_LTO_IR;
5354 Output = types::TY_LTO_BC;
5359 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5362 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5363 options::OPT_no_use_spirv_backend,
5371 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5373 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5375 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5377 auto &DefaultToolChain =
C.getDefaultToolChain();
5378 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5383 bool EmitBitcodeForNonOffloadAMDSPIRV =
5384 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5385 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5386 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5388 if (Args.hasArg(options::OPT_emit_llvm) ||
5389 EmitBitcodeForNonOffloadAMDSPIRV ||
5395 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5396 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5398 (Args.hasFlag(options::OPT_offload_new_driver,
5399 options::OPT_no_offload_new_driver,
5401 !(Args.hasArg(options::OPT_S) &&
5402 !Args.hasArg(options::OPT_emit_llvm)) &&
5409 Args.hasArg(options::OPT_S) &&
5413 !Args.hasFlag(options::OPT_offload_new_driver,
5414 options::OPT_no_offload_new_driver,
5415 C.getActiveOffloadKinds() !=
5418 : types::TY_LLVM_BC;
5431 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5440 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5444 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5446 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5466 unsigned NumOutputs = 0;
5467 unsigned NumIfsOutputs = 0;
5468 for (
const Action *A :
C.getActions()) {
5474 if (A->
getType() != types::TY_Nothing &&
5476 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5478 0 == NumIfsOutputs++) ||
5483 A->
getType() == types::TY_Nothing &&
5484 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5485 NumOutputs += A->
size();
5488 if (NumOutputs > 1) {
5489 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5490 FinalOutput =
nullptr;
5494 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5498 if (RawTriple.isOSBinFormatMachO())
5499 for (
const Arg *A :
C.getArgs())
5500 if (A->getOption().matches(options::OPT_arch))
5504 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5505 for (
Action *A :
C.getActions()) {
5512 const char *LinkingOutput =
nullptr;
5515 LinkingOutput = FinalOutput->getValue();
5524 LinkingOutput, CachedResults,
5531 for (
auto &J :
C.getJobs())
5532 J.InProcess =
false;
5535 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5536 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5541 const char *LinkingOutput =
nullptr;
5543 LinkingOutput = FinalOutput->getValue();
5550 using namespace llvm;
5553 <<
"output=" << LinkingOutput;
5554 outs() <<
", total="
5555 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5557 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5558 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5562 llvm::raw_string_ostream Out(Buffer);
5563 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5566 llvm::sys::printArg(Out, LinkingOutput,
true);
5567 Out <<
',' << ProcStat->TotalTime.count() <<
','
5568 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5573 llvm::sys::fs::OF_Append |
5574 llvm::sys::fs::OF_Text);
5579 llvm::errs() <<
"ERROR: Cannot lock file "
5581 <<
toString(L.takeError()) <<
"\n";
5592 bool ReportUnusedArguments =
5593 !Diags.hasErrorOccurred() &&
5594 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5597 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5599 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5602 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5603 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5605 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5609 return strstr(J.getCreator().getShortName(),
"assembler");
5611 for (Arg *A :
C.getArgs()) {
5615 if (!A->isClaimed()) {
5621 const Option &Opt = A->getOption();
5622 if (Opt.getKind() == Option::FlagClass) {
5623 bool DuplicateClaimed =
false;
5625 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5626 if (AA->isClaimed()) {
5627 DuplicateClaimed =
true;
5632 if (DuplicateClaimed)
5638 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5640 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5645 !
C.getActions().empty()) {
5646 Diag(diag::err_drv_unsupported_opt_for_target)
5648 }
else if (ReportUnusedArguments) {
5649 Diag(clang::diag::warn_drv_unused_argument)
5650 << A->getAsString(
C.getArgs());
5660class ToolSelector final {
5671 bool IsHostSelector;
5682 bool CanBeCollapsed =
true) {
5684 if (Inputs.size() != 1)
5687 Action *CurAction = *Inputs.begin();
5688 if (CanBeCollapsed &&
5694 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5698 if (!IsHostSelector) {
5699 if (OA->hasSingleDeviceDependence(
true)) {
5701 OA->getSingleDeviceDependence(
true);
5702 if (CanBeCollapsed &&
5705 SavedOffloadAction.push_back(OA);
5706 return dyn_cast<JobAction>(CurAction);
5708 }
else if (OA->hasHostDependence()) {
5709 CurAction = OA->getHostDependence();
5710 if (CanBeCollapsed &&
5713 SavedOffloadAction.push_back(OA);
5714 return dyn_cast<JobAction>(CurAction);
5719 return dyn_cast<JobAction>(CurAction);
5723 bool canCollapseAssembleAction()
const {
5724 return TC.useIntegratedAs() && !SaveTemps &&
5725 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5726 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5727 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5728 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5732 bool canCollapsePreprocessorAction()
const {
5733 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5734 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5735 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5740 struct JobActionInfo final {
5742 const JobAction *JA =
nullptr;
5750 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5751 ArrayRef<JobActionInfo> &ActionInfo,
5752 unsigned ElementNum) {
5753 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5754 for (
unsigned I = 0; I < ElementNum; ++I)
5755 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5756 ActionInfo[I].SavedOffloadAction.end());
5769 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5772 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5774 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5775 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5776 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5777 if (!AJ || !BJ || !CJ)
5781 const Tool *T = TC.SelectTool(*CJ);
5794 const Tool *BT = TC.SelectTool(*BJ);
5802 Inputs = CJ->getInputs();
5803 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5807 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5810 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5812 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5813 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5818 const Tool *T = TC.SelectTool(*BJ);
5825 Inputs = BJ->getInputs();
5826 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5830 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5833 if (ActionInfo.size() < 2)
5835 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5836 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5840 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5841 for (
auto &Input : AI.JA->getInputs())
5852 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5853 if (SaveTemps && !InputIsBitcode)
5857 const Tool *T = TC.SelectTool(*CJ);
5870 Inputs = CJ->getInputs();
5871 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5880 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5888 for (Action *A : Inputs) {
5889 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5891 NewInputs.push_back(A);
5897 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5898 PreprocessJobOffloadActions.end());
5899 NewInputs.append(PJ->input_begin(), PJ->input_end());
5905 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5907 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5909 assert(BaseAction &&
"Invalid base action.");
5925 SmallVector<JobActionInfo, 5> ActionChain(1);
5926 ActionChain.back().JA = BaseAction;
5927 while (ActionChain.back().JA) {
5928 const Action *CurAction = ActionChain.back().JA;
5931 ActionChain.resize(ActionChain.size() + 1);
5932 JobActionInfo &AI = ActionChain.back();
5936 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5940 ActionChain.pop_back();
5948 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5949 CollapsedOffloadAction);
5951 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5953 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5959 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5971 StringRef BoundArch,
5973 std::string TriplePlusArch = TC->
getTriple().normalize();
5974 if (!BoundArch.empty()) {
5975 TriplePlusArch +=
"-";
5976 TriplePlusArch += BoundArch;
5978 TriplePlusArch +=
"-";
5980 return TriplePlusArch;
5985 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5986 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5989 std::pair<const Action *, std::string> ActionTC = {
5991 auto CachedResult = CachedResults.find(ActionTC);
5992 if (CachedResult != CachedResults.end()) {
5993 return CachedResult->second;
5996 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5997 CachedResults, TargetDeviceOffloadKind);
5998 CachedResults[ActionTC] =
Result;
6003 const JobAction *JA,
const char *BaseInput,
6006 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6017 OffloadingPrefix +=
"-";
6018 OffloadingPrefix +=
Arch;
6021 C.getDriver().isSaveTempsEnabled()) {
6028 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6029 Path = A->getValue();
6030 if (llvm::sys::fs::is_directory(Path)) {
6032 ? llvm::sys::path::stem(
Result.getFilename())
6033 : llvm::sys::path::stem(BaseInput));
6034 Tmp += OffloadingPrefix;
6036 llvm::sys::path::append(Path, Tmp);
6039 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6042 Path = DumpDir->getValue();
6043 Path += llvm::sys::path::stem(BaseInput);
6044 Path += OffloadingPrefix;
6046 }
else if (!OffloadingPrefix.empty()) {
6050 TraceName += OffloadingPrefix;
6051 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6052 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6053 llvm::sys::path::append(Path, TraceName);
6056 Path =
Result.getFilename();
6057 llvm::sys::path::replace_extension(Path,
"json");
6060 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6061 C.addTimeTraceFile(ResultFile, JA);
6062 C.addResultFile(ResultFile, JA);
6067 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6068 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6071 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6075 StringRef SavedBoundArch =
C.getCurrentBoundArch();
6076 C.setCurrentBoundArch(BoundArch);
6077 auto RestoreBoundArch =
6078 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
6081 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6082 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6114 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6116 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6117 const char *DepBoundArch) {
6120 LinkingOutput, CachedResults,
6130 OA->doOnEachDependence(
6131 BuildingForOffloadDevice,
6132 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6134 C, DepA, DepTC, DepBoundArch,
false,
6135 !!DepBoundArch, LinkingOutput, CachedResults,
6139 A = BuildingForOffloadDevice
6140 ? OA->getSingleDeviceDependence(
true)
6141 : OA->getHostDependence();
6145 std::pair<const Action *, std::string> ActionTC = {
6146 OA->getHostDependence(),
6148 auto It = CachedResults.find(ActionTC);
6149 if (It != CachedResults.end()) {
6151 Inputs.append(OffloadDependencesInputInfo);
6156 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6159 const Arg &Input = IA->getInputArg();
6161 if (Input.getOption().matches(options::OPT_INPUT)) {
6162 const char *
Name = Input.getValue();
6165 return {InputInfo(A, &Input,
"")};
6168 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6169 const ToolChain *TC;
6172 if (!ArchName.empty())
6173 TC = &getToolChain(
C.getArgs(),
6175 C.getArgs(), ArchName));
6177 TC = &
C.getDefaultToolChain();
6180 MultipleArchs, LinkingOutput, CachedResults,
6181 TargetDeviceOffloadKind);
6192 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6195 return {InputInfo()};
6199 for (
const auto *OA : CollapsedOffloadActions)
6201 BuildingForOffloadDevice,
6202 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6204 C, DepA, DepTC, DepBoundArch,
false,
6205 !!DepBoundArch, LinkingOutput, CachedResults,
6211 for (
const Action *Input : Inputs) {
6215 bool SubJobAtTopLevel =
6218 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6223 const char *BaseInput = InputInfos[0].getBaseInput();
6224 for (
auto &Info : InputInfos) {
6225 if (Info.isFilename()) {
6226 BaseInput = Info.getBaseInput();
6233 if (JA->
getType() == types::TY_dSYM)
6234 BaseInput = InputInfos[0].getFilename();
6237 if (!OffloadDependencesInputInfo.empty())
6238 InputInfos.append(OffloadDependencesInputInfo.begin(),
6239 OffloadDependencesInputInfo.end());
6242 llvm::Triple EffectiveTriple;
6244 const ArgList &Args =
6246 if (InputInfos.size() != 1) {
6252 Args, BoundArch, InputInfos[0].getType()));
6254 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6259 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6263 for (
auto &UI : UA->getDependentActionsInfo()) {
6265 "Unbundling with no offloading??");
6272 UI.DependentOffloadKind,
6273 UI.DependentToolChain->getTriple().normalize(),
6275 auto CurI = InputInfo(
6284 UnbundlingResults.push_back(CurI);
6293 Arch = UI.DependentBoundArch;
6298 UI.DependentOffloadKind)}] = {
6304 std::pair<const Action *, std::string> ActionTC = {
6306 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6307 "Result does not exist??");
6308 Result = CachedResults[ActionTC].front();
6309 }
else if (JA->
getType() == types::TY_Nothing)
6310 Result = {InputInfo(A, BaseInput)};
6320 AtTopLevel, MultipleArchs,
6329 <<
'"' <<
" - \"" << T->
getName() <<
"\", inputs: [";
6330 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6331 llvm::errs() << InputInfos[i].getAsString();
6333 llvm::errs() <<
", ";
6335 if (UnbundlingResults.empty())
6336 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6338 llvm::errs() <<
"], outputs: [";
6339 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6340 llvm::errs() << UnbundlingResults[i].getAsString();
6342 llvm::errs() <<
", ";
6344 llvm::errs() <<
"] \n";
6347 if (UnbundlingResults.empty())
6351 Args, LinkingOutput);
6357 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6358 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6370 if (ArgValue.empty()) {
6372 Filename = BaseName;
6373 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6375 llvm::sys::path::append(Filename, BaseName);
6378 if (!llvm::sys::path::has_extension(ArgValue)) {
6383 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6388 llvm::sys::path::replace_extension(Filename, Extension);
6391 return Args.MakeArgString(Filename.c_str());
6406 StringRef Suffix,
bool MultipleArchs,
6407 StringRef BoundArch,
6408 bool NeedUniqueDirectory)
const {
6410 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6411 std::optional<std::string> CrashDirectory =
6413 ? std::string(A->getValue())
6414 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6415 if (CrashDirectory) {
6416 if (!
getVFS().exists(*CrashDirectory))
6417 llvm::sys::fs::create_directories(*CrashDirectory);
6419 llvm::sys::path::append(Path, Prefix);
6420 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6421 if (std::error_code EC =
6422 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6423 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6427 if (MultipleArchs && !BoundArch.empty()) {
6428 if (NeedUniqueDirectory) {
6430 llvm::sys::path::append(TmpName,
6431 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6441 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6456 const char *BaseInput) {
6458 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6459 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6464 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6468 const char *BaseInput,
6469 StringRef OrigBoundArch,
bool AtTopLevel,
6471 StringRef OffloadingPrefix)
const {
6474 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6477 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6478 return C.addResultFile(FinalOutput->getValue(), &JA);
6482 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6484 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6486 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6487 NameArg = A->getValue();
6488 return C.addResultFile(
6498 if (JA.
getType() == types::TY_ModuleFile &&
6499 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6503 if (JA.
getType() == types::TY_PP_Asm &&
6504 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6505 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6508 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6511 if ((JA.
getType() == types::TY_Object &&
6512 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6513 JA.
getType() == types::TY_DX_CONTAINER) {
6514 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6515 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6516 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6517 "expected DXIL or SPIR-V triple for HLSL output path");
6522 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6524 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6525 StringRef
Name = llvm::sys::path::filename(BaseInput);
6526 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6532 if (JA.
getType() == types::TY_PP_Asm &&
6533 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6534 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6536 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6537 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6538 return C.addResultFile(
6543 if (JA.
getType() == types::TY_API_INFO &&
6544 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6545 C.getArgs().hasArg(options::OPT_o))
6546 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6547 <<
C.getArgs().getLastArgValue(options::OPT_o);
6554 bool SpecifiedModuleOutput =
6555 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6556 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6557 if (MultipleArchs && SpecifiedModuleOutput)
6558 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6563 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6564 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6570 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6572 StringRef
Name = llvm::sys::path::filename(BaseInput);
6573 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6574 const char *Suffix =
6579 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6580 bool NeedUniqueDirectory =
6583 Triple.isOSDarwin();
6584 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6585 NeedUniqueDirectory);
6594 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6599 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6600 llvm::sys::path::filename(BasePath));
6601 BaseName = ExternalPath;
6603 BaseName = BasePath;
6605 BaseName = llvm::sys::path::filename(BasePath);
6608 const char *NamedOutput;
6610 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6611 JA.
getType() == types::TY_LLVM_BC ||
6612 JA.
getType() == types::TY_LLVM_IR) &&
6613 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6617 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6621 }
else if (JA.
getType() == types::TY_Image &&
6622 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6623 options::OPT__SLASH_o)) {
6627 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6631 }
else if (JA.
getType() == types::TY_Image) {
6641 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6642 options::OPT_fno_gpu_rdc,
false);
6644 if (UseOutExtension) {
6646 llvm::sys::path::replace_extension(Output,
"");
6648 Output += OffloadingPrefix;
6649 if (MultipleArchs && !BoundArch.empty()) {
6651 Output.append(BoundArch);
6653 if (UseOutExtension)
6655 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6658 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6659 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6660 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6663 .getLastArg(options::OPT__SLASH_o)
6668 const char *Suffix =
6670 assert(Suffix &&
"All types used for output should have a suffix.");
6672 std::string::size_type End = std::string::npos;
6674 End = BaseName.rfind(
'.');
6676 Suffixed += OffloadingPrefix;
6677 if (MultipleArchs && !BoundArch.empty()) {
6679 Suffixed.append(BoundArch);
6684 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6685 const llvm::opt::DerivedArgList &Args) {
6692 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6694 Args.hasFlag(options::OPT_offload_new_driver,
6695 options::OPT_no_offload_new_driver,
true))) ||
6702 bool IsLinkerWrapper =
6704 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6705 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6706 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6708 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6712 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6716 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6717 JA.
getType() != types::TY_PCH) {
6718 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6720 llvm::sys::path::remove_filename(TempPath);
6721 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6722 llvm::sys::path::append(TempPath, OutputFileName);
6723 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6729 bool SameFile =
false;
6731 llvm::sys::fs::current_path(
Result);
6732 llvm::sys::path::append(
Result, BaseName);
6733 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6736 StringRef
Name = llvm::sys::path::filename(BaseInput);
6737 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6741 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6747 llvm::sys::path::remove_filename(BasePath);
6748 if (BasePath.empty())
6749 BasePath = NamedOutput;
6751 llvm::sys::path::append(BasePath, NamedOutput);
6752 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6755 return C.addResultFile(NamedOutput, &JA);
6761 -> std::optional<std::string> {
6764 for (
const auto &
Dir : P) {
6768 llvm::sys::path::append(P,
Name);
6769 if (llvm::sys::fs::exists(Twine(P)))
6770 return std::string(P);
6772 return std::nullopt;
6779 llvm::sys::path::append(R,
Name);
6780 if (llvm::sys::fs::exists(Twine(R)))
6781 return std::string(R);
6784 llvm::sys::path::append(P,
Name);
6785 if (llvm::sys::fs::exists(Twine(P)))
6786 return std::string(P);
6790 if (std::optional<std::string> IntrPath =
6793 llvm::sys::path::append(P,
Name);
6794 if (llvm::sys::fs::exists(P))
6795 return std::string(P);
6800 llvm::sys::path::append(D,
"..",
Name);
6801 if (llvm::sys::fs::exists(Twine(D)))
6802 return std::string(D);
6811 llvm::sys::path::append(R2,
"..",
"..",
Name);
6812 if (llvm::sys::fs::exists(Twine(R2)))
6813 return std::string(R2);
6815 return std::string(
Name);
6818void Driver::generatePrefixedToolNames(
6822 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6823 Names.emplace_back(
Tool);
6827 llvm::sys::path::append(Dir, Name);
6828 if (llvm::sys::fs::can_execute(Twine(Dir)))
6830 llvm::sys::path::remove_filename(Dir);
6836 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6841 if (llvm::sys::fs::is_directory(PrefixDir)) {
6844 return std::string(P);
6847 if (llvm::sys::fs::can_execute(Twine(P)))
6848 return std::string(P);
6853 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6861 for (
const auto &Path : List) {
6864 return std::string(P);
6868 if (llvm::ErrorOr<std::string> P =
6869 llvm::sys::findProgramByName(TargetSpecificExecutable))
6873 return std::string(
Name);
6878 std::string error =
"<NOT PRESENT>";
6880 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6885 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6902 llvm::sys::path::remove_filename(path);
6903 llvm::sys::path::append(path,
"libc++.modules.json");
6904 if (TC.
getVFS().exists(path))
6905 return static_cast<std::string
>(path);
6910 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6913 return evaluate(
"libc++.a").value_or(error);
6917 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6921 llvm::sys::path::remove_filename(path);
6922 llvm::sys::path::append(path,
"libstdc++.modules.json");
6923 if (TC.
getVFS().exists(path))
6924 return static_cast<std::string
>(path);
6929 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6932 return evaluate(
"libstdc++.a").value_or(error);
6941 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6943 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6947 return std::string(Path);
6952 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6954 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6958 return std::string(Path);
6963 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6967 Output = FpArg->getValue();
6971 if (!llvm::sys::path::has_extension(Output))
6974 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6975 Output = YcArg->getValue();
6978 llvm::sys::path::replace_extension(Output,
".pch");
6980 return std::string(Output);
6983const ToolChain &Driver::getOffloadToolChain(
6985 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6986 std::unique_ptr<ToolChain> &TC =
6987 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6988 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6990 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6993 switch (
Target.getOS()) {
6994 case llvm::Triple::CUDA:
6995 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6998 case llvm::Triple::AMDHSA:
7000 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
7003 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
7012 switch (
Target.getArch()) {
7013 case llvm::Triple::spir:
7014 case llvm::Triple::spir64:
7015 case llvm::Triple::spirv:
7016 case llvm::Triple::spirv32:
7017 case llvm::Triple::spirv64:
7020 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
7024 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7028 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7032 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7046 return getToolChain(Args,
Target);
7050const ToolChain &Driver::getToolChain(
const ArgList &Args,
7051 const llvm::Triple &
Target)
const {
7053 auto &TC = ToolChains[
Target.str()];
7055 switch (
Target.getOS()) {
7056 case llvm::Triple::AIX:
7057 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7059 case llvm::Triple::Haiku:
7060 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7062 case llvm::Triple::Darwin:
7063 case llvm::Triple::MacOSX:
7064 case llvm::Triple::IOS:
7065 case llvm::Triple::TvOS:
7066 case llvm::Triple::WatchOS:
7067 case llvm::Triple::XROS:
7068 case llvm::Triple::DriverKit:
7069 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7071 case llvm::Triple::DragonFly:
7072 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7074 case llvm::Triple::OpenBSD:
7075 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7077 case llvm::Triple::NetBSD:
7078 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7080 case llvm::Triple::FreeBSD:
7082 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7085 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7087 case llvm::Triple::Linux:
7088 case llvm::Triple::ELFIAMCU:
7089 if (
Target.getArch() == llvm::Triple::hexagon)
7090 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7092 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7093 !
Target.hasEnvironment())
7094 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7097 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7099 else if (
Target.getArch() == llvm::Triple::ve)
7100 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7101 else if (
Target.isOHOSFamily())
7102 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7103 else if (
Target.isWALI())
7104 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7106 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7108 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7110 case llvm::Triple::Fuchsia:
7111 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7113 case llvm::Triple::Managarm:
7114 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7116 case llvm::Triple::Serenity:
7117 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7119 case llvm::Triple::Solaris:
7120 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7122 case llvm::Triple::CUDA:
7123 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7125 case llvm::Triple::AMDHSA: {
7126 if (
Target.getArch() == llvm::Triple::spirv64) {
7127 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7132 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7134 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7139 case llvm::Triple::AMDPAL:
7140 case llvm::Triple::Mesa3D:
7141 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7143 case llvm::Triple::UEFI:
7144 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7146 case llvm::Triple::Win32:
7147 switch (
Target.getEnvironment()) {
7149 if (
Target.isOSBinFormatELF())
7150 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7151 else if (
Target.isOSBinFormatMachO())
7152 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7154 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7156 case llvm::Triple::GNU:
7157 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7159 case llvm::Triple::Cygnus:
7160 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7162 case llvm::Triple::Itanium:
7163 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7166 case llvm::Triple::MSVC:
7167 case llvm::Triple::UnknownEnvironment:
7168 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7169 .starts_with_insensitive(
"bfd"))
7170 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7174 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7178 case llvm::Triple::PS4:
7179 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7181 case llvm::Triple::PS5:
7182 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7184 case llvm::Triple::Hurd:
7185 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7187 case llvm::Triple::LiteOS:
7188 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7190 case llvm::Triple::ZOS:
7191 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7193 case llvm::Triple::Vulkan:
7194 case llvm::Triple::ShaderModel:
7195 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7196 Target.getArch() == llvm::Triple::spirv64) &&
7198 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7200 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7202 case llvm::Triple::ChipStar:
7203 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7208 switch (
Target.getArch()) {
7209 case llvm::Triple::tce:
7210 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7212 case llvm::Triple::tcele:
7213 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7215 case llvm::Triple::tcele64:
7217 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7219 case llvm::Triple::hexagon:
7220 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7223 case llvm::Triple::lanai:
7224 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7226 case llvm::Triple::xcore:
7227 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7229 case llvm::Triple::wasm32:
7230 case llvm::Triple::wasm64:
7231 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7233 case llvm::Triple::avr:
7234 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7236 case llvm::Triple::msp430:
7237 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7239 case llvm::Triple::riscv32:
7240 case llvm::Triple::riscv64:
7241 case llvm::Triple::riscv32be:
7242 case llvm::Triple::riscv64be:
7243 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7245 case llvm::Triple::ve:
7246 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7248 case llvm::Triple::spirv32:
7249 case llvm::Triple::spirv64:
7250 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7252 case llvm::Triple::csky:
7253 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7255 case llvm::Triple::amdgcn:
7256 case llvm::Triple::r600:
7257 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7261 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7262 else if (
Target.isOSBinFormatELF())
7263 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7264 else if (
Target.isAppleFirmware())
7265 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7266 else if (
Target.isAppleMachO())
7267 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7268 else if (
Target.isOSBinFormatMachO())
7269 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7271 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7281 if (JA.
size() != 1 ||
7296 if (JA.
size() != 1 ||
7310 if (Args.hasArg(options::OPT_emit_static_lib))
7321 unsigned &Micro,
bool &HadExtra) {
7324 Major = Minor = Micro = 0;
7328 if (Str.consumeInteger(10, Major))
7332 if (!Str.consume_front(
"."))
7335 if (Str.consumeInteger(10, Minor))
7339 if (!Str.consume_front(
"."))
7342 if (Str.consumeInteger(10, Micro))
7360 unsigned CurDigit = 0;
7361 while (CurDigit < Digits.size()) {
7363 if (Str.consumeInteger(10, Digit))
7365 Digits[CurDigit] = Digit;
7368 if (!Str.consume_front(
"."))
7377llvm::opt::Visibility
7378Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7391const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7407 llvm_unreachable(
"Unhandled Mode");
7411 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7416 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7417 options::OPT_fno_save_optimization_record,
false))
7421 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7422 options::OPT_fno_save_optimization_record,
false))
7426 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7427 options::OPT_fno_save_optimization_record,
false))
7431 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7432 options::OPT_fno_save_optimization_record,
false))
7439 static StringRef OptName =
7441 llvm::StringRef Opt;
7442 for (StringRef Arg : Args) {
7443 if (!Arg.starts_with(OptName))
7449 return Opt.consume_front(OptName) ? Opt :
"";
7456 llvm::BumpPtrAllocator &Alloc,
7457 llvm::vfs::FileSystem *FS) {
7466 for (
const char *F : Args) {
7467 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7469 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7470 RSPQuoting = Windows;
7476 bool MarkEOLs = ClangCLMode;
7478 llvm::cl::TokenizerCallback Tokenizer;
7479 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7480 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7482 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7484 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7487 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7488 ECtx.setMarkEOLs(MarkEOLs);
7492 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7496 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7497 [](
const char *A) {
return A !=
nullptr; });
7498 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7501 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7502 Args.resize(newEnd - Args.begin());
7506 return llvm::Error::success();
7510 return SavedStrings.insert(S).first->getKeyData();
7544 llvm::StringSet<> &SavedStrings) {
7547 if (Edit[0] ==
'^') {
7548 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7549 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7550 Args.insert(Args.begin() + 1, Str);
7551 }
else if (Edit[0] ==
'+') {
7552 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7553 OS <<
"### Adding argument " << Str <<
" at end\n";
7554 Args.push_back(Str);
7555 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7556 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7557 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7558 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7559 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7561 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7563 if (Args[i] ==
nullptr)
7565 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7567 if (Repl != Args[i]) {
7568 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7572 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7573 auto Option = Edit.substr(1);
7574 for (
unsigned i = 1; i < Args.size();) {
7575 if (Option == Args[i]) {
7576 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7577 Args.erase(Args.begin() + i);
7578 if (Edit[0] ==
'X') {
7579 if (i < Args.size()) {
7580 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7581 Args.erase(Args.begin() + i);
7583 OS <<
"### Invalid X edit, end of command line!\n";
7588 }
else if (Edit[0] ==
'O') {
7589 for (
unsigned i = 1; i < Args.size();) {
7590 const char *A = Args[i];
7594 if (A[0] ==
'-' && A[1] ==
'O' &&
7595 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7596 (
'0' <= A[2] && A[2] <=
'9'))))) {
7597 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7598 Args.erase(Args.begin() + i);
7602 OS <<
"### Adding argument " << Edit <<
" at end\n";
7603 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7605 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7610 const char *OverrideStr,
7611 llvm::StringSet<> &SavedStrings,
7612 StringRef EnvVar, raw_ostream *OS) {
7614 OS = &llvm::nulls();
7616 if (OverrideStr[0] ==
'#') {
7618 OS = &llvm::nulls();
7621 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7625 const char *S = OverrideStr;
7627 const char *End = ::strchr(S,
' ');
7629 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
std::multiset< llvm::Triple > TripleSet
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static bool shouldBundleHIPAsmWithNewDriver(const Compilation &C, const llvm::opt::DerivedArgList &Args, const Driver &D)
HIP non-RDC -S for AMDGCN: emit host and device assembly separately and bundle with clang-offload-bun...
static TripleSet inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static StringRef getTriple(const Command &Job)
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
StringRef getBoundArch() const
Return the bound architecture for this command, if any.
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
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...
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
llvm::SmallVector< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
void buildStdModuleManifestInputs(ArrayRef< StdModuleManifest::Module > ManifestEntries, Compilation &C, InputList &Inputs)
Constructs compilation inputs for each module listed in the provided Standard library module manifest...
void runModulesDriver(Compilation &C, ArrayRef< StdModuleManifest::Module > ManifestEntries)
Scans the compilation inputs for module dependencies and adjusts the compilation to build and supply ...
llvm::Expected< StdModuleManifest > readStdModuleManifest(llvm::StringRef ManifestPath, llvm::vfs::FileSystem &VFS)
Reads the Standard library module manifest at ManifestPath.
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.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
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.
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