59#include "clang/Config/config.h"
75#include "llvm/ADT/ArrayRef.h"
76#include "llvm/ADT/STLExtras.h"
77#include "llvm/ADT/SmallSet.h"
78#include "llvm/ADT/SmallVector.h"
79#include "llvm/ADT/StringExtras.h"
80#include "llvm/ADT/StringRef.h"
81#include "llvm/ADT/StringSet.h"
82#include "llvm/ADT/StringSwitch.h"
83#include "llvm/Config/llvm-config.h"
84#include "llvm/MC/TargetRegistry.h"
85#include "llvm/Option/Arg.h"
86#include "llvm/Option/ArgList.h"
87#include "llvm/Option/OptSpecifier.h"
88#include "llvm/Option/OptTable.h"
89#include "llvm/Option/Option.h"
90#include "llvm/Support/CommandLine.h"
91#include "llvm/Support/ErrorHandling.h"
92#include "llvm/Support/ExitCodes.h"
93#include "llvm/Support/FileSystem.h"
94#include "llvm/Support/FileUtilities.h"
95#include "llvm/Support/FormatVariadic.h"
96#include "llvm/Support/IOSandbox.h"
97#include "llvm/Support/JSON.h"
98#include "llvm/Support/MD5.h"
99#include "llvm/Support/Path.h"
100#include "llvm/Support/PrettyStackTrace.h"
101#include "llvm/Support/Process.h"
102#include "llvm/Support/Program.h"
103#include "llvm/Support/Regex.h"
104#include "llvm/Support/StringSaver.h"
105#include "llvm/Support/VirtualFileSystem.h"
106#include "llvm/Support/raw_ostream.h"
107#include "llvm/TargetParser/Host.h"
108#include "llvm/TargetParser/RISCVISAInfo.h"
121using namespace clang;
124template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
125 return llvm::any_of(Args, [&](Arg *A) {
126 return (A->getOption().matches(options::OPT_x) &&
128 (A->getOption().
getKind() == Option::InputClass &&
129 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
131 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
137 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
138 StringRef UseCUIDStr = A->getValue();
139 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
140 .Case(
"hash", Kind::Hash)
141 .Case(
"random", Kind::Random)
142 .Case(
"none", Kind::None)
143 .Default(Kind::Invalid);
144 if (UseCUID == Kind::Invalid)
145 D.Diag(clang::diag::err_drv_invalid_value)
146 << A->getAsString(Args) << UseCUIDStr;
149 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
150 if (!FixedCUID.empty())
155 llvm::opt::DerivedArgList &Args)
const {
156 std::string CUID = FixedCUID.str();
159 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
163 llvm::MD5::MD5Result
Hash;
164 Hasher.update(InputFile);
165 for (
auto *A : Args) {
166 if (A->getOption().matches(options::OPT_INPUT))
168 Hasher.update(A->getAsString(Args));
171 CUID = llvm::utohexstr(
Hash.low(),
true);
179 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
180 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
187 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
188 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
189 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
192 this->VFS = llvm::vfs::getRealFileSystem();
197 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
200 llvm::sys::path::append(P,
SysRoot);
204#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
205 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
209 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
210 llvm::sys::path::remove_dots(configFileDir,
true);
214#if defined(CLANG_CONFIG_FILE_USER_DIR)
217 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
226void Driver::setDriverMode(StringRef
Value) {
227 static StringRef OptName =
228 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
229 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
230 .Case(
"gcc", GCCMode)
231 .Case(
"g++", GXXMode)
232 .Case(
"cpp", CPPMode)
234 .Case(
"flang", FlangMode)
235 .Case(
"dxc", DXCMode)
239 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
244 bool &ContainsError)
const {
245 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
246 ContainsError =
false;
248 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
249 unsigned MissingArgIndex, MissingArgCount;
250 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
251 MissingArgCount, VisibilityMask);
254 if (MissingArgCount) {
255 Diag(diag::err_drv_missing_argument)
256 << Args.getArgString(MissingArgIndex) << MissingArgCount;
258 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
263 for (
const Arg *A : Args) {
265 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
266 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
273 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
274 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
275 ContainsError |= Diags.getDiagnosticLevel(
276 diag::warn_drv_empty_joined_argument,
281 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
283 auto ArgString = A->getAsString(Args);
285 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
287 if (
getOpts().findExact(ArgString, Nearest,
289 DiagID = diag::err_drv_unknown_argument_with_suggestion;
290 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
292 DiagID = diag::err_drv_unknown_argument;
293 Diags.Report(DiagID) << ArgString;
296 llvm::opt::Visibility(
298 DiagID = diag::err_drv_unknown_argument_with_suggestion;
299 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
301 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
302 : diag::err_drv_unknown_argument;
303 Diags.Report(DiagID) << ArgString;
307 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
308 : diag::err_drv_unknown_argument_with_suggestion;
309 Diags.Report(DiagID) << ArgString << Nearest;
311 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
315 for (
const Arg *A : Args.filtered(options::OPT_o)) {
316 if (ArgStrings[A->getIndex()] == A->getSpelling())
320 std::string ArgString = ArgStrings[A->getIndex()];
322 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
323 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
324 << A->getAsString(Args) << Nearest;
334 Arg **FinalPhaseArg)
const {
335 Arg *PhaseArg =
nullptr;
339 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
340 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
341 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
342 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
349 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
351 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
352 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
353 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
354 options::OPT_fmodule_header_EQ))) {
357 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
360 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
361 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
375 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
378 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
386 *FinalPhaseArg = PhaseArg;
394 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
395 llvm::sys::fs::OF_Text);
396 llvm::FileRemover OutputRemover(OutputFile.c_str());
397 std::optional<llvm::StringRef> Redirects[] = {
403 std::string ErrorMessage;
404 int SecondsToWait = 60;
405 if (std::optional<std::string> Str =
406 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
407 if (!llvm::to_integer(*Str, SecondsToWait))
408 return llvm::createStringError(std::error_code(),
409 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
410 "an integer, got '" +
412 SecondsToWait = std::max(SecondsToWait, 0);
414 StringRef Executable = Args[0];
415 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
417 return llvm::createStringError(std::error_code(),
418 Executable +
": " + ErrorMessage);
420 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
421 llvm::MemoryBuffer::getFile(OutputFile.c_str());
423 return llvm::createStringError(OutputBuf.getError(),
424 "Failed to read stdout of " + Executable +
425 ": " + OutputBuf.getError().message());
426 return std::move(*OutputBuf);
430 StringRef
Value,
bool Claim) {
431 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
432 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
433 Args.AddSynthesizedArg(A);
439DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
440 const llvm::opt::OptTable &Opts =
getOpts();
441 DerivedArgList *DAL =
new DerivedArgList(Args);
443 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
444 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
445 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
446 bool IgnoreUnused =
false;
447 for (Arg *A : Args) {
451 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
455 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
456 IgnoreUnused =
false;
466 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
467 A->getOption().matches(options::OPT_Xlinker)) &&
468 A->containsValue(
"--no-demangle")) {
470 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
473 for (StringRef Val : A->getValues())
474 if (Val !=
"--no-demangle")
475 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
483 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
484 A->getNumValues() > 0 &&
485 (A->getValue(0) == StringRef(
"-MD") ||
486 A->getValue(0) == StringRef(
"-MMD"))) {
488 if (A->getValue(0) == StringRef(
"-MD"))
489 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
491 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
492 if (A->getNumValues() == 2)
493 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
498 if (A->getOption().matches(options::OPT_l)) {
499 StringRef
Value = A->getValue();
502 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
504 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
509 if (
Value ==
"cc_kext") {
510 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
516 if (A->getOption().matches(options::OPT__DASH_DASH)) {
518 for (StringRef Val : A->getValues())
527 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
528 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
531 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
532 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
536#if defined(HOST_LINK_VERSION)
537 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
538 strlen(HOST_LINK_VERSION) > 0) {
539 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
541 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
549 StringRef ArgTarget) {
551 static bool BeSilent =
false;
552 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
553 return ((v < 2) || ((v == 2) && (r < 4)));
557 if (ArgTarget.equals_insensitive(
"CURRENT")) {
561 unsigned int Version = 0;
562 unsigned int Release = 0;
563 unsigned int Modification = 0;
565 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
566 llvm::Regex HexRegex(
569 "([0-9a-fA-F][0-9a-fA-F])"
570 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
573 if (ZOsvRegex.match(ArgTarget, &Matches)) {
574 Matches[1].getAsInteger(10, Version);
575 Matches[2].getAsInteger(10, Release);
577 if (IsTooOldToBeSupported(Version, Release)) {
579 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
582 }
else if (HexRegex.match(ArgTarget, &Matches)) {
583 Matches[1].getAsInteger(16, Version);
584 Matches[2].getAsInteger(16, Release);
585 Matches[3].getAsInteger(16, Modification);
586 if (IsTooOldToBeSupported(Version, Release)) {
588 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
594 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
599 llvm::VersionTuple
V(Version, Release, Modification);
600 llvm::VersionTuple TV =
Target.getOSVersion();
603 if (TV.empty() ||
V < TV) {
605 Str = llvm::Triple::getOSTypeName(
Target.getOS());
606 Str +=
V.getAsString();
619 StringRef TargetTriple,
621 StringRef DarwinArchName =
"") {
623 if (
const Arg *A = Args.getLastArg(options::OPT_target))
624 TargetTriple = A->getValue();
626 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
631 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
635 if (
Target.isOSBinFormatMachO()) {
637 if (!DarwinArchName.empty()) {
644 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
645 StringRef ArchName = A->getValue();
652 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
653 options::OPT_mbig_endian)) {
654 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
655 ?
Target.getLittleEndianArchVariant()
656 :
Target.getBigEndianArchVariant();
657 if (T.getArch() != llvm::Triple::UnknownArch) {
659 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
664 if (
Target.getArch() == llvm::Triple::tce)
669 if (std::optional<std::string> ObjectModeValue =
670 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
671 StringRef ObjectMode = *ObjectModeValue;
672 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
674 if (ObjectMode ==
"64") {
675 AT =
Target.get64BitArchVariant().getArch();
676 }
else if (ObjectMode ==
"32") {
677 AT =
Target.get32BitArchVariant().getArch();
679 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
682 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
688 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
689 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
692 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
694 D.
Diag(diag::err_drv_unsupported_opt_for_target)
695 << A->getAsString(Args) <<
Target.str();
698 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
699 options::OPT_m32, options::OPT_m16,
700 options::OPT_maix32, options::OPT_maix64);
702 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
704 if (A->getOption().matches(options::OPT_m64) ||
705 A->getOption().matches(options::OPT_maix64)) {
706 AT =
Target.get64BitArchVariant().getArch();
707 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
708 Target.getEnvironment() == llvm::Triple::GNUT64)
709 Target.setEnvironment(llvm::Triple::GNU);
710 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
711 Target.setEnvironment(llvm::Triple::Musl);
712 }
else if (A->getOption().matches(options::OPT_mx32) &&
713 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
714 AT = llvm::Triple::x86_64;
715 if (
Target.getEnvironment() == llvm::Triple::Musl)
716 Target.setEnvironment(llvm::Triple::MuslX32);
718 Target.setEnvironment(llvm::Triple::GNUX32);
719 }
else if (A->getOption().matches(options::OPT_m32) ||
720 A->getOption().matches(options::OPT_maix32)) {
722 D.
Diag(diag::err_drv_unsupported_opt_for_target)
723 << A->getAsString(Args) <<
Target.str();
725 AT =
Target.get32BitArchVariant().getArch();
726 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
727 Target.setEnvironment(llvm::Triple::GNU);
728 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
729 Target.setEnvironment(llvm::Triple::Musl);
731 }
else if (A->getOption().matches(options::OPT_m16) &&
732 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
733 AT = llvm::Triple::x86;
734 Target.setEnvironment(llvm::Triple::CODE16);
737 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
739 if (
Target.isWindowsGNUEnvironment())
745 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
751 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
752 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
753 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
756 if (A && !A->getOption().matches(options::OPT_m32))
757 D.
Diag(diag::err_drv_argument_not_allowed_with)
758 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
760 Target.setArch(llvm::Triple::x86);
761 Target.setArchName(
"i586");
762 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
763 Target.setEnvironmentName(
"");
764 Target.setOS(llvm::Triple::ELFIAMCU);
765 Target.setVendor(llvm::Triple::UnknownVendor);
766 Target.setVendorName(
"intel");
772 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
773 StringRef ABIName = A->getValue();
774 if (ABIName ==
"32") {
776 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
777 Target.getEnvironment() == llvm::Triple::GNUABIN32)
778 Target.setEnvironment(llvm::Triple::GNU);
779 }
else if (ABIName ==
"n32") {
781 if (
Target.getEnvironment() == llvm::Triple::GNU ||
782 Target.getEnvironment() == llvm::Triple::GNUT64 ||
783 Target.getEnvironment() == llvm::Triple::GNUABI64)
784 Target.setEnvironment(llvm::Triple::GNUABIN32);
785 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
786 Target.getEnvironment() == llvm::Triple::MuslABI64)
787 Target.setEnvironment(llvm::Triple::MuslABIN32);
788 }
else if (ABIName ==
"64") {
790 if (
Target.getEnvironment() == llvm::Triple::GNU ||
791 Target.getEnvironment() == llvm::Triple::GNUT64 ||
792 Target.getEnvironment() == llvm::Triple::GNUABIN32)
793 Target.setEnvironment(llvm::Triple::GNUABI64);
794 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
795 Target.getEnvironment() == llvm::Triple::MuslABIN32)
796 Target.setEnvironment(llvm::Triple::MuslABI64);
804 if (Args.hasArg(options::OPT_march_EQ) ||
805 Args.hasArg(options::OPT_mcpu_EQ)) {
807 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
809 if (!llvm::errorToBool(ISAInfo.takeError())) {
810 unsigned XLen = (*ISAInfo)->getXLen();
812 if (
Target.isLittleEndian())
813 Target.setArch(llvm::Triple::riscv32);
815 Target.setArch(llvm::Triple::riscv32be);
816 }
else if (XLen == 64) {
817 if (
Target.isLittleEndian())
818 Target.setArch(llvm::Triple::riscv64);
820 Target.setArch(llvm::Triple::riscv64be);
826 if (
Target.getArch() == llvm::Triple::riscv32be ||
827 Target.getArch() == llvm::Triple::riscv64be) {
828 static bool WarnedRISCVBE =
false;
829 if (!WarnedRISCVBE) {
830 D.
Diag(diag::warn_drv_riscv_be_experimental);
831 WarnedRISCVBE =
true;
842 OptSpecifier OptEq, OptSpecifier OptNeg) {
843 if (!Args.hasFlag(OptEq, OptNeg,
false))
846 const Arg *A = Args.getLastArg(OptEq);
847 StringRef LTOName = A->getValue();
855 D.
Diag(diag::err_drv_unsupported_option_argument)
856 << A->getSpelling() << A->getValue();
863void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
865 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
867 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
868 options::OPT_fno_offload_lto);
871 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
872 options::OPT_fno_openmp_target_jit,
false)) {
873 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
874 options::OPT_fno_offload_lto))
876 Diag(diag::err_drv_incompatible_options)
877 << A->getSpelling() <<
"-fopenmp-target-jit";
884 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
886 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
888 RuntimeName = A->getValue();
890 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
898 Diag(diag::err_drv_unsupported_option_argument)
899 << A->getSpelling() << A->getValue();
902 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
911 StringRef Program =
C.getArgs().getLastArgValue(
912 options::OPT_offload_arch_tool_EQ,
"offload-arch");
915 if (llvm::ErrorOr<std::string> Executable =
916 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
919 Args.push_back(
"--only=amdgpu");
921 Args.push_back(
"--only=nvptx");
922 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
925 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
930 if ((*StdoutOrErr)->getBuffer().empty()) {
931 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
937 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
939 GPUArchs.push_back(
Arch.str());
941 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
952 std::set<std::string> Archs;
953 for (Arg *A :
C.getInputArgs()) {
954 for (StringRef
Arch : A->getValues()) {
955 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
956 if (
Arch ==
"native") {
958 Archs.insert(Str.str());
960 Archs.insert(
Arch.str());
962 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
966 Archs.erase(
Arch.str());
972 for (llvm::StringRef
Arch : Archs) {
979 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
984 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
990 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
995 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
996 <<
"offload" <<
Arch;
1000 llvm::Triple Triple =
1006 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1007 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1008 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1009 C.getArgs().MakeArgString(Triple.getArchName()),
1010 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1012 C.getArgs().append(A);
1013 C.getArgs().AddSynthesizedArg(A);
1015 auto It = Triples.lower_bound(Triple);
1016 if (It == Triples.end() || *It != Triple)
1017 Triples.insert(It, Triple);
1022 Triples.insert(llvm::Triple(
"amdgcn-amd-amdhsa"));
1025 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1026 ?
"nvptx64-nvidia-cuda"
1027 :
"nvptx-nvidia-cuda"));
1030 llvm::Triple(
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)
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) {
1102 if (ArgValues.empty())
1103 Diag(clang::diag::warn_drv_empty_joined_argument)
1105 .getLastArg(options::OPT_offload_targets_EQ)
1106 ->getAsString(
C.getInputArgs());
1113 llvm::StringMap<StringRef> FoundNormalizedTriples;
1114 for (
const llvm::Triple &
Target : Triples) {
1119 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1127 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1128 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1129 Diag(clang::diag::err_drv_argument_not_allowed_with)
1130 << IncompatArg->getSpelling() <<
"-fsycl";
1135 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1136 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1141 std::string NormalizedName =
Target.normalize();
1142 auto [TripleIt, Inserted] =
1143 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1145 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1146 <<
Target.str() << TripleIt->second;
1150 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1151 C.getDefaultToolChain().getTriple());
1155 auto &CudaInstallation =
1157 if (CudaInstallation.isValid())
1158 CudaInstallation.WarnIfUnsupportedVersion();
1161 C.addOffloadDeviceToolChain(&TC, Kind);
1166bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1171 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1175 if (!PathLIBEnv.empty()) {
1176 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1177 if (llvm::sys::fs::is_directory(PathLIBEnv))
1178 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1179 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1180 return readConfigFile(CustomizationFile, ExpCtx);
1181 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1186 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1187 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1188 return readConfigFile(CustomizationFile, ExpCtx);
1198 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1199 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1200 Copy->getValues() = Opt->getValues();
1201 if (Opt->isClaimed())
1203 Copy->setOwnsValues(Opt->getOwnsValues());
1204 Opt->setOwnsValues(
false);
1206 if (Opt->getAlias()) {
1207 const Arg *Alias = Opt->getAlias();
1208 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1209 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1210 Args.getArgString(Index), Index);
1211 AliasCopy->getValues() = Alias->getValues();
1212 AliasCopy->setOwnsValues(
false);
1213 if (Alias->isClaimed())
1215 Copy->setAlias(std::move(AliasCopy));
1219bool Driver::readConfigFile(StringRef
FileName,
1220 llvm::cl::ExpansionContext &ExpCtx) {
1224 Diag(diag::err_drv_cannot_open_config_file)
1225 <<
FileName << Status.getError().message();
1228 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1229 Diag(diag::err_drv_cannot_open_config_file)
1230 <<
FileName <<
"not a regular file";
1235 SmallVector<const char *, 32> NewCfgFileArgs;
1236 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1237 Diag(diag::err_drv_cannot_read_config_file)
1243 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1244 for (
const char *Opt : NewCfgFileArgs) {
1246 if (Opt[0] ==
'$' && Opt[1])
1247 NewCfgTailArgs.push_back(Opt + 1);
1249 NewCfgHeadArgs.push_back(Opt);
1253 llvm::SmallString<128> CfgFileName(
FileName);
1254 llvm::sys::path::native(CfgFileName);
1255 bool ContainErrors =
false;
1256 auto NewHeadOptions = std::make_unique<InputArgList>(
1260 auto NewTailOptions = std::make_unique<InputArgList>(
1267 for (Arg *A : *NewHeadOptions)
1269 for (Arg *A : *NewTailOptions)
1272 if (!CfgOptionsHead)
1273 CfgOptionsHead = std::move(NewHeadOptions);
1276 for (
auto *Opt : *NewHeadOptions)
1280 if (!CfgOptionsTail)
1281 CfgOptionsTail = std::move(NewTailOptions);
1284 for (
auto *Opt : *NewTailOptions)
1288 ConfigFiles.push_back(std::string(CfgFileName));
1292bool Driver::loadConfigFiles() {
1293 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1294 llvm::cl::tokenizeConfigFile, &
getVFS());
1298 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1299 SmallString<128> CfgDir;
1301 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1302 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1307 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1308 SmallString<128> CfgDir;
1309 llvm::sys::fs::expand_tilde(
1310 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1311 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1320 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1323 if (loadDefaultConfigFiles(ExpCtx))
1327 SmallString<128> CfgFilePath;
1329 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1332 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1333 CfgFilePath.assign(CfgFileName);
1334 if (llvm::sys::path::is_relative(CfgFilePath)) {
1335 if (
getVFS().makeAbsolute(CfgFilePath)) {
1336 Diag(diag::err_drv_cannot_open_config_file)
1337 << CfgFilePath <<
"cannot get absolute path";
1341 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1343 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1344 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1345 if (!SearchDir.empty())
1346 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1351 if (readConfigFile(CfgFilePath, ExpCtx))
1362 llvm::Triple Triple, std::string Suffix) {
1364 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1368 VersionTuple OSVersion = Triple.getOSVersion();
1369 if (!OSVersion.getMinor().has_value())
1372 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1376 if (OSVersion.getMajor() != 0) {
1377 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1378 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1384 Triple.setOSName(BaseOSName);
1385 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1388bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1391 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1395 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1398 std::string RealMode = getExecutableForDriverMode(Mode);
1399 llvm::Triple Triple;
1408 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1409 PrefixTriple.isOSUnknown())
1410 Triple = std::move(PrefixTriple);
1414 llvm::Triple RealTriple =
1416 if (Triple.str().empty()) {
1417 Triple = RealTriple;
1418 assert(!Triple.str().empty());
1423 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1437 SmallString<128> CfgFilePath;
1439 "-" + RealMode +
".cfg"))
1440 return readConfigFile(CfgFilePath, ExpCtx);
1444 if (TryModeSuffix) {
1447 return readConfigFile(CfgFilePath, ExpCtx);
1452 std::string CfgFileName = RealMode +
".cfg";
1453 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1454 if (readConfigFile(CfgFilePath, ExpCtx))
1456 }
else if (TryModeSuffix) {
1458 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1459 readConfigFile(CfgFilePath, ExpCtx))
1465 return readConfigFile(CfgFilePath, ExpCtx);
1473 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1482 if (!DriverMode.empty())
1483 setDriverMode(DriverMode);
1489 CLOptions = std::make_unique<InputArgList>(
1494 ContainsError = loadConfigFiles();
1495 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1496 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1500 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1502 if (HasConfigFileHead)
1503 for (
auto *Opt : *CLOptions)
1504 if (!Opt->getOption().matches(options::OPT_config))
1508 if (
IsCLMode() && !ContainsError) {
1510 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1512 CLModePassThroughArgList.push_back(A->getValue());
1515 if (!CLModePassThroughArgList.empty()) {
1518 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1523 for (
auto *Opt : *CLModePassThroughOptions)
1529 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1530 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1531 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1534 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1535 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1536 if (!VFS->exists(IncludeDir))
1537 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1542 bool CCCPrintPhases;
1545 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1546 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1549 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1550 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1553 Args.ClaimAllArgs(options::OPT_pipe);
1561 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1563 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1564 CCCGenericGCCName = A->getValue();
1567 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1571 if (Args.hasArg(options::OPT_fproc_stat_report))
1578 llvm::Triple T(TargetTriple);
1579 T.setOS(llvm::Triple::Win32);
1580 T.setVendor(llvm::Triple::PC);
1581 T.setEnvironment(llvm::Triple::MSVC);
1582 T.setObjectFormat(llvm::Triple::COFF);
1583 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1584 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1585 TargetTriple = T.str();
1588 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1589 StringRef TargetProfile = A->getValue();
1592 TargetTriple = *Triple;
1594 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1598 if (Args.hasArg(options::OPT_spirv)) {
1599 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1600 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1601 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1602 llvm::Triple T(TargetTriple);
1605 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1607 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1608 TargetInfo = ValidTargets.find(A->getValue());
1610 Diag(diag::err_drv_invalid_value)
1611 << A->getAsString(Args) << A->getValue();
1617 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1618 TargetTriple = T.str();
1622 Diag(diag::err_drv_dxc_missing_target_profile);
1626 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1627 TargetTriple = A->getValue();
1628 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1629 Dir =
Dir = A->getValue();
1630 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1634 if (std::optional<std::string> CompilerPathValue =
1635 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1636 StringRef CompilerPath = *CompilerPathValue;
1637 while (!CompilerPath.empty()) {
1638 std::pair<StringRef, StringRef> Split =
1639 CompilerPath.split(llvm::sys::EnvPathSeparator);
1640 PrefixDirs.push_back(std::string(Split.first));
1641 CompilerPath = Split.second;
1644 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1646 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1649 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1652 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1653 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1654 .Case(
"cwd", SaveTempsCwd)
1655 .Case(
"obj", SaveTempsObj)
1656 .Default(SaveTempsCwd);
1659 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1660 options::OPT_offload_device_only,
1661 options::OPT_offload_host_device)) {
1662 if (A->getOption().matches(options::OPT_offload_host_only))
1663 Offload = OffloadHost;
1664 else if (A->getOption().matches(options::OPT_offload_device_only))
1665 Offload = OffloadDevice;
1667 Offload = OffloadHostDevice;
1673 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1674 StringRef
Name = A->getValue();
1675 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1676 .Case(
"off", EmbedNone)
1677 .Case(
"all", EmbedBitcode)
1678 .Case(
"bitcode", EmbedBitcode)
1679 .Case(
"marker", EmbedMarker)
1682 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1685 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1689 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1690 llvm::sys::fs::remove(A->getValue());
1696 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1698 !Args.hasArg(options::OPT_fmodules) && Std &&
1699 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1700 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1701 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1702 Std->containsValue(
"c++latest"));
1705 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1706 options::OPT_fmodule_header)) {
1708 ModulesModeCXX20 =
true;
1709 if (A->getOption().matches(options::OPT_fmodule_header))
1712 StringRef ArgName = A->getValue();
1713 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1718 Diags.Report(diag::err_drv_invalid_value)
1719 << A->getAsString(Args) << ArgName;
1725 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1726 std::make_unique<InputArgList>(std::move(Args));
1736 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1737 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1739 bool MLContainsError;
1740 auto MultilibMacroDefineList =
1742 MLMacroDefinesChar,
false, MLContainsError));
1743 if (!MLContainsError) {
1744 for (
auto *Opt : *MultilibMacroDefineList) {
1751 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1755 if (!Triple.isWasm()) {
1756 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1757 StringRef TripleObjectFormat =
1758 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1759 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1760 TripleVersionName != TripleObjectFormat) {
1761 Diags.Report(diag::err_drv_triple_version_invalid)
1763 ContainsError =
true;
1768 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1769 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1770 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1778 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1779 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1781 case llvm::Triple::arm:
1782 case llvm::Triple::armeb:
1783 case llvm::Triple::thumb:
1784 case llvm::Triple::thumbeb:
1785 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1786 Diag(diag::warn_target_unrecognized_env)
1788 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1791 case llvm::Triple::aarch64:
1792 case llvm::Triple::aarch64_be:
1793 case llvm::Triple::aarch64_32:
1794 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1795 Diag(diag::warn_target_unrecognized_env)
1797 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1814 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1815 if (HasConfigFileTail && Inputs.size()) {
1818 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1819 for (Arg *A : *CfgOptionsTail)
1820 TranslatedLinkerIns.append(A);
1821 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1828 bool UseModulesDriver =
C->getArgs().hasFlag(
1829 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1831 if (UseModulesDriver) {
1832 Diags.Report(diag::remark_performing_driver_managed_module_build);
1838 const auto StdModuleManifestPath =
1841 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1842 Diags.Report(diag::remark_modules_manifest_not_found);
1844 Diags.Report(diag::remark_using_modules_manifest)
1845 << StdModuleManifestPath;
1846 if (
auto ManifestOrErr =
1848 ModulesManifest = std::move(*ManifestOrErr);
1850 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1851 return !ModuleEntry.IsStdlib;
1856 llvm::handleAllErrors(
1857 ManifestOrErr.takeError(),
1858 [&](llvm::json::ParseError &Err) {
1859 Diags.Report(diag::err_modules_manifest_failed_parse)
1862 [&](llvm::FileError &Err) {
1863 Diags.Report(diag::err_cannot_open_file)
1864 << Err.getFileName() << Err.messageWithoutFileInfo();
1872 if (TC.
getTriple().isOSBinFormatMachO())
1877 if (CCCPrintPhases) {
1884 if (UseModulesDriver)
1891 llvm::opt::ArgStringList ASL;
1892 for (
const auto *A : Args) {
1896 while (A->getAlias())
1898 A->render(Args, ASL);
1901 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1902 if (I != ASL.begin())
1904 llvm::sys::printArg(OS, *I,
true);
1909bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1910 SmallString<128> &CrashDiagDir) {
1911 using namespace llvm::sys;
1912 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1913 "Only knows about .crash files on Darwin");
1915 auto BypassSandbox = sandbox::scopedDisable();
1920 path::home_directory(CrashDiagDir);
1921 if (CrashDiagDir.starts_with(
"/var/root"))
1923 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1931 fs::file_status FileStatus;
1932 TimePoint<> LastAccessTime;
1933 SmallString<128> CrashFilePath;
1936 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1937 File != FileEnd && !EC;
File.increment(EC)) {
1941 if (fs::status(
File->path(), FileStatus))
1943 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1944 llvm::MemoryBuffer::getFile(
File->path());
1949 StringRef
Data = CrashFile.get()->getBuffer();
1950 if (!
Data.starts_with(
"Process:"))
1953 size_t ParentProcPos =
Data.find(
"Parent Process:");
1954 if (ParentProcPos == StringRef::npos)
1956 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1957 if (LineEnd == StringRef::npos)
1959 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1960 int OpenBracket = -1, CloseBracket = -1;
1961 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1962 if (ParentProcess[i] ==
'[')
1964 if (ParentProcess[i] ==
']')
1970 if (OpenBracket < 0 || CloseBracket < 0 ||
1971 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1972 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1982 const auto FileAccessTime = FileStatus.getLastModificationTime();
1983 if (FileAccessTime > LastAccessTime) {
1984 CrashFilePath.assign(
File->path());
1985 LastAccessTime = FileAccessTime;
1990 if (!CrashFilePath.empty()) {
1991 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2001 "\n********************\n\n"
2002 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2003 "Preprocessed source(s) and associated run script(s) are located at:";
2011 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2015 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2016 Level = llvm::StringSwitch<unsigned>(A->getValue())
2018 .Case(
"compiler", 1)
2030 ArgStringList SavedTemps;
2032 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2033 if (!IsLLD || Level < 2)
2040 SavedTemps = std::move(
C.getTempFiles());
2041 assert(!
C.getTempFiles().size());
2058 C.initCompilationForDiagnostics();
2063 Command NewLLDInvocation = Cmd;
2064 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2065 StringRef ReproduceOption =
2066 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2069 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2073 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2075 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2076 Diag(clang::diag::note_drv_command_failed_diag_msg)
2077 <<
"\n\n********************";
2079 Report->TemporaryFiles.push_back(TmpName);
2087 ArgStringList IRInputs;
2088 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2089 bool IgnoreInput =
false;
2095 IRInputs.push_back(it->second->getValue());
2099 }
else if (!strcmp(it->second->getValue(),
"-")) {
2100 Diag(clang::diag::note_drv_command_failed_diag_msg)
2101 <<
"Error generating preprocessed source(s) - "
2102 "ignoring input from stdin.";
2107 it = Inputs.erase(it);
2114 if (Inputs.empty() && IRInputs.empty()) {
2115 Diag(clang::diag::note_drv_command_failed_diag_msg)
2116 <<
"Error generating preprocessed source(s) - "
2117 "no preprocessable inputs.";
2124 for (
const Arg *A :
C.getArgs()) {
2125 if (A->getOption().matches(options::OPT_arch)) {
2126 StringRef ArchName = A->getValue();
2131 Diag(clang::diag::note_drv_command_failed_diag_msg)
2132 <<
"Error generating preprocessed source(s) - cannot generate "
2133 "preprocessed source with multiple -arch options.";
2138 if (!Inputs.empty()) {
2141 const ToolChain &TC =
C.getDefaultToolChain();
2142 if (TC.
getTriple().isOSBinFormatMachO())
2151 Diag(clang::diag::note_drv_command_failed_diag_msg)
2152 <<
"Error generating preprocessed source(s).";
2157 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2160 if (!FailingCommands.empty()) {
2161 Diag(clang::diag::note_drv_command_failed_diag_msg)
2162 <<
"Error generating preprocessed source(s).";
2166 const ArgStringList &TempFiles =
C.getTempFiles();
2167 if (TempFiles.empty()) {
2168 Diag(clang::diag::note_drv_command_failed_diag_msg)
2169 <<
"Error generating preprocessed source(s).";
2175 const ArgStringList &Files =
C.getTempFiles();
2180 for (
auto const *Input : IRInputs) {
2184 StringRef extension = llvm::sys::path::extension(Input);
2185 if (!extension.empty())
2186 extension = extension.drop_front();
2188 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2189 llvm::sys::path::stem(Input), extension, FD, Path);
2191 Diag(clang::diag::note_drv_command_failed_diag_msg)
2192 <<
"Error generating run script: " <<
"Failed copying IR input files"
2193 <<
" " << EC.message();
2197 EC = llvm::sys::fs::copy_file(Input, FD);
2199 Diag(clang::diag::note_drv_command_failed_diag_msg)
2200 <<
"Error generating run script: " <<
"Failed copying IR input files"
2201 <<
" " << EC.message();
2205 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2212 for (std::string &TempFile : TempFiles) {
2213 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2215 Report->TemporaryFiles.push_back(TempFile);
2216 if (ReproCrashFilename.empty()) {
2217 ReproCrashFilename = TempFile;
2218 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2220 if (StringRef(TempFile).ends_with(
".cache")) {
2223 VFS = llvm::sys::path::filename(TempFile);
2224 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2228 for (
const char *TempFile : SavedTemps)
2229 TempFiles.push_back(TempFile);
2235 llvm::sys::path::replace_extension(Script,
"sh");
2237 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2238 llvm::sys::fs::FA_Write,
2239 llvm::sys::fs::OF_Text);
2241 Diag(clang::diag::note_drv_command_failed_diag_msg)
2242 <<
"Error generating run script: " << Script <<
" " << EC.message();
2245 <<
"# Driver args: ";
2247 ScriptOS <<
"# Original command: ";
2248 Cmd.
Print(ScriptOS,
"\n",
true);
2249 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2250 if (!AdditionalInformation.empty())
2251 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2254 Report->TemporaryFiles.push_back(std::string(Script));
2255 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2259 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2261 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2262 Diag(clang::diag::note_drv_command_failed_diag_msg)
2263 << ReproCrashFilename.str();
2265 llvm::sys::path::append(CrashDiagDir,
Name);
2266 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2267 Diag(clang::diag::note_drv_command_failed_diag_msg)
2268 <<
"Crash backtrace is located in";
2269 Diag(clang::diag::note_drv_command_failed_diag_msg)
2270 << CrashDiagDir.str();
2271 Diag(clang::diag::note_drv_command_failed_diag_msg)
2272 <<
"(choose the .crash file that corresponds to your crash)";
2276 Diag(clang::diag::note_drv_command_failed_diag_msg)
2277 <<
"\n\n********************";
2287 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2298 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2299 if (
C.getArgs().hasArg(options::OPT_v))
2300 C.getJobs().Print(llvm::errs(),
"\n",
true);
2302 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2305 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2312 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2313 C.getJobs().Print(llvm::errs(),
"\n",
true);
2314 return Diags.hasErrorOccurred() ? 1 : 0;
2318 if (Diags.hasErrorOccurred())
2322 for (
auto &Job :
C.getJobs())
2323 setUpResponseFiles(
C, Job);
2325 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2328 if (FailingCommands.empty())
2334 for (
const auto &CmdPair : FailingCommands) {
2335 int CommandRes = CmdPair.first;
2336 const Command *FailingCommand = CmdPair.second;
2341 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2345 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2350 if (CommandRes == EX_IOERR) {
2370 if (CommandRes > 128 && CommandRes != 255)
2374 Diag(clang::diag::err_drv_command_signalled)
2377 Diag(clang::diag::err_drv_command_failed)
2385 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2387 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2401 const ToolChain &TC =
C.getDefaultToolChain();
2405 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2408 OS <<
"Thread model: " << A->getValue();
2414 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2419 if (!llvm::cl::getCompilerBuildConfig().empty())
2420 llvm::cl::printBuildConfig(OS);
2423 for (
auto ConfigFile : ConfigFiles)
2424 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2437 if (PassedFlags ==
"")
2441 std::vector<std::string> SuggestedCompletions;
2442 std::vector<std::string> Flags;
2454 const bool HasSpace = PassedFlags.ends_with(
",");
2458 StringRef TargetFlags = PassedFlags;
2459 while (TargetFlags !=
"") {
2461 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2462 Flags.push_back(std::string(CurFlag));
2467 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2470 const llvm::opt::OptTable &Opts =
getOpts();
2472 Cur = Flags.at(Flags.size() - 1);
2474 if (Flags.size() >= 2) {
2475 Prev = Flags.at(Flags.size() - 2);
2476 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2479 if (SuggestedCompletions.empty())
2480 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2487 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2488 llvm::outs() <<
'\n';
2494 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2498 SuggestedCompletions = Opts.findByPrefix(
2499 Cur, VisibilityMask,
2506 if (S.starts_with(Cur))
2507 SuggestedCompletions.push_back(std::string(S));
2514 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2515 if (
int X = A.compare_insensitive(B))
2517 return A.compare(B) > 0;
2520 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2527 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2528 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2532 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2535 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2539 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2544 if (
C.getArgs().hasArg(options::OPT_help) ||
2545 C.getArgs().hasArg(options::OPT__help_hidden)) {
2546 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2550 if (
C.getArgs().hasArg(options::OPT__version)) {
2557 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2558 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2559 if (ListExtractors || ListFormats) {
2567 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2572 if (
C.getArgs().hasArg(options::OPT_v) ||
2573 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2574 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2575 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2576 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2578 SuppressMissingInputWarning =
true;
2581 if (
C.getArgs().hasArg(options::OPT_v)) {
2583 llvm::errs() <<
"System configuration file directory: "
2586 llvm::errs() <<
"User configuration file directory: "
2590 const ToolChain &TC =
C.getDefaultToolChain();
2592 if (
C.getArgs().hasArg(options::OPT_v))
2595 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2600 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2601 llvm::outs() <<
"programs: =";
2602 bool separator =
false;
2606 llvm::outs() << llvm::sys::EnvPathSeparator;
2607 llvm::outs() << Path;
2612 llvm::outs() << llvm::sys::EnvPathSeparator;
2613 llvm::outs() << Path;
2616 llvm::outs() <<
"\n";
2619 StringRef sysroot =
C.getSysRoot();
2623 llvm::outs() << llvm::sys::EnvPathSeparator;
2626 llvm::outs() << sysroot << Path.substr(1);
2628 llvm::outs() << Path;
2630 llvm::outs() <<
"\n";
2634 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2640 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2641 for (
auto RuntimePath :
2643 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2644 llvm::outs() << *RuntimePath <<
'\n';
2648 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2652 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2654 for (std::size_t I = 0; I != Flags.size(); I += 2)
2655 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2661 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2662 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2666 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2667 StringRef ProgName = A->getValue();
2670 if (! ProgName.empty())
2673 llvm::outs() <<
"\n";
2677 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2678 StringRef PassedFlags = A->getValue();
2683 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2697 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2700 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2706 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2713 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2716 std::set<llvm::StringRef> SortedFlags;
2717 for (
const auto &FlagEntry : ExpandedFlags)
2718 SortedFlags.insert(FlagEntry.getKey());
2719 for (
auto Flag : SortedFlags)
2720 llvm::outs() << Flag <<
'\n';
2724 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2727 llvm::outs() <<
".\n";
2730 assert(Suffix.front() ==
'/');
2731 llvm::outs() << Suffix.substr(1) <<
"\n";
2737 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2742 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2744 llvm::outs() << Triple.getTriple() <<
"\n";
2748 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2749 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2766 std::map<Action *, unsigned> &Ids,
2768 if (
auto It = Ids.find(A); It != Ids.end())
2772 llvm::raw_string_ostream os(str);
2774 auto getSibIndent = [](
int K) -> Twine {
2778 Twine SibIndent =
Indent + getSibIndent(Kind);
2782 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2784 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2785 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2786 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2788 OA->doOnEachDependence(
2790 assert(TC &&
"Unknown host toolchain");
2802 os <<
":" << BoundArch;
2805 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2813 const char *Prefix =
"{";
2814 for (
Action *PreRequisite : *AL) {
2815 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2826 std::string offload_str;
2827 llvm::raw_string_ostream offload_os(offload_str);
2831 offload_os <<
", (" << S;
2838 auto getSelfIndent = [](
int K) -> Twine {
2842 unsigned Id = Ids.size();
2844 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2853 std::map<Action *, unsigned> Ids;
2854 for (
Action *A :
C.getActions())
2870 DerivedArgList &Args =
C.getArgs();
2872 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2877 for (Arg *A : Args) {
2878 if (A->getOption().matches(options::OPT_arch)) {
2881 llvm::Triple::ArchType
Arch =
2883 if (
Arch == llvm::Triple::UnknownArch) {
2884 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2889 if (
ArchNames.insert(A->getValue()).second)
2890 Archs.push_back(A->getValue());
2904 for (
Action* Act : SingleActions) {
2912 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2916 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2921 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2922 Actions.append(Inputs.begin(), Inputs.end());
2924 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2927 Arg *A = Args.getLastArg(options::OPT_g_Group);
2928 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2929 !A->getOption().matches(options::OPT_gstabs);
2930 bool enablesPseudoProbe =
2931 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2932 options::OPT_fno_pseudo_probe_for_profiling,
false);
2933 bool enablesDebugInfoForProfiling =
2934 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2935 options::OPT_fno_debug_info_for_profiling,
false);
2936 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2937 enablesDebugInfoForProfiling) &&
2945 if (Act->getType() == types::TY_Image) {
2947 Inputs.push_back(Actions.back());
2954 if (Args.hasArg(options::OPT_verify_debug_info)) {
2955 Action *LastAction = Actions.pop_back_val();
2957 LastAction, types::TY_Nothing));
2964 bool TypoCorrect)
const {
2976 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2977 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2989 std::string Nearest;
2990 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2991 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2992 <<
Value << Nearest;
3031 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3034 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3042 return types::TY_CXXUHeader;
3044 return types::TY_CXXSHeader;
3048 llvm_unreachable(
"should not be called in this case");
3050 return types::TY_CXXHUHeader;
3056 const llvm::opt::OptTable &Opts =
getOpts();
3060 types::ID InputType = types::TY_Nothing;
3061 Arg *InputTypeArg =
nullptr;
3064 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3065 options::OPT__SLASH_TP)) {
3066 InputTypeArg = TCTP;
3067 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3072 bool ShowNote =
false;
3074 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3076 Diag(clang::diag::warn_drv_overriding_option)
3077 <<
Previous->getSpelling() << A->getSpelling();
3083 Diag(clang::diag::note_drv_t_option_is_global);
3088 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3089 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3090 if (LastXArg && LastInputArg &&
3091 LastInputArg->getIndex() < LastXArg->getIndex())
3092 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3095 for (Arg *A : Args) {
3096 if (A->getOption().
getKind() == Option::InputClass) {
3097 const char *
Value = A->getValue();
3101 if (InputType == types::TY_Nothing) {
3104 InputTypeArg->claim();
3107 if (strcmp(
Value,
"-") == 0) {
3109 Ty = types::TY_Fortran;
3111 Ty = types::TY_HLSL;
3120 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3121 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3122 : clang::diag::err_drv_unknown_stdin_type);
3131 if (
const char *Ext = strrchr(
Value,
'.'))
3140 Ty = types::TY_HLSL;
3142 Ty = types::TY_Object;
3153 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3154 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3155 << getTypeName(OldTy) << getTypeName(Ty);
3160 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3161 Ty == types::TY_Object)
3162 Ty = types::TY_LLVM_BC;
3170 if (Ty != types::TY_Object) {
3171 if (Args.hasArg(options::OPT_ObjC))
3172 Ty = types::TY_ObjC;
3173 else if (Args.hasArg(options::OPT_ObjCXX))
3174 Ty = types::TY_ObjCXX;
3181 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3185 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3186 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3189 const char *Ext = strrchr(
Value,
'.');
3191 Ty = types::TY_Object;
3195 InputTypeArg->claim();
3199 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3200 Args.hasArgNoClaim(options::OPT_hipstdpar))
3204 Inputs.push_back(std::make_pair(Ty, A));
3206 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3207 StringRef
Value = A->getValue();
3210 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3211 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3214 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3215 StringRef
Value = A->getValue();
3218 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3219 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3225 Inputs.push_back(std::make_pair(types::TY_Object, A));
3227 }
else if (A->getOption().matches(options::OPT_x)) {
3236 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3237 InputType = types::TY_Object;
3244 }
else if (A->getOption().getID() == options::OPT_U) {
3245 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3246 StringRef Val = A->getValue(0);
3247 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3249 Diag(diag::warn_slash_u_filename) << Val;
3250 Diag(diag::note_use_dashdash);
3254 if (
CCCIsCPP() && Inputs.empty()) {
3258 Inputs.push_back(std::make_pair(types::TY_C, A));
3265class OffloadingActionBuilder final {
3267 bool IsValid =
false;
3273 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3276 std::map<Action *, const Arg *> HostActionToInputArgMap;
3279 class DeviceActionBuilder {
3283 enum ActionBuilderReturnCode {
3301 const ToolChain *FatBinaryToolChain =
nullptr;
3304 DerivedArgList &Args;
3313 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3316 :
C(
C), Args(Args), Inputs(Inputs),
3317 AssociatedOffloadKind(AssociatedOffloadKind) {}
3318 virtual ~DeviceActionBuilder() {}
3323 virtual ActionBuilderReturnCode
3324 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3327 return ABRT_Inactive;
3332 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3333 return ABRT_Inactive;
3337 virtual void appendTopLevelActions(
ActionList &AL) {}
3340 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3343 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3346 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3353 virtual bool canUseBundlerUnbundler()
const {
return false; }
3357 bool isValid() {
return !ToolChains.empty(); }
3361 return AssociatedOffloadKind;
3367 class CudaActionBuilderBase :
public DeviceActionBuilder {
3371 bool CompileHostOnly =
false;
3372 bool CompileDeviceOnly =
false;
3374 bool EmitAsm =
false;
3384 TargetID(
const char *ID) :
ID(
ID) {}
3385 operator const char *() {
return ID; }
3386 operator StringRef() {
return StringRef(ID); }
3389 SmallVector<TargetID, 4> GpuArchList;
3395 Action *CudaFatBinary =
nullptr;
3398 bool IsActive =
false;
3401 bool Relocatable =
false;
3404 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3407 const CUIDOptions &CUIDOpts;
3410 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3412 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3413 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3415 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3416 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3417 options::OPT_fno_gpu_rdc,
false);
3420 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3427 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3430 if (!(IA->getType() == types::TY_CUDA ||
3431 IA->getType() == types::TY_HIP ||
3432 IA->getType() == types::TY_PP_HIP)) {
3435 return ABRT_Inactive;
3442 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3444 if (CompileHostOnly)
3445 return ABRT_Success;
3448 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3449 : types::TY_CUDA_DEVICE;
3450 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3451 CudaDeviceActions.push_back(
3452 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3455 return ABRT_Success;
3459 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3463 if (UA->getType() == types::TY_Object && !Relocatable)
3464 return ABRT_Inactive;
3466 CudaDeviceActions.clear();
3468 std::string
FileName = IA->getInputArg().getAsString(Args);
3474 const StringRef LibFileExt =
".lib";
3475 if (IA->getType() == types::TY_Object &&
3476 (!llvm::sys::path::has_extension(
FileName) ||
3478 llvm::sys::path::extension(
FileName).drop_front()) !=
3480 llvm::sys::path::extension(
FileName) == LibFileExt))
3481 return ABRT_Inactive;
3483 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3484 CudaDeviceActions.push_back(UA);
3485 UA->registerDependentActionInfo(ToolChain,
Arch,
3486 AssociatedOffloadKind);
3489 return ABRT_Success;
3492 return IsActive ? ABRT_Success : ABRT_Inactive;
3495 void appendTopLevelActions(
ActionList &AL)
override {
3497 auto AddTopLevel = [&](Action *A, TargetID TargetID,
3498 const ToolChain *TC) {
3499 OffloadAction::DeviceDependences Dep;
3500 Dep.
add(*A, *TC, TargetID, AssociatedOffloadKind);
3501 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3505 if (CudaFatBinary) {
3506 AddTopLevel(CudaFatBinary, OffloadArch::Unused, FatBinaryToolChain);
3507 CudaDeviceActions.clear();
3508 CudaFatBinary =
nullptr;
3512 if (CudaDeviceActions.empty())
3518 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3519 "Expecting one action per GPU architecture.");
3520 assert(ToolChains.size() == GpuArchList.size() &&
3521 "Expecting to have a toolchain per GPU architecture");
3522 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3523 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3525 CudaDeviceActions.clear();
3528 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3546 assert(HostTC &&
"No toolchain for host compilation.");
3551 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3556 std::set<std::pair<StringRef, const ToolChain *>> GpuArchs;
3558 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3560 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3561 GpuArchs.insert({
Arch, I.second});
3565 for (
auto [
Arch, TC] : GpuArchs) {
3566 GpuArchList.push_back(
Arch.data());
3567 ToolChains.push_back(TC);
3570 FatBinaryToolChain = ToolChains.front();
3571 CompileHostOnly =
C.getDriver().offloadHostOnly();
3572 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3573 EmitAsm = Args.getLastArg(options::OPT_S);
3581 class CudaActionBuilder final :
public CudaActionBuilderBase {
3583 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3585 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3586 DefaultOffloadArch = OffloadArch::CudaDefault;
3589 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3591 const std::set<StringRef> &GpuArchs)
override {
3592 return std::nullopt;
3595 ActionBuilderReturnCode
3596 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3598 PhasesTy &Phases)
override {
3600 return ABRT_Inactive;
3604 if (CudaDeviceActions.empty())
3605 return ABRT_Success;
3607 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3608 "Expecting one action per GPU architecture.");
3609 assert(!CompileHostOnly &&
3610 "Not expecting CUDA actions in host-only compilation.");
3620 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3623 for (
auto Ph : Phases) {
3628 if (Ph > FinalPhase)
3631 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3645 Action *AssembleAction = CudaDeviceActions[I];
3646 assert(AssembleAction->
getType() == types::TY_Object);
3647 assert(AssembleAction->
getInputs().size() == 1);
3653 OffloadAction::DeviceDependences DDep;
3655 DeviceActions.push_back(
3656 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3661 if (!DeviceActions.empty()) {
3663 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3665 if (!CompileDeviceOnly) {
3666 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3670 CudaFatBinary =
nullptr;
3675 CudaDeviceActions.clear();
3679 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3684 return ABRT_Success;
3688 "instructions should only occur "
3689 "before the backend phase!");
3692 for (Action *&A : CudaDeviceActions)
3693 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3695 return ABRT_Success;
3700 class HIPActionBuilder final :
public CudaActionBuilderBase {
3702 SmallVector<ActionList, 8> DeviceLinkerInputs;
3708 std::optional<bool> BundleOutput;
3709 std::optional<bool> EmitReloc;
3712 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3714 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3716 DefaultOffloadArch = OffloadArch::HIPDefault;
3718 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3719 options::OPT_fno_hip_emit_relocatable)) {
3720 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3721 options::OPT_fno_hip_emit_relocatable, false);
3725 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3726 <<
"-fhip-emit-relocatable"
3730 if (!CompileDeviceOnly) {
3731 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3732 <<
"-fhip-emit-relocatable"
3733 <<
"--offload-device-only";
3738 if (Args.hasArg(options::OPT_gpu_bundle_output,
3739 options::OPT_no_gpu_bundle_output))
3740 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3741 options::OPT_no_gpu_bundle_output,
true) &&
3742 (!EmitReloc || !*EmitReloc);
3745 bool canUseBundlerUnbundler()
const override {
return true; }
3747 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3749 const std::set<StringRef> &GpuArchs)
override {
3753 ActionBuilderReturnCode
3754 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3756 PhasesTy &Phases)
override {
3758 return ABRT_Inactive;
3764 if (CudaDeviceActions.empty())
3765 return ABRT_Success;
3768 CudaDeviceActions.size() == GpuArchList.size()) &&
3769 "Expecting one action per GPU architecture.");
3770 assert(!CompileHostOnly &&
3771 "Not expecting HIP actions in host-only compilation.");
3773 bool ShouldLink = !EmitReloc || !*EmitReloc;
3776 !EmitAsm && ShouldLink) {
3782 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3783 if (
C.getDriver().isUsingOffloadLTO()) {
3787 AL.push_back(CudaDeviceActions[I]);
3790 CudaDeviceActions[I] =
3791 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3797 if (ToolChains[I]->
getTriple().isSPIRV() ||
3798 (ToolChains[I]->
getTriple().isAMDGCN() &&
3799 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3803 types::ID Output = Args.hasArg(options::OPT_S)
3805 : types::TY_LLVM_BC;
3807 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3811 AssociatedOffloadKind);
3812 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3814 AssociatedOffloadKind);
3815 AL.push_back(AssembleAction);
3818 CudaDeviceActions[I] =
3819 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3828 OffloadAction::DeviceDependences DDep;
3829 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3830 AssociatedOffloadKind);
3831 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3832 DDep, CudaDeviceActions[I]->getType());
3835 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3837 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3838 types::TY_HIP_FATBIN);
3840 if (!CompileDeviceOnly) {
3841 DA.
add(*CudaFatBinary, *FatBinaryToolChain,
nullptr,
3842 AssociatedOffloadKind);
3845 CudaFatBinary =
nullptr;
3850 CudaDeviceActions.clear();
3853 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3856 return ABRT_Success;
3862 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3863 auto LI = DeviceLinkerInputs.begin();
3864 for (
auto *A : CudaDeviceActions) {
3871 CudaDeviceActions.clear();
3872 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3876 for (Action *&A : CudaDeviceActions)
3877 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3878 AssociatedOffloadKind);
3880 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3882 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3883 OffloadAction::DeviceDependences DDep;
3884 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3885 AssociatedOffloadKind);
3886 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3887 DDep, CudaDeviceActions[I]->getType());
3890 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3891 CudaDeviceActions.clear();
3894 return (CompileDeviceOnly &&
3895 (CurPhase == FinalPhase ||
3901 void appendLinkDeviceActions(
ActionList &AL)
override {
3902 if (DeviceLinkerInputs.size() == 0)
3905 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3906 "Linker inputs and GPU arch list sizes do not match.");
3912 for (
auto &LI : DeviceLinkerInputs) {
3914 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3918 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3921 OffloadAction::DeviceDependences DeviceLinkDeps;
3922 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3923 AssociatedOffloadKind);
3924 Actions.push_back(
C.MakeAction<OffloadAction>(
3925 DeviceLinkDeps, DeviceLinkAction->getType()));
3928 DeviceLinkerInputs.clear();
3931 if (Args.hasArg(options::OPT_emit_llvm)) {
3939 OffloadAction::DeviceDependences DDeps;
3940 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3941 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3943 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3944 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain,
nullptr,
3945 AssociatedOffloadKind);
3948 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3954 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3956 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3964 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3970 bool ShouldUseBundler;
3973 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3981 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3984 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3992 unsigned ValidBuilders = 0u;
3993 unsigned ValidBuildersSupportingBundling = 0u;
3994 for (
auto *SB : SpecializedBuilders) {
3995 IsValid = IsValid && !SB->initialize();
3998 if (SB->isValid()) {
4000 if (SB->canUseBundlerUnbundler())
4001 ++ValidBuildersSupportingBundling;
4005 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4007 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4008 options::OPT_no_gpu_bundle_output,
true);
4011 ~OffloadingActionBuilder() {
4012 for (
auto *SB : SpecializedBuilders)
4017 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4018 assert(HostAction &&
"Invalid host action");
4019 assert(InputArg &&
"Invalid input argument");
4020 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4021 assert(Loc->second == InputArg &&
4022 "host action mapped to multiple input arguments");
4031 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4033 DeviceActionBuilder::PhasesTy &Phases) {
4037 if (SpecializedBuilders.empty())
4040 assert(HostAction &&
"Invalid host action!");
4041 recordHostAction(HostAction, InputArg);
4046 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4047 unsigned InactiveBuilders = 0u;
4048 unsigned IgnoringBuilders = 0u;
4049 for (
auto *SB : SpecializedBuilders) {
4050 if (!SB->isValid()) {
4055 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4060 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4065 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4066 OffloadKind |= SB->getAssociatedOffloadKind();
4071 if (IgnoringBuilders &&
4072 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4089 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4090 const Arg *InputArg) {
4094 recordHostAction(HostAction, InputArg);
4103 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4105 HostAction->
getType() == types::TY_PP_HIP)) {
4106 auto UnbundlingHostAction =
4111 HostAction = UnbundlingHostAction;
4112 recordHostAction(HostAction, InputArg);
4115 assert(HostAction &&
"Invalid host action!");
4118 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4119 for (
auto *SB : SpecializedBuilders) {
4123 auto RetCode = SB->addDeviceDependences(HostAction);
4127 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4128 "Host dependence not expected to be ignored.!");
4132 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4133 OffloadKind |= SB->getAssociatedOffloadKind();
4138 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4148 const Arg *InputArg) {
4150 recordHostAction(HostAction, InputArg);
4154 for (
auto *SB : SpecializedBuilders) {
4157 SB->appendTopLevelActions(OffloadAL);
4164 if (CanUseBundler && ShouldUseBundler && HostAction &&
4165 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4167 OffloadAL.push_back(HostAction);
4171 assert(HostAction == AL.back() &&
"Host action not in the list??");
4173 recordHostAction(HostAction, InputArg);
4174 AL.back() = HostAction;
4176 AL.append(OffloadAL.begin(), OffloadAL.end());
4186 void appendDeviceLinkActions(
ActionList &AL) {
4187 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4190 SB->appendLinkDeviceActions(AL);
4194 Action *makeHostLinkAction() {
4197 appendDeviceLinkActions(DeviceAL);
4198 if (DeviceAL.empty())
4203 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4206 HA = SB->appendLinkHostActions(DeviceAL);
4223 for (
auto *SB : SpecializedBuilders) {
4227 SB->appendLinkDependences(DDeps);
4231 unsigned ActiveOffloadKinds = 0u;
4232 for (
auto &I : InputArgToOffloadKindMap)
4233 ActiveOffloadKinds |= I.second;
4245 for (
auto *A : HostAction->
inputs()) {
4246 auto ArgLoc = HostActionToInputArgMap.find(A);
4247 if (ArgLoc == HostActionToInputArgMap.end())
4249 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4250 if (OFKLoc == InputArgToOffloadKindMap.end())
4262 nullptr, ActiveOffloadKinds);
4268void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4273 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4274 StringRef
V = A->getValue();
4275 if (Inputs.size() > 1 && !
V.empty() &&
4276 !llvm::sys::path::is_separator(
V.back())) {
4278 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4279 << A->getSpelling() <<
V;
4280 Args.eraseArg(options::OPT__SLASH_Fo);
4285 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4286 StringRef
V = A->getValue();
4287 if (Inputs.size() > 1 && !
V.empty() &&
4288 !llvm::sys::path::is_separator(
V.back())) {
4290 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4291 << A->getSpelling() <<
V;
4292 Args.eraseArg(options::OPT__SLASH_Fa);
4297 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4298 if (A->getValue()[0] ==
'\0') {
4300 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4301 Args.eraseArg(options::OPT__SLASH_o);
4306 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4307 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4308 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4309 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4310 Args.eraseArg(options::OPT__SLASH_Yc);
4311 Args.eraseArg(options::OPT__SLASH_Yu);
4312 YcArg = YuArg =
nullptr;
4314 if (YcArg && Inputs.size() > 1) {
4315 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4316 Args.eraseArg(options::OPT__SLASH_Yc);
4324 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4325 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4326 Args.AddFlagArg(
nullptr,
4327 getOpts().getOption(options::OPT_frtlib_add_rpath));
4331 if (Args.hasArg(options::OPT_emit_llvm) &&
4332 !Args.hasArg(options::OPT_hip_link) &&
4333 !
C.getDefaultToolChain().getTriple().isSPIRV())
4334 Diag(clang::diag::err_drv_emit_llvm_link);
4335 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4337 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4338 .starts_with_insensitive(
"lld"))
4339 Diag(clang::diag::err_drv_lto_without_lld);
4345 if (!Args.hasArg(options::OPT_dumpdir)) {
4346 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4347 Arg *Arg = Args.MakeSeparateArg(
4348 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4350 (FinalOutput ? FinalOutput->getValue()
4362 Args.eraseArg(options::OPT__SLASH_Fp);
4363 Args.eraseArg(options::OPT__SLASH_Yc);
4364 Args.eraseArg(options::OPT__SLASH_Yu);
4365 YcArg = YuArg =
nullptr;
4368 if (Args.hasArg(options::OPT_include_pch) &&
4369 Args.hasArg(options::OPT_ignore_pch)) {
4373 Args.eraseArg(options::OPT_include_pch);
4376 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4377 for (
auto &I : Inputs) {
4379 const Arg *InputArg = I.second;
4384 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4388 if (InitialPhase > FinalPhase) {
4389 if (InputArg->isClaimed())
4396 if (Args.hasArg(options::OPT_Qunused_arguments))
4402 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4403 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4407 (Args.getLastArg(options::OPT__SLASH_EP,
4408 options::OPT__SLASH_P) ||
4409 Args.getLastArg(options::OPT_E) ||
4410 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4412 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4413 << InputArg->getAsString(Args) << !!FinalPhaseArg
4414 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4416 Diag(clang::diag::warn_drv_input_file_unused)
4417 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4419 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4428 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4432 Actions.push_back(ClangClPch);
4444 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4445 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4454 const llvm::opt::DerivedArgList &Args,
4457 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4459 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4462 bool HasAMDGCNHIPDevice =
false;
4464 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4466 const llvm::Triple &Tr = TC->
getTriple();
4469 HasAMDGCNHIPDevice =
true;
4471 return HasAMDGCNHIPDevice;
4476 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4478 if (!SuppressMissingInputWarning && Inputs.empty()) {
4479 Diag(clang::diag::err_drv_no_input_files);
4483 handleArguments(
C, Args, Inputs, Actions);
4485 bool UseNewOffloadingDriver = Args.hasFlag(
4486 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4490 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4491 !UseNewOffloadingDriver
4492 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4500 for (
auto &I : Inputs) {
4502 const Arg *InputArg = I.second;
4515 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4523 if (!UseNewOffloadingDriver)
4524 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4530 if (!UseNewOffloadingDriver)
4531 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4532 Current, InputArg, Phase, PL.back(), FullPL);
4538 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4541 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4542 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4544 LinkerInputs.push_back(Current);
4554 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4555 MergerInputs.push_back(Current);
4573 if (NewCurrent == Current)
4576 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4579 Current = NewCurrent;
4583 if (UseNewOffloadingDriver)
4585 &HIPAsmDeviceActions);
4588 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4592 if (Current->
getType() == types::TY_Nothing)
4598 if (Current && !HIPAsmDeviceActions.empty()) {
4599 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4601 BundleInputs.append(HIPAsmDeviceActions);
4602 BundleInputs.push_back(Current);
4608 Actions.push_back(Current);
4611 if (!UseNewOffloadingDriver)
4612 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4620 if (LinkerInputs.empty()) {
4623 if (!UseNewOffloadingDriver)
4624 OffloadBuilder->appendDeviceLinkActions(Actions);
4627 if (!LinkerInputs.empty()) {
4628 if (!UseNewOffloadingDriver)
4629 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4630 LinkerInputs.push_back(Wrapper);
4635 }
else if (UseNewOffloadingDriver ||
4636 Args.hasArg(options::OPT_offload_link)) {
4644 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4645 C.getDefaultToolChain().getTriple().isSPIRV();
4646 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4650 if (!UseNewOffloadingDriver)
4651 LA = OffloadBuilder->processHostLinkAction(LA);
4652 Actions.push_back(LA);
4656 if (!MergerInputs.empty())
4660 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4667 for (
auto &I : Inputs) {
4669 const Arg *InputArg = I.second;
4674 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4675 InputType == types::TY_Asm)
4680 for (
auto Phase : PhaseList) {
4684 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4689 if (InputType == types::TY_Object)
4696 assert(Phase == PhaseList.back() &&
4697 "merging must be final compilation step.");
4698 MergerInputs.push_back(Current);
4707 Actions.push_back(Current);
4711 if (!MergerInputs.empty())
4716 for (
auto Opt : {options::OPT_print_supported_cpus,
4717 options::OPT_print_supported_extensions,
4718 options::OPT_print_enabled_extensions}) {
4725 if (Arg *A = Args.getLastArg(Opt)) {
4726 if (Opt == options::OPT_print_supported_extensions &&
4727 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4728 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4729 !
C.getDefaultToolChain().getTriple().isARM()) {
4730 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4731 <<
"--print-supported-extensions";
4734 if (Opt == options::OPT_print_enabled_extensions &&
4735 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4736 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4737 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4738 <<
"--print-enabled-extensions";
4745 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4748 for (
auto &I : Inputs)
4753 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4759 if (TC.requiresObjcopy(Args)) {
4760 Action *LastAction = Actions.back();
4762 if (LastAction->
getType() == types::TY_Object)
4768 if (TC.requiresValidation(Args)) {
4769 Action *LastAction = Actions.back();
4771 LastAction, types::TY_DX_CONTAINER));
4775 if (TC.requiresBinaryTranslation(Args)) {
4776 Action *LastAction = Actions.back();
4780 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4781 LastAction->
getType() == types::TY_Object)
4783 LastAction, types::TY_DX_CONTAINER));
4788 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4794 const llvm::opt::DerivedArgList &Args,
4796 const llvm::Triple &Triple) {
4801 if (Triple.isNVPTX() &&
4803 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4804 <<
"CUDA" << ArchStr;
4806 }
else if (Triple.isAMDGPU() &&
4808 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4809 <<
"HIP" << ArchStr;
4817 llvm::StringMap<bool> Features;
4820 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4832static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4834 llvm::Triple Triple) {
4835 if (!Triple.isAMDGPU())
4836 return std::nullopt;
4838 std::set<StringRef> ArchSet;
4839 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4843llvm::SmallVector<StringRef>
4847 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4848 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4849 options::OPT_no_offload_arch_EQ)) {
4850 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4852 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4854 :
"--no-offload-arch");
4857 llvm::DenseSet<StringRef> Archs;
4858 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4861 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4862 for (StringRef
Arch : Arg->getValues()) {
4863 if (
Arch ==
"native" ||
Arch.empty()) {
4867 << llvm::Triple::getArchTypeName(TC.
getArch())
4868 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4872 for (
auto ArchStr : *GPUsOrErr) {
4874 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4875 if (!CanonicalStr.empty())
4876 Archs.insert(CanonicalStr);
4881 StringRef CanonicalStr =
4883 if (!CanonicalStr.empty())
4884 Archs.insert(CanonicalStr);
4889 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4890 for (StringRef
Arch : Arg->getValues()) {
4891 if (
Arch ==
"all") {
4896 Archs.erase(ArchStr);
4902 if (
auto ConflictingArchs =
4904 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4905 << ConflictingArchs->first << ConflictingArchs->second;
4908 if (Archs.empty()) {
4916 Archs.insert(StringRef());
4919 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4920 .getLastArg(options::OPT_march_EQ)) {
4921 Archs.insert(Arg->getValue());
4926 << llvm::Triple::getArchTypeName(TC.
getArch())
4927 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4928 }
else if (!ArchsOrErr->empty()) {
4929 for (
auto Arch : *ArchsOrErr)
4930 Archs.insert(Args.MakeArgStringRef(
Arch));
4932 Archs.insert(StringRef());
4937 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4938 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4947 const InputTy &Input, StringRef CUID,
4957 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4959 bool HIPRelocatableObj =
4961 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4962 options::OPT_fno_hip_emit_relocatable,
false);
4964 if (!HIPNoRDC && HIPRelocatableObj)
4965 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4966 <<
"-fhip-emit-relocatable"
4970 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4971 <<
"-fhip-emit-relocatable"
4972 <<
"--offload-device-only";
4990 auto TCRange =
C.getOffloadToolChains(Kind);
4991 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4992 ToolChains.push_back(TI->second);
4994 if (ToolChains.empty())
4998 const Arg *InputArg = Input.second;
5007 for (
const ToolChain *TC : ToolChains) {
5009 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5010 DeviceActions.push_back(
5011 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5015 if (DeviceActions.empty())
5021 HostAction->
getType() != types::TY_Nothing &&
5031 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5040 auto *TCAndArch = TCAndArchs.begin();
5041 for (
Action *&A : DeviceActions) {
5042 if (A->
getType() == types::TY_Nothing)
5052 HostAction->
getType() != types::TY_Nothing) {
5059 TCAndArch->second.data(), Kind);
5061 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5071 for (
Action *&A : DeviceActions) {
5076 OffloadTriple && OffloadTriple->isSPIRV() &&
5077 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5078 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5079 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5080 options::OPT_no_use_spirv_backend,
5087 bool IsAMDGCNSPIRVWithBackend =
5088 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5091 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5092 A->
getType() != types::TY_LTO_BC) ||
5100 auto *TCAndArch = TCAndArchs.begin();
5101 for (
Action *A : DeviceActions) {
5102 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5104 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5109 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5111 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5120 bool ShouldBundleHIP =
5121 Args.hasFlag(options::OPT_gpu_bundle_output,
5122 options::OPT_no_gpu_bundle_output,
false) ||
5123 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5125 return A->
getType() != types::TY_Image;
5132 if (OffloadActions.empty())
5137 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5141 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5148 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5149 DDep.
add(*FatbinAction,
5152 }
else if (HIPNoRDC) {
5155 if (HIPAsmBundleDeviceOut &&
5157 for (
Action *OA : OffloadActions)
5158 HIPAsmBundleDeviceOut->push_back(OA);
5172 DDep.
add(*PackagerAction,
5181 nullptr,
C.getActiveOffloadKinds());
5190 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5191 return A->
getType() == types::TY_Nothing;
5195 nullptr, SingleDeviceOutput ? DDep : DDeps);
5196 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5202 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5212 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5218 llvm_unreachable(
"link action invalid here.");
5220 llvm_unreachable(
"ifsmerge action invalid here.");
5225 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5226 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5227 OutputTy = types::TY_Dependencies;
5232 if (!Args.hasFlag(options::OPT_frewrite_includes,
5233 options::OPT_fno_rewrite_includes,
false) &&
5234 !Args.hasFlag(options::OPT_frewrite_imports,
5235 options::OPT_fno_rewrite_imports,
false) &&
5236 !Args.hasFlag(options::OPT_fdirectives_only,
5237 options::OPT_fno_directives_only,
false) &&
5241 "Cannot preprocess this input type!");
5247 if (Args.hasArg(options::OPT_extract_api))
5256 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5257 (Input->
getType() == driver::types::TY_CXXModule ||
5258 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5259 !Args.getLastArg(options::OPT__precompile) &&
5260 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5265 "Cannot precompile this input type!");
5269 const char *ModName =
nullptr;
5270 if (OutputTy == types::TY_PCH) {
5271 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5272 ModName = A->getValue();
5274 OutputTy = types::TY_ModuleFile;
5277 if (Args.hasArg(options::OPT_fsyntax_only)) {
5279 OutputTy = types::TY_Nothing;
5285 if (Args.hasArg(options::OPT_fsyntax_only))
5287 if (Args.hasArg(options::OPT_rewrite_objc))
5289 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5291 types::TY_RewrittenLegacyObjC);
5292 if (Args.hasArg(options::OPT__analyze))
5294 if (Args.hasArg(options::OPT_emit_ast))
5296 if (Args.hasArg(options::OPT_emit_cir))
5298 if (Args.hasArg(options::OPT_module_file_info))
5300 if (Args.hasArg(options::OPT_verify_pch))
5302 if (Args.hasArg(options::OPT_extract_api))
5311 Args.hasFlag(options::OPT_offload_new_driver,
5312 options::OPT_no_offload_new_driver,
5315 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm)))
5320 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5321 !Args.hasArg(options::OPT_emit_llvm))
5322 Output = types::TY_PP_Asm;
5323 else if (Args.hasArg(options::OPT_S))
5324 Output = types::TY_LTO_IR;
5326 Output = types::TY_LTO_BC;
5331 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5334 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5335 options::OPT_no_use_spirv_backend,
5343 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5345 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5347 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5349 auto &DefaultToolChain =
C.getDefaultToolChain();
5350 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5355 bool EmitBitcodeForNonOffloadAMDSPIRV =
5356 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5357 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5358 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5360 if (Args.hasArg(options::OPT_emit_llvm) ||
5361 EmitBitcodeForNonOffloadAMDSPIRV ||
5367 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5368 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5370 (Args.hasFlag(options::OPT_offload_new_driver,
5371 options::OPT_no_offload_new_driver,
5373 !(Args.hasArg(options::OPT_S) &&
5374 !Args.hasArg(options::OPT_emit_llvm)) &&
5381 Args.hasArg(options::OPT_S) &&
5385 !Args.hasFlag(options::OPT_offload_new_driver,
5386 options::OPT_no_offload_new_driver,
5387 C.getActiveOffloadKinds() !=
5390 : types::TY_LLVM_BC;
5403 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5412 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5416 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5418 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5438 unsigned NumOutputs = 0;
5439 unsigned NumIfsOutputs = 0;
5440 for (
const Action *A :
C.getActions()) {
5443 if (A->
getType() == types::TY_DX_CONTAINER &&
5448 if (A->
getType() != types::TY_Nothing &&
5450 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5452 0 == NumIfsOutputs++) ||
5457 A->
getType() == types::TY_Nothing &&
5458 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5459 NumOutputs += A->
size();
5462 if (NumOutputs > 1) {
5463 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5464 FinalOutput =
nullptr;
5468 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5472 if (RawTriple.isOSBinFormatMachO())
5473 for (
const Arg *A :
C.getArgs())
5474 if (A->getOption().matches(options::OPT_arch))
5478 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5479 for (
Action *A :
C.getActions()) {
5486 const char *LinkingOutput =
nullptr;
5489 LinkingOutput = FinalOutput->getValue();
5498 LinkingOutput, CachedResults,
5505 for (
auto &J :
C.getJobs())
5506 J.InProcess =
false;
5509 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5510 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5515 const char *LinkingOutput =
nullptr;
5517 LinkingOutput = FinalOutput->getValue();
5524 using namespace llvm;
5527 <<
"output=" << LinkingOutput;
5528 outs() <<
", total="
5529 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5531 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5532 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5536 llvm::raw_string_ostream Out(Buffer);
5537 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5540 llvm::sys::printArg(Out, LinkingOutput,
true);
5541 Out <<
',' << ProcStat->TotalTime.count() <<
','
5542 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5547 llvm::sys::fs::OF_Append |
5548 llvm::sys::fs::OF_Text);
5553 llvm::errs() <<
"ERROR: Cannot lock file "
5555 <<
toString(L.takeError()) <<
"\n";
5566 bool ReportUnusedArguments =
5567 !Diags.hasErrorOccurred() &&
5568 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5571 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5573 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5576 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5577 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5579 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5583 return strstr(J.getCreator().getShortName(),
"assembler");
5585 for (Arg *A :
C.getArgs()) {
5589 if (!A->isClaimed()) {
5595 const Option &Opt = A->getOption();
5596 if (Opt.getKind() == Option::FlagClass) {
5597 bool DuplicateClaimed =
false;
5599 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5600 if (AA->isClaimed()) {
5601 DuplicateClaimed =
true;
5606 if (DuplicateClaimed)
5612 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5614 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5619 !
C.getActions().empty()) {
5620 Diag(diag::err_drv_unsupported_opt_for_target)
5622 }
else if (ReportUnusedArguments) {
5623 Diag(clang::diag::warn_drv_unused_argument)
5624 << A->getAsString(
C.getArgs());
5634class ToolSelector final {
5645 bool IsHostSelector;
5656 bool CanBeCollapsed =
true) {
5658 if (Inputs.size() != 1)
5661 Action *CurAction = *Inputs.begin();
5662 if (CanBeCollapsed &&
5668 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5672 if (!IsHostSelector) {
5673 if (OA->hasSingleDeviceDependence(
true)) {
5675 OA->getSingleDeviceDependence(
true);
5676 if (CanBeCollapsed &&
5679 SavedOffloadAction.push_back(OA);
5680 return dyn_cast<JobAction>(CurAction);
5682 }
else if (OA->hasHostDependence()) {
5683 CurAction = OA->getHostDependence();
5684 if (CanBeCollapsed &&
5687 SavedOffloadAction.push_back(OA);
5688 return dyn_cast<JobAction>(CurAction);
5693 return dyn_cast<JobAction>(CurAction);
5697 bool canCollapseAssembleAction()
const {
5698 return TC.useIntegratedAs() && !SaveTemps &&
5699 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5700 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5701 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5702 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5706 bool canCollapsePreprocessorAction()
const {
5707 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5708 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5709 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5714 struct JobActionInfo final {
5716 const JobAction *JA =
nullptr;
5724 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5725 ArrayRef<JobActionInfo> &ActionInfo,
5726 unsigned ElementNum) {
5727 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5728 for (
unsigned I = 0; I < ElementNum; ++I)
5729 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5730 ActionInfo[I].SavedOffloadAction.end());
5743 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5746 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5748 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5749 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5750 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5751 if (!AJ || !BJ || !CJ)
5755 const Tool *T = TC.SelectTool(*CJ);
5768 const Tool *BT = TC.SelectTool(*BJ);
5776 Inputs = CJ->getInputs();
5777 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5781 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5784 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5786 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5787 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5792 const Tool *T = TC.SelectTool(*BJ);
5799 Inputs = BJ->getInputs();
5800 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5804 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5807 if (ActionInfo.size() < 2)
5809 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5810 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5814 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5815 for (
auto &Input : AI.JA->getInputs())
5826 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5827 if (SaveTemps && !InputIsBitcode)
5831 const Tool *T = TC.SelectTool(*CJ);
5844 Inputs = CJ->getInputs();
5845 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5854 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5862 for (Action *A : Inputs) {
5863 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5865 NewInputs.push_back(A);
5871 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5872 PreprocessJobOffloadActions.end());
5873 NewInputs.append(PJ->input_begin(), PJ->input_end());
5879 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5881 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5883 assert(BaseAction &&
"Invalid base action.");
5899 SmallVector<JobActionInfo, 5> ActionChain(1);
5900 ActionChain.back().JA = BaseAction;
5901 while (ActionChain.back().JA) {
5902 const Action *CurAction = ActionChain.back().JA;
5905 ActionChain.resize(ActionChain.size() + 1);
5906 JobActionInfo &AI = ActionChain.back();
5910 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5914 ActionChain.pop_back();
5922 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5923 CollapsedOffloadAction);
5925 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5927 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5933 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5945 StringRef BoundArch,
5947 std::string TriplePlusArch = TC->
getTriple().normalize();
5948 if (!BoundArch.empty()) {
5949 TriplePlusArch +=
"-";
5950 TriplePlusArch += BoundArch;
5952 TriplePlusArch +=
"-";
5954 return TriplePlusArch;
5959 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5960 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5963 std::pair<const Action *, std::string> ActionTC = {
5965 auto CachedResult = CachedResults.find(ActionTC);
5966 if (CachedResult != CachedResults.end()) {
5967 return CachedResult->second;
5970 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5971 CachedResults, TargetDeviceOffloadKind);
5972 CachedResults[ActionTC] =
Result;
5977 const JobAction *JA,
const char *BaseInput,
5980 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5991 OffloadingPrefix +=
"-";
5992 OffloadingPrefix +=
Arch;
5995 C.getDriver().isSaveTempsEnabled()) {
6002 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6003 Path = A->getValue();
6004 if (llvm::sys::fs::is_directory(Path)) {
6006 ? llvm::sys::path::stem(Result.getFilename())
6007 : llvm::sys::path::stem(BaseInput));
6008 Tmp += OffloadingPrefix;
6010 llvm::sys::path::append(Path, Tmp);
6013 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6016 Path = DumpDir->getValue();
6017 Path += llvm::sys::path::stem(BaseInput);
6018 Path += OffloadingPrefix;
6019 }
else if (!OffloadingPrefix.empty()) {
6023 TraceName += OffloadingPrefix;
6024 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6025 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6026 llvm::sys::path::append(Path, TraceName);
6028 Path = Result.getFilename();
6030 llvm::sys::path::replace_extension(Path,
"json");
6032 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6033 C.addTimeTraceFile(ResultFile, JA);
6034 C.addResultFile(ResultFile, JA);
6039 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6040 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6043 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6046 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6047 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6079 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6081 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6082 const char *DepBoundArch) {
6085 LinkingOutput, CachedResults,
6095 OA->doOnEachDependence(
6096 BuildingForOffloadDevice,
6097 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6099 C, DepA, DepTC, DepBoundArch,
false,
6100 !!DepBoundArch, LinkingOutput, CachedResults,
6104 A = BuildingForOffloadDevice
6105 ? OA->getSingleDeviceDependence(
true)
6106 : OA->getHostDependence();
6110 std::pair<const Action *, std::string> ActionTC = {
6111 OA->getHostDependence(),
6113 auto It = CachedResults.find(ActionTC);
6114 if (It != CachedResults.end()) {
6116 Inputs.append(OffloadDependencesInputInfo);
6121 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6124 const Arg &Input = IA->getInputArg();
6126 if (Input.getOption().matches(options::OPT_INPUT)) {
6127 const char *
Name = Input.getValue();
6130 return {InputInfo(A, &Input,
"")};
6133 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6134 const ToolChain *TC;
6137 if (!ArchName.empty())
6138 TC = &getToolChain(
C.getArgs(),
6140 C.getArgs(), ArchName));
6142 TC = &
C.getDefaultToolChain();
6145 MultipleArchs, LinkingOutput, CachedResults,
6146 TargetDeviceOffloadKind);
6157 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6160 return {InputInfo()};
6164 for (
const auto *OA : CollapsedOffloadActions)
6166 BuildingForOffloadDevice,
6167 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6169 C, DepA, DepTC, DepBoundArch,
false,
6170 !!DepBoundArch, LinkingOutput, CachedResults,
6176 for (
const Action *Input : Inputs) {
6180 bool SubJobAtTopLevel =
6183 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6188 const char *BaseInput = InputInfos[0].getBaseInput();
6189 for (
auto &Info : InputInfos) {
6190 if (Info.isFilename()) {
6191 BaseInput = Info.getBaseInput();
6198 if (JA->
getType() == types::TY_dSYM)
6199 BaseInput = InputInfos[0].getFilename();
6202 if (!OffloadDependencesInputInfo.empty())
6203 InputInfos.append(OffloadDependencesInputInfo.begin(),
6204 OffloadDependencesInputInfo.end());
6207 llvm::Triple EffectiveTriple;
6209 const ArgList &Args =
6211 if (InputInfos.size() != 1) {
6215 EffectiveTriple = llvm::Triple(
6218 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6223 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6227 for (
auto &UI : UA->getDependentActionsInfo()) {
6229 "Unbundling with no offloading??");
6236 UI.DependentOffloadKind,
6237 UI.DependentToolChain->getTriple().normalize(),
6239 auto CurI = InputInfo(
6248 UnbundlingResults.push_back(CurI);
6257 Arch = UI.DependentBoundArch;
6262 UI.DependentOffloadKind)}] = {
6268 std::pair<const Action *, std::string> ActionTC = {
6270 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6271 "Result does not exist??");
6272 Result = CachedResults[ActionTC].front();
6273 }
else if (JA->
getType() == types::TY_Nothing)
6274 Result = {InputInfo(A, BaseInput)};
6284 AtTopLevel, MultipleArchs,
6293 <<
" - \"" << T->
getName() <<
"\", inputs: [";
6294 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6295 llvm::errs() << InputInfos[i].getAsString();
6297 llvm::errs() <<
", ";
6299 if (UnbundlingResults.empty())
6300 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6302 llvm::errs() <<
"], outputs: [";
6303 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6304 llvm::errs() << UnbundlingResults[i].getAsString();
6306 llvm::errs() <<
", ";
6308 llvm::errs() <<
"] \n";
6311 if (UnbundlingResults.empty())
6315 Args, LinkingOutput);
6321 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6322 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6334 if (ArgValue.empty()) {
6336 Filename = BaseName;
6337 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6339 llvm::sys::path::append(Filename, BaseName);
6342 if (!llvm::sys::path::has_extension(ArgValue)) {
6347 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6352 llvm::sys::path::replace_extension(Filename, Extension);
6355 return Args.MakeArgString(Filename.c_str());
6370 StringRef Suffix,
bool MultipleArchs,
6371 StringRef BoundArch,
6372 bool NeedUniqueDirectory)
const {
6374 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6375 std::optional<std::string> CrashDirectory =
6377 ? std::string(A->getValue())
6378 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6379 if (CrashDirectory) {
6380 if (!
getVFS().exists(*CrashDirectory))
6381 llvm::sys::fs::create_directories(*CrashDirectory);
6383 llvm::sys::path::append(Path, Prefix);
6384 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6385 if (std::error_code EC =
6386 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6387 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6391 if (MultipleArchs && !BoundArch.empty()) {
6392 if (NeedUniqueDirectory) {
6394 llvm::sys::path::append(TmpName,
6395 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6405 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6420 const char *BaseInput) {
6422 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6423 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6428 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6432 const char *BaseInput,
6433 StringRef OrigBoundArch,
bool AtTopLevel,
6435 StringRef OffloadingPrefix)
const {
6438 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6441 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6442 return C.addResultFile(FinalOutput->getValue(), &JA);
6446 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6448 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6450 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6451 NameArg = A->getValue();
6452 return C.addResultFile(
6462 if (JA.
getType() == types::TY_ModuleFile &&
6463 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6467 if (JA.
getType() == types::TY_PP_Asm &&
6468 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6469 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6472 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6475 if ((JA.
getType() == types::TY_Object &&
6476 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6477 JA.
getType() == types::TY_DX_CONTAINER) {
6478 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6482 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6484 C.getDefaultToolChain());
6487 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6488 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6489 StringRef
Name = llvm::sys::path::filename(BaseInput);
6490 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6496 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6497 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6501 if (JA.
getType() == types::TY_PP_Asm &&
6502 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6503 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6505 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6506 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6507 return C.addResultFile(
6512 if (JA.
getType() == types::TY_API_INFO &&
6513 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6514 C.getArgs().hasArg(options::OPT_o))
6515 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6516 <<
C.getArgs().getLastArgValue(options::OPT_o);
6523 bool SpecifiedModuleOutput =
6524 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6525 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6526 if (MultipleArchs && SpecifiedModuleOutput)
6527 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6532 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6533 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6539 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6541 StringRef
Name = llvm::sys::path::filename(BaseInput);
6542 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6543 const char *Suffix =
6548 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6549 bool NeedUniqueDirectory =
6552 Triple.isOSDarwin();
6553 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6554 NeedUniqueDirectory);
6563 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6568 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6569 llvm::sys::path::filename(BasePath));
6570 BaseName = ExternalPath;
6572 BaseName = BasePath;
6574 BaseName = llvm::sys::path::filename(BasePath);
6577 const char *NamedOutput;
6579 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6580 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6584 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6588 }
else if (JA.
getType() == types::TY_Image &&
6589 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6590 options::OPT__SLASH_o)) {
6594 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6598 }
else if (JA.
getType() == types::TY_Image) {
6608 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6609 options::OPT_fno_gpu_rdc,
false);
6611 if (UseOutExtension) {
6613 llvm::sys::path::replace_extension(Output,
"");
6615 Output += OffloadingPrefix;
6616 if (MultipleArchs && !BoundArch.empty()) {
6618 Output.append(BoundArch);
6620 if (UseOutExtension)
6622 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6625 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6626 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6627 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6630 .getLastArg(options::OPT__SLASH_o)
6635 const char *Suffix =
6637 assert(Suffix &&
"All types used for output should have a suffix.");
6639 std::string::size_type End = std::string::npos;
6641 End = BaseName.rfind(
'.');
6643 Suffixed += OffloadingPrefix;
6644 if (MultipleArchs && !BoundArch.empty()) {
6646 Suffixed.append(BoundArch);
6651 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6652 const llvm::opt::DerivedArgList &Args) {
6659 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6661 Args.hasFlag(options::OPT_offload_new_driver,
6662 options::OPT_no_offload_new_driver,
true))) ||
6669 bool IsLinkerWrapper =
6671 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6672 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6673 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6675 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6679 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6683 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6684 JA.
getType() != types::TY_PCH) {
6685 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6687 llvm::sys::path::remove_filename(TempPath);
6688 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6689 llvm::sys::path::append(TempPath, OutputFileName);
6690 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6696 bool SameFile =
false;
6698 llvm::sys::fs::current_path(
Result);
6699 llvm::sys::path::append(
Result, BaseName);
6700 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6703 StringRef
Name = llvm::sys::path::filename(BaseInput);
6704 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6708 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6714 llvm::sys::path::remove_filename(BasePath);
6715 if (BasePath.empty())
6716 BasePath = NamedOutput;
6718 llvm::sys::path::append(BasePath, NamedOutput);
6719 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6722 return C.addResultFile(NamedOutput, &JA);
6728 -> std::optional<std::string> {
6731 for (
const auto &
Dir : P) {
6735 llvm::sys::path::append(P,
Name);
6736 if (llvm::sys::fs::exists(Twine(P)))
6737 return std::string(P);
6739 return std::nullopt;
6746 llvm::sys::path::append(R,
Name);
6747 if (llvm::sys::fs::exists(Twine(R)))
6748 return std::string(R);
6751 llvm::sys::path::append(P,
Name);
6752 if (llvm::sys::fs::exists(Twine(P)))
6753 return std::string(P);
6756 llvm::sys::path::append(D,
"..",
Name);
6757 if (llvm::sys::fs::exists(Twine(D)))
6758 return std::string(D);
6767 llvm::sys::path::append(R2,
"..",
"..",
Name);
6768 if (llvm::sys::fs::exists(Twine(R2)))
6769 return std::string(R2);
6771 return std::string(
Name);
6774void Driver::generatePrefixedToolNames(
6778 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6779 Names.emplace_back(
Tool);
6783 llvm::sys::path::append(Dir, Name);
6784 if (llvm::sys::fs::can_execute(Twine(Dir)))
6786 llvm::sys::path::remove_filename(Dir);
6792 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6797 if (llvm::sys::fs::is_directory(PrefixDir)) {
6800 return std::string(P);
6803 if (llvm::sys::fs::can_execute(Twine(P)))
6804 return std::string(P);
6809 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6817 for (
const auto &Path : List) {
6820 return std::string(P);
6824 if (llvm::ErrorOr<std::string> P =
6825 llvm::sys::findProgramByName(TargetSpecificExecutable))
6829 return std::string(
Name);
6834 std::string error =
"<NOT PRESENT>";
6836 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6841 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6858 llvm::sys::path::remove_filename(path);
6859 llvm::sys::path::append(path,
"libc++.modules.json");
6860 if (TC.
getVFS().exists(path))
6861 return static_cast<std::string
>(path);
6866 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6869 return evaluate(
"libc++.a").value_or(error);
6873 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6877 llvm::sys::path::remove_filename(path);
6878 llvm::sys::path::append(path,
"libstdc++.modules.json");
6879 if (TC.
getVFS().exists(path))
6880 return static_cast<std::string
>(path);
6885 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6888 return evaluate(
"libstdc++.a").value_or(error);
6897 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6899 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6903 return std::string(Path);
6908 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6910 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6914 return std::string(Path);
6919 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6923 Output = FpArg->getValue();
6927 if (!llvm::sys::path::has_extension(Output))
6930 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6931 Output = YcArg->getValue();
6934 llvm::sys::path::replace_extension(Output,
".pch");
6936 return std::string(Output);
6939const ToolChain &Driver::getOffloadToolChain(
6941 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6942 std::unique_ptr<ToolChain> &TC =
6943 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6944 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6946 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6949 switch (
Target.getOS()) {
6950 case llvm::Triple::CUDA:
6951 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6954 case llvm::Triple::AMDHSA:
6956 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6959 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6968 switch (
Target.getArch()) {
6969 case llvm::Triple::spir:
6970 case llvm::Triple::spir64:
6971 case llvm::Triple::spirv:
6972 case llvm::Triple::spirv32:
6973 case llvm::Triple::spirv64:
6976 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6980 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6984 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6988 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7002 return getToolChain(Args,
Target);
7006const ToolChain &Driver::getToolChain(
const ArgList &Args,
7007 const llvm::Triple &
Target)
const {
7009 auto &TC = ToolChains[
Target.str()];
7011 switch (
Target.getOS()) {
7012 case llvm::Triple::AIX:
7013 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7015 case llvm::Triple::Haiku:
7016 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7018 case llvm::Triple::Darwin:
7019 case llvm::Triple::MacOSX:
7020 case llvm::Triple::IOS:
7021 case llvm::Triple::TvOS:
7022 case llvm::Triple::WatchOS:
7023 case llvm::Triple::XROS:
7024 case llvm::Triple::DriverKit:
7025 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7027 case llvm::Triple::DragonFly:
7028 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7030 case llvm::Triple::OpenBSD:
7031 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7033 case llvm::Triple::NetBSD:
7034 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7036 case llvm::Triple::FreeBSD:
7038 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7041 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7043 case llvm::Triple::Linux:
7044 case llvm::Triple::ELFIAMCU:
7045 if (
Target.getArch() == llvm::Triple::hexagon)
7046 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7048 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7049 !
Target.hasEnvironment())
7050 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7053 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7055 else if (
Target.getArch() == llvm::Triple::ve)
7056 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7057 else if (
Target.isOHOSFamily())
7058 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7059 else if (
Target.isWALI())
7060 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7062 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7064 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7066 case llvm::Triple::Fuchsia:
7067 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7069 case llvm::Triple::Managarm:
7070 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7072 case llvm::Triple::Solaris:
7073 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7075 case llvm::Triple::CUDA:
7076 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7078 case llvm::Triple::AMDHSA: {
7079 if (
Target.getArch() == llvm::Triple::spirv64) {
7080 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7085 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
7087 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
7092 case llvm::Triple::AMDPAL:
7093 case llvm::Triple::Mesa3D:
7094 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7096 case llvm::Triple::UEFI:
7097 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7099 case llvm::Triple::Win32:
7100 switch (
Target.getEnvironment()) {
7102 if (
Target.isOSBinFormatELF())
7103 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7104 else if (
Target.isOSBinFormatMachO())
7105 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7107 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7109 case llvm::Triple::GNU:
7110 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7112 case llvm::Triple::Cygnus:
7113 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7115 case llvm::Triple::Itanium:
7116 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7119 case llvm::Triple::MSVC:
7120 case llvm::Triple::UnknownEnvironment:
7121 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7122 .starts_with_insensitive(
"bfd"))
7123 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7127 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7131 case llvm::Triple::PS4:
7132 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7134 case llvm::Triple::PS5:
7135 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7137 case llvm::Triple::Hurd:
7138 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7140 case llvm::Triple::LiteOS:
7141 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7143 case llvm::Triple::ZOS:
7144 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7146 case llvm::Triple::Vulkan:
7147 case llvm::Triple::ShaderModel:
7148 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7150 case llvm::Triple::ChipStar:
7151 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7156 switch (
Target.getArch()) {
7157 case llvm::Triple::tce:
7158 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7160 case llvm::Triple::tcele:
7161 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7163 case llvm::Triple::hexagon:
7164 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7167 case llvm::Triple::lanai:
7168 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7170 case llvm::Triple::xcore:
7171 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7173 case llvm::Triple::wasm32:
7174 case llvm::Triple::wasm64:
7175 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7177 case llvm::Triple::avr:
7178 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7180 case llvm::Triple::msp430:
7181 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7183 case llvm::Triple::riscv32:
7184 case llvm::Triple::riscv64:
7185 case llvm::Triple::riscv32be:
7186 case llvm::Triple::riscv64be:
7187 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7189 case llvm::Triple::ve:
7190 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7192 case llvm::Triple::spirv32:
7193 case llvm::Triple::spirv64:
7194 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7196 case llvm::Triple::csky:
7197 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7201 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7202 else if (
Target.isOSBinFormatELF())
7203 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7204 else if (
Target.isAppleFirmware())
7205 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7206 else if (
Target.isAppleMachO())
7207 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7208 else if (
Target.isOSBinFormatMachO())
7209 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7211 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7221 if (JA.
size() != 1 ||
7236 if (JA.
size() != 1 ||
7250 if (Args.hasArg(options::OPT_emit_static_lib))
7261 unsigned &Micro,
bool &HadExtra) {
7264 Major = Minor = Micro = 0;
7268 if (Str.consumeInteger(10, Major))
7272 if (!Str.consume_front(
"."))
7275 if (Str.consumeInteger(10, Minor))
7279 if (!Str.consume_front(
"."))
7282 if (Str.consumeInteger(10, Micro))
7300 unsigned CurDigit = 0;
7301 while (CurDigit < Digits.size()) {
7303 if (Str.consumeInteger(10, Digit))
7305 Digits[CurDigit] = Digit;
7308 if (!Str.consume_front(
"."))
7317llvm::opt::Visibility
7318Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7331const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7347 llvm_unreachable(
"Unhandled Mode");
7351 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7356 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7357 options::OPT_fno_save_optimization_record,
false))
7361 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7362 options::OPT_fno_save_optimization_record,
false))
7366 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7367 options::OPT_fno_save_optimization_record,
false))
7371 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7372 options::OPT_fno_save_optimization_record,
false))
7379 static StringRef OptName =
7381 llvm::StringRef Opt;
7382 for (StringRef Arg : Args) {
7383 if (!Arg.starts_with(OptName))
7389 return Opt.consume_front(OptName) ? Opt :
"";
7396 llvm::BumpPtrAllocator &Alloc,
7397 llvm::vfs::FileSystem *FS) {
7406 for (
const char *F : Args) {
7407 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7409 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7410 RSPQuoting = Windows;
7416 bool MarkEOLs = ClangCLMode;
7418 llvm::cl::TokenizerCallback Tokenizer;
7419 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7420 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7422 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7424 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7427 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7428 ECtx.setMarkEOLs(MarkEOLs);
7432 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7436 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7437 [](
const char *A) {
return A !=
nullptr; });
7438 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7441 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7442 Args.resize(newEnd - Args.begin());
7446 return llvm::Error::success();
7450 return SavedStrings.insert(S).first->getKeyData();
7484 llvm::StringSet<> &SavedStrings) {
7487 if (Edit[0] ==
'^') {
7488 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7489 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7490 Args.insert(Args.begin() + 1, Str);
7491 }
else if (Edit[0] ==
'+') {
7492 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7493 OS <<
"### Adding argument " << Str <<
" at end\n";
7494 Args.push_back(Str);
7495 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7496 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7497 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7498 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7499 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7501 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7503 if (Args[i] ==
nullptr)
7505 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7507 if (Repl != Args[i]) {
7508 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7512 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7513 auto Option = Edit.substr(1);
7514 for (
unsigned i = 1; i < Args.size();) {
7515 if (Option == Args[i]) {
7516 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7517 Args.erase(Args.begin() + i);
7518 if (Edit[0] ==
'X') {
7519 if (i < Args.size()) {
7520 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7521 Args.erase(Args.begin() + i);
7523 OS <<
"### Invalid X edit, end of command line!\n";
7528 }
else if (Edit[0] ==
'O') {
7529 for (
unsigned i = 1; i < Args.size();) {
7530 const char *A = Args[i];
7534 if (A[0] ==
'-' && A[1] ==
'O' &&
7535 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7536 (
'0' <= A[2] && A[2] <=
'9'))))) {
7537 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7538 Args.erase(Args.begin() + i);
7542 OS <<
"### Adding argument " << Edit <<
" at end\n";
7543 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7545 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7550 const char *OverrideStr,
7551 llvm::StringSet<> &SavedStrings,
7552 StringRef EnvVar, raw_ostream *OS) {
7554 OS = &llvm::nulls();
7556 if (OverrideStr[0] ==
'#') {
7558 OS = &llvm::nulls();
7561 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7565 const char *S = OverrideStr;
7567 const char *End = ::strchr(S,
' ');
7569 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
std::multiset< llvm::Triple > TripleSet
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static bool shouldBundleHIPAsmWithNewDriver(const Compilation &C, const llvm::opt::DerivedArgList &Args, const Driver &D)
HIP non-RDC -S for AMDGCN: emit host and device assembly separately and bundle with clang-offload-bun...
static TripleSet inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static StringRef getTriple(const Command &Job)
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction, ActionList *HIPAsmBundleDeviceOut=nullptr) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
llvm::SmallVector< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
void buildStdModuleManifestInputs(ArrayRef< StdModuleManifest::Module > ManifestEntries, Compilation &C, InputList &Inputs)
Constructs compilation inputs for each module listed in the provided Standard library module manifest...
void runModulesDriver(Compilation &C, ArrayRef< StdModuleManifest::Module > ManifestEntries)
Scans the compilation inputs for module dependencies and adjusts the compilation to build and supply ...
llvm::Expected< StdModuleManifest > readStdModuleManifest(llvm::StringRef ManifestPath, llvm::vfs::FileSystem &VFS)
Reads the Standard library module manifest at ManifestPath.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules