59#include "clang/Config/config.h"
71#include "llvm/ADT/ArrayRef.h"
72#include "llvm/ADT/STLExtras.h"
73#include "llvm/ADT/SmallSet.h"
74#include "llvm/ADT/SmallVector.h"
75#include "llvm/ADT/StringExtras.h"
76#include "llvm/ADT/StringRef.h"
77#include "llvm/ADT/StringSet.h"
78#include "llvm/ADT/StringSwitch.h"
79#include "llvm/Config/llvm-config.h"
80#include "llvm/MC/TargetRegistry.h"
81#include "llvm/Option/Arg.h"
82#include "llvm/Option/ArgList.h"
83#include "llvm/Option/OptSpecifier.h"
84#include "llvm/Option/OptTable.h"
85#include "llvm/Option/Option.h"
86#include "llvm/Support/CommandLine.h"
87#include "llvm/Support/ErrorHandling.h"
88#include "llvm/Support/ExitCodes.h"
89#include "llvm/Support/FileSystem.h"
90#include "llvm/Support/FileUtilities.h"
91#include "llvm/Support/FormatVariadic.h"
92#include "llvm/Support/IOSandbox.h"
93#include "llvm/Support/MD5.h"
94#include "llvm/Support/Path.h"
95#include "llvm/Support/PrettyStackTrace.h"
96#include "llvm/Support/Process.h"
97#include "llvm/Support/Program.h"
98#include "llvm/Support/Regex.h"
99#include "llvm/Support/StringSaver.h"
100#include "llvm/Support/VirtualFileSystem.h"
101#include "llvm/Support/raw_ostream.h"
102#include "llvm/TargetParser/Host.h"
103#include "llvm/TargetParser/RISCVISAInfo.h"
116using namespace clang;
119template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
120 return llvm::any_of(Args, [&](Arg *A) {
121 return (A->getOption().matches(options::OPT_x) &&
123 (A->getOption().
getKind() == Option::InputClass &&
124 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
126 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
132 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
133 StringRef UseCUIDStr = A->getValue();
134 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
135 .Case(
"hash", Kind::Hash)
136 .Case(
"random", Kind::Random)
137 .Case(
"none", Kind::None)
138 .Default(Kind::Invalid);
139 if (UseCUID == Kind::Invalid)
140 D.Diag(clang::diag::err_drv_invalid_value)
141 << A->getAsString(Args) << UseCUIDStr;
144 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
145 if (!FixedCUID.empty())
150 llvm::opt::DerivedArgList &Args)
const {
151 std::string CUID = FixedCUID.str();
154 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
158 llvm::MD5::MD5Result
Hash;
159 Hasher.update(InputFile);
160 for (
auto *A : Args) {
161 if (A->getOption().matches(options::OPT_INPUT))
163 Hasher.update(A->getAsString(Args));
166 CUID = llvm::utohexstr(
Hash.low(),
true);
174 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
175 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
182 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
183 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
184 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
187 this->VFS = llvm::vfs::getRealFileSystem();
192 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
195 llvm::sys::path::append(P,
SysRoot);
199#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
200 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
204 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
205 llvm::sys::path::remove_dots(configFileDir,
true);
209#if defined(CLANG_CONFIG_FILE_USER_DIR)
212 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
221void Driver::setDriverMode(StringRef
Value) {
222 static StringRef OptName =
223 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
224 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
225 .Case(
"gcc", GCCMode)
226 .Case(
"g++", GXXMode)
227 .Case(
"cpp", CPPMode)
229 .Case(
"flang", FlangMode)
230 .Case(
"dxc", DXCMode)
234 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
239 bool &ContainsError)
const {
240 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
241 ContainsError =
false;
243 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
244 unsigned MissingArgIndex, MissingArgCount;
245 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
246 MissingArgCount, VisibilityMask);
249 if (MissingArgCount) {
250 Diag(diag::err_drv_missing_argument)
251 << Args.getArgString(MissingArgIndex) << MissingArgCount;
253 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
258 for (
const Arg *A : Args) {
260 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
261 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
268 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
269 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
270 ContainsError |= Diags.getDiagnosticLevel(
271 diag::warn_drv_empty_joined_argument,
276 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
278 auto ArgString = A->getAsString(Args);
280 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
282 if (
getOpts().findExact(ArgString, Nearest,
284 DiagID = diag::err_drv_unknown_argument_with_suggestion;
285 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
287 DiagID = diag::err_drv_unknown_argument;
288 Diags.Report(DiagID) << ArgString;
291 llvm::opt::Visibility(
293 DiagID = diag::err_drv_unknown_argument_with_suggestion;
294 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
296 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
297 : diag::err_drv_unknown_argument;
298 Diags.Report(DiagID) << ArgString;
302 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
303 : diag::err_drv_unknown_argument_with_suggestion;
304 Diags.Report(DiagID) << ArgString << Nearest;
306 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
310 for (
const Arg *A : Args.filtered(options::OPT_o)) {
311 if (ArgStrings[A->getIndex()] == A->getSpelling())
315 std::string ArgString = ArgStrings[A->getIndex()];
317 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
318 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
319 << A->getAsString(Args) << Nearest;
329 Arg **FinalPhaseArg)
const {
330 Arg *PhaseArg =
nullptr;
334 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
335 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
336 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
337 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
344 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
345 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
346 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
347 options::OPT_fmodule_header_EQ))) {
350 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
351 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
353 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
364 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
368 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
379 *FinalPhaseArg = PhaseArg;
387 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
388 llvm::sys::fs::OF_Text);
389 llvm::FileRemover OutputRemover(OutputFile.c_str());
390 std::optional<llvm::StringRef> Redirects[] = {
396 std::string ErrorMessage;
397 int SecondsToWait = 60;
398 if (std::optional<std::string> Str =
399 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
400 if (!llvm::to_integer(*Str, SecondsToWait))
401 return llvm::createStringError(std::error_code(),
402 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
403 "an integer, got '" +
405 SecondsToWait = std::max(SecondsToWait, 0);
407 StringRef Executable = Args[0];
408 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
410 return llvm::createStringError(std::error_code(),
411 Executable +
": " + ErrorMessage);
413 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
414 llvm::MemoryBuffer::getFile(OutputFile.c_str());
416 return llvm::createStringError(OutputBuf.getError(),
417 "Failed to read stdout of " + Executable +
418 ": " + OutputBuf.getError().message());
419 return std::move(*OutputBuf);
423 StringRef
Value,
bool Claim =
true) {
424 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
425 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
426 Args.AddSynthesizedArg(A);
432DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
433 const llvm::opt::OptTable &Opts =
getOpts();
434 DerivedArgList *DAL =
new DerivedArgList(Args);
436 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
437 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
438 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
439 bool IgnoreUnused =
false;
440 for (Arg *A : Args) {
444 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
448 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
449 IgnoreUnused =
false;
459 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
460 A->getOption().matches(options::OPT_Xlinker)) &&
461 A->containsValue(
"--no-demangle")) {
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
466 for (StringRef Val : A->getValues())
467 if (Val !=
"--no-demangle")
468 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
476 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
477 A->getNumValues() > 0 &&
478 (A->getValue(0) == StringRef(
"-MD") ||
479 A->getValue(0) == StringRef(
"-MMD"))) {
481 if (A->getValue(0) == StringRef(
"-MD"))
482 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
485 if (A->getNumValues() == 2)
486 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
491 if (A->getOption().matches(options::OPT_l)) {
492 StringRef
Value = A->getValue();
495 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
497 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
502 if (
Value ==
"cc_kext") {
503 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
509 if (A->getOption().matches(options::OPT__DASH_DASH)) {
511 for (StringRef Val : A->getValues())
520 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
521 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
524 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
525 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
529#if defined(HOST_LINK_VERSION)
530 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
531 strlen(HOST_LINK_VERSION) > 0) {
532 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
534 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
542 StringRef ArgTarget) {
544 static bool BeSilent =
false;
545 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
546 return ((v < 2) || ((v == 2) && (r < 4)));
550 if (ArgTarget.equals_insensitive(
"CURRENT")) {
554 unsigned int Version = 0;
555 unsigned int Release = 0;
556 unsigned int Modification = 0;
558 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
559 llvm::Regex HexRegex(
562 "([0-9a-fA-F][0-9a-fA-F])"
563 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
566 if (ZOsvRegex.match(ArgTarget, &Matches)) {
567 Matches[1].getAsInteger(10, Version);
568 Matches[2].getAsInteger(10, Release);
570 if (IsTooOldToBeSupported(Version, Release)) {
572 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
575 }
else if (HexRegex.match(ArgTarget, &Matches)) {
576 Matches[1].getAsInteger(16, Version);
577 Matches[2].getAsInteger(16, Release);
578 Matches[3].getAsInteger(16, Modification);
579 if (IsTooOldToBeSupported(Version, Release)) {
581 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
587 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
592 llvm::VersionTuple
V(Version, Release, Modification);
593 llvm::VersionTuple TV =
Target.getOSVersion();
596 if (TV.empty() ||
V < TV) {
598 Str = llvm::Triple::getOSTypeName(
Target.getOS());
599 Str +=
V.getAsString();
612 StringRef TargetTriple,
614 StringRef DarwinArchName =
"") {
616 if (
const Arg *A = Args.getLastArg(options::OPT_target))
617 TargetTriple = A->getValue();
619 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
624 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
628 if (
Target.isOSBinFormatMachO()) {
630 if (!DarwinArchName.empty()) {
637 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
638 StringRef ArchName = A->getValue();
645 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
646 options::OPT_mbig_endian)) {
647 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
648 ?
Target.getLittleEndianArchVariant()
649 :
Target.getBigEndianArchVariant();
650 if (
T.getArch() != llvm::Triple::UnknownArch) {
652 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
657 if (
Target.getArch() == llvm::Triple::tce)
662 if (std::optional<std::string> ObjectModeValue =
663 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
664 StringRef ObjectMode = *ObjectModeValue;
665 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
667 if (ObjectMode ==
"64") {
668 AT =
Target.get64BitArchVariant().getArch();
669 }
else if (ObjectMode ==
"32") {
670 AT =
Target.get32BitArchVariant().getArch();
672 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
675 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
681 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
682 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
685 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
687 D.
Diag(diag::err_drv_unsupported_opt_for_target)
688 << A->getAsString(Args) <<
Target.str();
691 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
692 options::OPT_m32, options::OPT_m16,
693 options::OPT_maix32, options::OPT_maix64);
695 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
697 if (A->getOption().matches(options::OPT_m64) ||
698 A->getOption().matches(options::OPT_maix64)) {
699 AT =
Target.get64BitArchVariant().getArch();
700 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
701 Target.getEnvironment() == llvm::Triple::GNUT64)
702 Target.setEnvironment(llvm::Triple::GNU);
703 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
704 Target.setEnvironment(llvm::Triple::Musl);
705 }
else if (A->getOption().matches(options::OPT_mx32) &&
706 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
707 AT = llvm::Triple::x86_64;
708 if (
Target.getEnvironment() == llvm::Triple::Musl)
709 Target.setEnvironment(llvm::Triple::MuslX32);
711 Target.setEnvironment(llvm::Triple::GNUX32);
712 }
else if (A->getOption().matches(options::OPT_m32) ||
713 A->getOption().matches(options::OPT_maix32)) {
715 D.
Diag(diag::err_drv_unsupported_opt_for_target)
716 << A->getAsString(Args) <<
Target.str();
718 AT =
Target.get32BitArchVariant().getArch();
719 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
720 Target.setEnvironment(llvm::Triple::GNU);
721 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
722 Target.setEnvironment(llvm::Triple::Musl);
724 }
else if (A->getOption().matches(options::OPT_m16) &&
725 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
726 AT = llvm::Triple::x86;
727 Target.setEnvironment(llvm::Triple::CODE16);
730 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
732 if (
Target.isWindowsGNUEnvironment())
738 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
744 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
745 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
746 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
749 if (A && !A->getOption().matches(options::OPT_m32))
750 D.
Diag(diag::err_drv_argument_not_allowed_with)
751 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
753 Target.setArch(llvm::Triple::x86);
754 Target.setArchName(
"i586");
755 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
756 Target.setEnvironmentName(
"");
757 Target.setOS(llvm::Triple::ELFIAMCU);
758 Target.setVendor(llvm::Triple::UnknownVendor);
759 Target.setVendorName(
"intel");
765 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
766 StringRef ABIName = A->getValue();
767 if (ABIName ==
"32") {
769 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
770 Target.getEnvironment() == llvm::Triple::GNUABIN32)
771 Target.setEnvironment(llvm::Triple::GNU);
772 }
else if (ABIName ==
"n32") {
774 if (
Target.getEnvironment() == llvm::Triple::GNU ||
775 Target.getEnvironment() == llvm::Triple::GNUT64 ||
776 Target.getEnvironment() == llvm::Triple::GNUABI64)
777 Target.setEnvironment(llvm::Triple::GNUABIN32);
778 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
779 Target.getEnvironment() == llvm::Triple::MuslABI64)
780 Target.setEnvironment(llvm::Triple::MuslABIN32);
781 }
else if (ABIName ==
"64") {
783 if (
Target.getEnvironment() == llvm::Triple::GNU ||
784 Target.getEnvironment() == llvm::Triple::GNUT64 ||
785 Target.getEnvironment() == llvm::Triple::GNUABIN32)
786 Target.setEnvironment(llvm::Triple::GNUABI64);
787 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
788 Target.getEnvironment() == llvm::Triple::MuslABIN32)
789 Target.setEnvironment(llvm::Triple::MuslABI64);
797 if (Args.hasArg(options::OPT_march_EQ) ||
798 Args.hasArg(options::OPT_mcpu_EQ)) {
800 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
802 if (!llvm::errorToBool(ISAInfo.takeError())) {
803 unsigned XLen = (*ISAInfo)->getXLen();
805 Target.setArch(llvm::Triple::riscv32);
807 Target.setArch(llvm::Triple::riscv64);
819 OptSpecifier OptEq, OptSpecifier OptNeg) {
820 if (!Args.hasFlag(OptEq, OptNeg,
false))
823 const Arg *A = Args.getLastArg(OptEq);
824 StringRef LTOName = A->getValue();
832 D.
Diag(diag::err_drv_unsupported_option_argument)
833 << A->getSpelling() << A->getValue();
840void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
842 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
844 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
845 options::OPT_fno_offload_lto);
848 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
849 options::OPT_fno_openmp_target_jit,
false)) {
850 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
851 options::OPT_fno_offload_lto))
853 Diag(diag::err_drv_incompatible_options)
854 << A->getSpelling() <<
"-fopenmp-target-jit";
861 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
863 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
865 RuntimeName = A->getValue();
867 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
875 Diag(diag::err_drv_unsupported_option_argument)
876 << A->getSpelling() << A->getValue();
879 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
888 StringRef Program =
C.getArgs().getLastArgValue(
889 options::OPT_offload_arch_tool_EQ,
"offload-arch");
892 if (llvm::ErrorOr<std::string> Executable =
893 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
896 Args.push_back(
"--only=amdgpu");
898 Args.push_back(
"--only=nvptx");
899 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
902 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
907 if ((*StdoutOrErr)->getBuffer().empty()) {
908 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
914 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
916 GPUArchs.push_back(
Arch.str());
918 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
925static llvm::DenseSet<llvm::StringRef>
927 std::set<std::string> Archs;
928 for (Arg *A :
C.getInputArgs()) {
929 for (StringRef
Arch : A->getValues()) {
930 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
931 if (
Arch ==
"native") {
933 Archs.insert(Str.str());
935 Archs.insert(
Arch.str());
937 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
941 Archs.erase(
Arch.str());
946 llvm::DenseSet<llvm::StringRef> Triples;
947 for (llvm::StringRef
Arch : Archs) {
954 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
956 return llvm::DenseSet<llvm::StringRef>();
959 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
961 return llvm::DenseSet<llvm::StringRef>();
965 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
967 return llvm::DenseSet<llvm::StringRef>();
970 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
971 <<
"offload" <<
Arch;
972 return llvm::DenseSet<llvm::StringRef>();
977 Triple =
"spirv64-amd-amdhsa";
979 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
980 ?
"nvptx64-nvidia-cuda"
981 :
"nvptx-nvidia-cuda";
983 Triple =
"amdgcn-amd-amdhsa";
990 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
991 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
992 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
993 C.getArgs().MakeArgString(Triple.split(
"-").first),
994 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
996 C.getArgs().append(A);
997 C.getArgs().AddSynthesizedArg(A);
998 Triples.insert(Triple);
1003 Triples.insert(
"amdgcn-amd-amdhsa");
1005 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1006 ?
"nvptx64-nvidia-cuda"
1007 :
"nvptx-nvidia-cuda");
1009 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1010 ?
"spirv64-unknown-unknown"
1011 :
"spirv32-unknown-unknown");
1014 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1015 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1022 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1023 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1025 llvm::any_of(Inputs,
1026 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1031 (llvm::any_of(Inputs,
1032 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1035 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1036 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1038 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1039 options::OPT_fno_sycl,
false);
1040 bool IsOpenMPOffloading =
1042 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1043 options::OPT_fno_openmp,
false) &&
1044 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1045 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1046 !(IsCuda || IsHIP))));
1048 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1049 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1054 for (
const auto &[Active, Kind] : ActiveKinds)
1059 if (Kinds.size() > 1) {
1060 Diag(clang::diag::err_drv_mix_offload)
1067 if (IsCuda || IsHIP)
1073 std::multiset<llvm::StringRef> Triples;
1074 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1075 std::vector<std::string> ArgValues =
1076 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1077 for (llvm::StringRef
Target : ArgValues)
1078 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1080 if (ArgValues.empty())
1081 Diag(clang::diag::warn_drv_empty_joined_argument)
1083 .getLastArg(options::OPT_offload_targets_EQ)
1084 ->getAsString(
C.getInputArgs());
1085 }
else if (Kinds.size() > 0) {
1088 Triples.insert(Derived.begin(), Derived.end());
1093 llvm::StringMap<StringRef> FoundNormalizedTriples;
1094 for (StringRef
Target : Triples) {
1099 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1107 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1108 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1109 Diag(clang::diag::err_drv_argument_not_allowed_with)
1110 << IncompatArg->getSpelling() <<
"-fsycl";
1118 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1119 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1123 std::string NormalizedName = TT.normalize();
1124 auto [TripleIt, Inserted] =
1125 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1127 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1128 <<
Target << TripleIt->second;
1132 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1133 C.getDefaultToolChain().getTriple());
1137 auto &CudaInstallation =
1139 if (CudaInstallation.isValid())
1140 CudaInstallation.WarnIfUnsupportedVersion();
1143 C.addOffloadDeviceToolChain(&TC, Kind);
1148bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1153 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1157 if (!PathLIBEnv.empty()) {
1158 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1159 if (llvm::sys::fs::is_directory(PathLIBEnv))
1160 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1161 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1162 return readConfigFile(CustomizationFile, ExpCtx);
1163 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1168 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1169 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1170 return readConfigFile(CustomizationFile, ExpCtx);
1180 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1181 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1182 Copy->getValues() = Opt->getValues();
1183 if (Opt->isClaimed())
1185 Copy->setOwnsValues(Opt->getOwnsValues());
1186 Opt->setOwnsValues(
false);
1188 if (Opt->getAlias()) {
1189 const Arg *Alias = Opt->getAlias();
1190 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1191 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1192 Args.getArgString(Index), Index);
1193 AliasCopy->getValues() = Alias->getValues();
1194 AliasCopy->setOwnsValues(
false);
1195 if (Alias->isClaimed())
1197 Copy->setAlias(std::move(AliasCopy));
1201bool Driver::readConfigFile(StringRef
FileName,
1202 llvm::cl::ExpansionContext &ExpCtx) {
1206 Diag(diag::err_drv_cannot_open_config_file)
1207 <<
FileName << Status.getError().message();
1210 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1211 Diag(diag::err_drv_cannot_open_config_file)
1212 <<
FileName <<
"not a regular file";
1217 SmallVector<const char *, 32> NewCfgFileArgs;
1218 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1219 Diag(diag::err_drv_cannot_read_config_file)
1225 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1226 for (
const char *Opt : NewCfgFileArgs) {
1228 if (Opt[0] ==
'$' && Opt[1])
1229 NewCfgTailArgs.push_back(Opt + 1);
1231 NewCfgHeadArgs.push_back(Opt);
1235 llvm::SmallString<128> CfgFileName(
FileName);
1236 llvm::sys::path::native(CfgFileName);
1237 bool ContainErrors =
false;
1238 auto NewHeadOptions = std::make_unique<InputArgList>(
1242 auto NewTailOptions = std::make_unique<InputArgList>(
1249 for (Arg *A : *NewHeadOptions)
1251 for (Arg *A : *NewTailOptions)
1254 if (!CfgOptionsHead)
1255 CfgOptionsHead = std::move(NewHeadOptions);
1258 for (
auto *Opt : *NewHeadOptions)
1262 if (!CfgOptionsTail)
1263 CfgOptionsTail = std::move(NewTailOptions);
1266 for (
auto *Opt : *NewTailOptions)
1270 ConfigFiles.push_back(std::string(CfgFileName));
1274bool Driver::loadConfigFiles() {
1275 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1276 llvm::cl::tokenizeConfigFile, &
getVFS());
1280 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1281 SmallString<128> CfgDir;
1283 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1284 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1289 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1290 SmallString<128> CfgDir;
1291 llvm::sys::fs::expand_tilde(
1292 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1293 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1302 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1305 if (loadDefaultConfigFiles(ExpCtx))
1309 SmallString<128> CfgFilePath;
1311 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1314 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1315 CfgFilePath.assign(CfgFileName);
1316 if (llvm::sys::path::is_relative(CfgFilePath)) {
1317 if (
getVFS().makeAbsolute(CfgFilePath)) {
1318 Diag(diag::err_drv_cannot_open_config_file)
1319 << CfgFilePath <<
"cannot get absolute path";
1323 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1325 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1326 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1327 if (!SearchDir.empty())
1328 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1333 if (readConfigFile(CfgFilePath, ExpCtx))
1344 llvm::Triple Triple, std::string Suffix) {
1346 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1350 VersionTuple OSVersion = Triple.getOSVersion();
1351 if (!OSVersion.getMinor().has_value())
1354 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1358 if (OSVersion.getMajor() != 0) {
1359 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1360 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1366 Triple.setOSName(BaseOSName);
1367 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1370bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1373 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1377 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1380 std::string RealMode = getExecutableForDriverMode(Mode);
1381 llvm::Triple Triple;
1390 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1391 PrefixTriple.isOSUnknown())
1392 Triple = PrefixTriple;
1396 llvm::Triple RealTriple =
1398 if (Triple.str().empty()) {
1399 Triple = RealTriple;
1400 assert(!Triple.str().empty());
1405 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1419 SmallString<128> CfgFilePath;
1421 "-" + RealMode +
".cfg"))
1422 return readConfigFile(CfgFilePath, ExpCtx);
1426 if (TryModeSuffix) {
1429 return readConfigFile(CfgFilePath, ExpCtx);
1434 std::string CfgFileName = RealMode +
".cfg";
1435 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1436 if (readConfigFile(CfgFilePath, ExpCtx))
1438 }
else if (TryModeSuffix) {
1440 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1441 readConfigFile(CfgFilePath, ExpCtx))
1447 return readConfigFile(CfgFilePath, ExpCtx);
1455 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1464 if (!DriverMode.empty())
1465 setDriverMode(DriverMode);
1471 CLOptions = std::make_unique<InputArgList>(
1476 ContainsError = loadConfigFiles();
1477 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1478 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1482 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1484 if (HasConfigFileHead)
1485 for (
auto *Opt : *CLOptions)
1486 if (!Opt->getOption().matches(options::OPT_config))
1490 if (
IsCLMode() && !ContainsError) {
1492 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1494 CLModePassThroughArgList.push_back(A->getValue());
1497 if (!CLModePassThroughArgList.empty()) {
1500 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1505 for (
auto *Opt : *CLModePassThroughOptions)
1511 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1512 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1513 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1516 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1517 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1518 if (!VFS->exists(IncludeDir))
1519 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1524 bool CCCPrintPhases;
1527 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1528 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1531 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1532 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1535 Args.ClaimAllArgs(options::OPT_pipe);
1543 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1545 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1546 CCCGenericGCCName = A->getValue();
1549 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1553 if (Args.hasArg(options::OPT_fproc_stat_report))
1560 llvm::Triple
T(TargetTriple);
1561 T.setOS(llvm::Triple::Win32);
1562 T.setVendor(llvm::Triple::PC);
1563 T.setEnvironment(llvm::Triple::MSVC);
1564 T.setObjectFormat(llvm::Triple::COFF);
1565 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1566 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1567 TargetTriple =
T.str();
1570 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1571 StringRef TargetProfile = A->getValue();
1574 TargetTriple = *Triple;
1576 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1580 if (Args.hasArg(options::OPT_spirv)) {
1581 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1582 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1583 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1584 llvm::Triple
T(TargetTriple);
1587 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1589 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1590 TargetInfo = ValidTargets.find(A->getValue());
1592 Diag(diag::err_drv_invalid_value)
1593 << A->getAsString(Args) << A->getValue();
1599 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1600 TargetTriple =
T.str();
1604 Diag(diag::err_drv_dxc_missing_target_profile);
1608 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1609 TargetTriple = A->getValue();
1610 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1611 Dir =
Dir = A->getValue();
1612 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1616 if (std::optional<std::string> CompilerPathValue =
1617 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1618 StringRef CompilerPath = *CompilerPathValue;
1619 while (!CompilerPath.empty()) {
1620 std::pair<StringRef, StringRef> Split =
1621 CompilerPath.split(llvm::sys::EnvPathSeparator);
1622 PrefixDirs.push_back(std::string(Split.first));
1623 CompilerPath = Split.second;
1626 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1628 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1631 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1634 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1635 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1636 .Case(
"cwd", SaveTempsCwd)
1637 .Case(
"obj", SaveTempsObj)
1638 .Default(SaveTempsCwd);
1641 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1642 options::OPT_offload_device_only,
1643 options::OPT_offload_host_device)) {
1644 if (A->getOption().matches(options::OPT_offload_host_only))
1645 Offload = OffloadHost;
1646 else if (A->getOption().matches(options::OPT_offload_device_only))
1647 Offload = OffloadDevice;
1649 Offload = OffloadHostDevice;
1655 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1656 StringRef
Name = A->getValue();
1657 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1658 .Case(
"off", EmbedNone)
1659 .Case(
"all", EmbedBitcode)
1660 .Case(
"bitcode", EmbedBitcode)
1661 .Case(
"marker", EmbedMarker)
1664 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1667 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1671 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1672 llvm::sys::fs::remove(A->getValue());
1678 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1680 !Args.hasArg(options::OPT_fmodules) && Std &&
1681 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1682 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1683 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1684 Std->containsValue(
"c++latest"));
1687 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1688 options::OPT_fmodule_header)) {
1690 ModulesModeCXX20 =
true;
1691 if (A->getOption().matches(options::OPT_fmodule_header))
1694 StringRef ArgName = A->getValue();
1695 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1700 Diags.Report(diag::err_drv_invalid_value)
1701 << A->getAsString(Args) << ArgName;
1707 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1708 std::make_unique<InputArgList>(std::move(Args));
1718 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1719 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1721 bool MLContainsError;
1722 auto MultilibMacroDefineList =
1724 MLMacroDefinesChar,
false, MLContainsError));
1725 if (!MLContainsError) {
1726 for (
auto *Opt : *MultilibMacroDefineList) {
1733 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1737 if (!Triple.isWasm()) {
1738 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1739 StringRef TripleObjectFormat =
1740 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1741 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1742 TripleVersionName != TripleObjectFormat) {
1743 Diags.Report(diag::err_drv_triple_version_invalid)
1745 ContainsError =
true;
1750 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1751 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1752 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1760 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1761 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1763 case llvm::Triple::arm:
1764 case llvm::Triple::armeb:
1765 case llvm::Triple::thumb:
1766 case llvm::Triple::thumbeb:
1767 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1768 Diag(diag::warn_target_unrecognized_env)
1770 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1773 case llvm::Triple::aarch64:
1774 case llvm::Triple::aarch64_be:
1775 case llvm::Triple::aarch64_32:
1776 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1777 Diag(diag::warn_target_unrecognized_env)
1779 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1796 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1797 if (HasConfigFileTail && Inputs.size()) {
1800 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1801 for (Arg *A : *CfgOptionsTail)
1802 TranslatedLinkerIns.append(A);
1803 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1812 if (TC.
getTriple().isOSBinFormatMachO())
1817 if (CCCPrintPhases) {
1828 llvm::opt::ArgStringList ASL;
1829 for (
const auto *A : Args) {
1833 while (A->getAlias())
1835 A->render(Args, ASL);
1838 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1839 if (I != ASL.begin())
1841 llvm::sys::printArg(OS, *I,
true);
1846bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1847 SmallString<128> &CrashDiagDir) {
1848 using namespace llvm::sys;
1849 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1850 "Only knows about .crash files on Darwin");
1852 auto BypassSandbox = sandbox::scopedDisable();
1857 path::home_directory(CrashDiagDir);
1858 if (CrashDiagDir.starts_with(
"/var/root"))
1860 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1868 fs::file_status FileStatus;
1869 TimePoint<> LastAccessTime;
1870 SmallString<128> CrashFilePath;
1873 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1874 File != FileEnd && !EC;
File.increment(EC)) {
1878 if (fs::status(
File->path(), FileStatus))
1880 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1881 llvm::MemoryBuffer::getFile(
File->path());
1886 StringRef
Data = CrashFile.get()->getBuffer();
1887 if (!
Data.starts_with(
"Process:"))
1890 size_t ParentProcPos =
Data.find(
"Parent Process:");
1891 if (ParentProcPos == StringRef::npos)
1893 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1894 if (LineEnd == StringRef::npos)
1896 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1897 int OpenBracket = -1, CloseBracket = -1;
1898 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1899 if (ParentProcess[i] ==
'[')
1901 if (ParentProcess[i] ==
']')
1907 if (OpenBracket < 0 || CloseBracket < 0 ||
1908 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1909 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1919 const auto FileAccessTime = FileStatus.getLastModificationTime();
1920 if (FileAccessTime > LastAccessTime) {
1921 CrashFilePath.assign(
File->path());
1922 LastAccessTime = FileAccessTime;
1927 if (!CrashFilePath.empty()) {
1928 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1938 "\n********************\n\n"
1939 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1940 "Preprocessed source(s) and associated run script(s) are located at:";
1948 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1952 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1953 Level = llvm::StringSwitch<unsigned>(A->getValue())
1955 .Case(
"compiler", 1)
1967 ArgStringList SavedTemps;
1969 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1970 if (!IsLLD || Level < 2)
1977 SavedTemps = std::move(
C.getTempFiles());
1978 assert(!
C.getTempFiles().size());
1995 C.initCompilationForDiagnostics();
2000 Command NewLLDInvocation = Cmd;
2001 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2002 StringRef ReproduceOption =
2003 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2006 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2010 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2012 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2013 Diag(clang::diag::note_drv_command_failed_diag_msg)
2014 <<
"\n\n********************";
2016 Report->TemporaryFiles.push_back(TmpName);
2024 ArgStringList IRInputs;
2025 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2026 bool IgnoreInput =
false;
2032 IRInputs.push_back(it->second->getValue());
2036 }
else if (!strcmp(it->second->getValue(),
"-")) {
2037 Diag(clang::diag::note_drv_command_failed_diag_msg)
2038 <<
"Error generating preprocessed source(s) - "
2039 "ignoring input from stdin.";
2044 it = Inputs.erase(it);
2051 if (Inputs.empty() && IRInputs.empty()) {
2052 Diag(clang::diag::note_drv_command_failed_diag_msg)
2053 <<
"Error generating preprocessed source(s) - "
2054 "no preprocessable inputs.";
2061 for (
const Arg *A :
C.getArgs()) {
2062 if (A->getOption().matches(options::OPT_arch)) {
2063 StringRef ArchName = A->getValue();
2068 Diag(clang::diag::note_drv_command_failed_diag_msg)
2069 <<
"Error generating preprocessed source(s) - cannot generate "
2070 "preprocessed source with multiple -arch options.";
2075 if (!Inputs.empty()) {
2078 const ToolChain &TC =
C.getDefaultToolChain();
2079 if (TC.
getTriple().isOSBinFormatMachO())
2088 Diag(clang::diag::note_drv_command_failed_diag_msg)
2089 <<
"Error generating preprocessed source(s).";
2094 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2097 if (!FailingCommands.empty()) {
2098 Diag(clang::diag::note_drv_command_failed_diag_msg)
2099 <<
"Error generating preprocessed source(s).";
2103 const ArgStringList &TempFiles =
C.getTempFiles();
2104 if (TempFiles.empty()) {
2105 Diag(clang::diag::note_drv_command_failed_diag_msg)
2106 <<
"Error generating preprocessed source(s).";
2112 const ArgStringList &Files =
C.getTempFiles();
2117 for (
auto const *Input : IRInputs) {
2121 StringRef extension = llvm::sys::path::extension(Input);
2122 if (!extension.empty())
2123 extension = extension.drop_front();
2125 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2126 llvm::sys::path::stem(Input), extension, FD, Path);
2128 Diag(clang::diag::note_drv_command_failed_diag_msg)
2129 <<
"Error generating run script: " <<
"Failed copying IR input files"
2130 <<
" " << EC.message();
2134 EC = llvm::sys::fs::copy_file(Input, FD);
2136 Diag(clang::diag::note_drv_command_failed_diag_msg)
2137 <<
"Error generating run script: " <<
"Failed copying IR input files"
2138 <<
" " << EC.message();
2142 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2149 for (std::string &TempFile : TempFiles) {
2150 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2152 Report->TemporaryFiles.push_back(TempFile);
2153 if (ReproCrashFilename.empty()) {
2154 ReproCrashFilename = TempFile;
2155 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2157 if (StringRef(TempFile).ends_with(
".cache")) {
2160 VFS = llvm::sys::path::filename(TempFile);
2161 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2165 for (
const char *TempFile : SavedTemps)
2166 TempFiles.push_back(TempFile);
2172 llvm::sys::path::replace_extension(Script,
"sh");
2174 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2175 llvm::sys::fs::FA_Write,
2176 llvm::sys::fs::OF_Text);
2178 Diag(clang::diag::note_drv_command_failed_diag_msg)
2179 <<
"Error generating run script: " << Script <<
" " << EC.message();
2182 <<
"# Driver args: ";
2184 ScriptOS <<
"# Original command: ";
2185 Cmd.
Print(ScriptOS,
"\n",
true);
2186 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2187 if (!AdditionalInformation.empty())
2188 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2191 Report->TemporaryFiles.push_back(std::string(Script));
2192 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2196 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2198 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2199 Diag(clang::diag::note_drv_command_failed_diag_msg)
2200 << ReproCrashFilename.str();
2202 llvm::sys::path::append(CrashDiagDir,
Name);
2203 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2204 Diag(clang::diag::note_drv_command_failed_diag_msg)
2205 <<
"Crash backtrace is located in";
2206 Diag(clang::diag::note_drv_command_failed_diag_msg)
2207 << CrashDiagDir.str();
2208 Diag(clang::diag::note_drv_command_failed_diag_msg)
2209 <<
"(choose the .crash file that corresponds to your crash)";
2213 Diag(clang::diag::note_drv_command_failed_diag_msg)
2214 <<
"\n\n********************";
2224 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2235 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2236 if (
C.getArgs().hasArg(options::OPT_v))
2237 C.getJobs().Print(llvm::errs(),
"\n",
true);
2239 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2242 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2249 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2250 C.getJobs().Print(llvm::errs(),
"\n",
true);
2251 return Diags.hasErrorOccurred() ? 1 : 0;
2255 if (Diags.hasErrorOccurred())
2259 for (
auto &Job :
C.getJobs())
2260 setUpResponseFiles(
C, Job);
2262 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2265 if (FailingCommands.empty())
2271 for (
const auto &CmdPair : FailingCommands) {
2272 int CommandRes = CmdPair.first;
2273 const Command *FailingCommand = CmdPair.second;
2278 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2282 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2287 if (CommandRes == EX_IOERR) {
2304 Diag(clang::diag::err_drv_command_signalled)
2307 Diag(clang::diag::err_drv_command_failed)
2315 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2317 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2331 const ToolChain &TC =
C.getDefaultToolChain();
2335 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2338 OS <<
"Thread model: " << A->getValue();
2344 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2349 if (!llvm::cl::getCompilerBuildConfig().empty())
2350 llvm::cl::printBuildConfig(OS);
2353 for (
auto ConfigFile : ConfigFiles)
2354 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2367 if (PassedFlags ==
"")
2371 std::vector<std::string> SuggestedCompletions;
2372 std::vector<std::string> Flags;
2384 const bool HasSpace = PassedFlags.ends_with(
",");
2388 StringRef TargetFlags = PassedFlags;
2389 while (TargetFlags !=
"") {
2391 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2392 Flags.push_back(std::string(CurFlag));
2397 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2400 const llvm::opt::OptTable &Opts =
getOpts();
2402 Cur = Flags.at(Flags.size() - 1);
2404 if (Flags.size() >= 2) {
2405 Prev = Flags.at(Flags.size() - 2);
2406 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2409 if (SuggestedCompletions.empty())
2410 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2417 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2418 llvm::outs() <<
'\n';
2424 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2428 SuggestedCompletions = Opts.findByPrefix(
2429 Cur, VisibilityMask,
2436 if (S.starts_with(Cur))
2437 SuggestedCompletions.push_back(std::string(S));
2444 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2445 if (
int X = A.compare_insensitive(B))
2447 return A.compare(B) > 0;
2450 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2457 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2458 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2462 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2465 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2469 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2474 if (
C.getArgs().hasArg(options::OPT_help) ||
2475 C.getArgs().hasArg(options::OPT__help_hidden)) {
2476 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2480 if (
C.getArgs().hasArg(options::OPT__version)) {
2486 if (
C.getArgs().hasArg(options::OPT_v) ||
2487 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2488 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2489 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2490 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2492 SuppressMissingInputWarning =
true;
2495 if (
C.getArgs().hasArg(options::OPT_v)) {
2497 llvm::errs() <<
"System configuration file directory: "
2500 llvm::errs() <<
"User configuration file directory: "
2504 const ToolChain &TC =
C.getDefaultToolChain();
2506 if (
C.getArgs().hasArg(options::OPT_v))
2509 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2514 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2515 llvm::outs() <<
"programs: =";
2516 bool separator =
false;
2520 llvm::outs() << llvm::sys::EnvPathSeparator;
2521 llvm::outs() << Path;
2526 llvm::outs() << llvm::sys::EnvPathSeparator;
2527 llvm::outs() << Path;
2530 llvm::outs() <<
"\n";
2533 StringRef sysroot =
C.getSysRoot();
2537 llvm::outs() << llvm::sys::EnvPathSeparator;
2540 llvm::outs() << sysroot << Path.substr(1);
2542 llvm::outs() << Path;
2544 llvm::outs() <<
"\n";
2548 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2554 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2555 for (
auto RuntimePath :
2557 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2558 llvm::outs() << *RuntimePath <<
'\n';
2562 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2566 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2568 for (std::size_t I = 0; I != Flags.size(); I += 2)
2569 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2575 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2576 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2580 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2581 StringRef ProgName = A->getValue();
2584 if (! ProgName.empty())
2587 llvm::outs() <<
"\n";
2591 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2592 StringRef PassedFlags = A->getValue();
2597 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2611 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2614 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2620 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2627 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2630 std::set<llvm::StringRef> SortedFlags;
2631 for (
const auto &FlagEntry : ExpandedFlags)
2632 SortedFlags.insert(FlagEntry.getKey());
2633 for (
auto Flag : SortedFlags)
2634 llvm::outs() << Flag <<
'\n';
2638 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2641 llvm::outs() <<
".\n";
2644 assert(Suffix.front() ==
'/');
2645 llvm::outs() << Suffix.substr(1) <<
"\n";
2651 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2656 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2658 llvm::outs() << Triple.getTriple() <<
"\n";
2662 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2663 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2680 std::map<Action *, unsigned> &Ids,
2682 if (
auto It = Ids.find(A); It != Ids.end())
2686 llvm::raw_string_ostream os(str);
2688 auto getSibIndent = [](
int K) -> Twine {
2692 Twine SibIndent =
Indent + getSibIndent(Kind);
2696 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2698 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2699 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2700 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2702 OA->doOnEachDependence(
2704 assert(TC &&
"Unknown host toolchain");
2716 os <<
":" << BoundArch;
2719 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2727 const char *Prefix =
"{";
2728 for (
Action *PreRequisite : *AL) {
2729 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2740 std::string offload_str;
2741 llvm::raw_string_ostream offload_os(offload_str);
2745 offload_os <<
", (" << S;
2752 auto getSelfIndent = [](
int K) -> Twine {
2756 unsigned Id = Ids.size();
2758 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2767 std::map<Action *, unsigned> Ids;
2768 for (
Action *A :
C.getActions())
2784 DerivedArgList &Args =
C.getArgs();
2786 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2791 for (Arg *A : Args) {
2792 if (A->getOption().matches(options::OPT_arch)) {
2795 llvm::Triple::ArchType
Arch =
2797 if (
Arch == llvm::Triple::UnknownArch) {
2798 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2803 if (
ArchNames.insert(A->getValue()).second)
2804 Archs.push_back(A->getValue());
2818 for (
Action* Act : SingleActions) {
2826 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2830 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2835 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2836 Actions.append(Inputs.begin(), Inputs.end());
2838 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2841 Arg *A = Args.getLastArg(options::OPT_g_Group);
2842 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2843 !A->getOption().matches(options::OPT_gstabs);
2851 if (Act->getType() == types::TY_Image) {
2853 Inputs.push_back(Actions.back());
2860 if (Args.hasArg(options::OPT_verify_debug_info)) {
2861 Action *LastAction = Actions.pop_back_val();
2863 LastAction, types::TY_Nothing));
2882 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2883 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2895 std::string Nearest;
2896 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2897 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2898 <<
Value << Nearest;
2937 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2940 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2948 return types::TY_CXXUHeader;
2950 return types::TY_CXXSHeader;
2954 llvm_unreachable(
"should not be called in this case");
2956 return types::TY_CXXHUHeader;
2962 const llvm::opt::OptTable &Opts =
getOpts();
2966 types::ID InputType = types::TY_Nothing;
2967 Arg *InputTypeArg =
nullptr;
2970 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2971 options::OPT__SLASH_TP)) {
2972 InputTypeArg = TCTP;
2973 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2978 bool ShowNote =
false;
2980 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2982 Diag(clang::diag::warn_drv_overriding_option)
2983 <<
Previous->getSpelling() << A->getSpelling();
2989 Diag(clang::diag::note_drv_t_option_is_global);
2994 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2995 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2996 if (LastXArg && LastInputArg &&
2997 LastInputArg->getIndex() < LastXArg->getIndex())
2998 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3001 for (Arg *A : Args) {
3002 if (A->getOption().
getKind() == Option::InputClass) {
3003 const char *
Value = A->getValue();
3007 if (InputType == types::TY_Nothing) {
3010 InputTypeArg->claim();
3013 if (memcmp(
Value,
"-", 2) == 0) {
3015 Ty = types::TY_Fortran;
3017 Ty = types::TY_HLSL;
3026 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3027 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3028 : clang::diag::err_drv_unknown_stdin_type);
3037 if (
const char *Ext = strrchr(
Value,
'.'))
3046 Ty = types::TY_HLSL;
3048 Ty = types::TY_Object;
3059 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3060 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3061 << getTypeName(OldTy) << getTypeName(Ty);
3066 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3067 Ty == types::TY_Object)
3068 Ty = types::TY_LLVM_BC;
3076 if (Ty != types::TY_Object) {
3077 if (Args.hasArg(options::OPT_ObjC))
3078 Ty = types::TY_ObjC;
3079 else if (Args.hasArg(options::OPT_ObjCXX))
3080 Ty = types::TY_ObjCXX;
3087 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3091 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3092 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3095 const char *Ext = strrchr(
Value,
'.');
3097 Ty = types::TY_Object;
3101 InputTypeArg->claim();
3105 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3106 Args.hasArgNoClaim(options::OPT_hipstdpar))
3110 Inputs.push_back(std::make_pair(Ty, A));
3112 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3113 StringRef
Value = A->getValue();
3116 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3117 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3120 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3121 StringRef
Value = A->getValue();
3124 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3125 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3131 Inputs.push_back(std::make_pair(types::TY_Object, A));
3133 }
else if (A->getOption().matches(options::OPT_x)) {
3142 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3143 InputType = types::TY_Object;
3150 }
else if (A->getOption().getID() == options::OPT_U) {
3151 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3152 StringRef Val = A->getValue(0);
3153 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3155 Diag(diag::warn_slash_u_filename) << Val;
3156 Diag(diag::note_use_dashdash);
3160 if (
CCCIsCPP() && Inputs.empty()) {
3164 Inputs.push_back(std::make_pair(types::TY_C, A));
3171class OffloadingActionBuilder final {
3173 bool IsValid =
false;
3179 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3182 std::map<Action *, const Arg *> HostActionToInputArgMap;
3185 class DeviceActionBuilder {
3189 enum ActionBuilderReturnCode {
3208 DerivedArgList &Args;
3217 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3220 :
C(
C), Args(Args), Inputs(Inputs),
3221 AssociatedOffloadKind(AssociatedOffloadKind) {}
3222 virtual ~DeviceActionBuilder() {}
3227 virtual ActionBuilderReturnCode
3228 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3231 return ABRT_Inactive;
3236 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3237 return ABRT_Inactive;
3241 virtual void appendTopLevelActions(
ActionList &AL) {}
3244 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3247 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3250 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3257 virtual bool canUseBundlerUnbundler()
const {
return false; }
3261 bool isValid() {
return !ToolChains.empty(); }
3265 return AssociatedOffloadKind;
3271 class CudaActionBuilderBase :
public DeviceActionBuilder {
3275 bool CompileHostOnly =
false;
3276 bool CompileDeviceOnly =
false;
3278 bool EmitAsm =
false;
3288 TargetID(
const char *ID) :
ID(
ID) {}
3289 operator const char *() {
return ID; }
3290 operator StringRef() {
return StringRef(ID); }
3293 SmallVector<TargetID, 4> GpuArchList;
3299 Action *CudaFatBinary =
nullptr;
3302 bool IsActive =
false;
3305 bool Relocatable =
false;
3308 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3311 const CUIDOptions &CUIDOpts;
3314 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3317 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3318 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3320 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3321 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3322 options::OPT_fno_gpu_rdc,
false);
3325 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3332 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3335 if (!(IA->getType() == types::TY_CUDA ||
3336 IA->getType() == types::TY_HIP ||
3337 IA->getType() == types::TY_PP_HIP)) {
3340 return ABRT_Inactive;
3347 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3349 if (CompileHostOnly)
3350 return ABRT_Success;
3353 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3354 : types::TY_CUDA_DEVICE;
3355 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3356 CudaDeviceActions.push_back(
3357 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3360 return ABRT_Success;
3364 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3368 if (UA->getType() == types::TY_Object && !Relocatable)
3369 return ABRT_Inactive;
3371 CudaDeviceActions.clear();
3373 std::string
FileName = IA->getInputArg().getAsString(Args);
3379 const StringRef LibFileExt =
".lib";
3380 if (IA->getType() == types::TY_Object &&
3381 (!llvm::sys::path::has_extension(
FileName) ||
3383 llvm::sys::path::extension(
FileName).drop_front()) !=
3385 llvm::sys::path::extension(
FileName) == LibFileExt))
3386 return ABRT_Inactive;
3388 for (
auto Arch : GpuArchList) {
3389 CudaDeviceActions.push_back(UA);
3390 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3391 AssociatedOffloadKind);
3394 return ABRT_Success;
3397 return IsActive ? ABRT_Success : ABRT_Inactive;
3400 void appendTopLevelActions(
ActionList &AL)
override {
3402 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3403 OffloadAction::DeviceDependences Dep;
3404 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3405 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3409 if (CudaFatBinary) {
3410 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3411 CudaDeviceActions.clear();
3412 CudaFatBinary =
nullptr;
3416 if (CudaDeviceActions.empty())
3422 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3423 "Expecting one action per GPU architecture.");
3424 assert(ToolChains.size() == 1 &&
3425 "Expecting to have a single CUDA toolchain.");
3426 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3427 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3429 CudaDeviceActions.clear();
3432 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3450 assert(HostTC &&
"No toolchain for host compilation.");
3455 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3460 std::set<StringRef> GpuArchs;
3462 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3463 ToolChains.push_back(I.second);
3466 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3467 GpuArchs.insert(
Arch);
3471 for (
auto Arch : GpuArchs)
3472 GpuArchList.push_back(
Arch.data());
3474 CompileHostOnly =
C.getDriver().offloadHostOnly();
3475 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3476 EmitAsm = Args.getLastArg(options::OPT_S);
3484 class CudaActionBuilder final :
public CudaActionBuilderBase {
3486 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3488 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3489 DefaultOffloadArch = OffloadArch::CudaDefault;
3492 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3494 const std::set<StringRef> &GpuArchs)
override {
3495 return std::nullopt;
3498 ActionBuilderReturnCode
3499 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3501 PhasesTy &Phases)
override {
3503 return ABRT_Inactive;
3507 if (CudaDeviceActions.empty())
3508 return ABRT_Success;
3510 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3511 "Expecting one action per GPU architecture.");
3512 assert(!CompileHostOnly &&
3513 "Not expecting CUDA actions in host-only compilation.");
3523 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3526 for (
auto Ph : Phases) {
3531 if (Ph > FinalPhase)
3534 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3548 Action *AssembleAction = CudaDeviceActions[I];
3549 assert(AssembleAction->
getType() == types::TY_Object);
3550 assert(AssembleAction->
getInputs().size() == 1);
3556 OffloadAction::DeviceDependences DDep;
3558 DeviceActions.push_back(
3559 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3564 if (!DeviceActions.empty()) {
3566 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3568 if (!CompileDeviceOnly) {
3569 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3573 CudaFatBinary =
nullptr;
3578 CudaDeviceActions.clear();
3582 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3587 return ABRT_Success;
3591 "instructions should only occur "
3592 "before the backend phase!");
3595 for (Action *&A : CudaDeviceActions)
3596 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3598 return ABRT_Success;
3603 class HIPActionBuilder final :
public CudaActionBuilderBase {
3605 SmallVector<ActionList, 8> DeviceLinkerInputs;
3611 std::optional<bool> BundleOutput;
3612 std::optional<bool> EmitReloc;
3615 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3617 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3619 DefaultOffloadArch = OffloadArch::HIPDefault;
3621 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3622 options::OPT_fno_hip_emit_relocatable)) {
3623 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3624 options::OPT_fno_hip_emit_relocatable, false);
3628 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3629 <<
"-fhip-emit-relocatable"
3633 if (!CompileDeviceOnly) {
3634 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3635 <<
"-fhip-emit-relocatable"
3636 <<
"--offload-device-only";
3641 if (Args.hasArg(options::OPT_gpu_bundle_output,
3642 options::OPT_no_gpu_bundle_output))
3643 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3644 options::OPT_no_gpu_bundle_output,
true) &&
3645 (!EmitReloc || !*EmitReloc);
3648 bool canUseBundlerUnbundler()
const override {
return true; }
3650 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3652 const std::set<StringRef> &GpuArchs)
override {
3656 ActionBuilderReturnCode
3657 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3659 PhasesTy &Phases)
override {
3661 return ABRT_Inactive;
3667 if (CudaDeviceActions.empty())
3668 return ABRT_Success;
3671 CudaDeviceActions.size() == GpuArchList.size()) &&
3672 "Expecting one action per GPU architecture.");
3673 assert(!CompileHostOnly &&
3674 "Not expecting HIP actions in host-only compilation.");
3676 bool ShouldLink = !EmitReloc || !*EmitReloc;
3679 !EmitAsm && ShouldLink) {
3685 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3686 if (
C.getDriver().isUsingOffloadLTO()) {
3690 AL.push_back(CudaDeviceActions[I]);
3693 CudaDeviceActions[I] =
3694 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3700 if (ToolChains.front()->getTriple().isSPIRV() ||
3701 (ToolChains.front()->getTriple().isAMDGCN() &&
3702 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3706 types::ID Output = Args.hasArg(options::OPT_S)
3708 : types::TY_LLVM_BC;
3710 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3714 AssociatedOffloadKind);
3715 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3717 AssociatedOffloadKind);
3718 AL.push_back(AssembleAction);
3721 CudaDeviceActions[I] =
3722 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3731 OffloadAction::DeviceDependences DDep;
3732 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3733 AssociatedOffloadKind);
3734 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3735 DDep, CudaDeviceActions[I]->getType());
3738 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3740 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3741 types::TY_HIP_FATBIN);
3743 if (!CompileDeviceOnly) {
3744 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3745 AssociatedOffloadKind);
3748 CudaFatBinary =
nullptr;
3753 CudaDeviceActions.clear();
3756 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3759 return ABRT_Success;
3765 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3766 auto LI = DeviceLinkerInputs.begin();
3767 for (
auto *A : CudaDeviceActions) {
3774 CudaDeviceActions.clear();
3775 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3779 for (Action *&A : CudaDeviceActions)
3780 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3781 AssociatedOffloadKind);
3783 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3785 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3786 OffloadAction::DeviceDependences DDep;
3787 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3788 AssociatedOffloadKind);
3789 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3790 DDep, CudaDeviceActions[I]->getType());
3793 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3794 CudaDeviceActions.clear();
3797 return (CompileDeviceOnly &&
3798 (CurPhase == FinalPhase ||
3804 void appendLinkDeviceActions(
ActionList &AL)
override {
3805 if (DeviceLinkerInputs.size() == 0)
3808 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3809 "Linker inputs and GPU arch list sizes do not match.");
3815 for (
auto &LI : DeviceLinkerInputs) {
3817 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3821 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3824 OffloadAction::DeviceDependences DeviceLinkDeps;
3825 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3826 GpuArchList[I], AssociatedOffloadKind);
3827 Actions.push_back(
C.MakeAction<OffloadAction>(
3828 DeviceLinkDeps, DeviceLinkAction->getType()));
3831 DeviceLinkerInputs.clear();
3834 if (Args.hasArg(options::OPT_emit_llvm)) {
3842 OffloadAction::DeviceDependences DDeps;
3843 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3844 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3846 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3847 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3848 AssociatedOffloadKind);
3851 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3857 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3859 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3867 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3873 bool ShouldUseBundler;
3876 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3884 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3887 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3895 unsigned ValidBuilders = 0u;
3896 unsigned ValidBuildersSupportingBundling = 0u;
3897 for (
auto *SB : SpecializedBuilders) {
3898 IsValid = IsValid && !SB->initialize();
3901 if (SB->isValid()) {
3903 if (SB->canUseBundlerUnbundler())
3904 ++ValidBuildersSupportingBundling;
3908 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3910 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
3911 options::OPT_no_gpu_bundle_output,
true);
3914 ~OffloadingActionBuilder() {
3915 for (
auto *SB : SpecializedBuilders)
3920 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3921 assert(HostAction &&
"Invalid host action");
3922 assert(InputArg &&
"Invalid input argument");
3923 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3924 assert(Loc->second == InputArg &&
3925 "host action mapped to multiple input arguments");
3934 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3936 DeviceActionBuilder::PhasesTy &Phases) {
3940 if (SpecializedBuilders.empty())
3943 assert(HostAction &&
"Invalid host action!");
3944 recordHostAction(HostAction, InputArg);
3949 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3950 unsigned InactiveBuilders = 0u;
3951 unsigned IgnoringBuilders = 0u;
3952 for (
auto *SB : SpecializedBuilders) {
3953 if (!SB->isValid()) {
3958 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3963 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3968 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3969 OffloadKind |= SB->getAssociatedOffloadKind();
3974 if (IgnoringBuilders &&
3975 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3992 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3993 const Arg *InputArg) {
3997 recordHostAction(HostAction, InputArg);
4006 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4008 HostAction->
getType() == types::TY_PP_HIP)) {
4009 auto UnbundlingHostAction =
4014 HostAction = UnbundlingHostAction;
4015 recordHostAction(HostAction, InputArg);
4018 assert(HostAction &&
"Invalid host action!");
4021 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4022 for (
auto *SB : SpecializedBuilders) {
4026 auto RetCode = SB->addDeviceDependences(HostAction);
4030 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4031 "Host dependence not expected to be ignored.!");
4035 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4036 OffloadKind |= SB->getAssociatedOffloadKind();
4041 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4051 const Arg *InputArg) {
4053 recordHostAction(HostAction, InputArg);
4057 for (
auto *SB : SpecializedBuilders) {
4060 SB->appendTopLevelActions(OffloadAL);
4067 if (CanUseBundler && ShouldUseBundler && HostAction &&
4068 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4070 OffloadAL.push_back(HostAction);
4074 assert(HostAction == AL.back() &&
"Host action not in the list??");
4076 recordHostAction(HostAction, InputArg);
4077 AL.back() = HostAction;
4079 AL.append(OffloadAL.begin(), OffloadAL.end());
4089 void appendDeviceLinkActions(
ActionList &AL) {
4090 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4093 SB->appendLinkDeviceActions(AL);
4097 Action *makeHostLinkAction() {
4100 appendDeviceLinkActions(DeviceAL);
4101 if (DeviceAL.empty())
4106 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4109 HA = SB->appendLinkHostActions(DeviceAL);
4126 for (
auto *SB : SpecializedBuilders) {
4130 SB->appendLinkDependences(DDeps);
4134 unsigned ActiveOffloadKinds = 0u;
4135 for (
auto &I : InputArgToOffloadKindMap)
4136 ActiveOffloadKinds |= I.second;
4148 for (
auto *A : HostAction->
inputs()) {
4149 auto ArgLoc = HostActionToInputArgMap.find(A);
4150 if (ArgLoc == HostActionToInputArgMap.end())
4152 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4153 if (OFKLoc == InputArgToOffloadKindMap.end())
4165 nullptr, ActiveOffloadKinds);
4171void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4172 const InputList &Inputs,
4176 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4177 StringRef
V = A->getValue();
4178 if (Inputs.size() > 1 && !
V.empty() &&
4179 !llvm::sys::path::is_separator(
V.back())) {
4181 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4182 << A->getSpelling() <<
V;
4183 Args.eraseArg(options::OPT__SLASH_Fo);
4188 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4189 StringRef
V = A->getValue();
4190 if (Inputs.size() > 1 && !
V.empty() &&
4191 !llvm::sys::path::is_separator(
V.back())) {
4193 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4194 << A->getSpelling() <<
V;
4195 Args.eraseArg(options::OPT__SLASH_Fa);
4200 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4201 if (A->getValue()[0] ==
'\0') {
4203 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4204 Args.eraseArg(options::OPT__SLASH_o);
4209 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4210 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4211 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4212 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4213 Args.eraseArg(options::OPT__SLASH_Yc);
4214 Args.eraseArg(options::OPT__SLASH_Yu);
4215 YcArg = YuArg =
nullptr;
4217 if (YcArg && Inputs.size() > 1) {
4218 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4219 Args.eraseArg(options::OPT__SLASH_Yc);
4227 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4228 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4229 Args.AddFlagArg(
nullptr,
4230 getOpts().getOption(options::OPT_frtlib_add_rpath));
4234 if (Args.hasArg(options::OPT_emit_llvm) &&
4235 !Args.hasArg(options::OPT_hip_link) &&
4236 !
C.getDefaultToolChain().getTriple().isSPIRV())
4237 Diag(clang::diag::err_drv_emit_llvm_link);
4238 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4240 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4241 .starts_with_insensitive(
"lld"))
4242 Diag(clang::diag::err_drv_lto_without_lld);
4248 if (!Args.hasArg(options::OPT_dumpdir)) {
4249 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4250 Arg *Arg = Args.MakeSeparateArg(
4251 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4253 (FinalOutput ? FinalOutput->getValue()
4265 Args.eraseArg(options::OPT__SLASH_Fp);
4266 Args.eraseArg(options::OPT__SLASH_Yc);
4267 Args.eraseArg(options::OPT__SLASH_Yu);
4268 YcArg = YuArg =
nullptr;
4271 if (Args.hasArg(options::OPT_include_pch) &&
4272 Args.hasArg(options::OPT_ignore_pch)) {
4276 Args.eraseArg(options::OPT_include_pch);
4279 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4280 for (
auto &I : Inputs) {
4282 const Arg *InputArg = I.second;
4287 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4291 if (InitialPhase > FinalPhase) {
4292 if (InputArg->isClaimed())
4299 if (Args.hasArg(options::OPT_Qunused_arguments))
4305 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4306 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4310 (Args.getLastArg(options::OPT__SLASH_EP,
4311 options::OPT__SLASH_P) ||
4312 Args.getLastArg(options::OPT_E) ||
4313 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4315 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4316 << InputArg->getAsString(Args) << !!FinalPhaseArg
4317 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4319 Diag(clang::diag::warn_drv_input_file_unused)
4320 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4322 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4331 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4335 Actions.push_back(ClangClPch);
4347 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4348 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4354 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4356 if (!SuppressMissingInputWarning && Inputs.empty()) {
4357 Diag(clang::diag::err_drv_no_input_files);
4361 handleArguments(
C, Args, Inputs, Actions);
4363 bool UseNewOffloadingDriver =
4366 Args.hasFlag(options::OPT_foffload_via_llvm,
4367 options::OPT_fno_offload_via_llvm,
false) ||
4368 Args.hasFlag(options::OPT_offload_new_driver,
4369 options::OPT_no_offload_new_driver,
4373 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4374 !UseNewOffloadingDriver
4375 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4383 for (
auto &I : Inputs) {
4385 const Arg *InputArg = I.second;
4398 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4404 if (!UseNewOffloadingDriver)
4405 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4411 if (!UseNewOffloadingDriver)
4412 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4413 Current, InputArg, Phase, PL.back(), FullPL);
4419 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4422 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4423 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4425 LinkerInputs.push_back(Current);
4435 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4436 MergerInputs.push_back(Current);
4454 if (NewCurrent == Current)
4457 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4460 Current = NewCurrent;
4464 if (UseNewOffloadingDriver)
4468 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4472 if (Current->
getType() == types::TY_Nothing)
4478 Actions.push_back(Current);
4481 if (!UseNewOffloadingDriver)
4482 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4490 if (LinkerInputs.empty()) {
4493 if (!UseNewOffloadingDriver)
4494 OffloadBuilder->appendDeviceLinkActions(Actions);
4497 if (!LinkerInputs.empty()) {
4498 if (!UseNewOffloadingDriver)
4499 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4500 LinkerInputs.push_back(Wrapper);
4505 }
else if (UseNewOffloadingDriver ||
4506 Args.hasArg(options::OPT_offload_link)) {
4514 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4515 C.getDefaultToolChain().getTriple().isSPIRV();
4516 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4520 if (!UseNewOffloadingDriver)
4521 LA = OffloadBuilder->processHostLinkAction(LA);
4522 Actions.push_back(LA);
4526 if (!MergerInputs.empty())
4530 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4537 for (
auto &I : Inputs) {
4539 const Arg *InputArg = I.second;
4544 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4545 InputType == types::TY_Asm)
4550 for (
auto Phase : PhaseList) {
4554 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4559 if (InputType == types::TY_Object)
4566 assert(Phase == PhaseList.back() &&
4567 "merging must be final compilation step.");
4568 MergerInputs.push_back(Current);
4577 Actions.push_back(Current);
4581 if (!MergerInputs.empty())
4586 for (
auto Opt : {options::OPT_print_supported_cpus,
4587 options::OPT_print_supported_extensions,
4588 options::OPT_print_enabled_extensions}) {
4595 if (Arg *A = Args.getLastArg(Opt)) {
4596 if (Opt == options::OPT_print_supported_extensions &&
4597 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4598 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4599 !
C.getDefaultToolChain().getTriple().isARM()) {
4600 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4601 <<
"--print-supported-extensions";
4604 if (Opt == options::OPT_print_enabled_extensions &&
4605 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4606 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4607 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4608 <<
"--print-enabled-extensions";
4615 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4618 for (
auto &I : Inputs)
4623 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4629 if (TC.requiresObjcopy(Args)) {
4630 Action *LastAction = Actions.back();
4632 if (LastAction->
getType() == types::TY_Object)
4638 if (TC.requiresValidation(Args)) {
4639 Action *LastAction = Actions.back();
4641 LastAction, types::TY_DX_CONTAINER));
4645 if (TC.requiresBinaryTranslation(Args)) {
4646 Action *LastAction = Actions.back();
4650 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4651 LastAction->
getType() == types::TY_Object)
4653 LastAction, types::TY_DX_CONTAINER));
4658 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4664 const llvm::opt::DerivedArgList &Args,
4666 const llvm::Triple &Triple) {
4671 if (Triple.isNVPTX() &&
4673 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4674 <<
"CUDA" << ArchStr;
4676 }
else if (Triple.isAMDGPU() &&
4678 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4679 <<
"HIP" << ArchStr;
4687 llvm::StringMap<bool> Features;
4690 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4702static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4704 llvm::Triple Triple) {
4705 if (!Triple.isAMDGPU())
4706 return std::nullopt;
4708 std::set<StringRef> ArchSet;
4709 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4713llvm::SmallVector<StringRef>
4717 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4718 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4719 options::OPT_no_offload_arch_EQ)) {
4720 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4722 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4724 :
"--no-offload-arch");
4727 llvm::DenseSet<StringRef> Archs;
4728 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4731 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4732 for (StringRef
Arch : Arg->getValues()) {
4733 if (
Arch ==
"native" ||
Arch.empty()) {
4737 << llvm::Triple::getArchTypeName(TC.
getArch())
4738 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4742 for (
auto ArchStr : *GPUsOrErr) {
4744 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4745 if (!CanonicalStr.empty())
4746 Archs.insert(CanonicalStr);
4751 StringRef CanonicalStr =
4753 if (!CanonicalStr.empty())
4754 Archs.insert(CanonicalStr);
4759 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4760 for (StringRef
Arch : Arg->getValues()) {
4761 if (
Arch ==
"all") {
4766 Archs.erase(ArchStr);
4772 if (
auto ConflictingArchs =
4774 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4775 << ConflictingArchs->first << ConflictingArchs->second;
4778 if (Archs.empty()) {
4786 Archs.insert(StringRef());
4789 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4790 .getLastArg(options::OPT_march_EQ)) {
4791 Archs.insert(Arg->getValue());
4796 << llvm::Triple::getArchTypeName(TC.
getArch())
4797 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4798 }
else if (!ArchsOrErr->empty()) {
4799 for (
auto Arch : *ArchsOrErr)
4800 Archs.insert(Args.MakeArgStringRef(
Arch));
4802 Archs.insert(StringRef());
4807 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4808 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4816 llvm::opt::DerivedArgList &Args,
4817 const InputTy &Input, StringRef CUID,
4818 Action *HostAction)
const {
4826 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4828 bool HIPRelocatableObj =
4830 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4831 options::OPT_fno_hip_emit_relocatable,
false);
4833 if (!HIPNoRDC && HIPRelocatableObj)
4834 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4835 <<
"-fhip-emit-relocatable"
4839 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4840 <<
"-fhip-emit-relocatable"
4841 <<
"--offload-device-only";
4859 auto TCRange =
C.getOffloadToolChains(Kind);
4860 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4861 ToolChains.push_back(TI->second);
4863 if (ToolChains.empty())
4867 const Arg *InputArg = Input.second;
4876 for (
const ToolChain *TC : ToolChains) {
4878 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4879 DeviceActions.push_back(
4880 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4884 if (DeviceActions.empty())
4890 HostAction->
getType() != types::TY_Nothing &&
4900 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4909 auto *TCAndArch = TCAndArchs.begin();
4910 for (
Action *&A : DeviceActions) {
4911 if (A->
getType() == types::TY_Nothing)
4921 HostAction->
getType() != types::TY_Nothing) {
4928 TCAndArch->second.data(), Kind);
4930 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4940 for (
Action *&A : DeviceActions) {
4943 llvm::Triple::OSType::AMDHSA &&
4945 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
4946 options::OPT_no_use_spirv_backend,
4953 bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
4955 if ((A->
getType() != types::TY_Object && !IsAMDGCNSPIRV &&
4956 A->
getType() != types::TY_LTO_BC) ||
4964 auto *TCAndArch = TCAndArchs.begin();
4965 for (
Action *A : DeviceActions) {
4966 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4968 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4973 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4975 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4984 bool ShouldBundleHIP =
4985 Args.hasFlag(options::OPT_gpu_bundle_output,
4986 options::OPT_no_gpu_bundle_output,
false) ||
4988 llvm::none_of(OffloadActions, [](
Action *A) {
4989 return A->
getType() != types::TY_Image;
4996 if (OffloadActions.empty())
5001 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5005 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5012 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5013 DDep.
add(*FatbinAction,
5016 }
else if (HIPNoRDC) {
5028 DDep.
add(*PackagerAction,
5037 nullptr,
C.getActiveOffloadKinds());
5046 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5047 return A->
getType() == types::TY_Nothing;
5051 nullptr, SingleDeviceOutput ? DDep : DDeps);
5052 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5058 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5068 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5074 llvm_unreachable(
"link action invalid here.");
5076 llvm_unreachable(
"ifsmerge action invalid here.");
5081 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5082 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5083 OutputTy = types::TY_Dependencies;
5088 if (!Args.hasFlag(options::OPT_frewrite_includes,
5089 options::OPT_fno_rewrite_includes,
false) &&
5090 !Args.hasFlag(options::OPT_frewrite_imports,
5091 options::OPT_fno_rewrite_imports,
false) &&
5092 !Args.hasFlag(options::OPT_fdirectives_only,
5093 options::OPT_fno_directives_only,
false) &&
5097 "Cannot preprocess this input type!");
5103 if (Args.hasArg(options::OPT_extract_api))
5110 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5111 (Input->
getType() == driver::types::TY_CXXModule ||
5112 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5113 !Args.getLastArg(options::OPT__precompile))
5118 "Cannot precompile this input type!");
5122 const char *ModName =
nullptr;
5123 if (OutputTy == types::TY_PCH) {
5124 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5125 ModName = A->getValue();
5127 OutputTy = types::TY_ModuleFile;
5130 if (Args.hasArg(options::OPT_fsyntax_only)) {
5132 OutputTy = types::TY_Nothing;
5138 if (Args.hasArg(options::OPT_fsyntax_only))
5140 if (Args.hasArg(options::OPT_rewrite_objc))
5142 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5144 types::TY_RewrittenLegacyObjC);
5145 if (Args.hasArg(options::OPT__analyze))
5147 if (Args.hasArg(options::OPT_emit_ast))
5149 if (Args.hasArg(options::OPT_emit_cir))
5151 if (Args.hasArg(options::OPT_module_file_info))
5153 if (Args.hasArg(options::OPT_verify_pch))
5155 if (Args.hasArg(options::OPT_extract_api))
5163 Args.hasFlag(options::OPT_offload_new_driver,
5164 options::OPT_no_offload_new_driver,
false) &&
5170 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5171 !Args.hasArg(options::OPT_emit_llvm))
5172 Output = types::TY_PP_Asm;
5173 else if (Args.hasArg(options::OPT_S))
5174 Output = types::TY_LTO_IR;
5176 Output = types::TY_LTO_BC;
5181 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5184 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5185 options::OPT_no_use_spirv_backend,
5193 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5195 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5197 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5199 auto &DefaultToolChain =
C.getDefaultToolChain();
5200 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5205 bool EmitBitcodeForNonOffloadAMDSPIRV =
5206 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5207 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5208 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5210 if (Args.hasArg(options::OPT_emit_llvm) ||
5211 EmitBitcodeForNonOffloadAMDSPIRV ||
5217 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5218 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5220 (Args.hasFlag(options::OPT_offload_new_driver,
5221 options::OPT_no_offload_new_driver,
false) &&
5228 Args.hasArg(options::OPT_S) &&
5232 !Args.hasFlag(options::OPT_offload_new_driver,
5233 options::OPT_no_offload_new_driver,
5236 : types::TY_LLVM_BC;
5249 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5258 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5262 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5264 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5284 unsigned NumOutputs = 0;
5285 unsigned NumIfsOutputs = 0;
5286 for (
const Action *A :
C.getActions()) {
5289 if (A->
getType() == types::TY_DX_CONTAINER &&
5294 if (A->
getType() != types::TY_Nothing &&
5296 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5298 0 == NumIfsOutputs++) ||
5303 A->
getType() == types::TY_Nothing &&
5304 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5305 NumOutputs += A->
size();
5308 if (NumOutputs > 1) {
5309 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5310 FinalOutput =
nullptr;
5314 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5318 if (RawTriple.isOSBinFormatMachO())
5319 for (
const Arg *A :
C.getArgs())
5320 if (A->getOption().matches(options::OPT_arch))
5324 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5325 for (
Action *A :
C.getActions()) {
5332 const char *LinkingOutput =
nullptr;
5335 LinkingOutput = FinalOutput->getValue();
5344 LinkingOutput, CachedResults,
5351 for (
auto &J :
C.getJobs())
5352 J.InProcess =
false;
5355 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5356 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5361 const char *LinkingOutput =
nullptr;
5363 LinkingOutput = FinalOutput->getValue();
5370 using namespace llvm;
5373 <<
"output=" << LinkingOutput;
5374 outs() <<
", total="
5375 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5377 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5378 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5382 llvm::raw_string_ostream Out(Buffer);
5383 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5386 llvm::sys::printArg(Out, LinkingOutput,
true);
5387 Out <<
',' << ProcStat->TotalTime.count() <<
','
5388 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5393 llvm::sys::fs::OF_Append |
5394 llvm::sys::fs::OF_Text);
5399 llvm::errs() <<
"ERROR: Cannot lock file "
5401 <<
toString(L.takeError()) <<
"\n";
5412 bool ReportUnusedArguments =
5413 !Diags.hasErrorOccurred() &&
5414 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5417 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5419 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5422 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5423 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5425 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5429 return strstr(J.getCreator().getShortName(),
"assembler");
5431 for (Arg *A :
C.getArgs()) {
5435 if (!A->isClaimed()) {
5441 const Option &Opt = A->getOption();
5442 if (Opt.getKind() == Option::FlagClass) {
5443 bool DuplicateClaimed =
false;
5445 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5446 if (AA->isClaimed()) {
5447 DuplicateClaimed =
true;
5452 if (DuplicateClaimed)
5458 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5460 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5465 !
C.getActions().empty()) {
5466 Diag(diag::err_drv_unsupported_opt_for_target)
5468 }
else if (ReportUnusedArguments) {
5469 Diag(clang::diag::warn_drv_unused_argument)
5470 << A->getAsString(
C.getArgs());
5480class ToolSelector final {
5491 bool IsHostSelector;
5502 bool CanBeCollapsed =
true) {
5504 if (Inputs.size() != 1)
5507 Action *CurAction = *Inputs.begin();
5508 if (CanBeCollapsed &&
5514 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5518 if (!IsHostSelector) {
5519 if (OA->hasSingleDeviceDependence(
true)) {
5521 OA->getSingleDeviceDependence(
true);
5522 if (CanBeCollapsed &&
5525 SavedOffloadAction.push_back(OA);
5526 return dyn_cast<JobAction>(CurAction);
5528 }
else if (OA->hasHostDependence()) {
5529 CurAction = OA->getHostDependence();
5530 if (CanBeCollapsed &&
5533 SavedOffloadAction.push_back(OA);
5534 return dyn_cast<JobAction>(CurAction);
5539 return dyn_cast<JobAction>(CurAction);
5543 bool canCollapseAssembleAction()
const {
5544 return TC.useIntegratedAs() && !SaveTemps &&
5545 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5546 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5547 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5548 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5552 bool canCollapsePreprocessorAction()
const {
5553 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5554 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5555 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5560 struct JobActionInfo final {
5562 const JobAction *JA =
nullptr;
5570 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5571 ArrayRef<JobActionInfo> &ActionInfo,
5572 unsigned ElementNum) {
5573 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5574 for (
unsigned I = 0; I < ElementNum; ++I)
5575 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5576 ActionInfo[I].SavedOffloadAction.end());
5589 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5592 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5594 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5595 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5596 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5597 if (!AJ || !BJ || !CJ)
5601 const Tool *
T = TC.SelectTool(*CJ);
5608 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5614 const Tool *BT = TC.SelectTool(*BJ);
5619 if (!
T->hasIntegratedAssembler())
5622 Inputs = CJ->getInputs();
5623 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5627 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5630 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5632 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5633 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5638 const Tool *
T = TC.SelectTool(*BJ);
5642 if (!
T->hasIntegratedAssembler())
5645 Inputs = BJ->getInputs();
5646 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5650 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5653 if (ActionInfo.size() < 2)
5655 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5656 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5660 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5661 for (
auto &Input : AI.JA->getInputs())
5672 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5673 if (SaveTemps && !InputIsBitcode)
5677 const Tool *
T = TC.SelectTool(*CJ);
5684 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5690 Inputs = CJ->getInputs();
5691 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5700 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5702 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5708 for (Action *A : Inputs) {
5709 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5711 NewInputs.push_back(A);
5717 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5718 PreprocessJobOffloadActions.end());
5719 NewInputs.append(PJ->input_begin(), PJ->input_end());
5725 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5727 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5729 assert(BaseAction &&
"Invalid base action.");
5745 SmallVector<JobActionInfo, 5> ActionChain(1);
5746 ActionChain.back().JA = BaseAction;
5747 while (ActionChain.back().JA) {
5748 const Action *CurAction = ActionChain.back().JA;
5751 ActionChain.resize(ActionChain.size() + 1);
5752 JobActionInfo &AI = ActionChain.back();
5756 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5760 ActionChain.pop_back();
5768 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5769 CollapsedOffloadAction);
5771 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5773 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5779 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5791 StringRef BoundArch,
5793 std::string TriplePlusArch = TC->
getTriple().normalize();
5794 if (!BoundArch.empty()) {
5795 TriplePlusArch +=
"-";
5796 TriplePlusArch += BoundArch;
5798 TriplePlusArch +=
"-";
5800 return TriplePlusArch;
5805 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5806 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5809 std::pair<const Action *, std::string> ActionTC = {
5811 auto CachedResult = CachedResults.find(ActionTC);
5812 if (CachedResult != CachedResults.end()) {
5813 return CachedResult->second;
5816 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5817 CachedResults, TargetDeviceOffloadKind);
5818 CachedResults[ActionTC] =
Result;
5823 const JobAction *JA,
const char *BaseInput,
5826 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5830 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5831 Path = A->getValue();
5832 if (llvm::sys::fs::is_directory(Path)) {
5834 llvm::sys::path::replace_extension(Tmp,
"json");
5835 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5838 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5841 Path = DumpDir->getValue();
5842 Path += llvm::sys::path::filename(BaseInput);
5844 Path = Result.getFilename();
5846 llvm::sys::path::replace_extension(Path,
"json");
5848 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5849 C.addTimeTraceFile(ResultFile, JA);
5850 C.addResultFile(ResultFile, JA);
5855 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5856 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5859 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5862 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5863 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5895 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5897 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5898 const char *DepBoundArch) {
5901 LinkingOutput, CachedResults,
5911 OA->doOnEachDependence(
5912 BuildingForOffloadDevice,
5913 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5915 C, DepA, DepTC, DepBoundArch,
false,
5916 !!DepBoundArch, LinkingOutput, CachedResults,
5920 A = BuildingForOffloadDevice
5921 ? OA->getSingleDeviceDependence(
true)
5922 : OA->getHostDependence();
5926 std::pair<const Action *, std::string> ActionTC = {
5927 OA->getHostDependence(),
5929 auto It = CachedResults.find(ActionTC);
5930 if (It != CachedResults.end()) {
5932 Inputs.append(OffloadDependencesInputInfo);
5937 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5940 const Arg &Input = IA->getInputArg();
5942 if (Input.getOption().matches(options::OPT_INPUT)) {
5943 const char *
Name = Input.getValue();
5946 return {InputInfo(A, &Input,
"")};
5949 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5950 const ToolChain *TC;
5953 if (!ArchName.empty())
5954 TC = &getToolChain(
C.getArgs(),
5956 C.getArgs(), ArchName));
5958 TC = &
C.getDefaultToolChain();
5961 MultipleArchs, LinkingOutput, CachedResults,
5962 TargetDeviceOffloadKind);
5973 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5976 return {InputInfo()};
5980 for (
const auto *OA : CollapsedOffloadActions)
5982 BuildingForOffloadDevice,
5983 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5985 C, DepA, DepTC, DepBoundArch,
false,
5986 !!DepBoundArch, LinkingOutput, CachedResults,
5992 for (
const Action *Input : Inputs) {
5996 bool SubJobAtTopLevel =
5999 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6004 const char *BaseInput = InputInfos[0].getBaseInput();
6005 for (
auto &Info : InputInfos) {
6006 if (Info.isFilename()) {
6007 BaseInput = Info.getBaseInput();
6014 if (JA->
getType() == types::TY_dSYM)
6015 BaseInput = InputInfos[0].getFilename();
6018 if (!OffloadDependencesInputInfo.empty())
6019 InputInfos.append(OffloadDependencesInputInfo.begin(),
6020 OffloadDependencesInputInfo.end());
6023 llvm::Triple EffectiveTriple;
6024 const ToolChain &ToolTC =
T->getToolChain();
6025 const ArgList &Args =
6027 if (InputInfos.size() != 1) {
6031 EffectiveTriple = llvm::Triple(
6034 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6039 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6043 for (
auto &UI : UA->getDependentActionsInfo()) {
6045 "Unbundling with no offloading??");
6052 UI.DependentOffloadKind,
6053 UI.DependentToolChain->getTriple().normalize(),
6055 auto CurI = InputInfo(
6064 UnbundlingResults.push_back(CurI);
6073 Arch = UI.DependentBoundArch;
6078 UI.DependentOffloadKind)}] = {
6084 std::pair<const Action *, std::string> ActionTC = {
6086 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6087 "Result does not exist??");
6088 Result = CachedResults[ActionTC].front();
6089 }
else if (JA->
getType() == types::TY_Nothing)
6090 Result = {InputInfo(A, BaseInput)};
6100 AtTopLevel, MultipleArchs,
6103 if (
T->canEmitIR() && OffloadingPrefix.empty())
6108 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
6109 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6110 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6111 llvm::errs() << InputInfos[i].getAsString();
6113 llvm::errs() <<
", ";
6115 if (UnbundlingResults.empty())
6116 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6118 llvm::errs() <<
"], outputs: [";
6119 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6120 llvm::errs() << UnbundlingResults[i].getAsString();
6122 llvm::errs() <<
", ";
6124 llvm::errs() <<
"] \n";
6127 if (UnbundlingResults.empty())
6128 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6130 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6131 Args, LinkingOutput);
6137 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6138 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6150 if (ArgValue.empty()) {
6152 Filename = BaseName;
6153 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6155 llvm::sys::path::append(Filename, BaseName);
6158 if (!llvm::sys::path::has_extension(ArgValue)) {
6163 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6168 llvm::sys::path::replace_extension(Filename, Extension);
6171 return Args.MakeArgString(Filename.c_str());
6186 StringRef Suffix,
bool MultipleArchs,
6187 StringRef BoundArch,
6188 bool NeedUniqueDirectory)
const {
6190 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6191 std::optional<std::string> CrashDirectory =
6193 ? std::string(A->getValue())
6194 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6195 if (CrashDirectory) {
6196 if (!
getVFS().exists(*CrashDirectory))
6197 llvm::sys::fs::create_directories(*CrashDirectory);
6199 llvm::sys::path::append(Path, Prefix);
6200 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6201 if (std::error_code EC =
6202 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6203 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6207 if (MultipleArchs && !BoundArch.empty()) {
6208 if (NeedUniqueDirectory) {
6210 llvm::sys::path::append(TmpName,
6211 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6221 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6236 const char *BaseInput) {
6238 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6239 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6244 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6248 const char *BaseInput,
6249 StringRef OrigBoundArch,
bool AtTopLevel,
6251 StringRef OffloadingPrefix)
const {
6254 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6257 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6258 return C.addResultFile(FinalOutput->getValue(), &JA);
6262 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6264 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6266 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6267 NameArg = A->getValue();
6268 return C.addResultFile(
6278 if (JA.
getType() == types::TY_ModuleFile &&
6279 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6283 if (JA.
getType() == types::TY_PP_Asm &&
6284 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6285 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6288 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6291 if ((JA.
getType() == types::TY_Object &&
6292 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6293 JA.
getType() == types::TY_DX_CONTAINER) {
6294 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6298 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6300 C.getDefaultToolChain());
6303 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6304 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6305 StringRef
Name = llvm::sys::path::filename(BaseInput);
6306 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6312 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6313 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6317 if (JA.
getType() == types::TY_PP_Asm &&
6318 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6319 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6321 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6322 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6323 return C.addResultFile(
6328 if (JA.
getType() == types::TY_API_INFO &&
6329 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6330 C.getArgs().hasArg(options::OPT_o))
6331 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6332 <<
C.getArgs().getLastArgValue(options::OPT_o);
6339 bool SpecifiedModuleOutput =
6340 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6341 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6342 if (MultipleArchs && SpecifiedModuleOutput)
6343 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6348 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6349 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6355 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6357 StringRef
Name = llvm::sys::path::filename(BaseInput);
6358 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6359 const char *Suffix =
6364 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6365 bool NeedUniqueDirectory =
6368 Triple.isOSDarwin();
6369 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6370 NeedUniqueDirectory);
6379 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6384 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6385 llvm::sys::path::filename(BasePath));
6386 BaseName = ExternalPath;
6388 BaseName = BasePath;
6390 BaseName = llvm::sys::path::filename(BasePath);
6393 const char *NamedOutput;
6395 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6396 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6400 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6404 }
else if (JA.
getType() == types::TY_Image &&
6405 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6406 options::OPT__SLASH_o)) {
6410 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6414 }
else if (JA.
getType() == types::TY_Image) {
6424 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6425 options::OPT_fno_gpu_rdc,
false);
6427 if (UseOutExtension) {
6429 llvm::sys::path::replace_extension(Output,
"");
6431 Output += OffloadingPrefix;
6432 if (MultipleArchs && !BoundArch.empty()) {
6434 Output.append(BoundArch);
6436 if (UseOutExtension)
6438 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6441 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6442 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6443 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6446 .getLastArg(options::OPT__SLASH_o)
6451 const char *Suffix =
6453 assert(Suffix &&
"All types used for output should have a suffix.");
6455 std::string::size_type End = std::string::npos;
6457 End = BaseName.rfind(
'.');
6459 Suffixed += OffloadingPrefix;
6460 if (MultipleArchs && !BoundArch.empty()) {
6462 Suffixed.append(BoundArch);
6467 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6468 const llvm::opt::DerivedArgList &Args) {
6475 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6483 bool IsLinkerWrapper =
6485 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6486 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6487 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6489 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6493 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6497 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6498 JA.
getType() != types::TY_PCH) {
6499 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6501 llvm::sys::path::remove_filename(TempPath);
6502 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6503 llvm::sys::path::append(TempPath, OutputFileName);
6504 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6510 bool SameFile =
false;
6512 llvm::sys::fs::current_path(
Result);
6513 llvm::sys::path::append(
Result, BaseName);
6514 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6517 StringRef
Name = llvm::sys::path::filename(BaseInput);
6518 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6522 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6528 llvm::sys::path::remove_filename(BasePath);
6529 if (BasePath.empty())
6530 BasePath = NamedOutput;
6532 llvm::sys::path::append(BasePath, NamedOutput);
6533 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6536 return C.addResultFile(NamedOutput, &JA);
6542 -> std::optional<std::string> {
6545 for (
const auto &
Dir : P) {
6549 llvm::sys::path::append(P,
Name);
6550 if (llvm::sys::fs::exists(Twine(P)))
6551 return std::string(P);
6553 return std::nullopt;
6560 llvm::sys::path::append(R,
Name);
6561 if (llvm::sys::fs::exists(Twine(R)))
6562 return std::string(R);
6565 llvm::sys::path::append(P,
Name);
6566 if (llvm::sys::fs::exists(Twine(P)))
6567 return std::string(P);
6570 llvm::sys::path::append(D,
"..",
Name);
6571 if (llvm::sys::fs::exists(Twine(D)))
6572 return std::string(D);
6581 llvm::sys::path::append(R2,
"..",
"..",
Name);
6582 if (llvm::sys::fs::exists(Twine(R2)))
6583 return std::string(R2);
6585 return std::string(
Name);
6588void Driver::generatePrefixedToolNames(
6592 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6593 Names.emplace_back(
Tool);
6597 llvm::sys::path::append(Dir, Name);
6598 if (llvm::sys::fs::can_execute(Twine(Dir)))
6600 llvm::sys::path::remove_filename(Dir);
6606 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6611 if (llvm::sys::fs::is_directory(PrefixDir)) {
6614 return std::string(P);
6617 if (llvm::sys::fs::can_execute(Twine(P)))
6618 return std::string(P);
6623 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6631 for (
const auto &Path : List) {
6634 return std::string(P);
6638 if (llvm::ErrorOr<std::string> P =
6639 llvm::sys::findProgramByName(TargetSpecificExecutable))
6643 return std::string(
Name);
6648 std::string error =
"<NOT PRESENT>";
6650 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6655 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6672 llvm::sys::path::remove_filename(path);
6673 llvm::sys::path::append(path,
"libc++.modules.json");
6674 if (TC.
getVFS().exists(path))
6675 return static_cast<std::string
>(path);
6680 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6683 return evaluate(
"libc++.a").value_or(error);
6687 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6691 llvm::sys::path::remove_filename(path);
6692 llvm::sys::path::append(path,
"libstdc++.modules.json");
6693 if (TC.
getVFS().exists(path))
6694 return static_cast<std::string
>(path);
6699 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6702 return evaluate(
"libstdc++.a").value_or(error);
6711 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6713 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6717 return std::string(Path);
6722 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6724 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6728 return std::string(Path);
6733 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6737 Output = FpArg->getValue();
6741 if (!llvm::sys::path::has_extension(Output))
6744 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6745 Output = YcArg->getValue();
6748 llvm::sys::path::replace_extension(Output,
".pch");
6750 return std::string(Output);
6753const ToolChain &Driver::getOffloadToolChain(
6755 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6756 std::unique_ptr<ToolChain> &TC =
6757 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6758 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6760 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6763 switch (
Target.getOS()) {
6764 case llvm::Triple::CUDA:
6765 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6768 case llvm::Triple::AMDHSA:
6770 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6773 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6782 switch (
Target.getArch()) {
6783 case llvm::Triple::spir:
6784 case llvm::Triple::spir64:
6785 case llvm::Triple::spirv:
6786 case llvm::Triple::spirv32:
6787 case llvm::Triple::spirv64:
6790 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6794 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6798 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6802 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6816 return getToolChain(Args,
Target);
6820const ToolChain &Driver::getToolChain(
const ArgList &Args,
6821 const llvm::Triple &
Target)
const {
6823 auto &TC = ToolChains[
Target.str()];
6825 switch (
Target.getOS()) {
6826 case llvm::Triple::AIX:
6827 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6829 case llvm::Triple::Haiku:
6830 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6832 case llvm::Triple::Darwin:
6833 case llvm::Triple::MacOSX:
6834 case llvm::Triple::IOS:
6835 case llvm::Triple::TvOS:
6836 case llvm::Triple::WatchOS:
6837 case llvm::Triple::XROS:
6838 case llvm::Triple::DriverKit:
6839 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6841 case llvm::Triple::DragonFly:
6842 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6844 case llvm::Triple::OpenBSD:
6845 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6847 case llvm::Triple::NetBSD:
6848 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6850 case llvm::Triple::FreeBSD:
6852 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6855 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6857 case llvm::Triple::Linux:
6858 case llvm::Triple::ELFIAMCU:
6859 if (
Target.getArch() == llvm::Triple::hexagon)
6860 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6862 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6863 !
Target.hasEnvironment())
6864 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6867 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6869 else if (
Target.getArch() == llvm::Triple::ve)
6870 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6871 else if (
Target.isOHOSFamily())
6872 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6873 else if (
Target.isWALI())
6874 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6876 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6878 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6880 case llvm::Triple::Fuchsia:
6881 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6883 case llvm::Triple::Managarm:
6884 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6886 case llvm::Triple::Solaris:
6887 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6889 case llvm::Triple::CUDA:
6890 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6892 case llvm::Triple::AMDHSA: {
6893 if (
Target.getArch() == llvm::Triple::spirv64) {
6894 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6899 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6901 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6906 case llvm::Triple::AMDPAL:
6907 case llvm::Triple::Mesa3D:
6908 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6910 case llvm::Triple::UEFI:
6911 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6913 case llvm::Triple::Win32:
6914 switch (
Target.getEnvironment()) {
6916 if (
Target.isOSBinFormatELF())
6917 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6918 else if (
Target.isOSBinFormatMachO())
6919 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6921 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6923 case llvm::Triple::GNU:
6924 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6926 case llvm::Triple::Cygnus:
6927 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6929 case llvm::Triple::Itanium:
6930 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6933 case llvm::Triple::MSVC:
6934 case llvm::Triple::UnknownEnvironment:
6935 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6936 .starts_with_insensitive(
"bfd"))
6937 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6941 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6945 case llvm::Triple::PS4:
6946 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6948 case llvm::Triple::PS5:
6949 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6951 case llvm::Triple::Hurd:
6952 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6954 case llvm::Triple::LiteOS:
6955 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6957 case llvm::Triple::ZOS:
6958 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6960 case llvm::Triple::Vulkan:
6961 case llvm::Triple::ShaderModel:
6962 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6967 switch (
Target.getArch()) {
6968 case llvm::Triple::tce:
6969 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6971 case llvm::Triple::tcele:
6972 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6974 case llvm::Triple::hexagon:
6975 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6978 case llvm::Triple::lanai:
6979 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6981 case llvm::Triple::xcore:
6982 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6984 case llvm::Triple::wasm32:
6985 case llvm::Triple::wasm64:
6986 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6988 case llvm::Triple::avr:
6989 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6991 case llvm::Triple::msp430:
6992 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6994 case llvm::Triple::riscv32:
6995 case llvm::Triple::riscv64:
6996 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6998 case llvm::Triple::ve:
6999 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7001 case llvm::Triple::spirv32:
7002 case llvm::Triple::spirv64:
7003 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7005 case llvm::Triple::csky:
7006 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7010 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7011 else if (
Target.isOSBinFormatELF())
7012 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7013 else if (
Target.isAppleMachO())
7014 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7015 else if (
Target.isOSBinFormatMachO())
7016 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7018 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7028 if (JA.
size() != 1 ||
7043 if (JA.
size() != 1 ||
7057 if (Args.hasArg(options::OPT_emit_static_lib))
7068 unsigned &Micro,
bool &HadExtra) {
7071 Major = Minor = Micro = 0;
7075 if (Str.consumeInteger(10, Major))
7079 if (!Str.consume_front(
"."))
7082 if (Str.consumeInteger(10, Minor))
7086 if (!Str.consume_front(
"."))
7089 if (Str.consumeInteger(10, Micro))
7107 unsigned CurDigit = 0;
7108 while (CurDigit < Digits.size()) {
7110 if (Str.consumeInteger(10, Digit))
7112 Digits[CurDigit] = Digit;
7115 if (!Str.consume_front(
"."))
7124llvm::opt::Visibility
7125Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7138const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7154 llvm_unreachable(
"Unhandled Mode");
7158 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7163 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7164 options::OPT_fno_save_optimization_record,
false))
7168 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7169 options::OPT_fno_save_optimization_record,
false))
7173 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7174 options::OPT_fno_save_optimization_record,
false))
7178 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7179 options::OPT_fno_save_optimization_record,
false))
7186 static StringRef OptName =
7188 llvm::StringRef Opt;
7189 for (StringRef Arg : Args) {
7190 if (!Arg.starts_with(OptName))
7196 return Opt.consume_front(OptName) ? Opt :
"";
7203 llvm::BumpPtrAllocator &Alloc,
7204 llvm::vfs::FileSystem *FS) {
7213 for (
const char *F : Args) {
7214 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7216 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7217 RSPQuoting = Windows;
7223 bool MarkEOLs = ClangCLMode;
7225 llvm::cl::TokenizerCallback Tokenizer;
7226 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7227 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7229 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7231 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7234 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7235 ECtx.setMarkEOLs(MarkEOLs);
7239 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7243 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7244 [](
const char *A) {
return A !=
nullptr; });
7245 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7248 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7249 Args.resize(newEnd - Args.begin());
7253 return llvm::Error::success();
7257 return SavedStrings.insert(S).first->getKeyData();
7291 llvm::StringSet<> &SavedStrings) {
7294 if (Edit[0] ==
'^') {
7295 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7296 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7297 Args.insert(Args.begin() + 1, Str);
7298 }
else if (Edit[0] ==
'+') {
7299 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7300 OS <<
"### Adding argument " << Str <<
" at end\n";
7301 Args.push_back(Str);
7302 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7303 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7304 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7305 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7306 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7308 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7310 if (Args[i] ==
nullptr)
7312 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7314 if (Repl != Args[i]) {
7315 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7319 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7320 auto Option = Edit.substr(1);
7321 for (
unsigned i = 1; i < Args.size();) {
7322 if (Option == Args[i]) {
7323 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7324 Args.erase(Args.begin() + i);
7325 if (Edit[0] ==
'X') {
7326 if (i < Args.size()) {
7327 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7328 Args.erase(Args.begin() + i);
7330 OS <<
"### Invalid X edit, end of command line!\n";
7335 }
else if (Edit[0] ==
'O') {
7336 for (
unsigned i = 1; i < Args.size();) {
7337 const char *A = Args[i];
7341 if (A[0] ==
'-' && A[1] ==
'O' &&
7342 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7343 (
'0' <= A[2] && A[2] <=
'9'))))) {
7344 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7345 Args.erase(Args.begin() + i);
7349 OS <<
"### Adding argument " << Edit <<
" at end\n";
7350 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7352 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7357 const char *OverrideStr,
7358 llvm::StringSet<> &SavedStrings,
7359 StringRef EnvVar, raw_ostream *OS) {
7361 OS = &llvm::nulls();
7363 if (OverrideStr[0] ==
'#') {
7365 OS = &llvm::nulls();
7368 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7372 const char *S = OverrideStr;
7374 const char *End = ::strchr(S,
' ');
7376 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)
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 llvm::DenseSet< llvm::StringRef > inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
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 Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
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 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)
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static bool hasFlag(SVal val, ProgramStateRef state)
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
SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
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
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.
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
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.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
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.
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)
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.
const FunctionProtoType * T
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)
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.