60#include "clang/Config/config.h"
76#include "llvm/ADT/ArrayRef.h"
77#include "llvm/ADT/STLExtras.h"
78#include "llvm/ADT/SmallSet.h"
79#include "llvm/ADT/SmallVector.h"
80#include "llvm/ADT/StringExtras.h"
81#include "llvm/ADT/StringRef.h"
82#include "llvm/ADT/StringSet.h"
83#include "llvm/ADT/StringSwitch.h"
84#include "llvm/Config/llvm-config.h"
85#include "llvm/MC/TargetRegistry.h"
86#include "llvm/Option/Arg.h"
87#include "llvm/Option/ArgList.h"
88#include "llvm/Option/OptSpecifier.h"
89#include "llvm/Option/OptTable.h"
90#include "llvm/Option/Option.h"
91#include "llvm/Support/CommandLine.h"
92#include "llvm/Support/ErrorHandling.h"
93#include "llvm/Support/ExitCodes.h"
94#include "llvm/Support/FileSystem.h"
95#include "llvm/Support/FileUtilities.h"
96#include "llvm/Support/FormatVariadic.h"
97#include "llvm/Support/IOSandbox.h"
98#include "llvm/Support/JSON.h"
99#include "llvm/Support/MD5.h"
100#include "llvm/Support/Path.h"
101#include "llvm/Support/PrettyStackTrace.h"
102#include "llvm/Support/Process.h"
103#include "llvm/Support/Program.h"
104#include "llvm/Support/Regex.h"
105#include "llvm/Support/StringSaver.h"
106#include "llvm/Support/VirtualFileSystem.h"
107#include "llvm/Support/raw_ostream.h"
108#include "llvm/TargetParser/Host.h"
109#include "llvm/TargetParser/RISCVISAInfo.h"
122using namespace clang;
125template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
126 return llvm::any_of(Args, [&](Arg *A) {
127 return (A->getOption().matches(options::OPT_x) &&
129 (A->getOption().
getKind() == Option::InputClass &&
130 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
132 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
138 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
139 StringRef UseCUIDStr = A->getValue();
140 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
141 .Case(
"hash", Kind::Hash)
142 .Case(
"random", Kind::Random)
143 .Case(
"none", Kind::None)
144 .Default(Kind::Invalid);
145 if (UseCUID == Kind::Invalid)
146 D.Diag(clang::diag::err_drv_invalid_value)
147 << A->getAsString(Args) << UseCUIDStr;
150 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
151 if (!FixedCUID.empty())
156 llvm::opt::DerivedArgList &Args)
const {
157 std::string CUID = FixedCUID.str();
160 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
164 llvm::MD5::MD5Result
Hash;
165 Hasher.update(InputFile);
166 for (
auto *A : Args) {
167 if (A->getOption().matches(options::OPT_INPUT))
169 Hasher.update(A->getAsString(Args));
172 CUID = llvm::utohexstr(
Hash.low(),
true);
180 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
181 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
188 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
189 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
190 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
193 this->VFS = llvm::vfs::getRealFileSystem();
198 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
201 llvm::sys::path::append(P,
SysRoot);
205#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
206 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
210 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
211 llvm::sys::path::remove_dots(configFileDir,
true);
215#if defined(CLANG_CONFIG_FILE_USER_DIR)
218 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
227void Driver::setDriverMode(StringRef
Value) {
228 static StringRef OptName =
229 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
230 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
231 .Case(
"gcc", GCCMode)
232 .Case(
"g++", GXXMode)
233 .Case(
"cpp", CPPMode)
235 .Case(
"flang", FlangMode)
236 .Case(
"dxc", DXCMode)
240 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
245 bool &ContainsError)
const {
246 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
247 ContainsError =
false;
249 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
250 unsigned MissingArgIndex, MissingArgCount;
251 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
252 MissingArgCount, VisibilityMask);
255 if (MissingArgCount) {
256 Diag(diag::err_drv_missing_argument)
257 << Args.getArgString(MissingArgIndex) << MissingArgCount;
259 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
264 for (
const Arg *A : Args) {
266 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
267 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
274 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
275 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
276 ContainsError |= Diags.getDiagnosticLevel(
277 diag::warn_drv_empty_joined_argument,
282 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
284 auto ArgString = A->getAsString(Args);
286 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
288 if (
getOpts().findExact(ArgString, Nearest,
290 DiagID = diag::err_drv_unknown_argument_with_suggestion;
291 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
293 DiagID = diag::err_drv_unknown_argument;
294 Diags.Report(DiagID) << ArgString;
297 llvm::opt::Visibility(
299 DiagID = diag::err_drv_unknown_argument_with_suggestion;
300 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
302 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
303 : diag::err_drv_unknown_argument;
304 Diags.Report(DiagID) << ArgString;
308 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
309 : diag::err_drv_unknown_argument_with_suggestion;
310 Diags.Report(DiagID) << ArgString << Nearest;
312 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
316 for (
const Arg *A : Args.filtered(options::OPT_o)) {
317 if (ArgStrings[A->getIndex()] == A->getSpelling())
321 std::string ArgString = ArgStrings[A->getIndex()];
323 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
324 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
325 << A->getAsString(Args) << Nearest;
335 Arg **FinalPhaseArg)
const {
336 Arg *PhaseArg =
nullptr;
340 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
341 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
342 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
343 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
350 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
352 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
353 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
355 options::OPT_fmodule_header_EQ))) {
358 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
361 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
368 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
376 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
379 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
387 *FinalPhaseArg = PhaseArg;
395 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
396 llvm::sys::fs::OF_Text);
397 llvm::FileRemover OutputRemover(OutputFile.c_str());
398 std::optional<llvm::StringRef> Redirects[] = {
404 std::string ErrorMessage;
405 int SecondsToWait = 60;
406 if (std::optional<std::string> Str =
407 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
408 if (!llvm::to_integer(*Str, SecondsToWait))
409 return llvm::createStringError(std::error_code(),
410 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
411 "an integer, got '" +
413 SecondsToWait = std::max(SecondsToWait, 0);
415 StringRef Executable = Args[0];
416 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
418 return llvm::createStringError(std::error_code(),
419 Executable +
": " + ErrorMessage);
421 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
422 llvm::MemoryBuffer::getFile(OutputFile.c_str());
424 return llvm::createStringError(OutputBuf.getError(),
425 "Failed to read stdout of " + Executable +
426 ": " + OutputBuf.getError().message());
427 return std::move(*OutputBuf);
431 StringRef
Value,
bool Claim) {
432 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
433 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
434 Args.AddSynthesizedArg(A);
440DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
441 const llvm::opt::OptTable &Opts =
getOpts();
442 DerivedArgList *DAL =
new DerivedArgList(Args);
444 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
445 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
446 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
447 bool IgnoreUnused =
false;
448 for (Arg *A : Args) {
452 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
456 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
457 IgnoreUnused =
false;
467 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
468 A->getOption().matches(options::OPT_Xlinker)) &&
469 A->containsValue(
"--no-demangle")) {
471 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
474 for (StringRef Val : A->getValues())
475 if (Val !=
"--no-demangle")
476 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
484 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
485 A->getNumValues() > 0 &&
486 (A->getValue(0) == StringRef(
"-MD") ||
487 A->getValue(0) == StringRef(
"-MMD"))) {
489 if (A->getValue(0) == StringRef(
"-MD"))
490 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
492 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
493 if (A->getNumValues() == 2)
494 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
499 if (A->getOption().matches(options::OPT_l)) {
500 StringRef
Value = A->getValue();
503 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
505 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
510 if (
Value ==
"cc_kext") {
511 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
517 if (A->getOption().matches(options::OPT__DASH_DASH)) {
519 for (StringRef Val : A->getValues())
528 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
529 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
532 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
533 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
537#if defined(HOST_LINK_VERSION)
538 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
539 strlen(HOST_LINK_VERSION) > 0) {
540 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
542 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
550 StringRef ArgTarget) {
552 static bool BeSilent =
false;
553 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
554 return ((v < 2) || ((v == 2) && (r < 4)));
558 if (ArgTarget.equals_insensitive(
"CURRENT")) {
562 unsigned int Version = 0;
563 unsigned int Release = 0;
564 unsigned int Modification = 0;
566 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
567 llvm::Regex HexRegex(
570 "([0-9a-fA-F][0-9a-fA-F])"
571 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
574 if (ZOsvRegex.match(ArgTarget, &Matches)) {
575 Matches[1].getAsInteger(10, Version);
576 Matches[2].getAsInteger(10, Release);
578 if (IsTooOldToBeSupported(Version, Release)) {
580 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
583 }
else if (HexRegex.match(ArgTarget, &Matches)) {
584 Matches[1].getAsInteger(16, Version);
585 Matches[2].getAsInteger(16, Release);
586 Matches[3].getAsInteger(16, Modification);
587 if (IsTooOldToBeSupported(Version, Release)) {
589 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
595 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
600 llvm::VersionTuple
V(Version, Release, Modification);
601 llvm::VersionTuple TV =
Target.getOSVersion();
604 if (TV.empty() ||
V < TV) {
606 Str = llvm::Triple::getOSTypeName(
Target.getOS());
607 Str +=
V.getAsString();
620 StringRef TargetTriple,
622 StringRef DarwinArchName =
"") {
624 if (
const Arg *A = Args.getLastArg(options::OPT_target))
625 TargetTriple = A->getValue();
627 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
632 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
636 if (
Target.isOSBinFormatMachO()) {
638 if (!DarwinArchName.empty()) {
645 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
646 StringRef ArchName = A->getValue();
653 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
654 options::OPT_mbig_endian)) {
655 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
656 ?
Target.getLittleEndianArchVariant()
657 :
Target.getBigEndianArchVariant();
658 if (T.getArch() != llvm::Triple::UnknownArch) {
660 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
665 if (
Target.getArch() == llvm::Triple::tce)
670 if (std::optional<std::string> ObjectModeValue =
671 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
672 StringRef ObjectMode = *ObjectModeValue;
673 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
675 if (ObjectMode ==
"64") {
676 AT =
Target.get64BitArchVariant().getArch();
677 }
else if (ObjectMode ==
"32") {
678 AT =
Target.get32BitArchVariant().getArch();
680 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
683 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
689 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
690 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
693 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
695 D.
Diag(diag::err_drv_unsupported_opt_for_target)
696 << A->getAsString(Args) <<
Target.str();
699 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
700 options::OPT_m32, options::OPT_m16,
701 options::OPT_maix32, options::OPT_maix64);
703 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
705 if (A->getOption().matches(options::OPT_m64) ||
706 A->getOption().matches(options::OPT_maix64)) {
707 AT =
Target.get64BitArchVariant().getArch();
708 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
709 Target.getEnvironment() == llvm::Triple::GNUT64)
710 Target.setEnvironment(llvm::Triple::GNU);
711 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
712 Target.setEnvironment(llvm::Triple::Musl);
713 }
else if (A->getOption().matches(options::OPT_mx32) &&
714 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
715 AT = llvm::Triple::x86_64;
716 if (
Target.getEnvironment() == llvm::Triple::Musl)
717 Target.setEnvironment(llvm::Triple::MuslX32);
719 Target.setEnvironment(llvm::Triple::GNUX32);
720 }
else if (A->getOption().matches(options::OPT_m32) ||
721 A->getOption().matches(options::OPT_maix32)) {
723 D.
Diag(diag::err_drv_unsupported_opt_for_target)
724 << A->getAsString(Args) <<
Target.str();
726 AT =
Target.get32BitArchVariant().getArch();
727 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
728 Target.setEnvironment(llvm::Triple::GNU);
729 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
730 Target.setEnvironment(llvm::Triple::Musl);
732 }
else if (A->getOption().matches(options::OPT_m16) &&
733 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
734 AT = llvm::Triple::x86;
735 Target.setEnvironment(llvm::Triple::CODE16);
738 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
740 if (
Target.isWindowsGNUEnvironment())
746 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
752 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
753 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
754 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
757 if (A && !A->getOption().matches(options::OPT_m32))
758 D.
Diag(diag::err_drv_argument_not_allowed_with)
759 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
761 Target.setArch(llvm::Triple::x86);
762 Target.setArchName(
"i586");
763 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
764 Target.setEnvironmentName(
"");
765 Target.setOS(llvm::Triple::ELFIAMCU);
766 Target.setVendor(llvm::Triple::UnknownVendor);
767 Target.setVendorName(
"intel");
773 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
774 StringRef ABIName = A->getValue();
775 if (ABIName ==
"32") {
777 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
778 Target.getEnvironment() == llvm::Triple::GNUABIN32)
779 Target.setEnvironment(llvm::Triple::GNU);
780 }
else if (ABIName ==
"n32") {
782 if (
Target.getEnvironment() == llvm::Triple::GNU ||
783 Target.getEnvironment() == llvm::Triple::GNUT64 ||
784 Target.getEnvironment() == llvm::Triple::GNUABI64)
785 Target.setEnvironment(llvm::Triple::GNUABIN32);
786 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
787 Target.getEnvironment() == llvm::Triple::MuslABI64)
788 Target.setEnvironment(llvm::Triple::MuslABIN32);
789 }
else if (ABIName ==
"64") {
791 if (
Target.getEnvironment() == llvm::Triple::GNU ||
792 Target.getEnvironment() == llvm::Triple::GNUT64 ||
793 Target.getEnvironment() == llvm::Triple::GNUABIN32)
794 Target.setEnvironment(llvm::Triple::GNUABI64);
795 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
796 Target.getEnvironment() == llvm::Triple::MuslABIN32)
797 Target.setEnvironment(llvm::Triple::MuslABI64);
805 if (Args.hasArg(options::OPT_march_EQ) ||
806 Args.hasArg(options::OPT_mcpu_EQ)) {
808 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
810 if (!llvm::errorToBool(ISAInfo.takeError())) {
811 unsigned XLen = (*ISAInfo)->getXLen();
813 if (
Target.isLittleEndian())
814 Target.setArch(llvm::Triple::riscv32);
816 Target.setArch(llvm::Triple::riscv32be);
817 }
else if (XLen == 64) {
818 if (
Target.isLittleEndian())
819 Target.setArch(llvm::Triple::riscv64);
821 Target.setArch(llvm::Triple::riscv64be);
827 if (
Target.getArch() == llvm::Triple::riscv32be ||
828 Target.getArch() == llvm::Triple::riscv64be) {
829 static bool WarnedRISCVBE =
false;
830 if (!WarnedRISCVBE) {
831 D.
Diag(diag::warn_drv_riscv_be_experimental);
832 WarnedRISCVBE =
true;
843 OptSpecifier OptEq, OptSpecifier OptNeg) {
844 if (!Args.hasFlag(OptEq, OptNeg,
false))
847 const Arg *A = Args.getLastArg(OptEq);
848 StringRef LTOName = A->getValue();
856 D.
Diag(diag::err_drv_unsupported_option_argument)
857 << A->getSpelling() << A->getValue();
864void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
866 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
868 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
869 options::OPT_fno_offload_lto);
872 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
873 options::OPT_fno_openmp_target_jit,
false)) {
874 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
875 options::OPT_fno_offload_lto))
877 Diag(diag::err_drv_incompatible_options)
878 << A->getSpelling() <<
"-fopenmp-target-jit";
885 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
887 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
889 RuntimeName = A->getValue();
891 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
899 Diag(diag::err_drv_unsupported_option_argument)
900 << A->getSpelling() << A->getValue();
903 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
912 StringRef Program =
C.getArgs().getLastArgValue(
913 options::OPT_offload_arch_tool_EQ,
"offload-arch");
916 if (llvm::ErrorOr<std::string> Executable =
917 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
920 Args.push_back(
"--only=amdgpu");
922 Args.push_back(
"--only=nvptx");
923 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
926 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
931 if ((*StdoutOrErr)->getBuffer().empty()) {
932 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
938 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
940 GPUArchs.push_back(
Arch.str());
942 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
953 std::set<std::string> Archs;
954 for (Arg *A :
C.getInputArgs()) {
955 for (StringRef
Arch : A->getValues()) {
956 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
957 if (
Arch ==
"native") {
959 Archs.insert(Str.str());
961 Archs.insert(
Arch.str());
963 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
967 Archs.erase(
Arch.str());
973 for (llvm::StringRef
Arch : Archs) {
977 llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
978 llvm::Triple::AMD, llvm::Triple::AMDHSA),
982 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
987 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
993 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
998 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
999 <<
"offload" <<
Arch;
1003 llvm::Triple Triple =
1009 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1010 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1011 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1012 C.getArgs().MakeArgString(Triple.getArchName()),
1013 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1015 C.getArgs().append(A);
1016 C.getArgs().AddSynthesizedArg(A);
1018 auto It = Triples.lower_bound(Triple);
1019 if (It == Triples.end() || *It != Triple)
1020 Triples.insert(It, Triple);
1025 Triples.insert(llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
1026 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1028 llvm::Triple::ArchType
Arch =
1029 C.getDefaultToolChain().getTriple().isArch64Bit()
1030 ? llvm::Triple::nvptx64
1031 : llvm::Triple::nvptx;
1032 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1033 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1036 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1037 ? llvm::Triple::spirv64
1038 : llvm::Triple::spirv32));
1041 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1042 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1049 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1050 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1052 llvm::any_of(Inputs,
1053 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1058 (llvm::any_of(Inputs,
1059 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1062 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1063 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1065 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1066 options::OPT_fno_sycl,
false);
1067 bool IsOpenMPOffloading =
1069 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1070 options::OPT_fno_openmp,
false) &&
1071 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1072 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1073 !(IsCuda || IsHIP))));
1075 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1076 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1081 for (
const auto &[Active, Kind] : ActiveKinds)
1086 if (Kinds.size() > 1) {
1087 Diag(clang::diag::err_drv_mix_offload)
1094 if (IsCuda || IsHIP)
1101 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1102 std::vector<std::string> ArgValues =
1103 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1104 for (llvm::StringRef
Target : ArgValues) {
1108 if (ArgValues.empty())
1109 Diag(clang::diag::warn_drv_empty_joined_argument)
1111 .getLastArg(options::OPT_offload_targets_EQ)
1112 ->getAsString(
C.getInputArgs());
1119 llvm::StringMap<StringRef> FoundNormalizedTriples;
1120 for (
const llvm::Triple &
Target : Triples) {
1125 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1133 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1134 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1135 Diag(clang::diag::err_drv_argument_not_allowed_with)
1136 << IncompatArg->getSpelling() <<
"-fsycl";
1141 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1142 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1147 std::string NormalizedName =
Target.normalize();
1148 auto [TripleIt, Inserted] =
1149 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1151 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1152 <<
Target.str() << TripleIt->second;
1156 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1157 C.getDefaultToolChain().getTriple());
1161 auto &CudaInstallation =
1163 if (CudaInstallation.isValid())
1164 CudaInstallation.WarnIfUnsupportedVersion();
1167 C.addOffloadDeviceToolChain(&TC, Kind);
1172bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1177 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1181 if (!PathLIBEnv.empty()) {
1182 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1183 if (llvm::sys::fs::is_directory(PathLIBEnv))
1184 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1185 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1186 return readConfigFile(CustomizationFile, ExpCtx);
1187 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1192 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1193 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1194 return readConfigFile(CustomizationFile, ExpCtx);
1204 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1205 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1206 Copy->getValues() = Opt->getValues();
1207 if (Opt->isClaimed())
1209 Copy->setOwnsValues(Opt->getOwnsValues());
1210 Opt->setOwnsValues(
false);
1212 if (Opt->getAlias()) {
1213 const Arg *Alias = Opt->getAlias();
1214 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1215 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1216 Args.getArgString(Index), Index);
1217 AliasCopy->getValues() = Alias->getValues();
1218 AliasCopy->setOwnsValues(
false);
1219 if (Alias->isClaimed())
1221 Copy->setAlias(std::move(AliasCopy));
1225bool Driver::readConfigFile(StringRef
FileName,
1226 llvm::cl::ExpansionContext &ExpCtx) {
1230 Diag(diag::err_drv_cannot_open_config_file)
1231 <<
FileName << Status.getError().message();
1234 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1235 Diag(diag::err_drv_cannot_open_config_file)
1236 <<
FileName <<
"not a regular file";
1241 SmallVector<const char *, 32> NewCfgFileArgs;
1242 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1243 Diag(diag::err_drv_cannot_read_config_file)
1249 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1250 for (
const char *Opt : NewCfgFileArgs) {
1252 if (Opt[0] ==
'$' && Opt[1])
1253 NewCfgTailArgs.push_back(Opt + 1);
1255 NewCfgHeadArgs.push_back(Opt);
1259 llvm::SmallString<128> CfgFileName(
FileName);
1260 llvm::sys::path::native(CfgFileName);
1261 bool ContainErrors =
false;
1262 auto NewHeadOptions = std::make_unique<InputArgList>(
1266 auto NewTailOptions = std::make_unique<InputArgList>(
1273 for (Arg *A : *NewHeadOptions)
1275 for (Arg *A : *NewTailOptions)
1278 if (!CfgOptionsHead)
1279 CfgOptionsHead = std::move(NewHeadOptions);
1282 for (
auto *Opt : *NewHeadOptions)
1286 if (!CfgOptionsTail)
1287 CfgOptionsTail = std::move(NewTailOptions);
1290 for (
auto *Opt : *NewTailOptions)
1294 ConfigFiles.push_back(std::string(CfgFileName));
1298bool Driver::loadConfigFiles() {
1299 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1300 llvm::cl::tokenizeConfigFile, &
getVFS());
1304 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1305 SmallString<128> CfgDir;
1307 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1308 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1313 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1314 SmallString<128> CfgDir;
1315 llvm::sys::fs::expand_tilde(
1316 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1317 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1326 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1329 if (loadDefaultConfigFiles(ExpCtx))
1333 SmallString<128> CfgFilePath;
1335 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1338 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1339 CfgFilePath.assign(CfgFileName);
1340 if (llvm::sys::path::is_relative(CfgFilePath)) {
1341 if (
getVFS().makeAbsolute(CfgFilePath)) {
1342 Diag(diag::err_drv_cannot_open_config_file)
1343 << CfgFilePath <<
"cannot get absolute path";
1347 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1349 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1350 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1351 if (!SearchDir.empty())
1352 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1357 if (readConfigFile(CfgFilePath, ExpCtx))
1368 llvm::Triple Triple, std::string Suffix) {
1370 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1374 VersionTuple OSVersion = Triple.getOSVersion();
1375 if (!OSVersion.getMinor().has_value())
1378 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1382 if (OSVersion.getMajor() != 0) {
1383 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1384 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1390 Triple.setOSName(BaseOSName);
1391 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1394bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1397 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1401 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1404 std::string RealMode = getExecutableForDriverMode(Mode);
1405 llvm::Triple Triple;
1414 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1415 PrefixTriple.isOSUnknown())
1416 Triple = std::move(PrefixTriple);
1420 llvm::Triple RealTriple =
1422 if (Triple.str().empty()) {
1423 Triple = RealTriple;
1424 assert(!Triple.str().empty());
1429 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1443 SmallString<128> CfgFilePath;
1445 "-" + RealMode +
".cfg"))
1446 return readConfigFile(CfgFilePath, ExpCtx);
1450 if (TryModeSuffix) {
1453 return readConfigFile(CfgFilePath, ExpCtx);
1458 std::string CfgFileName = RealMode +
".cfg";
1459 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1460 if (readConfigFile(CfgFilePath, ExpCtx))
1462 }
else if (TryModeSuffix) {
1464 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1465 readConfigFile(CfgFilePath, ExpCtx))
1471 return readConfigFile(CfgFilePath, ExpCtx);
1479 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1488 if (!DriverMode.empty())
1489 setDriverMode(DriverMode);
1495 CLOptions = std::make_unique<InputArgList>(
1500 ContainsError = loadConfigFiles();
1501 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1502 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1506 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1508 if (HasConfigFileHead)
1509 for (
auto *Opt : *CLOptions)
1510 if (!Opt->getOption().matches(options::OPT_config))
1514 if (
IsCLMode() && !ContainsError) {
1516 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1518 CLModePassThroughArgList.push_back(A->getValue());
1521 if (!CLModePassThroughArgList.empty()) {
1524 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1529 for (
auto *Opt : *CLModePassThroughOptions)
1535 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1536 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1537 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1540 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1541 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1542 if (!VFS->exists(IncludeDir))
1543 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1548 bool CCCPrintPhases;
1551 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1552 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1555 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1556 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1559 Args.ClaimAllArgs(options::OPT_pipe);
1567 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1569 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1570 CCCGenericGCCName = A->getValue();
1573 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1577 if (Args.hasArg(options::OPT_fproc_stat_report))
1584 llvm::Triple T(TargetTriple);
1585 T.setOS(llvm::Triple::Win32);
1586 T.setVendor(llvm::Triple::PC);
1587 T.setEnvironment(llvm::Triple::MSVC);
1588 T.setObjectFormat(llvm::Triple::COFF);
1589 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1590 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1591 TargetTriple = T.str();
1594 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1595 StringRef TargetProfile = A->getValue();
1598 TargetTriple = *Triple;
1600 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1604 if (Args.hasArg(options::OPT_spirv)) {
1605 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1606 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1607 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1608 llvm::Triple T(TargetTriple);
1611 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1613 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1614 TargetInfo = ValidTargets.find(A->getValue());
1616 Diag(diag::err_drv_invalid_value)
1617 << A->getAsString(Args) << A->getValue();
1623 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1624 TargetTriple = T.str();
1628 Diag(diag::err_drv_dxc_missing_target_profile);
1632 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1633 TargetTriple = A->getValue();
1634 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1635 Dir = A->getValue();
1636 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1640 if (std::optional<std::string> CompilerPathValue =
1641 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1642 StringRef CompilerPath = *CompilerPathValue;
1643 while (!CompilerPath.empty()) {
1644 std::pair<StringRef, StringRef> Split =
1645 CompilerPath.split(llvm::sys::EnvPathSeparator);
1646 PrefixDirs.push_back(std::string(Split.first));
1647 CompilerPath = Split.second;
1650 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1652 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1655 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1658 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1659 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1660 .Case(
"cwd", SaveTempsCwd)
1661 .Case(
"obj", SaveTempsObj)
1662 .Default(SaveTempsCwd);
1665 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1666 options::OPT_offload_device_only,
1667 options::OPT_offload_host_device)) {
1668 if (A->getOption().matches(options::OPT_offload_host_only))
1669 Offload = OffloadHost;
1670 else if (A->getOption().matches(options::OPT_offload_device_only))
1671 Offload = OffloadDevice;
1673 Offload = OffloadHostDevice;
1679 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1680 StringRef
Name = A->getValue();
1681 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1682 .Case(
"off", EmbedNone)
1683 .Case(
"all", EmbedBitcode)
1684 .Case(
"bitcode", EmbedBitcode)
1685 .Case(
"marker", EmbedMarker)
1688 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1691 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1695 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1696 llvm::sys::fs::remove(A->getValue());
1702 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1704 !Args.hasArg(options::OPT_fmodules) && Std &&
1705 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1706 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1707 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1708 Std->containsValue(
"c++latest"));
1711 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1712 options::OPT_fmodule_header)) {
1714 ModulesModeCXX20 =
true;
1715 if (A->getOption().matches(options::OPT_fmodule_header))
1718 StringRef ArgName = A->getValue();
1719 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1724 Diags.Report(diag::err_drv_invalid_value)
1725 << A->getAsString(Args) << ArgName;
1731 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1732 std::make_unique<InputArgList>(std::move(Args));
1742 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1743 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1745 bool MLContainsError;
1746 auto MultilibMacroDefineList =
1748 MLMacroDefinesChar,
false, MLContainsError));
1749 if (!MLContainsError) {
1750 for (
auto *Opt : *MultilibMacroDefineList) {
1757 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1761 if (!Triple.isWasm()) {
1762 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1763 StringRef TripleObjectFormat =
1764 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1765 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1766 TripleVersionName != TripleObjectFormat) {
1767 Diags.Report(diag::err_drv_triple_version_invalid)
1769 ContainsError =
true;
1774 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1775 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1776 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1784 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1785 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1787 case llvm::Triple::arm:
1788 case llvm::Triple::armeb:
1789 case llvm::Triple::thumb:
1790 case llvm::Triple::thumbeb:
1791 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1792 Diag(diag::warn_target_unrecognized_env)
1794 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1797 case llvm::Triple::aarch64:
1798 case llvm::Triple::aarch64_be:
1799 case llvm::Triple::aarch64_32:
1800 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1801 Diag(diag::warn_target_unrecognized_env)
1803 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1820 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1821 if (HasConfigFileTail && Inputs.size()) {
1824 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1825 for (Arg *A : *CfgOptionsTail)
1826 TranslatedLinkerIns.append(A);
1827 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1834 bool UseModulesDriver =
C->getArgs().hasFlag(
1835 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1837 if (UseModulesDriver) {
1838 Diags.Report(diag::remark_performing_driver_managed_module_build);
1846 const auto StdModuleManifestPath =
1849 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1850 Diags.Report(diag::remark_modules_manifest_not_found);
1852 Diags.Report(diag::remark_using_modules_manifest)
1853 << StdModuleManifestPath;
1854 if (
auto ManifestOrErr =
1856 ModulesManifest = std::move(*ManifestOrErr);
1858 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1859 return !ModuleEntry.IsStdlib;
1864 llvm::handleAllErrors(
1865 ManifestOrErr.takeError(),
1866 [&](llvm::json::ParseError &Err) {
1867 Diags.Report(diag::err_modules_manifest_failed_parse)
1870 [&](llvm::FileError &Err) {
1871 Diags.Report(diag::err_cannot_open_file)
1872 << Err.getFileName() << Err.messageWithoutFileInfo();
1880 if (TC.
getTriple().isOSBinFormatMachO())
1885 if (CCCPrintPhases) {
1892 if (UseModulesDriver)
1899 llvm::opt::ArgStringList ASL;
1900 for (
const auto *A : Args) {
1904 while (A->getAlias())
1906 A->render(Args, ASL);
1909 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1910 if (I != ASL.begin())
1912 llvm::sys::printArg(OS, *I,
true);
1917bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1918 SmallString<128> &CrashDiagDir) {
1919 using namespace llvm::sys;
1920 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1921 "Only knows about .crash files on Darwin");
1923 auto BypassSandbox = sandbox::scopedDisable();
1928 path::home_directory(CrashDiagDir);
1929 if (CrashDiagDir.starts_with(
"/var/root"))
1931 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1939 fs::file_status FileStatus;
1940 TimePoint<> LastAccessTime;
1941 SmallString<128> CrashFilePath;
1944 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1945 File != FileEnd && !EC;
File.increment(EC)) {
1949 if (fs::status(
File->path(), FileStatus))
1951 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1952 llvm::MemoryBuffer::getFile(
File->path());
1957 StringRef
Data = CrashFile.get()->getBuffer();
1958 if (!
Data.starts_with(
"Process:"))
1961 size_t ParentProcPos =
Data.find(
"Parent Process:");
1962 if (ParentProcPos == StringRef::npos)
1964 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1965 if (LineEnd == StringRef::npos)
1967 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1968 int OpenBracket = -1, CloseBracket = -1;
1969 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1970 if (ParentProcess[i] ==
'[')
1972 if (ParentProcess[i] ==
']')
1978 if (OpenBracket < 0 || CloseBracket < 0 ||
1979 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1980 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1990 const auto FileAccessTime = FileStatus.getLastModificationTime();
1991 if (FileAccessTime > LastAccessTime) {
1992 CrashFilePath.assign(
File->path());
1993 LastAccessTime = FileAccessTime;
1998 if (!CrashFilePath.empty()) {
1999 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2009 "\n********************\n\n"
2010 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2011 "Preprocessed source(s) and associated run script(s) are located at:";
2019 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2023 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2024 Level = llvm::StringSwitch<unsigned>(A->getValue())
2026 .Case(
"compiler", 1)
2038 ArgStringList SavedTemps;
2040 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2041 if (!IsLLD || Level < 2)
2048 SavedTemps = std::move(
C.getTempFiles());
2049 assert(!
C.getTempFiles().size());
2066 C.initCompilationForDiagnostics();
2071 Command NewLLDInvocation = Cmd;
2072 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2073 StringRef ReproduceOption =
2074 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2077 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2081 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2083 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2084 Diag(clang::diag::note_drv_command_failed_diag_msg)
2085 <<
"\n\n********************";
2087 Report->TemporaryFiles.push_back(TmpName);
2095 ArgStringList IRInputs;
2096 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2097 bool IgnoreInput =
false;
2103 IRInputs.push_back(it->second->getValue());
2107 }
else if (!strcmp(it->second->getValue(),
"-")) {
2108 Diag(clang::diag::note_drv_command_failed_diag_msg)
2109 <<
"Error generating preprocessed source(s) - "
2110 "ignoring input from stdin.";
2115 it = Inputs.erase(it);
2122 if (Inputs.empty() && IRInputs.empty()) {
2123 Diag(clang::diag::note_drv_command_failed_diag_msg)
2124 <<
"Error generating preprocessed source(s) - "
2125 "no preprocessable inputs.";
2132 for (
const Arg *A :
C.getArgs()) {
2133 if (A->getOption().matches(options::OPT_arch)) {
2134 StringRef ArchName = A->getValue();
2139 Diag(clang::diag::note_drv_command_failed_diag_msg)
2140 <<
"Error generating preprocessed source(s) - cannot generate "
2141 "preprocessed source with multiple -arch options.";
2146 if (!Inputs.empty()) {
2149 const ToolChain &TC =
C.getDefaultToolChain();
2150 if (TC.
getTriple().isOSBinFormatMachO())
2159 Diag(clang::diag::note_drv_command_failed_diag_msg)
2160 <<
"Error generating preprocessed source(s).";
2165 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2168 if (!FailingCommands.empty()) {
2169 Diag(clang::diag::note_drv_command_failed_diag_msg)
2170 <<
"Error generating preprocessed source(s).";
2174 const ArgStringList &TempFiles =
C.getTempFiles();
2175 if (TempFiles.empty()) {
2176 Diag(clang::diag::note_drv_command_failed_diag_msg)
2177 <<
"Error generating preprocessed source(s).";
2183 const ArgStringList &Files =
C.getTempFiles();
2188 for (
auto const *Input : IRInputs) {
2192 StringRef extension = llvm::sys::path::extension(Input);
2193 if (!extension.empty())
2194 extension = extension.drop_front();
2196 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2197 llvm::sys::path::stem(Input), extension, FD, Path);
2199 Diag(clang::diag::note_drv_command_failed_diag_msg)
2200 <<
"Error generating run script: " <<
"Failed copying IR input files"
2201 <<
" " << EC.message();
2205 EC = llvm::sys::fs::copy_file(Input, FD);
2207 Diag(clang::diag::note_drv_command_failed_diag_msg)
2208 <<
"Error generating run script: " <<
"Failed copying IR input files"
2209 <<
" " << EC.message();
2213 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2220 for (std::string &TempFile : TempFiles) {
2221 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2223 Report->TemporaryFiles.push_back(TempFile);
2224 if (ReproCrashFilename.empty()) {
2225 ReproCrashFilename = TempFile;
2226 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2228 if (StringRef(TempFile).ends_with(
".cache")) {
2231 VFS = llvm::sys::path::filename(TempFile);
2232 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2236 for (
const char *TempFile : SavedTemps)
2237 TempFiles.push_back(TempFile);
2243 llvm::sys::path::replace_extension(Script,
"sh");
2245 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2246 llvm::sys::fs::FA_Write,
2247 llvm::sys::fs::OF_Text);
2249 Diag(clang::diag::note_drv_command_failed_diag_msg)
2250 <<
"Error generating run script: " << Script <<
" " << EC.message();
2253 <<
"# Driver args: ";
2255 ScriptOS <<
"# Original command: ";
2256 Cmd.
Print(ScriptOS,
"\n",
true);
2257 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2258 if (!AdditionalInformation.empty())
2259 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2262 Report->TemporaryFiles.push_back(std::string(Script));
2263 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2267 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2269 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2270 Diag(clang::diag::note_drv_command_failed_diag_msg)
2271 << ReproCrashFilename.str();
2273 llvm::sys::path::append(CrashDiagDir,
Name);
2274 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2275 Diag(clang::diag::note_drv_command_failed_diag_msg)
2276 <<
"Crash backtrace is located in";
2277 Diag(clang::diag::note_drv_command_failed_diag_msg)
2278 << CrashDiagDir.str();
2279 Diag(clang::diag::note_drv_command_failed_diag_msg)
2280 <<
"(choose the .crash file that corresponds to your crash)";
2284 Diag(clang::diag::note_drv_command_failed_diag_msg)
2285 <<
"\n\n********************";
2295 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2306 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2307 if (
C.getArgs().hasArg(options::OPT_v))
2308 C.getJobs().Print(llvm::errs(),
"\n",
true);
2310 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2313 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2320 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2321 C.getJobs().Print(llvm::errs(),
"\n",
true);
2322 return Diags.hasErrorOccurred() ? 1 : 0;
2326 if (Diags.hasErrorOccurred())
2330 for (
auto &Job :
C.getJobs())
2331 setUpResponseFiles(
C, Job);
2333 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2336 if (FailingCommands.empty())
2342 for (
const auto &CmdPair : FailingCommands) {
2343 int CommandRes = CmdPair.first;
2344 const Command *FailingCommand = CmdPair.second;
2349 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2353 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2358 if (CommandRes == EX_IOERR) {
2378 if (CommandRes > 128 && CommandRes != 255)
2382 Diag(clang::diag::err_drv_command_signalled)
2385 Diag(clang::diag::err_drv_command_failed)
2393 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2395 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2409 const ToolChain &TC =
C.getDefaultToolChain();
2413 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2416 OS <<
"Thread model: " << A->getValue();
2422 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2427 if (!llvm::cl::getCompilerBuildConfig().empty())
2428 llvm::cl::printBuildConfig(OS);
2431 for (
auto ConfigFile : ConfigFiles)
2432 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2445 if (PassedFlags ==
"")
2449 std::vector<std::string> SuggestedCompletions;
2450 std::vector<std::string> Flags;
2462 const bool HasSpace = PassedFlags.ends_with(
",");
2466 StringRef TargetFlags = PassedFlags;
2467 while (TargetFlags !=
"") {
2469 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2470 Flags.push_back(std::string(CurFlag));
2475 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2478 const llvm::opt::OptTable &Opts =
getOpts();
2480 Cur = Flags.at(Flags.size() - 1);
2482 if (Flags.size() >= 2) {
2483 Prev = Flags.at(Flags.size() - 2);
2484 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2487 if (SuggestedCompletions.empty())
2488 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2495 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2496 llvm::outs() <<
'\n';
2502 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2506 SuggestedCompletions = Opts.findByPrefix(
2507 Cur, VisibilityMask,
2514 if (S.starts_with(Cur))
2515 SuggestedCompletions.push_back(std::string(S));
2522 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2523 if (
int X = A.compare_insensitive(B))
2525 return A.compare(B) > 0;
2528 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2535 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2536 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2540 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2543 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2547 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2552 if (
C.getArgs().hasArg(options::OPT_help) ||
2553 C.getArgs().hasArg(options::OPT__help_hidden)) {
2554 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2558 if (
C.getArgs().hasArg(options::OPT__version)) {
2565 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2566 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2567 if (ListExtractors || ListFormats) {
2575 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2580 if (
C.getArgs().hasArg(options::OPT_v) ||
2581 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2582 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2583 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2584 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2586 SuppressMissingInputWarning =
true;
2589 if (
C.getArgs().hasArg(options::OPT_v)) {
2591 llvm::errs() <<
"System configuration file directory: "
2594 llvm::errs() <<
"User configuration file directory: "
2598 const ToolChain &TC =
C.getDefaultToolChain();
2600 if (
C.getArgs().hasArg(options::OPT_v))
2603 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2608 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2609 llvm::outs() <<
"programs: =";
2610 bool separator =
false;
2614 llvm::outs() << llvm::sys::EnvPathSeparator;
2615 llvm::outs() << Path;
2620 llvm::outs() << llvm::sys::EnvPathSeparator;
2621 llvm::outs() << Path;
2624 llvm::outs() <<
"\n";
2627 StringRef sysroot =
C.getSysRoot();
2631 llvm::outs() << llvm::sys::EnvPathSeparator;
2634 llvm::outs() << sysroot << Path.substr(1);
2636 llvm::outs() << Path;
2638 llvm::outs() <<
"\n";
2642 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2648 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2649 for (
auto RuntimePath :
2651 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2652 llvm::outs() << *RuntimePath <<
'\n';
2656 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2660 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2662 for (std::size_t I = 0; I != Flags.size(); I += 2)
2663 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2669 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2670 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2674 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2675 StringRef ProgName = A->getValue();
2678 if (! ProgName.empty())
2681 llvm::outs() <<
"\n";
2685 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2686 StringRef PassedFlags = A->getValue();
2691 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2705 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2708 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2714 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2721 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2724 std::set<llvm::StringRef> SortedFlags;
2725 for (
const auto &FlagEntry : ExpandedFlags)
2726 SortedFlags.insert(FlagEntry.getKey());
2727 for (
auto Flag : SortedFlags)
2728 llvm::outs() << Flag <<
'\n';
2732 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2735 llvm::outs() <<
".\n";
2738 assert(Suffix.front() ==
'/');
2739 llvm::outs() << Suffix.substr(1) <<
"\n";
2745 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2750 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2752 llvm::outs() << Triple.getTriple() <<
"\n";
2756 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2757 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2774 std::map<Action *, unsigned> &Ids,
2776 if (
auto It = Ids.find(A); It != Ids.end())
2780 llvm::raw_string_ostream os(str);
2782 auto getSibIndent = [](
int K) -> Twine {
2786 Twine SibIndent =
Indent + getSibIndent(Kind);
2790 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2792 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2793 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2794 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2796 OA->doOnEachDependence(
2798 assert(TC &&
"Unknown host toolchain");
2810 os <<
":" << BoundArch;
2813 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2821 const char *Prefix =
"{";
2822 for (
Action *PreRequisite : *AL) {
2823 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2834 std::string offload_str;
2835 llvm::raw_string_ostream offload_os(offload_str);
2839 offload_os <<
", (" << S;
2846 auto getSelfIndent = [](
int K) -> Twine {
2850 unsigned Id = Ids.size();
2852 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2861 std::map<Action *, unsigned> Ids;
2862 for (
Action *A :
C.getActions())
2878 DerivedArgList &Args =
C.getArgs();
2880 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2885 for (Arg *A : Args) {
2886 if (A->getOption().matches(options::OPT_arch)) {
2889 llvm::Triple::ArchType
Arch =
2891 if (
Arch == llvm::Triple::UnknownArch) {
2892 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2897 if (
ArchNames.insert(A->getValue()).second)
2898 Archs.push_back(A->getValue());
2912 for (
Action* Act : SingleActions) {
2920 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2924 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2929 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2930 Actions.append(Inputs.begin(), Inputs.end());
2932 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2935 Arg *A = Args.getLastArg(options::OPT_g_Group);
2936 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2937 !A->getOption().matches(options::OPT_gstabs);
2938 bool enablesPseudoProbe =
2939 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2940 options::OPT_fno_pseudo_probe_for_profiling,
false);
2941 bool enablesDebugInfoForProfiling =
2942 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2943 options::OPT_fno_debug_info_for_profiling,
false);
2944 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2945 enablesDebugInfoForProfiling) &&
2953 if (Act->getType() == types::TY_Image) {
2955 Inputs.push_back(Actions.back());
2962 if (Args.hasArg(options::OPT_verify_debug_info)) {
2963 Action *LastAction = Actions.pop_back_val();
2965 LastAction, types::TY_Nothing));
2972 bool TypoCorrect)
const {
2984 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2985 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2997 std::string Nearest;
2998 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2999 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3000 <<
Value << Nearest;
3039 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3042 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3050 return types::TY_CXXUHeader;
3052 return types::TY_CXXSHeader;
3056 llvm_unreachable(
"should not be called in this case");
3058 return types::TY_CXXHUHeader;
3064 const llvm::opt::OptTable &Opts =
getOpts();
3068 types::ID InputType = types::TY_Nothing;
3069 Arg *InputTypeArg =
nullptr;
3072 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3073 options::OPT__SLASH_TP)) {
3074 InputTypeArg = TCTP;
3075 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3080 bool ShowNote =
false;
3082 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3084 Diag(clang::diag::warn_drv_overriding_option)
3085 <<
Previous->getSpelling() << A->getSpelling();
3091 Diag(clang::diag::note_drv_t_option_is_global);
3096 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3097 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3098 if (LastXArg && LastInputArg &&
3099 LastInputArg->getIndex() < LastXArg->getIndex())
3100 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3103 for (Arg *A : Args) {
3104 if (A->getOption().
getKind() == Option::InputClass) {
3105 const char *
Value = A->getValue();
3109 if (InputType == types::TY_Nothing) {
3112 InputTypeArg->claim();
3115 if (strcmp(
Value,
"-") == 0) {
3117 Ty = types::TY_Fortran;
3119 Ty = types::TY_HLSL;
3128 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3129 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3130 : clang::diag::err_drv_unknown_stdin_type);
3139 if (
const char *Ext = strrchr(
Value,
'.'))
3148 Ty = types::TY_HLSL;
3150 Ty = types::TY_Object;
3161 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3162 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3163 << getTypeName(OldTy) << getTypeName(Ty);
3168 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3169 Ty == types::TY_Object)
3170 Ty = types::TY_LLVM_BC;
3178 if (Ty != types::TY_Object) {
3179 if (Args.hasArg(options::OPT_ObjC))
3180 Ty = types::TY_ObjC;
3181 else if (Args.hasArg(options::OPT_ObjCXX))
3182 Ty = types::TY_ObjCXX;
3189 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3193 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3194 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3197 const char *Ext = strrchr(
Value,
'.');
3199 Ty = types::TY_Object;
3203 InputTypeArg->claim();
3207 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3208 Args.hasArgNoClaim(options::OPT_hipstdpar))
3212 Inputs.push_back(std::make_pair(Ty, A));
3214 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3215 StringRef
Value = A->getValue();
3218 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3219 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3222 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3223 StringRef
Value = A->getValue();
3226 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3227 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3233 Inputs.push_back(std::make_pair(types::TY_Object, A));
3235 }
else if (A->getOption().matches(options::OPT_x)) {
3244 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3245 InputType = types::TY_Object;
3252 }
else if (A->getOption().getID() == options::OPT_U) {
3253 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3254 StringRef Val = A->getValue(0);
3255 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3257 Diag(diag::warn_slash_u_filename) << Val;
3258 Diag(diag::note_use_dashdash);
3262 if (
CCCIsCPP() && Inputs.empty()) {
3266 Inputs.push_back(std::make_pair(types::TY_C, A));
3273class OffloadingActionBuilder final {
3275 bool IsValid =
false;
3281 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3284 std::map<Action *, const Arg *> HostActionToInputArgMap;
3287 class DeviceActionBuilder {
3291 enum ActionBuilderReturnCode {
3309 const ToolChain *FatBinaryToolChain =
nullptr;
3312 DerivedArgList &Args;
3321 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3324 :
C(
C), Args(Args), Inputs(Inputs),
3325 AssociatedOffloadKind(AssociatedOffloadKind) {}
3326 virtual ~DeviceActionBuilder() {}
3331 virtual ActionBuilderReturnCode
3332 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3335 return ABRT_Inactive;
3340 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3341 return ABRT_Inactive;
3345 virtual void appendTopLevelActions(
ActionList &AL) {}
3348 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3351 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3354 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3361 virtual bool canUseBundlerUnbundler()
const {
return false; }
3365 bool isValid() {
return !ToolChains.empty(); }
3369 return AssociatedOffloadKind;
3375 class CudaActionBuilderBase :
public DeviceActionBuilder {
3379 bool CompileHostOnly =
false;
3380 bool CompileDeviceOnly =
false;
3382 bool EmitAsm =
false;
3392 TargetID(
const char *ID) :
ID(
ID) {}
3393 operator const char *() {
return ID; }
3394 operator StringRef() {
return StringRef(ID); }
3397 SmallVector<TargetID, 4> GpuArchList;
3403 Action *CudaFatBinary =
nullptr;
3406 bool IsActive =
false;
3409 bool Relocatable =
false;
3412 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3415 const CUIDOptions &CUIDOpts;
3418 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3420 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3421 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3423 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3424 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3425 options::OPT_fno_gpu_rdc,
false);
3428 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3435 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3438 if (!(IA->getType() == types::TY_CUDA ||
3439 IA->getType() == types::TY_HIP ||
3440 IA->getType() == types::TY_PP_HIP)) {
3443 return ABRT_Inactive;
3450 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3452 if (CompileHostOnly)
3453 return ABRT_Success;
3456 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3457 : types::TY_CUDA_DEVICE;
3458 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3459 CudaDeviceActions.push_back(
3460 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3463 return ABRT_Success;
3467 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3471 if (UA->getType() == types::TY_Object && !Relocatable)
3472 return ABRT_Inactive;
3474 CudaDeviceActions.clear();
3476 std::string
FileName = IA->getInputArg().getAsString(Args);
3482 const StringRef LibFileExt =
".lib";
3483 if (IA->getType() == types::TY_Object &&
3484 (!llvm::sys::path::has_extension(
FileName) ||
3486 llvm::sys::path::extension(
FileName).drop_front()) !=
3488 llvm::sys::path::extension(
FileName) == LibFileExt))
3489 return ABRT_Inactive;
3491 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3492 CudaDeviceActions.push_back(UA);
3493 UA->registerDependentActionInfo(ToolChain,
Arch,
3494 AssociatedOffloadKind);
3497 return ABRT_Success;
3500 return IsActive ? ABRT_Success : ABRT_Inactive;
3503 void appendTopLevelActions(
ActionList &AL)
override {
3505 auto AddTopLevel = [&](Action *A, TargetID TargetID,
3506 const ToolChain *TC) {
3507 OffloadAction::DeviceDependences Dep;
3508 Dep.
add(*A, *TC, TargetID, AssociatedOffloadKind);
3509 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3513 if (CudaFatBinary) {
3514 AddTopLevel(CudaFatBinary, OffloadArch::Unused, FatBinaryToolChain);
3515 CudaDeviceActions.clear();
3516 CudaFatBinary =
nullptr;
3520 if (CudaDeviceActions.empty())
3526 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3527 "Expecting one action per GPU architecture.");
3528 assert(ToolChains.size() == GpuArchList.size() &&
3529 "Expecting to have a toolchain per GPU architecture");
3530 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3531 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3533 CudaDeviceActions.clear();
3536 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3554 assert(HostTC &&
"No toolchain for host compilation.");
3559 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3564 std::set<std::pair<StringRef, const ToolChain *>> GpuArchs;
3566 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3568 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3569 GpuArchs.insert({
Arch, I.second});
3573 for (
auto [
Arch, TC] : GpuArchs) {
3574 GpuArchList.push_back(
Arch.data());
3575 ToolChains.push_back(TC);
3578 FatBinaryToolChain = ToolChains.front();
3579 CompileHostOnly =
C.getDriver().offloadHostOnly();
3580 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3581 EmitAsm = Args.getLastArg(options::OPT_S);
3589 class CudaActionBuilder final :
public CudaActionBuilderBase {
3591 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3593 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3594 DefaultOffloadArch = OffloadArch::CudaDefault;
3597 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3599 const std::set<StringRef> &GpuArchs)
override {
3600 return std::nullopt;
3603 ActionBuilderReturnCode
3604 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3606 PhasesTy &Phases)
override {
3608 return ABRT_Inactive;
3612 if (CudaDeviceActions.empty())
3613 return ABRT_Success;
3615 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3616 "Expecting one action per GPU architecture.");
3617 assert(!CompileHostOnly &&
3618 "Not expecting CUDA actions in host-only compilation.");
3628 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3631 for (
auto Ph : Phases) {
3636 if (Ph > FinalPhase)
3639 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3653 Action *AssembleAction = CudaDeviceActions[I];
3654 assert(AssembleAction->
getType() == types::TY_Object);
3655 assert(AssembleAction->
getInputs().size() == 1);
3661 OffloadAction::DeviceDependences DDep;
3663 DeviceActions.push_back(
3664 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3669 if (!DeviceActions.empty()) {
3671 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3673 if (!CompileDeviceOnly) {
3674 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3678 CudaFatBinary =
nullptr;
3683 CudaDeviceActions.clear();
3687 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3692 return ABRT_Success;
3696 "instructions should only occur "
3697 "before the backend phase!");
3700 for (Action *&A : CudaDeviceActions)
3701 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3703 return ABRT_Success;
3708 class HIPActionBuilder final :
public CudaActionBuilderBase {
3710 SmallVector<ActionList, 8> DeviceLinkerInputs;
3716 std::optional<bool> BundleOutput;
3717 std::optional<bool> EmitReloc;
3720 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3722 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3724 DefaultOffloadArch = OffloadArch::HIPDefault;
3726 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3727 options::OPT_fno_hip_emit_relocatable)) {
3728 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3729 options::OPT_fno_hip_emit_relocatable, false);
3733 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3734 <<
"-fhip-emit-relocatable"
3738 if (!CompileDeviceOnly) {
3739 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3740 <<
"-fhip-emit-relocatable"
3741 <<
"--offload-device-only";
3746 if (Args.hasArg(options::OPT_gpu_bundle_output,
3747 options::OPT_no_gpu_bundle_output))
3748 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3749 options::OPT_no_gpu_bundle_output,
true) &&
3750 (!EmitReloc || !*EmitReloc);
3753 bool canUseBundlerUnbundler()
const override {
return true; }
3755 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3757 const std::set<StringRef> &GpuArchs)
override {
3761 ActionBuilderReturnCode
3762 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3764 PhasesTy &Phases)
override {
3766 return ABRT_Inactive;
3772 if (CudaDeviceActions.empty())
3773 return ABRT_Success;
3776 CudaDeviceActions.size() == GpuArchList.size()) &&
3777 "Expecting one action per GPU architecture.");
3778 assert(!CompileHostOnly &&
3779 "Not expecting HIP actions in host-only compilation.");
3781 bool ShouldLink = !EmitReloc || !*EmitReloc;
3784 !EmitAsm && ShouldLink) {
3790 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3791 if (
C.getDriver().isUsingOffloadLTO()) {
3795 AL.push_back(CudaDeviceActions[I]);
3798 CudaDeviceActions[I] =
3799 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3805 if (ToolChains[I]->
getTriple().isSPIRV() ||
3806 (ToolChains[I]->
getTriple().isAMDGCN() &&
3807 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3811 types::ID Output = Args.hasArg(options::OPT_S)
3813 : types::TY_LLVM_BC;
3815 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3819 AssociatedOffloadKind);
3820 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3822 AssociatedOffloadKind);
3823 AL.push_back(AssembleAction);
3826 CudaDeviceActions[I] =
3827 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3836 OffloadAction::DeviceDependences DDep;
3837 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3838 AssociatedOffloadKind);
3839 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3840 DDep, CudaDeviceActions[I]->getType());
3843 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3845 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3846 types::TY_HIP_FATBIN);
3848 if (!CompileDeviceOnly) {
3849 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3850 AssociatedOffloadKind);
3853 CudaFatBinary =
nullptr;
3858 CudaDeviceActions.clear();
3861 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3864 return ABRT_Success;
3870 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3871 auto LI = DeviceLinkerInputs.begin();
3872 for (
auto *A : CudaDeviceActions) {
3879 CudaDeviceActions.clear();
3880 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3884 for (Action *&A : CudaDeviceActions)
3885 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3886 AssociatedOffloadKind);
3888 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3890 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3891 OffloadAction::DeviceDependences DDep;
3892 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3893 AssociatedOffloadKind);
3894 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3895 DDep, CudaDeviceActions[I]->getType());
3898 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3899 CudaDeviceActions.clear();
3902 return (CompileDeviceOnly &&
3903 (CurPhase == FinalPhase ||
3909 void appendLinkDeviceActions(
ActionList &AL)
override {
3910 if (DeviceLinkerInputs.size() == 0)
3913 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3914 "Linker inputs and GPU arch list sizes do not match.");
3920 for (
auto &LI : DeviceLinkerInputs) {
3922 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3926 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3929 OffloadAction::DeviceDependences DeviceLinkDeps;
3930 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3931 AssociatedOffloadKind);
3932 Actions.push_back(
C.MakeAction<OffloadAction>(
3933 DeviceLinkDeps, DeviceLinkAction->getType()));
3936 DeviceLinkerInputs.clear();
3939 if (Args.hasArg(options::OPT_emit_llvm)) {
3947 OffloadAction::DeviceDependences DDeps;
3948 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3949 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3951 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3952 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain,
nullptr,
3953 AssociatedOffloadKind);
3956 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3962 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3964 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3972 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3978 bool ShouldUseBundler;
3981 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3989 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3992 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4000 unsigned ValidBuilders = 0u;
4001 unsigned ValidBuildersSupportingBundling = 0u;
4002 for (
auto *SB : SpecializedBuilders) {
4003 IsValid = IsValid && !SB->initialize();
4006 if (SB->isValid()) {
4008 if (SB->canUseBundlerUnbundler())
4009 ++ValidBuildersSupportingBundling;
4013 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4015 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4016 options::OPT_no_gpu_bundle_output,
true);
4019 ~OffloadingActionBuilder() {
4020 for (
auto *SB : SpecializedBuilders)
4025 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4026 assert(HostAction &&
"Invalid host action");
4027 assert(InputArg &&
"Invalid input argument");
4028 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4029 assert(Loc->second == InputArg &&
4030 "host action mapped to multiple input arguments");
4039 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4041 DeviceActionBuilder::PhasesTy &Phases) {
4045 if (SpecializedBuilders.empty())
4048 assert(HostAction &&
"Invalid host action!");
4049 recordHostAction(HostAction, InputArg);
4054 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4055 unsigned InactiveBuilders = 0u;
4056 unsigned IgnoringBuilders = 0u;
4057 for (
auto *SB : SpecializedBuilders) {
4058 if (!SB->isValid()) {
4063 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4068 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4073 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4074 OffloadKind |= SB->getAssociatedOffloadKind();
4079 if (IgnoringBuilders &&
4080 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4097 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4098 const Arg *InputArg) {
4102 recordHostAction(HostAction, InputArg);
4111 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4113 HostAction->
getType() == types::TY_PP_HIP)) {
4114 auto UnbundlingHostAction =
4119 HostAction = UnbundlingHostAction;
4120 recordHostAction(HostAction, InputArg);
4123 assert(HostAction &&
"Invalid host action!");
4126 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4127 for (
auto *SB : SpecializedBuilders) {
4131 auto RetCode = SB->addDeviceDependences(HostAction);
4135 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4136 "Host dependence not expected to be ignored.!");
4140 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4141 OffloadKind |= SB->getAssociatedOffloadKind();
4146 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4156 const Arg *InputArg) {
4158 recordHostAction(HostAction, InputArg);
4162 for (
auto *SB : SpecializedBuilders) {
4165 SB->appendTopLevelActions(OffloadAL);
4172 if (CanUseBundler && ShouldUseBundler && HostAction &&
4173 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4175 OffloadAL.push_back(HostAction);
4179 assert(HostAction == AL.back() &&
"Host action not in the list??");
4181 recordHostAction(HostAction, InputArg);
4182 AL.back() = HostAction;
4184 AL.append(OffloadAL.begin(), OffloadAL.end());
4194 void appendDeviceLinkActions(
ActionList &AL) {
4195 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4198 SB->appendLinkDeviceActions(AL);
4202 Action *makeHostLinkAction() {
4205 appendDeviceLinkActions(DeviceAL);
4206 if (DeviceAL.empty())
4211 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4214 HA = SB->appendLinkHostActions(DeviceAL);
4231 for (
auto *SB : SpecializedBuilders) {
4235 SB->appendLinkDependences(DDeps);
4239 unsigned ActiveOffloadKinds = 0u;
4240 for (
auto &I : InputArgToOffloadKindMap)
4241 ActiveOffloadKinds |= I.second;
4253 for (
auto *A : HostAction->
inputs()) {
4254 auto ArgLoc = HostActionToInputArgMap.find(A);
4255 if (ArgLoc == HostActionToInputArgMap.end())
4257 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4258 if (OFKLoc == InputArgToOffloadKindMap.end())
4270 nullptr, ActiveOffloadKinds);
4276void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4281 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4282 StringRef
V = A->getValue();
4283 if (Inputs.size() > 1 && !
V.empty() &&
4284 !llvm::sys::path::is_separator(
V.back())) {
4286 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4287 << A->getSpelling() <<
V;
4288 Args.eraseArg(options::OPT__SLASH_Fo);
4293 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4294 StringRef
V = A->getValue();
4295 if (Inputs.size() > 1 && !
V.empty() &&
4296 !llvm::sys::path::is_separator(
V.back())) {
4298 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4299 << A->getSpelling() <<
V;
4300 Args.eraseArg(options::OPT__SLASH_Fa);
4305 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4306 if (A->getValue()[0] ==
'\0') {
4308 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4309 Args.eraseArg(options::OPT__SLASH_o);
4314 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4315 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4316 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4317 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4318 Args.eraseArg(options::OPT__SLASH_Yc);
4319 Args.eraseArg(options::OPT__SLASH_Yu);
4320 YcArg = YuArg =
nullptr;
4322 if (YcArg && Inputs.size() > 1) {
4323 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4324 Args.eraseArg(options::OPT__SLASH_Yc);
4332 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4333 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4334 Args.AddFlagArg(
nullptr,
4335 getOpts().getOption(options::OPT_frtlib_add_rpath));
4339 if (Args.hasArg(options::OPT_emit_llvm) &&
4340 !Args.hasArg(options::OPT_hip_link) &&
4341 !
C.getDefaultToolChain().getTriple().isSPIRV())
4342 Diag(clang::diag::err_drv_emit_llvm_link);
4343 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4345 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4346 .starts_with_insensitive(
"lld"))
4347 Diag(clang::diag::err_drv_lto_without_lld);
4353 if (!Args.hasArg(options::OPT_dumpdir)) {
4354 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4355 Arg *Arg = Args.MakeSeparateArg(
4356 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4358 (FinalOutput ? FinalOutput->getValue()
4370 Args.eraseArg(options::OPT__SLASH_Fp);
4371 Args.eraseArg(options::OPT__SLASH_Yc);
4372 Args.eraseArg(options::OPT__SLASH_Yu);
4373 YcArg = YuArg =
nullptr;
4376 if (Args.hasArg(options::OPT_include_pch) &&
4377 Args.hasArg(options::OPT_ignore_pch)) {
4381 Args.eraseArg(options::OPT_include_pch);
4384 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4385 for (
auto &I : Inputs) {
4387 const Arg *InputArg = I.second;
4392 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4396 if (InitialPhase > FinalPhase) {
4397 if (InputArg->isClaimed())
4404 if (Args.hasArg(options::OPT_Qunused_arguments))
4410 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4411 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4415 (Args.getLastArg(options::OPT__SLASH_EP,
4416 options::OPT__SLASH_P) ||
4417 Args.getLastArg(options::OPT_E) ||
4418 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4420 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4421 << InputArg->getAsString(Args) << !!FinalPhaseArg
4422 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4424 Diag(clang::diag::warn_drv_input_file_unused)
4425 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4427 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4436 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4440 Actions.push_back(ClangClPch);
4452 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4453 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4462 const llvm::opt::DerivedArgList &Args,
4465 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4467 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4470 bool HasAMDGCNHIPDevice =
false;
4472 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4474 const llvm::Triple &Tr = TC->
getTriple();
4477 HasAMDGCNHIPDevice =
true;
4479 return HasAMDGCNHIPDevice;
4484 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4486 if (!SuppressMissingInputWarning && Inputs.empty()) {
4487 Diag(clang::diag::err_drv_no_input_files);
4491 handleArguments(
C, Args, Inputs, Actions);
4493 bool UseNewOffloadingDriver = Args.hasFlag(
4494 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4498 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4499 !UseNewOffloadingDriver
4500 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4508 for (
auto &I : Inputs) {
4510 const Arg *InputArg = I.second;
4523 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4531 if (!UseNewOffloadingDriver)
4532 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4538 if (!UseNewOffloadingDriver)
4539 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4540 Current, InputArg, Phase, PL.back(), FullPL);
4546 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4549 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4550 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4552 LinkerInputs.push_back(Current);
4562 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4563 MergerInputs.push_back(Current);
4581 if (NewCurrent == Current)
4584 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4587 Current = NewCurrent;
4591 if (UseNewOffloadingDriver)
4593 &HIPAsmDeviceActions);
4596 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4600 if (Current->
getType() == types::TY_Nothing)
4606 if (Current && !HIPAsmDeviceActions.empty()) {
4607 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4609 BundleInputs.append(HIPAsmDeviceActions);
4610 BundleInputs.push_back(Current);
4616 Actions.push_back(Current);
4619 if (!UseNewOffloadingDriver)
4620 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4628 if (LinkerInputs.empty()) {
4631 if (!UseNewOffloadingDriver)
4632 OffloadBuilder->appendDeviceLinkActions(Actions);
4635 if (!LinkerInputs.empty()) {
4636 if (!UseNewOffloadingDriver)
4637 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4638 LinkerInputs.push_back(Wrapper);
4643 }
else if (UseNewOffloadingDriver ||
4644 Args.hasArg(options::OPT_offload_link)) {
4652 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4653 C.getDefaultToolChain().getTriple().isSPIRV();
4654 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4658 if (!UseNewOffloadingDriver)
4659 LA = OffloadBuilder->processHostLinkAction(LA);
4660 Actions.push_back(LA);
4664 if (!MergerInputs.empty())
4668 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4675 for (
auto &I : Inputs) {
4677 const Arg *InputArg = I.second;
4682 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4683 InputType == types::TY_Asm)
4688 for (
auto Phase : PhaseList) {
4692 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4697 if (InputType == types::TY_Object)
4704 assert(Phase == PhaseList.back() &&
4705 "merging must be final compilation step.");
4706 MergerInputs.push_back(Current);
4715 Actions.push_back(Current);
4719 if (!MergerInputs.empty())
4724 for (
auto Opt : {options::OPT_print_supported_cpus,
4725 options::OPT_print_supported_extensions,
4726 options::OPT_print_enabled_extensions}) {
4733 if (Arg *A = Args.getLastArg(Opt)) {
4734 if (Opt == options::OPT_print_supported_extensions &&
4735 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4736 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4737 !
C.getDefaultToolChain().getTriple().isARM()) {
4738 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4739 <<
"--print-supported-extensions";
4742 if (Opt == options::OPT_print_enabled_extensions &&
4743 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4744 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4745 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4746 <<
"--print-enabled-extensions";
4753 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4756 for (
auto &I : Inputs)
4761 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4762 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4763 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4769 if (TC.requiresObjcopy(Args)) {
4770 Action *LastAction = Actions.back();
4772 if (LastAction->
getType() == types::TY_Object)
4778 auto ValInfo = TC.getValidationInfo(Args);
4779 if (ValInfo.NeedsValidation) {
4780 Action *LastAction = Actions.back();
4781 if (LastAction->
getType() == types::TY_Object) {
4783 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4790 if (TC.requiresBinaryTranslation(Args)) {
4791 Action *LastAction = Actions.back();
4795 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4796 LastAction->
getType() == types::TY_Object)
4798 LastAction, types::TY_DX_CONTAINER));
4803 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4809 const llvm::opt::DerivedArgList &Args,
4811 const llvm::Triple &Triple) {
4816 if (Triple.isNVPTX() &&
4818 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4819 <<
"CUDA" << ArchStr;
4821 }
else if (Triple.isAMDGPU() &&
4823 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4824 <<
"HIP" << ArchStr;
4832 llvm::StringMap<bool> Features;
4835 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4847static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4849 llvm::Triple Triple) {
4850 if (!Triple.isAMDGPU())
4851 return std::nullopt;
4853 std::set<StringRef> ArchSet;
4854 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4858llvm::SmallVector<StringRef>
4862 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4863 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4864 options::OPT_no_offload_arch_EQ)) {
4865 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4867 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4869 :
"--no-offload-arch");
4872 llvm::DenseSet<StringRef> Archs;
4873 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4876 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4877 for (StringRef
Arch : Arg->getValues()) {
4878 if (
Arch ==
"native" ||
Arch.empty()) {
4882 << llvm::Triple::getArchTypeName(TC.
getArch())
4883 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4887 for (
auto ArchStr : *GPUsOrErr) {
4889 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4890 if (!CanonicalStr.empty())
4891 Archs.insert(CanonicalStr);
4896 StringRef CanonicalStr =
4898 if (!CanonicalStr.empty())
4899 Archs.insert(CanonicalStr);
4904 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4905 for (StringRef
Arch : Arg->getValues()) {
4906 if (
Arch ==
"all") {
4911 Archs.erase(ArchStr);
4917 if (
auto ConflictingArchs =
4919 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4920 << ConflictingArchs->first << ConflictingArchs->second;
4923 if (Archs.empty()) {
4931 Archs.insert(StringRef());
4934 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4935 .getLastArg(options::OPT_march_EQ)) {
4936 Archs.insert(Arg->getValue());
4941 << llvm::Triple::getArchTypeName(TC.
getArch())
4942 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4943 }
else if (!ArchsOrErr->empty()) {
4944 for (
auto Arch : *ArchsOrErr)
4945 Archs.insert(Args.MakeArgStringRef(
Arch));
4947 Archs.insert(StringRef());
4952 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4953 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4962 const InputTy &Input, StringRef CUID,
4972 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4974 bool HIPRelocatableObj =
4976 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4977 options::OPT_fno_hip_emit_relocatable,
false);
4979 if (!HIPNoRDC && HIPRelocatableObj)
4980 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4981 <<
"-fhip-emit-relocatable"
4985 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4986 <<
"-fhip-emit-relocatable"
4987 <<
"--offload-device-only";
5005 auto TCRange =
C.getOffloadToolChains(Kind);
5006 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5007 ToolChains.push_back(TI->second);
5009 if (ToolChains.empty())
5013 const Arg *InputArg = Input.second;
5022 for (
const ToolChain *TC : ToolChains) {
5024 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5025 DeviceActions.push_back(
5026 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5030 if (DeviceActions.empty())
5036 HostAction->
getType() != types::TY_Nothing &&
5046 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5055 auto *TCAndArch = TCAndArchs.begin();
5056 for (
Action *&A : DeviceActions) {
5057 if (A->
getType() == types::TY_Nothing)
5067 HostAction->
getType() != types::TY_Nothing) {
5074 TCAndArch->second.data(), Kind);
5076 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5086 for (
Action *&A : DeviceActions) {
5091 OffloadTriple && OffloadTriple->isSPIRV() &&
5092 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5093 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5094 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5095 options::OPT_no_use_spirv_backend,
5102 bool IsAMDGCNSPIRVWithBackend =
5103 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5106 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5107 A->
getType() != types::TY_LTO_BC) ||
5115 auto *TCAndArch = TCAndArchs.begin();
5116 for (
Action *A : DeviceActions) {
5117 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5119 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5124 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5126 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5135 bool ShouldBundleHIP =
5136 Args.hasFlag(options::OPT_gpu_bundle_output,
5137 options::OPT_no_gpu_bundle_output,
false) ||
5138 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5140 return A->
getType() != types::TY_Image;
5147 if (OffloadActions.empty())
5152 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5156 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5163 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5164 DDep.
add(*FatbinAction,
5167 }
else if (HIPNoRDC) {
5170 if (HIPAsmBundleDeviceOut &&
5172 for (
Action *OA : OffloadActions)
5173 HIPAsmBundleDeviceOut->push_back(OA);
5187 DDep.
add(*PackagerAction,
5196 nullptr,
C.getActiveOffloadKinds());
5205 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5206 return A->
getType() == types::TY_Nothing;
5210 nullptr, SingleDeviceOutput ? DDep : DDeps);
5211 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5217 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5227 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5233 llvm_unreachable(
"link action invalid here.");
5235 llvm_unreachable(
"ifsmerge action invalid here.");
5240 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5241 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5242 OutputTy = types::TY_Dependencies;
5247 if (!Args.hasFlag(options::OPT_frewrite_includes,
5248 options::OPT_fno_rewrite_includes,
false) &&
5249 !Args.hasFlag(options::OPT_frewrite_imports,
5250 options::OPT_fno_rewrite_imports,
false) &&
5251 !Args.hasFlag(options::OPT_fdirectives_only,
5252 options::OPT_fno_directives_only,
false) &&
5256 "Cannot preprocess this input type!");
5262 if (Args.hasArg(options::OPT_extract_api))
5271 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5272 (Input->
getType() == driver::types::TY_CXXModule ||
5273 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5274 !Args.getLastArg(options::OPT__precompile) &&
5275 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5280 "Cannot precompile this input type!");
5284 const char *ModName =
nullptr;
5285 if (OutputTy == types::TY_PCH) {
5286 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5287 ModName = A->getValue();
5289 OutputTy = types::TY_ModuleFile;
5292 if (Args.hasArg(options::OPT_fsyntax_only)) {
5294 OutputTy = types::TY_Nothing;
5300 if (Args.hasArg(options::OPT_fsyntax_only))
5302 if (Args.hasArg(options::OPT_rewrite_objc))
5304 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5306 types::TY_RewrittenLegacyObjC);
5307 if (Args.hasArg(options::OPT__analyze))
5309 if (Args.hasArg(options::OPT_emit_ast))
5311 if (Args.hasArg(options::OPT_emit_cir))
5313 if (Args.hasArg(options::OPT_module_file_info))
5315 if (Args.hasArg(options::OPT_verify_pch))
5317 if (Args.hasArg(options::OPT_extract_api))
5326 Args.hasFlag(options::OPT_offload_new_driver,
5327 options::OPT_no_offload_new_driver,
5330 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm)))
5335 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5336 !Args.hasArg(options::OPT_emit_llvm))
5337 Output = types::TY_PP_Asm;
5338 else if (Args.hasArg(options::OPT_S))
5339 Output = types::TY_LTO_IR;
5341 Output = types::TY_LTO_BC;
5346 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5349 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5350 options::OPT_no_use_spirv_backend,
5358 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5360 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5362 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5364 auto &DefaultToolChain =
C.getDefaultToolChain();
5365 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5370 bool EmitBitcodeForNonOffloadAMDSPIRV =
5371 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5372 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5373 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5375 if (Args.hasArg(options::OPT_emit_llvm) ||
5376 EmitBitcodeForNonOffloadAMDSPIRV ||
5382 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5383 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5385 (Args.hasFlag(options::OPT_offload_new_driver,
5386 options::OPT_no_offload_new_driver,
5388 !(Args.hasArg(options::OPT_S) &&
5389 !Args.hasArg(options::OPT_emit_llvm)) &&
5396 Args.hasArg(options::OPT_S) &&
5400 !Args.hasFlag(options::OPT_offload_new_driver,
5401 options::OPT_no_offload_new_driver,
5402 C.getActiveOffloadKinds() !=
5405 : types::TY_LLVM_BC;
5418 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5427 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5431 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5433 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5453 unsigned NumOutputs = 0;
5454 unsigned NumIfsOutputs = 0;
5455 for (
const Action *A :
C.getActions()) {
5461 if (A->
getType() != types::TY_Nothing &&
5463 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5465 0 == NumIfsOutputs++) ||
5470 A->
getType() == types::TY_Nothing &&
5471 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5472 NumOutputs += A->
size();
5475 if (NumOutputs > 1) {
5476 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5477 FinalOutput =
nullptr;
5481 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5485 if (RawTriple.isOSBinFormatMachO())
5486 for (
const Arg *A :
C.getArgs())
5487 if (A->getOption().matches(options::OPT_arch))
5491 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5492 for (
Action *A :
C.getActions()) {
5499 const char *LinkingOutput =
nullptr;
5502 LinkingOutput = FinalOutput->getValue();
5511 LinkingOutput, CachedResults,
5518 for (
auto &J :
C.getJobs())
5519 J.InProcess =
false;
5522 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5523 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5528 const char *LinkingOutput =
nullptr;
5530 LinkingOutput = FinalOutput->getValue();
5537 using namespace llvm;
5540 <<
"output=" << LinkingOutput;
5541 outs() <<
", total="
5542 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5544 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5545 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5549 llvm::raw_string_ostream Out(Buffer);
5550 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5553 llvm::sys::printArg(Out, LinkingOutput,
true);
5554 Out <<
',' << ProcStat->TotalTime.count() <<
','
5555 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5560 llvm::sys::fs::OF_Append |
5561 llvm::sys::fs::OF_Text);
5566 llvm::errs() <<
"ERROR: Cannot lock file "
5568 <<
toString(L.takeError()) <<
"\n";
5579 bool ReportUnusedArguments =
5580 !Diags.hasErrorOccurred() &&
5581 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5584 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5586 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5589 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5590 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5592 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5596 return strstr(J.getCreator().getShortName(),
"assembler");
5598 for (Arg *A :
C.getArgs()) {
5602 if (!A->isClaimed()) {
5608 const Option &Opt = A->getOption();
5609 if (Opt.getKind() == Option::FlagClass) {
5610 bool DuplicateClaimed =
false;
5612 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5613 if (AA->isClaimed()) {
5614 DuplicateClaimed =
true;
5619 if (DuplicateClaimed)
5625 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5627 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5632 !
C.getActions().empty()) {
5633 Diag(diag::err_drv_unsupported_opt_for_target)
5635 }
else if (ReportUnusedArguments) {
5636 Diag(clang::diag::warn_drv_unused_argument)
5637 << A->getAsString(
C.getArgs());
5647class ToolSelector final {
5658 bool IsHostSelector;
5669 bool CanBeCollapsed =
true) {
5671 if (Inputs.size() != 1)
5674 Action *CurAction = *Inputs.begin();
5675 if (CanBeCollapsed &&
5681 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5685 if (!IsHostSelector) {
5686 if (OA->hasSingleDeviceDependence(
true)) {
5688 OA->getSingleDeviceDependence(
true);
5689 if (CanBeCollapsed &&
5692 SavedOffloadAction.push_back(OA);
5693 return dyn_cast<JobAction>(CurAction);
5695 }
else if (OA->hasHostDependence()) {
5696 CurAction = OA->getHostDependence();
5697 if (CanBeCollapsed &&
5700 SavedOffloadAction.push_back(OA);
5701 return dyn_cast<JobAction>(CurAction);
5706 return dyn_cast<JobAction>(CurAction);
5710 bool canCollapseAssembleAction()
const {
5711 return TC.useIntegratedAs() && !SaveTemps &&
5712 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5713 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5714 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5715 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5719 bool canCollapsePreprocessorAction()
const {
5720 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5721 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5722 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5727 struct JobActionInfo final {
5729 const JobAction *JA =
nullptr;
5737 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5738 ArrayRef<JobActionInfo> &ActionInfo,
5739 unsigned ElementNum) {
5740 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5741 for (
unsigned I = 0; I < ElementNum; ++I)
5742 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5743 ActionInfo[I].SavedOffloadAction.end());
5756 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5759 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5761 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5762 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5763 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5764 if (!AJ || !BJ || !CJ)
5768 const Tool *T = TC.SelectTool(*CJ);
5781 const Tool *BT = TC.SelectTool(*BJ);
5789 Inputs = CJ->getInputs();
5790 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5794 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5797 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5799 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5800 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5805 const Tool *T = TC.SelectTool(*BJ);
5812 Inputs = BJ->getInputs();
5813 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5817 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5820 if (ActionInfo.size() < 2)
5822 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5823 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5827 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5828 for (
auto &Input : AI.JA->getInputs())
5839 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5840 if (SaveTemps && !InputIsBitcode)
5844 const Tool *T = TC.SelectTool(*CJ);
5857 Inputs = CJ->getInputs();
5858 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5867 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5875 for (Action *A : Inputs) {
5876 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5878 NewInputs.push_back(A);
5884 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5885 PreprocessJobOffloadActions.end());
5886 NewInputs.append(PJ->input_begin(), PJ->input_end());
5892 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5894 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5896 assert(BaseAction &&
"Invalid base action.");
5912 SmallVector<JobActionInfo, 5> ActionChain(1);
5913 ActionChain.back().JA = BaseAction;
5914 while (ActionChain.back().JA) {
5915 const Action *CurAction = ActionChain.back().JA;
5918 ActionChain.resize(ActionChain.size() + 1);
5919 JobActionInfo &AI = ActionChain.back();
5923 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5927 ActionChain.pop_back();
5935 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5936 CollapsedOffloadAction);
5938 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5940 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5946 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5958 StringRef BoundArch,
5960 std::string TriplePlusArch = TC->
getTriple().normalize();
5961 if (!BoundArch.empty()) {
5962 TriplePlusArch +=
"-";
5963 TriplePlusArch += BoundArch;
5965 TriplePlusArch +=
"-";
5967 return TriplePlusArch;
5972 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5973 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5976 std::pair<const Action *, std::string> ActionTC = {
5978 auto CachedResult = CachedResults.find(ActionTC);
5979 if (CachedResult != CachedResults.end()) {
5980 return CachedResult->second;
5983 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5984 CachedResults, TargetDeviceOffloadKind);
5985 CachedResults[ActionTC] =
Result;
5990 const JobAction *JA,
const char *BaseInput,
5993 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6004 OffloadingPrefix +=
"-";
6005 OffloadingPrefix +=
Arch;
6008 C.getDriver().isSaveTempsEnabled()) {
6015 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6016 Path = A->getValue();
6017 if (llvm::sys::fs::is_directory(Path)) {
6019 ? llvm::sys::path::stem(
Result.getFilename())
6020 : llvm::sys::path::stem(BaseInput));
6021 Tmp += OffloadingPrefix;
6023 llvm::sys::path::append(Path, Tmp);
6026 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6029 Path = DumpDir->getValue();
6030 Path += llvm::sys::path::stem(BaseInput);
6031 Path += OffloadingPrefix;
6032 }
else if (!OffloadingPrefix.empty()) {
6036 TraceName += OffloadingPrefix;
6037 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6038 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6039 llvm::sys::path::append(Path, TraceName);
6041 Path =
Result.getFilename();
6043 llvm::sys::path::replace_extension(Path,
"json");
6045 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6046 C.addTimeTraceFile(ResultFile, JA);
6047 C.addResultFile(ResultFile, JA);
6052 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6053 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6056 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6059 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6060 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6092 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6094 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6095 const char *DepBoundArch) {
6098 LinkingOutput, CachedResults,
6108 OA->doOnEachDependence(
6109 BuildingForOffloadDevice,
6110 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6112 C, DepA, DepTC, DepBoundArch,
false,
6113 !!DepBoundArch, LinkingOutput, CachedResults,
6117 A = BuildingForOffloadDevice
6118 ? OA->getSingleDeviceDependence(
true)
6119 : OA->getHostDependence();
6123 std::pair<const Action *, std::string> ActionTC = {
6124 OA->getHostDependence(),
6126 auto It = CachedResults.find(ActionTC);
6127 if (It != CachedResults.end()) {
6129 Inputs.append(OffloadDependencesInputInfo);
6134 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6137 const Arg &Input = IA->getInputArg();
6139 if (Input.getOption().matches(options::OPT_INPUT)) {
6140 const char *
Name = Input.getValue();
6143 return {InputInfo(A, &Input,
"")};
6146 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6147 const ToolChain *TC;
6150 if (!ArchName.empty())
6151 TC = &getToolChain(
C.getArgs(),
6153 C.getArgs(), ArchName));
6155 TC = &
C.getDefaultToolChain();
6158 MultipleArchs, LinkingOutput, CachedResults,
6159 TargetDeviceOffloadKind);
6170 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6173 return {InputInfo()};
6177 for (
const auto *OA : CollapsedOffloadActions)
6179 BuildingForOffloadDevice,
6180 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6182 C, DepA, DepTC, DepBoundArch,
false,
6183 !!DepBoundArch, LinkingOutput, CachedResults,
6189 for (
const Action *Input : Inputs) {
6193 bool SubJobAtTopLevel =
6196 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6201 const char *BaseInput = InputInfos[0].getBaseInput();
6202 for (
auto &Info : InputInfos) {
6203 if (Info.isFilename()) {
6204 BaseInput = Info.getBaseInput();
6211 if (JA->
getType() == types::TY_dSYM)
6212 BaseInput = InputInfos[0].getFilename();
6215 if (!OffloadDependencesInputInfo.empty())
6216 InputInfos.append(OffloadDependencesInputInfo.begin(),
6217 OffloadDependencesInputInfo.end());
6220 llvm::Triple EffectiveTriple;
6222 const ArgList &Args =
6224 if (InputInfos.size() != 1) {
6228 EffectiveTriple = llvm::Triple(
6231 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6236 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6240 for (
auto &UI : UA->getDependentActionsInfo()) {
6242 "Unbundling with no offloading??");
6249 UI.DependentOffloadKind,
6250 UI.DependentToolChain->getTriple().normalize(),
6252 auto CurI = InputInfo(
6261 UnbundlingResults.push_back(CurI);
6270 Arch = UI.DependentBoundArch;
6275 UI.DependentOffloadKind)}] = {
6281 std::pair<const Action *, std::string> ActionTC = {
6283 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6284 "Result does not exist??");
6285 Result = CachedResults[ActionTC].front();
6286 }
else if (JA->
getType() == types::TY_Nothing)
6287 Result = {InputInfo(A, BaseInput)};
6297 AtTopLevel, MultipleArchs,
6306 <<
" - \"" << T->
getName() <<
"\", inputs: [";
6307 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6308 llvm::errs() << InputInfos[i].getAsString();
6310 llvm::errs() <<
", ";
6312 if (UnbundlingResults.empty())
6313 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6315 llvm::errs() <<
"], outputs: [";
6316 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6317 llvm::errs() << UnbundlingResults[i].getAsString();
6319 llvm::errs() <<
", ";
6321 llvm::errs() <<
"] \n";
6324 if (UnbundlingResults.empty())
6328 Args, LinkingOutput);
6334 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6335 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6347 if (ArgValue.empty()) {
6349 Filename = BaseName;
6350 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6352 llvm::sys::path::append(Filename, BaseName);
6355 if (!llvm::sys::path::has_extension(ArgValue)) {
6360 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6365 llvm::sys::path::replace_extension(Filename, Extension);
6368 return Args.MakeArgString(Filename.c_str());
6383 StringRef Suffix,
bool MultipleArchs,
6384 StringRef BoundArch,
6385 bool NeedUniqueDirectory)
const {
6387 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6388 std::optional<std::string> CrashDirectory =
6390 ? std::string(A->getValue())
6391 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6392 if (CrashDirectory) {
6393 if (!
getVFS().exists(*CrashDirectory))
6394 llvm::sys::fs::create_directories(*CrashDirectory);
6396 llvm::sys::path::append(Path, Prefix);
6397 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6398 if (std::error_code EC =
6399 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6400 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6404 if (MultipleArchs && !BoundArch.empty()) {
6405 if (NeedUniqueDirectory) {
6407 llvm::sys::path::append(TmpName,
6408 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6418 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6433 const char *BaseInput) {
6435 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6436 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6441 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6445 const char *BaseInput,
6446 StringRef OrigBoundArch,
bool AtTopLevel,
6448 StringRef OffloadingPrefix)
const {
6451 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6454 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6455 return C.addResultFile(FinalOutput->getValue(), &JA);
6459 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6461 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6463 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6464 NameArg = A->getValue();
6465 return C.addResultFile(
6475 if (JA.
getType() == types::TY_ModuleFile &&
6476 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6480 if (JA.
getType() == types::TY_PP_Asm &&
6481 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6482 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6485 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6488 if ((JA.
getType() == types::TY_Object &&
6489 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6490 JA.
getType() == types::TY_DX_CONTAINER) {
6491 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6492 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6493 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6494 "expected DXIL or SPIR-V triple for HLSL output path");
6499 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6501 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6502 StringRef
Name = llvm::sys::path::filename(BaseInput);
6503 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6509 if (JA.
getType() == types::TY_PP_Asm &&
6510 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6511 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6513 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6514 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6515 return C.addResultFile(
6520 if (JA.
getType() == types::TY_API_INFO &&
6521 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6522 C.getArgs().hasArg(options::OPT_o))
6523 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6524 <<
C.getArgs().getLastArgValue(options::OPT_o);
6531 bool SpecifiedModuleOutput =
6532 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6533 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6534 if (MultipleArchs && SpecifiedModuleOutput)
6535 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6540 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6541 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6547 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6549 StringRef
Name = llvm::sys::path::filename(BaseInput);
6550 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6551 const char *Suffix =
6556 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6557 bool NeedUniqueDirectory =
6560 Triple.isOSDarwin();
6561 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6562 NeedUniqueDirectory);
6571 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6576 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6577 llvm::sys::path::filename(BasePath));
6578 BaseName = ExternalPath;
6580 BaseName = BasePath;
6582 BaseName = llvm::sys::path::filename(BasePath);
6585 const char *NamedOutput;
6587 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6588 JA.
getType() == types::TY_LLVM_BC ||
6589 JA.
getType() == types::TY_LLVM_IR) &&
6590 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6594 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6598 }
else if (JA.
getType() == types::TY_Image &&
6599 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6600 options::OPT__SLASH_o)) {
6604 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6608 }
else if (JA.
getType() == types::TY_Image) {
6618 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6619 options::OPT_fno_gpu_rdc,
false);
6621 if (UseOutExtension) {
6623 llvm::sys::path::replace_extension(Output,
"");
6625 Output += OffloadingPrefix;
6626 if (MultipleArchs && !BoundArch.empty()) {
6628 Output.append(BoundArch);
6630 if (UseOutExtension)
6632 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6635 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6636 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6637 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6640 .getLastArg(options::OPT__SLASH_o)
6645 const char *Suffix =
6647 assert(Suffix &&
"All types used for output should have a suffix.");
6649 std::string::size_type End = std::string::npos;
6651 End = BaseName.rfind(
'.');
6653 Suffixed += OffloadingPrefix;
6654 if (MultipleArchs && !BoundArch.empty()) {
6656 Suffixed.append(BoundArch);
6661 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6662 const llvm::opt::DerivedArgList &Args) {
6669 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6671 Args.hasFlag(options::OPT_offload_new_driver,
6672 options::OPT_no_offload_new_driver,
true))) ||
6679 bool IsLinkerWrapper =
6681 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6682 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6683 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6685 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6689 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6693 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6694 JA.
getType() != types::TY_PCH) {
6695 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6697 llvm::sys::path::remove_filename(TempPath);
6698 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6699 llvm::sys::path::append(TempPath, OutputFileName);
6700 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6706 bool SameFile =
false;
6708 llvm::sys::fs::current_path(
Result);
6709 llvm::sys::path::append(
Result, BaseName);
6710 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6713 StringRef
Name = llvm::sys::path::filename(BaseInput);
6714 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6718 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6724 llvm::sys::path::remove_filename(BasePath);
6725 if (BasePath.empty())
6726 BasePath = NamedOutput;
6728 llvm::sys::path::append(BasePath, NamedOutput);
6729 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6732 return C.addResultFile(NamedOutput, &JA);
6738 -> std::optional<std::string> {
6741 for (
const auto &
Dir : P) {
6745 llvm::sys::path::append(P,
Name);
6746 if (llvm::sys::fs::exists(Twine(P)))
6747 return std::string(P);
6749 return std::nullopt;
6756 llvm::sys::path::append(R,
Name);
6757 if (llvm::sys::fs::exists(Twine(R)))
6758 return std::string(R);
6761 llvm::sys::path::append(P,
Name);
6762 if (llvm::sys::fs::exists(Twine(P)))
6763 return std::string(P);
6766 llvm::sys::path::append(D,
"..",
Name);
6767 if (llvm::sys::fs::exists(Twine(D)))
6768 return std::string(D);
6777 llvm::sys::path::append(R2,
"..",
"..",
Name);
6778 if (llvm::sys::fs::exists(Twine(R2)))
6779 return std::string(R2);
6781 return std::string(
Name);
6784void Driver::generatePrefixedToolNames(
6788 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6789 Names.emplace_back(
Tool);
6793 llvm::sys::path::append(Dir, Name);
6794 if (llvm::sys::fs::can_execute(Twine(Dir)))
6796 llvm::sys::path::remove_filename(Dir);
6802 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6807 if (llvm::sys::fs::is_directory(PrefixDir)) {
6810 return std::string(P);
6813 if (llvm::sys::fs::can_execute(Twine(P)))
6814 return std::string(P);
6819 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6827 for (
const auto &Path : List) {
6830 return std::string(P);
6834 if (llvm::ErrorOr<std::string> P =
6835 llvm::sys::findProgramByName(TargetSpecificExecutable))
6839 return std::string(
Name);
6844 std::string error =
"<NOT PRESENT>";
6846 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6851 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6868 llvm::sys::path::remove_filename(path);
6869 llvm::sys::path::append(path,
"libc++.modules.json");
6870 if (TC.
getVFS().exists(path))
6871 return static_cast<std::string
>(path);
6876 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6879 return evaluate(
"libc++.a").value_or(error);
6883 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6887 llvm::sys::path::remove_filename(path);
6888 llvm::sys::path::append(path,
"libstdc++.modules.json");
6889 if (TC.
getVFS().exists(path))
6890 return static_cast<std::string
>(path);
6895 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6898 return evaluate(
"libstdc++.a").value_or(error);
6907 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6909 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6913 return std::string(Path);
6918 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6920 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6924 return std::string(Path);
6929 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6933 Output = FpArg->getValue();
6937 if (!llvm::sys::path::has_extension(Output))
6940 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6941 Output = YcArg->getValue();
6944 llvm::sys::path::replace_extension(Output,
".pch");
6946 return std::string(Output);
6949const ToolChain &Driver::getOffloadToolChain(
6951 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6952 std::unique_ptr<ToolChain> &TC =
6953 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6954 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6956 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6959 switch (
Target.getOS()) {
6960 case llvm::Triple::CUDA:
6961 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6964 case llvm::Triple::AMDHSA:
6966 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6969 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6978 switch (
Target.getArch()) {
6979 case llvm::Triple::spir:
6980 case llvm::Triple::spir64:
6981 case llvm::Triple::spirv:
6982 case llvm::Triple::spirv32:
6983 case llvm::Triple::spirv64:
6986 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6990 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6994 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6998 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7012 return getToolChain(Args,
Target);
7016const ToolChain &Driver::getToolChain(
const ArgList &Args,
7017 const llvm::Triple &
Target)
const {
7019 auto &TC = ToolChains[
Target.str()];
7021 switch (
Target.getOS()) {
7022 case llvm::Triple::AIX:
7023 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7025 case llvm::Triple::Haiku:
7026 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7028 case llvm::Triple::Darwin:
7029 case llvm::Triple::MacOSX:
7030 case llvm::Triple::IOS:
7031 case llvm::Triple::TvOS:
7032 case llvm::Triple::WatchOS:
7033 case llvm::Triple::XROS:
7034 case llvm::Triple::DriverKit:
7035 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7037 case llvm::Triple::DragonFly:
7038 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7040 case llvm::Triple::OpenBSD:
7041 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7043 case llvm::Triple::NetBSD:
7044 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7046 case llvm::Triple::FreeBSD:
7048 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7051 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7053 case llvm::Triple::Linux:
7054 case llvm::Triple::ELFIAMCU:
7055 if (
Target.getArch() == llvm::Triple::hexagon)
7056 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7058 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7059 !
Target.hasEnvironment())
7060 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7063 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7065 else if (
Target.getArch() == llvm::Triple::ve)
7066 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7067 else if (
Target.isOHOSFamily())
7068 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7069 else if (
Target.isWALI())
7070 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7072 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7074 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7076 case llvm::Triple::Fuchsia:
7077 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7079 case llvm::Triple::Managarm:
7080 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7082 case llvm::Triple::Serenity:
7083 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7085 case llvm::Triple::Solaris:
7086 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7088 case llvm::Triple::CUDA:
7089 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7091 case llvm::Triple::AMDHSA: {
7092 if (
Target.getArch() == llvm::Triple::spirv64) {
7093 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7098 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7100 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7105 case llvm::Triple::AMDPAL:
7106 case llvm::Triple::Mesa3D:
7107 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7109 case llvm::Triple::UEFI:
7110 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7112 case llvm::Triple::Win32:
7113 switch (
Target.getEnvironment()) {
7115 if (
Target.isOSBinFormatELF())
7116 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7117 else if (
Target.isOSBinFormatMachO())
7118 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7120 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7122 case llvm::Triple::GNU:
7123 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7125 case llvm::Triple::Cygnus:
7126 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7128 case llvm::Triple::Itanium:
7129 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7132 case llvm::Triple::MSVC:
7133 case llvm::Triple::UnknownEnvironment:
7134 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7135 .starts_with_insensitive(
"bfd"))
7136 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7140 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7144 case llvm::Triple::PS4:
7145 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7147 case llvm::Triple::PS5:
7148 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7150 case llvm::Triple::Hurd:
7151 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7153 case llvm::Triple::LiteOS:
7154 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7156 case llvm::Triple::ZOS:
7157 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7159 case llvm::Triple::Vulkan:
7160 case llvm::Triple::ShaderModel:
7161 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7163 case llvm::Triple::ChipStar:
7164 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7169 switch (
Target.getArch()) {
7170 case llvm::Triple::tce:
7171 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7173 case llvm::Triple::tcele:
7174 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7176 case llvm::Triple::tcele64:
7178 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7180 case llvm::Triple::hexagon:
7181 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7184 case llvm::Triple::lanai:
7185 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7187 case llvm::Triple::xcore:
7188 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7190 case llvm::Triple::wasm32:
7191 case llvm::Triple::wasm64:
7192 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7194 case llvm::Triple::avr:
7195 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7197 case llvm::Triple::msp430:
7198 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7200 case llvm::Triple::riscv32:
7201 case llvm::Triple::riscv64:
7202 case llvm::Triple::riscv32be:
7203 case llvm::Triple::riscv64be:
7204 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7206 case llvm::Triple::ve:
7207 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7209 case llvm::Triple::spirv32:
7210 case llvm::Triple::spirv64:
7211 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7213 case llvm::Triple::csky:
7214 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7216 case llvm::Triple::amdgcn:
7217 case llvm::Triple::r600:
7218 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7222 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7223 else if (
Target.isOSBinFormatELF())
7224 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7225 else if (
Target.isAppleFirmware())
7226 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7227 else if (
Target.isAppleMachO())
7228 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7229 else if (
Target.isOSBinFormatMachO())
7230 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7232 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7242 if (JA.
size() != 1 ||
7257 if (JA.
size() != 1 ||
7271 if (Args.hasArg(options::OPT_emit_static_lib))
7282 unsigned &Micro,
bool &HadExtra) {
7285 Major = Minor = Micro = 0;
7289 if (Str.consumeInteger(10, Major))
7293 if (!Str.consume_front(
"."))
7296 if (Str.consumeInteger(10, Minor))
7300 if (!Str.consume_front(
"."))
7303 if (Str.consumeInteger(10, Micro))
7321 unsigned CurDigit = 0;
7322 while (CurDigit < Digits.size()) {
7324 if (Str.consumeInteger(10, Digit))
7326 Digits[CurDigit] = Digit;
7329 if (!Str.consume_front(
"."))
7338llvm::opt::Visibility
7339Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7352const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7368 llvm_unreachable(
"Unhandled Mode");
7372 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7377 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7378 options::OPT_fno_save_optimization_record,
false))
7382 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7383 options::OPT_fno_save_optimization_record,
false))
7387 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7388 options::OPT_fno_save_optimization_record,
false))
7392 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7393 options::OPT_fno_save_optimization_record,
false))
7400 static StringRef OptName =
7402 llvm::StringRef Opt;
7403 for (StringRef Arg : Args) {
7404 if (!Arg.starts_with(OptName))
7410 return Opt.consume_front(OptName) ? Opt :
"";
7417 llvm::BumpPtrAllocator &Alloc,
7418 llvm::vfs::FileSystem *FS) {
7427 for (
const char *F : Args) {
7428 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7430 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7431 RSPQuoting = Windows;
7437 bool MarkEOLs = ClangCLMode;
7439 llvm::cl::TokenizerCallback Tokenizer;
7440 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7441 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7443 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7445 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7448 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7449 ECtx.setMarkEOLs(MarkEOLs);
7453 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7457 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7458 [](
const char *A) {
return A !=
nullptr; });
7459 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7462 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7463 Args.resize(newEnd - Args.begin());
7467 return llvm::Error::success();
7471 return SavedStrings.insert(S).first->getKeyData();
7505 llvm::StringSet<> &SavedStrings) {
7508 if (Edit[0] ==
'^') {
7509 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7510 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7511 Args.insert(Args.begin() + 1, Str);
7512 }
else if (Edit[0] ==
'+') {
7513 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7514 OS <<
"### Adding argument " << Str <<
" at end\n";
7515 Args.push_back(Str);
7516 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7517 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7518 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7519 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7520 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7522 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7524 if (Args[i] ==
nullptr)
7526 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7528 if (Repl != Args[i]) {
7529 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7533 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7534 auto Option = Edit.substr(1);
7535 for (
unsigned i = 1; i < Args.size();) {
7536 if (Option == Args[i]) {
7537 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7538 Args.erase(Args.begin() + i);
7539 if (Edit[0] ==
'X') {
7540 if (i < Args.size()) {
7541 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7542 Args.erase(Args.begin() + i);
7544 OS <<
"### Invalid X edit, end of command line!\n";
7549 }
else if (Edit[0] ==
'O') {
7550 for (
unsigned i = 1; i < Args.size();) {
7551 const char *A = Args[i];
7555 if (A[0] ==
'-' && A[1] ==
'O' &&
7556 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7557 (
'0' <= A[2] && A[2] <=
'9'))))) {
7558 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7559 Args.erase(Args.begin() + i);
7563 OS <<
"### Adding argument " << Edit <<
" at end\n";
7564 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7566 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7571 const char *OverrideStr,
7572 llvm::StringSet<> &SavedStrings,
7573 StringRef EnvVar, raw_ostream *OS) {
7575 OS = &llvm::nulls();
7577 if (OverrideStr[0] ==
'#') {
7579 OS = &llvm::nulls();
7582 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7586 const char *S = OverrideStr;
7588 const char *End = ::strchr(S,
' ');
7590 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
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.
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