58#include "clang/Config/config.h"
70#include "llvm/ADT/ArrayRef.h"
71#include "llvm/ADT/STLExtras.h"
72#include "llvm/ADT/SmallSet.h"
73#include "llvm/ADT/StringExtras.h"
74#include "llvm/ADT/StringRef.h"
75#include "llvm/ADT/StringSet.h"
76#include "llvm/ADT/StringSwitch.h"
77#include "llvm/Config/llvm-config.h"
78#include "llvm/MC/TargetRegistry.h"
79#include "llvm/Option/Arg.h"
80#include "llvm/Option/ArgList.h"
81#include "llvm/Option/OptSpecifier.h"
82#include "llvm/Option/OptTable.h"
83#include "llvm/Option/Option.h"
84#include "llvm/Support/CommandLine.h"
85#include "llvm/Support/ErrorHandling.h"
86#include "llvm/Support/ExitCodes.h"
87#include "llvm/Support/FileSystem.h"
88#include "llvm/Support/FileUtilities.h"
89#include "llvm/Support/FormatVariadic.h"
90#include "llvm/Support/MD5.h"
91#include "llvm/Support/Path.h"
92#include "llvm/Support/PrettyStackTrace.h"
93#include "llvm/Support/Process.h"
94#include "llvm/Support/Program.h"
95#include "llvm/Support/Regex.h"
96#include "llvm/Support/StringSaver.h"
97#include "llvm/Support/VirtualFileSystem.h"
98#include "llvm/Support/raw_ostream.h"
99#include "llvm/TargetParser/Host.h"
100#include "llvm/TargetParser/RISCVISAInfo.h"
112using namespace clang;
115template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
116 return llvm::any_of(Args, [&](Arg *A) {
117 return (A->getOption().matches(options::OPT_x) &&
119 (A->getOption().getKind() == Option::InputClass &&
120 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
122 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
133 StringRef
Dir = llvm::sys::path::parent_path(BinaryPath);
136 StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
137 if (!ConfiguredResourceDir.empty()) {
140 if (llvm::sys::path::is_absolute(ConfiguredResourceDir))
141 P = ConfiguredResourceDir;
143 llvm::sys::path::append(
P, ConfiguredResourceDir);
150 P = llvm::sys::path::parent_path(
Dir);
153 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
154 CLANG_VERSION_MAJOR_STRING);
157 return std::string(
P);
161 : UseCUID(
Kind::Hash) {
162 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
163 StringRef UseCUIDStr = A->getValue();
164 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
170 D.Diag(clang::diag::err_drv_invalid_value)
171 << A->getAsString(Args) << UseCUIDStr;
174 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
175 if (!FixedCUID.empty())
180 llvm::opt::DerivedArgList &Args)
const {
181 std::string CUID = FixedCUID.str();
184 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
188 llvm::MD5::MD5Result
Hash;
189 Hasher.update(InputFile);
190 for (
auto *A : Args) {
191 if (A->getOption().matches(options::OPT_INPUT))
193 Hasher.update(A->getAsString(Args));
196 CUID = llvm::utohexstr(
Hash.low(),
true);
204 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
205 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
208 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
209 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
210 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
211 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
212 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
213 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
214 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
217 this->VFS = llvm::vfs::getRealFileSystem();
222 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
225 llvm::sys::path::append(
P,
SysRoot);
229#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
230 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
234 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
235 llvm::sys::path::remove_dots(configFileDir,
true);
239#if defined(CLANG_CONFIG_FILE_USER_DIR)
242 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
251void Driver::setDriverMode(StringRef
Value) {
252 static StringRef OptName =
253 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
254 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
255 .Case(
"gcc", GCCMode)
256 .Case(
"g++", GXXMode)
257 .Case(
"cpp", CPPMode)
259 .Case(
"flang", FlangMode)
260 .Case(
"dxc", DXCMode)
264 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
269 bool &ContainsError)
const {
270 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
271 ContainsError =
false;
273 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
274 unsigned MissingArgIndex, MissingArgCount;
275 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
276 MissingArgCount, VisibilityMask);
279 if (MissingArgCount) {
280 Diag(diag::err_drv_missing_argument)
281 << Args.getArgString(MissingArgIndex) << MissingArgCount;
288 for (
const Arg *A : Args) {
290 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
298 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
299 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
301 diag::warn_drv_empty_joined_argument,
306 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
308 auto ArgString = A->getAsString(Args);
310 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
312 getOpts().findExact(ArgString, Nearest,
314 DiagID = diag::err_drv_unknown_argument_with_suggestion;
315 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
317 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
318 : diag::err_drv_unknown_argument;
319 Diags.
Report(DiagID) << ArgString;
323 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
324 : diag::err_drv_unknown_argument_with_suggestion;
325 Diags.
Report(DiagID) << ArgString << Nearest;
331 for (
const Arg *A : Args.filtered(options::OPT_o)) {
332 if (ArgStrings[A->getIndex()] == A->getSpelling())
336 std::string ArgString = ArgStrings[A->getIndex()];
338 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
339 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
340 << A->getAsString(Args) << Nearest;
350 Arg **FinalPhaseArg)
const {
351 Arg *PhaseArg =
nullptr;
355 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
365 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
368 options::OPT_fmodule_header_EQ))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
374 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
378 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
379 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
380 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
381 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
385 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
389 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
392 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
400 *FinalPhaseArg = PhaseArg;
408 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
409 llvm::sys::fs::OF_Text);
410 llvm::FileRemover OutputRemover(OutputFile.c_str());
411 std::optional<llvm::StringRef> Redirects[] = {
417 std::string ErrorMessage;
418 int SecondsToWait = 60;
419 if (std::optional<std::string> Str =
420 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
421 if (!llvm::to_integer(*Str, SecondsToWait))
422 return llvm::createStringError(std::error_code(),
423 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
424 "an integer, got '" +
426 SecondsToWait = std::max(SecondsToWait, 0);
428 StringRef Executable = Args[0];
429 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
431 return llvm::createStringError(std::error_code(),
432 Executable +
": " + ErrorMessage);
434 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
435 llvm::MemoryBuffer::getFile(OutputFile.c_str());
437 return llvm::createStringError(OutputBuf.getError(),
438 "Failed to read stdout of " + Executable +
439 ": " + OutputBuf.getError().message());
440 return std::move(*OutputBuf);
444 StringRef
Value,
bool Claim =
true) {
445 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
446 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
447 Args.AddSynthesizedArg(A);
453DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
454 const llvm::opt::OptTable &Opts =
getOpts();
455 DerivedArgList *DAL =
new DerivedArgList(Args);
457 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
458 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
459 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
460 bool IgnoreUnused =
false;
461 for (Arg *A : Args) {
465 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
469 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
470 IgnoreUnused =
false;
480 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
481 A->getOption().matches(options::OPT_Xlinker)) &&
482 A->containsValue(
"--no-demangle")) {
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
487 for (StringRef Val : A->getValues())
488 if (Val !=
"--no-demangle")
489 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
497 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
498 A->getNumValues() > 0 &&
499 (A->getValue(0) == StringRef(
"-MD") ||
500 A->getValue(0) == StringRef(
"-MMD"))) {
502 if (A->getValue(0) == StringRef(
"-MD"))
503 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
505 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
506 if (A->getNumValues() == 2)
507 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
512 if (A->getOption().matches(options::OPT_l)) {
513 StringRef
Value = A->getValue();
516 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
518 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
523 if (
Value ==
"cc_kext") {
524 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
530 if (A->getOption().matches(options::OPT__DASH_DASH)) {
532 for (StringRef Val : A->getValues())
541 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
542 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
545 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
546 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
550#if defined(HOST_LINK_VERSION)
551 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
552 strlen(HOST_LINK_VERSION) > 0) {
553 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
555 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
563 StringRef ArgTarget) {
565 static bool BeSilent =
false;
566 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
567 return ((v < 2) || ((v == 2) && (r < 4)));
571 if (ArgTarget.equals_insensitive(
"CURRENT")) {
575 unsigned int Version = 0;
576 unsigned int Release = 0;
577 unsigned int Modification = 0;
579 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
580 llvm::Regex HexRegex(
583 "([0-9a-fA-F][0-9a-fA-F])"
584 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
587 if (ZOsvRegex.match(ArgTarget, &Matches)) {
588 Matches[1].getAsInteger(10, Version);
589 Matches[2].getAsInteger(10, Release);
591 if (IsTooOldToBeSupported(Version, Release)) {
593 D.Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
596 }
else if (HexRegex.match(ArgTarget, &Matches)) {
597 Matches[1].getAsInteger(16, Version);
598 Matches[2].getAsInteger(16, Release);
599 Matches[3].getAsInteger(16, Modification);
600 if (IsTooOldToBeSupported(Version, Release)) {
602 D.Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
608 D.Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
613 llvm::VersionTuple
V(Version, Release, Modification);
614 llvm::VersionTuple TV =
Target.getOSVersion();
617 if (TV.empty() ||
V < TV) {
619 Str = llvm::Triple::getOSTypeName(
Target.getOS());
620 Str +=
V.getAsString();
633 StringRef TargetTriple,
635 StringRef DarwinArchName =
"") {
637 if (
const Arg *A = Args.getLastArg(options::OPT_target))
638 TargetTriple = A->getValue();
640 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
645 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
649 if (
Target.isOSBinFormatMachO()) {
651 if (!DarwinArchName.empty()) {
658 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
666 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
667 options::OPT_mbig_endian)) {
668 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
669 ?
Target.getLittleEndianArchVariant()
670 :
Target.getBigEndianArchVariant();
671 if (
T.getArch() != llvm::Triple::UnknownArch) {
673 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
678 if (
Target.getArch() == llvm::Triple::tce)
683 if (std::optional<std::string> ObjectModeValue =
684 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
685 StringRef ObjectMode = *ObjectModeValue;
686 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
688 if (ObjectMode ==
"64") {
689 AT =
Target.get64BitArchVariant().getArch();
690 }
else if (ObjectMode ==
"32") {
691 AT =
Target.get32BitArchVariant().getArch();
693 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
696 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
702 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
703 D.Diag(diag::err_target_unknown_triple) <<
Target.str();
706 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
708 D.Diag(diag::err_drv_unsupported_opt_for_target)
709 << A->getAsString(Args) <<
Target.str();
712 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
713 options::OPT_m32, options::OPT_m16,
714 options::OPT_maix32, options::OPT_maix64);
716 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
718 if (A->getOption().matches(options::OPT_m64) ||
719 A->getOption().matches(options::OPT_maix64)) {
720 AT =
Target.get64BitArchVariant().getArch();
721 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
722 Target.getEnvironment() == llvm::Triple::GNUT64)
723 Target.setEnvironment(llvm::Triple::GNU);
724 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
725 Target.setEnvironment(llvm::Triple::Musl);
726 }
else if (A->getOption().matches(options::OPT_mx32) &&
727 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
728 AT = llvm::Triple::x86_64;
729 if (
Target.getEnvironment() == llvm::Triple::Musl)
730 Target.setEnvironment(llvm::Triple::MuslX32);
732 Target.setEnvironment(llvm::Triple::GNUX32);
733 }
else if (A->getOption().matches(options::OPT_m32) ||
734 A->getOption().matches(options::OPT_maix32)) {
735 if (
D.IsFlangMode() && !
Target.isOSAIX()) {
736 D.Diag(diag::err_drv_unsupported_opt_for_target)
737 << A->getAsString(Args) <<
Target.str();
739 AT =
Target.get32BitArchVariant().getArch();
740 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
741 Target.setEnvironment(llvm::Triple::GNU);
742 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
743 Target.setEnvironment(llvm::Triple::Musl);
745 }
else if (A->getOption().matches(options::OPT_m16) &&
746 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
747 AT = llvm::Triple::x86;
748 Target.setEnvironment(llvm::Triple::CODE16);
751 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
753 if (
Target.isWindowsGNUEnvironment())
759 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
765 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
766 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
767 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
770 if (A && !A->getOption().matches(options::OPT_m32))
771 D.Diag(diag::err_drv_argument_not_allowed_with)
772 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
774 Target.setArch(llvm::Triple::x86);
775 Target.setArchName(
"i586");
776 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
777 Target.setEnvironmentName(
"");
778 Target.setOS(llvm::Triple::ELFIAMCU);
779 Target.setVendor(llvm::Triple::UnknownVendor);
780 Target.setVendorName(
"intel");
786 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
787 StringRef ABIName = A->getValue();
788 if (ABIName ==
"32") {
790 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
791 Target.getEnvironment() == llvm::Triple::GNUABIN32)
792 Target.setEnvironment(llvm::Triple::GNU);
793 }
else if (ABIName ==
"n32") {
795 if (
Target.getEnvironment() == llvm::Triple::GNU ||
796 Target.getEnvironment() == llvm::Triple::GNUT64 ||
797 Target.getEnvironment() == llvm::Triple::GNUABI64)
798 Target.setEnvironment(llvm::Triple::GNUABIN32);
799 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
800 Target.getEnvironment() == llvm::Triple::MuslABI64)
801 Target.setEnvironment(llvm::Triple::MuslABIN32);
802 }
else if (ABIName ==
"64") {
804 if (
Target.getEnvironment() == llvm::Triple::GNU ||
805 Target.getEnvironment() == llvm::Triple::GNUT64 ||
806 Target.getEnvironment() == llvm::Triple::GNUABIN32)
807 Target.setEnvironment(llvm::Triple::GNUABI64);
808 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
809 Target.getEnvironment() == llvm::Triple::MuslABIN32)
810 Target.setEnvironment(llvm::Triple::MuslABI64);
818 if (Args.hasArg(options::OPT_march_EQ) ||
819 Args.hasArg(options::OPT_mcpu_EQ)) {
821 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
823 if (!llvm::errorToBool(ISAInfo.takeError())) {
824 unsigned XLen = (*ISAInfo)->getXLen();
826 Target.setArch(llvm::Triple::riscv32);
828 Target.setArch(llvm::Triple::riscv64);
840 OptSpecifier OptEq, OptSpecifier OptNeg) {
841 if (!Args.hasFlag(OptEq, OptNeg,
false))
844 const Arg *A = Args.getLastArg(OptEq);
845 StringRef LTOName = A->getValue();
853 D.Diag(diag::err_drv_unsupported_option_argument)
854 << A->getSpelling() << A->getValue();
861void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
863 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
865 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
866 options::OPT_fno_offload_lto);
869 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
870 options::OPT_fno_openmp_target_jit,
false)) {
871 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
872 options::OPT_fno_offload_lto))
874 Diag(diag::err_drv_incompatible_options)
875 << A->getSpelling() <<
"-fopenmp-target-jit";
882 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
884 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
886 RuntimeName = A->getValue();
888 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
896 Diag(diag::err_drv_unsupported_option_argument)
897 << A->getSpelling() << A->getValue();
900 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
909 StringRef Program =
C.getArgs().getLastArgValue(
910 options::OPT_offload_arch_tool_EQ,
"offload-arch");
913 if (llvm::ErrorOr<std::string> Executable =
914 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
917 Args.push_back(
"--only=amdgpu");
919 Args.push_back(
"--only=nvptx");
920 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
923 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
928 if ((*StdoutOrErr)->getBuffer().empty()) {
929 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
935 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
937 GPUArchs.push_back(
Arch.str());
939 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
946static llvm::DenseSet<llvm::StringRef>
948 std::set<std::string> Archs;
949 for (Arg *A :
C.getInputArgs()) {
950 for (StringRef
Arch : A->getValues()) {
951 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
952 if (
Arch ==
"native") {
954 Archs.insert(Str.str());
956 Archs.insert(
Arch.str());
958 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
962 Archs.erase(
Arch.str());
967 llvm::DenseSet<llvm::StringRef> Triples;
968 for (llvm::StringRef
Arch : Archs) {
975 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
977 return llvm::DenseSet<llvm::StringRef>();
980 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
982 return llvm::DenseSet<llvm::StringRef>();
986 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
988 return llvm::DenseSet<llvm::StringRef>();
991 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
992 <<
"offload" <<
Arch;
993 return llvm::DenseSet<llvm::StringRef>();
998 Triple =
"spirv64-amd-amdhsa";
1000 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
1001 ?
"nvptx64-nvidia-cuda"
1002 :
"nvptx-nvidia-cuda";
1004 Triple =
"amdgcn-amd-amdhsa";
1011 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1012 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1013 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1014 C.getArgs().MakeArgString(Triple.split(
"-").first),
1015 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1017 C.getArgs().append(A);
1018 C.getArgs().AddSynthesizedArg(A);
1019 Triples.insert(Triple);
1024 Triples.insert(
"amdgcn-amd-amdhsa");
1026 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1027 ?
"nvptx64-nvidia-cuda"
1028 :
"nvptx-nvidia-cuda");
1030 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1031 ?
"spirv64-unknown-unknown"
1032 :
"spirv32-unknown-unknown");
1035 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1036 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1043 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1044 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1046 llvm::any_of(Inputs,
1047 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1052 (llvm::any_of(Inputs,
1053 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1056 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1057 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1059 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1060 options::OPT_fno_sycl,
false);
1061 bool IsOpenMPOffloading =
1063 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1064 options::OPT_fno_openmp,
false) &&
1065 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1066 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1067 !(IsCuda || IsHIP))));
1069 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1070 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1075 for (
const auto &[Active, Kind] : ActiveKinds)
1080 if (Kinds.size() > 1) {
1081 Diag(clang::diag::err_drv_mix_offload)
1088 if (IsCuda || IsHIP)
1094 std::multiset<llvm::StringRef> Triples;
1095 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1096 std::vector<std::string> ArgValues =
1097 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1098 for (llvm::StringRef
Target : ArgValues)
1099 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1101 if (ArgValues.empty())
1102 Diag(clang::diag::warn_drv_empty_joined_argument)
1104 .getLastArg(options::OPT_offload_targets_EQ)
1105 ->getAsString(
C.getInputArgs());
1106 }
else if (Kinds.size() > 0) {
1109 Triples.insert(Derived.begin(), Derived.end());
1114 llvm::StringMap<StringRef> FoundNormalizedTriples;
1115 for (StringRef
Target : Triples) {
1120 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1128 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1129 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1130 Diag(clang::diag::err_drv_argument_not_allowed_with)
1131 << IncompatArg->getSpelling() <<
"-fsycl";
1139 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1140 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1144 std::string NormalizedName = TT.normalize();
1145 auto [TripleIt, Inserted] =
1146 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1148 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1149 <<
Target << TripleIt->second;
1153 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1154 C.getDefaultToolChain().getTriple());
1158 auto &CudaInstallation =
1160 if (CudaInstallation.isValid())
1161 CudaInstallation.WarnIfUnsupportedVersion();
1164 C.addOffloadDeviceToolChain(&TC, Kind);
1169bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1174 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1178 if (!PathLIBEnv.empty()) {
1179 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1180 if (llvm::sys::fs::is_directory(PathLIBEnv))
1181 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1182 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1183 return readConfigFile(CustomizationFile, ExpCtx);
1184 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1189 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1190 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1191 return readConfigFile(CustomizationFile, ExpCtx);
1201 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1202 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1203 Copy->getValues() = Opt->getValues();
1204 if (Opt->isClaimed())
1206 Copy->setOwnsValues(Opt->getOwnsValues());
1207 Opt->setOwnsValues(
false);
1209 if (Opt->getAlias()) {
1210 const Arg *Alias = Opt->getAlias();
1211 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1212 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1213 Args.getArgString(Index), Index);
1214 AliasCopy->getValues() = Alias->getValues();
1215 AliasCopy->setOwnsValues(
false);
1216 if (Alias->isClaimed())
1218 Copy->setAlias(std::move(AliasCopy));
1222bool Driver::readConfigFile(StringRef
FileName,
1223 llvm::cl::ExpansionContext &ExpCtx) {
1227 Diag(diag::err_drv_cannot_open_config_file)
1228 <<
FileName << Status.getError().message();
1231 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1232 Diag(diag::err_drv_cannot_open_config_file)
1233 <<
FileName <<
"not a regular file";
1239 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1240 Diag(diag::err_drv_cannot_read_config_file)
1247 for (
const char *Opt : NewCfgFileArgs) {
1249 if (Opt[0] ==
'$' && Opt[1])
1250 NewCfgTailArgs.push_back(Opt + 1);
1252 NewCfgHeadArgs.push_back(Opt);
1257 llvm::sys::path::native(CfgFileName);
1258 bool ContainErrors =
false;
1259 auto NewHeadOptions = std::make_unique<InputArgList>(
1263 auto NewTailOptions = std::make_unique<InputArgList>(
1270 for (Arg *A : *NewHeadOptions)
1272 for (Arg *A : *NewTailOptions)
1275 if (!CfgOptionsHead)
1276 CfgOptionsHead = std::move(NewHeadOptions);
1279 for (
auto *Opt : *NewHeadOptions)
1283 if (!CfgOptionsTail)
1284 CfgOptionsTail = std::move(NewTailOptions);
1287 for (
auto *Opt : *NewTailOptions)
1291 ConfigFiles.push_back(std::string(CfgFileName));
1295bool Driver::loadConfigFiles() {
1296 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1297 llvm::cl::tokenizeConfigFile);
1298 ExpCtx.setVFS(&
getVFS());
1302 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1305 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1306 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1311 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1313 llvm::sys::fs::expand_tilde(
1314 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1315 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1324 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1327 if (loadDefaultConfigFiles(ExpCtx))
1333 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1336 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1337 CfgFilePath.assign(CfgFileName);
1338 if (llvm::sys::path::is_relative(CfgFilePath)) {
1339 if (
getVFS().makeAbsolute(CfgFilePath)) {
1340 Diag(diag::err_drv_cannot_open_config_file)
1341 << CfgFilePath <<
"cannot get absolute path";
1345 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1347 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1348 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1349 if (!SearchDir.empty())
1350 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1355 if (readConfigFile(CfgFilePath, ExpCtx))
1366 llvm::Triple Triple, std::string Suffix) {
1368 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1372 VersionTuple OSVersion = Triple.getOSVersion();
1373 if (!OSVersion.getMinor().has_value())
1376 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1380 if (OSVersion.getMajor() != 0) {
1381 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1382 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1388 Triple.setOSName(BaseOSName);
1389 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1392bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1395 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1399 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1402 std::string RealMode = getExecutableForDriverMode(Mode);
1403 llvm::Triple Triple;
1412 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1413 PrefixTriple.isOSUnknown())
1414 Triple = PrefixTriple;
1418 llvm::Triple RealTriple =
1420 if (Triple.str().empty()) {
1421 Triple = RealTriple;
1422 assert(!Triple.str().empty());
1427 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1443 "-" + RealMode +
".cfg"))
1444 return readConfigFile(CfgFilePath, ExpCtx);
1448 if (TryModeSuffix) {
1451 return readConfigFile(CfgFilePath, ExpCtx);
1456 std::string CfgFileName = RealMode +
".cfg";
1457 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1458 if (readConfigFile(CfgFilePath, ExpCtx))
1460 }
else if (TryModeSuffix) {
1462 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1463 readConfigFile(CfgFilePath, ExpCtx))
1469 return readConfigFile(CfgFilePath, ExpCtx);
1477 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1486 if (!DriverMode.empty())
1487 setDriverMode(DriverMode);
1493 CLOptions = std::make_unique<InputArgList>(
1498 ContainsError = loadConfigFiles();
1499 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1500 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1504 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1506 if (HasConfigFileHead)
1507 for (
auto *Opt : *CLOptions)
1508 if (!Opt->getOption().matches(options::OPT_config))
1512 if (
IsCLMode() && !ContainsError) {
1514 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1516 CLModePassThroughArgList.push_back(A->getValue());
1519 if (!CLModePassThroughArgList.empty()) {
1522 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1527 for (
auto *Opt : *CLModePassThroughOptions)
1533 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1534 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1535 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1539 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1540 if (!VFS->exists(IncludeDir))
1541 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1546 bool CCCPrintPhases;
1549 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1550 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1553 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1554 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1557 Args.ClaimAllArgs(options::OPT_pipe);
1565 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1567 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1568 CCCGenericGCCName = A->getValue();
1571 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1575 if (Args.hasArg(options::OPT_fproc_stat_report))
1582 llvm::Triple
T(TargetTriple);
1583 T.setOS(llvm::Triple::Win32);
1584 T.setVendor(llvm::Triple::PC);
1585 T.setEnvironment(llvm::Triple::MSVC);
1586 T.setObjectFormat(llvm::Triple::COFF);
1587 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1588 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1589 TargetTriple =
T.str();
1592 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1593 StringRef TargetProfile = A->getValue();
1596 TargetTriple = *Triple;
1598 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1602 if (Args.hasArg(options::OPT_spirv)) {
1603 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1604 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1605 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1606 llvm::Triple
T(TargetTriple);
1609 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1611 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1612 TargetInfo = ValidTargets.find(A->getValue());
1614 Diag(diag::err_drv_invalid_value)
1615 << A->getAsString(Args) << A->getValue();
1621 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1622 TargetTriple =
T.str();
1626 Diag(diag::err_drv_dxc_missing_target_profile);
1630 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1631 TargetTriple = A->getValue();
1632 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1633 Dir =
Dir = A->getValue();
1634 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1638 if (std::optional<std::string> CompilerPathValue =
1639 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1640 StringRef CompilerPath = *CompilerPathValue;
1641 while (!CompilerPath.empty()) {
1642 std::pair<StringRef, StringRef> Split =
1643 CompilerPath.split(llvm::sys::EnvPathSeparator);
1644 PrefixDirs.push_back(std::string(Split.first));
1645 CompilerPath = Split.second;
1648 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1650 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1653 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1656 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1657 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1658 .Case(
"cwd", SaveTempsCwd)
1659 .Case(
"obj", SaveTempsObj)
1660 .Default(SaveTempsCwd);
1663 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1664 options::OPT_offload_device_only,
1665 options::OPT_offload_host_device)) {
1666 if (A->getOption().matches(options::OPT_offload_host_only))
1667 Offload = OffloadHost;
1668 else if (A->getOption().matches(options::OPT_offload_device_only))
1669 Offload = OffloadDevice;
1671 Offload = OffloadHostDevice;
1677 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1678 StringRef
Name = A->getValue();
1679 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1680 .Case(
"off", EmbedNone)
1681 .Case(
"all", EmbedBitcode)
1682 .Case(
"bitcode", EmbedBitcode)
1683 .Case(
"marker", EmbedMarker)
1686 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1689 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1693 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1694 llvm::sys::fs::remove(A->getValue());
1700 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1702 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1703 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1704 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1705 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1706 Std->containsValue(
"c++latest"));
1709 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1710 options::OPT_fmodule_header)) {
1712 ModulesModeCXX20 =
true;
1713 if (A->getOption().matches(options::OPT_fmodule_header))
1716 StringRef ArgName = A->getValue();
1717 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1722 Diags.
Report(diag::err_drv_invalid_value)
1723 << A->getAsString(Args) << ArgName;
1729 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1730 std::make_unique<InputArgList>(std::move(Args));
1740 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1741 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1743 bool MLContainsError;
1744 auto MultilibMacroDefineList =
1746 MLMacroDefinesChar,
false, MLContainsError));
1747 if (!MLContainsError) {
1748 for (
auto *Opt : *MultilibMacroDefineList) {
1755 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1759 if (!Triple.isWasm()) {
1760 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1761 StringRef TripleObjectFormat =
1762 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1763 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1764 TripleVersionName != TripleObjectFormat) {
1765 Diags.
Report(diag::err_drv_triple_version_invalid)
1767 ContainsError =
true;
1772 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1773 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1774 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1782 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1783 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1785 case llvm::Triple::arm:
1786 case llvm::Triple::armeb:
1787 case llvm::Triple::thumb:
1788 case llvm::Triple::thumbeb:
1789 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1790 Diag(diag::warn_target_unrecognized_env)
1792 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1795 case llvm::Triple::aarch64:
1796 case llvm::Triple::aarch64_be:
1797 case llvm::Triple::aarch64_32:
1798 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1799 Diag(diag::warn_target_unrecognized_env)
1801 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1818 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1819 if (HasConfigFileTail && Inputs.size()) {
1822 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1823 for (Arg *A : *CfgOptionsTail)
1824 TranslatedLinkerIns.append(A);
1825 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1834 if (TC.
getTriple().isOSBinFormatMachO())
1839 if (CCCPrintPhases) {
1850 llvm::opt::ArgStringList ASL;
1851 for (
const auto *A : Args) {
1855 while (A->getAlias())
1857 A->render(Args, ASL);
1860 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1861 if (I != ASL.begin())
1863 llvm::sys::printArg(OS, *I,
true);
1868bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1870 using namespace llvm::sys;
1871 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1872 "Only knows about .crash files on Darwin");
1877 path::home_directory(CrashDiagDir);
1878 if (CrashDiagDir.starts_with(
"/var/root"))
1880 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1888 fs::file_status FileStatus;
1889 TimePoint<> LastAccessTime;
1893 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1894 File != FileEnd && !EC;
File.increment(EC)) {
1898 if (fs::status(
File->path(), FileStatus))
1900 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1901 llvm::MemoryBuffer::getFile(
File->path());
1906 StringRef
Data = CrashFile.get()->getBuffer();
1907 if (!
Data.starts_with(
"Process:"))
1910 size_t ParentProcPos =
Data.find(
"Parent Process:");
1911 if (ParentProcPos == StringRef::npos)
1913 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1914 if (LineEnd == StringRef::npos)
1916 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1917 int OpenBracket = -1, CloseBracket = -1;
1918 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1919 if (ParentProcess[i] ==
'[')
1921 if (ParentProcess[i] ==
']')
1927 if (OpenBracket < 0 || CloseBracket < 0 ||
1928 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1929 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1939 const auto FileAccessTime = FileStatus.getLastModificationTime();
1940 if (FileAccessTime > LastAccessTime) {
1941 CrashFilePath.assign(
File->path());
1942 LastAccessTime = FileAccessTime;
1947 if (!CrashFilePath.empty()) {
1948 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1958 "\n********************\n\n"
1959 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1960 "Preprocessed source(s) and associated run script(s) are located at:";
1968 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1972 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1973 Level = llvm::StringSwitch<unsigned>(A->getValue())
1975 .Case(
"compiler", 1)
1987 ArgStringList SavedTemps;
1989 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1990 if (!IsLLD || Level < 2)
1997 SavedTemps = std::move(
C.getTempFiles());
1998 assert(!
C.getTempFiles().size());
2015 C.initCompilationForDiagnostics();
2021 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2022 StringRef ReproduceOption =
2023 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2026 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2030 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2032 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2033 Diag(clang::diag::note_drv_command_failed_diag_msg)
2034 <<
"\n\n********************";
2036 Report->TemporaryFiles.push_back(TmpName);
2044 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2045 bool IgnoreInput =
false;
2051 }
else if (!strcmp(it->second->getValue(),
"-")) {
2052 Diag(clang::diag::note_drv_command_failed_diag_msg)
2053 <<
"Error generating preprocessed source(s) - "
2054 "ignoring input from stdin.";
2059 it = Inputs.erase(it);
2066 if (Inputs.empty()) {
2067 Diag(clang::diag::note_drv_command_failed_diag_msg)
2068 <<
"Error generating preprocessed source(s) - "
2069 "no preprocessable inputs.";
2076 for (
const Arg *A :
C.getArgs()) {
2077 if (A->getOption().matches(options::OPT_arch)) {
2078 StringRef
ArchName = A->getValue();
2083 Diag(clang::diag::note_drv_command_failed_diag_msg)
2084 <<
"Error generating preprocessed source(s) - cannot generate "
2085 "preprocessed source with multiple -arch options.";
2091 const ToolChain &TC =
C.getDefaultToolChain();
2092 if (TC.
getTriple().isOSBinFormatMachO())
2101 Diag(clang::diag::note_drv_command_failed_diag_msg)
2102 <<
"Error generating preprocessed source(s).";
2108 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2111 if (!FailingCommands.empty()) {
2112 Diag(clang::diag::note_drv_command_failed_diag_msg)
2113 <<
"Error generating preprocessed source(s).";
2117 const ArgStringList &TempFiles =
C.getTempFiles();
2118 if (TempFiles.empty()) {
2119 Diag(clang::diag::note_drv_command_failed_diag_msg)
2120 <<
"Error generating preprocessed source(s).";
2128 for (
const char *TempFile : TempFiles) {
2129 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2131 Report->TemporaryFiles.push_back(TempFile);
2132 if (ReproCrashFilename.empty()) {
2133 ReproCrashFilename = TempFile;
2134 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2136 if (StringRef(TempFile).ends_with(
".cache")) {
2139 VFS = llvm::sys::path::filename(TempFile);
2140 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2144 for (
const char *TempFile : SavedTemps)
2145 C.addTempFile(TempFile);
2151 llvm::sys::path::replace_extension(Script,
"sh");
2153 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2154 llvm::sys::fs::FA_Write,
2155 llvm::sys::fs::OF_Text);
2157 Diag(clang::diag::note_drv_command_failed_diag_msg)
2158 <<
"Error generating run script: " << Script <<
" " << EC.message();
2161 <<
"# Driver args: ";
2163 ScriptOS <<
"# Original command: ";
2164 Cmd.Print(ScriptOS,
"\n",
true);
2165 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2166 if (!AdditionalInformation.empty())
2167 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2170 Report->TemporaryFiles.push_back(std::string(Script));
2171 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2175 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2177 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2178 Diag(clang::diag::note_drv_command_failed_diag_msg)
2179 << ReproCrashFilename.str();
2181 llvm::sys::path::append(CrashDiagDir,
Name);
2182 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2183 Diag(clang::diag::note_drv_command_failed_diag_msg)
2184 <<
"Crash backtrace is located in";
2185 Diag(clang::diag::note_drv_command_failed_diag_msg)
2186 << CrashDiagDir.str();
2187 Diag(clang::diag::note_drv_command_failed_diag_msg)
2188 <<
"(choose the .crash file that corresponds to your crash)";
2192 Diag(clang::diag::note_drv_command_failed_diag_msg)
2193 <<
"\n\n********************";
2201 if (
Cmd.getResponseFileSupport().ResponseKind ==
2203 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2204 Cmd.getArguments()))
2208 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
2214 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2215 if (
C.getArgs().hasArg(options::OPT_v))
2216 C.getJobs().Print(llvm::errs(),
"\n",
true);
2218 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2228 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2229 C.getJobs().Print(llvm::errs(),
"\n",
true);
2238 for (
auto &Job :
C.getJobs())
2239 setUpResponseFiles(
C, Job);
2241 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2244 if (FailingCommands.empty())
2250 for (
const auto &CmdPair : FailingCommands) {
2251 int CommandRes = CmdPair.first;
2252 const Command *FailingCommand = CmdPair.second;
2257 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2261 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2266 if (CommandRes == EX_IOERR) {
2283 Diag(clang::diag::err_drv_command_signalled)
2286 Diag(clang::diag::err_drv_command_failed)
2294 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2296 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2310 const ToolChain &TC =
C.getDefaultToolChain();
2314 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2317 OS <<
"Thread model: " << A->getValue();
2323 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2328 if (!llvm::cl::getCompilerBuildConfig().empty())
2329 llvm::cl::printBuildConfig(OS);
2332 for (
auto ConfigFile : ConfigFiles)
2333 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2346 if (PassedFlags ==
"")
2350 std::vector<std::string> SuggestedCompletions;
2351 std::vector<std::string> Flags;
2363 const bool HasSpace = PassedFlags.ends_with(
",");
2367 StringRef TargetFlags = PassedFlags;
2368 while (TargetFlags !=
"") {
2370 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2371 Flags.push_back(std::string(CurFlag));
2376 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2379 const llvm::opt::OptTable &Opts =
getOpts();
2381 Cur = Flags.at(Flags.size() - 1);
2383 if (Flags.size() >= 2) {
2384 Prev = Flags.at(Flags.size() - 2);
2385 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2388 if (SuggestedCompletions.empty())
2389 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2396 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2397 llvm::outs() <<
'\n';
2403 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2407 SuggestedCompletions = Opts.findByPrefix(
2408 Cur, VisibilityMask,
2415 if (S.starts_with(Cur))
2416 SuggestedCompletions.push_back(std::string(S));
2423 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2424 if (
int X = A.compare_insensitive(B))
2426 return A.compare(B) > 0;
2429 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2436 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2437 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2441 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2444 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2448 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2453 if (
C.getArgs().hasArg(options::OPT_help) ||
2454 C.getArgs().hasArg(options::OPT__help_hidden)) {
2455 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2459 if (
C.getArgs().hasArg(options::OPT__version)) {
2465 if (
C.getArgs().hasArg(options::OPT_v) ||
2466 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2467 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2468 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2469 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2471 SuppressMissingInputWarning =
true;
2474 if (
C.getArgs().hasArg(options::OPT_v)) {
2476 llvm::errs() <<
"System configuration file directory: "
2479 llvm::errs() <<
"User configuration file directory: "
2483 const ToolChain &TC =
C.getDefaultToolChain();
2485 if (
C.getArgs().hasArg(options::OPT_v))
2488 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2493 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2494 llvm::outs() <<
"programs: =";
2495 bool separator =
false;
2499 llvm::outs() << llvm::sys::EnvPathSeparator;
2500 llvm::outs() <<
Path;
2505 llvm::outs() << llvm::sys::EnvPathSeparator;
2506 llvm::outs() <<
Path;
2509 llvm::outs() <<
"\n";
2512 StringRef sysroot =
C.getSysRoot();
2516 llvm::outs() << llvm::sys::EnvPathSeparator;
2519 llvm::outs() << sysroot <<
Path.substr(1);
2521 llvm::outs() <<
Path;
2523 llvm::outs() <<
"\n";
2527 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2533 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2534 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2535 llvm::outs() << *RuntimePath <<
'\n';
2541 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2543 for (std::size_t I = 0; I != Flags.size(); I += 2)
2544 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2550 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2551 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2555 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2556 StringRef ProgName = A->getValue();
2559 if (! ProgName.empty())
2562 llvm::outs() <<
"\n";
2566 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2567 StringRef PassedFlags = A->getValue();
2572 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2586 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2589 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2595 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2602 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2605 std::set<llvm::StringRef> SortedFlags;
2606 for (
const auto &FlagEntry : ExpandedFlags)
2607 SortedFlags.insert(FlagEntry.getKey());
2608 for (
auto Flag : SortedFlags)
2609 llvm::outs() << Flag <<
'\n';
2613 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2616 llvm::outs() <<
".\n";
2619 assert(Suffix.front() ==
'/');
2620 llvm::outs() << Suffix.substr(1) <<
"\n";
2626 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2631 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2633 llvm::outs() << Triple.getTriple() <<
"\n";
2637 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2638 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2655 std::map<Action *, unsigned> &Ids,
2657 if (
auto It = Ids.find(A); It != Ids.end())
2661 llvm::raw_string_ostream os(str);
2663 auto getSibIndent = [](
int K) -> Twine {
2667 Twine SibIndent = Indent + getSibIndent(Kind);
2671 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2673 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2674 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2675 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2676 bool IsFirst =
true;
2677 OA->doOnEachDependence(
2679 assert(TC &&
"Unknown host toolchain");
2691 os <<
":" << BoundArch;
2694 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2702 const char *Prefix =
"{";
2703 for (
Action *PreRequisite : *AL) {
2704 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2715 std::string offload_str;
2716 llvm::raw_string_ostream offload_os(offload_str);
2717 if (!isa<OffloadAction>(A)) {
2720 offload_os <<
", (" << S;
2727 auto getSelfIndent = [](
int K) -> Twine {
2731 unsigned Id = Ids.size();
2733 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2742 std::map<Action *, unsigned> Ids;
2743 for (
Action *A :
C.getActions())
2750 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2751 isa<AssembleJobAction>(A))
2759 DerivedArgList &Args =
C.getArgs();
2761 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2766 for (Arg *A : Args) {
2767 if (A->getOption().matches(options::OPT_arch)) {
2770 llvm::Triple::ArchType
Arch =
2772 if (
Arch == llvm::Triple::UnknownArch) {
2773 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2778 if (
ArchNames.insert(A->getValue()).second)
2779 Archs.push_back(A->getValue());
2793 for (
Action* Act : SingleActions) {
2801 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2805 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2810 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2811 Actions.append(Inputs.begin(), Inputs.end());
2813 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2816 Arg *A = Args.getLastArg(options::OPT_g_Group);
2817 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2818 !A->getOption().matches(options::OPT_gstabs);
2826 if (Act->getType() == types::TY_Image) {
2828 Inputs.push_back(Actions.back());
2835 if (Args.hasArg(options::OPT_verify_debug_info)) {
2836 Action *LastAction = Actions.pop_back_val();
2838 LastAction, types::TY_Nothing));
2857 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2858 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2870 std::string Nearest;
2871 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2872 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2873 <<
Value << Nearest;
2912 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2915 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2923 return types::TY_CXXUHeader;
2925 return types::TY_CXXSHeader;
2929 llvm_unreachable(
"should not be called in this case");
2931 return types::TY_CXXHUHeader;
2937 const llvm::opt::OptTable &Opts =
getOpts();
2941 types::ID InputType = types::TY_Nothing;
2942 Arg *InputTypeArg =
nullptr;
2945 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2946 options::OPT__SLASH_TP)) {
2947 InputTypeArg = TCTP;
2948 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2953 bool ShowNote =
false;
2955 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2957 Diag(clang::diag::warn_drv_overriding_option)
2958 <<
Previous->getSpelling() << A->getSpelling();
2964 Diag(clang::diag::note_drv_t_option_is_global);
2969 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2970 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2971 if (LastXArg && LastInputArg &&
2972 LastInputArg->getIndex() < LastXArg->getIndex())
2973 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2976 for (Arg *A : Args) {
2977 if (A->getOption().
getKind() == Option::InputClass) {
2978 const char *
Value = A->getValue();
2982 if (InputType == types::TY_Nothing) {
2985 InputTypeArg->claim();
2988 if (memcmp(
Value,
"-", 2) == 0) {
2990 Ty = types::TY_Fortran;
2992 Ty = types::TY_HLSL;
3001 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3002 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3003 : clang::diag::err_drv_unknown_stdin_type);
3012 if (
const char *Ext = strrchr(
Value,
'.'))
3021 Ty = types::TY_HLSL;
3023 Ty = types::TY_Object;
3034 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3035 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3036 << getTypeName(OldTy) << getTypeName(Ty);
3041 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3042 Ty == types::TY_Object)
3043 Ty = types::TY_LLVM_BC;
3051 if (Ty != types::TY_Object) {
3052 if (Args.hasArg(options::OPT_ObjC))
3053 Ty = types::TY_ObjC;
3054 else if (Args.hasArg(options::OPT_ObjCXX))
3055 Ty = types::TY_ObjCXX;
3062 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3066 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3067 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3070 const char *Ext = strrchr(
Value,
'.');
3072 Ty = types::TY_Object;
3076 InputTypeArg->claim();
3080 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3081 Args.hasArgNoClaim(options::OPT_hipstdpar))
3085 Inputs.push_back(std::make_pair(Ty, A));
3087 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3088 StringRef
Value = A->getValue();
3091 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3092 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3095 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3096 StringRef
Value = A->getValue();
3099 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3100 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3106 Inputs.push_back(std::make_pair(types::TY_Object, A));
3108 }
else if (A->getOption().matches(options::OPT_x)) {
3117 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3118 InputType = types::TY_Object;
3125 }
else if (A->getOption().getID() == options::OPT_U) {
3126 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3127 StringRef Val = A->getValue(0);
3128 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3130 Diag(diag::warn_slash_u_filename) << Val;
3131 Diag(diag::note_use_dashdash);
3135 if (
CCCIsCPP() && Inputs.empty()) {
3139 Inputs.push_back(std::make_pair(types::TY_C, A));
3146class OffloadingActionBuilder final {
3148 bool IsValid =
false;
3154 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3157 std::map<Action *, const Arg *> HostActionToInputArgMap;
3160 class DeviceActionBuilder {
3164 enum ActionBuilderReturnCode {
3183 DerivedArgList &Args;
3192 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3195 :
C(
C), Args(Args), Inputs(Inputs),
3196 AssociatedOffloadKind(AssociatedOffloadKind) {}
3197 virtual ~DeviceActionBuilder() {}
3202 virtual ActionBuilderReturnCode
3206 return ABRT_Inactive;
3211 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3212 return ABRT_Inactive;
3216 virtual void appendTopLevelActions(
ActionList &AL) {}
3219 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3232 virtual bool canUseBundlerUnbundler()
const {
return false; }
3236 bool isValid() {
return !ToolChains.empty(); }
3240 return AssociatedOffloadKind;
3246 class CudaActionBuilderBase :
public DeviceActionBuilder {
3250 bool CompileHostOnly =
false;
3251 bool CompileDeviceOnly =
false;
3253 bool EmitAsm =
false;
3263 TargetID(
const char *
ID) :
ID(
ID) {}
3264 operator const char *() {
return ID; }
3265 operator StringRef() {
return StringRef(
ID); }
3274 Action *CudaFatBinary =
nullptr;
3277 bool IsActive =
false;
3280 bool Relocatable =
false;
3283 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3289 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3292 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3293 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3295 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3296 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3297 options::OPT_fno_gpu_rdc,
false);
3300 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3307 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3310 if (!(IA->getType() == types::TY_CUDA ||
3311 IA->getType() == types::TY_HIP ||
3312 IA->getType() == types::TY_PP_HIP)) {
3315 return ABRT_Inactive;
3322 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3324 if (CompileHostOnly)
3325 return ABRT_Success;
3328 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3329 : types::TY_CUDA_DEVICE;
3330 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3331 CudaDeviceActions.push_back(
3332 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3335 return ABRT_Success;
3339 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3343 if (UA->getType() == types::TY_Object && !Relocatable)
3344 return ABRT_Inactive;
3346 CudaDeviceActions.clear();
3347 auto *IA = cast<InputAction>(UA->getInputs().back());
3348 std::string
FileName = IA->getInputArg().getAsString(Args);
3354 const StringRef LibFileExt =
".lib";
3355 if (IA->getType() == types::TY_Object &&
3356 (!llvm::sys::path::has_extension(
FileName) ||
3358 llvm::sys::path::extension(
FileName).drop_front()) !=
3360 llvm::sys::path::extension(
FileName) == LibFileExt))
3361 return ABRT_Inactive;
3363 for (
auto Arch : GpuArchList) {
3364 CudaDeviceActions.push_back(UA);
3365 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3366 AssociatedOffloadKind);
3369 return ABRT_Success;
3372 return IsActive ? ABRT_Success : ABRT_Inactive;
3375 void appendTopLevelActions(
ActionList &AL)
override {
3377 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3379 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3384 if (CudaFatBinary) {
3385 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3386 CudaDeviceActions.clear();
3387 CudaFatBinary =
nullptr;
3391 if (CudaDeviceActions.empty())
3397 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3398 "Expecting one action per GPU architecture.");
3399 assert(ToolChains.size() == 1 &&
3400 "Expecting to have a single CUDA toolchain.");
3401 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3402 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3404 CudaDeviceActions.clear();
3407 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3425 assert(HostTC &&
"No toolchain for host compilation.");
3430 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3435 std::set<StringRef> GpuArchs;
3437 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(
Kind))) {
3438 ToolChains.push_back(I.second);
3441 C.getDriver().getOffloadArchs(
C,
C.getArgs(),
Kind, *I.second))
3442 GpuArchs.insert(
Arch);
3446 for (
auto Arch : GpuArchs)
3447 GpuArchList.push_back(
Arch.data());
3449 CompileHostOnly =
C.getDriver().offloadHostOnly();
3450 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3451 EmitAsm = Args.getLastArg(options::OPT_S);
3459 class CudaActionBuilder final :
public CudaActionBuilderBase {
3461 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3463 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3464 DefaultOffloadArch = OffloadArch::CudaDefault;
3467 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3469 const std::set<StringRef> &GpuArchs)
override {
3470 return std::nullopt;
3473 ActionBuilderReturnCode
3476 PhasesTy &Phases)
override {
3478 return ABRT_Inactive;
3482 if (CudaDeviceActions.empty())
3483 return ABRT_Success;
3485 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3486 "Expecting one action per GPU architecture.");
3487 assert(!CompileHostOnly &&
3488 "Not expecting CUDA actions in host-only compilation.");
3498 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3501 for (
auto Ph : Phases) {
3506 if (Ph > FinalPhase)
3509 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3519 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3523 Action *AssembleAction = CudaDeviceActions[I];
3524 assert(AssembleAction->
getType() == types::TY_Object);
3525 assert(AssembleAction->
getInputs().size() == 1);
3533 DeviceActions.push_back(
3539 if (!DeviceActions.empty()) {
3541 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3543 if (!CompileDeviceOnly) {
3544 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3548 CudaFatBinary =
nullptr;
3553 CudaDeviceActions.clear();
3557 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3562 return ABRT_Success;
3566 "instructions should only occur "
3567 "before the backend phase!");
3570 for (
Action *&A : CudaDeviceActions)
3571 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3573 return ABRT_Success;
3578 class HIPActionBuilder final :
public CudaActionBuilderBase {
3586 std::optional<bool> BundleOutput;
3587 std::optional<bool> EmitReloc;
3592 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3594 DefaultOffloadArch = OffloadArch::HIPDefault;
3596 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3597 options::OPT_fno_hip_emit_relocatable)) {
3598 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3599 options::OPT_fno_hip_emit_relocatable,
false);
3603 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3604 <<
"-fhip-emit-relocatable"
3608 if (!CompileDeviceOnly) {
3609 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3610 <<
"-fhip-emit-relocatable"
3611 <<
"--offload-device-only";
3616 if (Args.hasArg(options::OPT_gpu_bundle_output,
3617 options::OPT_no_gpu_bundle_output))
3618 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3619 options::OPT_no_gpu_bundle_output,
true) &&
3620 (!EmitReloc || !*EmitReloc);
3623 bool canUseBundlerUnbundler()
const override {
return true; }
3625 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3627 const std::set<StringRef> &GpuArchs)
override {
3631 ActionBuilderReturnCode
3634 PhasesTy &Phases)
override {
3636 return ABRT_Inactive;
3642 if (CudaDeviceActions.empty())
3643 return ABRT_Success;
3646 CudaDeviceActions.size() == GpuArchList.size()) &&
3647 "Expecting one action per GPU architecture.");
3648 assert(!CompileHostOnly &&
3649 "Not expecting HIP actions in host-only compilation.");
3651 bool ShouldLink = !EmitReloc || !*EmitReloc;
3654 !EmitAsm && ShouldLink) {
3660 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3661 if (
C.getDriver().isUsingOffloadLTO()) {
3665 AL.push_back(CudaDeviceActions[I]);
3668 CudaDeviceActions[I] =
3675 if (ToolChains.front()->getTriple().isSPIRV() ||
3676 (ToolChains.front()->getTriple().isAMDGCN() &&
3677 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3681 types::ID Output = Args.hasArg(options::OPT_S)
3683 : types::TY_LLVM_BC;
3689 AssociatedOffloadKind);
3690 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3692 AssociatedOffloadKind);
3693 AL.push_back(AssembleAction);
3696 CudaDeviceActions[I] =
3707 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3708 AssociatedOffloadKind);
3710 DDep, CudaDeviceActions[I]->getType());
3713 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3716 types::TY_HIP_FATBIN);
3718 if (!CompileDeviceOnly) {
3719 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3720 AssociatedOffloadKind);
3723 CudaFatBinary =
nullptr;
3728 CudaDeviceActions.clear();
3731 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3734 return ABRT_Success;
3740 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3741 auto LI = DeviceLinkerInputs.begin();
3742 for (
auto *A : CudaDeviceActions) {
3749 CudaDeviceActions.clear();
3750 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3754 for (
Action *&A : CudaDeviceActions)
3755 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3756 AssociatedOffloadKind);
3758 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3760 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3762 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3763 AssociatedOffloadKind);
3765 DDep, CudaDeviceActions[I]->getType());
3769 CudaDeviceActions.clear();
3772 return (CompileDeviceOnly &&
3773 (CurPhase == FinalPhase ||
3779 void appendLinkDeviceActions(
ActionList &AL)
override {
3780 if (DeviceLinkerInputs.size() == 0)
3783 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3784 "Linker inputs and GPU arch list sizes do not match.");
3790 for (
auto &LI : DeviceLinkerInputs) {
3792 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3796 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3800 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3801 GpuArchList[I], AssociatedOffloadKind);
3803 DeviceLinkDeps, DeviceLinkAction->getType()));
3806 DeviceLinkerInputs.clear();
3809 if (Args.hasArg(options::OPT_emit_llvm)) {
3818 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3821 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3822 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3823 AssociatedOffloadKind);
3826 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3832 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3848 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3856 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3859 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3867 unsigned ValidBuilders = 0u;
3868 unsigned ValidBuildersSupportingBundling = 0u;
3869 for (
auto *SB : SpecializedBuilders) {
3870 IsValid = IsValid && !SB->initialize();
3873 if (SB->isValid()) {
3875 if (SB->canUseBundlerUnbundler())
3876 ++ValidBuildersSupportingBundling;
3880 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3883 ~OffloadingActionBuilder() {
3884 for (
auto *SB : SpecializedBuilders)
3889 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3890 assert(HostAction &&
"Invalid host action");
3891 assert(InputArg &&
"Invalid input argument");
3892 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3893 assert(
Loc->second == InputArg &&
3894 "host action mapped to multiple input arguments");
3903 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3905 DeviceActionBuilder::PhasesTy &Phases) {
3909 if (SpecializedBuilders.empty())
3912 assert(HostAction &&
"Invalid host action!");
3913 recordHostAction(HostAction, InputArg);
3918 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3919 unsigned InactiveBuilders = 0u;
3920 unsigned IgnoringBuilders = 0u;
3921 for (
auto *SB : SpecializedBuilders) {
3922 if (!SB->isValid()) {
3927 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3932 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3937 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3938 OffloadKind |= SB->getAssociatedOffloadKind();
3943 if (IgnoringBuilders &&
3944 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3961 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3962 const Arg *InputArg) {
3966 recordHostAction(HostAction, InputArg);
3974 if (CanUseBundler && isa<InputAction>(HostAction) &&
3975 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3977 HostAction->
getType() == types::TY_PP_HIP)) {
3978 auto UnbundlingHostAction =
3983 HostAction = UnbundlingHostAction;
3984 recordHostAction(HostAction, InputArg);
3987 assert(HostAction &&
"Invalid host action!");
3990 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3991 for (
auto *SB : SpecializedBuilders) {
3995 auto RetCode = SB->addDeviceDependences(HostAction);
3999 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4000 "Host dependence not expected to be ignored.!");
4004 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4005 OffloadKind |= SB->getAssociatedOffloadKind();
4010 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4020 const Arg *InputArg) {
4022 recordHostAction(HostAction, InputArg);
4026 for (
auto *SB : SpecializedBuilders) {
4029 SB->appendTopLevelActions(OffloadAL);
4036 if (CanUseBundler && HostAction &&
4037 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4039 OffloadAL.push_back(HostAction);
4043 assert(HostAction == AL.back() &&
"Host action not in the list??");
4045 recordHostAction(HostAction, InputArg);
4046 AL.back() = HostAction;
4048 AL.append(OffloadAL.begin(), OffloadAL.end());
4058 void appendDeviceLinkActions(
ActionList &AL) {
4059 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4062 SB->appendLinkDeviceActions(AL);
4066 Action *makeHostLinkAction() {
4069 appendDeviceLinkActions(DeviceAL);
4070 if (DeviceAL.empty())
4075 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4078 HA = SB->appendLinkHostActions(DeviceAL);
4095 for (
auto *SB : SpecializedBuilders) {
4099 SB->appendLinkDependences(DDeps);
4103 unsigned ActiveOffloadKinds = 0u;
4104 for (
auto &I : InputArgToOffloadKindMap)
4105 ActiveOffloadKinds |= I.second;
4117 for (
auto *A : HostAction->
inputs()) {
4118 auto ArgLoc = HostActionToInputArgMap.find(A);
4119 if (ArgLoc == HostActionToInputArgMap.end())
4121 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4122 if (OFKLoc == InputArgToOffloadKindMap.end())
4134 nullptr, ActiveOffloadKinds);
4140void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4141 const InputList &Inputs,
4145 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4146 StringRef
V = A->getValue();
4147 if (Inputs.size() > 1 && !
V.empty() &&
4148 !llvm::sys::path::is_separator(
V.back())) {
4150 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4151 << A->getSpelling() <<
V;
4152 Args.eraseArg(options::OPT__SLASH_Fo);
4157 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4158 StringRef
V = A->getValue();
4159 if (Inputs.size() > 1 && !
V.empty() &&
4160 !llvm::sys::path::is_separator(
V.back())) {
4162 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4163 << A->getSpelling() <<
V;
4164 Args.eraseArg(options::OPT__SLASH_Fa);
4169 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4170 if (A->getValue()[0] ==
'\0') {
4172 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4173 Args.eraseArg(options::OPT__SLASH_o);
4178 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4179 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4180 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4181 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4182 Args.eraseArg(options::OPT__SLASH_Yc);
4183 Args.eraseArg(options::OPT__SLASH_Yu);
4184 YcArg = YuArg =
nullptr;
4186 if (YcArg && Inputs.size() > 1) {
4187 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4188 Args.eraseArg(options::OPT__SLASH_Yc);
4192 if (Args.hasArgNoClaim(options::OPT_fmodules_driver))
4194 if (!ModulesModeCXX20 && !Args.hasArgNoClaim(options::OPT_fmodules))
4195 Args.eraseArg(options::OPT_fmodules_driver);
4201 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4202 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4203 Args.AddFlagArg(
nullptr,
4204 getOpts().getOption(options::OPT_frtlib_add_rpath));
4207 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4208 Diag(clang::diag::err_drv_emit_llvm_link);
4209 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4211 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4212 .starts_with_insensitive(
"lld"))
4213 Diag(clang::diag::err_drv_lto_without_lld);
4219 if (!Args.hasArg(options::OPT_dumpdir)) {
4220 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4221 Arg *Arg = Args.MakeSeparateArg(
4222 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4224 (FinalOutput ? FinalOutput->getValue()
4236 Args.eraseArg(options::OPT__SLASH_Fp);
4237 Args.eraseArg(options::OPT__SLASH_Yc);
4238 Args.eraseArg(options::OPT__SLASH_Yu);
4239 YcArg = YuArg =
nullptr;
4242 if (Args.hasArg(options::OPT_include_pch) &&
4243 Args.hasArg(options::OPT_ignore_pch)) {
4247 Args.eraseArg(options::OPT_include_pch);
4250 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4251 for (
auto &I : Inputs) {
4253 const Arg *InputArg = I.second;
4258 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4262 if (InitialPhase > FinalPhase) {
4263 if (InputArg->isClaimed())
4270 if (Args.hasArg(options::OPT_Qunused_arguments))
4276 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4277 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4281 (Args.getLastArg(options::OPT__SLASH_EP,
4282 options::OPT__SLASH_P) ||
4283 Args.getLastArg(options::OPT_E) ||
4284 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4286 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4287 << InputArg->getAsString(Args) << !!FinalPhaseArg
4288 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4290 Diag(clang::diag::warn_drv_input_file_unused)
4291 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4293 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4306 Actions.push_back(ClangClPch);
4318 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4319 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4324 const auto IsTypeCXXModule = [](
const auto &Input) ->
bool {
4325 const auto TypeID = Input.first;
4326 return (TypeID == types::TY_CXXModule);
4328 return llvm::any_of(Inputs, IsTypeCXXModule);
4332Driver::ScanInputsForCXX20ModulesUsage(
const InputList &Inputs)
const {
4333 const auto CXXInputs = llvm::make_filter_range(
4334 Inputs, [](
const auto &Input) {
return types::isCXX(Input.first); });
4335 for (
const auto &Input : CXXInputs) {
4336 StringRef
Filename = Input.second->getSpelling();
4337 auto ErrOrBuffer = VFS->getBufferForFile(
Filename);
4339 return ErrOrBuffer.getError();
4340 const auto Buffer = std::move(*ErrOrBuffer);
4352 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4354 if (!SuppressMissingInputWarning && Inputs.empty()) {
4355 Diag(clang::diag::err_drv_no_input_files);
4359 handleArguments(
C, Args, Inputs, Actions);
4361 if (Args.hasFlag(options::OPT_fmodules_driver,
4362 options::OPT_fno_modules_driver,
false)) {
4367 if (!UsesCXXModules) {
4368 const auto ErrOrScanResult = ScanInputsForCXX20ModulesUsage(Inputs);
4369 if (!ErrOrScanResult) {
4370 Diags.
Report(diag::err_cannot_open_file)
4371 << ErrOrScanResult.getError().message();
4374 UsesCXXModules = *ErrOrScanResult;
4376 if (UsesCXXModules || Args.hasArg(options::OPT_fmodules))
4377 BuildDriverManagedModuleBuildActions(
C, Args, Inputs, Actions);
4381 BuildDefaultActions(
C, Args, Inputs, Actions);
4384void Driver::BuildDefaultActions(
Compilation &
C, DerivedArgList &Args,
4385 const InputList &Inputs,
4388 bool UseNewOffloadingDriver =
4391 Args.hasFlag(options::OPT_foffload_via_llvm,
4392 options::OPT_fno_offload_via_llvm,
false) ||
4393 Args.hasFlag(options::OPT_offload_new_driver,
4394 options::OPT_no_offload_new_driver,
4399 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4402 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4403 !UseNewOffloadingDriver
4404 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4412 for (
auto &I : Inputs) {
4414 const Arg *InputArg = I.second;
4427 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4428 cast<InputAction>(Current)->setId(CUID);
4433 if (!UseNewOffloadingDriver)
4434 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4440 if (!UseNewOffloadingDriver)
4441 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4442 Current, InputArg, Phase, PL.back(), FullPL);
4448 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4451 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4452 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4454 LinkerInputs.push_back(Current);
4464 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4465 MergerInputs.push_back(Current);
4483 if (NewCurrent == Current)
4486 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4489 Current = NewCurrent;
4493 if (UseNewOffloadingDriver)
4497 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4501 if (Current->getType() == types::TY_Nothing)
4507 Actions.push_back(Current);
4510 if (!UseNewOffloadingDriver)
4511 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4513 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4519 if (LinkerInputs.empty()) {
4522 if (!UseNewOffloadingDriver)
4523 OffloadBuilder->appendDeviceLinkActions(Actions);
4526 if (!LinkerInputs.empty()) {
4527 if (!UseNewOffloadingDriver)
4528 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4529 LinkerInputs.push_back(Wrapper);
4534 }
else if ((UseNewOffloadingDriver && !HIPNoRDC) ||
4535 Args.hasArg(options::OPT_offload_link)) {
4542 if (!UseNewOffloadingDriver)
4543 LA = OffloadBuilder->processHostLinkAction(LA);
4544 Actions.push_back(LA);
4548 if (!MergerInputs.empty())
4552 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4559 for (
auto &I : Inputs) {
4561 const Arg *InputArg = I.second;
4566 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4567 InputType == types::TY_Asm)
4572 for (
auto Phase : PhaseList) {
4576 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4581 if (InputType == types::TY_Object)
4588 assert(Phase == PhaseList.back() &&
4589 "merging must be final compilation step.");
4590 MergerInputs.push_back(Current);
4599 Actions.push_back(Current);
4603 if (!MergerInputs.empty())
4608 for (
auto Opt : {options::OPT_print_supported_cpus,
4609 options::OPT_print_supported_extensions,
4610 options::OPT_print_enabled_extensions}) {
4617 if (Arg *A = Args.getLastArg(Opt)) {
4618 if (Opt == options::OPT_print_supported_extensions &&
4619 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4620 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4621 !
C.getDefaultToolChain().getTriple().isARM()) {
4622 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4623 <<
"--print-supported-extensions";
4626 if (Opt == options::OPT_print_enabled_extensions &&
4627 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4628 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4629 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4630 <<
"--print-enabled-extensions";
4637 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4640 for (
auto &I : Inputs)
4645 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4651 if (TC.requiresObjcopy(Args)) {
4652 Action *LastAction = Actions.back();
4654 if (LastAction->
getType() == types::TY_Object)
4660 if (TC.requiresValidation(Args)) {
4661 Action *LastAction = Actions.back();
4663 LastAction, types::TY_DX_CONTAINER));
4667 if (TC.requiresBinaryTranslation(Args)) {
4668 Action *LastAction = Actions.back();
4672 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4673 LastAction->
getType() == types::TY_Object)
4675 LastAction, types::TY_DX_CONTAINER));
4680 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4683void Driver::BuildDriverManagedModuleBuildActions(
4684 Compilation &
C, llvm::opt::DerivedArgList &Args,
const InputList &Inputs,
4686 Diags.
Report(diag::remark_performing_driver_managed_module_build);
4692 const llvm::opt::DerivedArgList &Args,
4694 const llvm::Triple &Triple) {
4699 if (Triple.isNVPTX() &&
4701 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4702 <<
"CUDA" << ArchStr;
4704 }
else if (Triple.isAMDGPU() &&
4706 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4707 <<
"HIP" << ArchStr;
4715 llvm::StringMap<bool> Features;
4718 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4730static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4732 llvm::Triple Triple) {
4733 if (!Triple.isAMDGPU())
4734 return std::nullopt;
4736 std::set<StringRef> ArchSet;
4737 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4745 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4746 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4747 options::OPT_no_offload_arch_EQ)) {
4748 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4750 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4752 :
"--no-offload-arch");
4755 llvm::DenseSet<StringRef> Archs;
4756 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4759 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4760 for (StringRef
Arch : Arg->getValues()) {
4761 if (
Arch ==
"native" ||
Arch.empty()) {
4765 << llvm::Triple::getArchTypeName(TC.
getArch())
4766 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4770 for (
auto ArchStr : *GPUsOrErr) {
4772 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4773 if (!CanonicalStr.empty())
4774 Archs.insert(CanonicalStr);
4779 StringRef CanonicalStr =
4781 if (!CanonicalStr.empty())
4782 Archs.insert(CanonicalStr);
4787 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4788 for (StringRef
Arch : Arg->getValues()) {
4789 if (
Arch ==
"all") {
4794 Archs.erase(ArchStr);
4800 if (
auto ConflictingArchs =
4802 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4803 << ConflictingArchs->first << ConflictingArchs->second;
4806 if (Archs.empty()) {
4814 Archs.insert(StringRef());
4817 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4818 .getLastArg(options::OPT_march_EQ)) {
4819 Archs.insert(Arg->getValue());
4824 << llvm::Triple::getArchTypeName(TC.
getArch())
4825 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4826 }
else if (!ArchsOrErr->empty()) {
4827 for (
auto Arch : *ArchsOrErr)
4828 Archs.insert(Args.MakeArgStringRef(
Arch));
4830 Archs.insert(StringRef());
4835 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4836 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4844 llvm::opt::DerivedArgList &Args,
4845 const InputTy &Input, StringRef CUID,
4846 Action *HostAction)
const {
4854 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4856 bool HIPRelocatableObj =
4858 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4859 options::OPT_fno_hip_emit_relocatable,
false);
4861 if (!HIPNoRDC && HIPRelocatableObj)
4862 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4863 <<
"-fhip-emit-relocatable"
4867 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4868 <<
"-fhip-emit-relocatable"
4869 <<
"--offload-device-only";
4874 if ((isa<AssembleJobAction>(HostAction) ||
4875 (isa<BackendJobAction>(HostAction) &&
4876 HostAction->
getType() == types::TY_LTO_BC)) &&
4887 if (!(isa<CompileJobAction>(HostAction) ||
4901 auto TCRange =
C.getOffloadToolChains(Kind);
4902 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4903 ToolChains.push_back(TI->second);
4905 if (ToolChains.empty())
4909 const Arg *InputArg = Input.second;
4918 for (
const ToolChain *TC : ToolChains) {
4920 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4921 DeviceActions.push_back(
4922 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4926 if (DeviceActions.empty())
4932 HostAction->
getType() != types::TY_Nothing &&
4942 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4951 auto *TCAndArch = TCAndArchs.begin();
4952 for (
Action *&A : DeviceActions) {
4953 if (A->
getType() == types::TY_Nothing)
4961 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4963 HostAction->
getType() != types::TY_Nothing) {
4970 TCAndArch->second.data(), Kind);
4972 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4982 for (
Action *&A : DeviceActions) {
4987 llvm::Triple::OSType::AMDHSA &&
4989 if ((A->
getType() != types::TY_Object && !IsAMDGCNSPIRV &&
4990 A->
getType() != types::TY_LTO_BC) ||
4997 auto *TCAndArch = TCAndArchs.begin();
4998 for (
Action *A : DeviceActions) {
4999 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5001 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5006 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5008 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5017 bool ShouldBundleHIP =
5018 Args.hasFlag(options::OPT_gpu_bundle_output,
5019 options::OPT_no_gpu_bundle_output,
false) ||
5021 llvm::none_of(OffloadActions, [](
Action *A) {
5022 return A->
getType() != types::TY_Image;
5029 if (OffloadActions.empty())
5034 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5038 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5045 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5046 DDep.
add(*FatbinAction,
5055 nullptr,
C.getActiveOffloadKinds());
5064 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5065 return A->
getType() == types::TY_Nothing;
5066 }) && isa<CompileJobAction>(HostAction);
5069 nullptr, SingleDeviceOutput ? DDep : DDeps);
5070 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5076 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5086 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5092 llvm_unreachable(
"link action invalid here.");
5094 llvm_unreachable(
"ifsmerge action invalid here.");
5099 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5100 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5101 OutputTy = types::TY_Dependencies;
5106 if (!Args.hasFlag(options::OPT_frewrite_includes,
5107 options::OPT_fno_rewrite_includes,
false) &&
5108 !Args.hasFlag(options::OPT_frewrite_imports,
5109 options::OPT_fno_rewrite_imports,
false) &&
5110 !Args.hasFlag(options::OPT_fdirectives_only,
5111 options::OPT_fno_directives_only,
false) &&
5115 "Cannot preprocess this input type!");
5121 if (Args.hasArg(options::OPT_extract_api))
5128 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5129 (Input->
getType() == driver::types::TY_CXXModule ||
5130 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5131 !Args.getLastArg(options::OPT__precompile))
5136 "Cannot precompile this input type!");
5140 const char *ModName =
nullptr;
5141 if (OutputTy == types::TY_PCH) {
5142 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5143 ModName = A->getValue();
5145 OutputTy = types::TY_ModuleFile;
5148 if (Args.hasArg(options::OPT_fsyntax_only)) {
5150 OutputTy = types::TY_Nothing;
5156 if (Args.hasArg(options::OPT_fsyntax_only))
5158 if (Args.hasArg(options::OPT_rewrite_objc))
5160 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5162 types::TY_RewrittenLegacyObjC);
5163 if (Args.hasArg(options::OPT__analyze))
5165 if (Args.hasArg(options::OPT_emit_ast))
5167 if (Args.hasArg(options::OPT_emit_cir))
5169 if (Args.hasArg(options::OPT_module_file_info))
5171 if (Args.hasArg(options::OPT_verify_pch))
5173 if (Args.hasArg(options::OPT_extract_api))
5180 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5181 !Args.hasArg(options::OPT_emit_llvm))
5182 Output = types::TY_PP_Asm;
5183 else if (Args.hasArg(options::OPT_S))
5184 Output = types::TY_LTO_IR;
5186 Output = types::TY_LTO_BC;
5191 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5194 if (Args.hasArg(options::OPT_emit_llvm) ||
5199 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5201 (Args.hasFlag(options::OPT_offload_new_driver,
5202 options::OPT_no_offload_new_driver,
false) &&
5209 Args.hasArg(options::OPT_S) &&
5213 !Args.hasFlag(options::OPT_offload_new_driver,
5214 options::OPT_no_offload_new_driver,
5217 : types::TY_LLVM_BC;
5226 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5230 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5232 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5252 unsigned NumOutputs = 0;
5253 unsigned NumIfsOutputs = 0;
5254 for (
const Action *A :
C.getActions()) {
5257 if (A->
getType() == types::TY_DX_CONTAINER &&
5262 if (A->
getType() != types::TY_Nothing &&
5264 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5266 0 == NumIfsOutputs++) ||
5271 A->
getType() == types::TY_Nothing &&
5272 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5273 NumOutputs += A->
size();
5276 if (NumOutputs > 1) {
5277 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5278 FinalOutput =
nullptr;
5282 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5286 if (RawTriple.isOSBinFormatMachO())
5287 for (
const Arg *A :
C.getArgs())
5288 if (A->getOption().matches(options::OPT_arch))
5292 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5293 for (
Action *A :
C.getActions()) {
5300 const char *LinkingOutput =
nullptr;
5301 if (isa<LipoJobAction>(A)) {
5303 LinkingOutput = FinalOutput->getValue();
5312 LinkingOutput, CachedResults,
5319 for (
auto &J :
C.getJobs())
5320 J.InProcess =
false;
5323 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5324 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5325 Cmd.getProcessStatistics();
5329 const char *LinkingOutput =
nullptr;
5331 LinkingOutput = FinalOutput->getValue();
5332 else if (!
Cmd.getOutputFilenames().empty())
5333 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5338 using namespace llvm;
5340 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5341 <<
"output=" << LinkingOutput;
5342 outs() <<
", total="
5343 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5345 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5346 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5350 llvm::raw_string_ostream Out(Buffer);
5351 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5354 llvm::sys::printArg(Out, LinkingOutput, true);
5355 Out <<
',' << ProcStat->TotalTime.count() <<
','
5356 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5360 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5361 llvm::sys::fs::OF_Append |
5362 llvm::sys::fs::OF_Text);
5367 llvm::errs() <<
"ERROR: Cannot lock file "
5368 << CCPrintStatReportFilename <<
": "
5369 << toString(L.takeError()) <<
"\n";
5380 bool ReportUnusedArguments =
5381 !Diags.hasErrorOccurred() &&
5382 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5385 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5387 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5390 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5391 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5393 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5397 return strstr(J.getCreator().getShortName(),
"assembler");
5399 for (Arg *A :
C.getArgs()) {
5403 if (!A->isClaimed()) {
5409 const Option &Opt = A->getOption();
5410 if (Opt.getKind() == Option::FlagClass) {
5411 bool DuplicateClaimed =
false;
5413 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5414 if (AA->isClaimed()) {
5415 DuplicateClaimed =
true;
5420 if (DuplicateClaimed)
5426 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5428 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5433 !
C.getActions().empty()) {
5434 Diag(diag::err_drv_unsupported_opt_for_target)
5435 << A->getSpelling() << getTargetTriple();
5436 }
else if (ReportUnusedArguments) {
5437 Diag(clang::diag::warn_drv_unused_argument)
5438 << A->getAsString(
C.getArgs());
5448class ToolSelector final {
5459 bool IsHostSelector;
5470 bool CanBeCollapsed =
true) {
5472 if (Inputs.size() != 1)
5475 Action *CurAction = *Inputs.begin();
5476 if (CanBeCollapsed &&
5482 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5486 if (!IsHostSelector) {
5487 if (OA->hasSingleDeviceDependence(
true)) {
5489 OA->getSingleDeviceDependence(
true);
5490 if (CanBeCollapsed &&
5493 SavedOffloadAction.push_back(OA);
5494 return dyn_cast<JobAction>(CurAction);
5496 }
else if (OA->hasHostDependence()) {
5497 CurAction = OA->getHostDependence();
5498 if (CanBeCollapsed &&
5501 SavedOffloadAction.push_back(OA);
5502 return dyn_cast<JobAction>(CurAction);
5507 return dyn_cast<JobAction>(CurAction);
5511 bool canCollapseAssembleAction()
const {
5512 return TC.useIntegratedAs() && !SaveTemps &&
5513 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5514 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5515 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5516 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5520 bool canCollapsePreprocessorAction()
const {
5521 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5522 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5523 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5528 struct JobActionInfo final {
5538 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5540 unsigned ElementNum) {
5541 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5542 for (
unsigned I = 0; I < ElementNum; ++I)
5543 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5544 ActionInfo[I].SavedOffloadAction.end());
5560 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5562 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5563 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5564 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5565 if (!AJ || !BJ || !CJ)
5569 const Tool *
T = TC.SelectTool(*CJ);
5576 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5582 const Tool *BT = TC.SelectTool(*BJ);
5587 if (!
T->hasIntegratedAssembler())
5590 Inputs = CJ->getInputs();
5591 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5598 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5600 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5601 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5606 const Tool *
T = TC.SelectTool(*BJ);
5610 if (!
T->hasIntegratedAssembler())
5613 Inputs = BJ->getInputs();
5614 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5621 if (ActionInfo.size() < 2)
5623 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5624 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5628 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5629 for (
auto &Input : AI.JA->getInputs())
5640 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5641 if (SaveTemps && !InputIsBitcode)
5645 const Tool *
T = TC.SelectTool(*CJ);
5652 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5658 Inputs = CJ->getInputs();
5659 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5670 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5676 for (
Action *A : Inputs) {
5677 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5678 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5679 NewInputs.push_back(A);
5685 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5686 PreprocessJobOffloadActions.end());
5687 NewInputs.append(PJ->input_begin(), PJ->input_end());
5695 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5697 assert(BaseAction &&
"Invalid base action.");
5714 ActionChain.back().JA = BaseAction;
5715 while (ActionChain.back().JA) {
5716 const Action *CurAction = ActionChain.back().JA;
5719 ActionChain.resize(ActionChain.size() + 1);
5720 JobActionInfo &AI = ActionChain.back();
5724 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5728 ActionChain.pop_back();
5736 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5737 CollapsedOffloadAction);
5739 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5741 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5747 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5759 StringRef BoundArch,
5761 std::string TriplePlusArch = TC->
getTriple().normalize();
5762 if (!BoundArch.empty()) {
5763 TriplePlusArch +=
"-";
5764 TriplePlusArch += BoundArch;
5766 TriplePlusArch +=
"-";
5768 return TriplePlusArch;
5773 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5774 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5777 std::pair<const Action *, std::string> ActionTC = {
5779 auto CachedResult = CachedResults.find(ActionTC);
5780 if (CachedResult != CachedResults.end()) {
5781 return CachedResult->second;
5784 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5785 CachedResults, TargetDeviceOffloadKind);
5786 CachedResults[ActionTC] =
Result;
5791 const JobAction *JA,
const char *BaseInput,
5794 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5798 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5799 Path = A->getValue();
5800 if (llvm::sys::fs::is_directory(
Path)) {
5802 llvm::sys::path::replace_extension(Tmp,
"json");
5803 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5806 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5809 Path = DumpDir->getValue();
5810 Path += llvm::sys::path::filename(BaseInput);
5814 llvm::sys::path::replace_extension(
Path,
"json");
5816 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5817 C.addTimeTraceFile(ResultFile, JA);
5818 C.addResultFile(ResultFile, JA);
5823 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5824 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5827 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5830 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5863 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5865 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5866 const char *DepBoundArch) {
5869 LinkingOutput, CachedResults,
5879 OA->doOnEachDependence(
5880 BuildingForOffloadDevice,
5883 C, DepA, DepTC, DepBoundArch,
false,
5884 !!DepBoundArch, LinkingOutput, CachedResults,
5888 A = BuildingForOffloadDevice
5889 ? OA->getSingleDeviceDependence(
true)
5890 : OA->getHostDependence();
5894 std::pair<const Action *, std::string> ActionTC = {
5895 OA->getHostDependence(),
5897 auto It = CachedResults.find(ActionTC);
5898 if (It != CachedResults.end()) {
5900 Inputs.append(OffloadDependencesInputInfo);
5905 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5908 const Arg &Input = IA->getInputArg();
5910 if (Input.getOption().matches(options::OPT_INPUT)) {
5911 const char *
Name = Input.getValue();
5919 StringRef
ArchName = BAA->getArchName();
5922 TC = &getToolChain(
C.getArgs(),
5926 TC = &
C.getDefaultToolChain();
5929 MultipleArchs, LinkingOutput, CachedResults,
5930 TargetDeviceOffloadKind);
5936 const JobAction *JA = cast<JobAction>(A);
5941 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5948 for (
const auto *OA : CollapsedOffloadActions)
5949 cast<OffloadAction>(OA)->doOnEachDependence(
5950 BuildingForOffloadDevice,
5953 C, DepA, DepTC, DepBoundArch,
false,
5954 !!DepBoundArch, LinkingOutput, CachedResults,
5960 for (
const Action *Input : Inputs) {
5964 bool SubJobAtTopLevel =
5965 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5967 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5972 const char *BaseInput = InputInfos[0].getBaseInput();
5973 for (
auto &Info : InputInfos) {
5974 if (Info.isFilename()) {
5975 BaseInput = Info.getBaseInput();
5982 if (JA->
getType() == types::TY_dSYM)
5983 BaseInput = InputInfos[0].getFilename();
5986 if (!OffloadDependencesInputInfo.empty())
5987 InputInfos.append(OffloadDependencesInputInfo.begin(),
5988 OffloadDependencesInputInfo.end());
5991 llvm::Triple EffectiveTriple;
5993 const ArgList &Args =
5995 if (InputInfos.size() != 1) {
5999 EffectiveTriple = llvm::Triple(
6007 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6011 for (
auto &UI : UA->getDependentActionsInfo()) {
6013 "Unbundling with no offloading??");
6020 UI.DependentOffloadKind,
6021 UI.DependentToolChain->getTriple().normalize(),
6032 UnbundlingResults.push_back(CurI);
6041 Arch = UI.DependentBoundArch;
6046 UI.DependentOffloadKind)}] = {
6052 std::pair<const Action *, std::string> ActionTC = {
6054 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6055 "Result does not exist??");
6056 Result = CachedResults[ActionTC].front();
6057 }
else if (JA->
getType() == types::TY_Nothing)
6064 isa<OffloadPackagerJobAction>(A) ||
6068 AtTopLevel, MultipleArchs,
6071 if (
T->canEmitIR() && OffloadingPrefix.empty())
6076 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
6077 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6078 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6079 llvm::errs() << InputInfos[i].getAsString();
6081 llvm::errs() <<
", ";
6083 if (UnbundlingResults.empty())
6084 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6086 llvm::errs() <<
"], outputs: [";
6087 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6088 llvm::errs() << UnbundlingResults[i].getAsString();
6090 llvm::errs() <<
", ";
6092 llvm::errs() <<
"] \n";
6095 if (UnbundlingResults.empty())
6096 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6098 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6099 Args, LinkingOutput);
6105 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6106 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6118 if (ArgValue.empty()) {
6121 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
6123 llvm::sys::path::append(
Filename, BaseName);
6126 if (!llvm::sys::path::has_extension(ArgValue)) {
6131 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6136 llvm::sys::path::replace_extension(
Filename, Extension);
6139 return Args.MakeArgString(
Filename.c_str());
6143 if (isa<PreprocessJobAction>(JA))
6145 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
6147 if (isa<OffloadBundlingJobAction>(JA) &&
6154 StringRef Suffix,
bool MultipleArchs,
6155 StringRef BoundArch,
6156 bool NeedUniqueDirectory)
const {
6158 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6159 std::optional<std::string> CrashDirectory =
6161 ? std::string(A->getValue())
6162 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6163 if (CrashDirectory) {
6164 if (!
getVFS().exists(*CrashDirectory))
6165 llvm::sys::fs::create_directories(*CrashDirectory);
6167 llvm::sys::path::append(
Path, Prefix);
6168 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6169 if (std::error_code EC =
6170 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6171 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6175 if (MultipleArchs && !BoundArch.empty()) {
6176 if (NeedUniqueDirectory) {
6178 llvm::sys::path::append(TmpName,
6179 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6189 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6204 const char *BaseInput) {
6205 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6206 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6207 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6212 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6216 const char *BaseInput,
6217 StringRef OrigBoundArch,
bool AtTopLevel,
6219 StringRef OffloadingPrefix)
const {
6220 std::string BoundArch = OrigBoundArch.str();
6221 if (is_style_windows(llvm::sys::path::Style::native)) {
6224 llvm::replace(BoundArch,
':',
'@');
6227 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6229 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6230 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6231 return C.addResultFile(FinalOutput->getValue(), &JA);
6235 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6236 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6237 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6239 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6240 NameArg = A->getValue();
6241 return C.addResultFile(
6251 if (JA.
getType() == types::TY_ModuleFile &&
6252 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6256 if (JA.
getType() == types::TY_PP_Asm &&
6257 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6258 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6261 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6264 if ((JA.
getType() == types::TY_Object &&
6265 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6266 JA.
getType() == types::TY_DX_CONTAINER) {
6267 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6271 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6273 C.getDefaultToolChain());
6276 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6277 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6278 StringRef
Name = llvm::sys::path::filename(BaseInput);
6279 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6285 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6286 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6290 if (JA.
getType() == types::TY_PP_Asm &&
6291 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6292 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6294 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6295 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6296 return C.addResultFile(
6301 if (JA.
getType() == types::TY_API_INFO &&
6302 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6303 C.getArgs().hasArg(options::OPT_o))
6304 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6305 <<
C.getArgs().getLastArgValue(options::OPT_o);
6312 bool SpecifiedModuleOutput =
6313 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6314 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6315 if (MultipleArchs && SpecifiedModuleOutput)
6316 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6320 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6321 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6322 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6328 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6330 StringRef
Name = llvm::sys::path::filename(BaseInput);
6331 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6332 const char *Suffix =
6337 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6338 bool NeedUniqueDirectory =
6341 Triple.isOSDarwin();
6342 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6343 NeedUniqueDirectory);
6351 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6352 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6357 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6358 llvm::sys::path::filename(BasePath));
6359 BaseName = ExternalPath;
6360 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6361 BaseName = BasePath;
6363 BaseName = llvm::sys::path::filename(BasePath);
6366 const char *NamedOutput;
6368 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6369 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6373 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6377 }
else if (JA.
getType() == types::TY_Image &&
6378 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6379 options::OPT__SLASH_o)) {
6383 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6387 }
else if (JA.
getType() == types::TY_Image) {
6397 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6398 options::OPT_fno_gpu_rdc,
false);
6399 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6400 if (UseOutExtension) {
6402 llvm::sys::path::replace_extension(Output,
"");
6404 Output += OffloadingPrefix;
6405 if (MultipleArchs && !BoundArch.empty()) {
6407 Output.append(BoundArch);
6409 if (UseOutExtension)
6411 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6414 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6415 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6416 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6419 .getLastArg(options::OPT__SLASH_o)
6424 const char *Suffix =
6426 assert(Suffix &&
"All types used for output should have a suffix.");
6428 std::string::size_type End = std::string::npos;
6430 End = BaseName.rfind(
'.');
6432 Suffixed += OffloadingPrefix;
6433 if (MultipleArchs && !BoundArch.empty()) {
6435 Suffixed.append(BoundArch);
6440 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6441 const llvm::opt::DerivedArgList &Args) {
6446 return isa<CompileJobAction>(JA) &&
6448 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6453 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6454 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6455 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6459 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6463 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6464 JA.
getType() != types::TY_PCH) {
6465 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6467 llvm::sys::path::remove_filename(TempPath);
6468 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6469 llvm::sys::path::append(TempPath, OutputFileName);
6470 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6476 bool SameFile =
false;
6478 llvm::sys::fs::current_path(
Result);
6479 llvm::sys::path::append(
Result, BaseName);
6480 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6483 StringRef
Name = llvm::sys::path::filename(BaseInput);
6484 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6488 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6494 llvm::sys::path::remove_filename(BasePath);
6495 if (BasePath.empty())
6496 BasePath = NamedOutput;
6498 llvm::sys::path::append(BasePath, NamedOutput);
6499 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6502 return C.addResultFile(NamedOutput, &JA);
6508 -> std::optional<std::string> {
6511 for (
const auto &
Dir :
P) {
6515 llvm::sys::path::append(
P,
Name);
6516 if (llvm::sys::fs::exists(Twine(
P)))
6517 return std::string(
P);
6519 return std::nullopt;
6526 llvm::sys::path::append(R,
Name);
6527 if (llvm::sys::fs::exists(Twine(R)))
6528 return std::string(R);
6531 llvm::sys::path::append(
P,
Name);
6532 if (llvm::sys::fs::exists(Twine(
P)))
6533 return std::string(
P);
6536 llvm::sys::path::append(
D,
"..",
Name);
6537 if (llvm::sys::fs::exists(Twine(
D)))
6538 return std::string(
D);
6547 llvm::sys::path::append(R2,
"..",
"..",
Name);
6548 if (llvm::sys::fs::exists(Twine(R2)))
6549 return std::string(R2);
6551 return std::string(
Name);
6554void Driver::generatePrefixedToolNames(
6558 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6559 Names.emplace_back(
Tool);
6563 llvm::sys::path::append(Dir, Name);
6564 if (llvm::sys::fs::can_execute(Twine(Dir)))
6566 llvm::sys::path::remove_filename(Dir);
6572 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6577 if (llvm::sys::fs::is_directory(PrefixDir)) {
6580 return std::string(
P);
6583 if (llvm::sys::fs::can_execute(Twine(
P)))
6584 return std::string(
P);
6589 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6597 for (
const auto &
Path : List) {
6600 return std::string(
P);
6604 if (llvm::ErrorOr<std::string>
P =
6605 llvm::sys::findProgramByName(TargetSpecificExecutable))
6609 return std::string(
Name);
6614 std::string error =
"<NOT PRESENT>";
6618 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6635 llvm::sys::path::remove_filename(path);
6636 llvm::sys::path::append(path,
"libc++.modules.json");
6637 if (TC.
getVFS().exists(path))
6638 return static_cast<std::string
>(path);
6643 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6646 return evaluate(
"libc++.a").value_or(error);
6650 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6654 llvm::sys::path::remove_filename(path);
6655 llvm::sys::path::append(path,
"libstdc++.modules.json");
6656 if (TC.
getVFS().exists(path))
6657 return static_cast<std::string
>(path);
6662 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6665 return evaluate(
"libstdc++.a").value_or(error);
6674 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6676 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6680 return std::string(
Path);
6685 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6687 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6691 return std::string(
Path);
6696 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6700 Output = FpArg->getValue();
6704 if (!llvm::sys::path::has_extension(Output))
6707 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6708 Output = YcArg->getValue();
6711 llvm::sys::path::replace_extension(Output,
".pch");
6713 return std::string(Output);
6716const ToolChain &Driver::getOffloadToolChain(
6718 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6719 std::unique_ptr<ToolChain> &TC =
6720 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6721 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6723 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6726 switch (
Target.getOS()) {
6727 case llvm::Triple::CUDA:
6728 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6731 case llvm::Triple::AMDHSA:
6733 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6736 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6745 switch (
Target.getArch()) {
6746 case llvm::Triple::spir:
6747 case llvm::Triple::spir64:
6748 case llvm::Triple::spirv:
6749 case llvm::Triple::spirv32:
6750 case llvm::Triple::spirv64:
6753 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6757 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6761 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6765 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6779 return getToolChain(Args,
Target);
6783const ToolChain &Driver::getToolChain(
const ArgList &Args,
6784 const llvm::Triple &
Target)
const {
6786 auto &TC = ToolChains[
Target.str()];
6788 switch (
Target.getOS()) {
6789 case llvm::Triple::AIX:
6790 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6792 case llvm::Triple::Haiku:
6793 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6795 case llvm::Triple::Darwin:
6796 case llvm::Triple::MacOSX:
6797 case llvm::Triple::IOS:
6798 case llvm::Triple::TvOS:
6799 case llvm::Triple::WatchOS:
6800 case llvm::Triple::XROS:
6801 case llvm::Triple::DriverKit:
6802 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6804 case llvm::Triple::DragonFly:
6805 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6807 case llvm::Triple::OpenBSD:
6808 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6810 case llvm::Triple::NetBSD:
6811 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6813 case llvm::Triple::FreeBSD:
6815 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6818 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6820 case llvm::Triple::Linux:
6821 case llvm::Triple::ELFIAMCU:
6822 if (
Target.getArch() == llvm::Triple::hexagon)
6823 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6825 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6826 !
Target.hasEnvironment())
6827 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6830 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6832 else if (
Target.getArch() == llvm::Triple::ve)
6833 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6834 else if (
Target.isOHOSFamily())
6835 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6837 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6839 case llvm::Triple::Fuchsia:
6840 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6842 case llvm::Triple::Managarm:
6843 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6845 case llvm::Triple::Solaris:
6846 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6848 case llvm::Triple::CUDA:
6849 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6851 case llvm::Triple::AMDHSA: {
6852 if (
Target.getArch() == llvm::Triple::spirv64) {
6853 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6858 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6860 :
std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6865 case llvm::Triple::AMDPAL:
6866 case llvm::Triple::Mesa3D:
6867 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6869 case llvm::Triple::UEFI:
6870 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6872 case llvm::Triple::Win32:
6873 switch (
Target.getEnvironment()) {
6875 if (
Target.isOSBinFormatELF())
6876 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6877 else if (
Target.isOSBinFormatMachO())
6878 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6880 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6882 case llvm::Triple::GNU:
6883 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6885 case llvm::Triple::Cygnus:
6886 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6888 case llvm::Triple::Itanium:
6889 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6892 case llvm::Triple::MSVC:
6893 case llvm::Triple::UnknownEnvironment:
6894 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6895 .starts_with_insensitive(
"bfd"))
6896 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6900 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6904 case llvm::Triple::PS4:
6905 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6907 case llvm::Triple::PS5:
6908 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6910 case llvm::Triple::Hurd:
6911 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6913 case llvm::Triple::LiteOS:
6914 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6916 case llvm::Triple::ZOS:
6917 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6919 case llvm::Triple::Vulkan:
6920 case llvm::Triple::ShaderModel:
6921 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6926 switch (
Target.getArch()) {
6927 case llvm::Triple::tce:
6928 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6930 case llvm::Triple::tcele:
6931 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6933 case llvm::Triple::hexagon:
6934 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6937 case llvm::Triple::lanai:
6938 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6940 case llvm::Triple::xcore:
6941 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6943 case llvm::Triple::wasm32:
6944 case llvm::Triple::wasm64:
6945 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6947 case llvm::Triple::avr:
6948 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6950 case llvm::Triple::msp430:
6951 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6953 case llvm::Triple::riscv32:
6954 case llvm::Triple::riscv64:
6955 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6957 case llvm::Triple::ve:
6958 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6960 case llvm::Triple::spirv32:
6961 case llvm::Triple::spirv64:
6962 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6964 case llvm::Triple::csky:
6965 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6969 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6970 else if (
Target.isOSBinFormatELF())
6971 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6972 else if (
Target.isAppleMachO())
6973 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6974 else if (
Target.isOSBinFormatMachO())
6975 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6977 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6987 if (JA.
size() != 1 ||
6992 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6993 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6994 !isa<ExtractAPIJobAction>(JA))
7002 if (JA.
size() != 1 ||
7007 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
7008 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
7016 if (Args.hasArg(options::OPT_emit_static_lib))
7027 unsigned &Micro,
bool &HadExtra) {
7030 Major = Minor = Micro = 0;
7034 if (Str.consumeInteger(10, Major))
7038 if (!Str.consume_front(
"."))
7041 if (Str.consumeInteger(10, Minor))
7045 if (!Str.consume_front(
"."))
7048 if (Str.consumeInteger(10, Micro))
7066 unsigned CurDigit = 0;
7067 while (CurDigit < Digits.size()) {
7069 if (Str.consumeInteger(10, Digit))
7071 Digits[CurDigit] = Digit;
7074 if (!Str.consume_front(
"."))
7083llvm::opt::Visibility
7084Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7097const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7113 llvm_unreachable(
"Unhandled Mode");
7117 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7122 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7123 options::OPT_fno_save_optimization_record,
false))
7127 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7128 options::OPT_fno_save_optimization_record,
false))
7132 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7133 options::OPT_fno_save_optimization_record,
false))
7137 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7138 options::OPT_fno_save_optimization_record,
false))
7145 static StringRef OptName =
7147 llvm::StringRef Opt;
7148 for (StringRef Arg : Args) {
7149 if (!Arg.starts_with(OptName))
7155 return Opt.consume_front(OptName) ? Opt :
"";
7162 llvm::BumpPtrAllocator &Alloc,
7163 llvm::vfs::FileSystem *FS) {
7172 for (
const char *F : Args) {
7173 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7175 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7176 RSPQuoting = Windows;
7184 llvm::cl::TokenizerCallback Tokenizer;
7186 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7188 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7190 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7193 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7194 ECtx.setMarkEOLs(MarkEOLs);
7198 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7202 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7203 [](
const char *A) {
return A !=
nullptr; });
7204 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7207 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7208 Args.resize(newEnd - Args.begin());
7212 return llvm::Error::success();
7216 return SavedStrings.insert(S).first->getKeyData();
7250 llvm::StringSet<> &SavedStrings) {
7253 if (Edit[0] ==
'^') {
7254 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7255 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7256 Args.insert(Args.begin() + 1, Str);
7257 }
else if (Edit[0] ==
'+') {
7258 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7259 OS <<
"### Adding argument " << Str <<
" at end\n";
7260 Args.push_back(Str);
7261 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7262 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7263 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7264 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7265 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7267 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7269 if (Args[i] ==
nullptr)
7271 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7273 if (Repl != Args[i]) {
7274 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7278 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7279 auto Option = Edit.substr(1);
7280 for (
unsigned i = 1; i < Args.size();) {
7281 if (Option == Args[i]) {
7282 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7283 Args.erase(Args.begin() + i);
7284 if (Edit[0] ==
'X') {
7285 if (i < Args.size()) {
7286 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7287 Args.erase(Args.begin() + i);
7289 OS <<
"### Invalid X edit, end of command line!\n";
7294 }
else if (Edit[0] ==
'O') {
7295 for (
unsigned i = 1; i < Args.size();) {
7296 const char *A = Args[i];
7300 if (A[0] ==
'-' && A[1] ==
'O' &&
7301 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7302 (
'0' <= A[2] && A[2] <=
'9'))))) {
7303 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7304 Args.erase(Args.begin() + i);
7308 OS <<
"### Adding argument " << Edit <<
" at end\n";
7309 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7311 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7316 const char *OverrideStr,
7317 llvm::StringSet<> &SavedStrings,
7318 StringRef EnvVar, raw_ostream *OS) {
7320 OS = &llvm::nulls();
7322 if (OverrideStr[0] ==
'#') {
7324 OS = &llvm::nulls();
7327 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7331 const char *S = OverrideStr;
7333 const char *End = ::strchr(S,
' ');
7335 End = S + strlen(S);
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
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 bool hasCXXModuleInputType(const Driver::InputList &Inputs)
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)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
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.
bool hasErrorOccurred() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
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 Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
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.
static std::string GetResourcesPath(StringRef BinaryPath)
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
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.
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.
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
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)
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.
bool isCXX(ID Id)
isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
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.
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.
const llvm::opt::OptTable & getDriverOptTable()
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.
The JSON file list parser is used to communicate input to InstallAPI.
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.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
bool scanInputForCXX20ModulesUsage(StringRef Source)
Scan an input source buffer for C++20 named module usage.
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 ...
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const FunctionProtoType * T
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.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
std::string ModeSuffix
Driver mode part of the executable name, as g++.
std::string TargetPrefix
Target part of the executable name, as i686-linux-android.