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)
671 if (!Args.hasArg(options::OPT_target)) {
672 if (std::optional<std::string> ObjectModeValue =
673 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
674 StringRef ObjectMode = *ObjectModeValue;
675 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
677 if (ObjectMode ==
"64") {
678 AT =
Target.get64BitArchVariant().getArch();
679 }
else if (ObjectMode ==
"32") {
680 AT =
Target.get32BitArchVariant().getArch();
682 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
685 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
692 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
693 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
696 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
698 D.
Diag(diag::err_drv_unsupported_opt_for_target)
699 << A->getAsString(Args) <<
Target.str();
702 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
703 options::OPT_m32, options::OPT_m16,
704 options::OPT_maix32, options::OPT_maix64);
706 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
708 if (A->getOption().matches(options::OPT_m64) ||
709 A->getOption().matches(options::OPT_maix64)) {
710 AT =
Target.get64BitArchVariant().getArch();
711 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
712 Target.getEnvironment() == llvm::Triple::GNUT64)
713 Target.setEnvironment(llvm::Triple::GNU);
714 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
715 Target.setEnvironment(llvm::Triple::Musl);
716 }
else if (A->getOption().matches(options::OPT_mx32) &&
717 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
718 AT = llvm::Triple::x86_64;
719 if (
Target.getEnvironment() == llvm::Triple::Musl)
720 Target.setEnvironment(llvm::Triple::MuslX32);
722 Target.setEnvironment(llvm::Triple::GNUX32);
723 }
else if (A->getOption().matches(options::OPT_m32) ||
724 A->getOption().matches(options::OPT_maix32)) {
726 D.
Diag(diag::err_drv_unsupported_opt_for_target)
727 << A->getAsString(Args) <<
Target.str();
729 AT =
Target.get32BitArchVariant().getArch();
730 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
731 Target.setEnvironment(llvm::Triple::GNU);
732 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
733 Target.setEnvironment(llvm::Triple::Musl);
735 }
else if (A->getOption().matches(options::OPT_m16) &&
736 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
737 AT = llvm::Triple::x86;
738 Target.setEnvironment(llvm::Triple::CODE16);
741 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
743 if (
Target.isWindowsGNUEnvironment())
749 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
755 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
756 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
757 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
760 if (A && !A->getOption().matches(options::OPT_m32))
761 D.
Diag(diag::err_drv_argument_not_allowed_with)
762 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
764 Target.setArch(llvm::Triple::x86);
765 Target.setArchName(
"i586");
766 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
767 Target.setEnvironmentName(
"");
768 Target.setOS(llvm::Triple::ELFIAMCU);
769 Target.setVendor(llvm::Triple::UnknownVendor);
770 Target.setVendorName(
"intel");
776 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
777 StringRef ABIName = A->getValue();
778 if (ABIName ==
"32") {
780 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
781 Target.getEnvironment() == llvm::Triple::GNUABIN32)
782 Target.setEnvironment(llvm::Triple::GNU);
783 }
else if (ABIName ==
"n32") {
785 if (
Target.getEnvironment() == llvm::Triple::GNU ||
786 Target.getEnvironment() == llvm::Triple::GNUT64 ||
787 Target.getEnvironment() == llvm::Triple::GNUABI64)
788 Target.setEnvironment(llvm::Triple::GNUABIN32);
789 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
790 Target.getEnvironment() == llvm::Triple::MuslABI64)
791 Target.setEnvironment(llvm::Triple::MuslABIN32);
792 }
else if (ABIName ==
"64") {
794 if (
Target.getEnvironment() == llvm::Triple::GNU ||
795 Target.getEnvironment() == llvm::Triple::GNUT64 ||
796 Target.getEnvironment() == llvm::Triple::GNUABIN32)
797 Target.setEnvironment(llvm::Triple::GNUABI64);
798 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
799 Target.getEnvironment() == llvm::Triple::MuslABIN32)
800 Target.setEnvironment(llvm::Triple::MuslABI64);
808 if (Args.hasArg(options::OPT_march_EQ) ||
809 Args.hasArg(options::OPT_mcpu_EQ)) {
811 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
813 if (!llvm::errorToBool(ISAInfo.takeError())) {
814 unsigned XLen = (*ISAInfo)->getXLen();
816 if (
Target.isLittleEndian())
817 Target.setArch(llvm::Triple::riscv32);
819 Target.setArch(llvm::Triple::riscv32be);
820 }
else if (XLen == 64) {
821 if (
Target.isLittleEndian())
822 Target.setArch(llvm::Triple::riscv64);
824 Target.setArch(llvm::Triple::riscv64be);
830 if (
Target.getArch() == llvm::Triple::riscv32be ||
831 Target.getArch() == llvm::Triple::riscv64be) {
832 static bool WarnedRISCVBE =
false;
833 if (!WarnedRISCVBE) {
834 D.
Diag(diag::warn_drv_riscv_be_experimental);
835 WarnedRISCVBE =
true;
846 OptSpecifier OptEq, OptSpecifier OptNeg) {
847 if (!Args.hasFlag(OptEq, OptNeg,
false))
850 const Arg *A = Args.getLastArg(OptEq);
851 StringRef LTOName = A->getValue();
859 D.
Diag(diag::err_drv_unsupported_option_argument)
860 << A->getSpelling() << A->getValue();
867void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
869 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
871 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
872 options::OPT_fno_offload_lto);
875 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
876 options::OPT_fno_openmp_target_jit,
false)) {
877 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
878 options::OPT_fno_offload_lto))
880 Diag(diag::err_drv_incompatible_options)
881 << A->getSpelling() <<
"-fopenmp-target-jit";
888 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
890 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
892 RuntimeName = A->getValue();
894 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
902 Diag(diag::err_drv_unsupported_option_argument)
903 << A->getSpelling() << A->getValue();
906 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
915 StringRef Program =
C.getArgs().getLastArgValue(
916 options::OPT_offload_arch_tool_EQ,
"offload-arch");
919 if (llvm::ErrorOr<std::string> Executable =
920 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
923 Args.push_back(
"--only=amdgpu");
925 Args.push_back(
"--only=nvptx");
926 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
929 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
934 if ((*StdoutOrErr)->getBuffer().empty()) {
935 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
941 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
943 GPUArchs.push_back(
Arch.str());
945 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
956 std::set<std::string> Archs;
957 for (Arg *A :
C.getInputArgs()) {
958 for (StringRef
Arch : A->getValues()) {
959 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
960 if (
Arch ==
"native") {
962 Archs.insert(Str.str());
964 Archs.insert(
Arch.str());
966 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
970 Archs.erase(
Arch.str());
976 for (llvm::StringRef
Arch : Archs) {
980 llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
981 llvm::Triple::AMD, llvm::Triple::AMDHSA),
985 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
990 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
996 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1001 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
1002 <<
"offload" <<
Arch;
1006 llvm::Triple Triple =
1012 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1013 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1014 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1015 C.getArgs().MakeArgString(Triple.getArchName()),
1016 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1018 C.getArgs().append(A);
1019 C.getArgs().AddSynthesizedArg(A);
1021 auto It = Triples.lower_bound(Triple);
1022 if (It == Triples.end() || *It != Triple)
1023 Triples.insert(It, Triple);
1028 Triples.insert(llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
1029 llvm::Triple::AMD, llvm::Triple::AMDHSA));
1031 llvm::Triple::ArchType
Arch =
1032 C.getDefaultToolChain().getTriple().isArch64Bit()
1033 ? llvm::Triple::nvptx64
1034 : llvm::Triple::nvptx;
1035 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
1036 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1039 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1040 ? llvm::Triple::spirv64
1041 : llvm::Triple::spirv32));
1044 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1045 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1052 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1053 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1055 llvm::any_of(Inputs,
1056 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1061 (llvm::any_of(Inputs,
1062 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1065 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1066 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1068 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1069 options::OPT_fno_sycl,
false);
1070 bool IsOpenMPOffloading =
1072 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1073 options::OPT_fno_openmp,
false) &&
1074 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1075 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1076 !(IsCuda || IsHIP))));
1078 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1079 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1084 for (
const auto &[Active, Kind] : ActiveKinds)
1089 if (Kinds.size() > 1) {
1090 Diag(clang::diag::err_drv_mix_offload)
1097 if (IsCuda || IsHIP)
1104 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1105 std::vector<std::string> ArgValues =
1106 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1107 for (llvm::StringRef
Target : ArgValues) {
1111 if (ArgValues.empty())
1112 Diag(clang::diag::warn_drv_empty_joined_argument)
1114 .getLastArg(options::OPT_offload_targets_EQ)
1115 ->getAsString(
C.getInputArgs());
1122 llvm::StringMap<StringRef> FoundNormalizedTriples;
1123 for (
const llvm::Triple &
Target : Triples) {
1128 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1136 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1137 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1138 Diag(clang::diag::err_drv_argument_not_allowed_with)
1139 << IncompatArg->getSpelling() <<
"-fsycl";
1144 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1145 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1150 std::string NormalizedName =
Target.normalize();
1151 auto [TripleIt, Inserted] =
1152 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1154 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1155 <<
Target.str() << TripleIt->second;
1159 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1160 C.getDefaultToolChain().getTriple());
1164 auto &CudaInstallation =
1166 if (CudaInstallation.isValid())
1167 CudaInstallation.WarnIfUnsupportedVersion();
1170 C.addOffloadDeviceToolChain(&TC, Kind);
1175bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1180 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1184 if (!PathLIBEnv.empty()) {
1185 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1186 if (llvm::sys::fs::is_directory(PathLIBEnv))
1187 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1188 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1189 return readConfigFile(CustomizationFile, ExpCtx);
1190 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1195 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1196 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1197 return readConfigFile(CustomizationFile, ExpCtx);
1207 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1208 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1209 Copy->getValues() = Opt->getValues();
1210 if (Opt->isClaimed())
1212 Copy->setOwnsValues(Opt->getOwnsValues());
1213 Opt->setOwnsValues(
false);
1215 if (Opt->getAlias()) {
1216 const Arg *Alias = Opt->getAlias();
1217 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1218 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1219 Args.getArgString(Index), Index);
1220 AliasCopy->getValues() = Alias->getValues();
1221 AliasCopy->setOwnsValues(
false);
1222 if (Alias->isClaimed())
1224 Copy->setAlias(std::move(AliasCopy));
1228bool Driver::readConfigFile(StringRef
FileName,
1229 llvm::cl::ExpansionContext &ExpCtx) {
1233 Diag(diag::err_drv_cannot_open_config_file)
1234 <<
FileName << Status.getError().message();
1237 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1238 Diag(diag::err_drv_cannot_open_config_file)
1239 <<
FileName <<
"not a regular file";
1244 SmallVector<const char *, 32> NewCfgFileArgs;
1245 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1246 Diag(diag::err_drv_cannot_read_config_file)
1252 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1253 for (
const char *Opt : NewCfgFileArgs) {
1255 if (Opt[0] ==
'$' && Opt[1])
1256 NewCfgTailArgs.push_back(Opt + 1);
1258 NewCfgHeadArgs.push_back(Opt);
1262 llvm::SmallString<128> CfgFileName(
FileName);
1263 llvm::sys::path::native(CfgFileName);
1264 bool ContainErrors =
false;
1265 auto NewHeadOptions = std::make_unique<InputArgList>(
1269 auto NewTailOptions = std::make_unique<InputArgList>(
1276 for (Arg *A : *NewHeadOptions)
1278 for (Arg *A : *NewTailOptions)
1281 if (!CfgOptionsHead)
1282 CfgOptionsHead = std::move(NewHeadOptions);
1285 for (
auto *Opt : *NewHeadOptions)
1289 if (!CfgOptionsTail)
1290 CfgOptionsTail = std::move(NewTailOptions);
1293 for (
auto *Opt : *NewTailOptions)
1297 ConfigFiles.push_back(std::string(CfgFileName));
1301bool Driver::loadConfigFiles() {
1302 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1303 llvm::cl::tokenizeConfigFile, &
getVFS());
1307 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1308 SmallString<128> CfgDir;
1310 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1311 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1316 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1317 SmallString<128> CfgDir;
1318 llvm::sys::fs::expand_tilde(
1319 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1320 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1329 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1332 if (loadDefaultConfigFiles(ExpCtx))
1336 SmallString<128> CfgFilePath;
1338 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1341 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1342 CfgFilePath.assign(CfgFileName);
1343 if (llvm::sys::path::is_relative(CfgFilePath)) {
1344 if (
getVFS().makeAbsolute(CfgFilePath)) {
1345 Diag(diag::err_drv_cannot_open_config_file)
1346 << CfgFilePath <<
"cannot get absolute path";
1350 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1352 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1353 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1354 if (!SearchDir.empty())
1355 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1360 if (readConfigFile(CfgFilePath, ExpCtx))
1371 llvm::Triple Triple, std::string Suffix) {
1373 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1377 VersionTuple OSVersion = Triple.getOSVersion();
1378 if (!OSVersion.getMinor().has_value())
1381 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1385 if (OSVersion.getMajor() != 0) {
1386 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1387 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1393 Triple.setOSName(BaseOSName);
1394 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1397bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1400 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1404 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1407 std::string RealMode = getExecutableForDriverMode(Mode);
1408 llvm::Triple Triple;
1417 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1418 PrefixTriple.isOSUnknown())
1419 Triple = std::move(PrefixTriple);
1423 llvm::Triple RealTriple =
1425 if (Triple.str().empty()) {
1426 Triple = RealTriple;
1427 assert(!Triple.str().empty());
1432 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1446 SmallString<128> CfgFilePath;
1448 "-" + RealMode +
".cfg"))
1449 return readConfigFile(CfgFilePath, ExpCtx);
1453 if (TryModeSuffix) {
1456 return readConfigFile(CfgFilePath, ExpCtx);
1461 std::string CfgFileName = RealMode +
".cfg";
1462 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1463 if (readConfigFile(CfgFilePath, ExpCtx))
1465 }
else if (TryModeSuffix) {
1467 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1468 readConfigFile(CfgFilePath, ExpCtx))
1474 return readConfigFile(CfgFilePath, ExpCtx);
1482 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1491 if (!DriverMode.empty())
1492 setDriverMode(DriverMode);
1498 CLOptions = std::make_unique<InputArgList>(
1503 ContainsError = loadConfigFiles();
1504 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1505 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1509 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1511 if (HasConfigFileHead)
1512 for (
auto *Opt : *CLOptions)
1513 if (!Opt->getOption().matches(options::OPT_config))
1517 if (
IsCLMode() && !ContainsError) {
1519 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1521 CLModePassThroughArgList.push_back(A->getValue());
1524 if (!CLModePassThroughArgList.empty()) {
1527 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1532 for (
auto *Opt : *CLModePassThroughOptions)
1538 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1539 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1540 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1543 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1544 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1545 if (!VFS->exists(IncludeDir))
1546 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1551 bool CCCPrintPhases;
1554 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1555 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1558 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1559 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1562 Args.ClaimAllArgs(options::OPT_pipe);
1570 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1572 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1573 CCCGenericGCCName = A->getValue();
1576 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1580 if (Args.hasArg(options::OPT_fproc_stat_report))
1587 llvm::Triple T(TargetTriple);
1588 T.setOS(llvm::Triple::Win32);
1589 T.setVendor(llvm::Triple::PC);
1590 T.setEnvironment(llvm::Triple::MSVC);
1591 T.setObjectFormat(llvm::Triple::COFF);
1592 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1593 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1594 TargetTriple = T.str();
1597 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1598 StringRef TargetProfile = A->getValue();
1601 TargetTriple = *Triple;
1603 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1607 if (Args.hasArg(options::OPT_spirv)) {
1608 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1609 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1610 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1611 llvm::Triple T(TargetTriple);
1614 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1616 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1617 TargetInfo = ValidTargets.find(A->getValue());
1619 Diag(diag::err_drv_invalid_value)
1620 << A->getAsString(Args) << A->getValue();
1626 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1627 TargetTriple = T.str();
1631 Diag(diag::err_drv_dxc_missing_target_profile);
1635 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1636 TargetTriple = A->getValue();
1637 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1638 Dir = A->getValue();
1639 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1643 if (std::optional<std::string> CompilerPathValue =
1644 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1645 StringRef CompilerPath = *CompilerPathValue;
1646 while (!CompilerPath.empty()) {
1647 std::pair<StringRef, StringRef> Split =
1648 CompilerPath.split(llvm::sys::EnvPathSeparator);
1649 PrefixDirs.push_back(std::string(Split.first));
1650 CompilerPath = Split.second;
1653 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1655 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1658 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1661 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1662 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1663 .Case(
"cwd", SaveTempsCwd)
1664 .Case(
"obj", SaveTempsObj)
1665 .Default(SaveTempsCwd);
1668 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1669 options::OPT_offload_device_only,
1670 options::OPT_offload_host_device)) {
1671 if (A->getOption().matches(options::OPT_offload_host_only))
1672 Offload = OffloadHost;
1673 else if (A->getOption().matches(options::OPT_offload_device_only))
1674 Offload = OffloadDevice;
1676 Offload = OffloadHostDevice;
1682 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1683 StringRef
Name = A->getValue();
1684 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1685 .Case(
"off", EmbedNone)
1686 .Case(
"all", EmbedBitcode)
1687 .Case(
"bitcode", EmbedBitcode)
1688 .Case(
"marker", EmbedMarker)
1691 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1694 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1698 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1699 llvm::sys::fs::remove(A->getValue());
1705 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1707 !Args.hasArg(options::OPT_fmodules) && Std &&
1708 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1709 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1710 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1711 Std->containsValue(
"c++latest"));
1714 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1715 options::OPT_fmodule_header)) {
1717 ModulesModeCXX20 =
true;
1718 if (A->getOption().matches(options::OPT_fmodule_header))
1721 StringRef ArgName = A->getValue();
1722 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1727 Diags.Report(diag::err_drv_invalid_value)
1728 << A->getAsString(Args) << ArgName;
1734 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1735 std::make_unique<InputArgList>(std::move(Args));
1745 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1746 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1748 bool MLContainsError;
1749 auto MultilibMacroDefineList =
1751 MLMacroDefinesChar,
false, MLContainsError));
1752 if (!MLContainsError) {
1753 for (
auto *Opt : *MultilibMacroDefineList) {
1760 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1764 if (!Triple.isWasm()) {
1765 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1766 StringRef TripleObjectFormat =
1767 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1768 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1769 TripleVersionName != TripleObjectFormat) {
1770 Diags.Report(diag::err_drv_triple_version_invalid)
1772 ContainsError =
true;
1777 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1778 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1779 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1787 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1788 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1790 case llvm::Triple::arm:
1791 case llvm::Triple::armeb:
1792 case llvm::Triple::thumb:
1793 case llvm::Triple::thumbeb:
1794 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1795 Diag(diag::warn_target_unrecognized_env)
1797 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1800 case llvm::Triple::aarch64:
1801 case llvm::Triple::aarch64_be:
1802 case llvm::Triple::aarch64_32:
1803 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1804 Diag(diag::warn_target_unrecognized_env)
1806 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1823 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1824 if (HasConfigFileTail && Inputs.size()) {
1827 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1828 for (Arg *A : *CfgOptionsTail)
1829 TranslatedLinkerIns.append(A);
1830 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1837 bool UseModulesDriver =
C->getArgs().hasFlag(
1838 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1840 if (UseModulesDriver) {
1841 Diags.Report(diag::remark_performing_driver_managed_module_build);
1849 const auto StdModuleManifestPath =
1852 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1853 Diags.Report(diag::remark_modules_manifest_not_found);
1855 Diags.Report(diag::remark_using_modules_manifest)
1856 << StdModuleManifestPath;
1857 if (
auto ManifestOrErr =
1859 ModulesManifest = std::move(*ManifestOrErr);
1861 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1862 return !ModuleEntry.IsStdlib;
1867 llvm::handleAllErrors(
1868 ManifestOrErr.takeError(),
1869 [&](llvm::json::ParseError &Err) {
1870 Diags.Report(diag::err_modules_manifest_failed_parse)
1873 [&](llvm::FileError &Err) {
1874 Diags.Report(diag::err_cannot_open_file)
1875 << Err.getFileName() << Err.messageWithoutFileInfo();
1883 if (TC.
getTriple().isOSBinFormatMachO())
1888 if (CCCPrintPhases) {
1895 if (UseModulesDriver)
1902 llvm::opt::ArgStringList ASL;
1903 for (
const auto *A : Args) {
1907 while (A->getAlias())
1909 A->render(Args, ASL);
1912 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1913 if (I != ASL.begin())
1915 llvm::sys::printArg(OS, *I,
true);
1920bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1921 SmallString<128> &CrashDiagDir) {
1922 using namespace llvm::sys;
1923 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1924 "Only knows about .crash files on Darwin");
1926 auto BypassSandbox = sandbox::scopedDisable();
1931 path::home_directory(CrashDiagDir);
1932 if (CrashDiagDir.starts_with(
"/var/root"))
1934 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1942 fs::file_status FileStatus;
1943 TimePoint<> LastAccessTime;
1944 SmallString<128> CrashFilePath;
1947 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1948 File != FileEnd && !EC;
File.increment(EC)) {
1952 if (fs::status(
File->path(), FileStatus))
1954 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1955 llvm::MemoryBuffer::getFile(
File->path());
1960 StringRef
Data = CrashFile.get()->getBuffer();
1961 if (!
Data.starts_with(
"Process:"))
1964 size_t ParentProcPos =
Data.find(
"Parent Process:");
1965 if (ParentProcPos == StringRef::npos)
1967 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1968 if (LineEnd == StringRef::npos)
1970 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1971 int OpenBracket = -1, CloseBracket = -1;
1972 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1973 if (ParentProcess[i] ==
'[')
1975 if (ParentProcess[i] ==
']')
1981 if (OpenBracket < 0 || CloseBracket < 0 ||
1982 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1983 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1993 const auto FileAccessTime = FileStatus.getLastModificationTime();
1994 if (FileAccessTime > LastAccessTime) {
1995 CrashFilePath.assign(
File->path());
1996 LastAccessTime = FileAccessTime;
2001 if (!CrashFilePath.empty()) {
2002 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2012 "\n********************\n\n"
2013 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2014 "Preprocessed source(s) and associated run script(s) are located at:";
2022 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2026 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2027 Level = llvm::StringSwitch<unsigned>(A->getValue())
2029 .Case(
"compiler", 1)
2041 ArgStringList SavedTemps;
2043 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2044 if (!IsLLD || Level < 2)
2051 SavedTemps = std::move(
C.getTempFiles());
2052 assert(!
C.getTempFiles().size());
2069 C.initCompilationForDiagnostics();
2074 Command NewLLDInvocation = Cmd;
2075 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2076 StringRef ReproduceOption =
2077 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2080 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2084 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2086 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2087 Diag(clang::diag::note_drv_command_failed_diag_msg)
2088 <<
"\n\n********************";
2090 Report->TemporaryFiles.push_back(TmpName);
2098 ArgStringList IRInputs;
2099 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2100 bool IgnoreInput =
false;
2106 IRInputs.push_back(it->second->getValue());
2110 }
else if (!strcmp(it->second->getValue(),
"-")) {
2111 Diag(clang::diag::note_drv_command_failed_diag_msg)
2112 <<
"Error generating preprocessed source(s) - "
2113 "ignoring input from stdin.";
2118 it = Inputs.erase(it);
2125 if (Inputs.empty() && IRInputs.empty()) {
2126 Diag(clang::diag::note_drv_command_failed_diag_msg)
2127 <<
"Error generating preprocessed source(s) - "
2128 "no preprocessable inputs.";
2135 for (
const Arg *A :
C.getArgs()) {
2136 if (A->getOption().matches(options::OPT_arch)) {
2137 StringRef ArchName = A->getValue();
2142 Diag(clang::diag::note_drv_command_failed_diag_msg)
2143 <<
"Error generating preprocessed source(s) - cannot generate "
2144 "preprocessed source with multiple -arch options.";
2149 if (!Inputs.empty()) {
2152 const ToolChain &TC =
C.getDefaultToolChain();
2153 if (TC.
getTriple().isOSBinFormatMachO())
2162 Diag(clang::diag::note_drv_command_failed_diag_msg)
2163 <<
"Error generating preprocessed source(s).";
2168 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2171 if (!FailingCommands.empty()) {
2172 Diag(clang::diag::note_drv_command_failed_diag_msg)
2173 <<
"Error generating preprocessed source(s).";
2177 const ArgStringList &TempFiles =
C.getTempFiles();
2178 if (TempFiles.empty()) {
2179 Diag(clang::diag::note_drv_command_failed_diag_msg)
2180 <<
"Error generating preprocessed source(s).";
2186 const ArgStringList &Files =
C.getTempFiles();
2191 for (
auto const *Input : IRInputs) {
2195 StringRef extension = llvm::sys::path::extension(Input);
2196 if (!extension.empty())
2197 extension = extension.drop_front();
2199 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2200 llvm::sys::path::stem(Input), extension, FD, Path);
2202 Diag(clang::diag::note_drv_command_failed_diag_msg)
2203 <<
"Error generating run script: " <<
"Failed copying IR input files"
2204 <<
" " << EC.message();
2208 EC = llvm::sys::fs::copy_file(Input, FD);
2210 Diag(clang::diag::note_drv_command_failed_diag_msg)
2211 <<
"Error generating run script: " <<
"Failed copying IR input files"
2212 <<
" " << EC.message();
2216 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2223 for (std::string &TempFile : TempFiles) {
2224 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2226 Report->TemporaryFiles.push_back(TempFile);
2227 if (ReproCrashFilename.empty()) {
2228 ReproCrashFilename = TempFile;
2229 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2231 if (StringRef(TempFile).ends_with(
".cache")) {
2234 VFS = llvm::sys::path::filename(TempFile);
2235 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2239 for (
const char *TempFile : SavedTemps)
2240 TempFiles.push_back(TempFile);
2246 llvm::sys::path::replace_extension(Script,
"sh");
2248 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2249 llvm::sys::fs::FA_Write,
2250 llvm::sys::fs::OF_Text);
2252 Diag(clang::diag::note_drv_command_failed_diag_msg)
2253 <<
"Error generating run script: " << Script <<
" " << EC.message();
2256 <<
"# Driver args: ";
2258 ScriptOS <<
"# Original command: ";
2259 Cmd.
Print(ScriptOS,
"\n",
true);
2260 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2261 if (!AdditionalInformation.empty())
2262 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2265 Report->TemporaryFiles.push_back(std::string(Script));
2266 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2270 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2272 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2273 Diag(clang::diag::note_drv_command_failed_diag_msg)
2274 << ReproCrashFilename.str();
2276 llvm::sys::path::append(CrashDiagDir,
Name);
2277 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2278 Diag(clang::diag::note_drv_command_failed_diag_msg)
2279 <<
"Crash backtrace is located in";
2280 Diag(clang::diag::note_drv_command_failed_diag_msg)
2281 << CrashDiagDir.str();
2282 Diag(clang::diag::note_drv_command_failed_diag_msg)
2283 <<
"(choose the .crash file that corresponds to your crash)";
2287 Diag(clang::diag::note_drv_command_failed_diag_msg)
2288 <<
"\n\n********************";
2298 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2309 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2310 if (
C.getArgs().hasArg(options::OPT_v))
2311 C.getJobs().Print(llvm::errs(),
"\n",
true);
2313 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2316 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2323 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2324 C.getJobs().Print(llvm::errs(),
"\n",
true);
2325 return Diags.hasErrorOccurred() ? 1 : 0;
2329 if (Diags.hasErrorOccurred())
2333 for (
auto &Job :
C.getJobs())
2334 setUpResponseFiles(
C, Job);
2336 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2339 if (FailingCommands.empty())
2345 for (
const auto &CmdPair : FailingCommands) {
2346 int CommandRes = CmdPair.first;
2347 const Command *FailingCommand = CmdPair.second;
2352 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2356 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2361 if (CommandRes == EX_IOERR) {
2381 if (CommandRes > 128 && CommandRes != 255)
2385 Diag(clang::diag::err_drv_command_signalled)
2388 Diag(clang::diag::err_drv_command_failed)
2396 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2398 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2412 const ToolChain &TC =
C.getDefaultToolChain();
2416 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2419 OS <<
"Thread model: " << A->getValue();
2425 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2430 if (!llvm::cl::getCompilerBuildConfig().empty())
2431 llvm::cl::printBuildConfig(OS);
2434 for (
auto ConfigFile : ConfigFiles)
2435 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2448 if (PassedFlags ==
"")
2452 std::vector<std::string> SuggestedCompletions;
2453 std::vector<std::string> Flags;
2465 const bool HasSpace = PassedFlags.ends_with(
",");
2469 StringRef TargetFlags = PassedFlags;
2470 while (TargetFlags !=
"") {
2472 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2473 Flags.push_back(std::string(CurFlag));
2478 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2481 const llvm::opt::OptTable &Opts =
getOpts();
2483 Cur = Flags.at(Flags.size() - 1);
2485 if (Flags.size() >= 2) {
2486 Prev = Flags.at(Flags.size() - 2);
2487 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2490 if (SuggestedCompletions.empty())
2491 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2498 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2499 llvm::outs() <<
'\n';
2505 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2509 SuggestedCompletions = Opts.findByPrefix(
2510 Cur, VisibilityMask,
2517 if (S.starts_with(Cur))
2518 SuggestedCompletions.push_back(std::string(S));
2525 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2526 if (
int X = A.compare_insensitive(B))
2528 return A.compare(B) > 0;
2531 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2538 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2539 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2543 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2546 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2550 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2555 if (
C.getArgs().hasArg(options::OPT_help) ||
2556 C.getArgs().hasArg(options::OPT__help_hidden)) {
2557 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2561 if (
C.getArgs().hasArg(options::OPT__version)) {
2568 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2569 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2570 if (ListExtractors || ListFormats) {
2578 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2583 if (
C.getArgs().hasArg(options::OPT_v) ||
2584 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2585 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2586 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2587 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2589 SuppressMissingInputWarning =
true;
2592 if (
C.getArgs().hasArg(options::OPT_v)) {
2594 llvm::errs() <<
"System configuration file directory: "
2597 llvm::errs() <<
"User configuration file directory: "
2601 const ToolChain &TC =
C.getDefaultToolChain();
2603 if (
C.getArgs().hasArg(options::OPT_v))
2606 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2611 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2612 llvm::outs() <<
"programs: =";
2613 bool separator =
false;
2617 llvm::outs() << llvm::sys::EnvPathSeparator;
2618 llvm::outs() << Path;
2623 llvm::outs() << llvm::sys::EnvPathSeparator;
2624 llvm::outs() << Path;
2627 llvm::outs() <<
"\n";
2630 StringRef sysroot =
C.getSysRoot();
2634 llvm::outs() << llvm::sys::EnvPathSeparator;
2637 llvm::outs() << sysroot << Path.substr(1);
2639 llvm::outs() << Path;
2641 llvm::outs() <<
"\n";
2645 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2651 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2652 for (
auto RuntimePath :
2654 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2655 llvm::outs() << *RuntimePath <<
'\n';
2659 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2663 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2665 for (std::size_t I = 0; I != Flags.size(); I += 2)
2666 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2672 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2673 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2677 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2678 StringRef ProgName = A->getValue();
2681 if (! ProgName.empty())
2684 llvm::outs() <<
"\n";
2688 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2689 StringRef PassedFlags = A->getValue();
2694 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2708 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2711 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2717 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2724 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2727 std::set<llvm::StringRef> SortedFlags;
2728 for (
const auto &FlagEntry : ExpandedFlags)
2729 SortedFlags.insert(FlagEntry.getKey());
2730 for (
auto Flag : SortedFlags)
2731 llvm::outs() << Flag <<
'\n';
2735 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2738 llvm::outs() <<
".\n";
2741 assert(Suffix.front() ==
'/');
2742 llvm::outs() << Suffix.substr(1) <<
"\n";
2748 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2753 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2755 llvm::outs() << Triple.getTriple() <<
"\n";
2759 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2760 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2777 std::map<Action *, unsigned> &Ids,
2779 if (
auto It = Ids.find(A); It != Ids.end())
2783 llvm::raw_string_ostream os(str);
2785 auto getSibIndent = [](
int K) -> Twine {
2789 Twine SibIndent =
Indent + getSibIndent(Kind);
2793 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2795 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2796 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2797 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2799 OA->doOnEachDependence(
2801 assert(TC &&
"Unknown host toolchain");
2813 os <<
":" << BoundArch;
2816 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2824 const char *Prefix =
"{";
2825 for (
Action *PreRequisite : *AL) {
2826 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2837 std::string offload_str;
2838 llvm::raw_string_ostream offload_os(offload_str);
2842 offload_os <<
", (" << S;
2849 auto getSelfIndent = [](
int K) -> Twine {
2853 unsigned Id = Ids.size();
2855 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2864 std::map<Action *, unsigned> Ids;
2865 for (
Action *A :
C.getActions())
2881 DerivedArgList &Args =
C.getArgs();
2883 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2888 for (Arg *A : Args) {
2889 if (A->getOption().matches(options::OPT_arch)) {
2892 llvm::Triple::ArchType
Arch =
2894 if (
Arch == llvm::Triple::UnknownArch) {
2895 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2900 if (
ArchNames.insert(A->getValue()).second)
2901 Archs.push_back(A->getValue());
2915 for (
Action* Act : SingleActions) {
2923 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2927 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2932 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2933 Actions.append(Inputs.begin(), Inputs.end());
2935 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2938 Arg *A = Args.getLastArg(options::OPT_g_Group);
2939 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2940 !A->getOption().matches(options::OPT_gstabs);
2941 bool enablesPseudoProbe =
2942 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2943 options::OPT_fno_pseudo_probe_for_profiling,
false);
2944 bool enablesDebugInfoForProfiling =
2945 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2946 options::OPT_fno_debug_info_for_profiling,
false);
2947 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2948 enablesDebugInfoForProfiling) &&
2956 if (Act->getType() == types::TY_Image) {
2958 Inputs.push_back(Actions.back());
2965 if (Args.hasArg(options::OPT_verify_debug_info)) {
2966 Action *LastAction = Actions.pop_back_val();
2968 LastAction, types::TY_Nothing));
2975 bool TypoCorrect)
const {
2987 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2988 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3000 std::string Nearest;
3001 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3002 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3003 <<
Value << Nearest;
3042 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3045 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3053 return types::TY_CXXUHeader;
3055 return types::TY_CXXSHeader;
3059 llvm_unreachable(
"should not be called in this case");
3061 return types::TY_CXXHUHeader;
3067 const llvm::opt::OptTable &Opts =
getOpts();
3071 types::ID InputType = types::TY_Nothing;
3072 Arg *InputTypeArg =
nullptr;
3075 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3076 options::OPT__SLASH_TP)) {
3077 InputTypeArg = TCTP;
3078 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3083 bool ShowNote =
false;
3085 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3087 Diag(clang::diag::warn_drv_overriding_option)
3088 <<
Previous->getSpelling() << A->getSpelling();
3094 Diag(clang::diag::note_drv_t_option_is_global);
3099 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3100 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3101 if (LastXArg && LastInputArg &&
3102 LastInputArg->getIndex() < LastXArg->getIndex())
3103 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3106 for (Arg *A : Args) {
3107 if (A->getOption().
getKind() == Option::InputClass) {
3108 const char *
Value = A->getValue();
3112 if (InputType == types::TY_Nothing) {
3115 InputTypeArg->claim();
3118 if (strcmp(
Value,
"-") == 0) {
3120 Ty = types::TY_Fortran;
3122 Ty = types::TY_HLSL;
3131 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3132 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3133 : clang::diag::err_drv_unknown_stdin_type);
3142 if (
const char *Ext = strrchr(
Value,
'.'))
3151 Ty = types::TY_HLSL;
3153 Ty = types::TY_Object;
3164 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3165 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3166 << getTypeName(OldTy) << getTypeName(Ty);
3171 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3172 Ty == types::TY_Object)
3173 Ty = types::TY_LLVM_BC;
3181 if (Ty != types::TY_Object) {
3182 if (Args.hasArg(options::OPT_ObjC))
3183 Ty = types::TY_ObjC;
3184 else if (Args.hasArg(options::OPT_ObjCXX))
3185 Ty = types::TY_ObjCXX;
3192 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3196 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3197 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3200 const char *Ext = strrchr(
Value,
'.');
3202 Ty = types::TY_Object;
3206 InputTypeArg->claim();
3210 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3211 Args.hasArgNoClaim(options::OPT_hipstdpar))
3215 Inputs.push_back(std::make_pair(Ty, A));
3217 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3218 StringRef
Value = A->getValue();
3221 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3222 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3225 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3226 StringRef
Value = A->getValue();
3229 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3230 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3236 Inputs.push_back(std::make_pair(types::TY_Object, A));
3238 }
else if (A->getOption().matches(options::OPT_x)) {
3247 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3248 InputType = types::TY_Object;
3255 }
else if (A->getOption().getID() == options::OPT_U) {
3256 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3257 StringRef Val = A->getValue(0);
3258 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3260 Diag(diag::warn_slash_u_filename) << Val;
3261 Diag(diag::note_use_dashdash);
3265 if (
CCCIsCPP() && Inputs.empty()) {
3269 Inputs.push_back(std::make_pair(types::TY_C, A));
3276class OffloadingActionBuilder final {
3278 bool IsValid =
false;
3284 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3287 std::map<Action *, const Arg *> HostActionToInputArgMap;
3290 class DeviceActionBuilder {
3294 enum ActionBuilderReturnCode {
3312 const ToolChain *FatBinaryToolChain =
nullptr;
3315 DerivedArgList &Args;
3324 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3327 :
C(
C), Args(Args), Inputs(Inputs),
3328 AssociatedOffloadKind(AssociatedOffloadKind) {}
3329 virtual ~DeviceActionBuilder() {}
3334 virtual ActionBuilderReturnCode
3335 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3338 return ABRT_Inactive;
3343 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3344 return ABRT_Inactive;
3348 virtual void appendTopLevelActions(
ActionList &AL) {}
3351 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3354 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3357 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3364 virtual bool canUseBundlerUnbundler()
const {
return false; }
3368 bool isValid() {
return !ToolChains.empty(); }
3372 return AssociatedOffloadKind;
3378 class CudaActionBuilderBase :
public DeviceActionBuilder {
3382 bool CompileHostOnly =
false;
3383 bool CompileDeviceOnly =
false;
3385 bool EmitAsm =
false;
3395 TargetID(
const char *ID) :
ID(
ID) {}
3396 operator const char *() {
return ID; }
3397 operator StringRef() {
return StringRef(ID); }
3400 SmallVector<TargetID, 4> GpuArchList;
3406 Action *CudaFatBinary =
nullptr;
3409 bool IsActive =
false;
3412 bool Relocatable =
false;
3415 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3418 const CUIDOptions &CUIDOpts;
3421 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3423 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3424 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3426 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3427 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3428 options::OPT_fno_gpu_rdc,
false);
3431 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3438 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3441 if (!(IA->getType() == types::TY_CUDA ||
3442 IA->getType() == types::TY_HIP ||
3443 IA->getType() == types::TY_PP_HIP)) {
3446 return ABRT_Inactive;
3453 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3455 if (CompileHostOnly)
3456 return ABRT_Success;
3459 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3460 : types::TY_CUDA_DEVICE;
3461 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3462 CudaDeviceActions.push_back(
3463 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3466 return ABRT_Success;
3470 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3474 if (UA->getType() == types::TY_Object && !Relocatable)
3475 return ABRT_Inactive;
3477 CudaDeviceActions.clear();
3479 std::string
FileName = IA->getInputArg().getAsString(Args);
3485 const StringRef LibFileExt =
".lib";
3486 if (IA->getType() == types::TY_Object &&
3487 (!llvm::sys::path::has_extension(
FileName) ||
3489 llvm::sys::path::extension(
FileName).drop_front()) !=
3491 llvm::sys::path::extension(
FileName) == LibFileExt))
3492 return ABRT_Inactive;
3494 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3495 CudaDeviceActions.push_back(UA);
3496 UA->registerDependentActionInfo(ToolChain,
Arch,
3497 AssociatedOffloadKind);
3500 return ABRT_Success;
3503 return IsActive ? ABRT_Success : ABRT_Inactive;
3506 void appendTopLevelActions(
ActionList &AL)
override {
3508 auto AddTopLevel = [&](Action *A, TargetID TargetID,
3509 const ToolChain *TC) {
3510 OffloadAction::DeviceDependences Dep;
3511 Dep.
add(*A, *TC, TargetID, AssociatedOffloadKind);
3512 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3516 if (CudaFatBinary) {
3517 AddTopLevel(CudaFatBinary, OffloadArch::Unused, FatBinaryToolChain);
3518 CudaDeviceActions.clear();
3519 CudaFatBinary =
nullptr;
3523 if (CudaDeviceActions.empty())
3529 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3530 "Expecting one action per GPU architecture.");
3531 assert(ToolChains.size() == GpuArchList.size() &&
3532 "Expecting to have a toolchain per GPU architecture");
3533 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3534 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3536 CudaDeviceActions.clear();
3539 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3557 assert(HostTC &&
"No toolchain for host compilation.");
3562 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3567 std::set<std::pair<StringRef, const ToolChain *>> GpuArchs;
3569 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3571 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3572 GpuArchs.insert({
Arch, I.second});
3576 for (
auto [
Arch, TC] : GpuArchs) {
3577 GpuArchList.push_back(
Arch.data());
3578 ToolChains.push_back(TC);
3581 FatBinaryToolChain = ToolChains.front();
3582 CompileHostOnly =
C.getDriver().offloadHostOnly();
3583 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3584 EmitAsm = Args.getLastArg(options::OPT_S);
3592 class CudaActionBuilder final :
public CudaActionBuilderBase {
3594 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3596 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3597 DefaultOffloadArch = OffloadArch::CudaDefault;
3600 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3602 const std::set<StringRef> &GpuArchs)
override {
3603 return std::nullopt;
3606 ActionBuilderReturnCode
3607 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3609 PhasesTy &Phases)
override {
3611 return ABRT_Inactive;
3615 if (CudaDeviceActions.empty())
3616 return ABRT_Success;
3618 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3619 "Expecting one action per GPU architecture.");
3620 assert(!CompileHostOnly &&
3621 "Not expecting CUDA actions in host-only compilation.");
3631 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3634 for (
auto Ph : Phases) {
3639 if (Ph > FinalPhase)
3642 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3656 Action *AssembleAction = CudaDeviceActions[I];
3657 assert(AssembleAction->
getType() == types::TY_Object);
3658 assert(AssembleAction->
getInputs().size() == 1);
3664 OffloadAction::DeviceDependences DDep;
3666 DeviceActions.push_back(
3667 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3672 if (!DeviceActions.empty()) {
3674 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3676 if (!CompileDeviceOnly) {
3677 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3681 CudaFatBinary =
nullptr;
3686 CudaDeviceActions.clear();
3690 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3695 return ABRT_Success;
3699 "instructions should only occur "
3700 "before the backend phase!");
3703 for (Action *&A : CudaDeviceActions)
3704 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3706 return ABRT_Success;
3711 class HIPActionBuilder final :
public CudaActionBuilderBase {
3713 SmallVector<ActionList, 8> DeviceLinkerInputs;
3719 std::optional<bool> BundleOutput;
3720 std::optional<bool> EmitReloc;
3723 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3725 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3727 DefaultOffloadArch = OffloadArch::HIPDefault;
3729 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3730 options::OPT_fno_hip_emit_relocatable)) {
3731 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3732 options::OPT_fno_hip_emit_relocatable, false);
3736 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3737 <<
"-fhip-emit-relocatable"
3741 if (!CompileDeviceOnly) {
3742 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3743 <<
"-fhip-emit-relocatable"
3744 <<
"--offload-device-only";
3749 if (Args.hasArg(options::OPT_gpu_bundle_output,
3750 options::OPT_no_gpu_bundle_output))
3751 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3752 options::OPT_no_gpu_bundle_output,
true) &&
3753 (!EmitReloc || !*EmitReloc);
3756 bool canUseBundlerUnbundler()
const override {
return true; }
3758 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3760 const std::set<StringRef> &GpuArchs)
override {
3764 ActionBuilderReturnCode
3765 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3767 PhasesTy &Phases)
override {
3769 return ABRT_Inactive;
3775 if (CudaDeviceActions.empty())
3776 return ABRT_Success;
3779 CudaDeviceActions.size() == GpuArchList.size()) &&
3780 "Expecting one action per GPU architecture.");
3781 assert(!CompileHostOnly &&
3782 "Not expecting HIP actions in host-only compilation.");
3784 bool ShouldLink = !EmitReloc || !*EmitReloc;
3787 !EmitAsm && ShouldLink) {
3793 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3794 if (
C.getDriver().isUsingOffloadLTO()) {
3798 AL.push_back(CudaDeviceActions[I]);
3801 CudaDeviceActions[I] =
3802 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3808 if (ToolChains[I]->
getTriple().isSPIRV() ||
3809 (ToolChains[I]->
getTriple().isAMDGCN() &&
3810 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3814 types::ID Output = Args.hasArg(options::OPT_S)
3816 : types::TY_LLVM_BC;
3818 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3822 AssociatedOffloadKind);
3823 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3825 AssociatedOffloadKind);
3826 AL.push_back(AssembleAction);
3829 CudaDeviceActions[I] =
3830 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3839 OffloadAction::DeviceDependences DDep;
3840 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3841 AssociatedOffloadKind);
3842 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3843 DDep, CudaDeviceActions[I]->getType());
3846 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3848 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3849 types::TY_HIP_FATBIN);
3851 if (!CompileDeviceOnly) {
3852 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3853 AssociatedOffloadKind);
3856 CudaFatBinary =
nullptr;
3861 CudaDeviceActions.clear();
3864 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3867 return ABRT_Success;
3873 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3874 auto LI = DeviceLinkerInputs.begin();
3875 for (
auto *A : CudaDeviceActions) {
3882 CudaDeviceActions.clear();
3883 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3887 for (Action *&A : CudaDeviceActions)
3888 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3889 AssociatedOffloadKind);
3891 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3893 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3894 OffloadAction::DeviceDependences DDep;
3895 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3896 AssociatedOffloadKind);
3897 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3898 DDep, CudaDeviceActions[I]->getType());
3901 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3902 CudaDeviceActions.clear();
3905 return (CompileDeviceOnly &&
3906 (CurPhase == FinalPhase ||
3912 void appendLinkDeviceActions(
ActionList &AL)
override {
3913 if (DeviceLinkerInputs.size() == 0)
3916 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3917 "Linker inputs and GPU arch list sizes do not match.");
3923 for (
auto &LI : DeviceLinkerInputs) {
3925 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3929 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3932 OffloadAction::DeviceDependences DeviceLinkDeps;
3933 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3934 AssociatedOffloadKind);
3935 Actions.push_back(
C.MakeAction<OffloadAction>(
3936 DeviceLinkDeps, DeviceLinkAction->getType()));
3939 DeviceLinkerInputs.clear();
3942 if (Args.hasArg(options::OPT_emit_llvm)) {
3950 OffloadAction::DeviceDependences DDeps;
3951 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3952 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3954 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3955 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain,
nullptr,
3956 AssociatedOffloadKind);
3959 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3965 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3967 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3975 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3981 bool ShouldUseBundler;
3984 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3992 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3995 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4003 unsigned ValidBuilders = 0u;
4004 unsigned ValidBuildersSupportingBundling = 0u;
4005 for (
auto *SB : SpecializedBuilders) {
4006 IsValid = IsValid && !SB->initialize();
4009 if (SB->isValid()) {
4011 if (SB->canUseBundlerUnbundler())
4012 ++ValidBuildersSupportingBundling;
4016 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4018 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4019 options::OPT_no_gpu_bundle_output,
true);
4022 ~OffloadingActionBuilder() {
4023 for (
auto *SB : SpecializedBuilders)
4028 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4029 assert(HostAction &&
"Invalid host action");
4030 assert(InputArg &&
"Invalid input argument");
4031 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4032 assert(Loc->second == InputArg &&
4033 "host action mapped to multiple input arguments");
4042 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4044 DeviceActionBuilder::PhasesTy &Phases) {
4048 if (SpecializedBuilders.empty())
4051 assert(HostAction &&
"Invalid host action!");
4052 recordHostAction(HostAction, InputArg);
4057 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4058 unsigned InactiveBuilders = 0u;
4059 unsigned IgnoringBuilders = 0u;
4060 for (
auto *SB : SpecializedBuilders) {
4061 if (!SB->isValid()) {
4066 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4071 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4076 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4077 OffloadKind |= SB->getAssociatedOffloadKind();
4082 if (IgnoringBuilders &&
4083 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4100 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4101 const Arg *InputArg) {
4105 recordHostAction(HostAction, InputArg);
4114 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4116 HostAction->
getType() == types::TY_PP_HIP)) {
4117 auto UnbundlingHostAction =
4122 HostAction = UnbundlingHostAction;
4123 recordHostAction(HostAction, InputArg);
4126 assert(HostAction &&
"Invalid host action!");
4129 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4130 for (
auto *SB : SpecializedBuilders) {
4134 auto RetCode = SB->addDeviceDependences(HostAction);
4138 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4139 "Host dependence not expected to be ignored.!");
4143 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4144 OffloadKind |= SB->getAssociatedOffloadKind();
4149 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4159 const Arg *InputArg) {
4161 recordHostAction(HostAction, InputArg);
4165 for (
auto *SB : SpecializedBuilders) {
4168 SB->appendTopLevelActions(OffloadAL);
4175 if (CanUseBundler && ShouldUseBundler && HostAction &&
4176 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4178 OffloadAL.push_back(HostAction);
4182 assert(HostAction == AL.back() &&
"Host action not in the list??");
4184 recordHostAction(HostAction, InputArg);
4185 AL.back() = HostAction;
4187 AL.append(OffloadAL.begin(), OffloadAL.end());
4197 void appendDeviceLinkActions(
ActionList &AL) {
4198 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4201 SB->appendLinkDeviceActions(AL);
4205 Action *makeHostLinkAction() {
4208 appendDeviceLinkActions(DeviceAL);
4209 if (DeviceAL.empty())
4214 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4217 HA = SB->appendLinkHostActions(DeviceAL);
4234 for (
auto *SB : SpecializedBuilders) {
4238 SB->appendLinkDependences(DDeps);
4242 unsigned ActiveOffloadKinds = 0u;
4243 for (
auto &I : InputArgToOffloadKindMap)
4244 ActiveOffloadKinds |= I.second;
4256 for (
auto *A : HostAction->
inputs()) {
4257 auto ArgLoc = HostActionToInputArgMap.find(A);
4258 if (ArgLoc == HostActionToInputArgMap.end())
4260 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4261 if (OFKLoc == InputArgToOffloadKindMap.end())
4273 nullptr, ActiveOffloadKinds);
4279void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4284 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4285 StringRef
V = A->getValue();
4286 if (Inputs.size() > 1 && !
V.empty() &&
4287 !llvm::sys::path::is_separator(
V.back())) {
4289 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4290 << A->getSpelling() <<
V;
4291 Args.eraseArg(options::OPT__SLASH_Fo);
4296 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4297 StringRef
V = A->getValue();
4298 if (Inputs.size() > 1 && !
V.empty() &&
4299 !llvm::sys::path::is_separator(
V.back())) {
4301 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4302 << A->getSpelling() <<
V;
4303 Args.eraseArg(options::OPT__SLASH_Fa);
4308 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4309 if (A->getValue()[0] ==
'\0') {
4311 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4312 Args.eraseArg(options::OPT__SLASH_o);
4317 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4318 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4319 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4320 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4321 Args.eraseArg(options::OPT__SLASH_Yc);
4322 Args.eraseArg(options::OPT__SLASH_Yu);
4323 YcArg = YuArg =
nullptr;
4325 if (YcArg && Inputs.size() > 1) {
4326 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4327 Args.eraseArg(options::OPT__SLASH_Yc);
4335 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4336 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4337 Args.AddFlagArg(
nullptr,
4338 getOpts().getOption(options::OPT_frtlib_add_rpath));
4342 if (Args.hasArg(options::OPT_emit_llvm) &&
4343 !Args.hasArg(options::OPT_hip_link) &&
4344 !
C.getDefaultToolChain().getTriple().isSPIRV())
4345 Diag(clang::diag::err_drv_emit_llvm_link);
4346 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4348 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4349 .starts_with_insensitive(
"lld"))
4350 Diag(clang::diag::err_drv_lto_without_lld);
4356 if (!Args.hasArg(options::OPT_dumpdir)) {
4357 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4358 Arg *Arg = Args.MakeSeparateArg(
4359 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4361 (FinalOutput ? FinalOutput->getValue()
4373 Args.eraseArg(options::OPT__SLASH_Fp);
4374 Args.eraseArg(options::OPT__SLASH_Yc);
4375 Args.eraseArg(options::OPT__SLASH_Yu);
4376 YcArg = YuArg =
nullptr;
4379 if (Args.hasArg(options::OPT_include_pch) &&
4380 Args.hasArg(options::OPT_ignore_pch)) {
4384 Args.eraseArg(options::OPT_include_pch);
4387 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4388 for (
auto &I : Inputs) {
4390 const Arg *InputArg = I.second;
4395 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4399 if (InitialPhase > FinalPhase) {
4400 if (InputArg->isClaimed())
4407 if (Args.hasArg(options::OPT_Qunused_arguments))
4413 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4414 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4418 (Args.getLastArg(options::OPT__SLASH_EP,
4419 options::OPT__SLASH_P) ||
4420 Args.getLastArg(options::OPT_E) ||
4421 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4423 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4424 << InputArg->getAsString(Args) << !!FinalPhaseArg
4425 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4427 Diag(clang::diag::warn_drv_input_file_unused)
4428 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4430 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4439 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4443 Actions.push_back(ClangClPch);
4455 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4456 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4465 const llvm::opt::DerivedArgList &Args,
4468 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4470 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4473 bool HasAMDGCNHIPDevice =
false;
4475 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4477 const llvm::Triple &Tr = TC->
getTriple();
4480 HasAMDGCNHIPDevice =
true;
4482 return HasAMDGCNHIPDevice;
4487 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4489 if (!SuppressMissingInputWarning && Inputs.empty()) {
4490 Diag(clang::diag::err_drv_no_input_files);
4494 handleArguments(
C, Args, Inputs, Actions);
4496 bool UseNewOffloadingDriver = Args.hasFlag(
4497 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4501 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4502 !UseNewOffloadingDriver
4503 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4511 for (
auto &I : Inputs) {
4513 const Arg *InputArg = I.second;
4526 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4534 if (!UseNewOffloadingDriver)
4535 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4541 if (!UseNewOffloadingDriver)
4542 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4543 Current, InputArg, Phase, PL.back(), FullPL);
4549 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4552 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4553 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4555 LinkerInputs.push_back(Current);
4565 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4566 MergerInputs.push_back(Current);
4584 if (NewCurrent == Current)
4587 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4590 Current = NewCurrent;
4594 if (UseNewOffloadingDriver)
4596 &HIPAsmDeviceActions);
4599 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4603 if (Current->
getType() == types::TY_Nothing)
4609 if (Current && !HIPAsmDeviceActions.empty()) {
4610 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4612 BundleInputs.append(HIPAsmDeviceActions);
4613 BundleInputs.push_back(Current);
4619 Actions.push_back(Current);
4622 if (!UseNewOffloadingDriver)
4623 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4631 if (LinkerInputs.empty()) {
4634 if (!UseNewOffloadingDriver)
4635 OffloadBuilder->appendDeviceLinkActions(Actions);
4638 if (!LinkerInputs.empty()) {
4639 if (!UseNewOffloadingDriver)
4640 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4641 LinkerInputs.push_back(Wrapper);
4646 }
else if (UseNewOffloadingDriver ||
4647 Args.hasArg(options::OPT_offload_link)) {
4655 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4656 C.getDefaultToolChain().getTriple().isSPIRV();
4657 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4661 if (!UseNewOffloadingDriver)
4662 LA = OffloadBuilder->processHostLinkAction(LA);
4663 Actions.push_back(LA);
4667 if (!MergerInputs.empty())
4671 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4678 for (
auto &I : Inputs) {
4680 const Arg *InputArg = I.second;
4685 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4686 InputType == types::TY_Asm)
4691 for (
auto Phase : PhaseList) {
4695 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4700 if (InputType == types::TY_Object)
4707 assert(Phase == PhaseList.back() &&
4708 "merging must be final compilation step.");
4709 MergerInputs.push_back(Current);
4718 Actions.push_back(Current);
4722 if (!MergerInputs.empty())
4727 for (
auto Opt : {options::OPT_print_supported_cpus,
4728 options::OPT_print_supported_extensions,
4729 options::OPT_print_enabled_extensions}) {
4736 if (Arg *A = Args.getLastArg(Opt)) {
4737 if (Opt == options::OPT_print_supported_extensions &&
4738 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4739 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4740 !
C.getDefaultToolChain().getTriple().isARM()) {
4741 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4742 <<
"--print-supported-extensions";
4745 if (Opt == options::OPT_print_enabled_extensions &&
4746 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4747 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4748 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4749 <<
"--print-enabled-extensions";
4756 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4759 for (
auto &I : Inputs)
4764 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4765 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4766 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4772 if (TC.requiresObjcopy(Args)) {
4773 Action *LastAction = Actions.back();
4775 if (LastAction->
getType() == types::TY_Object)
4781 auto ValInfo = TC.getValidationInfo(Args);
4782 if (ValInfo.NeedsValidation) {
4783 Action *LastAction = Actions.back();
4784 if (LastAction->
getType() == types::TY_Object) {
4786 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4793 if (TC.requiresBinaryTranslation(Args)) {
4794 Action *LastAction = Actions.back();
4798 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4799 LastAction->
getType() == types::TY_Object)
4801 LastAction, types::TY_DX_CONTAINER));
4806 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4812 const llvm::opt::DerivedArgList &Args,
4814 const llvm::Triple &Triple) {
4819 if (Triple.isNVPTX() &&
4821 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4822 <<
"CUDA" << ArchStr;
4824 }
else if (Triple.isAMDGPU() &&
4826 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4827 <<
"HIP" << ArchStr;
4835 llvm::StringMap<bool> Features;
4838 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4850static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4852 llvm::Triple Triple) {
4853 if (!Triple.isAMDGPU())
4854 return std::nullopt;
4856 std::set<StringRef> ArchSet;
4857 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4861llvm::SmallVector<StringRef>
4865 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4866 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4867 options::OPT_no_offload_arch_EQ)) {
4868 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4870 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4872 :
"--no-offload-arch");
4875 llvm::DenseSet<StringRef> Archs;
4876 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4879 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4880 for (StringRef
Arch : Arg->getValues()) {
4881 if (
Arch ==
"native" ||
Arch.empty()) {
4886 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4890 for (
auto ArchStr : *GPUsOrErr) {
4892 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4893 if (!CanonicalStr.empty())
4894 Archs.insert(CanonicalStr);
4899 StringRef CanonicalStr =
4901 if (!CanonicalStr.empty())
4902 Archs.insert(CanonicalStr);
4907 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4908 for (StringRef
Arch : Arg->getValues()) {
4909 if (
Arch ==
"all") {
4914 Archs.erase(ArchStr);
4920 if (
auto ConflictingArchs =
4922 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4923 << ConflictingArchs->first << ConflictingArchs->second;
4926 if (Archs.empty()) {
4936 Archs.insert(StringRef());
4939 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4940 .getLastArg(options::OPT_march_EQ)) {
4941 Archs.insert(Arg->getValue());
4946 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4947 <<
"--offload-arch";
4948 }
else if (!ArchsOrErr->empty()) {
4949 for (
auto Arch : *ArchsOrErr)
4950 Archs.insert(Args.MakeArgStringRef(
Arch));
4952 Archs.insert(StringRef());
4957 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4958 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4967 const InputTy &Input, StringRef CUID,
4977 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4979 bool HIPRelocatableObj =
4981 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4982 options::OPT_fno_hip_emit_relocatable,
false);
4984 if (!HIPNoRDC && HIPRelocatableObj)
4985 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4986 <<
"-fhip-emit-relocatable"
4990 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4991 <<
"-fhip-emit-relocatable"
4992 <<
"--offload-device-only";
5010 auto TCRange =
C.getOffloadToolChains(Kind);
5011 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5012 ToolChains.push_back(TI->second);
5014 if (ToolChains.empty())
5018 const Arg *InputArg = Input.second;
5027 for (
const ToolChain *TC : ToolChains) {
5029 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5030 DeviceActions.push_back(
5031 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5035 if (DeviceActions.empty())
5041 HostAction->
getType() != types::TY_Nothing &&
5051 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5060 auto *TCAndArch = TCAndArchs.begin();
5061 for (
Action *&A : DeviceActions) {
5062 if (A->
getType() == types::TY_Nothing)
5072 HostAction->
getType() != types::TY_Nothing) {
5079 TCAndArch->second.data(), Kind);
5081 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5091 for (
Action *&A : DeviceActions) {
5096 OffloadTriple && OffloadTriple->isSPIRV() &&
5097 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5098 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5099 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5100 options::OPT_no_use_spirv_backend,
5107 bool IsAMDGCNSPIRVWithBackend =
5108 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5111 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5112 A->
getType() != types::TY_LTO_BC) ||
5120 auto *TCAndArch = TCAndArchs.begin();
5121 for (
Action *A : DeviceActions) {
5122 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5124 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5129 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5131 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5140 bool ShouldBundleHIP =
5141 Args.hasFlag(options::OPT_gpu_bundle_output,
5142 options::OPT_no_gpu_bundle_output,
false) ||
5143 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5145 return A->
getType() != types::TY_Image;
5152 if (OffloadActions.empty())
5157 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5161 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5168 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5169 DDep.
add(*FatbinAction,
5172 }
else if (HIPNoRDC) {
5175 if (HIPAsmBundleDeviceOut &&
5177 for (
Action *OA : OffloadActions)
5178 HIPAsmBundleDeviceOut->push_back(OA);
5192 DDep.
add(*PackagerAction,
5201 nullptr,
C.getActiveOffloadKinds());
5210 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5211 return A->
getType() == types::TY_Nothing;
5215 nullptr, SingleDeviceOutput ? DDep : DDeps);
5216 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5222 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5232 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5238 llvm_unreachable(
"link action invalid here.");
5240 llvm_unreachable(
"ifsmerge action invalid here.");
5245 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5246 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5247 OutputTy = types::TY_Dependencies;
5252 if (!Args.hasFlag(options::OPT_frewrite_includes,
5253 options::OPT_fno_rewrite_includes,
false) &&
5254 !Args.hasFlag(options::OPT_frewrite_imports,
5255 options::OPT_fno_rewrite_imports,
false) &&
5256 !Args.hasFlag(options::OPT_fdirectives_only,
5257 options::OPT_fno_directives_only,
false) &&
5261 "Cannot preprocess this input type!");
5267 if (Args.hasArg(options::OPT_extract_api))
5276 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5277 (Input->
getType() == driver::types::TY_CXXModule ||
5278 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5279 !Args.getLastArg(options::OPT__precompile) &&
5280 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5285 "Cannot precompile this input type!");
5289 const char *ModName =
nullptr;
5290 if (OutputTy == types::TY_PCH) {
5291 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5292 ModName = A->getValue();
5294 OutputTy = types::TY_ModuleFile;
5297 if (Args.hasArg(options::OPT_fsyntax_only)) {
5299 OutputTy = types::TY_Nothing;
5305 if (Args.hasArg(options::OPT_fsyntax_only))
5307 if (Args.hasArg(options::OPT_rewrite_objc))
5309 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5311 types::TY_RewrittenLegacyObjC);
5312 if (Args.hasArg(options::OPT__analyze))
5314 if (Args.hasArg(options::OPT_emit_ast))
5316 if (Args.hasArg(options::OPT_emit_cir))
5318 if (Args.hasArg(options::OPT_module_file_info))
5320 if (Args.hasArg(options::OPT_verify_pch))
5322 if (Args.hasArg(options::OPT_extract_api))
5331 Args.hasFlag(options::OPT_offload_new_driver,
5332 options::OPT_no_offload_new_driver,
5335 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm)))
5340 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5341 !Args.hasArg(options::OPT_emit_llvm))
5342 Output = types::TY_PP_Asm;
5343 else if (Args.hasArg(options::OPT_S))
5344 Output = types::TY_LTO_IR;
5346 Output = types::TY_LTO_BC;
5351 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5354 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5355 options::OPT_no_use_spirv_backend,
5363 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5365 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5367 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5369 auto &DefaultToolChain =
C.getDefaultToolChain();
5370 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5375 bool EmitBitcodeForNonOffloadAMDSPIRV =
5376 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5377 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5378 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5380 if (Args.hasArg(options::OPT_emit_llvm) ||
5381 EmitBitcodeForNonOffloadAMDSPIRV ||
5387 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5388 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5390 (Args.hasFlag(options::OPT_offload_new_driver,
5391 options::OPT_no_offload_new_driver,
5393 !(Args.hasArg(options::OPT_S) &&
5394 !Args.hasArg(options::OPT_emit_llvm)) &&
5401 Args.hasArg(options::OPT_S) &&
5405 !Args.hasFlag(options::OPT_offload_new_driver,
5406 options::OPT_no_offload_new_driver,
5407 C.getActiveOffloadKinds() !=
5410 : types::TY_LLVM_BC;
5423 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5432 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5436 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5438 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5458 unsigned NumOutputs = 0;
5459 unsigned NumIfsOutputs = 0;
5460 for (
const Action *A :
C.getActions()) {
5466 if (A->
getType() != types::TY_Nothing &&
5468 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5470 0 == NumIfsOutputs++) ||
5475 A->
getType() == types::TY_Nothing &&
5476 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5477 NumOutputs += A->
size();
5480 if (NumOutputs > 1) {
5481 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5482 FinalOutput =
nullptr;
5486 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5490 if (RawTriple.isOSBinFormatMachO())
5491 for (
const Arg *A :
C.getArgs())
5492 if (A->getOption().matches(options::OPT_arch))
5496 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5497 for (
Action *A :
C.getActions()) {
5504 const char *LinkingOutput =
nullptr;
5507 LinkingOutput = FinalOutput->getValue();
5516 LinkingOutput, CachedResults,
5523 for (
auto &J :
C.getJobs())
5524 J.InProcess =
false;
5527 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5528 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5533 const char *LinkingOutput =
nullptr;
5535 LinkingOutput = FinalOutput->getValue();
5542 using namespace llvm;
5545 <<
"output=" << LinkingOutput;
5546 outs() <<
", total="
5547 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5549 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5550 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5554 llvm::raw_string_ostream Out(Buffer);
5555 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5558 llvm::sys::printArg(Out, LinkingOutput,
true);
5559 Out <<
',' << ProcStat->TotalTime.count() <<
','
5560 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5565 llvm::sys::fs::OF_Append |
5566 llvm::sys::fs::OF_Text);
5571 llvm::errs() <<
"ERROR: Cannot lock file "
5573 <<
toString(L.takeError()) <<
"\n";
5584 bool ReportUnusedArguments =
5585 !Diags.hasErrorOccurred() &&
5586 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5589 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5591 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5594 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5595 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5597 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5601 return strstr(J.getCreator().getShortName(),
"assembler");
5603 for (Arg *A :
C.getArgs()) {
5607 if (!A->isClaimed()) {
5613 const Option &Opt = A->getOption();
5614 if (Opt.getKind() == Option::FlagClass) {
5615 bool DuplicateClaimed =
false;
5617 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5618 if (AA->isClaimed()) {
5619 DuplicateClaimed =
true;
5624 if (DuplicateClaimed)
5630 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5632 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5637 !
C.getActions().empty()) {
5638 Diag(diag::err_drv_unsupported_opt_for_target)
5640 }
else if (ReportUnusedArguments) {
5641 Diag(clang::diag::warn_drv_unused_argument)
5642 << A->getAsString(
C.getArgs());
5652class ToolSelector final {
5663 bool IsHostSelector;
5674 bool CanBeCollapsed =
true) {
5676 if (Inputs.size() != 1)
5679 Action *CurAction = *Inputs.begin();
5680 if (CanBeCollapsed &&
5686 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5690 if (!IsHostSelector) {
5691 if (OA->hasSingleDeviceDependence(
true)) {
5693 OA->getSingleDeviceDependence(
true);
5694 if (CanBeCollapsed &&
5697 SavedOffloadAction.push_back(OA);
5698 return dyn_cast<JobAction>(CurAction);
5700 }
else if (OA->hasHostDependence()) {
5701 CurAction = OA->getHostDependence();
5702 if (CanBeCollapsed &&
5705 SavedOffloadAction.push_back(OA);
5706 return dyn_cast<JobAction>(CurAction);
5711 return dyn_cast<JobAction>(CurAction);
5715 bool canCollapseAssembleAction()
const {
5716 return TC.useIntegratedAs() && !SaveTemps &&
5717 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5718 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5719 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5720 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5724 bool canCollapsePreprocessorAction()
const {
5725 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5726 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5727 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5732 struct JobActionInfo final {
5734 const JobAction *JA =
nullptr;
5742 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5743 ArrayRef<JobActionInfo> &ActionInfo,
5744 unsigned ElementNum) {
5745 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5746 for (
unsigned I = 0; I < ElementNum; ++I)
5747 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5748 ActionInfo[I].SavedOffloadAction.end());
5761 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5764 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5766 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5767 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5768 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5769 if (!AJ || !BJ || !CJ)
5773 const Tool *T = TC.SelectTool(*CJ);
5786 const Tool *BT = TC.SelectTool(*BJ);
5794 Inputs = CJ->getInputs();
5795 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5799 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5802 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5804 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5805 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5810 const Tool *T = TC.SelectTool(*BJ);
5817 Inputs = BJ->getInputs();
5818 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5822 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5825 if (ActionInfo.size() < 2)
5827 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5828 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5832 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5833 for (
auto &Input : AI.JA->getInputs())
5844 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5845 if (SaveTemps && !InputIsBitcode)
5849 const Tool *T = TC.SelectTool(*CJ);
5862 Inputs = CJ->getInputs();
5863 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5872 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5880 for (Action *A : Inputs) {
5881 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5883 NewInputs.push_back(A);
5889 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5890 PreprocessJobOffloadActions.end());
5891 NewInputs.append(PJ->input_begin(), PJ->input_end());
5897 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5899 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5901 assert(BaseAction &&
"Invalid base action.");
5917 SmallVector<JobActionInfo, 5> ActionChain(1);
5918 ActionChain.back().JA = BaseAction;
5919 while (ActionChain.back().JA) {
5920 const Action *CurAction = ActionChain.back().JA;
5923 ActionChain.resize(ActionChain.size() + 1);
5924 JobActionInfo &AI = ActionChain.back();
5928 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5932 ActionChain.pop_back();
5940 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5941 CollapsedOffloadAction);
5943 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5945 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5951 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5963 StringRef BoundArch,
5965 std::string TriplePlusArch = TC->
getTriple().normalize();
5966 if (!BoundArch.empty()) {
5967 TriplePlusArch +=
"-";
5968 TriplePlusArch += BoundArch;
5970 TriplePlusArch +=
"-";
5972 return TriplePlusArch;
5977 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5978 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5981 std::pair<const Action *, std::string> ActionTC = {
5983 auto CachedResult = CachedResults.find(ActionTC);
5984 if (CachedResult != CachedResults.end()) {
5985 return CachedResult->second;
5988 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5989 CachedResults, TargetDeviceOffloadKind);
5990 CachedResults[ActionTC] =
Result;
5995 const JobAction *JA,
const char *BaseInput,
5998 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6009 OffloadingPrefix +=
"-";
6010 OffloadingPrefix +=
Arch;
6013 C.getDriver().isSaveTempsEnabled()) {
6020 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6021 Path = A->getValue();
6022 if (llvm::sys::fs::is_directory(Path)) {
6024 ? llvm::sys::path::stem(
Result.getFilename())
6025 : llvm::sys::path::stem(BaseInput));
6026 Tmp += OffloadingPrefix;
6028 llvm::sys::path::append(Path, Tmp);
6031 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6034 Path = DumpDir->getValue();
6035 Path += llvm::sys::path::stem(BaseInput);
6036 Path += OffloadingPrefix;
6038 }
else if (!OffloadingPrefix.empty()) {
6042 TraceName += OffloadingPrefix;
6043 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6044 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6045 llvm::sys::path::append(Path, TraceName);
6048 Path =
Result.getFilename();
6049 llvm::sys::path::replace_extension(Path,
"json");
6052 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6053 C.addTimeTraceFile(ResultFile, JA);
6054 C.addResultFile(ResultFile, JA);
6059 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6060 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6063 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6066 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6067 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6099 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6101 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6102 const char *DepBoundArch) {
6105 LinkingOutput, CachedResults,
6115 OA->doOnEachDependence(
6116 BuildingForOffloadDevice,
6117 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6119 C, DepA, DepTC, DepBoundArch,
false,
6120 !!DepBoundArch, LinkingOutput, CachedResults,
6124 A = BuildingForOffloadDevice
6125 ? OA->getSingleDeviceDependence(
true)
6126 : OA->getHostDependence();
6130 std::pair<const Action *, std::string> ActionTC = {
6131 OA->getHostDependence(),
6133 auto It = CachedResults.find(ActionTC);
6134 if (It != CachedResults.end()) {
6136 Inputs.append(OffloadDependencesInputInfo);
6141 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6144 const Arg &Input = IA->getInputArg();
6146 if (Input.getOption().matches(options::OPT_INPUT)) {
6147 const char *
Name = Input.getValue();
6150 return {InputInfo(A, &Input,
"")};
6153 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6154 const ToolChain *TC;
6157 if (!ArchName.empty())
6158 TC = &getToolChain(
C.getArgs(),
6160 C.getArgs(), ArchName));
6162 TC = &
C.getDefaultToolChain();
6165 MultipleArchs, LinkingOutput, CachedResults,
6166 TargetDeviceOffloadKind);
6177 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6180 return {InputInfo()};
6184 for (
const auto *OA : CollapsedOffloadActions)
6186 BuildingForOffloadDevice,
6187 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6189 C, DepA, DepTC, DepBoundArch,
false,
6190 !!DepBoundArch, LinkingOutput, CachedResults,
6196 for (
const Action *Input : Inputs) {
6200 bool SubJobAtTopLevel =
6203 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6208 const char *BaseInput = InputInfos[0].getBaseInput();
6209 for (
auto &Info : InputInfos) {
6210 if (Info.isFilename()) {
6211 BaseInput = Info.getBaseInput();
6218 if (JA->
getType() == types::TY_dSYM)
6219 BaseInput = InputInfos[0].getFilename();
6222 if (!OffloadDependencesInputInfo.empty())
6223 InputInfos.append(OffloadDependencesInputInfo.begin(),
6224 OffloadDependencesInputInfo.end());
6227 llvm::Triple EffectiveTriple;
6229 const ArgList &Args =
6231 if (InputInfos.size() != 1) {
6237 Args, BoundArch, InputInfos[0].getType()));
6239 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6244 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6248 for (
auto &UI : UA->getDependentActionsInfo()) {
6250 "Unbundling with no offloading??");
6257 UI.DependentOffloadKind,
6258 UI.DependentToolChain->getTriple().normalize(),
6260 auto CurI = InputInfo(
6269 UnbundlingResults.push_back(CurI);
6278 Arch = UI.DependentBoundArch;
6283 UI.DependentOffloadKind)}] = {
6289 std::pair<const Action *, std::string> ActionTC = {
6291 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6292 "Result does not exist??");
6293 Result = CachedResults[ActionTC].front();
6294 }
else if (JA->
getType() == types::TY_Nothing)
6295 Result = {InputInfo(A, BaseInput)};
6305 AtTopLevel, MultipleArchs,
6314 <<
'"' <<
" - \"" << T->
getName() <<
"\", inputs: [";
6315 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6316 llvm::errs() << InputInfos[i].getAsString();
6318 llvm::errs() <<
", ";
6320 if (UnbundlingResults.empty())
6321 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6323 llvm::errs() <<
"], outputs: [";
6324 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6325 llvm::errs() << UnbundlingResults[i].getAsString();
6327 llvm::errs() <<
", ";
6329 llvm::errs() <<
"] \n";
6332 if (UnbundlingResults.empty())
6336 Args, LinkingOutput);
6342 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6343 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6355 if (ArgValue.empty()) {
6357 Filename = BaseName;
6358 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6360 llvm::sys::path::append(Filename, BaseName);
6363 if (!llvm::sys::path::has_extension(ArgValue)) {
6368 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6373 llvm::sys::path::replace_extension(Filename, Extension);
6376 return Args.MakeArgString(Filename.c_str());
6391 StringRef Suffix,
bool MultipleArchs,
6392 StringRef BoundArch,
6393 bool NeedUniqueDirectory)
const {
6395 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6396 std::optional<std::string> CrashDirectory =
6398 ? std::string(A->getValue())
6399 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6400 if (CrashDirectory) {
6401 if (!
getVFS().exists(*CrashDirectory))
6402 llvm::sys::fs::create_directories(*CrashDirectory);
6404 llvm::sys::path::append(Path, Prefix);
6405 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6406 if (std::error_code EC =
6407 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6408 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6412 if (MultipleArchs && !BoundArch.empty()) {
6413 if (NeedUniqueDirectory) {
6415 llvm::sys::path::append(TmpName,
6416 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6426 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6441 const char *BaseInput) {
6443 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6444 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6449 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6453 const char *BaseInput,
6454 StringRef OrigBoundArch,
bool AtTopLevel,
6456 StringRef OffloadingPrefix)
const {
6459 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6462 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6463 return C.addResultFile(FinalOutput->getValue(), &JA);
6467 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6469 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6471 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6472 NameArg = A->getValue();
6473 return C.addResultFile(
6483 if (JA.
getType() == types::TY_ModuleFile &&
6484 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6488 if (JA.
getType() == types::TY_PP_Asm &&
6489 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6490 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6493 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6496 if ((JA.
getType() == types::TY_Object &&
6497 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6498 JA.
getType() == types::TY_DX_CONTAINER) {
6499 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6500 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6501 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6502 "expected DXIL or SPIR-V triple for HLSL output path");
6507 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6509 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6510 StringRef
Name = llvm::sys::path::filename(BaseInput);
6511 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6517 if (JA.
getType() == types::TY_PP_Asm &&
6518 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6519 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6521 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6522 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6523 return C.addResultFile(
6528 if (JA.
getType() == types::TY_API_INFO &&
6529 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6530 C.getArgs().hasArg(options::OPT_o))
6531 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6532 <<
C.getArgs().getLastArgValue(options::OPT_o);
6539 bool SpecifiedModuleOutput =
6540 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6541 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6542 if (MultipleArchs && SpecifiedModuleOutput)
6543 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6548 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6549 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6555 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6557 StringRef
Name = llvm::sys::path::filename(BaseInput);
6558 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6559 const char *Suffix =
6564 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6565 bool NeedUniqueDirectory =
6568 Triple.isOSDarwin();
6569 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6570 NeedUniqueDirectory);
6579 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6584 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6585 llvm::sys::path::filename(BasePath));
6586 BaseName = ExternalPath;
6588 BaseName = BasePath;
6590 BaseName = llvm::sys::path::filename(BasePath);
6593 const char *NamedOutput;
6595 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6596 JA.
getType() == types::TY_LLVM_BC ||
6597 JA.
getType() == types::TY_LLVM_IR) &&
6598 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6602 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6606 }
else if (JA.
getType() == types::TY_Image &&
6607 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6608 options::OPT__SLASH_o)) {
6612 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6616 }
else if (JA.
getType() == types::TY_Image) {
6626 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6627 options::OPT_fno_gpu_rdc,
false);
6629 if (UseOutExtension) {
6631 llvm::sys::path::replace_extension(Output,
"");
6633 Output += OffloadingPrefix;
6634 if (MultipleArchs && !BoundArch.empty()) {
6636 Output.append(BoundArch);
6638 if (UseOutExtension)
6640 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6643 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6644 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6645 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6648 .getLastArg(options::OPT__SLASH_o)
6653 const char *Suffix =
6655 assert(Suffix &&
"All types used for output should have a suffix.");
6657 std::string::size_type End = std::string::npos;
6659 End = BaseName.rfind(
'.');
6661 Suffixed += OffloadingPrefix;
6662 if (MultipleArchs && !BoundArch.empty()) {
6664 Suffixed.append(BoundArch);
6669 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6670 const llvm::opt::DerivedArgList &Args) {
6677 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6679 Args.hasFlag(options::OPT_offload_new_driver,
6680 options::OPT_no_offload_new_driver,
true))) ||
6687 bool IsLinkerWrapper =
6689 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6690 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6691 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6693 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6697 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6701 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6702 JA.
getType() != types::TY_PCH) {
6703 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6705 llvm::sys::path::remove_filename(TempPath);
6706 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6707 llvm::sys::path::append(TempPath, OutputFileName);
6708 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6714 bool SameFile =
false;
6716 llvm::sys::fs::current_path(
Result);
6717 llvm::sys::path::append(
Result, BaseName);
6718 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6721 StringRef
Name = llvm::sys::path::filename(BaseInput);
6722 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6726 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6732 llvm::sys::path::remove_filename(BasePath);
6733 if (BasePath.empty())
6734 BasePath = NamedOutput;
6736 llvm::sys::path::append(BasePath, NamedOutput);
6737 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6740 return C.addResultFile(NamedOutput, &JA);
6746 -> std::optional<std::string> {
6749 for (
const auto &
Dir : P) {
6753 llvm::sys::path::append(P,
Name);
6754 if (llvm::sys::fs::exists(Twine(P)))
6755 return std::string(P);
6757 return std::nullopt;
6764 llvm::sys::path::append(R,
Name);
6765 if (llvm::sys::fs::exists(Twine(R)))
6766 return std::string(R);
6769 llvm::sys::path::append(P,
Name);
6770 if (llvm::sys::fs::exists(Twine(P)))
6771 return std::string(P);
6774 llvm::sys::path::append(D,
"..",
Name);
6775 if (llvm::sys::fs::exists(Twine(D)))
6776 return std::string(D);
6785 llvm::sys::path::append(R2,
"..",
"..",
Name);
6786 if (llvm::sys::fs::exists(Twine(R2)))
6787 return std::string(R2);
6789 return std::string(
Name);
6792void Driver::generatePrefixedToolNames(
6796 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6797 Names.emplace_back(
Tool);
6801 llvm::sys::path::append(Dir, Name);
6802 if (llvm::sys::fs::can_execute(Twine(Dir)))
6804 llvm::sys::path::remove_filename(Dir);
6810 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6815 if (llvm::sys::fs::is_directory(PrefixDir)) {
6818 return std::string(P);
6821 if (llvm::sys::fs::can_execute(Twine(P)))
6822 return std::string(P);
6827 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6835 for (
const auto &Path : List) {
6838 return std::string(P);
6842 if (llvm::ErrorOr<std::string> P =
6843 llvm::sys::findProgramByName(TargetSpecificExecutable))
6847 return std::string(
Name);
6852 std::string error =
"<NOT PRESENT>";
6854 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6859 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6876 llvm::sys::path::remove_filename(path);
6877 llvm::sys::path::append(path,
"libc++.modules.json");
6878 if (TC.
getVFS().exists(path))
6879 return static_cast<std::string
>(path);
6884 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6887 return evaluate(
"libc++.a").value_or(error);
6891 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6895 llvm::sys::path::remove_filename(path);
6896 llvm::sys::path::append(path,
"libstdc++.modules.json");
6897 if (TC.
getVFS().exists(path))
6898 return static_cast<std::string
>(path);
6903 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6906 return evaluate(
"libstdc++.a").value_or(error);
6915 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6917 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6921 return std::string(Path);
6926 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6928 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6932 return std::string(Path);
6937 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6941 Output = FpArg->getValue();
6945 if (!llvm::sys::path::has_extension(Output))
6948 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6949 Output = YcArg->getValue();
6952 llvm::sys::path::replace_extension(Output,
".pch");
6954 return std::string(Output);
6957const ToolChain &Driver::getOffloadToolChain(
6959 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6960 std::unique_ptr<ToolChain> &TC =
6961 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6962 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6964 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6967 switch (
Target.getOS()) {
6968 case llvm::Triple::CUDA:
6969 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6972 case llvm::Triple::AMDHSA:
6974 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6977 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6986 switch (
Target.getArch()) {
6987 case llvm::Triple::spir:
6988 case llvm::Triple::spir64:
6989 case llvm::Triple::spirv:
6990 case llvm::Triple::spirv32:
6991 case llvm::Triple::spirv64:
6994 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6998 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7002 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7006 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7020 return getToolChain(Args,
Target);
7024const ToolChain &Driver::getToolChain(
const ArgList &Args,
7025 const llvm::Triple &
Target)
const {
7027 auto &TC = ToolChains[
Target.str()];
7029 switch (
Target.getOS()) {
7030 case llvm::Triple::AIX:
7031 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7033 case llvm::Triple::Haiku:
7034 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7036 case llvm::Triple::Darwin:
7037 case llvm::Triple::MacOSX:
7038 case llvm::Triple::IOS:
7039 case llvm::Triple::TvOS:
7040 case llvm::Triple::WatchOS:
7041 case llvm::Triple::XROS:
7042 case llvm::Triple::DriverKit:
7043 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7045 case llvm::Triple::DragonFly:
7046 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7048 case llvm::Triple::OpenBSD:
7049 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7051 case llvm::Triple::NetBSD:
7052 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7054 case llvm::Triple::FreeBSD:
7056 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7059 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7061 case llvm::Triple::Linux:
7062 case llvm::Triple::ELFIAMCU:
7063 if (
Target.getArch() == llvm::Triple::hexagon)
7064 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7066 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7067 !
Target.hasEnvironment())
7068 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7071 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7073 else if (
Target.getArch() == llvm::Triple::ve)
7074 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7075 else if (
Target.isOHOSFamily())
7076 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7077 else if (
Target.isWALI())
7078 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7080 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7082 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7084 case llvm::Triple::Fuchsia:
7085 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7087 case llvm::Triple::Managarm:
7088 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7090 case llvm::Triple::Serenity:
7091 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7093 case llvm::Triple::Solaris:
7094 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7096 case llvm::Triple::CUDA:
7097 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7099 case llvm::Triple::AMDHSA: {
7100 if (
Target.getArch() == llvm::Triple::spirv64) {
7101 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7106 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7108 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7113 case llvm::Triple::AMDPAL:
7114 case llvm::Triple::Mesa3D:
7115 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7117 case llvm::Triple::UEFI:
7118 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7120 case llvm::Triple::Win32:
7121 switch (
Target.getEnvironment()) {
7123 if (
Target.isOSBinFormatELF())
7124 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7125 else if (
Target.isOSBinFormatMachO())
7126 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7128 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7130 case llvm::Triple::GNU:
7131 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7133 case llvm::Triple::Cygnus:
7134 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7136 case llvm::Triple::Itanium:
7137 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7140 case llvm::Triple::MSVC:
7141 case llvm::Triple::UnknownEnvironment:
7142 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7143 .starts_with_insensitive(
"bfd"))
7144 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7148 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7152 case llvm::Triple::PS4:
7153 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7155 case llvm::Triple::PS5:
7156 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7158 case llvm::Triple::Hurd:
7159 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7161 case llvm::Triple::LiteOS:
7162 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7164 case llvm::Triple::ZOS:
7165 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7167 case llvm::Triple::Vulkan:
7168 case llvm::Triple::ShaderModel:
7169 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7170 Target.getArch() == llvm::Triple::spirv64) &&
7172 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7174 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7176 case llvm::Triple::ChipStar:
7177 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7182 switch (
Target.getArch()) {
7183 case llvm::Triple::tce:
7184 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7186 case llvm::Triple::tcele:
7187 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7189 case llvm::Triple::tcele64:
7191 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7193 case llvm::Triple::hexagon:
7194 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7197 case llvm::Triple::lanai:
7198 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7200 case llvm::Triple::xcore:
7201 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7203 case llvm::Triple::wasm32:
7204 case llvm::Triple::wasm64:
7205 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7207 case llvm::Triple::avr:
7208 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7210 case llvm::Triple::msp430:
7211 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7213 case llvm::Triple::riscv32:
7214 case llvm::Triple::riscv64:
7215 case llvm::Triple::riscv32be:
7216 case llvm::Triple::riscv64be:
7217 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7219 case llvm::Triple::ve:
7220 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7222 case llvm::Triple::spirv32:
7223 case llvm::Triple::spirv64:
7224 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7226 case llvm::Triple::csky:
7227 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7229 case llvm::Triple::amdgcn:
7230 case llvm::Triple::r600:
7231 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7235 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7236 else if (
Target.isOSBinFormatELF())
7237 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7238 else if (
Target.isAppleFirmware())
7239 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7240 else if (
Target.isAppleMachO())
7241 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7242 else if (
Target.isOSBinFormatMachO())
7243 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7245 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7255 if (JA.
size() != 1 ||
7270 if (JA.
size() != 1 ||
7284 if (Args.hasArg(options::OPT_emit_static_lib))
7295 unsigned &Micro,
bool &HadExtra) {
7298 Major = Minor = Micro = 0;
7302 if (Str.consumeInteger(10, Major))
7306 if (!Str.consume_front(
"."))
7309 if (Str.consumeInteger(10, Minor))
7313 if (!Str.consume_front(
"."))
7316 if (Str.consumeInteger(10, Micro))
7334 unsigned CurDigit = 0;
7335 while (CurDigit < Digits.size()) {
7337 if (Str.consumeInteger(10, Digit))
7339 Digits[CurDigit] = Digit;
7342 if (!Str.consume_front(
"."))
7351llvm::opt::Visibility
7352Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7365const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7381 llvm_unreachable(
"Unhandled Mode");
7385 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7390 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7391 options::OPT_fno_save_optimization_record,
false))
7395 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7396 options::OPT_fno_save_optimization_record,
false))
7400 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7401 options::OPT_fno_save_optimization_record,
false))
7405 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7406 options::OPT_fno_save_optimization_record,
false))
7413 static StringRef OptName =
7415 llvm::StringRef Opt;
7416 for (StringRef Arg : Args) {
7417 if (!Arg.starts_with(OptName))
7423 return Opt.consume_front(OptName) ? Opt :
"";
7430 llvm::BumpPtrAllocator &Alloc,
7431 llvm::vfs::FileSystem *FS) {
7440 for (
const char *F : Args) {
7441 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7443 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7444 RSPQuoting = Windows;
7450 bool MarkEOLs = ClangCLMode;
7452 llvm::cl::TokenizerCallback Tokenizer;
7453 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7454 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7456 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7458 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7461 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7462 ECtx.setMarkEOLs(MarkEOLs);
7466 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7470 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7471 [](
const char *A) {
return A !=
nullptr; });
7472 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7475 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7476 Args.resize(newEnd - Args.begin());
7480 return llvm::Error::success();
7484 return SavedStrings.insert(S).first->getKeyData();
7518 llvm::StringSet<> &SavedStrings) {
7521 if (Edit[0] ==
'^') {
7522 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7523 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7524 Args.insert(Args.begin() + 1, Str);
7525 }
else if (Edit[0] ==
'+') {
7526 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7527 OS <<
"### Adding argument " << Str <<
" at end\n";
7528 Args.push_back(Str);
7529 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7530 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7531 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7532 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7533 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7535 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7537 if (Args[i] ==
nullptr)
7539 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7541 if (Repl != Args[i]) {
7542 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7546 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7547 auto Option = Edit.substr(1);
7548 for (
unsigned i = 1; i < Args.size();) {
7549 if (Option == Args[i]) {
7550 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7551 Args.erase(Args.begin() + i);
7552 if (Edit[0] ==
'X') {
7553 if (i < Args.size()) {
7554 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7555 Args.erase(Args.begin() + i);
7557 OS <<
"### Invalid X edit, end of command line!\n";
7562 }
else if (Edit[0] ==
'O') {
7563 for (
unsigned i = 1; i < Args.size();) {
7564 const char *A = Args[i];
7568 if (A[0] ==
'-' && A[1] ==
'O' &&
7569 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7570 (
'0' <= A[2] && A[2] <=
'9'))))) {
7571 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7572 Args.erase(Args.begin() + i);
7576 OS <<
"### Adding argument " << Edit <<
" at end\n";
7577 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7579 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7584 const char *OverrideStr,
7585 llvm::StringSet<> &SavedStrings,
7586 StringRef EnvVar, raw_ostream *OS) {
7588 OS = &llvm::nulls();
7590 if (OverrideStr[0] ==
'#') {
7592 OS = &llvm::nulls();
7595 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7599 const char *S = OverrideStr;
7601 const char *End = ::strchr(S,
' ');
7603 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.
bool isHLSL(ID Id)
isHLSL - Is this an HLSL input.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules