58#include "clang/Config/config.h"
71#include "llvm/ADT/ArrayRef.h"
72#include "llvm/ADT/STLExtras.h"
73#include "llvm/ADT/SmallSet.h"
74#include "llvm/ADT/SmallVector.h"
75#include "llvm/ADT/StringExtras.h"
76#include "llvm/ADT/StringRef.h"
77#include "llvm/ADT/StringSet.h"
78#include "llvm/ADT/StringSwitch.h"
79#include "llvm/Config/llvm-config.h"
80#include "llvm/MC/TargetRegistry.h"
81#include "llvm/Option/Arg.h"
82#include "llvm/Option/ArgList.h"
83#include "llvm/Option/OptSpecifier.h"
84#include "llvm/Option/OptTable.h"
85#include "llvm/Option/Option.h"
86#include "llvm/Support/CommandLine.h"
87#include "llvm/Support/ErrorHandling.h"
88#include "llvm/Support/ExitCodes.h"
89#include "llvm/Support/FileSystem.h"
90#include "llvm/Support/FileUtilities.h"
91#include "llvm/Support/FormatVariadic.h"
92#include "llvm/Support/IOSandbox.h"
93#include "llvm/Support/MD5.h"
94#include "llvm/Support/Path.h"
95#include "llvm/Support/PrettyStackTrace.h"
96#include "llvm/Support/Process.h"
97#include "llvm/Support/Program.h"
98#include "llvm/Support/Regex.h"
99#include "llvm/Support/StringSaver.h"
100#include "llvm/Support/VirtualFileSystem.h"
101#include "llvm/Support/raw_ostream.h"
102#include "llvm/TargetParser/Host.h"
103#include "llvm/TargetParser/RISCVISAInfo.h"
116using namespace clang;
119template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
120 return llvm::any_of(Args, [&](Arg *A) {
121 return (A->getOption().matches(options::OPT_x) &&
123 (A->getOption().
getKind() == Option::InputClass &&
124 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
126 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
132 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
133 StringRef UseCUIDStr = A->getValue();
134 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
135 .Case(
"hash", Kind::Hash)
136 .Case(
"random", Kind::Random)
137 .Case(
"none", Kind::None)
138 .Default(Kind::Invalid);
139 if (UseCUID == Kind::Invalid)
140 D.Diag(clang::diag::err_drv_invalid_value)
141 << A->getAsString(Args) << UseCUIDStr;
144 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
145 if (!FixedCUID.empty())
150 llvm::opt::DerivedArgList &Args)
const {
151 std::string CUID = FixedCUID.str();
154 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
158 llvm::MD5::MD5Result
Hash;
159 Hasher.update(InputFile);
160 for (
auto *A : Args) {
161 if (A->getOption().matches(options::OPT_INPUT))
163 Hasher.update(A->getAsString(Args));
166 CUID = llvm::utohexstr(
Hash.low(),
true);
174 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
175 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
182 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
183 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
184 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
187 this->VFS = llvm::vfs::getRealFileSystem();
192 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
195 llvm::sys::path::append(P,
SysRoot);
199#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
200 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
204 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
205 llvm::sys::path::remove_dots(configFileDir,
true);
209#if defined(CLANG_CONFIG_FILE_USER_DIR)
212 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
221void Driver::setDriverMode(StringRef
Value) {
222 static StringRef OptName =
223 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
224 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
225 .Case(
"gcc", GCCMode)
226 .Case(
"g++", GXXMode)
227 .Case(
"cpp", CPPMode)
229 .Case(
"flang", FlangMode)
230 .Case(
"dxc", DXCMode)
234 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
239 bool &ContainsError)
const {
240 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
241 ContainsError =
false;
243 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
244 unsigned MissingArgIndex, MissingArgCount;
245 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
246 MissingArgCount, VisibilityMask);
249 if (MissingArgCount) {
250 Diag(diag::err_drv_missing_argument)
251 << Args.getArgString(MissingArgIndex) << MissingArgCount;
253 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
258 for (
const Arg *A : Args) {
260 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
261 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
268 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
269 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
270 ContainsError |= Diags.getDiagnosticLevel(
271 diag::warn_drv_empty_joined_argument,
276 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
278 auto ArgString = A->getAsString(Args);
280 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
282 if (
getOpts().findExact(ArgString, Nearest,
284 DiagID = diag::err_drv_unknown_argument_with_suggestion;
285 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
287 DiagID = diag::err_drv_unknown_argument;
288 Diags.Report(DiagID) << ArgString;
291 llvm::opt::Visibility(
293 DiagID = diag::err_drv_unknown_argument_with_suggestion;
294 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
296 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
297 : diag::err_drv_unknown_argument;
298 Diags.Report(DiagID) << ArgString;
302 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
303 : diag::err_drv_unknown_argument_with_suggestion;
304 Diags.Report(DiagID) << ArgString << Nearest;
306 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
310 for (
const Arg *A : Args.filtered(options::OPT_o)) {
311 if (ArgStrings[A->getIndex()] == A->getSpelling())
315 std::string ArgString = ArgStrings[A->getIndex()];
317 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
318 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
319 << A->getAsString(Args) << Nearest;
329 Arg **FinalPhaseArg)
const {
330 Arg *PhaseArg =
nullptr;
334 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
335 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
336 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
337 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
344 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
345 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
346 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
347 options::OPT_fmodule_header_EQ))) {
350 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
351 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
353 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
364 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
368 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
379 *FinalPhaseArg = PhaseArg;
387 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
388 llvm::sys::fs::OF_Text);
389 llvm::FileRemover OutputRemover(OutputFile.c_str());
390 std::optional<llvm::StringRef> Redirects[] = {
396 std::string ErrorMessage;
397 int SecondsToWait = 60;
398 if (std::optional<std::string> Str =
399 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
400 if (!llvm::to_integer(*Str, SecondsToWait))
401 return llvm::createStringError(std::error_code(),
402 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
403 "an integer, got '" +
405 SecondsToWait = std::max(SecondsToWait, 0);
407 StringRef Executable = Args[0];
408 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
410 return llvm::createStringError(std::error_code(),
411 Executable +
": " + ErrorMessage);
413 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
414 llvm::MemoryBuffer::getFile(OutputFile.c_str());
416 return llvm::createStringError(OutputBuf.getError(),
417 "Failed to read stdout of " + Executable +
418 ": " + OutputBuf.getError().message());
419 return std::move(*OutputBuf);
423 StringRef
Value,
bool Claim =
true) {
424 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
425 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
426 Args.AddSynthesizedArg(A);
432DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
433 const llvm::opt::OptTable &Opts =
getOpts();
434 DerivedArgList *DAL =
new DerivedArgList(Args);
436 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
437 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
438 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
439 bool IgnoreUnused =
false;
440 for (Arg *A : Args) {
444 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
448 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
449 IgnoreUnused =
false;
459 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
460 A->getOption().matches(options::OPT_Xlinker)) &&
461 A->containsValue(
"--no-demangle")) {
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
466 for (StringRef Val : A->getValues())
467 if (Val !=
"--no-demangle")
468 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
476 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
477 A->getNumValues() > 0 &&
478 (A->getValue(0) == StringRef(
"-MD") ||
479 A->getValue(0) == StringRef(
"-MMD"))) {
481 if (A->getValue(0) == StringRef(
"-MD"))
482 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
485 if (A->getNumValues() == 2)
486 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
491 if (A->getOption().matches(options::OPT_l)) {
492 StringRef
Value = A->getValue();
495 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
497 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
502 if (
Value ==
"cc_kext") {
503 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
509 if (A->getOption().matches(options::OPT__DASH_DASH)) {
511 for (StringRef Val : A->getValues())
520 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
521 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
524 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
525 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
529#if defined(HOST_LINK_VERSION)
530 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
531 strlen(HOST_LINK_VERSION) > 0) {
532 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
534 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
542 StringRef ArgTarget) {
544 static bool BeSilent =
false;
545 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
546 return ((v < 2) || ((v == 2) && (r < 4)));
550 if (ArgTarget.equals_insensitive(
"CURRENT")) {
554 unsigned int Version = 0;
555 unsigned int Release = 0;
556 unsigned int Modification = 0;
558 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
559 llvm::Regex HexRegex(
562 "([0-9a-fA-F][0-9a-fA-F])"
563 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
566 if (ZOsvRegex.match(ArgTarget, &Matches)) {
567 Matches[1].getAsInteger(10, Version);
568 Matches[2].getAsInteger(10, Release);
570 if (IsTooOldToBeSupported(Version, Release)) {
572 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
575 }
else if (HexRegex.match(ArgTarget, &Matches)) {
576 Matches[1].getAsInteger(16, Version);
577 Matches[2].getAsInteger(16, Release);
578 Matches[3].getAsInteger(16, Modification);
579 if (IsTooOldToBeSupported(Version, Release)) {
581 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
587 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
592 llvm::VersionTuple
V(Version, Release, Modification);
593 llvm::VersionTuple TV =
Target.getOSVersion();
596 if (TV.empty() ||
V < TV) {
598 Str = llvm::Triple::getOSTypeName(
Target.getOS());
599 Str +=
V.getAsString();
612 StringRef TargetTriple,
614 StringRef DarwinArchName =
"") {
616 if (
const Arg *A = Args.getLastArg(options::OPT_target))
617 TargetTriple = A->getValue();
619 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
624 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
628 if (
Target.isOSBinFormatMachO()) {
630 if (!DarwinArchName.empty()) {
637 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
638 StringRef ArchName = A->getValue();
645 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
646 options::OPT_mbig_endian)) {
647 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
648 ?
Target.getLittleEndianArchVariant()
649 :
Target.getBigEndianArchVariant();
650 if (
T.getArch() != llvm::Triple::UnknownArch) {
652 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
657 if (
Target.getArch() == llvm::Triple::tce)
662 if (std::optional<std::string> ObjectModeValue =
663 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
664 StringRef ObjectMode = *ObjectModeValue;
665 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
667 if (ObjectMode ==
"64") {
668 AT =
Target.get64BitArchVariant().getArch();
669 }
else if (ObjectMode ==
"32") {
670 AT =
Target.get32BitArchVariant().getArch();
672 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
675 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
681 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
682 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
685 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
687 D.
Diag(diag::err_drv_unsupported_opt_for_target)
688 << A->getAsString(Args) <<
Target.str();
691 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
692 options::OPT_m32, options::OPT_m16,
693 options::OPT_maix32, options::OPT_maix64);
695 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
697 if (A->getOption().matches(options::OPT_m64) ||
698 A->getOption().matches(options::OPT_maix64)) {
699 AT =
Target.get64BitArchVariant().getArch();
700 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
701 Target.getEnvironment() == llvm::Triple::GNUT64)
702 Target.setEnvironment(llvm::Triple::GNU);
703 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
704 Target.setEnvironment(llvm::Triple::Musl);
705 }
else if (A->getOption().matches(options::OPT_mx32) &&
706 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
707 AT = llvm::Triple::x86_64;
708 if (
Target.getEnvironment() == llvm::Triple::Musl)
709 Target.setEnvironment(llvm::Triple::MuslX32);
711 Target.setEnvironment(llvm::Triple::GNUX32);
712 }
else if (A->getOption().matches(options::OPT_m32) ||
713 A->getOption().matches(options::OPT_maix32)) {
715 D.
Diag(diag::err_drv_unsupported_opt_for_target)
716 << A->getAsString(Args) <<
Target.str();
718 AT =
Target.get32BitArchVariant().getArch();
719 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
720 Target.setEnvironment(llvm::Triple::GNU);
721 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
722 Target.setEnvironment(llvm::Triple::Musl);
724 }
else if (A->getOption().matches(options::OPT_m16) &&
725 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
726 AT = llvm::Triple::x86;
727 Target.setEnvironment(llvm::Triple::CODE16);
730 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
732 if (
Target.isWindowsGNUEnvironment())
738 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
744 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
745 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
746 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
749 if (A && !A->getOption().matches(options::OPT_m32))
750 D.
Diag(diag::err_drv_argument_not_allowed_with)
751 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
753 Target.setArch(llvm::Triple::x86);
754 Target.setArchName(
"i586");
755 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
756 Target.setEnvironmentName(
"");
757 Target.setOS(llvm::Triple::ELFIAMCU);
758 Target.setVendor(llvm::Triple::UnknownVendor);
759 Target.setVendorName(
"intel");
765 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
766 StringRef ABIName = A->getValue();
767 if (ABIName ==
"32") {
769 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
770 Target.getEnvironment() == llvm::Triple::GNUABIN32)
771 Target.setEnvironment(llvm::Triple::GNU);
772 }
else if (ABIName ==
"n32") {
774 if (
Target.getEnvironment() == llvm::Triple::GNU ||
775 Target.getEnvironment() == llvm::Triple::GNUT64 ||
776 Target.getEnvironment() == llvm::Triple::GNUABI64)
777 Target.setEnvironment(llvm::Triple::GNUABIN32);
778 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
779 Target.getEnvironment() == llvm::Triple::MuslABI64)
780 Target.setEnvironment(llvm::Triple::MuslABIN32);
781 }
else if (ABIName ==
"64") {
783 if (
Target.getEnvironment() == llvm::Triple::GNU ||
784 Target.getEnvironment() == llvm::Triple::GNUT64 ||
785 Target.getEnvironment() == llvm::Triple::GNUABIN32)
786 Target.setEnvironment(llvm::Triple::GNUABI64);
787 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
788 Target.getEnvironment() == llvm::Triple::MuslABIN32)
789 Target.setEnvironment(llvm::Triple::MuslABI64);
797 if (Args.hasArg(options::OPT_march_EQ) ||
798 Args.hasArg(options::OPT_mcpu_EQ)) {
800 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
802 if (!llvm::errorToBool(ISAInfo.takeError())) {
803 unsigned XLen = (*ISAInfo)->getXLen();
805 Target.setArch(llvm::Triple::riscv32);
807 Target.setArch(llvm::Triple::riscv64);
819 OptSpecifier OptEq, OptSpecifier OptNeg) {
820 if (!Args.hasFlag(OptEq, OptNeg,
false))
823 const Arg *A = Args.getLastArg(OptEq);
824 StringRef LTOName = A->getValue();
832 D.
Diag(diag::err_drv_unsupported_option_argument)
833 << A->getSpelling() << A->getValue();
840void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
842 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
844 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
845 options::OPT_fno_offload_lto);
848 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
849 options::OPT_fno_openmp_target_jit,
false)) {
850 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
851 options::OPT_fno_offload_lto))
853 Diag(diag::err_drv_incompatible_options)
854 << A->getSpelling() <<
"-fopenmp-target-jit";
861 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
863 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
865 RuntimeName = A->getValue();
867 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
875 Diag(diag::err_drv_unsupported_option_argument)
876 << A->getSpelling() << A->getValue();
879 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
888 StringRef Program =
C.getArgs().getLastArgValue(
889 options::OPT_offload_arch_tool_EQ,
"offload-arch");
892 if (llvm::ErrorOr<std::string> Executable =
893 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
896 Args.push_back(
"--only=amdgpu");
898 Args.push_back(
"--only=nvptx");
899 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
902 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
907 if ((*StdoutOrErr)->getBuffer().empty()) {
908 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
914 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
916 GPUArchs.push_back(
Arch.str());
918 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
925static llvm::DenseSet<llvm::StringRef>
927 std::set<std::string> Archs;
928 for (Arg *A :
C.getInputArgs()) {
929 for (StringRef
Arch : A->getValues()) {
930 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
931 if (
Arch ==
"native") {
933 Archs.insert(Str.str());
935 Archs.insert(
Arch.str());
937 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
941 Archs.erase(
Arch.str());
946 llvm::DenseSet<llvm::StringRef> Triples;
947 for (llvm::StringRef
Arch : Archs) {
954 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
956 return llvm::DenseSet<llvm::StringRef>();
959 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
961 return llvm::DenseSet<llvm::StringRef>();
965 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
967 return llvm::DenseSet<llvm::StringRef>();
970 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
971 <<
"offload" <<
Arch;
972 return llvm::DenseSet<llvm::StringRef>();
977 Triple =
"spirv64-amd-amdhsa";
979 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
980 ?
"nvptx64-nvidia-cuda"
981 :
"nvptx-nvidia-cuda";
983 Triple =
"amdgcn-amd-amdhsa";
990 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
991 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
992 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
993 C.getArgs().MakeArgString(Triple.split(
"-").first),
994 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
996 C.getArgs().append(A);
997 C.getArgs().AddSynthesizedArg(A);
998 Triples.insert(Triple);
1003 Triples.insert(
"amdgcn-amd-amdhsa");
1005 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1006 ?
"nvptx64-nvidia-cuda"
1007 :
"nvptx-nvidia-cuda");
1009 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1010 ?
"spirv64-unknown-unknown"
1011 :
"spirv32-unknown-unknown");
1014 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1015 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1022 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1023 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1025 llvm::any_of(Inputs,
1026 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1031 (llvm::any_of(Inputs,
1032 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1035 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1036 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1038 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1039 options::OPT_fno_sycl,
false);
1040 bool IsOpenMPOffloading =
1042 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1043 options::OPT_fno_openmp,
false) &&
1044 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1045 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1046 !(IsCuda || IsHIP))));
1048 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1049 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1054 for (
const auto &[Active, Kind] : ActiveKinds)
1059 if (Kinds.size() > 1) {
1060 Diag(clang::diag::err_drv_mix_offload)
1067 if (IsCuda || IsHIP)
1073 std::multiset<llvm::StringRef> Triples;
1074 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1075 std::vector<std::string> ArgValues =
1076 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1077 for (llvm::StringRef
Target : ArgValues)
1078 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1080 if (ArgValues.empty())
1081 Diag(clang::diag::warn_drv_empty_joined_argument)
1083 .getLastArg(options::OPT_offload_targets_EQ)
1084 ->getAsString(
C.getInputArgs());
1085 }
else if (Kinds.size() > 0) {
1088 Triples.insert(Derived.begin(), Derived.end());
1093 llvm::StringMap<StringRef> FoundNormalizedTriples;
1094 for (StringRef
Target : Triples) {
1099 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1107 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1108 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1109 Diag(clang::diag::err_drv_argument_not_allowed_with)
1110 << IncompatArg->getSpelling() <<
"-fsycl";
1118 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1119 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1123 std::string NormalizedName = TT.normalize();
1124 auto [TripleIt, Inserted] =
1125 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1127 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1128 <<
Target << TripleIt->second;
1132 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1133 C.getDefaultToolChain().getTriple());
1137 auto &CudaInstallation =
1139 if (CudaInstallation.isValid())
1140 CudaInstallation.WarnIfUnsupportedVersion();
1143 C.addOffloadDeviceToolChain(&TC, Kind);
1148bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1153 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1157 if (!PathLIBEnv.empty()) {
1158 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1159 if (llvm::sys::fs::is_directory(PathLIBEnv))
1160 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1161 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1162 return readConfigFile(CustomizationFile, ExpCtx);
1163 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1168 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1169 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1170 return readConfigFile(CustomizationFile, ExpCtx);
1180 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1181 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1182 Copy->getValues() = Opt->getValues();
1183 if (Opt->isClaimed())
1185 Copy->setOwnsValues(Opt->getOwnsValues());
1186 Opt->setOwnsValues(
false);
1188 if (Opt->getAlias()) {
1189 const Arg *Alias = Opt->getAlias();
1190 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1191 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1192 Args.getArgString(Index), Index);
1193 AliasCopy->getValues() = Alias->getValues();
1194 AliasCopy->setOwnsValues(
false);
1195 if (Alias->isClaimed())
1197 Copy->setAlias(std::move(AliasCopy));
1201bool Driver::readConfigFile(StringRef
FileName,
1202 llvm::cl::ExpansionContext &ExpCtx) {
1206 Diag(diag::err_drv_cannot_open_config_file)
1207 <<
FileName << Status.getError().message();
1210 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1211 Diag(diag::err_drv_cannot_open_config_file)
1212 <<
FileName <<
"not a regular file";
1217 SmallVector<const char *, 32> NewCfgFileArgs;
1218 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1219 Diag(diag::err_drv_cannot_read_config_file)
1225 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1226 for (
const char *Opt : NewCfgFileArgs) {
1228 if (Opt[0] ==
'$' && Opt[1])
1229 NewCfgTailArgs.push_back(Opt + 1);
1231 NewCfgHeadArgs.push_back(Opt);
1235 llvm::SmallString<128> CfgFileName(
FileName);
1236 llvm::sys::path::native(CfgFileName);
1237 bool ContainErrors =
false;
1238 auto NewHeadOptions = std::make_unique<InputArgList>(
1242 auto NewTailOptions = std::make_unique<InputArgList>(
1249 for (Arg *A : *NewHeadOptions)
1251 for (Arg *A : *NewTailOptions)
1254 if (!CfgOptionsHead)
1255 CfgOptionsHead = std::move(NewHeadOptions);
1258 for (
auto *Opt : *NewHeadOptions)
1262 if (!CfgOptionsTail)
1263 CfgOptionsTail = std::move(NewTailOptions);
1266 for (
auto *Opt : *NewTailOptions)
1270 ConfigFiles.push_back(std::string(CfgFileName));
1274bool Driver::loadConfigFiles() {
1275 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1276 llvm::cl::tokenizeConfigFile);
1277 ExpCtx.setVFS(&
getVFS());
1281 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1282 SmallString<128> CfgDir;
1284 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1285 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1290 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1291 SmallString<128> CfgDir;
1292 llvm::sys::fs::expand_tilde(
1293 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1294 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1303 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1306 if (loadDefaultConfigFiles(ExpCtx))
1310 SmallString<128> CfgFilePath;
1312 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1315 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1316 CfgFilePath.assign(CfgFileName);
1317 if (llvm::sys::path::is_relative(CfgFilePath)) {
1318 if (
getVFS().makeAbsolute(CfgFilePath)) {
1319 Diag(diag::err_drv_cannot_open_config_file)
1320 << CfgFilePath <<
"cannot get absolute path";
1324 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1326 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1327 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1328 if (!SearchDir.empty())
1329 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1334 if (readConfigFile(CfgFilePath, ExpCtx))
1345 llvm::Triple Triple, std::string Suffix) {
1347 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1351 VersionTuple OSVersion = Triple.getOSVersion();
1352 if (!OSVersion.getMinor().has_value())
1355 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1359 if (OSVersion.getMajor() != 0) {
1360 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1361 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1367 Triple.setOSName(BaseOSName);
1368 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1371bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1374 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1378 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1381 std::string RealMode = getExecutableForDriverMode(Mode);
1382 llvm::Triple Triple;
1391 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1392 PrefixTriple.isOSUnknown())
1393 Triple = PrefixTriple;
1397 llvm::Triple RealTriple =
1399 if (Triple.str().empty()) {
1400 Triple = RealTriple;
1401 assert(!Triple.str().empty());
1406 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1420 SmallString<128> CfgFilePath;
1422 "-" + RealMode +
".cfg"))
1423 return readConfigFile(CfgFilePath, ExpCtx);
1427 if (TryModeSuffix) {
1430 return readConfigFile(CfgFilePath, ExpCtx);
1435 std::string CfgFileName = RealMode +
".cfg";
1436 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1437 if (readConfigFile(CfgFilePath, ExpCtx))
1439 }
else if (TryModeSuffix) {
1441 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1442 readConfigFile(CfgFilePath, ExpCtx))
1448 return readConfigFile(CfgFilePath, ExpCtx);
1456 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1465 if (!DriverMode.empty())
1466 setDriverMode(DriverMode);
1472 CLOptions = std::make_unique<InputArgList>(
1477 ContainsError = loadConfigFiles();
1478 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1479 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1483 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1485 if (HasConfigFileHead)
1486 for (
auto *Opt : *CLOptions)
1487 if (!Opt->getOption().matches(options::OPT_config))
1491 if (
IsCLMode() && !ContainsError) {
1493 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1495 CLModePassThroughArgList.push_back(A->getValue());
1498 if (!CLModePassThroughArgList.empty()) {
1501 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1506 for (
auto *Opt : *CLModePassThroughOptions)
1512 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1513 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1514 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1517 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1518 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1519 if (!VFS->exists(IncludeDir))
1520 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1525 bool CCCPrintPhases;
1528 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1529 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1532 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1533 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1536 Args.ClaimAllArgs(options::OPT_pipe);
1544 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1546 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1547 CCCGenericGCCName = A->getValue();
1550 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1554 if (Args.hasArg(options::OPT_fproc_stat_report))
1561 llvm::Triple
T(TargetTriple);
1562 T.setOS(llvm::Triple::Win32);
1563 T.setVendor(llvm::Triple::PC);
1564 T.setEnvironment(llvm::Triple::MSVC);
1565 T.setObjectFormat(llvm::Triple::COFF);
1566 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1567 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1568 TargetTriple =
T.str();
1571 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1572 StringRef TargetProfile = A->getValue();
1575 TargetTriple = *Triple;
1577 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1581 if (Args.hasArg(options::OPT_spirv)) {
1582 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1583 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1584 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1585 llvm::Triple
T(TargetTriple);
1588 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1590 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1591 TargetInfo = ValidTargets.find(A->getValue());
1593 Diag(diag::err_drv_invalid_value)
1594 << A->getAsString(Args) << A->getValue();
1600 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1601 TargetTriple =
T.str();
1605 Diag(diag::err_drv_dxc_missing_target_profile);
1609 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1610 TargetTriple = A->getValue();
1611 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1612 Dir =
Dir = A->getValue();
1613 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1617 if (std::optional<std::string> CompilerPathValue =
1618 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1619 StringRef CompilerPath = *CompilerPathValue;
1620 while (!CompilerPath.empty()) {
1621 std::pair<StringRef, StringRef> Split =
1622 CompilerPath.split(llvm::sys::EnvPathSeparator);
1623 PrefixDirs.push_back(std::string(Split.first));
1624 CompilerPath = Split.second;
1627 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1629 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1632 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1635 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1636 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1637 .Case(
"cwd", SaveTempsCwd)
1638 .Case(
"obj", SaveTempsObj)
1639 .Default(SaveTempsCwd);
1642 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1643 options::OPT_offload_device_only,
1644 options::OPT_offload_host_device)) {
1645 if (A->getOption().matches(options::OPT_offload_host_only))
1646 Offload = OffloadHost;
1647 else if (A->getOption().matches(options::OPT_offload_device_only))
1648 Offload = OffloadDevice;
1650 Offload = OffloadHostDevice;
1656 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1657 StringRef
Name = A->getValue();
1658 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1659 .Case(
"off", EmbedNone)
1660 .Case(
"all", EmbedBitcode)
1661 .Case(
"bitcode", EmbedBitcode)
1662 .Case(
"marker", EmbedMarker)
1665 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1668 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1672 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1673 llvm::sys::fs::remove(A->getValue());
1679 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1681 !Args.hasArg(options::OPT_fmodules) && Std &&
1682 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1683 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1684 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1685 Std->containsValue(
"c++latest"));
1688 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1689 options::OPT_fmodule_header)) {
1691 ModulesModeCXX20 =
true;
1692 if (A->getOption().matches(options::OPT_fmodule_header))
1695 StringRef ArgName = A->getValue();
1696 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1701 Diags.Report(diag::err_drv_invalid_value)
1702 << A->getAsString(Args) << ArgName;
1708 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1709 std::make_unique<InputArgList>(std::move(Args));
1719 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1720 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1722 bool MLContainsError;
1723 auto MultilibMacroDefineList =
1725 MLMacroDefinesChar,
false, MLContainsError));
1726 if (!MLContainsError) {
1727 for (
auto *Opt : *MultilibMacroDefineList) {
1734 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1738 if (!Triple.isWasm()) {
1739 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1740 StringRef TripleObjectFormat =
1741 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1742 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1743 TripleVersionName != TripleObjectFormat) {
1744 Diags.Report(diag::err_drv_triple_version_invalid)
1746 ContainsError =
true;
1751 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1752 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1753 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1761 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1762 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1764 case llvm::Triple::arm:
1765 case llvm::Triple::armeb:
1766 case llvm::Triple::thumb:
1767 case llvm::Triple::thumbeb:
1768 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1769 Diag(diag::warn_target_unrecognized_env)
1771 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1774 case llvm::Triple::aarch64:
1775 case llvm::Triple::aarch64_be:
1776 case llvm::Triple::aarch64_32:
1777 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1778 Diag(diag::warn_target_unrecognized_env)
1780 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1797 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1798 if (HasConfigFileTail && Inputs.size()) {
1801 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1802 for (Arg *A : *CfgOptionsTail)
1803 TranslatedLinkerIns.append(A);
1804 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1813 if (TC.
getTriple().isOSBinFormatMachO())
1818 if (CCCPrintPhases) {
1829 llvm::opt::ArgStringList ASL;
1830 for (
const auto *A : Args) {
1834 while (A->getAlias())
1836 A->render(Args, ASL);
1839 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1840 if (I != ASL.begin())
1842 llvm::sys::printArg(OS, *I,
true);
1847bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1848 SmallString<128> &CrashDiagDir) {
1849 using namespace llvm::sys;
1850 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1851 "Only knows about .crash files on Darwin");
1853 auto BypassSandbox = sandbox::scopedDisable();
1858 path::home_directory(CrashDiagDir);
1859 if (CrashDiagDir.starts_with(
"/var/root"))
1861 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1869 fs::file_status FileStatus;
1870 TimePoint<> LastAccessTime;
1871 SmallString<128> CrashFilePath;
1874 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1875 File != FileEnd && !EC;
File.increment(EC)) {
1879 if (fs::status(
File->path(), FileStatus))
1881 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1882 llvm::MemoryBuffer::getFile(
File->path());
1887 StringRef
Data = CrashFile.get()->getBuffer();
1888 if (!
Data.starts_with(
"Process:"))
1891 size_t ParentProcPos =
Data.find(
"Parent Process:");
1892 if (ParentProcPos == StringRef::npos)
1894 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1895 if (LineEnd == StringRef::npos)
1897 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1898 int OpenBracket = -1, CloseBracket = -1;
1899 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1900 if (ParentProcess[i] ==
'[')
1902 if (ParentProcess[i] ==
']')
1908 if (OpenBracket < 0 || CloseBracket < 0 ||
1909 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1910 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1920 const auto FileAccessTime = FileStatus.getLastModificationTime();
1921 if (FileAccessTime > LastAccessTime) {
1922 CrashFilePath.assign(
File->path());
1923 LastAccessTime = FileAccessTime;
1928 if (!CrashFilePath.empty()) {
1929 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1939 "\n********************\n\n"
1940 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1941 "Preprocessed source(s) and associated run script(s) are located at:";
1949 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1953 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1954 Level = llvm::StringSwitch<unsigned>(A->getValue())
1956 .Case(
"compiler", 1)
1968 ArgStringList SavedTemps;
1970 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1971 if (!IsLLD || Level < 2)
1978 SavedTemps = std::move(
C.getTempFiles());
1979 assert(!
C.getTempFiles().size());
1996 C.initCompilationForDiagnostics();
2001 Command NewLLDInvocation = Cmd;
2002 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2003 StringRef ReproduceOption =
2004 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2007 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2011 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2013 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2014 Diag(clang::diag::note_drv_command_failed_diag_msg)
2015 <<
"\n\n********************";
2017 Report->TemporaryFiles.push_back(TmpName);
2025 ArgStringList IRInputs;
2026 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2027 bool IgnoreInput =
false;
2033 IRInputs.push_back(it->second->getValue());
2037 }
else if (!strcmp(it->second->getValue(),
"-")) {
2038 Diag(clang::diag::note_drv_command_failed_diag_msg)
2039 <<
"Error generating preprocessed source(s) - "
2040 "ignoring input from stdin.";
2045 it = Inputs.erase(it);
2052 if (Inputs.empty() && IRInputs.empty()) {
2053 Diag(clang::diag::note_drv_command_failed_diag_msg)
2054 <<
"Error generating preprocessed source(s) - "
2055 "no preprocessable inputs.";
2062 for (
const Arg *A :
C.getArgs()) {
2063 if (A->getOption().matches(options::OPT_arch)) {
2064 StringRef ArchName = A->getValue();
2069 Diag(clang::diag::note_drv_command_failed_diag_msg)
2070 <<
"Error generating preprocessed source(s) - cannot generate "
2071 "preprocessed source with multiple -arch options.";
2076 if (!Inputs.empty()) {
2079 const ToolChain &TC =
C.getDefaultToolChain();
2080 if (TC.
getTriple().isOSBinFormatMachO())
2089 Diag(clang::diag::note_drv_command_failed_diag_msg)
2090 <<
"Error generating preprocessed source(s).";
2095 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2098 if (!FailingCommands.empty()) {
2099 Diag(clang::diag::note_drv_command_failed_diag_msg)
2100 <<
"Error generating preprocessed source(s).";
2104 const ArgStringList &TempFiles =
C.getTempFiles();
2105 if (TempFiles.empty()) {
2106 Diag(clang::diag::note_drv_command_failed_diag_msg)
2107 <<
"Error generating preprocessed source(s).";
2113 const ArgStringList &Files =
C.getTempFiles();
2118 for (
auto const *Input : IRInputs) {
2122 StringRef extension = llvm::sys::path::extension(Input);
2123 if (!extension.empty())
2124 extension = extension.drop_front();
2126 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2127 llvm::sys::path::stem(Input), extension, FD, Path);
2129 Diag(clang::diag::note_drv_command_failed_diag_msg)
2130 <<
"Error generating run script: " <<
"Failed copying IR input files"
2131 <<
" " << EC.message();
2135 EC = llvm::sys::fs::copy_file(Input, FD);
2137 Diag(clang::diag::note_drv_command_failed_diag_msg)
2138 <<
"Error generating run script: " <<
"Failed copying IR input files"
2139 <<
" " << EC.message();
2143 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2150 for (std::string &TempFile : TempFiles) {
2151 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2153 Report->TemporaryFiles.push_back(TempFile);
2154 if (ReproCrashFilename.empty()) {
2155 ReproCrashFilename = TempFile;
2156 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2158 if (StringRef(TempFile).ends_with(
".cache")) {
2161 VFS = llvm::sys::path::filename(TempFile);
2162 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2166 for (
const char *TempFile : SavedTemps)
2167 TempFiles.push_back(TempFile);
2173 llvm::sys::path::replace_extension(Script,
"sh");
2175 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2176 llvm::sys::fs::FA_Write,
2177 llvm::sys::fs::OF_Text);
2179 Diag(clang::diag::note_drv_command_failed_diag_msg)
2180 <<
"Error generating run script: " << Script <<
" " << EC.message();
2183 <<
"# Driver args: ";
2185 ScriptOS <<
"# Original command: ";
2186 Cmd.
Print(ScriptOS,
"\n",
true);
2187 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2188 if (!AdditionalInformation.empty())
2189 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2192 Report->TemporaryFiles.push_back(std::string(Script));
2193 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2197 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2199 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2200 Diag(clang::diag::note_drv_command_failed_diag_msg)
2201 << ReproCrashFilename.str();
2203 llvm::sys::path::append(CrashDiagDir,
Name);
2204 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2205 Diag(clang::diag::note_drv_command_failed_diag_msg)
2206 <<
"Crash backtrace is located in";
2207 Diag(clang::diag::note_drv_command_failed_diag_msg)
2208 << CrashDiagDir.str();
2209 Diag(clang::diag::note_drv_command_failed_diag_msg)
2210 <<
"(choose the .crash file that corresponds to your crash)";
2214 Diag(clang::diag::note_drv_command_failed_diag_msg)
2215 <<
"\n\n********************";
2225 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2236 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2237 if (
C.getArgs().hasArg(options::OPT_v))
2238 C.getJobs().Print(llvm::errs(),
"\n",
true);
2240 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2243 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2250 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2251 C.getJobs().Print(llvm::errs(),
"\n",
true);
2252 return Diags.hasErrorOccurred() ? 1 : 0;
2256 if (Diags.hasErrorOccurred())
2260 for (
auto &Job :
C.getJobs())
2261 setUpResponseFiles(
C, Job);
2263 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2266 if (FailingCommands.empty())
2272 for (
const auto &CmdPair : FailingCommands) {
2273 int CommandRes = CmdPair.first;
2274 const Command *FailingCommand = CmdPair.second;
2279 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2283 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2288 if (CommandRes == EX_IOERR) {
2305 Diag(clang::diag::err_drv_command_signalled)
2308 Diag(clang::diag::err_drv_command_failed)
2316 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2318 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2332 const ToolChain &TC =
C.getDefaultToolChain();
2336 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2339 OS <<
"Thread model: " << A->getValue();
2345 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2350 if (!llvm::cl::getCompilerBuildConfig().empty())
2351 llvm::cl::printBuildConfig(OS);
2354 for (
auto ConfigFile : ConfigFiles)
2355 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2368 if (PassedFlags ==
"")
2372 std::vector<std::string> SuggestedCompletions;
2373 std::vector<std::string> Flags;
2385 const bool HasSpace = PassedFlags.ends_with(
",");
2389 StringRef TargetFlags = PassedFlags;
2390 while (TargetFlags !=
"") {
2392 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2393 Flags.push_back(std::string(CurFlag));
2398 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2401 const llvm::opt::OptTable &Opts =
getOpts();
2403 Cur = Flags.at(Flags.size() - 1);
2405 if (Flags.size() >= 2) {
2406 Prev = Flags.at(Flags.size() - 2);
2407 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2410 if (SuggestedCompletions.empty())
2411 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2418 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2419 llvm::outs() <<
'\n';
2425 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2429 SuggestedCompletions = Opts.findByPrefix(
2430 Cur, VisibilityMask,
2437 if (S.starts_with(Cur))
2438 SuggestedCompletions.push_back(std::string(S));
2445 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2446 if (
int X = A.compare_insensitive(B))
2448 return A.compare(B) > 0;
2451 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2458 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2459 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2463 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2466 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2470 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2475 if (
C.getArgs().hasArg(options::OPT_help) ||
2476 C.getArgs().hasArg(options::OPT__help_hidden)) {
2477 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2481 if (
C.getArgs().hasArg(options::OPT__version)) {
2487 if (
C.getArgs().hasArg(options::OPT_v) ||
2488 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2489 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2490 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2491 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2493 SuppressMissingInputWarning =
true;
2496 if (
C.getArgs().hasArg(options::OPT_v)) {
2498 llvm::errs() <<
"System configuration file directory: "
2501 llvm::errs() <<
"User configuration file directory: "
2505 const ToolChain &TC =
C.getDefaultToolChain();
2507 if (
C.getArgs().hasArg(options::OPT_v))
2510 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2515 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2516 llvm::outs() <<
"programs: =";
2517 bool separator =
false;
2521 llvm::outs() << llvm::sys::EnvPathSeparator;
2522 llvm::outs() << Path;
2527 llvm::outs() << llvm::sys::EnvPathSeparator;
2528 llvm::outs() << Path;
2531 llvm::outs() <<
"\n";
2534 StringRef sysroot =
C.getSysRoot();
2538 llvm::outs() << llvm::sys::EnvPathSeparator;
2541 llvm::outs() << sysroot << Path.substr(1);
2543 llvm::outs() << Path;
2545 llvm::outs() <<
"\n";
2549 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2555 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2556 for (
auto RuntimePath :
2558 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2559 llvm::outs() << *RuntimePath <<
'\n';
2563 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2567 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2569 for (std::size_t I = 0; I != Flags.size(); I += 2)
2570 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2576 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2577 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2581 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2582 StringRef ProgName = A->getValue();
2585 if (! ProgName.empty())
2588 llvm::outs() <<
"\n";
2592 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2593 StringRef PassedFlags = A->getValue();
2598 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2612 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2615 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2621 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2628 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2631 std::set<llvm::StringRef> SortedFlags;
2632 for (
const auto &FlagEntry : ExpandedFlags)
2633 SortedFlags.insert(FlagEntry.getKey());
2634 for (
auto Flag : SortedFlags)
2635 llvm::outs() << Flag <<
'\n';
2639 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2642 llvm::outs() <<
".\n";
2645 assert(Suffix.front() ==
'/');
2646 llvm::outs() << Suffix.substr(1) <<
"\n";
2652 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2657 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2659 llvm::outs() << Triple.getTriple() <<
"\n";
2663 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2664 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2681 std::map<Action *, unsigned> &Ids,
2683 if (
auto It = Ids.find(A); It != Ids.end())
2687 llvm::raw_string_ostream os(str);
2689 auto getSibIndent = [](
int K) -> Twine {
2693 Twine SibIndent =
Indent + getSibIndent(Kind);
2697 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2699 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2700 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2701 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2703 OA->doOnEachDependence(
2705 assert(TC &&
"Unknown host toolchain");
2717 os <<
":" << BoundArch;
2720 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2728 const char *Prefix =
"{";
2729 for (
Action *PreRequisite : *AL) {
2730 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2741 std::string offload_str;
2742 llvm::raw_string_ostream offload_os(offload_str);
2746 offload_os <<
", (" << S;
2753 auto getSelfIndent = [](
int K) -> Twine {
2757 unsigned Id = Ids.size();
2759 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2768 std::map<Action *, unsigned> Ids;
2769 for (
Action *A :
C.getActions())
2785 DerivedArgList &Args =
C.getArgs();
2787 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2792 for (Arg *A : Args) {
2793 if (A->getOption().matches(options::OPT_arch)) {
2796 llvm::Triple::ArchType
Arch =
2798 if (
Arch == llvm::Triple::UnknownArch) {
2799 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2804 if (
ArchNames.insert(A->getValue()).second)
2805 Archs.push_back(A->getValue());
2819 for (
Action* Act : SingleActions) {
2827 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2831 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2836 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2837 Actions.append(Inputs.begin(), Inputs.end());
2839 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2842 Arg *A = Args.getLastArg(options::OPT_g_Group);
2843 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2844 !A->getOption().matches(options::OPT_gstabs);
2852 if (Act->getType() == types::TY_Image) {
2854 Inputs.push_back(Actions.back());
2861 if (Args.hasArg(options::OPT_verify_debug_info)) {
2862 Action *LastAction = Actions.pop_back_val();
2864 LastAction, types::TY_Nothing));
2883 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2884 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2896 std::string Nearest;
2897 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2898 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2899 <<
Value << Nearest;
2938 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2941 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2949 return types::TY_CXXUHeader;
2951 return types::TY_CXXSHeader;
2955 llvm_unreachable(
"should not be called in this case");
2957 return types::TY_CXXHUHeader;
2963 const llvm::opt::OptTable &Opts =
getOpts();
2967 types::ID InputType = types::TY_Nothing;
2968 Arg *InputTypeArg =
nullptr;
2971 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2972 options::OPT__SLASH_TP)) {
2973 InputTypeArg = TCTP;
2974 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2979 bool ShowNote =
false;
2981 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2983 Diag(clang::diag::warn_drv_overriding_option)
2984 <<
Previous->getSpelling() << A->getSpelling();
2990 Diag(clang::diag::note_drv_t_option_is_global);
2995 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2996 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2997 if (LastXArg && LastInputArg &&
2998 LastInputArg->getIndex() < LastXArg->getIndex())
2999 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3002 for (Arg *A : Args) {
3003 if (A->getOption().
getKind() == Option::InputClass) {
3004 const char *
Value = A->getValue();
3008 if (InputType == types::TY_Nothing) {
3011 InputTypeArg->claim();
3014 if (memcmp(
Value,
"-", 2) == 0) {
3016 Ty = types::TY_Fortran;
3018 Ty = types::TY_HLSL;
3027 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3028 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3029 : clang::diag::err_drv_unknown_stdin_type);
3038 if (
const char *Ext = strrchr(
Value,
'.'))
3047 Ty = types::TY_HLSL;
3049 Ty = types::TY_Object;
3060 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3061 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3062 << getTypeName(OldTy) << getTypeName(Ty);
3067 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3068 Ty == types::TY_Object)
3069 Ty = types::TY_LLVM_BC;
3077 if (Ty != types::TY_Object) {
3078 if (Args.hasArg(options::OPT_ObjC))
3079 Ty = types::TY_ObjC;
3080 else if (Args.hasArg(options::OPT_ObjCXX))
3081 Ty = types::TY_ObjCXX;
3088 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3092 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3093 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3096 const char *Ext = strrchr(
Value,
'.');
3098 Ty = types::TY_Object;
3102 InputTypeArg->claim();
3106 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3107 Args.hasArgNoClaim(options::OPT_hipstdpar))
3111 Inputs.push_back(std::make_pair(Ty, A));
3113 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3114 StringRef
Value = A->getValue();
3117 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3118 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3121 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3122 StringRef
Value = A->getValue();
3125 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3126 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3132 Inputs.push_back(std::make_pair(types::TY_Object, A));
3134 }
else if (A->getOption().matches(options::OPT_x)) {
3143 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3144 InputType = types::TY_Object;
3151 }
else if (A->getOption().getID() == options::OPT_U) {
3152 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3153 StringRef Val = A->getValue(0);
3154 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3156 Diag(diag::warn_slash_u_filename) << Val;
3157 Diag(diag::note_use_dashdash);
3161 if (
CCCIsCPP() && Inputs.empty()) {
3165 Inputs.push_back(std::make_pair(types::TY_C, A));
3172class OffloadingActionBuilder final {
3174 bool IsValid =
false;
3180 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3183 std::map<Action *, const Arg *> HostActionToInputArgMap;
3186 class DeviceActionBuilder {
3190 enum ActionBuilderReturnCode {
3209 DerivedArgList &Args;
3218 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3221 :
C(
C), Args(Args), Inputs(Inputs),
3222 AssociatedOffloadKind(AssociatedOffloadKind) {}
3223 virtual ~DeviceActionBuilder() {}
3228 virtual ActionBuilderReturnCode
3229 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3232 return ABRT_Inactive;
3237 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3238 return ABRT_Inactive;
3242 virtual void appendTopLevelActions(
ActionList &AL) {}
3245 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3248 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3251 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3258 virtual bool canUseBundlerUnbundler()
const {
return false; }
3262 bool isValid() {
return !ToolChains.empty(); }
3266 return AssociatedOffloadKind;
3272 class CudaActionBuilderBase :
public DeviceActionBuilder {
3276 bool CompileHostOnly =
false;
3277 bool CompileDeviceOnly =
false;
3279 bool EmitAsm =
false;
3289 TargetID(
const char *ID) :
ID(
ID) {}
3290 operator const char *() {
return ID; }
3291 operator StringRef() {
return StringRef(ID); }
3294 SmallVector<TargetID, 4> GpuArchList;
3300 Action *CudaFatBinary =
nullptr;
3303 bool IsActive =
false;
3306 bool Relocatable =
false;
3309 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3312 const CUIDOptions &CUIDOpts;
3315 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3318 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3319 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3321 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3322 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3323 options::OPT_fno_gpu_rdc,
false);
3326 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3333 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3336 if (!(IA->getType() == types::TY_CUDA ||
3337 IA->getType() == types::TY_HIP ||
3338 IA->getType() == types::TY_PP_HIP)) {
3341 return ABRT_Inactive;
3348 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3350 if (CompileHostOnly)
3351 return ABRT_Success;
3354 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3355 : types::TY_CUDA_DEVICE;
3356 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3357 CudaDeviceActions.push_back(
3358 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3361 return ABRT_Success;
3365 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3369 if (UA->getType() == types::TY_Object && !Relocatable)
3370 return ABRT_Inactive;
3372 CudaDeviceActions.clear();
3374 std::string
FileName = IA->getInputArg().getAsString(Args);
3380 const StringRef LibFileExt =
".lib";
3381 if (IA->getType() == types::TY_Object &&
3382 (!llvm::sys::path::has_extension(
FileName) ||
3384 llvm::sys::path::extension(
FileName).drop_front()) !=
3386 llvm::sys::path::extension(
FileName) == LibFileExt))
3387 return ABRT_Inactive;
3389 for (
auto Arch : GpuArchList) {
3390 CudaDeviceActions.push_back(UA);
3391 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3392 AssociatedOffloadKind);
3395 return ABRT_Success;
3398 return IsActive ? ABRT_Success : ABRT_Inactive;
3401 void appendTopLevelActions(
ActionList &AL)
override {
3403 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3404 OffloadAction::DeviceDependences Dep;
3405 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3406 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3410 if (CudaFatBinary) {
3411 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3412 CudaDeviceActions.clear();
3413 CudaFatBinary =
nullptr;
3417 if (CudaDeviceActions.empty())
3423 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3424 "Expecting one action per GPU architecture.");
3425 assert(ToolChains.size() == 1 &&
3426 "Expecting to have a single CUDA toolchain.");
3427 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3428 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3430 CudaDeviceActions.clear();
3433 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3451 assert(HostTC &&
"No toolchain for host compilation.");
3456 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3461 std::set<StringRef> GpuArchs;
3463 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3464 ToolChains.push_back(I.second);
3467 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3468 GpuArchs.insert(
Arch);
3472 for (
auto Arch : GpuArchs)
3473 GpuArchList.push_back(
Arch.data());
3475 CompileHostOnly =
C.getDriver().offloadHostOnly();
3476 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3477 EmitAsm = Args.getLastArg(options::OPT_S);
3485 class CudaActionBuilder final :
public CudaActionBuilderBase {
3487 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3489 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3490 DefaultOffloadArch = OffloadArch::CudaDefault;
3493 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3495 const std::set<StringRef> &GpuArchs)
override {
3496 return std::nullopt;
3499 ActionBuilderReturnCode
3500 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3502 PhasesTy &Phases)
override {
3504 return ABRT_Inactive;
3508 if (CudaDeviceActions.empty())
3509 return ABRT_Success;
3511 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3512 "Expecting one action per GPU architecture.");
3513 assert(!CompileHostOnly &&
3514 "Not expecting CUDA actions in host-only compilation.");
3524 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3527 for (
auto Ph : Phases) {
3532 if (Ph > FinalPhase)
3535 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3549 Action *AssembleAction = CudaDeviceActions[I];
3550 assert(AssembleAction->
getType() == types::TY_Object);
3551 assert(AssembleAction->
getInputs().size() == 1);
3557 OffloadAction::DeviceDependences DDep;
3559 DeviceActions.push_back(
3560 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3565 if (!DeviceActions.empty()) {
3567 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3569 if (!CompileDeviceOnly) {
3570 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3574 CudaFatBinary =
nullptr;
3579 CudaDeviceActions.clear();
3583 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3588 return ABRT_Success;
3592 "instructions should only occur "
3593 "before the backend phase!");
3596 for (Action *&A : CudaDeviceActions)
3597 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3599 return ABRT_Success;
3604 class HIPActionBuilder final :
public CudaActionBuilderBase {
3606 SmallVector<ActionList, 8> DeviceLinkerInputs;
3612 std::optional<bool> BundleOutput;
3613 std::optional<bool> EmitReloc;
3616 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3618 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3620 DefaultOffloadArch = OffloadArch::HIPDefault;
3622 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3623 options::OPT_fno_hip_emit_relocatable)) {
3624 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3625 options::OPT_fno_hip_emit_relocatable, false);
3629 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3630 <<
"-fhip-emit-relocatable"
3634 if (!CompileDeviceOnly) {
3635 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3636 <<
"-fhip-emit-relocatable"
3637 <<
"--offload-device-only";
3642 if (Args.hasArg(options::OPT_gpu_bundle_output,
3643 options::OPT_no_gpu_bundle_output))
3644 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3645 options::OPT_no_gpu_bundle_output,
true) &&
3646 (!EmitReloc || !*EmitReloc);
3649 bool canUseBundlerUnbundler()
const override {
return true; }
3651 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3653 const std::set<StringRef> &GpuArchs)
override {
3657 ActionBuilderReturnCode
3658 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3660 PhasesTy &Phases)
override {
3662 return ABRT_Inactive;
3668 if (CudaDeviceActions.empty())
3669 return ABRT_Success;
3672 CudaDeviceActions.size() == GpuArchList.size()) &&
3673 "Expecting one action per GPU architecture.");
3674 assert(!CompileHostOnly &&
3675 "Not expecting HIP actions in host-only compilation.");
3677 bool ShouldLink = !EmitReloc || !*EmitReloc;
3680 !EmitAsm && ShouldLink) {
3686 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3687 if (
C.getDriver().isUsingOffloadLTO()) {
3691 AL.push_back(CudaDeviceActions[I]);
3694 CudaDeviceActions[I] =
3695 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3701 if (ToolChains.front()->getTriple().isSPIRV() ||
3702 (ToolChains.front()->getTriple().isAMDGCN() &&
3703 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3707 types::ID Output = Args.hasArg(options::OPT_S)
3709 : types::TY_LLVM_BC;
3711 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3715 AssociatedOffloadKind);
3716 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3718 AssociatedOffloadKind);
3719 AL.push_back(AssembleAction);
3722 CudaDeviceActions[I] =
3723 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3732 OffloadAction::DeviceDependences DDep;
3733 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3734 AssociatedOffloadKind);
3735 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3736 DDep, CudaDeviceActions[I]->getType());
3739 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3741 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3742 types::TY_HIP_FATBIN);
3744 if (!CompileDeviceOnly) {
3745 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3746 AssociatedOffloadKind);
3749 CudaFatBinary =
nullptr;
3754 CudaDeviceActions.clear();
3757 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3760 return ABRT_Success;
3766 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3767 auto LI = DeviceLinkerInputs.begin();
3768 for (
auto *A : CudaDeviceActions) {
3775 CudaDeviceActions.clear();
3776 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3780 for (Action *&A : CudaDeviceActions)
3781 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3782 AssociatedOffloadKind);
3784 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3786 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3787 OffloadAction::DeviceDependences DDep;
3788 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3789 AssociatedOffloadKind);
3790 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3791 DDep, CudaDeviceActions[I]->getType());
3794 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3795 CudaDeviceActions.clear();
3798 return (CompileDeviceOnly &&
3799 (CurPhase == FinalPhase ||
3805 void appendLinkDeviceActions(
ActionList &AL)
override {
3806 if (DeviceLinkerInputs.size() == 0)
3809 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3810 "Linker inputs and GPU arch list sizes do not match.");
3816 for (
auto &LI : DeviceLinkerInputs) {
3818 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3822 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3825 OffloadAction::DeviceDependences DeviceLinkDeps;
3826 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3827 GpuArchList[I], AssociatedOffloadKind);
3828 Actions.push_back(
C.MakeAction<OffloadAction>(
3829 DeviceLinkDeps, DeviceLinkAction->getType()));
3832 DeviceLinkerInputs.clear();
3835 if (Args.hasArg(options::OPT_emit_llvm)) {
3843 OffloadAction::DeviceDependences DDeps;
3844 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3845 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3847 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3848 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3849 AssociatedOffloadKind);
3852 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3858 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3860 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3868 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3874 bool ShouldUseBundler;
3877 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3885 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3888 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3896 unsigned ValidBuilders = 0u;
3897 unsigned ValidBuildersSupportingBundling = 0u;
3898 for (
auto *SB : SpecializedBuilders) {
3899 IsValid = IsValid && !SB->initialize();
3902 if (SB->isValid()) {
3904 if (SB->canUseBundlerUnbundler())
3905 ++ValidBuildersSupportingBundling;
3909 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3911 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
3912 options::OPT_no_gpu_bundle_output,
true);
3915 ~OffloadingActionBuilder() {
3916 for (
auto *SB : SpecializedBuilders)
3921 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3922 assert(HostAction &&
"Invalid host action");
3923 assert(InputArg &&
"Invalid input argument");
3924 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3925 assert(Loc->second == InputArg &&
3926 "host action mapped to multiple input arguments");
3935 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3937 DeviceActionBuilder::PhasesTy &Phases) {
3941 if (SpecializedBuilders.empty())
3944 assert(HostAction &&
"Invalid host action!");
3945 recordHostAction(HostAction, InputArg);
3950 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3951 unsigned InactiveBuilders = 0u;
3952 unsigned IgnoringBuilders = 0u;
3953 for (
auto *SB : SpecializedBuilders) {
3954 if (!SB->isValid()) {
3959 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3964 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3969 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3970 OffloadKind |= SB->getAssociatedOffloadKind();
3975 if (IgnoringBuilders &&
3976 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3993 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3994 const Arg *InputArg) {
3998 recordHostAction(HostAction, InputArg);
4007 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4009 HostAction->
getType() == types::TY_PP_HIP)) {
4010 auto UnbundlingHostAction =
4015 HostAction = UnbundlingHostAction;
4016 recordHostAction(HostAction, InputArg);
4019 assert(HostAction &&
"Invalid host action!");
4022 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4023 for (
auto *SB : SpecializedBuilders) {
4027 auto RetCode = SB->addDeviceDependences(HostAction);
4031 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4032 "Host dependence not expected to be ignored.!");
4036 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4037 OffloadKind |= SB->getAssociatedOffloadKind();
4042 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4052 const Arg *InputArg) {
4054 recordHostAction(HostAction, InputArg);
4058 for (
auto *SB : SpecializedBuilders) {
4061 SB->appendTopLevelActions(OffloadAL);
4068 if (CanUseBundler && ShouldUseBundler && HostAction &&
4069 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4071 OffloadAL.push_back(HostAction);
4075 assert(HostAction == AL.back() &&
"Host action not in the list??");
4077 recordHostAction(HostAction, InputArg);
4078 AL.back() = HostAction;
4080 AL.append(OffloadAL.begin(), OffloadAL.end());
4090 void appendDeviceLinkActions(
ActionList &AL) {
4091 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4094 SB->appendLinkDeviceActions(AL);
4098 Action *makeHostLinkAction() {
4101 appendDeviceLinkActions(DeviceAL);
4102 if (DeviceAL.empty())
4107 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4110 HA = SB->appendLinkHostActions(DeviceAL);
4127 for (
auto *SB : SpecializedBuilders) {
4131 SB->appendLinkDependences(DDeps);
4135 unsigned ActiveOffloadKinds = 0u;
4136 for (
auto &I : InputArgToOffloadKindMap)
4137 ActiveOffloadKinds |= I.second;
4149 for (
auto *A : HostAction->
inputs()) {
4150 auto ArgLoc = HostActionToInputArgMap.find(A);
4151 if (ArgLoc == HostActionToInputArgMap.end())
4153 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4154 if (OFKLoc == InputArgToOffloadKindMap.end())
4166 nullptr, ActiveOffloadKinds);
4172void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4173 const InputList &Inputs,
4177 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4178 StringRef
V = A->getValue();
4179 if (Inputs.size() > 1 && !
V.empty() &&
4180 !llvm::sys::path::is_separator(
V.back())) {
4182 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4183 << A->getSpelling() <<
V;
4184 Args.eraseArg(options::OPT__SLASH_Fo);
4189 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4190 StringRef
V = A->getValue();
4191 if (Inputs.size() > 1 && !
V.empty() &&
4192 !llvm::sys::path::is_separator(
V.back())) {
4194 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4195 << A->getSpelling() <<
V;
4196 Args.eraseArg(options::OPT__SLASH_Fa);
4201 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4202 if (A->getValue()[0] ==
'\0') {
4204 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4205 Args.eraseArg(options::OPT__SLASH_o);
4210 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4211 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4212 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4213 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4214 Args.eraseArg(options::OPT__SLASH_Yc);
4215 Args.eraseArg(options::OPT__SLASH_Yu);
4216 YcArg = YuArg =
nullptr;
4218 if (YcArg && Inputs.size() > 1) {
4219 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4220 Args.eraseArg(options::OPT__SLASH_Yc);
4224 if (Args.hasArgNoClaim(options::OPT_fmodules_driver))
4226 if (!ModulesModeCXX20 && !Args.hasArgNoClaim(options::OPT_fmodules))
4227 Args.eraseArg(options::OPT_fmodules_driver);
4233 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4234 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4235 Args.AddFlagArg(
nullptr,
4236 getOpts().getOption(options::OPT_frtlib_add_rpath));
4239 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4240 Diag(clang::diag::err_drv_emit_llvm_link);
4241 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4243 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4244 .starts_with_insensitive(
"lld"))
4245 Diag(clang::diag::err_drv_lto_without_lld);
4251 if (!Args.hasArg(options::OPT_dumpdir)) {
4252 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4253 Arg *Arg = Args.MakeSeparateArg(
4254 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4256 (FinalOutput ? FinalOutput->getValue()
4268 Args.eraseArg(options::OPT__SLASH_Fp);
4269 Args.eraseArg(options::OPT__SLASH_Yc);
4270 Args.eraseArg(options::OPT__SLASH_Yu);
4271 YcArg = YuArg =
nullptr;
4274 if (Args.hasArg(options::OPT_include_pch) &&
4275 Args.hasArg(options::OPT_ignore_pch)) {
4279 Args.eraseArg(options::OPT_include_pch);
4282 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4283 for (
auto &I : Inputs) {
4285 const Arg *InputArg = I.second;
4290 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4294 if (InitialPhase > FinalPhase) {
4295 if (InputArg->isClaimed())
4302 if (Args.hasArg(options::OPT_Qunused_arguments))
4308 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4309 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4313 (Args.getLastArg(options::OPT__SLASH_EP,
4314 options::OPT__SLASH_P) ||
4315 Args.getLastArg(options::OPT_E) ||
4316 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4318 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4319 << InputArg->getAsString(Args) << !!FinalPhaseArg
4320 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4322 Diag(clang::diag::warn_drv_input_file_unused)
4323 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4325 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4334 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4338 Actions.push_back(ClangClPch);
4350 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4351 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4356 const auto IsTypeCXXModule = [](
const auto &Input) ->
bool {
4357 const auto TypeID = Input.first;
4358 return (TypeID == types::TY_CXXModule);
4360 return llvm::any_of(Inputs, IsTypeCXXModule);
4364Driver::ScanInputsForCXX20ModulesUsage(
const InputList &Inputs)
const {
4365 const auto CXXInputs = llvm::make_filter_range(
4366 Inputs, [](
const auto &Input) {
return types::isCXX(Input.first); });
4367 for (
const auto &Input : CXXInputs) {
4368 StringRef Filename = Input.second->getSpelling();
4369 auto ErrOrBuffer = VFS->getBufferForFile(Filename);
4371 return ErrOrBuffer.getError();
4372 const auto Buffer = std::move(*ErrOrBuffer);
4375 Diags.Report(diag::remark_found_cxx20_module_usage) << Filename;
4384 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4386 if (!SuppressMissingInputWarning && Inputs.empty()) {
4387 Diag(clang::diag::err_drv_no_input_files);
4391 handleArguments(
C, Args, Inputs, Actions);
4393 if (Args.hasFlag(options::OPT_fmodules_driver,
4394 options::OPT_fno_modules_driver,
false)) {
4399 if (!UsesCXXModules) {
4400 const auto ErrOrScanResult = ScanInputsForCXX20ModulesUsage(Inputs);
4401 if (!ErrOrScanResult) {
4402 Diags.Report(diag::err_cannot_open_file)
4403 << ErrOrScanResult.getError().message();
4406 UsesCXXModules = *ErrOrScanResult;
4408 if (UsesCXXModules || Args.hasArg(options::OPT_fmodules))
4409 BuildDriverManagedModuleBuildActions(
C, Args, Inputs, Actions);
4413 BuildDefaultActions(
C, Args, Inputs, Actions);
4416void Driver::BuildDefaultActions(
Compilation &
C, DerivedArgList &Args,
4417 const InputList &Inputs,
4420 bool UseNewOffloadingDriver =
4423 Args.hasFlag(options::OPT_foffload_via_llvm,
4424 options::OPT_fno_offload_via_llvm,
false) ||
4425 Args.hasFlag(options::OPT_offload_new_driver,
4426 options::OPT_no_offload_new_driver,
4430 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4431 !UseNewOffloadingDriver
4432 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4440 for (
auto &I : Inputs) {
4442 const Arg *InputArg = I.second;
4455 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4461 if (!UseNewOffloadingDriver)
4462 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4468 if (!UseNewOffloadingDriver)
4469 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4470 Current, InputArg, Phase, PL.back(), FullPL);
4476 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4479 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4480 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4482 LinkerInputs.push_back(Current);
4492 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4493 MergerInputs.push_back(Current);
4511 if (NewCurrent == Current)
4514 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4515 ExtractAPIAction = EAA;
4517 Current = NewCurrent;
4521 if (UseNewOffloadingDriver)
4525 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4529 if (Current->
getType() == types::TY_Nothing)
4535 Actions.push_back(Current);
4538 if (!UseNewOffloadingDriver)
4539 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4547 if (LinkerInputs.empty()) {
4550 if (!UseNewOffloadingDriver)
4551 OffloadBuilder->appendDeviceLinkActions(Actions);
4554 if (!LinkerInputs.empty()) {
4555 if (!UseNewOffloadingDriver)
4556 if (Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4557 LinkerInputs.push_back(Wrapper);
4561 LA =
C.MakeAction<StaticLibJobAction>(LinkerInputs, types::TY_Image);
4562 }
else if (UseNewOffloadingDriver ||
4563 Args.hasArg(options::OPT_offload_link)) {
4564 LA =
C.MakeAction<LinkerWrapperJobAction>(LinkerInputs, types::TY_Image);
4568 LA =
C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image);
4570 if (!UseNewOffloadingDriver)
4571 LA = OffloadBuilder->processHostLinkAction(LA);
4572 Actions.push_back(LA);
4576 if (!MergerInputs.empty())
4578 C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
4580 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4587 for (
auto &I : Inputs) {
4589 const Arg *InputArg = I.second;
4594 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4595 InputType == types::TY_Asm)
4598 Action *Current =
C.MakeAction<InputAction>(*InputArg, InputType);
4600 for (
auto Phase : PhaseList) {
4604 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4609 if (InputType == types::TY_Object)
4612 Current =
C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);
4616 assert(Phase == PhaseList.back() &&
4617 "merging must be final compilation step.");
4618 MergerInputs.push_back(Current);
4627 Actions.push_back(Current);
4631 if (!MergerInputs.empty())
4633 C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
4636 for (
auto Opt : {options::OPT_print_supported_cpus,
4637 options::OPT_print_supported_extensions,
4638 options::OPT_print_enabled_extensions}) {
4645 if (Arg *A = Args.getLastArg(Opt)) {
4646 if (Opt == options::OPT_print_supported_extensions &&
4647 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4648 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4649 !
C.getDefaultToolChain().getTriple().isARM()) {
4650 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4651 <<
"--print-supported-extensions";
4654 if (Opt == options::OPT_print_enabled_extensions &&
4655 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4656 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4657 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4658 <<
"--print-enabled-extensions";
4664 Action *InputAc =
C.MakeAction<InputAction>(
4665 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4667 C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
4668 for (
auto &I : Inputs)
4673 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4675 static_cast<const toolchains::HLSLToolChain &
>(
C.getDefaultToolChain());
4679 if (TC.requiresObjcopy(Args)) {
4680 Action *LastAction = Actions.back();
4682 if (LastAction->
getType() == types::TY_Object)
4684 C.MakeAction<ObjcopyJobAction>(LastAction, types::TY_Object));
4688 if (TC.requiresValidation(Args)) {
4689 Action *LastAction = Actions.back();
4690 Actions.push_back(
C.MakeAction<BinaryAnalyzeJobAction>(
4691 LastAction, types::TY_DX_CONTAINER));
4695 if (TC.requiresBinaryTranslation(Args)) {
4696 Action *LastAction = Actions.back();
4700 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4701 LastAction->
getType() == types::TY_Object)
4702 Actions.push_back(
C.MakeAction<BinaryTranslatorJobAction>(
4703 LastAction, types::TY_DX_CONTAINER));
4708 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4711void Driver::BuildDriverManagedModuleBuildActions(
4712 Compilation &
C, llvm::opt::DerivedArgList &Args,
const InputList &Inputs,
4714 Diags.Report(diag::remark_performing_driver_managed_module_build);
4720 const llvm::opt::DerivedArgList &Args,
4722 const llvm::Triple &Triple) {
4727 if (Triple.isNVPTX() &&
4729 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4730 <<
"CUDA" << ArchStr;
4732 }
else if (Triple.isAMDGPU() &&
4734 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4735 <<
"HIP" << ArchStr;
4743 llvm::StringMap<bool> Features;
4746 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4758static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4760 llvm::Triple Triple) {
4761 if (!Triple.isAMDGPU())
4762 return std::nullopt;
4764 std::set<StringRef> ArchSet;
4765 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4769llvm::SmallVector<StringRef>
4773 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4774 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4775 options::OPT_no_offload_arch_EQ)) {
4776 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4778 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4780 :
"--no-offload-arch");
4783 llvm::DenseSet<StringRef> Archs;
4784 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4787 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4788 for (StringRef
Arch : Arg->getValues()) {
4789 if (
Arch ==
"native" ||
Arch.empty()) {
4793 << llvm::Triple::getArchTypeName(TC.
getArch())
4794 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4798 for (
auto ArchStr : *GPUsOrErr) {
4800 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4801 if (!CanonicalStr.empty())
4802 Archs.insert(CanonicalStr);
4807 StringRef CanonicalStr =
4809 if (!CanonicalStr.empty())
4810 Archs.insert(CanonicalStr);
4815 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4816 for (StringRef
Arch : Arg->getValues()) {
4817 if (
Arch ==
"all") {
4822 Archs.erase(ArchStr);
4828 if (
auto ConflictingArchs =
4830 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4831 << ConflictingArchs->first << ConflictingArchs->second;
4834 if (Archs.empty()) {
4842 Archs.insert(StringRef());
4845 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4846 .getLastArg(options::OPT_march_EQ)) {
4847 Archs.insert(Arg->getValue());
4852 << llvm::Triple::getArchTypeName(TC.
getArch())
4853 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4854 }
else if (!ArchsOrErr->empty()) {
4855 for (
auto Arch : *ArchsOrErr)
4856 Archs.insert(Args.MakeArgStringRef(
Arch));
4858 Archs.insert(StringRef());
4863 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4864 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4872 llvm::opt::DerivedArgList &Args,
4873 const InputTy &Input, StringRef CUID,
4874 Action *HostAction)
const {
4882 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4884 bool HIPRelocatableObj =
4886 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4887 options::OPT_fno_hip_emit_relocatable,
false);
4889 if (!HIPNoRDC && HIPRelocatableObj)
4890 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4891 <<
"-fhip-emit-relocatable"
4895 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4896 <<
"-fhip-emit-relocatable"
4897 <<
"--offload-device-only";
4915 auto TCRange =
C.getOffloadToolChains(Kind);
4916 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4917 ToolChains.push_back(TI->second);
4919 if (ToolChains.empty())
4923 const Arg *InputArg = Input.second;
4932 for (
const ToolChain *TC : ToolChains) {
4934 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4935 DeviceActions.push_back(
4936 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4940 if (DeviceActions.empty())
4946 HostAction->
getType() != types::TY_Nothing &&
4956 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4965 auto *TCAndArch = TCAndArchs.begin();
4966 for (
Action *&A : DeviceActions) {
4967 if (A->
getType() == types::TY_Nothing)
4977 HostAction->
getType() != types::TY_Nothing) {
4984 TCAndArch->second.data(), Kind);
4986 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4996 for (
Action *&A : DeviceActions) {
4999 llvm::Triple::OSType::AMDHSA &&
5001 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5002 options::OPT_no_use_spirv_backend,
5009 bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
5011 if ((A->
getType() != types::TY_Object && !IsAMDGCNSPIRV &&
5012 A->
getType() != types::TY_LTO_BC) ||
5020 auto *TCAndArch = TCAndArchs.begin();
5021 for (
Action *A : DeviceActions) {
5022 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5024 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5029 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5031 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5040 bool ShouldBundleHIP =
5041 Args.hasFlag(options::OPT_gpu_bundle_output,
5042 options::OPT_no_gpu_bundle_output,
false) ||
5044 llvm::none_of(OffloadActions, [](
Action *A) {
5045 return A->
getType() != types::TY_Image;
5052 if (OffloadActions.empty())
5057 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5061 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5068 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5069 DDep.
add(*FatbinAction,
5072 }
else if (HIPNoRDC) {
5084 DDep.
add(*PackagerAction,
5093 nullptr,
C.getActiveOffloadKinds());
5102 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5103 return A->
getType() == types::TY_Nothing;
5107 nullptr, SingleDeviceOutput ? DDep : DDeps);
5108 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5114 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5124 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5130 llvm_unreachable(
"link action invalid here.");
5132 llvm_unreachable(
"ifsmerge action invalid here.");
5137 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5138 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5139 OutputTy = types::TY_Dependencies;
5144 if (!Args.hasFlag(options::OPT_frewrite_includes,
5145 options::OPT_fno_rewrite_includes,
false) &&
5146 !Args.hasFlag(options::OPT_frewrite_imports,
5147 options::OPT_fno_rewrite_imports,
false) &&
5148 !Args.hasFlag(options::OPT_fdirectives_only,
5149 options::OPT_fno_directives_only,
false) &&
5153 "Cannot preprocess this input type!");
5159 if (Args.hasArg(options::OPT_extract_api))
5166 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5167 (Input->
getType() == driver::types::TY_CXXModule ||
5168 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5169 !Args.getLastArg(options::OPT__precompile))
5174 "Cannot precompile this input type!");
5178 const char *ModName =
nullptr;
5179 if (OutputTy == types::TY_PCH) {
5180 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5181 ModName = A->getValue();
5183 OutputTy = types::TY_ModuleFile;
5186 if (Args.hasArg(options::OPT_fsyntax_only)) {
5188 OutputTy = types::TY_Nothing;
5194 if (Args.hasArg(options::OPT_fsyntax_only))
5196 if (Args.hasArg(options::OPT_rewrite_objc))
5198 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5200 types::TY_RewrittenLegacyObjC);
5201 if (Args.hasArg(options::OPT__analyze))
5203 if (Args.hasArg(options::OPT_emit_ast))
5205 if (Args.hasArg(options::OPT_emit_cir))
5207 if (Args.hasArg(options::OPT_module_file_info))
5209 if (Args.hasArg(options::OPT_verify_pch))
5211 if (Args.hasArg(options::OPT_extract_api))
5219 Args.hasFlag(options::OPT_offload_new_driver,
5220 options::OPT_no_offload_new_driver,
false) &&
5226 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5227 !Args.hasArg(options::OPT_emit_llvm))
5228 Output = types::TY_PP_Asm;
5229 else if (Args.hasArg(options::OPT_S))
5230 Output = types::TY_LTO_IR;
5232 Output = types::TY_LTO_BC;
5237 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5240 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5241 options::OPT_no_use_spirv_backend,
5249 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5251 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5253 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5255 if (Args.hasArg(options::OPT_emit_llvm) ||
5261 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5262 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5264 (Args.hasFlag(options::OPT_offload_new_driver,
5265 options::OPT_no_offload_new_driver,
false) &&
5272 Args.hasArg(options::OPT_S) &&
5276 !Args.hasFlag(options::OPT_offload_new_driver,
5277 options::OPT_no_offload_new_driver,
5280 : types::TY_LLVM_BC;
5293 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5302 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5306 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5308 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5328 unsigned NumOutputs = 0;
5329 unsigned NumIfsOutputs = 0;
5330 for (
const Action *A :
C.getActions()) {
5333 if (A->
getType() == types::TY_DX_CONTAINER &&
5338 if (A->
getType() != types::TY_Nothing &&
5340 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5342 0 == NumIfsOutputs++) ||
5347 A->
getType() == types::TY_Nothing &&
5348 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5349 NumOutputs += A->
size();
5352 if (NumOutputs > 1) {
5353 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5354 FinalOutput =
nullptr;
5358 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5362 if (RawTriple.isOSBinFormatMachO())
5363 for (
const Arg *A :
C.getArgs())
5364 if (A->getOption().matches(options::OPT_arch))
5368 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5369 for (
Action *A :
C.getActions()) {
5376 const char *LinkingOutput =
nullptr;
5379 LinkingOutput = FinalOutput->getValue();
5388 LinkingOutput, CachedResults,
5395 for (
auto &J :
C.getJobs())
5396 J.InProcess =
false;
5399 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5400 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5405 const char *LinkingOutput =
nullptr;
5407 LinkingOutput = FinalOutput->getValue();
5414 using namespace llvm;
5417 <<
"output=" << LinkingOutput;
5418 outs() <<
", total="
5419 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5421 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5422 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5426 llvm::raw_string_ostream Out(Buffer);
5427 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5430 llvm::sys::printArg(Out, LinkingOutput,
true);
5431 Out <<
',' << ProcStat->TotalTime.count() <<
','
5432 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5437 llvm::sys::fs::OF_Append |
5438 llvm::sys::fs::OF_Text);
5443 llvm::errs() <<
"ERROR: Cannot lock file "
5445 <<
toString(L.takeError()) <<
"\n";
5456 bool ReportUnusedArguments =
5457 !Diags.hasErrorOccurred() &&
5458 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5461 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5463 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5466 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5467 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5469 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5473 return strstr(J.getCreator().getShortName(),
"assembler");
5475 for (Arg *A :
C.getArgs()) {
5479 if (!A->isClaimed()) {
5485 const Option &Opt = A->getOption();
5486 if (Opt.getKind() == Option::FlagClass) {
5487 bool DuplicateClaimed =
false;
5489 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5490 if (AA->isClaimed()) {
5491 DuplicateClaimed =
true;
5496 if (DuplicateClaimed)
5502 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5504 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5509 !
C.getActions().empty()) {
5510 Diag(diag::err_drv_unsupported_opt_for_target)
5512 }
else if (ReportUnusedArguments) {
5513 Diag(clang::diag::warn_drv_unused_argument)
5514 << A->getAsString(
C.getArgs());
5524class ToolSelector final {
5535 bool IsHostSelector;
5546 bool CanBeCollapsed =
true) {
5548 if (Inputs.size() != 1)
5551 Action *CurAction = *Inputs.begin();
5552 if (CanBeCollapsed &&
5558 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5562 if (!IsHostSelector) {
5563 if (OA->hasSingleDeviceDependence(
true)) {
5565 OA->getSingleDeviceDependence(
true);
5566 if (CanBeCollapsed &&
5569 SavedOffloadAction.push_back(OA);
5570 return dyn_cast<JobAction>(CurAction);
5572 }
else if (OA->hasHostDependence()) {
5573 CurAction = OA->getHostDependence();
5574 if (CanBeCollapsed &&
5577 SavedOffloadAction.push_back(OA);
5578 return dyn_cast<JobAction>(CurAction);
5583 return dyn_cast<JobAction>(CurAction);
5587 bool canCollapseAssembleAction()
const {
5588 return TC.useIntegratedAs() && !SaveTemps &&
5589 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5590 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5591 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5592 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5596 bool canCollapsePreprocessorAction()
const {
5597 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5598 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5599 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5604 struct JobActionInfo final {
5606 const JobAction *JA =
nullptr;
5614 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5615 ArrayRef<JobActionInfo> &ActionInfo,
5616 unsigned ElementNum) {
5617 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5618 for (
unsigned I = 0; I < ElementNum; ++I)
5619 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5620 ActionInfo[I].SavedOffloadAction.end());
5633 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5636 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5638 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5639 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5640 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5641 if (!AJ || !BJ || !CJ)
5645 const Tool *
T = TC.SelectTool(*CJ);
5652 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5658 const Tool *BT = TC.SelectTool(*BJ);
5663 if (!
T->hasIntegratedAssembler())
5666 Inputs = CJ->getInputs();
5667 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5671 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5674 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5676 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5677 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5682 const Tool *
T = TC.SelectTool(*BJ);
5686 if (!
T->hasIntegratedAssembler())
5689 Inputs = BJ->getInputs();
5690 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5694 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5697 if (ActionInfo.size() < 2)
5699 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5700 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5704 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5705 for (
auto &Input : AI.JA->getInputs())
5716 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5717 if (SaveTemps && !InputIsBitcode)
5721 const Tool *
T = TC.SelectTool(*CJ);
5728 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5734 Inputs = CJ->getInputs();
5735 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5744 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5746 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5752 for (Action *A : Inputs) {
5753 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5755 NewInputs.push_back(A);
5761 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5762 PreprocessJobOffloadActions.end());
5763 NewInputs.append(PJ->input_begin(), PJ->input_end());
5769 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5771 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5773 assert(BaseAction &&
"Invalid base action.");
5789 SmallVector<JobActionInfo, 5> ActionChain(1);
5790 ActionChain.back().JA = BaseAction;
5791 while (ActionChain.back().JA) {
5792 const Action *CurAction = ActionChain.back().JA;
5795 ActionChain.resize(ActionChain.size() + 1);
5796 JobActionInfo &AI = ActionChain.back();
5800 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5804 ActionChain.pop_back();
5812 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5813 CollapsedOffloadAction);
5815 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5817 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5823 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5835 StringRef BoundArch,
5837 std::string TriplePlusArch = TC->
getTriple().normalize();
5838 if (!BoundArch.empty()) {
5839 TriplePlusArch +=
"-";
5840 TriplePlusArch += BoundArch;
5842 TriplePlusArch +=
"-";
5844 return TriplePlusArch;
5849 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5850 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5853 std::pair<const Action *, std::string> ActionTC = {
5855 auto CachedResult = CachedResults.find(ActionTC);
5856 if (CachedResult != CachedResults.end()) {
5857 return CachedResult->second;
5860 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5861 CachedResults, TargetDeviceOffloadKind);
5862 CachedResults[ActionTC] =
Result;
5867 const JobAction *JA,
const char *BaseInput,
5870 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5874 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5875 Path = A->getValue();
5876 if (llvm::sys::fs::is_directory(Path)) {
5878 llvm::sys::path::replace_extension(Tmp,
"json");
5879 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5882 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5885 Path = DumpDir->getValue();
5886 Path += llvm::sys::path::filename(BaseInput);
5888 Path = Result.getFilename();
5890 llvm::sys::path::replace_extension(Path,
"json");
5892 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5893 C.addTimeTraceFile(ResultFile, JA);
5894 C.addResultFile(ResultFile, JA);
5899 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5900 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5903 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5906 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5907 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5939 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5941 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5942 const char *DepBoundArch) {
5945 LinkingOutput, CachedResults,
5955 OA->doOnEachDependence(
5956 BuildingForOffloadDevice,
5957 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5959 C, DepA, DepTC, DepBoundArch,
false,
5960 !!DepBoundArch, LinkingOutput, CachedResults,
5964 A = BuildingForOffloadDevice
5965 ? OA->getSingleDeviceDependence(
true)
5966 : OA->getHostDependence();
5970 std::pair<const Action *, std::string> ActionTC = {
5971 OA->getHostDependence(),
5973 auto It = CachedResults.find(ActionTC);
5974 if (It != CachedResults.end()) {
5976 Inputs.append(OffloadDependencesInputInfo);
5981 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5984 const Arg &Input = IA->getInputArg();
5986 if (Input.getOption().matches(options::OPT_INPUT)) {
5987 const char *
Name = Input.getValue();
5990 return {InputInfo(A, &Input,
"")};
5993 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5994 const ToolChain *TC;
5997 if (!ArchName.empty())
5998 TC = &getToolChain(
C.getArgs(),
6000 C.getArgs(), ArchName));
6002 TC = &
C.getDefaultToolChain();
6005 MultipleArchs, LinkingOutput, CachedResults,
6006 TargetDeviceOffloadKind);
6017 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
6020 return {InputInfo()};
6024 for (
const auto *OA : CollapsedOffloadActions)
6026 BuildingForOffloadDevice,
6027 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6029 C, DepA, DepTC, DepBoundArch,
false,
6030 !!DepBoundArch, LinkingOutput, CachedResults,
6036 for (
const Action *Input : Inputs) {
6040 bool SubJobAtTopLevel =
6043 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6048 const char *BaseInput = InputInfos[0].getBaseInput();
6049 for (
auto &Info : InputInfos) {
6050 if (Info.isFilename()) {
6051 BaseInput = Info.getBaseInput();
6058 if (JA->
getType() == types::TY_dSYM)
6059 BaseInput = InputInfos[0].getFilename();
6062 if (!OffloadDependencesInputInfo.empty())
6063 InputInfos.append(OffloadDependencesInputInfo.begin(),
6064 OffloadDependencesInputInfo.end());
6067 llvm::Triple EffectiveTriple;
6068 const ToolChain &ToolTC =
T->getToolChain();
6069 const ArgList &Args =
6071 if (InputInfos.size() != 1) {
6075 EffectiveTriple = llvm::Triple(
6078 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6083 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6087 for (
auto &UI : UA->getDependentActionsInfo()) {
6089 "Unbundling with no offloading??");
6096 UI.DependentOffloadKind,
6097 UI.DependentToolChain->getTriple().normalize(),
6099 auto CurI = InputInfo(
6108 UnbundlingResults.push_back(CurI);
6117 Arch = UI.DependentBoundArch;
6122 UI.DependentOffloadKind)}] = {
6128 std::pair<const Action *, std::string> ActionTC = {
6130 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6131 "Result does not exist??");
6132 Result = CachedResults[ActionTC].front();
6133 }
else if (JA->
getType() == types::TY_Nothing)
6134 Result = {InputInfo(A, BaseInput)};
6144 AtTopLevel, MultipleArchs,
6147 if (
T->canEmitIR() && OffloadingPrefix.empty())
6152 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
6153 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6154 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6155 llvm::errs() << InputInfos[i].getAsString();
6157 llvm::errs() <<
", ";
6159 if (UnbundlingResults.empty())
6160 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6162 llvm::errs() <<
"], outputs: [";
6163 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6164 llvm::errs() << UnbundlingResults[i].getAsString();
6166 llvm::errs() <<
", ";
6168 llvm::errs() <<
"] \n";
6171 if (UnbundlingResults.empty())
6172 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6174 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6175 Args, LinkingOutput);
6181 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6182 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6194 if (ArgValue.empty()) {
6196 Filename = BaseName;
6197 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6199 llvm::sys::path::append(Filename, BaseName);
6202 if (!llvm::sys::path::has_extension(ArgValue)) {
6207 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6212 llvm::sys::path::replace_extension(Filename, Extension);
6215 return Args.MakeArgString(Filename.c_str());
6230 StringRef Suffix,
bool MultipleArchs,
6231 StringRef BoundArch,
6232 bool NeedUniqueDirectory)
const {
6234 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6235 std::optional<std::string> CrashDirectory =
6237 ? std::string(A->getValue())
6238 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6239 if (CrashDirectory) {
6240 if (!
getVFS().exists(*CrashDirectory))
6241 llvm::sys::fs::create_directories(*CrashDirectory);
6243 llvm::sys::path::append(Path, Prefix);
6244 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6245 if (std::error_code EC =
6246 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6247 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6251 if (MultipleArchs && !BoundArch.empty()) {
6252 if (NeedUniqueDirectory) {
6254 llvm::sys::path::append(TmpName,
6255 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6265 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6280 const char *BaseInput) {
6282 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6283 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6288 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6292 const char *BaseInput,
6293 StringRef OrigBoundArch,
bool AtTopLevel,
6295 StringRef OffloadingPrefix)
const {
6298 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6301 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6302 return C.addResultFile(FinalOutput->getValue(), &JA);
6306 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6308 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6310 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6311 NameArg = A->getValue();
6312 return C.addResultFile(
6322 if (JA.
getType() == types::TY_ModuleFile &&
6323 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6327 if (JA.
getType() == types::TY_PP_Asm &&
6328 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6329 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6332 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6335 if ((JA.
getType() == types::TY_Object &&
6336 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6337 JA.
getType() == types::TY_DX_CONTAINER) {
6338 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6342 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6344 C.getDefaultToolChain());
6347 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6348 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6349 StringRef
Name = llvm::sys::path::filename(BaseInput);
6350 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6356 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6357 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6361 if (JA.
getType() == types::TY_PP_Asm &&
6362 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6363 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6365 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6366 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6367 return C.addResultFile(
6372 if (JA.
getType() == types::TY_API_INFO &&
6373 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6374 C.getArgs().hasArg(options::OPT_o))
6375 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6376 <<
C.getArgs().getLastArgValue(options::OPT_o);
6383 bool SpecifiedModuleOutput =
6384 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6385 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6386 if (MultipleArchs && SpecifiedModuleOutput)
6387 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6392 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6393 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6399 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6401 StringRef
Name = llvm::sys::path::filename(BaseInput);
6402 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6403 const char *Suffix =
6408 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6409 bool NeedUniqueDirectory =
6412 Triple.isOSDarwin();
6413 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6414 NeedUniqueDirectory);
6423 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6428 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6429 llvm::sys::path::filename(BasePath));
6430 BaseName = ExternalPath;
6432 BaseName = BasePath;
6434 BaseName = llvm::sys::path::filename(BasePath);
6437 const char *NamedOutput;
6439 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6440 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6444 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6448 }
else if (JA.
getType() == types::TY_Image &&
6449 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6450 options::OPT__SLASH_o)) {
6454 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6458 }
else if (JA.
getType() == types::TY_Image) {
6468 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6469 options::OPT_fno_gpu_rdc,
false);
6471 if (UseOutExtension) {
6473 llvm::sys::path::replace_extension(Output,
"");
6475 Output += OffloadingPrefix;
6476 if (MultipleArchs && !BoundArch.empty()) {
6478 Output.append(BoundArch);
6480 if (UseOutExtension)
6482 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6485 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6486 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6487 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6490 .getLastArg(options::OPT__SLASH_o)
6495 const char *Suffix =
6497 assert(Suffix &&
"All types used for output should have a suffix.");
6499 std::string::size_type End = std::string::npos;
6501 End = BaseName.rfind(
'.');
6503 Suffixed += OffloadingPrefix;
6504 if (MultipleArchs && !BoundArch.empty()) {
6506 Suffixed.append(BoundArch);
6511 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6512 const llvm::opt::DerivedArgList &Args) {
6519 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6527 bool IsLinkerWrapper =
6529 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6530 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6531 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6533 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6537 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6541 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6542 JA.
getType() != types::TY_PCH) {
6543 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6545 llvm::sys::path::remove_filename(TempPath);
6546 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6547 llvm::sys::path::append(TempPath, OutputFileName);
6548 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6554 bool SameFile =
false;
6556 llvm::sys::fs::current_path(
Result);
6557 llvm::sys::path::append(
Result, BaseName);
6558 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6561 StringRef
Name = llvm::sys::path::filename(BaseInput);
6562 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6566 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6572 llvm::sys::path::remove_filename(BasePath);
6573 if (BasePath.empty())
6574 BasePath = NamedOutput;
6576 llvm::sys::path::append(BasePath, NamedOutput);
6577 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6580 return C.addResultFile(NamedOutput, &JA);
6586 -> std::optional<std::string> {
6589 for (
const auto &
Dir : P) {
6593 llvm::sys::path::append(P,
Name);
6594 if (llvm::sys::fs::exists(Twine(P)))
6595 return std::string(P);
6597 return std::nullopt;
6604 llvm::sys::path::append(R,
Name);
6605 if (llvm::sys::fs::exists(Twine(R)))
6606 return std::string(R);
6609 llvm::sys::path::append(P,
Name);
6610 if (llvm::sys::fs::exists(Twine(P)))
6611 return std::string(P);
6614 llvm::sys::path::append(D,
"..",
Name);
6615 if (llvm::sys::fs::exists(Twine(D)))
6616 return std::string(D);
6625 llvm::sys::path::append(R2,
"..",
"..",
Name);
6626 if (llvm::sys::fs::exists(Twine(R2)))
6627 return std::string(R2);
6629 return std::string(
Name);
6632void Driver::generatePrefixedToolNames(
6636 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6637 Names.emplace_back(
Tool);
6641 llvm::sys::path::append(Dir, Name);
6642 if (llvm::sys::fs::can_execute(Twine(Dir)))
6644 llvm::sys::path::remove_filename(Dir);
6650 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6655 if (llvm::sys::fs::is_directory(PrefixDir)) {
6658 return std::string(P);
6661 if (llvm::sys::fs::can_execute(Twine(P)))
6662 return std::string(P);
6667 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6675 for (
const auto &Path : List) {
6678 return std::string(P);
6682 if (llvm::ErrorOr<std::string> P =
6683 llvm::sys::findProgramByName(TargetSpecificExecutable))
6687 return std::string(
Name);
6692 std::string error =
"<NOT PRESENT>";
6694 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6699 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6716 llvm::sys::path::remove_filename(path);
6717 llvm::sys::path::append(path,
"libc++.modules.json");
6718 if (TC.
getVFS().exists(path))
6719 return static_cast<std::string
>(path);
6724 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6727 return evaluate(
"libc++.a").value_or(error);
6731 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6735 llvm::sys::path::remove_filename(path);
6736 llvm::sys::path::append(path,
"libstdc++.modules.json");
6737 if (TC.
getVFS().exists(path))
6738 return static_cast<std::string
>(path);
6743 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6746 return evaluate(
"libstdc++.a").value_or(error);
6755 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6757 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6761 return std::string(Path);
6766 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6768 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6772 return std::string(Path);
6777 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6781 Output = FpArg->getValue();
6785 if (!llvm::sys::path::has_extension(Output))
6788 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6789 Output = YcArg->getValue();
6792 llvm::sys::path::replace_extension(Output,
".pch");
6794 return std::string(Output);
6797const ToolChain &Driver::getOffloadToolChain(
6799 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6800 std::unique_ptr<ToolChain> &TC =
6801 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6802 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6804 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6807 switch (
Target.getOS()) {
6808 case llvm::Triple::CUDA:
6809 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6812 case llvm::Triple::AMDHSA:
6814 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6817 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6826 switch (
Target.getArch()) {
6827 case llvm::Triple::spir:
6828 case llvm::Triple::spir64:
6829 case llvm::Triple::spirv:
6830 case llvm::Triple::spirv32:
6831 case llvm::Triple::spirv64:
6834 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6838 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6842 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6846 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6860 return getToolChain(Args,
Target);
6864const ToolChain &Driver::getToolChain(
const ArgList &Args,
6865 const llvm::Triple &
Target)
const {
6867 auto &TC = ToolChains[
Target.str()];
6869 switch (
Target.getOS()) {
6870 case llvm::Triple::AIX:
6871 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6873 case llvm::Triple::Haiku:
6874 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6876 case llvm::Triple::Darwin:
6877 case llvm::Triple::MacOSX:
6878 case llvm::Triple::IOS:
6879 case llvm::Triple::TvOS:
6880 case llvm::Triple::WatchOS:
6881 case llvm::Triple::XROS:
6882 case llvm::Triple::DriverKit:
6883 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6885 case llvm::Triple::DragonFly:
6886 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6888 case llvm::Triple::OpenBSD:
6889 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6891 case llvm::Triple::NetBSD:
6892 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6894 case llvm::Triple::FreeBSD:
6896 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6899 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6901 case llvm::Triple::Linux:
6902 case llvm::Triple::ELFIAMCU:
6903 if (
Target.getArch() == llvm::Triple::hexagon)
6904 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6906 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6907 !
Target.hasEnvironment())
6908 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6911 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6913 else if (
Target.getArch() == llvm::Triple::ve)
6914 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6915 else if (
Target.isOHOSFamily())
6916 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6917 else if (
Target.isWALI())
6918 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6920 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6922 case llvm::Triple::Fuchsia:
6923 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6925 case llvm::Triple::Managarm:
6926 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6928 case llvm::Triple::Solaris:
6929 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6931 case llvm::Triple::CUDA:
6932 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6934 case llvm::Triple::AMDHSA: {
6935 if (
Target.getArch() == llvm::Triple::spirv64) {
6936 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6941 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6943 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6948 case llvm::Triple::AMDPAL:
6949 case llvm::Triple::Mesa3D:
6950 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6952 case llvm::Triple::UEFI:
6953 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6955 case llvm::Triple::Win32:
6956 switch (
Target.getEnvironment()) {
6958 if (
Target.isOSBinFormatELF())
6959 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6960 else if (
Target.isOSBinFormatMachO())
6961 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6963 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6965 case llvm::Triple::GNU:
6966 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6968 case llvm::Triple::Cygnus:
6969 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6971 case llvm::Triple::Itanium:
6972 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6975 case llvm::Triple::MSVC:
6976 case llvm::Triple::UnknownEnvironment:
6977 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6978 .starts_with_insensitive(
"bfd"))
6979 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6983 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6987 case llvm::Triple::PS4:
6988 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6990 case llvm::Triple::PS5:
6991 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6993 case llvm::Triple::Hurd:
6994 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6996 case llvm::Triple::LiteOS:
6997 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6999 case llvm::Triple::ZOS:
7000 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7002 case llvm::Triple::Vulkan:
7003 case llvm::Triple::ShaderModel:
7004 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7009 switch (
Target.getArch()) {
7010 case llvm::Triple::tce:
7011 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7013 case llvm::Triple::tcele:
7014 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7016 case llvm::Triple::hexagon:
7017 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7020 case llvm::Triple::lanai:
7021 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7023 case llvm::Triple::xcore:
7024 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7026 case llvm::Triple::wasm32:
7027 case llvm::Triple::wasm64:
7028 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7030 case llvm::Triple::avr:
7031 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7033 case llvm::Triple::msp430:
7034 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7036 case llvm::Triple::riscv32:
7037 case llvm::Triple::riscv64:
7038 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7040 case llvm::Triple::ve:
7041 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7043 case llvm::Triple::spirv32:
7044 case llvm::Triple::spirv64:
7045 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7047 case llvm::Triple::csky:
7048 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7052 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7053 else if (
Target.isOSBinFormatELF())
7054 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7055 else if (
Target.isAppleMachO())
7056 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7057 else if (
Target.isOSBinFormatMachO())
7058 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7060 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7070 if (JA.
size() != 1 ||
7085 if (JA.
size() != 1 ||
7099 if (Args.hasArg(options::OPT_emit_static_lib))
7110 unsigned &Micro,
bool &HadExtra) {
7113 Major = Minor = Micro = 0;
7117 if (Str.consumeInteger(10, Major))
7121 if (!Str.consume_front(
"."))
7124 if (Str.consumeInteger(10, Minor))
7128 if (!Str.consume_front(
"."))
7131 if (Str.consumeInteger(10, Micro))
7149 unsigned CurDigit = 0;
7150 while (CurDigit < Digits.size()) {
7152 if (Str.consumeInteger(10, Digit))
7154 Digits[CurDigit] = Digit;
7157 if (!Str.consume_front(
"."))
7166llvm::opt::Visibility
7167Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7180const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7196 llvm_unreachable(
"Unhandled Mode");
7200 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7205 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7206 options::OPT_fno_save_optimization_record,
false))
7210 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7211 options::OPT_fno_save_optimization_record,
false))
7215 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7216 options::OPT_fno_save_optimization_record,
false))
7220 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7221 options::OPT_fno_save_optimization_record,
false))
7228 static StringRef OptName =
7230 llvm::StringRef Opt;
7231 for (StringRef Arg : Args) {
7232 if (!Arg.starts_with(OptName))
7238 return Opt.consume_front(OptName) ? Opt :
"";
7245 llvm::BumpPtrAllocator &Alloc,
7246 llvm::vfs::FileSystem *FS) {
7255 for (
const char *F : Args) {
7256 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7258 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7259 RSPQuoting = Windows;
7265 bool MarkEOLs = ClangCLMode;
7267 llvm::cl::TokenizerCallback Tokenizer;
7268 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7269 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7271 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7273 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7276 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7277 ECtx.setMarkEOLs(MarkEOLs);
7281 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7285 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7286 [](
const char *A) {
return A !=
nullptr; });
7287 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7290 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7291 Args.resize(newEnd - Args.begin());
7295 return llvm::Error::success();
7299 return SavedStrings.insert(S).first->getKeyData();
7333 llvm::StringSet<> &SavedStrings) {
7336 if (Edit[0] ==
'^') {
7337 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7338 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7339 Args.insert(Args.begin() + 1, Str);
7340 }
else if (Edit[0] ==
'+') {
7341 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7342 OS <<
"### Adding argument " << Str <<
" at end\n";
7343 Args.push_back(Str);
7344 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7345 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7346 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7347 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7348 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7350 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7352 if (Args[i] ==
nullptr)
7354 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7356 if (Repl != Args[i]) {
7357 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7361 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7362 auto Option = Edit.substr(1);
7363 for (
unsigned i = 1; i < Args.size();) {
7364 if (Option == Args[i]) {
7365 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7366 Args.erase(Args.begin() + i);
7367 if (Edit[0] ==
'X') {
7368 if (i < Args.size()) {
7369 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7370 Args.erase(Args.begin() + i);
7372 OS <<
"### Invalid X edit, end of command line!\n";
7377 }
else if (Edit[0] ==
'O') {
7378 for (
unsigned i = 1; i < Args.size();) {
7379 const char *A = Args[i];
7383 if (A[0] ==
'-' && A[1] ==
'O' &&
7384 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7385 (
'0' <= A[2] && A[2] <=
'9'))))) {
7386 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7387 Args.erase(Args.begin() + i);
7391 OS <<
"### Adding argument " << Edit <<
" at end\n";
7392 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7394 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7399 const char *OverrideStr,
7400 llvm::StringSet<> &SavedStrings,
7401 StringRef EnvVar, raw_ostream *OS) {
7403 OS = &llvm::nulls();
7405 if (OverrideStr[0] ==
'#') {
7407 OS = &llvm::nulls();
7410 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7414 const char *S = OverrideStr;
7416 const char *End = ::strchr(S,
' ');
7418 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static bool hasCXXModuleInputType(const Driver::InputList &Inputs)
static llvm::DenseSet< llvm::StringRef > inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
static const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static bool hasFlag(SVal val, ProgramStateRef state)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
llvm::SmallVector< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
bool isCXX(ID Id)
isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
bool scanInputForCXX20ModulesUsage(StringRef Source)
Scan an input source buffer for C++20 named module usage.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
const FunctionProtoType * T
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.