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/MD5.h"
93#include "llvm/Support/Path.h"
94#include "llvm/Support/PrettyStackTrace.h"
95#include "llvm/Support/Process.h"
96#include "llvm/Support/Program.h"
97#include "llvm/Support/Regex.h"
98#include "llvm/Support/StringSaver.h"
99#include "llvm/Support/VirtualFileSystem.h"
100#include "llvm/Support/raw_ostream.h"
101#include "llvm/TargetParser/Host.h"
102#include "llvm/TargetParser/RISCVISAInfo.h"
115using namespace clang;
118template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
119 return llvm::any_of(Args, [&](Arg *A) {
120 return (A->getOption().matches(options::OPT_x) &&
122 (A->getOption().
getKind() == Option::InputClass &&
123 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
125 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
131 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
132 StringRef UseCUIDStr = A->getValue();
133 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
134 .Case(
"hash", Kind::Hash)
135 .Case(
"random", Kind::Random)
136 .Case(
"none", Kind::None)
137 .Default(Kind::Invalid);
138 if (UseCUID == Kind::Invalid)
139 D.Diag(clang::diag::err_drv_invalid_value)
140 << A->getAsString(Args) << UseCUIDStr;
143 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
144 if (!FixedCUID.empty())
149 llvm::opt::DerivedArgList &Args)
const {
150 std::string CUID = FixedCUID.str();
153 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
157 llvm::MD5::MD5Result
Hash;
158 Hasher.update(InputFile);
159 for (
auto *A : Args) {
160 if (A->getOption().matches(options::OPT_INPUT))
162 Hasher.update(A->getAsString(Args));
165 CUID = llvm::utohexstr(
Hash.low(),
true);
173 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
174 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
181 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
182 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
183 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
186 this->VFS = llvm::vfs::getRealFileSystem();
191 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
194 llvm::sys::path::append(P,
SysRoot);
198#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
199 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
203 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
204 llvm::sys::path::remove_dots(configFileDir,
true);
208#if defined(CLANG_CONFIG_FILE_USER_DIR)
211 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
220void Driver::setDriverMode(StringRef
Value) {
221 static StringRef OptName =
222 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
223 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
224 .Case(
"gcc", GCCMode)
225 .Case(
"g++", GXXMode)
226 .Case(
"cpp", CPPMode)
228 .Case(
"flang", FlangMode)
229 .Case(
"dxc", DXCMode)
233 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
238 bool &ContainsError)
const {
239 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
240 ContainsError =
false;
242 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
243 unsigned MissingArgIndex, MissingArgCount;
244 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
245 MissingArgCount, VisibilityMask);
248 if (MissingArgCount) {
249 Diag(diag::err_drv_missing_argument)
250 << Args.getArgString(MissingArgIndex) << MissingArgCount;
252 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
257 for (
const Arg *A : Args) {
259 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
260 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
267 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
268 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
269 ContainsError |= Diags.getDiagnosticLevel(
270 diag::warn_drv_empty_joined_argument,
275 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
277 auto ArgString = A->getAsString(Args);
279 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
281 if (
getOpts().findExact(ArgString, Nearest,
283 DiagID = diag::err_drv_unknown_argument_with_suggestion;
284 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
286 DiagID = diag::err_drv_unknown_argument;
287 Diags.Report(DiagID) << ArgString;
290 llvm::opt::Visibility(
292 DiagID = diag::err_drv_unknown_argument_with_suggestion;
293 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
295 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
296 : diag::err_drv_unknown_argument;
297 Diags.Report(DiagID) << ArgString;
301 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
302 : diag::err_drv_unknown_argument_with_suggestion;
303 Diags.Report(DiagID) << ArgString << Nearest;
305 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
309 for (
const Arg *A : Args.filtered(options::OPT_o)) {
310 if (ArgStrings[A->getIndex()] == A->getSpelling())
314 std::string ArgString = ArgStrings[A->getIndex()];
316 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
317 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
318 << A->getAsString(Args) << Nearest;
328 Arg **FinalPhaseArg)
const {
329 Arg *PhaseArg =
nullptr;
333 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
334 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
335 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
336 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
343 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
344 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
345 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
346 options::OPT_fmodule_header_EQ))) {
349 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
350 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
352 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
353 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
363 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
367 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
370 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
378 *FinalPhaseArg = PhaseArg;
386 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
387 llvm::sys::fs::OF_Text);
388 llvm::FileRemover OutputRemover(OutputFile.c_str());
389 std::optional<llvm::StringRef> Redirects[] = {
395 std::string ErrorMessage;
396 int SecondsToWait = 60;
397 if (std::optional<std::string> Str =
398 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
399 if (!llvm::to_integer(*Str, SecondsToWait))
400 return llvm::createStringError(std::error_code(),
401 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
402 "an integer, got '" +
404 SecondsToWait = std::max(SecondsToWait, 0);
406 StringRef Executable = Args[0];
407 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
409 return llvm::createStringError(std::error_code(),
410 Executable +
": " + ErrorMessage);
412 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
413 llvm::MemoryBuffer::getFile(OutputFile.c_str());
415 return llvm::createStringError(OutputBuf.getError(),
416 "Failed to read stdout of " + Executable +
417 ": " + OutputBuf.getError().message());
418 return std::move(*OutputBuf);
422 StringRef
Value,
bool Claim =
true) {
423 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
424 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
425 Args.AddSynthesizedArg(A);
431DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
432 const llvm::opt::OptTable &Opts =
getOpts();
433 DerivedArgList *DAL =
new DerivedArgList(Args);
435 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
436 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
437 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
438 bool IgnoreUnused =
false;
439 for (Arg *A : Args) {
443 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
447 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
448 IgnoreUnused =
false;
458 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
459 A->getOption().matches(options::OPT_Xlinker)) &&
460 A->containsValue(
"--no-demangle")) {
462 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
465 for (StringRef Val : A->getValues())
466 if (Val !=
"--no-demangle")
467 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
475 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
476 A->getNumValues() > 0 &&
477 (A->getValue(0) == StringRef(
"-MD") ||
478 A->getValue(0) == StringRef(
"-MMD"))) {
480 if (A->getValue(0) == StringRef(
"-MD"))
481 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
483 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
484 if (A->getNumValues() == 2)
485 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
490 if (A->getOption().matches(options::OPT_l)) {
491 StringRef
Value = A->getValue();
494 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
496 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
501 if (
Value ==
"cc_kext") {
502 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
508 if (A->getOption().matches(options::OPT__DASH_DASH)) {
510 for (StringRef Val : A->getValues())
519 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
520 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
523 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
524 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
528#if defined(HOST_LINK_VERSION)
529 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
530 strlen(HOST_LINK_VERSION) > 0) {
531 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
533 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
541 StringRef ArgTarget) {
543 static bool BeSilent =
false;
544 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
545 return ((v < 2) || ((v == 2) && (r < 4)));
549 if (ArgTarget.equals_insensitive(
"CURRENT")) {
553 unsigned int Version = 0;
554 unsigned int Release = 0;
555 unsigned int Modification = 0;
557 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
558 llvm::Regex HexRegex(
561 "([0-9a-fA-F][0-9a-fA-F])"
562 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
565 if (ZOsvRegex.match(ArgTarget, &Matches)) {
566 Matches[1].getAsInteger(10, Version);
567 Matches[2].getAsInteger(10, Release);
569 if (IsTooOldToBeSupported(Version, Release)) {
571 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
574 }
else if (HexRegex.match(ArgTarget, &Matches)) {
575 Matches[1].getAsInteger(16, Version);
576 Matches[2].getAsInteger(16, Release);
577 Matches[3].getAsInteger(16, Modification);
578 if (IsTooOldToBeSupported(Version, Release)) {
580 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
586 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
591 llvm::VersionTuple
V(Version, Release, Modification);
592 llvm::VersionTuple TV =
Target.getOSVersion();
595 if (TV.empty() ||
V < TV) {
597 Str = llvm::Triple::getOSTypeName(
Target.getOS());
598 Str +=
V.getAsString();
611 StringRef TargetTriple,
613 StringRef DarwinArchName =
"") {
615 if (
const Arg *A = Args.getLastArg(options::OPT_target))
616 TargetTriple = A->getValue();
618 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
623 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
627 if (
Target.isOSBinFormatMachO()) {
629 if (!DarwinArchName.empty()) {
636 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
637 StringRef ArchName = A->getValue();
644 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
645 options::OPT_mbig_endian)) {
646 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
647 ?
Target.getLittleEndianArchVariant()
648 :
Target.getBigEndianArchVariant();
649 if (
T.getArch() != llvm::Triple::UnknownArch) {
651 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
656 if (
Target.getArch() == llvm::Triple::tce)
661 if (std::optional<std::string> ObjectModeValue =
662 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
663 StringRef ObjectMode = *ObjectModeValue;
664 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
666 if (ObjectMode ==
"64") {
667 AT =
Target.get64BitArchVariant().getArch();
668 }
else if (ObjectMode ==
"32") {
669 AT =
Target.get32BitArchVariant().getArch();
671 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
674 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
680 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
681 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
684 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
686 D.
Diag(diag::err_drv_unsupported_opt_for_target)
687 << A->getAsString(Args) <<
Target.str();
690 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
691 options::OPT_m32, options::OPT_m16,
692 options::OPT_maix32, options::OPT_maix64);
694 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
696 if (A->getOption().matches(options::OPT_m64) ||
697 A->getOption().matches(options::OPT_maix64)) {
698 AT =
Target.get64BitArchVariant().getArch();
699 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
700 Target.getEnvironment() == llvm::Triple::GNUT64)
701 Target.setEnvironment(llvm::Triple::GNU);
702 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
703 Target.setEnvironment(llvm::Triple::Musl);
704 }
else if (A->getOption().matches(options::OPT_mx32) &&
705 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
706 AT = llvm::Triple::x86_64;
707 if (
Target.getEnvironment() == llvm::Triple::Musl)
708 Target.setEnvironment(llvm::Triple::MuslX32);
710 Target.setEnvironment(llvm::Triple::GNUX32);
711 }
else if (A->getOption().matches(options::OPT_m32) ||
712 A->getOption().matches(options::OPT_maix32)) {
714 D.
Diag(diag::err_drv_unsupported_opt_for_target)
715 << A->getAsString(Args) <<
Target.str();
717 AT =
Target.get32BitArchVariant().getArch();
718 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
719 Target.setEnvironment(llvm::Triple::GNU);
720 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
721 Target.setEnvironment(llvm::Triple::Musl);
723 }
else if (A->getOption().matches(options::OPT_m16) &&
724 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
725 AT = llvm::Triple::x86;
726 Target.setEnvironment(llvm::Triple::CODE16);
729 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
731 if (
Target.isWindowsGNUEnvironment())
737 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
743 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
744 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
745 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
748 if (A && !A->getOption().matches(options::OPT_m32))
749 D.
Diag(diag::err_drv_argument_not_allowed_with)
750 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
752 Target.setArch(llvm::Triple::x86);
753 Target.setArchName(
"i586");
754 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
755 Target.setEnvironmentName(
"");
756 Target.setOS(llvm::Triple::ELFIAMCU);
757 Target.setVendor(llvm::Triple::UnknownVendor);
758 Target.setVendorName(
"intel");
764 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
765 StringRef ABIName = A->getValue();
766 if (ABIName ==
"32") {
768 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
769 Target.getEnvironment() == llvm::Triple::GNUABIN32)
770 Target.setEnvironment(llvm::Triple::GNU);
771 }
else if (ABIName ==
"n32") {
773 if (
Target.getEnvironment() == llvm::Triple::GNU ||
774 Target.getEnvironment() == llvm::Triple::GNUT64 ||
775 Target.getEnvironment() == llvm::Triple::GNUABI64)
776 Target.setEnvironment(llvm::Triple::GNUABIN32);
777 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
778 Target.getEnvironment() == llvm::Triple::MuslABI64)
779 Target.setEnvironment(llvm::Triple::MuslABIN32);
780 }
else if (ABIName ==
"64") {
782 if (
Target.getEnvironment() == llvm::Triple::GNU ||
783 Target.getEnvironment() == llvm::Triple::GNUT64 ||
784 Target.getEnvironment() == llvm::Triple::GNUABIN32)
785 Target.setEnvironment(llvm::Triple::GNUABI64);
786 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
787 Target.getEnvironment() == llvm::Triple::MuslABIN32)
788 Target.setEnvironment(llvm::Triple::MuslABI64);
796 if (Args.hasArg(options::OPT_march_EQ) ||
797 Args.hasArg(options::OPT_mcpu_EQ)) {
799 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
801 if (!llvm::errorToBool(ISAInfo.takeError())) {
802 unsigned XLen = (*ISAInfo)->getXLen();
804 Target.setArch(llvm::Triple::riscv32);
806 Target.setArch(llvm::Triple::riscv64);
818 OptSpecifier OptEq, OptSpecifier OptNeg) {
819 if (!Args.hasFlag(OptEq, OptNeg,
false))
822 const Arg *A = Args.getLastArg(OptEq);
823 StringRef LTOName = A->getValue();
831 D.
Diag(diag::err_drv_unsupported_option_argument)
832 << A->getSpelling() << A->getValue();
839void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
841 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
843 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
844 options::OPT_fno_offload_lto);
847 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
848 options::OPT_fno_openmp_target_jit,
false)) {
849 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
850 options::OPT_fno_offload_lto))
852 Diag(diag::err_drv_incompatible_options)
853 << A->getSpelling() <<
"-fopenmp-target-jit";
860 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
862 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
864 RuntimeName = A->getValue();
866 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
874 Diag(diag::err_drv_unsupported_option_argument)
875 << A->getSpelling() << A->getValue();
878 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
887 StringRef Program =
C.getArgs().getLastArgValue(
888 options::OPT_offload_arch_tool_EQ,
"offload-arch");
891 if (llvm::ErrorOr<std::string> Executable =
892 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
895 Args.push_back(
"--only=amdgpu");
897 Args.push_back(
"--only=nvptx");
898 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
901 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
906 if ((*StdoutOrErr)->getBuffer().empty()) {
907 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
913 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
915 GPUArchs.push_back(
Arch.str());
917 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
924static llvm::DenseSet<llvm::StringRef>
926 std::set<std::string> Archs;
927 for (Arg *A :
C.getInputArgs()) {
928 for (StringRef
Arch : A->getValues()) {
929 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
930 if (
Arch ==
"native") {
932 Archs.insert(Str.str());
934 Archs.insert(
Arch.str());
936 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
940 Archs.erase(
Arch.str());
945 llvm::DenseSet<llvm::StringRef> Triples;
946 for (llvm::StringRef
Arch : Archs) {
953 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
955 return llvm::DenseSet<llvm::StringRef>();
958 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
960 return llvm::DenseSet<llvm::StringRef>();
964 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
966 return llvm::DenseSet<llvm::StringRef>();
969 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
970 <<
"offload" <<
Arch;
971 return llvm::DenseSet<llvm::StringRef>();
976 Triple =
"spirv64-amd-amdhsa";
978 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
979 ?
"nvptx64-nvidia-cuda"
980 :
"nvptx-nvidia-cuda";
982 Triple =
"amdgcn-amd-amdhsa";
989 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
990 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
991 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
992 C.getArgs().MakeArgString(Triple.split(
"-").first),
993 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
995 C.getArgs().append(A);
996 C.getArgs().AddSynthesizedArg(A);
997 Triples.insert(Triple);
1002 Triples.insert(
"amdgcn-amd-amdhsa");
1004 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1005 ?
"nvptx64-nvidia-cuda"
1006 :
"nvptx-nvidia-cuda");
1008 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1009 ?
"spirv64-unknown-unknown"
1010 :
"spirv32-unknown-unknown");
1013 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1014 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1021 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1022 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1024 llvm::any_of(Inputs,
1025 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1030 (llvm::any_of(Inputs,
1031 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1034 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1035 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1037 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1038 options::OPT_fno_sycl,
false);
1039 bool IsOpenMPOffloading =
1041 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1042 options::OPT_fno_openmp,
false) &&
1043 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1044 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1045 !(IsCuda || IsHIP))));
1047 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1048 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1053 for (
const auto &[Active, Kind] : ActiveKinds)
1058 if (Kinds.size() > 1) {
1059 Diag(clang::diag::err_drv_mix_offload)
1066 if (IsCuda || IsHIP)
1072 std::multiset<llvm::StringRef> Triples;
1073 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1074 std::vector<std::string> ArgValues =
1075 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1076 for (llvm::StringRef
Target : ArgValues)
1077 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1079 if (ArgValues.empty())
1080 Diag(clang::diag::warn_drv_empty_joined_argument)
1082 .getLastArg(options::OPT_offload_targets_EQ)
1083 ->getAsString(
C.getInputArgs());
1084 }
else if (Kinds.size() > 0) {
1087 Triples.insert(Derived.begin(), Derived.end());
1092 llvm::StringMap<StringRef> FoundNormalizedTriples;
1093 for (StringRef
Target : Triples) {
1098 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1106 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1107 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1108 Diag(clang::diag::err_drv_argument_not_allowed_with)
1109 << IncompatArg->getSpelling() <<
"-fsycl";
1117 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1118 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1122 std::string NormalizedName = TT.normalize();
1123 auto [TripleIt, Inserted] =
1124 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1126 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1127 <<
Target << TripleIt->second;
1131 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1132 C.getDefaultToolChain().getTriple());
1136 auto &CudaInstallation =
1138 if (CudaInstallation.isValid())
1139 CudaInstallation.WarnIfUnsupportedVersion();
1142 C.addOffloadDeviceToolChain(&TC, Kind);
1147bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1152 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1156 if (!PathLIBEnv.empty()) {
1157 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1158 if (llvm::sys::fs::is_directory(PathLIBEnv))
1159 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1160 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1161 return readConfigFile(CustomizationFile, ExpCtx);
1162 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1167 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1168 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1169 return readConfigFile(CustomizationFile, ExpCtx);
1179 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1180 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1181 Copy->getValues() = Opt->getValues();
1182 if (Opt->isClaimed())
1184 Copy->setOwnsValues(Opt->getOwnsValues());
1185 Opt->setOwnsValues(
false);
1187 if (Opt->getAlias()) {
1188 const Arg *Alias = Opt->getAlias();
1189 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1190 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1191 Args.getArgString(Index), Index);
1192 AliasCopy->getValues() = Alias->getValues();
1193 AliasCopy->setOwnsValues(
false);
1194 if (Alias->isClaimed())
1196 Copy->setAlias(std::move(AliasCopy));
1200bool Driver::readConfigFile(StringRef
FileName,
1201 llvm::cl::ExpansionContext &ExpCtx) {
1205 Diag(diag::err_drv_cannot_open_config_file)
1206 <<
FileName << Status.getError().message();
1209 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1210 Diag(diag::err_drv_cannot_open_config_file)
1211 <<
FileName <<
"not a regular file";
1216 SmallVector<const char *, 32> NewCfgFileArgs;
1217 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1218 Diag(diag::err_drv_cannot_read_config_file)
1224 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1225 for (
const char *Opt : NewCfgFileArgs) {
1227 if (Opt[0] ==
'$' && Opt[1])
1228 NewCfgTailArgs.push_back(Opt + 1);
1230 NewCfgHeadArgs.push_back(Opt);
1234 llvm::SmallString<128> CfgFileName(
FileName);
1235 llvm::sys::path::native(CfgFileName);
1236 bool ContainErrors =
false;
1237 auto NewHeadOptions = std::make_unique<InputArgList>(
1241 auto NewTailOptions = std::make_unique<InputArgList>(
1248 for (Arg *A : *NewHeadOptions)
1250 for (Arg *A : *NewTailOptions)
1253 if (!CfgOptionsHead)
1254 CfgOptionsHead = std::move(NewHeadOptions);
1257 for (
auto *Opt : *NewHeadOptions)
1261 if (!CfgOptionsTail)
1262 CfgOptionsTail = std::move(NewTailOptions);
1265 for (
auto *Opt : *NewTailOptions)
1269 ConfigFiles.push_back(std::string(CfgFileName));
1273bool Driver::loadConfigFiles() {
1274 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1275 llvm::cl::tokenizeConfigFile);
1276 ExpCtx.setVFS(&
getVFS());
1280 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1281 SmallString<128> CfgDir;
1283 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1284 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1289 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1290 SmallString<128> CfgDir;
1291 llvm::sys::fs::expand_tilde(
1292 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1293 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1302 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1305 if (loadDefaultConfigFiles(ExpCtx))
1309 SmallString<128> CfgFilePath;
1311 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1314 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1315 CfgFilePath.assign(CfgFileName);
1316 if (llvm::sys::path::is_relative(CfgFilePath)) {
1317 if (
getVFS().makeAbsolute(CfgFilePath)) {
1318 Diag(diag::err_drv_cannot_open_config_file)
1319 << CfgFilePath <<
"cannot get absolute path";
1323 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1325 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1326 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1327 if (!SearchDir.empty())
1328 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1333 if (readConfigFile(CfgFilePath, ExpCtx))
1344 llvm::Triple Triple, std::string Suffix) {
1346 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1350 VersionTuple OSVersion = Triple.getOSVersion();
1351 if (!OSVersion.getMinor().has_value())
1354 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1358 if (OSVersion.getMajor() != 0) {
1359 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1360 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1366 Triple.setOSName(BaseOSName);
1367 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1370bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1373 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1377 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1380 std::string RealMode = getExecutableForDriverMode(Mode);
1381 llvm::Triple Triple;
1390 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1391 PrefixTriple.isOSUnknown())
1392 Triple = PrefixTriple;
1396 llvm::Triple RealTriple =
1398 if (Triple.str().empty()) {
1399 Triple = RealTriple;
1400 assert(!Triple.str().empty());
1405 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1419 SmallString<128> CfgFilePath;
1421 "-" + RealMode +
".cfg"))
1422 return readConfigFile(CfgFilePath, ExpCtx);
1426 if (TryModeSuffix) {
1429 return readConfigFile(CfgFilePath, ExpCtx);
1434 std::string CfgFileName = RealMode +
".cfg";
1435 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1436 if (readConfigFile(CfgFilePath, ExpCtx))
1438 }
else if (TryModeSuffix) {
1440 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1441 readConfigFile(CfgFilePath, ExpCtx))
1447 return readConfigFile(CfgFilePath, ExpCtx);
1455 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1464 if (!DriverMode.empty())
1465 setDriverMode(DriverMode);
1471 CLOptions = std::make_unique<InputArgList>(
1476 ContainsError = loadConfigFiles();
1477 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1478 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1482 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1484 if (HasConfigFileHead)
1485 for (
auto *Opt : *CLOptions)
1486 if (!Opt->getOption().matches(options::OPT_config))
1490 if (
IsCLMode() && !ContainsError) {
1492 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1494 CLModePassThroughArgList.push_back(A->getValue());
1497 if (!CLModePassThroughArgList.empty()) {
1500 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1505 for (
auto *Opt : *CLModePassThroughOptions)
1511 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1512 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1513 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1516 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1517 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1518 if (!VFS->exists(IncludeDir))
1519 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1524 bool CCCPrintPhases;
1527 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1528 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1531 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1532 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1535 Args.ClaimAllArgs(options::OPT_pipe);
1543 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1545 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1546 CCCGenericGCCName = A->getValue();
1549 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1553 if (Args.hasArg(options::OPT_fproc_stat_report))
1560 llvm::Triple
T(TargetTriple);
1561 T.setOS(llvm::Triple::Win32);
1562 T.setVendor(llvm::Triple::PC);
1563 T.setEnvironment(llvm::Triple::MSVC);
1564 T.setObjectFormat(llvm::Triple::COFF);
1565 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1566 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1567 TargetTriple =
T.str();
1570 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1571 StringRef TargetProfile = A->getValue();
1574 TargetTriple = *Triple;
1576 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1580 if (Args.hasArg(options::OPT_spirv)) {
1581 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1582 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1583 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1584 llvm::Triple
T(TargetTriple);
1587 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1589 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1590 TargetInfo = ValidTargets.find(A->getValue());
1592 Diag(diag::err_drv_invalid_value)
1593 << A->getAsString(Args) << A->getValue();
1599 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1600 TargetTriple =
T.str();
1604 Diag(diag::err_drv_dxc_missing_target_profile);
1608 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1609 TargetTriple = A->getValue();
1610 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1611 Dir =
Dir = A->getValue();
1612 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1616 if (std::optional<std::string> CompilerPathValue =
1617 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1618 StringRef CompilerPath = *CompilerPathValue;
1619 while (!CompilerPath.empty()) {
1620 std::pair<StringRef, StringRef> Split =
1621 CompilerPath.split(llvm::sys::EnvPathSeparator);
1622 PrefixDirs.push_back(std::string(Split.first));
1623 CompilerPath = Split.second;
1626 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1628 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1631 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1634 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1635 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1636 .Case(
"cwd", SaveTempsCwd)
1637 .Case(
"obj", SaveTempsObj)
1638 .Default(SaveTempsCwd);
1641 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1642 options::OPT_offload_device_only,
1643 options::OPT_offload_host_device)) {
1644 if (A->getOption().matches(options::OPT_offload_host_only))
1645 Offload = OffloadHost;
1646 else if (A->getOption().matches(options::OPT_offload_device_only))
1647 Offload = OffloadDevice;
1649 Offload = OffloadHostDevice;
1655 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1656 StringRef
Name = A->getValue();
1657 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1658 .Case(
"off", EmbedNone)
1659 .Case(
"all", EmbedBitcode)
1660 .Case(
"bitcode", EmbedBitcode)
1661 .Case(
"marker", EmbedMarker)
1664 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1667 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1671 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1672 llvm::sys::fs::remove(A->getValue());
1678 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1680 !Args.hasArg(options::OPT_fmodules) && Std &&
1681 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1682 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1683 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1684 Std->containsValue(
"c++latest"));
1687 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1688 options::OPT_fmodule_header)) {
1690 ModulesModeCXX20 =
true;
1691 if (A->getOption().matches(options::OPT_fmodule_header))
1694 StringRef ArgName = A->getValue();
1695 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1700 Diags.Report(diag::err_drv_invalid_value)
1701 << A->getAsString(Args) << ArgName;
1707 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1708 std::make_unique<InputArgList>(std::move(Args));
1718 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1719 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1721 bool MLContainsError;
1722 auto MultilibMacroDefineList =
1724 MLMacroDefinesChar,
false, MLContainsError));
1725 if (!MLContainsError) {
1726 for (
auto *Opt : *MultilibMacroDefineList) {
1733 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1737 if (!Triple.isWasm()) {
1738 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1739 StringRef TripleObjectFormat =
1740 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1741 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1742 TripleVersionName != TripleObjectFormat) {
1743 Diags.Report(diag::err_drv_triple_version_invalid)
1745 ContainsError =
true;
1750 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1751 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1752 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1760 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1761 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1763 case llvm::Triple::arm:
1764 case llvm::Triple::armeb:
1765 case llvm::Triple::thumb:
1766 case llvm::Triple::thumbeb:
1767 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1768 Diag(diag::warn_target_unrecognized_env)
1770 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1773 case llvm::Triple::aarch64:
1774 case llvm::Triple::aarch64_be:
1775 case llvm::Triple::aarch64_32:
1776 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1777 Diag(diag::warn_target_unrecognized_env)
1779 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1796 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1797 if (HasConfigFileTail && Inputs.size()) {
1800 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1801 for (Arg *A : *CfgOptionsTail)
1802 TranslatedLinkerIns.append(A);
1803 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1812 if (TC.
getTriple().isOSBinFormatMachO())
1817 if (CCCPrintPhases) {
1828 llvm::opt::ArgStringList ASL;
1829 for (
const auto *A : Args) {
1833 while (A->getAlias())
1835 A->render(Args, ASL);
1838 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1839 if (I != ASL.begin())
1841 llvm::sys::printArg(OS, *I,
true);
1846bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1847 SmallString<128> &CrashDiagDir) {
1848 using namespace llvm::sys;
1849 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1850 "Only knows about .crash files on Darwin");
1855 path::home_directory(CrashDiagDir);
1856 if (CrashDiagDir.starts_with(
"/var/root"))
1858 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1866 fs::file_status FileStatus;
1867 TimePoint<> LastAccessTime;
1868 SmallString<128> CrashFilePath;
1871 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1872 File != FileEnd && !EC;
File.increment(EC)) {
1876 if (fs::status(
File->path(), FileStatus))
1878 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1879 llvm::MemoryBuffer::getFile(
File->path());
1884 StringRef
Data = CrashFile.get()->getBuffer();
1885 if (!
Data.starts_with(
"Process:"))
1888 size_t ParentProcPos =
Data.find(
"Parent Process:");
1889 if (ParentProcPos == StringRef::npos)
1891 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1892 if (LineEnd == StringRef::npos)
1894 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1895 int OpenBracket = -1, CloseBracket = -1;
1896 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1897 if (ParentProcess[i] ==
'[')
1899 if (ParentProcess[i] ==
']')
1905 if (OpenBracket < 0 || CloseBracket < 0 ||
1906 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1907 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1917 const auto FileAccessTime = FileStatus.getLastModificationTime();
1918 if (FileAccessTime > LastAccessTime) {
1919 CrashFilePath.assign(
File->path());
1920 LastAccessTime = FileAccessTime;
1925 if (!CrashFilePath.empty()) {
1926 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1936 "\n********************\n\n"
1937 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1938 "Preprocessed source(s) and associated run script(s) are located at:";
1946 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1950 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1951 Level = llvm::StringSwitch<unsigned>(A->getValue())
1953 .Case(
"compiler", 1)
1965 ArgStringList SavedTemps;
1967 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1968 if (!IsLLD || Level < 2)
1975 SavedTemps = std::move(
C.getTempFiles());
1976 assert(!
C.getTempFiles().size());
1993 C.initCompilationForDiagnostics();
1998 Command NewLLDInvocation = Cmd;
1999 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2000 StringRef ReproduceOption =
2001 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2004 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2008 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2010 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2011 Diag(clang::diag::note_drv_command_failed_diag_msg)
2012 <<
"\n\n********************";
2014 Report->TemporaryFiles.push_back(TmpName);
2022 ArgStringList IRInputs;
2023 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2024 bool IgnoreInput =
false;
2030 IRInputs.push_back(it->second->getValue());
2034 }
else if (!strcmp(it->second->getValue(),
"-")) {
2035 Diag(clang::diag::note_drv_command_failed_diag_msg)
2036 <<
"Error generating preprocessed source(s) - "
2037 "ignoring input from stdin.";
2042 it = Inputs.erase(it);
2049 if (Inputs.empty() && IRInputs.empty()) {
2050 Diag(clang::diag::note_drv_command_failed_diag_msg)
2051 <<
"Error generating preprocessed source(s) - "
2052 "no preprocessable inputs.";
2059 for (
const Arg *A :
C.getArgs()) {
2060 if (A->getOption().matches(options::OPT_arch)) {
2061 StringRef ArchName = A->getValue();
2066 Diag(clang::diag::note_drv_command_failed_diag_msg)
2067 <<
"Error generating preprocessed source(s) - cannot generate "
2068 "preprocessed source with multiple -arch options.";
2073 if (!Inputs.empty()) {
2076 const ToolChain &TC =
C.getDefaultToolChain();
2077 if (TC.
getTriple().isOSBinFormatMachO())
2086 Diag(clang::diag::note_drv_command_failed_diag_msg)
2087 <<
"Error generating preprocessed source(s).";
2092 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2095 if (!FailingCommands.empty()) {
2096 Diag(clang::diag::note_drv_command_failed_diag_msg)
2097 <<
"Error generating preprocessed source(s).";
2101 const ArgStringList &TempFiles =
C.getTempFiles();
2102 if (TempFiles.empty()) {
2103 Diag(clang::diag::note_drv_command_failed_diag_msg)
2104 <<
"Error generating preprocessed source(s).";
2110 const ArgStringList &Files =
C.getTempFiles();
2115 for (
auto const *Input : IRInputs) {
2119 StringRef extension = llvm::sys::path::extension(Input);
2120 if (!extension.empty())
2121 extension = extension.drop_front();
2123 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2124 llvm::sys::path::stem(Input), extension, FD, Path);
2126 Diag(clang::diag::note_drv_command_failed_diag_msg)
2127 <<
"Error generating run script: " <<
"Failed copying IR input files"
2128 <<
" " << EC.message();
2132 EC = llvm::sys::fs::copy_file(Input, FD);
2134 Diag(clang::diag::note_drv_command_failed_diag_msg)
2135 <<
"Error generating run script: " <<
"Failed copying IR input files"
2136 <<
" " << EC.message();
2140 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2147 for (std::string &TempFile : TempFiles) {
2148 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2150 Report->TemporaryFiles.push_back(TempFile);
2151 if (ReproCrashFilename.empty()) {
2152 ReproCrashFilename = TempFile;
2153 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2155 if (StringRef(TempFile).ends_with(
".cache")) {
2158 VFS = llvm::sys::path::filename(TempFile);
2159 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2163 for (
const char *TempFile : SavedTemps)
2164 TempFiles.push_back(TempFile);
2170 llvm::sys::path::replace_extension(Script,
"sh");
2172 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2173 llvm::sys::fs::FA_Write,
2174 llvm::sys::fs::OF_Text);
2176 Diag(clang::diag::note_drv_command_failed_diag_msg)
2177 <<
"Error generating run script: " << Script <<
" " << EC.message();
2180 <<
"# Driver args: ";
2182 ScriptOS <<
"# Original command: ";
2183 Cmd.
Print(ScriptOS,
"\n",
true);
2184 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2185 if (!AdditionalInformation.empty())
2186 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2189 Report->TemporaryFiles.push_back(std::string(Script));
2190 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2194 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2196 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2197 Diag(clang::diag::note_drv_command_failed_diag_msg)
2198 << ReproCrashFilename.str();
2200 llvm::sys::path::append(CrashDiagDir,
Name);
2201 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2202 Diag(clang::diag::note_drv_command_failed_diag_msg)
2203 <<
"Crash backtrace is located in";
2204 Diag(clang::diag::note_drv_command_failed_diag_msg)
2205 << CrashDiagDir.str();
2206 Diag(clang::diag::note_drv_command_failed_diag_msg)
2207 <<
"(choose the .crash file that corresponds to your crash)";
2211 Diag(clang::diag::note_drv_command_failed_diag_msg)
2212 <<
"\n\n********************";
2222 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2233 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2234 if (
C.getArgs().hasArg(options::OPT_v))
2235 C.getJobs().Print(llvm::errs(),
"\n",
true);
2237 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2240 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2247 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2248 C.getJobs().Print(llvm::errs(),
"\n",
true);
2249 return Diags.hasErrorOccurred() ? 1 : 0;
2253 if (Diags.hasErrorOccurred())
2257 for (
auto &Job :
C.getJobs())
2258 setUpResponseFiles(
C, Job);
2260 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2263 if (FailingCommands.empty())
2269 for (
const auto &CmdPair : FailingCommands) {
2270 int CommandRes = CmdPair.first;
2271 const Command *FailingCommand = CmdPair.second;
2276 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2280 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2285 if (CommandRes == EX_IOERR) {
2302 Diag(clang::diag::err_drv_command_signalled)
2305 Diag(clang::diag::err_drv_command_failed)
2313 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2315 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2329 const ToolChain &TC =
C.getDefaultToolChain();
2333 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2336 OS <<
"Thread model: " << A->getValue();
2342 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2347 if (!llvm::cl::getCompilerBuildConfig().empty())
2348 llvm::cl::printBuildConfig(OS);
2351 for (
auto ConfigFile : ConfigFiles)
2352 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2365 if (PassedFlags ==
"")
2369 std::vector<std::string> SuggestedCompletions;
2370 std::vector<std::string> Flags;
2382 const bool HasSpace = PassedFlags.ends_with(
",");
2386 StringRef TargetFlags = PassedFlags;
2387 while (TargetFlags !=
"") {
2389 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2390 Flags.push_back(std::string(CurFlag));
2395 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2398 const llvm::opt::OptTable &Opts =
getOpts();
2400 Cur = Flags.at(Flags.size() - 1);
2402 if (Flags.size() >= 2) {
2403 Prev = Flags.at(Flags.size() - 2);
2404 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2407 if (SuggestedCompletions.empty())
2408 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2415 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2416 llvm::outs() <<
'\n';
2422 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2426 SuggestedCompletions = Opts.findByPrefix(
2427 Cur, VisibilityMask,
2434 if (S.starts_with(Cur))
2435 SuggestedCompletions.push_back(std::string(S));
2442 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2443 if (
int X = A.compare_insensitive(B))
2445 return A.compare(B) > 0;
2448 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2455 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2456 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2460 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2463 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2467 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2472 if (
C.getArgs().hasArg(options::OPT_help) ||
2473 C.getArgs().hasArg(options::OPT__help_hidden)) {
2474 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2478 if (
C.getArgs().hasArg(options::OPT__version)) {
2484 if (
C.getArgs().hasArg(options::OPT_v) ||
2485 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2486 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2487 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2488 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2490 SuppressMissingInputWarning =
true;
2493 if (
C.getArgs().hasArg(options::OPT_v)) {
2495 llvm::errs() <<
"System configuration file directory: "
2498 llvm::errs() <<
"User configuration file directory: "
2502 const ToolChain &TC =
C.getDefaultToolChain();
2504 if (
C.getArgs().hasArg(options::OPT_v))
2507 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2512 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2513 llvm::outs() <<
"programs: =";
2514 bool separator =
false;
2518 llvm::outs() << llvm::sys::EnvPathSeparator;
2519 llvm::outs() << Path;
2524 llvm::outs() << llvm::sys::EnvPathSeparator;
2525 llvm::outs() << Path;
2528 llvm::outs() <<
"\n";
2531 StringRef sysroot =
C.getSysRoot();
2535 llvm::outs() << llvm::sys::EnvPathSeparator;
2538 llvm::outs() << sysroot << Path.substr(1);
2540 llvm::outs() << Path;
2542 llvm::outs() <<
"\n";
2546 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2552 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2553 for (
auto RuntimePath :
2555 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2556 llvm::outs() << *RuntimePath <<
'\n';
2560 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2564 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2566 for (std::size_t I = 0; I != Flags.size(); I += 2)
2567 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2573 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2574 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2578 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2579 StringRef ProgName = A->getValue();
2582 if (! ProgName.empty())
2585 llvm::outs() <<
"\n";
2589 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2590 StringRef PassedFlags = A->getValue();
2595 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2609 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2612 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2618 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2625 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2628 std::set<llvm::StringRef> SortedFlags;
2629 for (
const auto &FlagEntry : ExpandedFlags)
2630 SortedFlags.insert(FlagEntry.getKey());
2631 for (
auto Flag : SortedFlags)
2632 llvm::outs() << Flag <<
'\n';
2636 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2639 llvm::outs() <<
".\n";
2642 assert(Suffix.front() ==
'/');
2643 llvm::outs() << Suffix.substr(1) <<
"\n";
2649 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2654 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2656 llvm::outs() << Triple.getTriple() <<
"\n";
2660 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2661 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2678 std::map<Action *, unsigned> &Ids,
2680 if (
auto It = Ids.find(A); It != Ids.end())
2684 llvm::raw_string_ostream os(str);
2686 auto getSibIndent = [](
int K) -> Twine {
2690 Twine SibIndent =
Indent + getSibIndent(Kind);
2694 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2696 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2697 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2698 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2700 OA->doOnEachDependence(
2702 assert(TC &&
"Unknown host toolchain");
2714 os <<
":" << BoundArch;
2717 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2725 const char *Prefix =
"{";
2726 for (
Action *PreRequisite : *AL) {
2727 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2738 std::string offload_str;
2739 llvm::raw_string_ostream offload_os(offload_str);
2743 offload_os <<
", (" << S;
2750 auto getSelfIndent = [](
int K) -> Twine {
2754 unsigned Id = Ids.size();
2756 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2765 std::map<Action *, unsigned> Ids;
2766 for (
Action *A :
C.getActions())
2782 DerivedArgList &Args =
C.getArgs();
2784 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2789 for (Arg *A : Args) {
2790 if (A->getOption().matches(options::OPT_arch)) {
2793 llvm::Triple::ArchType
Arch =
2795 if (
Arch == llvm::Triple::UnknownArch) {
2796 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2801 if (
ArchNames.insert(A->getValue()).second)
2802 Archs.push_back(A->getValue());
2816 for (
Action* Act : SingleActions) {
2824 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2828 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2833 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2834 Actions.append(Inputs.begin(), Inputs.end());
2836 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2839 Arg *A = Args.getLastArg(options::OPT_g_Group);
2840 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2841 !A->getOption().matches(options::OPT_gstabs);
2849 if (Act->getType() == types::TY_Image) {
2851 Inputs.push_back(Actions.back());
2858 if (Args.hasArg(options::OPT_verify_debug_info)) {
2859 Action *LastAction = Actions.pop_back_val();
2861 LastAction, types::TY_Nothing));
2880 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2881 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2893 std::string Nearest;
2894 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2895 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2896 <<
Value << Nearest;
2935 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2938 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2946 return types::TY_CXXUHeader;
2948 return types::TY_CXXSHeader;
2952 llvm_unreachable(
"should not be called in this case");
2954 return types::TY_CXXHUHeader;
2960 const llvm::opt::OptTable &Opts =
getOpts();
2964 types::ID InputType = types::TY_Nothing;
2965 Arg *InputTypeArg =
nullptr;
2968 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2969 options::OPT__SLASH_TP)) {
2970 InputTypeArg = TCTP;
2971 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2976 bool ShowNote =
false;
2978 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2980 Diag(clang::diag::warn_drv_overriding_option)
2981 <<
Previous->getSpelling() << A->getSpelling();
2987 Diag(clang::diag::note_drv_t_option_is_global);
2992 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2993 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2994 if (LastXArg && LastInputArg &&
2995 LastInputArg->getIndex() < LastXArg->getIndex())
2996 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2999 for (Arg *A : Args) {
3000 if (A->getOption().
getKind() == Option::InputClass) {
3001 const char *
Value = A->getValue();
3005 if (InputType == types::TY_Nothing) {
3008 InputTypeArg->claim();
3011 if (memcmp(
Value,
"-", 2) == 0) {
3013 Ty = types::TY_Fortran;
3015 Ty = types::TY_HLSL;
3024 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3025 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3026 : clang::diag::err_drv_unknown_stdin_type);
3035 if (
const char *Ext = strrchr(
Value,
'.'))
3044 Ty = types::TY_HLSL;
3046 Ty = types::TY_Object;
3057 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3058 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3059 << getTypeName(OldTy) << getTypeName(Ty);
3064 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3065 Ty == types::TY_Object)
3066 Ty = types::TY_LLVM_BC;
3074 if (Ty != types::TY_Object) {
3075 if (Args.hasArg(options::OPT_ObjC))
3076 Ty = types::TY_ObjC;
3077 else if (Args.hasArg(options::OPT_ObjCXX))
3078 Ty = types::TY_ObjCXX;
3085 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3089 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3090 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3093 const char *Ext = strrchr(
Value,
'.');
3095 Ty = types::TY_Object;
3099 InputTypeArg->claim();
3103 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3104 Args.hasArgNoClaim(options::OPT_hipstdpar))
3108 Inputs.push_back(std::make_pair(Ty, A));
3110 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3111 StringRef
Value = A->getValue();
3114 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3115 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3118 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3119 StringRef
Value = A->getValue();
3122 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3123 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3129 Inputs.push_back(std::make_pair(types::TY_Object, A));
3131 }
else if (A->getOption().matches(options::OPT_x)) {
3140 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3141 InputType = types::TY_Object;
3148 }
else if (A->getOption().getID() == options::OPT_U) {
3149 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3150 StringRef Val = A->getValue(0);
3151 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3153 Diag(diag::warn_slash_u_filename) << Val;
3154 Diag(diag::note_use_dashdash);
3158 if (
CCCIsCPP() && Inputs.empty()) {
3162 Inputs.push_back(std::make_pair(types::TY_C, A));
3169class OffloadingActionBuilder final {
3171 bool IsValid =
false;
3177 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3180 std::map<Action *, const Arg *> HostActionToInputArgMap;
3183 class DeviceActionBuilder {
3187 enum ActionBuilderReturnCode {
3206 DerivedArgList &Args;
3215 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3218 :
C(
C), Args(Args), Inputs(Inputs),
3219 AssociatedOffloadKind(AssociatedOffloadKind) {}
3220 virtual ~DeviceActionBuilder() {}
3225 virtual ActionBuilderReturnCode
3226 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3229 return ABRT_Inactive;
3234 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3235 return ABRT_Inactive;
3239 virtual void appendTopLevelActions(
ActionList &AL) {}
3242 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3245 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3248 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3255 virtual bool canUseBundlerUnbundler()
const {
return false; }
3259 bool isValid() {
return !ToolChains.empty(); }
3263 return AssociatedOffloadKind;
3269 class CudaActionBuilderBase :
public DeviceActionBuilder {
3273 bool CompileHostOnly =
false;
3274 bool CompileDeviceOnly =
false;
3276 bool EmitAsm =
false;
3286 TargetID(
const char *ID) :
ID(
ID) {}
3287 operator const char *() {
return ID; }
3288 operator StringRef() {
return StringRef(ID); }
3291 SmallVector<TargetID, 4> GpuArchList;
3297 Action *CudaFatBinary =
nullptr;
3300 bool IsActive =
false;
3303 bool Relocatable =
false;
3306 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3309 const CUIDOptions &CUIDOpts;
3312 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3315 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3316 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3318 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3319 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3320 options::OPT_fno_gpu_rdc,
false);
3323 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3330 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3333 if (!(IA->getType() == types::TY_CUDA ||
3334 IA->getType() == types::TY_HIP ||
3335 IA->getType() == types::TY_PP_HIP)) {
3338 return ABRT_Inactive;
3345 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3347 if (CompileHostOnly)
3348 return ABRT_Success;
3351 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3352 : types::TY_CUDA_DEVICE;
3353 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3354 CudaDeviceActions.push_back(
3355 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3358 return ABRT_Success;
3362 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3366 if (UA->getType() == types::TY_Object && !Relocatable)
3367 return ABRT_Inactive;
3369 CudaDeviceActions.clear();
3371 std::string
FileName = IA->getInputArg().getAsString(Args);
3377 const StringRef LibFileExt =
".lib";
3378 if (IA->getType() == types::TY_Object &&
3379 (!llvm::sys::path::has_extension(
FileName) ||
3381 llvm::sys::path::extension(
FileName).drop_front()) !=
3383 llvm::sys::path::extension(
FileName) == LibFileExt))
3384 return ABRT_Inactive;
3386 for (
auto Arch : GpuArchList) {
3387 CudaDeviceActions.push_back(UA);
3388 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3389 AssociatedOffloadKind);
3392 return ABRT_Success;
3395 return IsActive ? ABRT_Success : ABRT_Inactive;
3398 void appendTopLevelActions(
ActionList &AL)
override {
3400 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3401 OffloadAction::DeviceDependences Dep;
3402 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3403 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3407 if (CudaFatBinary) {
3408 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3409 CudaDeviceActions.clear();
3410 CudaFatBinary =
nullptr;
3414 if (CudaDeviceActions.empty())
3420 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3421 "Expecting one action per GPU architecture.");
3422 assert(ToolChains.size() == 1 &&
3423 "Expecting to have a single CUDA toolchain.");
3424 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3425 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3427 CudaDeviceActions.clear();
3430 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3448 assert(HostTC &&
"No toolchain for host compilation.");
3453 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3458 std::set<StringRef> GpuArchs;
3460 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3461 ToolChains.push_back(I.second);
3464 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3465 GpuArchs.insert(
Arch);
3469 for (
auto Arch : GpuArchs)
3470 GpuArchList.push_back(
Arch.data());
3472 CompileHostOnly =
C.getDriver().offloadHostOnly();
3473 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3474 EmitAsm = Args.getLastArg(options::OPT_S);
3482 class CudaActionBuilder final :
public CudaActionBuilderBase {
3484 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3486 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3487 DefaultOffloadArch = OffloadArch::CudaDefault;
3490 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3492 const std::set<StringRef> &GpuArchs)
override {
3493 return std::nullopt;
3496 ActionBuilderReturnCode
3497 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3499 PhasesTy &Phases)
override {
3501 return ABRT_Inactive;
3505 if (CudaDeviceActions.empty())
3506 return ABRT_Success;
3508 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3509 "Expecting one action per GPU architecture.");
3510 assert(!CompileHostOnly &&
3511 "Not expecting CUDA actions in host-only compilation.");
3521 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3524 for (
auto Ph : Phases) {
3529 if (Ph > FinalPhase)
3532 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3546 Action *AssembleAction = CudaDeviceActions[I];
3547 assert(AssembleAction->
getType() == types::TY_Object);
3548 assert(AssembleAction->
getInputs().size() == 1);
3554 OffloadAction::DeviceDependences DDep;
3556 DeviceActions.push_back(
3557 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3562 if (!DeviceActions.empty()) {
3564 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3566 if (!CompileDeviceOnly) {
3567 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3571 CudaFatBinary =
nullptr;
3576 CudaDeviceActions.clear();
3580 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3585 return ABRT_Success;
3589 "instructions should only occur "
3590 "before the backend phase!");
3593 for (Action *&A : CudaDeviceActions)
3594 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3596 return ABRT_Success;
3601 class HIPActionBuilder final :
public CudaActionBuilderBase {
3603 SmallVector<ActionList, 8> DeviceLinkerInputs;
3609 std::optional<bool> BundleOutput;
3610 std::optional<bool> EmitReloc;
3613 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3615 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3617 DefaultOffloadArch = OffloadArch::HIPDefault;
3619 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3620 options::OPT_fno_hip_emit_relocatable)) {
3621 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3622 options::OPT_fno_hip_emit_relocatable, false);
3626 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3627 <<
"-fhip-emit-relocatable"
3631 if (!CompileDeviceOnly) {
3632 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3633 <<
"-fhip-emit-relocatable"
3634 <<
"--offload-device-only";
3639 if (Args.hasArg(options::OPT_gpu_bundle_output,
3640 options::OPT_no_gpu_bundle_output))
3641 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3642 options::OPT_no_gpu_bundle_output,
true) &&
3643 (!EmitReloc || !*EmitReloc);
3646 bool canUseBundlerUnbundler()
const override {
return true; }
3648 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3650 const std::set<StringRef> &GpuArchs)
override {
3654 ActionBuilderReturnCode
3655 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3657 PhasesTy &Phases)
override {
3659 return ABRT_Inactive;
3665 if (CudaDeviceActions.empty())
3666 return ABRT_Success;
3669 CudaDeviceActions.size() == GpuArchList.size()) &&
3670 "Expecting one action per GPU architecture.");
3671 assert(!CompileHostOnly &&
3672 "Not expecting HIP actions in host-only compilation.");
3674 bool ShouldLink = !EmitReloc || !*EmitReloc;
3677 !EmitAsm && ShouldLink) {
3683 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3684 if (
C.getDriver().isUsingOffloadLTO()) {
3688 AL.push_back(CudaDeviceActions[I]);
3691 CudaDeviceActions[I] =
3692 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3698 if (ToolChains.front()->getTriple().isSPIRV() ||
3699 (ToolChains.front()->getTriple().isAMDGCN() &&
3700 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3704 types::ID Output = Args.hasArg(options::OPT_S)
3706 : types::TY_LLVM_BC;
3708 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3712 AssociatedOffloadKind);
3713 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3715 AssociatedOffloadKind);
3716 AL.push_back(AssembleAction);
3719 CudaDeviceActions[I] =
3720 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3729 OffloadAction::DeviceDependences DDep;
3730 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3731 AssociatedOffloadKind);
3732 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3733 DDep, CudaDeviceActions[I]->getType());
3736 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3738 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3739 types::TY_HIP_FATBIN);
3741 if (!CompileDeviceOnly) {
3742 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3743 AssociatedOffloadKind);
3746 CudaFatBinary =
nullptr;
3751 CudaDeviceActions.clear();
3754 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3757 return ABRT_Success;
3763 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3764 auto LI = DeviceLinkerInputs.begin();
3765 for (
auto *A : CudaDeviceActions) {
3772 CudaDeviceActions.clear();
3773 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3777 for (Action *&A : CudaDeviceActions)
3778 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3779 AssociatedOffloadKind);
3781 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3783 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3784 OffloadAction::DeviceDependences DDep;
3785 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3786 AssociatedOffloadKind);
3787 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3788 DDep, CudaDeviceActions[I]->getType());
3791 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3792 CudaDeviceActions.clear();
3795 return (CompileDeviceOnly &&
3796 (CurPhase == FinalPhase ||
3802 void appendLinkDeviceActions(
ActionList &AL)
override {
3803 if (DeviceLinkerInputs.size() == 0)
3806 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3807 "Linker inputs and GPU arch list sizes do not match.");
3813 for (
auto &LI : DeviceLinkerInputs) {
3815 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3819 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3822 OffloadAction::DeviceDependences DeviceLinkDeps;
3823 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3824 GpuArchList[I], AssociatedOffloadKind);
3825 Actions.push_back(
C.MakeAction<OffloadAction>(
3826 DeviceLinkDeps, DeviceLinkAction->getType()));
3829 DeviceLinkerInputs.clear();
3832 if (Args.hasArg(options::OPT_emit_llvm)) {
3840 OffloadAction::DeviceDependences DDeps;
3841 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3842 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3844 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3845 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3846 AssociatedOffloadKind);
3849 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3855 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3857 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3865 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3871 bool ShouldUseBundler;
3874 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3882 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3885 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3893 unsigned ValidBuilders = 0u;
3894 unsigned ValidBuildersSupportingBundling = 0u;
3895 for (
auto *SB : SpecializedBuilders) {
3896 IsValid = IsValid && !SB->initialize();
3899 if (SB->isValid()) {
3901 if (SB->canUseBundlerUnbundler())
3902 ++ValidBuildersSupportingBundling;
3906 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3908 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
3909 options::OPT_no_gpu_bundle_output,
true);
3912 ~OffloadingActionBuilder() {
3913 for (
auto *SB : SpecializedBuilders)
3918 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3919 assert(HostAction &&
"Invalid host action");
3920 assert(InputArg &&
"Invalid input argument");
3921 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3922 assert(Loc->second == InputArg &&
3923 "host action mapped to multiple input arguments");
3932 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3934 DeviceActionBuilder::PhasesTy &Phases) {
3938 if (SpecializedBuilders.empty())
3941 assert(HostAction &&
"Invalid host action!");
3942 recordHostAction(HostAction, InputArg);
3947 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3948 unsigned InactiveBuilders = 0u;
3949 unsigned IgnoringBuilders = 0u;
3950 for (
auto *SB : SpecializedBuilders) {
3951 if (!SB->isValid()) {
3956 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3961 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3966 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3967 OffloadKind |= SB->getAssociatedOffloadKind();
3972 if (IgnoringBuilders &&
3973 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3990 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3991 const Arg *InputArg) {
3995 recordHostAction(HostAction, InputArg);
4004 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4006 HostAction->
getType() == types::TY_PP_HIP)) {
4007 auto UnbundlingHostAction =
4012 HostAction = UnbundlingHostAction;
4013 recordHostAction(HostAction, InputArg);
4016 assert(HostAction &&
"Invalid host action!");
4019 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4020 for (
auto *SB : SpecializedBuilders) {
4024 auto RetCode = SB->addDeviceDependences(HostAction);
4028 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4029 "Host dependence not expected to be ignored.!");
4033 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4034 OffloadKind |= SB->getAssociatedOffloadKind();
4039 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4049 const Arg *InputArg) {
4051 recordHostAction(HostAction, InputArg);
4055 for (
auto *SB : SpecializedBuilders) {
4058 SB->appendTopLevelActions(OffloadAL);
4065 if (CanUseBundler && ShouldUseBundler && HostAction &&
4066 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4068 OffloadAL.push_back(HostAction);
4072 assert(HostAction == AL.back() &&
"Host action not in the list??");
4074 recordHostAction(HostAction, InputArg);
4075 AL.back() = HostAction;
4077 AL.append(OffloadAL.begin(), OffloadAL.end());
4087 void appendDeviceLinkActions(
ActionList &AL) {
4088 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4091 SB->appendLinkDeviceActions(AL);
4095 Action *makeHostLinkAction() {
4098 appendDeviceLinkActions(DeviceAL);
4099 if (DeviceAL.empty())
4104 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4107 HA = SB->appendLinkHostActions(DeviceAL);
4124 for (
auto *SB : SpecializedBuilders) {
4128 SB->appendLinkDependences(DDeps);
4132 unsigned ActiveOffloadKinds = 0u;
4133 for (
auto &I : InputArgToOffloadKindMap)
4134 ActiveOffloadKinds |= I.second;
4146 for (
auto *A : HostAction->
inputs()) {
4147 auto ArgLoc = HostActionToInputArgMap.find(A);
4148 if (ArgLoc == HostActionToInputArgMap.end())
4150 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4151 if (OFKLoc == InputArgToOffloadKindMap.end())
4163 nullptr, ActiveOffloadKinds);
4169void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4170 const InputList &Inputs,
4174 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4175 StringRef
V = A->getValue();
4176 if (Inputs.size() > 1 && !
V.empty() &&
4177 !llvm::sys::path::is_separator(
V.back())) {
4179 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4180 << A->getSpelling() <<
V;
4181 Args.eraseArg(options::OPT__SLASH_Fo);
4186 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4187 StringRef
V = A->getValue();
4188 if (Inputs.size() > 1 && !
V.empty() &&
4189 !llvm::sys::path::is_separator(
V.back())) {
4191 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4192 << A->getSpelling() <<
V;
4193 Args.eraseArg(options::OPT__SLASH_Fa);
4198 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4199 if (A->getValue()[0] ==
'\0') {
4201 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4202 Args.eraseArg(options::OPT__SLASH_o);
4207 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4208 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4209 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4210 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4211 Args.eraseArg(options::OPT__SLASH_Yc);
4212 Args.eraseArg(options::OPT__SLASH_Yu);
4213 YcArg = YuArg =
nullptr;
4215 if (YcArg && Inputs.size() > 1) {
4216 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4217 Args.eraseArg(options::OPT__SLASH_Yc);
4221 if (Args.hasArgNoClaim(options::OPT_fmodules_driver))
4223 if (!ModulesModeCXX20 && !Args.hasArgNoClaim(options::OPT_fmodules))
4224 Args.eraseArg(options::OPT_fmodules_driver);
4230 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4231 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4232 Args.AddFlagArg(
nullptr,
4233 getOpts().getOption(options::OPT_frtlib_add_rpath));
4236 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4237 Diag(clang::diag::err_drv_emit_llvm_link);
4238 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4240 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4241 .starts_with_insensitive(
"lld"))
4242 Diag(clang::diag::err_drv_lto_without_lld);
4248 if (!Args.hasArg(options::OPT_dumpdir)) {
4249 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4250 Arg *Arg = Args.MakeSeparateArg(
4251 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4253 (FinalOutput ? FinalOutput->getValue()
4265 Args.eraseArg(options::OPT__SLASH_Fp);
4266 Args.eraseArg(options::OPT__SLASH_Yc);
4267 Args.eraseArg(options::OPT__SLASH_Yu);
4268 YcArg = YuArg =
nullptr;
4271 if (Args.hasArg(options::OPT_include_pch) &&
4272 Args.hasArg(options::OPT_ignore_pch)) {
4276 Args.eraseArg(options::OPT_include_pch);
4279 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4280 for (
auto &I : Inputs) {
4282 const Arg *InputArg = I.second;
4287 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4291 if (InitialPhase > FinalPhase) {
4292 if (InputArg->isClaimed())
4299 if (Args.hasArg(options::OPT_Qunused_arguments))
4305 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4306 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4310 (Args.getLastArg(options::OPT__SLASH_EP,
4311 options::OPT__SLASH_P) ||
4312 Args.getLastArg(options::OPT_E) ||
4313 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4315 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4316 << InputArg->getAsString(Args) << !!FinalPhaseArg
4317 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4319 Diag(clang::diag::warn_drv_input_file_unused)
4320 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4322 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4331 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4335 Actions.push_back(ClangClPch);
4347 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4348 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4353 const auto IsTypeCXXModule = [](
const auto &Input) ->
bool {
4354 const auto TypeID = Input.first;
4355 return (TypeID == types::TY_CXXModule);
4357 return llvm::any_of(Inputs, IsTypeCXXModule);
4361Driver::ScanInputsForCXX20ModulesUsage(
const InputList &Inputs)
const {
4362 const auto CXXInputs = llvm::make_filter_range(
4363 Inputs, [](
const auto &Input) {
return types::isCXX(Input.first); });
4364 for (
const auto &Input : CXXInputs) {
4365 StringRef Filename = Input.second->getSpelling();
4366 auto ErrOrBuffer = VFS->getBufferForFile(Filename);
4368 return ErrOrBuffer.getError();
4369 const auto Buffer = std::move(*ErrOrBuffer);
4372 Diags.Report(diag::remark_found_cxx20_module_usage) << Filename;
4381 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4383 if (!SuppressMissingInputWarning && Inputs.empty()) {
4384 Diag(clang::diag::err_drv_no_input_files);
4388 handleArguments(
C, Args, Inputs, Actions);
4390 if (Args.hasFlag(options::OPT_fmodules_driver,
4391 options::OPT_fno_modules_driver,
false)) {
4396 if (!UsesCXXModules) {
4397 const auto ErrOrScanResult = ScanInputsForCXX20ModulesUsage(Inputs);
4398 if (!ErrOrScanResult) {
4399 Diags.Report(diag::err_cannot_open_file)
4400 << ErrOrScanResult.getError().message();
4403 UsesCXXModules = *ErrOrScanResult;
4405 if (UsesCXXModules || Args.hasArg(options::OPT_fmodules))
4406 BuildDriverManagedModuleBuildActions(
C, Args, Inputs, Actions);
4410 BuildDefaultActions(
C, Args, Inputs, Actions);
4413void Driver::BuildDefaultActions(
Compilation &
C, DerivedArgList &Args,
4414 const InputList &Inputs,
4417 bool UseNewOffloadingDriver =
4420 Args.hasFlag(options::OPT_foffload_via_llvm,
4421 options::OPT_fno_offload_via_llvm,
false) ||
4422 Args.hasFlag(options::OPT_offload_new_driver,
4423 options::OPT_no_offload_new_driver,
4427 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4428 !UseNewOffloadingDriver
4429 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4437 for (
auto &I : Inputs) {
4439 const Arg *InputArg = I.second;
4452 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4458 if (!UseNewOffloadingDriver)
4459 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4465 if (!UseNewOffloadingDriver)
4466 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4467 Current, InputArg, Phase, PL.back(), FullPL);
4473 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4476 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4477 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4479 LinkerInputs.push_back(Current);
4489 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4490 MergerInputs.push_back(Current);
4508 if (NewCurrent == Current)
4511 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4512 ExtractAPIAction = EAA;
4514 Current = NewCurrent;
4518 if (UseNewOffloadingDriver)
4522 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4526 if (Current->
getType() == types::TY_Nothing)
4532 Actions.push_back(Current);
4535 if (!UseNewOffloadingDriver)
4536 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4544 if (LinkerInputs.empty()) {
4547 if (!UseNewOffloadingDriver)
4548 OffloadBuilder->appendDeviceLinkActions(Actions);
4551 if (!LinkerInputs.empty()) {
4552 if (!UseNewOffloadingDriver)
4553 if (Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4554 LinkerInputs.push_back(Wrapper);
4558 LA =
C.MakeAction<StaticLibJobAction>(LinkerInputs, types::TY_Image);
4559 }
else if (UseNewOffloadingDriver ||
4560 Args.hasArg(options::OPT_offload_link)) {
4561 LA =
C.MakeAction<LinkerWrapperJobAction>(LinkerInputs, types::TY_Image);
4565 LA =
C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image);
4567 if (!UseNewOffloadingDriver)
4568 LA = OffloadBuilder->processHostLinkAction(LA);
4569 Actions.push_back(LA);
4573 if (!MergerInputs.empty())
4575 C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
4577 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4584 for (
auto &I : Inputs) {
4586 const Arg *InputArg = I.second;
4591 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4592 InputType == types::TY_Asm)
4595 Action *Current =
C.MakeAction<InputAction>(*InputArg, InputType);
4597 for (
auto Phase : PhaseList) {
4601 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4606 if (InputType == types::TY_Object)
4609 Current =
C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);
4613 assert(Phase == PhaseList.back() &&
4614 "merging must be final compilation step.");
4615 MergerInputs.push_back(Current);
4624 Actions.push_back(Current);
4628 if (!MergerInputs.empty())
4630 C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
4633 for (
auto Opt : {options::OPT_print_supported_cpus,
4634 options::OPT_print_supported_extensions,
4635 options::OPT_print_enabled_extensions}) {
4642 if (Arg *A = Args.getLastArg(Opt)) {
4643 if (Opt == options::OPT_print_supported_extensions &&
4644 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4645 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4646 !
C.getDefaultToolChain().getTriple().isARM()) {
4647 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4648 <<
"--print-supported-extensions";
4651 if (Opt == options::OPT_print_enabled_extensions &&
4652 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4653 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4654 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4655 <<
"--print-enabled-extensions";
4661 Action *InputAc =
C.MakeAction<InputAction>(
4662 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4664 C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
4665 for (
auto &I : Inputs)
4670 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4672 static_cast<const toolchains::HLSLToolChain &
>(
C.getDefaultToolChain());
4676 if (TC.requiresObjcopy(Args)) {
4677 Action *LastAction = Actions.back();
4679 if (LastAction->
getType() == types::TY_Object)
4681 C.MakeAction<ObjcopyJobAction>(LastAction, types::TY_Object));
4685 if (TC.requiresValidation(Args)) {
4686 Action *LastAction = Actions.back();
4687 Actions.push_back(
C.MakeAction<BinaryAnalyzeJobAction>(
4688 LastAction, types::TY_DX_CONTAINER));
4692 if (TC.requiresBinaryTranslation(Args)) {
4693 Action *LastAction = Actions.back();
4697 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4698 LastAction->
getType() == types::TY_Object)
4699 Actions.push_back(
C.MakeAction<BinaryTranslatorJobAction>(
4700 LastAction, types::TY_DX_CONTAINER));
4705 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4708void Driver::BuildDriverManagedModuleBuildActions(
4709 Compilation &
C, llvm::opt::DerivedArgList &Args,
const InputList &Inputs,
4711 Diags.Report(diag::remark_performing_driver_managed_module_build);
4717 const llvm::opt::DerivedArgList &Args,
4719 const llvm::Triple &Triple) {
4724 if (Triple.isNVPTX() &&
4726 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4727 <<
"CUDA" << ArchStr;
4729 }
else if (Triple.isAMDGPU() &&
4731 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4732 <<
"HIP" << ArchStr;
4740 llvm::StringMap<bool> Features;
4743 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4755static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4757 llvm::Triple Triple) {
4758 if (!Triple.isAMDGPU())
4759 return std::nullopt;
4761 std::set<StringRef> ArchSet;
4762 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4766llvm::SmallVector<StringRef>
4770 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4771 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4772 options::OPT_no_offload_arch_EQ)) {
4773 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4775 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4777 :
"--no-offload-arch");
4780 llvm::DenseSet<StringRef> Archs;
4781 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4784 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4785 for (StringRef
Arch : Arg->getValues()) {
4786 if (
Arch ==
"native" ||
Arch.empty()) {
4790 << llvm::Triple::getArchTypeName(TC.
getArch())
4791 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4795 for (
auto ArchStr : *GPUsOrErr) {
4797 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4798 if (!CanonicalStr.empty())
4799 Archs.insert(CanonicalStr);
4804 StringRef CanonicalStr =
4806 if (!CanonicalStr.empty())
4807 Archs.insert(CanonicalStr);
4812 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4813 for (StringRef
Arch : Arg->getValues()) {
4814 if (
Arch ==
"all") {
4819 Archs.erase(ArchStr);
4825 if (
auto ConflictingArchs =
4827 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4828 << ConflictingArchs->first << ConflictingArchs->second;
4831 if (Archs.empty()) {
4839 Archs.insert(StringRef());
4842 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4843 .getLastArg(options::OPT_march_EQ)) {
4844 Archs.insert(Arg->getValue());
4849 << llvm::Triple::getArchTypeName(TC.
getArch())
4850 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4851 }
else if (!ArchsOrErr->empty()) {
4852 for (
auto Arch : *ArchsOrErr)
4853 Archs.insert(Args.MakeArgStringRef(
Arch));
4855 Archs.insert(StringRef());
4860 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4861 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4869 llvm::opt::DerivedArgList &Args,
4870 const InputTy &Input, StringRef CUID,
4871 Action *HostAction)
const {
4879 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4881 bool HIPRelocatableObj =
4883 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4884 options::OPT_fno_hip_emit_relocatable,
false);
4886 if (!HIPNoRDC && HIPRelocatableObj)
4887 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4888 <<
"-fhip-emit-relocatable"
4892 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4893 <<
"-fhip-emit-relocatable"
4894 <<
"--offload-device-only";
4912 auto TCRange =
C.getOffloadToolChains(Kind);
4913 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4914 ToolChains.push_back(TI->second);
4916 if (ToolChains.empty())
4920 const Arg *InputArg = Input.second;
4929 for (
const ToolChain *TC : ToolChains) {
4931 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4932 DeviceActions.push_back(
4933 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4937 if (DeviceActions.empty())
4943 HostAction->
getType() != types::TY_Nothing &&
4953 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4962 auto *TCAndArch = TCAndArchs.begin();
4963 for (
Action *&A : DeviceActions) {
4964 if (A->
getType() == types::TY_Nothing)
4974 HostAction->
getType() != types::TY_Nothing) {
4981 TCAndArch->second.data(), Kind);
4983 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4993 for (
Action *&A : DeviceActions) {
4996 llvm::Triple::OSType::AMDHSA &&
4998 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
4999 options::OPT_no_use_spirv_backend,
5006 bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
5008 if ((A->
getType() != types::TY_Object && !IsAMDGCNSPIRV &&
5009 A->
getType() != types::TY_LTO_BC) ||
5017 auto *TCAndArch = TCAndArchs.begin();
5018 for (
Action *A : DeviceActions) {
5019 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5021 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5026 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5028 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5037 bool ShouldBundleHIP =
5038 Args.hasFlag(options::OPT_gpu_bundle_output,
5039 options::OPT_no_gpu_bundle_output,
false) ||
5041 llvm::none_of(OffloadActions, [](
Action *A) {
5042 return A->
getType() != types::TY_Image;
5049 if (OffloadActions.empty())
5054 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5058 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5065 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5066 DDep.
add(*FatbinAction,
5069 }
else if (HIPNoRDC) {
5081 DDep.
add(*PackagerAction,
5090 nullptr,
C.getActiveOffloadKinds());
5099 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5100 return A->
getType() == types::TY_Nothing;
5104 nullptr, SingleDeviceOutput ? DDep : DDeps);
5105 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5111 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5121 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5127 llvm_unreachable(
"link action invalid here.");
5129 llvm_unreachable(
"ifsmerge action invalid here.");
5134 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5135 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5136 OutputTy = types::TY_Dependencies;
5141 if (!Args.hasFlag(options::OPT_frewrite_includes,
5142 options::OPT_fno_rewrite_includes,
false) &&
5143 !Args.hasFlag(options::OPT_frewrite_imports,
5144 options::OPT_fno_rewrite_imports,
false) &&
5145 !Args.hasFlag(options::OPT_fdirectives_only,
5146 options::OPT_fno_directives_only,
false) &&
5150 "Cannot preprocess this input type!");
5156 if (Args.hasArg(options::OPT_extract_api))
5163 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5164 (Input->
getType() == driver::types::TY_CXXModule ||
5165 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5166 !Args.getLastArg(options::OPT__precompile))
5171 "Cannot precompile this input type!");
5175 const char *ModName =
nullptr;
5176 if (OutputTy == types::TY_PCH) {
5177 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5178 ModName = A->getValue();
5180 OutputTy = types::TY_ModuleFile;
5183 if (Args.hasArg(options::OPT_fsyntax_only)) {
5185 OutputTy = types::TY_Nothing;
5191 if (Args.hasArg(options::OPT_fsyntax_only))
5193 if (Args.hasArg(options::OPT_rewrite_objc))
5195 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5197 types::TY_RewrittenLegacyObjC);
5198 if (Args.hasArg(options::OPT__analyze))
5200 if (Args.hasArg(options::OPT_emit_ast))
5202 if (Args.hasArg(options::OPT_emit_cir))
5204 if (Args.hasArg(options::OPT_module_file_info))
5206 if (Args.hasArg(options::OPT_verify_pch))
5208 if (Args.hasArg(options::OPT_extract_api))
5216 Args.hasFlag(options::OPT_offload_new_driver,
5217 options::OPT_no_offload_new_driver,
false) &&
5223 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5224 !Args.hasArg(options::OPT_emit_llvm))
5225 Output = types::TY_PP_Asm;
5226 else if (Args.hasArg(options::OPT_S))
5227 Output = types::TY_LTO_IR;
5229 Output = types::TY_LTO_BC;
5234 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5237 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5238 options::OPT_no_use_spirv_backend,
5246 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5248 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5250 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5252 if (Args.hasArg(options::OPT_emit_llvm) ||
5258 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5259 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5261 (Args.hasFlag(options::OPT_offload_new_driver,
5262 options::OPT_no_offload_new_driver,
false) &&
5269 Args.hasArg(options::OPT_S) &&
5273 !Args.hasFlag(options::OPT_offload_new_driver,
5274 options::OPT_no_offload_new_driver,
5277 : types::TY_LLVM_BC;
5290 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5299 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5303 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5305 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5325 unsigned NumOutputs = 0;
5326 unsigned NumIfsOutputs = 0;
5327 for (
const Action *A :
C.getActions()) {
5330 if (A->
getType() == types::TY_DX_CONTAINER &&
5335 if (A->
getType() != types::TY_Nothing &&
5337 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5339 0 == NumIfsOutputs++) ||
5344 A->
getType() == types::TY_Nothing &&
5345 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5346 NumOutputs += A->
size();
5349 if (NumOutputs > 1) {
5350 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5351 FinalOutput =
nullptr;
5355 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5359 if (RawTriple.isOSBinFormatMachO())
5360 for (
const Arg *A :
C.getArgs())
5361 if (A->getOption().matches(options::OPT_arch))
5365 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5366 for (
Action *A :
C.getActions()) {
5373 const char *LinkingOutput =
nullptr;
5376 LinkingOutput = FinalOutput->getValue();
5385 LinkingOutput, CachedResults,
5392 for (
auto &J :
C.getJobs())
5393 J.InProcess =
false;
5396 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5397 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5402 const char *LinkingOutput =
nullptr;
5404 LinkingOutput = FinalOutput->getValue();
5411 using namespace llvm;
5414 <<
"output=" << LinkingOutput;
5415 outs() <<
", total="
5416 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5418 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5419 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5423 llvm::raw_string_ostream Out(Buffer);
5424 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5427 llvm::sys::printArg(Out, LinkingOutput,
true);
5428 Out <<
',' << ProcStat->TotalTime.count() <<
','
5429 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5434 llvm::sys::fs::OF_Append |
5435 llvm::sys::fs::OF_Text);
5440 llvm::errs() <<
"ERROR: Cannot lock file "
5442 <<
toString(L.takeError()) <<
"\n";
5453 bool ReportUnusedArguments =
5454 !Diags.hasErrorOccurred() &&
5455 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5458 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5460 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5463 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5464 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5466 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5470 return strstr(J.getCreator().getShortName(),
"assembler");
5472 for (Arg *A :
C.getArgs()) {
5476 if (!A->isClaimed()) {
5482 const Option &Opt = A->getOption();
5483 if (Opt.getKind() == Option::FlagClass) {
5484 bool DuplicateClaimed =
false;
5486 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5487 if (AA->isClaimed()) {
5488 DuplicateClaimed =
true;
5493 if (DuplicateClaimed)
5499 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5501 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5506 !
C.getActions().empty()) {
5507 Diag(diag::err_drv_unsupported_opt_for_target)
5509 }
else if (ReportUnusedArguments) {
5510 Diag(clang::diag::warn_drv_unused_argument)
5511 << A->getAsString(
C.getArgs());
5521class ToolSelector final {
5532 bool IsHostSelector;
5543 bool CanBeCollapsed =
true) {
5545 if (Inputs.size() != 1)
5548 Action *CurAction = *Inputs.begin();
5549 if (CanBeCollapsed &&
5555 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5559 if (!IsHostSelector) {
5560 if (OA->hasSingleDeviceDependence(
true)) {
5562 OA->getSingleDeviceDependence(
true);
5563 if (CanBeCollapsed &&
5566 SavedOffloadAction.push_back(OA);
5567 return dyn_cast<JobAction>(CurAction);
5569 }
else if (OA->hasHostDependence()) {
5570 CurAction = OA->getHostDependence();
5571 if (CanBeCollapsed &&
5574 SavedOffloadAction.push_back(OA);
5575 return dyn_cast<JobAction>(CurAction);
5580 return dyn_cast<JobAction>(CurAction);
5584 bool canCollapseAssembleAction()
const {
5585 return TC.useIntegratedAs() && !SaveTemps &&
5586 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5587 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5588 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5589 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5593 bool canCollapsePreprocessorAction()
const {
5594 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5595 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5596 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5601 struct JobActionInfo final {
5603 const JobAction *JA =
nullptr;
5611 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5612 ArrayRef<JobActionInfo> &ActionInfo,
5613 unsigned ElementNum) {
5614 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5615 for (
unsigned I = 0; I < ElementNum; ++I)
5616 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5617 ActionInfo[I].SavedOffloadAction.end());
5630 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5633 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5635 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5636 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5637 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5638 if (!AJ || !BJ || !CJ)
5642 const Tool *
T = TC.SelectTool(*CJ);
5649 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5655 const Tool *BT = TC.SelectTool(*BJ);
5660 if (!
T->hasIntegratedAssembler())
5663 Inputs = CJ->getInputs();
5664 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5668 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5671 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5673 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5674 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5679 const Tool *
T = TC.SelectTool(*BJ);
5683 if (!
T->hasIntegratedAssembler())
5686 Inputs = BJ->getInputs();
5687 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5691 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5694 if (ActionInfo.size() < 2)
5696 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5697 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5701 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5702 for (
auto &Input : AI.JA->getInputs())
5713 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5714 if (SaveTemps && !InputIsBitcode)
5718 const Tool *
T = TC.SelectTool(*CJ);
5725 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5731 Inputs = CJ->getInputs();
5732 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5741 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5743 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5749 for (Action *A : Inputs) {
5750 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5752 NewInputs.push_back(A);
5758 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5759 PreprocessJobOffloadActions.end());
5760 NewInputs.append(PJ->input_begin(), PJ->input_end());
5766 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5768 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5770 assert(BaseAction &&
"Invalid base action.");
5786 SmallVector<JobActionInfo, 5> ActionChain(1);
5787 ActionChain.back().JA = BaseAction;
5788 while (ActionChain.back().JA) {
5789 const Action *CurAction = ActionChain.back().JA;
5792 ActionChain.resize(ActionChain.size() + 1);
5793 JobActionInfo &AI = ActionChain.back();
5797 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5801 ActionChain.pop_back();
5809 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5810 CollapsedOffloadAction);
5812 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5814 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5820 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5832 StringRef BoundArch,
5834 std::string TriplePlusArch = TC->
getTriple().normalize();
5835 if (!BoundArch.empty()) {
5836 TriplePlusArch +=
"-";
5837 TriplePlusArch += BoundArch;
5839 TriplePlusArch +=
"-";
5841 return TriplePlusArch;
5846 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5847 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5850 std::pair<const Action *, std::string> ActionTC = {
5852 auto CachedResult = CachedResults.find(ActionTC);
5853 if (CachedResult != CachedResults.end()) {
5854 return CachedResult->second;
5857 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5858 CachedResults, TargetDeviceOffloadKind);
5859 CachedResults[ActionTC] =
Result;
5864 const JobAction *JA,
const char *BaseInput,
5867 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5871 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5872 Path = A->getValue();
5873 if (llvm::sys::fs::is_directory(Path)) {
5875 llvm::sys::path::replace_extension(Tmp,
"json");
5876 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5879 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5882 Path = DumpDir->getValue();
5883 Path += llvm::sys::path::filename(BaseInput);
5885 Path = Result.getFilename();
5887 llvm::sys::path::replace_extension(Path,
"json");
5889 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5890 C.addTimeTraceFile(ResultFile, JA);
5891 C.addResultFile(ResultFile, JA);
5896 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5897 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5900 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5903 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5904 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5936 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5938 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5939 const char *DepBoundArch) {
5942 LinkingOutput, CachedResults,
5952 OA->doOnEachDependence(
5953 BuildingForOffloadDevice,
5954 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5956 C, DepA, DepTC, DepBoundArch,
false,
5957 !!DepBoundArch, LinkingOutput, CachedResults,
5961 A = BuildingForOffloadDevice
5962 ? OA->getSingleDeviceDependence(
true)
5963 : OA->getHostDependence();
5967 std::pair<const Action *, std::string> ActionTC = {
5968 OA->getHostDependence(),
5970 auto It = CachedResults.find(ActionTC);
5971 if (It != CachedResults.end()) {
5973 Inputs.append(OffloadDependencesInputInfo);
5978 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5981 const Arg &Input = IA->getInputArg();
5983 if (Input.getOption().matches(options::OPT_INPUT)) {
5984 const char *
Name = Input.getValue();
5987 return {InputInfo(A, &Input,
"")};
5990 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5991 const ToolChain *TC;
5994 if (!ArchName.empty())
5995 TC = &getToolChain(
C.getArgs(),
5997 C.getArgs(), ArchName));
5999 TC = &
C.getDefaultToolChain();
6002 MultipleArchs, LinkingOutput, CachedResults,
6003 TargetDeviceOffloadKind);
6014 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
6017 return {InputInfo()};
6021 for (
const auto *OA : CollapsedOffloadActions)
6023 BuildingForOffloadDevice,
6024 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6026 C, DepA, DepTC, DepBoundArch,
false,
6027 !!DepBoundArch, LinkingOutput, CachedResults,
6033 for (
const Action *Input : Inputs) {
6037 bool SubJobAtTopLevel =
6040 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6045 const char *BaseInput = InputInfos[0].getBaseInput();
6046 for (
auto &Info : InputInfos) {
6047 if (Info.isFilename()) {
6048 BaseInput = Info.getBaseInput();
6055 if (JA->
getType() == types::TY_dSYM)
6056 BaseInput = InputInfos[0].getFilename();
6059 if (!OffloadDependencesInputInfo.empty())
6060 InputInfos.append(OffloadDependencesInputInfo.begin(),
6061 OffloadDependencesInputInfo.end());
6064 llvm::Triple EffectiveTriple;
6065 const ToolChain &ToolTC =
T->getToolChain();
6066 const ArgList &Args =
6068 if (InputInfos.size() != 1) {
6072 EffectiveTriple = llvm::Triple(
6075 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6080 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6084 for (
auto &UI : UA->getDependentActionsInfo()) {
6086 "Unbundling with no offloading??");
6093 UI.DependentOffloadKind,
6094 UI.DependentToolChain->getTriple().normalize(),
6096 auto CurI = InputInfo(
6105 UnbundlingResults.push_back(CurI);
6114 Arch = UI.DependentBoundArch;
6119 UI.DependentOffloadKind)}] = {
6125 std::pair<const Action *, std::string> ActionTC = {
6127 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6128 "Result does not exist??");
6129 Result = CachedResults[ActionTC].front();
6130 }
else if (JA->
getType() == types::TY_Nothing)
6131 Result = {InputInfo(A, BaseInput)};
6141 AtTopLevel, MultipleArchs,
6144 if (
T->canEmitIR() && OffloadingPrefix.empty())
6149 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
6150 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6151 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6152 llvm::errs() << InputInfos[i].getAsString();
6154 llvm::errs() <<
", ";
6156 if (UnbundlingResults.empty())
6157 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6159 llvm::errs() <<
"], outputs: [";
6160 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6161 llvm::errs() << UnbundlingResults[i].getAsString();
6163 llvm::errs() <<
", ";
6165 llvm::errs() <<
"] \n";
6168 if (UnbundlingResults.empty())
6169 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6171 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6172 Args, LinkingOutput);
6178 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6179 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6191 if (ArgValue.empty()) {
6193 Filename = BaseName;
6194 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6196 llvm::sys::path::append(Filename, BaseName);
6199 if (!llvm::sys::path::has_extension(ArgValue)) {
6204 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6209 llvm::sys::path::replace_extension(Filename, Extension);
6212 return Args.MakeArgString(Filename.c_str());
6227 StringRef Suffix,
bool MultipleArchs,
6228 StringRef BoundArch,
6229 bool NeedUniqueDirectory)
const {
6231 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6232 std::optional<std::string> CrashDirectory =
6234 ? std::string(A->getValue())
6235 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6236 if (CrashDirectory) {
6237 if (!
getVFS().exists(*CrashDirectory))
6238 llvm::sys::fs::create_directories(*CrashDirectory);
6240 llvm::sys::path::append(Path, Prefix);
6241 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6242 if (std::error_code EC =
6243 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6244 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6248 if (MultipleArchs && !BoundArch.empty()) {
6249 if (NeedUniqueDirectory) {
6251 llvm::sys::path::append(TmpName,
6252 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6262 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6277 const char *BaseInput) {
6279 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6280 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6285 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6289 const char *BaseInput,
6290 StringRef OrigBoundArch,
bool AtTopLevel,
6292 StringRef OffloadingPrefix)
const {
6295 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6298 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6299 return C.addResultFile(FinalOutput->getValue(), &JA);
6303 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6305 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6307 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6308 NameArg = A->getValue();
6309 return C.addResultFile(
6319 if (JA.
getType() == types::TY_ModuleFile &&
6320 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6324 if (JA.
getType() == types::TY_PP_Asm &&
6325 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6326 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6329 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6332 if ((JA.
getType() == types::TY_Object &&
6333 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6334 JA.
getType() == types::TY_DX_CONTAINER) {
6335 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6339 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6341 C.getDefaultToolChain());
6344 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6345 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6346 StringRef
Name = llvm::sys::path::filename(BaseInput);
6347 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6353 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6354 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6358 if (JA.
getType() == types::TY_PP_Asm &&
6359 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6360 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6362 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6363 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6364 return C.addResultFile(
6369 if (JA.
getType() == types::TY_API_INFO &&
6370 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6371 C.getArgs().hasArg(options::OPT_o))
6372 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6373 <<
C.getArgs().getLastArgValue(options::OPT_o);
6380 bool SpecifiedModuleOutput =
6381 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6382 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6383 if (MultipleArchs && SpecifiedModuleOutput)
6384 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6389 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6390 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6396 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6398 StringRef
Name = llvm::sys::path::filename(BaseInput);
6399 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6400 const char *Suffix =
6405 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6406 bool NeedUniqueDirectory =
6409 Triple.isOSDarwin();
6410 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6411 NeedUniqueDirectory);
6420 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6425 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6426 llvm::sys::path::filename(BasePath));
6427 BaseName = ExternalPath;
6429 BaseName = BasePath;
6431 BaseName = llvm::sys::path::filename(BasePath);
6434 const char *NamedOutput;
6436 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6437 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6441 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6445 }
else if (JA.
getType() == types::TY_Image &&
6446 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6447 options::OPT__SLASH_o)) {
6451 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6455 }
else if (JA.
getType() == types::TY_Image) {
6465 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6466 options::OPT_fno_gpu_rdc,
false);
6468 if (UseOutExtension) {
6470 llvm::sys::path::replace_extension(Output,
"");
6472 Output += OffloadingPrefix;
6473 if (MultipleArchs && !BoundArch.empty()) {
6475 Output.append(BoundArch);
6477 if (UseOutExtension)
6479 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6482 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6483 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6484 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6487 .getLastArg(options::OPT__SLASH_o)
6492 const char *Suffix =
6494 assert(Suffix &&
"All types used for output should have a suffix.");
6496 std::string::size_type End = std::string::npos;
6498 End = BaseName.rfind(
'.');
6500 Suffixed += OffloadingPrefix;
6501 if (MultipleArchs && !BoundArch.empty()) {
6503 Suffixed.append(BoundArch);
6508 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6509 const llvm::opt::DerivedArgList &Args) {
6516 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6524 bool IsLinkerWrapper =
6526 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6527 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6528 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6530 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6534 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6538 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6539 JA.
getType() != types::TY_PCH) {
6540 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6542 llvm::sys::path::remove_filename(TempPath);
6543 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6544 llvm::sys::path::append(TempPath, OutputFileName);
6545 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6551 bool SameFile =
false;
6553 llvm::sys::fs::current_path(
Result);
6554 llvm::sys::path::append(
Result, BaseName);
6555 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6558 StringRef
Name = llvm::sys::path::filename(BaseInput);
6559 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6563 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6569 llvm::sys::path::remove_filename(BasePath);
6570 if (BasePath.empty())
6571 BasePath = NamedOutput;
6573 llvm::sys::path::append(BasePath, NamedOutput);
6574 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6577 return C.addResultFile(NamedOutput, &JA);
6583 -> std::optional<std::string> {
6586 for (
const auto &
Dir : P) {
6590 llvm::sys::path::append(P,
Name);
6591 if (llvm::sys::fs::exists(Twine(P)))
6592 return std::string(P);
6594 return std::nullopt;
6601 llvm::sys::path::append(R,
Name);
6602 if (llvm::sys::fs::exists(Twine(R)))
6603 return std::string(R);
6606 llvm::sys::path::append(P,
Name);
6607 if (llvm::sys::fs::exists(Twine(P)))
6608 return std::string(P);
6611 llvm::sys::path::append(D,
"..",
Name);
6612 if (llvm::sys::fs::exists(Twine(D)))
6613 return std::string(D);
6622 llvm::sys::path::append(R2,
"..",
"..",
Name);
6623 if (llvm::sys::fs::exists(Twine(R2)))
6624 return std::string(R2);
6626 return std::string(
Name);
6629void Driver::generatePrefixedToolNames(
6633 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6634 Names.emplace_back(
Tool);
6638 llvm::sys::path::append(Dir, Name);
6639 if (llvm::sys::fs::can_execute(Twine(Dir)))
6641 llvm::sys::path::remove_filename(Dir);
6647 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6652 if (llvm::sys::fs::is_directory(PrefixDir)) {
6655 return std::string(P);
6658 if (llvm::sys::fs::can_execute(Twine(P)))
6659 return std::string(P);
6664 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6672 for (
const auto &Path : List) {
6675 return std::string(P);
6679 if (llvm::ErrorOr<std::string> P =
6680 llvm::sys::findProgramByName(TargetSpecificExecutable))
6684 return std::string(
Name);
6689 std::string error =
"<NOT PRESENT>";
6691 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6696 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6713 llvm::sys::path::remove_filename(path);
6714 llvm::sys::path::append(path,
"libc++.modules.json");
6715 if (TC.
getVFS().exists(path))
6716 return static_cast<std::string
>(path);
6721 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6724 return evaluate(
"libc++.a").value_or(error);
6728 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6732 llvm::sys::path::remove_filename(path);
6733 llvm::sys::path::append(path,
"libstdc++.modules.json");
6734 if (TC.
getVFS().exists(path))
6735 return static_cast<std::string
>(path);
6740 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6743 return evaluate(
"libstdc++.a").value_or(error);
6752 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6754 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6758 return std::string(Path);
6763 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6765 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6769 return std::string(Path);
6774 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6778 Output = FpArg->getValue();
6782 if (!llvm::sys::path::has_extension(Output))
6785 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6786 Output = YcArg->getValue();
6789 llvm::sys::path::replace_extension(Output,
".pch");
6791 return std::string(Output);
6794const ToolChain &Driver::getOffloadToolChain(
6796 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6797 std::unique_ptr<ToolChain> &TC =
6798 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6799 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6801 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6804 switch (
Target.getOS()) {
6805 case llvm::Triple::CUDA:
6806 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6809 case llvm::Triple::AMDHSA:
6811 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6814 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6823 switch (
Target.getArch()) {
6824 case llvm::Triple::spir:
6825 case llvm::Triple::spir64:
6826 case llvm::Triple::spirv:
6827 case llvm::Triple::spirv32:
6828 case llvm::Triple::spirv64:
6831 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6835 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6839 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6843 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6857 return getToolChain(Args,
Target);
6861const ToolChain &Driver::getToolChain(
const ArgList &Args,
6862 const llvm::Triple &
Target)
const {
6864 auto &TC = ToolChains[
Target.str()];
6866 switch (
Target.getOS()) {
6867 case llvm::Triple::AIX:
6868 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6870 case llvm::Triple::Haiku:
6871 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6873 case llvm::Triple::Darwin:
6874 case llvm::Triple::MacOSX:
6875 case llvm::Triple::IOS:
6876 case llvm::Triple::TvOS:
6877 case llvm::Triple::WatchOS:
6878 case llvm::Triple::XROS:
6879 case llvm::Triple::DriverKit:
6880 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6882 case llvm::Triple::DragonFly:
6883 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6885 case llvm::Triple::OpenBSD:
6886 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6888 case llvm::Triple::NetBSD:
6889 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6891 case llvm::Triple::FreeBSD:
6893 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6896 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6898 case llvm::Triple::Linux:
6899 case llvm::Triple::ELFIAMCU:
6900 if (
Target.getArch() == llvm::Triple::hexagon)
6901 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6903 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6904 !
Target.hasEnvironment())
6905 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6908 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6910 else if (
Target.getArch() == llvm::Triple::ve)
6911 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6912 else if (
Target.isOHOSFamily())
6913 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6914 else if (
Target.isWALI())
6915 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6917 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6919 case llvm::Triple::Fuchsia:
6920 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6922 case llvm::Triple::Managarm:
6923 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6925 case llvm::Triple::Solaris:
6926 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6928 case llvm::Triple::CUDA:
6929 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6931 case llvm::Triple::AMDHSA: {
6932 if (
Target.getArch() == llvm::Triple::spirv64) {
6933 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6938 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6940 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6945 case llvm::Triple::AMDPAL:
6946 case llvm::Triple::Mesa3D:
6947 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6949 case llvm::Triple::UEFI:
6950 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6952 case llvm::Triple::Win32:
6953 switch (
Target.getEnvironment()) {
6955 if (
Target.isOSBinFormatELF())
6956 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6957 else if (
Target.isOSBinFormatMachO())
6958 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6960 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6962 case llvm::Triple::GNU:
6963 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6965 case llvm::Triple::Cygnus:
6966 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6968 case llvm::Triple::Itanium:
6969 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6972 case llvm::Triple::MSVC:
6973 case llvm::Triple::UnknownEnvironment:
6974 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6975 .starts_with_insensitive(
"bfd"))
6976 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6980 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6984 case llvm::Triple::PS4:
6985 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6987 case llvm::Triple::PS5:
6988 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6990 case llvm::Triple::Hurd:
6991 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6993 case llvm::Triple::LiteOS:
6994 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6996 case llvm::Triple::ZOS:
6997 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6999 case llvm::Triple::Vulkan:
7000 case llvm::Triple::ShaderModel:
7001 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7006 switch (
Target.getArch()) {
7007 case llvm::Triple::tce:
7008 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7010 case llvm::Triple::tcele:
7011 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7013 case llvm::Triple::hexagon:
7014 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7017 case llvm::Triple::lanai:
7018 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7020 case llvm::Triple::xcore:
7021 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7023 case llvm::Triple::wasm32:
7024 case llvm::Triple::wasm64:
7025 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7027 case llvm::Triple::avr:
7028 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7030 case llvm::Triple::msp430:
7031 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7033 case llvm::Triple::riscv32:
7034 case llvm::Triple::riscv64:
7035 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7037 case llvm::Triple::ve:
7038 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7040 case llvm::Triple::spirv32:
7041 case llvm::Triple::spirv64:
7042 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7044 case llvm::Triple::csky:
7045 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7049 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7050 else if (
Target.isOSBinFormatELF())
7051 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7052 else if (
Target.isAppleMachO())
7053 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7054 else if (
Target.isOSBinFormatMachO())
7055 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7057 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7067 if (JA.
size() != 1 ||
7082 if (JA.
size() != 1 ||
7096 if (Args.hasArg(options::OPT_emit_static_lib))
7107 unsigned &Micro,
bool &HadExtra) {
7110 Major = Minor = Micro = 0;
7114 if (Str.consumeInteger(10, Major))
7118 if (!Str.consume_front(
"."))
7121 if (Str.consumeInteger(10, Minor))
7125 if (!Str.consume_front(
"."))
7128 if (Str.consumeInteger(10, Micro))
7146 unsigned CurDigit = 0;
7147 while (CurDigit < Digits.size()) {
7149 if (Str.consumeInteger(10, Digit))
7151 Digits[CurDigit] = Digit;
7154 if (!Str.consume_front(
"."))
7163llvm::opt::Visibility
7164Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7177const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7193 llvm_unreachable(
"Unhandled Mode");
7197 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7202 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7203 options::OPT_fno_save_optimization_record,
false))
7207 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7208 options::OPT_fno_save_optimization_record,
false))
7212 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7213 options::OPT_fno_save_optimization_record,
false))
7217 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7218 options::OPT_fno_save_optimization_record,
false))
7225 static StringRef OptName =
7227 llvm::StringRef Opt;
7228 for (StringRef Arg : Args) {
7229 if (!Arg.starts_with(OptName))
7235 return Opt.consume_front(OptName) ? Opt :
"";
7242 llvm::BumpPtrAllocator &Alloc,
7243 llvm::vfs::FileSystem *FS) {
7252 for (
const char *F : Args) {
7253 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7255 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7256 RSPQuoting = Windows;
7262 bool MarkEOLs = ClangCLMode;
7264 llvm::cl::TokenizerCallback Tokenizer;
7265 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7266 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7268 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7270 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7273 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7274 ECtx.setMarkEOLs(MarkEOLs);
7278 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7282 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7283 [](
const char *A) {
return A !=
nullptr; });
7284 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7287 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7288 Args.resize(newEnd - Args.begin());
7292 return llvm::Error::success();
7296 return SavedStrings.insert(S).first->getKeyData();
7330 llvm::StringSet<> &SavedStrings) {
7333 if (Edit[0] ==
'^') {
7334 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7335 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7336 Args.insert(Args.begin() + 1, Str);
7337 }
else if (Edit[0] ==
'+') {
7338 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7339 OS <<
"### Adding argument " << Str <<
" at end\n";
7340 Args.push_back(Str);
7341 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7342 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7343 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7344 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7345 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7347 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7349 if (Args[i] ==
nullptr)
7351 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7353 if (Repl != Args[i]) {
7354 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7358 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7359 auto Option = Edit.substr(1);
7360 for (
unsigned i = 1; i < Args.size();) {
7361 if (Option == Args[i]) {
7362 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7363 Args.erase(Args.begin() + i);
7364 if (Edit[0] ==
'X') {
7365 if (i < Args.size()) {
7366 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7367 Args.erase(Args.begin() + i);
7369 OS <<
"### Invalid X edit, end of command line!\n";
7374 }
else if (Edit[0] ==
'O') {
7375 for (
unsigned i = 1; i < Args.size();) {
7376 const char *A = Args[i];
7380 if (A[0] ==
'-' && A[1] ==
'O' &&
7381 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7382 (
'0' <= A[2] && A[2] <=
'9'))))) {
7383 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7384 Args.erase(Args.begin() + i);
7388 OS <<
"### Adding argument " << Edit <<
" at end\n";
7389 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7391 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7396 const char *OverrideStr,
7397 llvm::StringSet<> &SavedStrings,
7398 StringRef EnvVar, raw_ostream *OS) {
7400 OS = &llvm::nulls();
7402 if (OverrideStr[0] ==
'#') {
7404 OS = &llvm::nulls();
7407 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7411 const char *S = OverrideStr;
7413 const char *End = ::strchr(S,
' ');
7415 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.