59#include "clang/Config/config.h"
72#include "llvm/ADT/ArrayRef.h"
73#include "llvm/ADT/STLExtras.h"
74#include "llvm/ADT/SmallSet.h"
75#include "llvm/ADT/SmallVector.h"
76#include "llvm/ADT/StringExtras.h"
77#include "llvm/ADT/StringRef.h"
78#include "llvm/ADT/StringSet.h"
79#include "llvm/ADT/StringSwitch.h"
80#include "llvm/Config/llvm-config.h"
81#include "llvm/MC/TargetRegistry.h"
82#include "llvm/Option/Arg.h"
83#include "llvm/Option/ArgList.h"
84#include "llvm/Option/OptSpecifier.h"
85#include "llvm/Option/OptTable.h"
86#include "llvm/Option/Option.h"
87#include "llvm/Support/CommandLine.h"
88#include "llvm/Support/ErrorHandling.h"
89#include "llvm/Support/ExitCodes.h"
90#include "llvm/Support/FileSystem.h"
91#include "llvm/Support/FileUtilities.h"
92#include "llvm/Support/FormatVariadic.h"
93#include "llvm/Support/IOSandbox.h"
94#include "llvm/Support/JSON.h"
95#include "llvm/Support/MD5.h"
96#include "llvm/Support/Path.h"
97#include "llvm/Support/PrettyStackTrace.h"
98#include "llvm/Support/Process.h"
99#include "llvm/Support/Program.h"
100#include "llvm/Support/Regex.h"
101#include "llvm/Support/StringSaver.h"
102#include "llvm/Support/VirtualFileSystem.h"
103#include "llvm/Support/raw_ostream.h"
104#include "llvm/TargetParser/Host.h"
105#include "llvm/TargetParser/RISCVISAInfo.h"
118using namespace clang;
121template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
122 return llvm::any_of(Args, [&](Arg *A) {
123 return (A->getOption().matches(options::OPT_x) &&
125 (A->getOption().
getKind() == Option::InputClass &&
126 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
128 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
134 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
135 StringRef UseCUIDStr = A->getValue();
136 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
137 .Case(
"hash", Kind::Hash)
138 .Case(
"random", Kind::Random)
139 .Case(
"none", Kind::None)
140 .Default(Kind::Invalid);
141 if (UseCUID == Kind::Invalid)
142 D.Diag(clang::diag::err_drv_invalid_value)
143 << A->getAsString(Args) << UseCUIDStr;
146 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
147 if (!FixedCUID.empty())
152 llvm::opt::DerivedArgList &Args)
const {
153 std::string CUID = FixedCUID.str();
156 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
160 llvm::MD5::MD5Result
Hash;
161 Hasher.update(InputFile);
162 for (
auto *A : Args) {
163 if (A->getOption().matches(options::OPT_INPUT))
165 Hasher.update(A->getAsString(Args));
168 CUID = llvm::utohexstr(
Hash.low(),
true);
176 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
177 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
184 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
185 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
186 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
189 this->VFS = llvm::vfs::getRealFileSystem();
194 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
197 llvm::sys::path::append(P,
SysRoot);
201#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
202 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
206 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
207 llvm::sys::path::remove_dots(configFileDir,
true);
211#if defined(CLANG_CONFIG_FILE_USER_DIR)
214 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
223void Driver::setDriverMode(StringRef
Value) {
224 static StringRef OptName =
225 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
226 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
227 .Case(
"gcc", GCCMode)
228 .Case(
"g++", GXXMode)
229 .Case(
"cpp", CPPMode)
231 .Case(
"flang", FlangMode)
232 .Case(
"dxc", DXCMode)
236 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
241 bool &ContainsError)
const {
242 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
243 ContainsError =
false;
245 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
246 unsigned MissingArgIndex, MissingArgCount;
247 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
248 MissingArgCount, VisibilityMask);
251 if (MissingArgCount) {
252 Diag(diag::err_drv_missing_argument)
253 << Args.getArgString(MissingArgIndex) << MissingArgCount;
255 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
260 for (
const Arg *A : Args) {
262 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
263 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
270 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
271 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
272 ContainsError |= Diags.getDiagnosticLevel(
273 diag::warn_drv_empty_joined_argument,
278 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
280 auto ArgString = A->getAsString(Args);
282 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
284 if (
getOpts().findExact(ArgString, Nearest,
286 DiagID = diag::err_drv_unknown_argument_with_suggestion;
287 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
289 DiagID = diag::err_drv_unknown_argument;
290 Diags.Report(DiagID) << ArgString;
293 llvm::opt::Visibility(
295 DiagID = diag::err_drv_unknown_argument_with_suggestion;
296 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
298 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
299 : diag::err_drv_unknown_argument;
300 Diags.Report(DiagID) << ArgString;
304 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
305 : diag::err_drv_unknown_argument_with_suggestion;
306 Diags.Report(DiagID) << ArgString << Nearest;
308 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
312 for (
const Arg *A : Args.filtered(options::OPT_o)) {
313 if (ArgStrings[A->getIndex()] == A->getSpelling())
317 std::string ArgString = ArgStrings[A->getIndex()];
319 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
320 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
321 << A->getAsString(Args) << Nearest;
331 Arg **FinalPhaseArg)
const {
332 Arg *PhaseArg =
nullptr;
336 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
337 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
338 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
339 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
346 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
348 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
349 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
350 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
351 options::OPT_fmodule_header_EQ))) {
354 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
357 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
361 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
368 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
375 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
383 *FinalPhaseArg = PhaseArg;
391 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
392 llvm::sys::fs::OF_Text);
393 llvm::FileRemover OutputRemover(OutputFile.c_str());
394 std::optional<llvm::StringRef> Redirects[] = {
400 std::string ErrorMessage;
401 int SecondsToWait = 60;
402 if (std::optional<std::string> Str =
403 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
404 if (!llvm::to_integer(*Str, SecondsToWait))
405 return llvm::createStringError(std::error_code(),
406 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
407 "an integer, got '" +
409 SecondsToWait = std::max(SecondsToWait, 0);
411 StringRef Executable = Args[0];
412 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
414 return llvm::createStringError(std::error_code(),
415 Executable +
": " + ErrorMessage);
417 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
418 llvm::MemoryBuffer::getFile(OutputFile.c_str());
420 return llvm::createStringError(OutputBuf.getError(),
421 "Failed to read stdout of " + Executable +
422 ": " + OutputBuf.getError().message());
423 return std::move(*OutputBuf);
427 StringRef
Value,
bool Claim) {
428 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
429 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
430 Args.AddSynthesizedArg(A);
436DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
437 const llvm::opt::OptTable &Opts =
getOpts();
438 DerivedArgList *DAL =
new DerivedArgList(Args);
440 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
441 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
442 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
443 bool IgnoreUnused =
false;
444 for (Arg *A : Args) {
448 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
452 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
453 IgnoreUnused =
false;
463 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
464 A->getOption().matches(options::OPT_Xlinker)) &&
465 A->containsValue(
"--no-demangle")) {
467 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
470 for (StringRef Val : A->getValues())
471 if (Val !=
"--no-demangle")
472 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
480 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
481 A->getNumValues() > 0 &&
482 (A->getValue(0) == StringRef(
"-MD") ||
483 A->getValue(0) == StringRef(
"-MMD"))) {
485 if (A->getValue(0) == StringRef(
"-MD"))
486 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
488 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
489 if (A->getNumValues() == 2)
490 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
495 if (A->getOption().matches(options::OPT_l)) {
496 StringRef
Value = A->getValue();
499 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
501 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
506 if (
Value ==
"cc_kext") {
507 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
513 if (A->getOption().matches(options::OPT__DASH_DASH)) {
515 for (StringRef Val : A->getValues())
524 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
525 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
528 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
529 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
533#if defined(HOST_LINK_VERSION)
534 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
535 strlen(HOST_LINK_VERSION) > 0) {
536 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
538 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
546 StringRef ArgTarget) {
548 static bool BeSilent =
false;
549 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
550 return ((v < 2) || ((v == 2) && (r < 4)));
554 if (ArgTarget.equals_insensitive(
"CURRENT")) {
558 unsigned int Version = 0;
559 unsigned int Release = 0;
560 unsigned int Modification = 0;
562 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
563 llvm::Regex HexRegex(
566 "([0-9a-fA-F][0-9a-fA-F])"
567 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
570 if (ZOsvRegex.match(ArgTarget, &Matches)) {
571 Matches[1].getAsInteger(10, Version);
572 Matches[2].getAsInteger(10, Release);
574 if (IsTooOldToBeSupported(Version, Release)) {
576 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
579 }
else if (HexRegex.match(ArgTarget, &Matches)) {
580 Matches[1].getAsInteger(16, Version);
581 Matches[2].getAsInteger(16, Release);
582 Matches[3].getAsInteger(16, Modification);
583 if (IsTooOldToBeSupported(Version, Release)) {
585 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
591 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
596 llvm::VersionTuple
V(Version, Release, Modification);
597 llvm::VersionTuple TV =
Target.getOSVersion();
600 if (TV.empty() ||
V < TV) {
602 Str = llvm::Triple::getOSTypeName(
Target.getOS());
603 Str +=
V.getAsString();
616 StringRef TargetTriple,
618 StringRef DarwinArchName =
"") {
620 if (
const Arg *A = Args.getLastArg(options::OPT_target))
621 TargetTriple = A->getValue();
623 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
628 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
632 if (
Target.isOSBinFormatMachO()) {
634 if (!DarwinArchName.empty()) {
641 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
642 StringRef ArchName = A->getValue();
649 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
650 options::OPT_mbig_endian)) {
651 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
652 ?
Target.getLittleEndianArchVariant()
653 :
Target.getBigEndianArchVariant();
654 if (T.getArch() != llvm::Triple::UnknownArch) {
656 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
661 if (
Target.getArch() == llvm::Triple::tce)
666 if (std::optional<std::string> ObjectModeValue =
667 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
668 StringRef ObjectMode = *ObjectModeValue;
669 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
671 if (ObjectMode ==
"64") {
672 AT =
Target.get64BitArchVariant().getArch();
673 }
else if (ObjectMode ==
"32") {
674 AT =
Target.get32BitArchVariant().getArch();
676 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
679 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
685 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
686 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
689 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
691 D.
Diag(diag::err_drv_unsupported_opt_for_target)
692 << A->getAsString(Args) <<
Target.str();
695 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
696 options::OPT_m32, options::OPT_m16,
697 options::OPT_maix32, options::OPT_maix64);
699 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
701 if (A->getOption().matches(options::OPT_m64) ||
702 A->getOption().matches(options::OPT_maix64)) {
703 AT =
Target.get64BitArchVariant().getArch();
704 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
705 Target.getEnvironment() == llvm::Triple::GNUT64)
706 Target.setEnvironment(llvm::Triple::GNU);
707 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
708 Target.setEnvironment(llvm::Triple::Musl);
709 }
else if (A->getOption().matches(options::OPT_mx32) &&
710 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
711 AT = llvm::Triple::x86_64;
712 if (
Target.getEnvironment() == llvm::Triple::Musl)
713 Target.setEnvironment(llvm::Triple::MuslX32);
715 Target.setEnvironment(llvm::Triple::GNUX32);
716 }
else if (A->getOption().matches(options::OPT_m32) ||
717 A->getOption().matches(options::OPT_maix32)) {
719 D.
Diag(diag::err_drv_unsupported_opt_for_target)
720 << A->getAsString(Args) <<
Target.str();
722 AT =
Target.get32BitArchVariant().getArch();
723 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
724 Target.setEnvironment(llvm::Triple::GNU);
725 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
726 Target.setEnvironment(llvm::Triple::Musl);
728 }
else if (A->getOption().matches(options::OPT_m16) &&
729 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
730 AT = llvm::Triple::x86;
731 Target.setEnvironment(llvm::Triple::CODE16);
734 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
736 if (
Target.isWindowsGNUEnvironment())
742 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
748 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
749 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
750 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
753 if (A && !A->getOption().matches(options::OPT_m32))
754 D.
Diag(diag::err_drv_argument_not_allowed_with)
755 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
757 Target.setArch(llvm::Triple::x86);
758 Target.setArchName(
"i586");
759 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
760 Target.setEnvironmentName(
"");
761 Target.setOS(llvm::Triple::ELFIAMCU);
762 Target.setVendor(llvm::Triple::UnknownVendor);
763 Target.setVendorName(
"intel");
769 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
770 StringRef ABIName = A->getValue();
771 if (ABIName ==
"32") {
773 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
774 Target.getEnvironment() == llvm::Triple::GNUABIN32)
775 Target.setEnvironment(llvm::Triple::GNU);
776 }
else if (ABIName ==
"n32") {
778 if (
Target.getEnvironment() == llvm::Triple::GNU ||
779 Target.getEnvironment() == llvm::Triple::GNUT64 ||
780 Target.getEnvironment() == llvm::Triple::GNUABI64)
781 Target.setEnvironment(llvm::Triple::GNUABIN32);
782 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
783 Target.getEnvironment() == llvm::Triple::MuslABI64)
784 Target.setEnvironment(llvm::Triple::MuslABIN32);
785 }
else if (ABIName ==
"64") {
787 if (
Target.getEnvironment() == llvm::Triple::GNU ||
788 Target.getEnvironment() == llvm::Triple::GNUT64 ||
789 Target.getEnvironment() == llvm::Triple::GNUABIN32)
790 Target.setEnvironment(llvm::Triple::GNUABI64);
791 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
792 Target.getEnvironment() == llvm::Triple::MuslABIN32)
793 Target.setEnvironment(llvm::Triple::MuslABI64);
801 if (Args.hasArg(options::OPT_march_EQ) ||
802 Args.hasArg(options::OPT_mcpu_EQ)) {
804 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
806 if (!llvm::errorToBool(ISAInfo.takeError())) {
807 unsigned XLen = (*ISAInfo)->getXLen();
809 if (
Target.isLittleEndian())
810 Target.setArch(llvm::Triple::riscv32);
812 Target.setArch(llvm::Triple::riscv32be);
813 }
else if (XLen == 64) {
814 if (
Target.isLittleEndian())
815 Target.setArch(llvm::Triple::riscv64);
817 Target.setArch(llvm::Triple::riscv64be);
823 if (
Target.getArch() == llvm::Triple::riscv32be ||
824 Target.getArch() == llvm::Triple::riscv64be) {
825 static bool WarnedRISCVBE =
false;
826 if (!WarnedRISCVBE) {
827 D.
Diag(diag::warn_drv_riscv_be_experimental);
828 WarnedRISCVBE =
true;
839 OptSpecifier OptEq, OptSpecifier OptNeg) {
840 if (!Args.hasFlag(OptEq, OptNeg,
false))
843 const Arg *A = Args.getLastArg(OptEq);
844 StringRef LTOName = A->getValue();
852 D.
Diag(diag::err_drv_unsupported_option_argument)
853 << A->getSpelling() << A->getValue();
860void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
862 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
864 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
865 options::OPT_fno_offload_lto);
868 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
869 options::OPT_fno_openmp_target_jit,
false)) {
870 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
871 options::OPT_fno_offload_lto))
873 Diag(diag::err_drv_incompatible_options)
874 << A->getSpelling() <<
"-fopenmp-target-jit";
881 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
883 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
885 RuntimeName = A->getValue();
887 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
895 Diag(diag::err_drv_unsupported_option_argument)
896 << A->getSpelling() << A->getValue();
899 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
908 StringRef Program =
C.getArgs().getLastArgValue(
909 options::OPT_offload_arch_tool_EQ,
"offload-arch");
912 if (llvm::ErrorOr<std::string> Executable =
913 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
916 Args.push_back(
"--only=amdgpu");
918 Args.push_back(
"--only=nvptx");
919 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
922 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
927 if ((*StdoutOrErr)->getBuffer().empty()) {
928 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
934 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
936 GPUArchs.push_back(
Arch.str());
938 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
945static llvm::DenseSet<llvm::StringRef>
947 std::set<std::string> Archs;
948 for (Arg *A :
C.getInputArgs()) {
949 for (StringRef
Arch : A->getValues()) {
950 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
951 if (
Arch ==
"native") {
953 Archs.insert(Str.str());
955 Archs.insert(
Arch.str());
957 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
961 Archs.erase(
Arch.str());
966 llvm::DenseSet<llvm::StringRef> Triples;
967 for (llvm::StringRef
Arch : Archs) {
974 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
976 return llvm::DenseSet<llvm::StringRef>();
979 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
981 return llvm::DenseSet<llvm::StringRef>();
985 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
987 return llvm::DenseSet<llvm::StringRef>();
990 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
991 <<
"offload" <<
Arch;
992 return llvm::DenseSet<llvm::StringRef>();
997 Triple =
"spirv64-amd-amdhsa";
999 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
1000 ?
"nvptx64-nvidia-cuda"
1001 :
"nvptx-nvidia-cuda";
1003 Triple =
"amdgcn-amd-amdhsa";
1010 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
1011 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
1012 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
1013 C.getArgs().MakeArgString(Triple.split(
"-").first),
1014 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
1016 C.getArgs().append(A);
1017 C.getArgs().AddSynthesizedArg(A);
1018 Triples.insert(Triple);
1023 Triples.insert(
"amdgcn-amd-amdhsa");
1025 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1026 ?
"nvptx64-nvidia-cuda"
1027 :
"nvptx-nvidia-cuda");
1029 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1030 ?
"spirv64-unknown-unknown"
1031 :
"spirv32-unknown-unknown");
1034 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1035 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1042 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1043 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1045 llvm::any_of(Inputs,
1046 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1051 (llvm::any_of(Inputs,
1052 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1055 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1056 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1058 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1059 options::OPT_fno_sycl,
false);
1060 bool IsOpenMPOffloading =
1062 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1063 options::OPT_fno_openmp,
false) &&
1064 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1065 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1066 !(IsCuda || IsHIP))));
1068 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1069 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1074 for (
const auto &[Active, Kind] : ActiveKinds)
1079 if (Kinds.size() > 1) {
1080 Diag(clang::diag::err_drv_mix_offload)
1087 if (IsCuda || IsHIP)
1093 std::multiset<llvm::StringRef> Triples;
1094 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1095 std::vector<std::string> ArgValues =
1096 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1097 for (llvm::StringRef
Target : ArgValues)
1098 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1100 if (ArgValues.empty())
1101 Diag(clang::diag::warn_drv_empty_joined_argument)
1103 .getLastArg(options::OPT_offload_targets_EQ)
1104 ->getAsString(
C.getInputArgs());
1105 }
else if (Kinds.size() > 0) {
1108 Triples.insert(Derived.begin(), Derived.end());
1113 llvm::StringMap<StringRef> FoundNormalizedTriples;
1114 for (StringRef
Target : Triples) {
1119 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1127 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1128 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1129 Diag(clang::diag::err_drv_argument_not_allowed_with)
1130 << IncompatArg->getSpelling() <<
"-fsycl";
1138 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1139 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1143 std::string NormalizedName = TT.normalize();
1144 auto [TripleIt, Inserted] =
1145 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1147 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1148 <<
Target << TripleIt->second;
1152 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1153 C.getDefaultToolChain().getTriple());
1157 auto &CudaInstallation =
1159 if (CudaInstallation.isValid())
1160 CudaInstallation.WarnIfUnsupportedVersion();
1163 C.addOffloadDeviceToolChain(&TC, Kind);
1168bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1173 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1177 if (!PathLIBEnv.empty()) {
1178 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1179 if (llvm::sys::fs::is_directory(PathLIBEnv))
1180 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1181 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1182 return readConfigFile(CustomizationFile, ExpCtx);
1183 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1188 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1189 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1190 return readConfigFile(CustomizationFile, ExpCtx);
1200 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1201 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1202 Copy->getValues() = Opt->getValues();
1203 if (Opt->isClaimed())
1205 Copy->setOwnsValues(Opt->getOwnsValues());
1206 Opt->setOwnsValues(
false);
1208 if (Opt->getAlias()) {
1209 const Arg *Alias = Opt->getAlias();
1210 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1211 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1212 Args.getArgString(Index), Index);
1213 AliasCopy->getValues() = Alias->getValues();
1214 AliasCopy->setOwnsValues(
false);
1215 if (Alias->isClaimed())
1217 Copy->setAlias(std::move(AliasCopy));
1221bool Driver::readConfigFile(StringRef
FileName,
1222 llvm::cl::ExpansionContext &ExpCtx) {
1226 Diag(diag::err_drv_cannot_open_config_file)
1227 <<
FileName << Status.getError().message();
1230 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1231 Diag(diag::err_drv_cannot_open_config_file)
1232 <<
FileName <<
"not a regular file";
1237 SmallVector<const char *, 32> NewCfgFileArgs;
1238 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1239 Diag(diag::err_drv_cannot_read_config_file)
1245 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1246 for (
const char *Opt : NewCfgFileArgs) {
1248 if (Opt[0] ==
'$' && Opt[1])
1249 NewCfgTailArgs.push_back(Opt + 1);
1251 NewCfgHeadArgs.push_back(Opt);
1255 llvm::SmallString<128> CfgFileName(
FileName);
1256 llvm::sys::path::native(CfgFileName);
1257 bool ContainErrors =
false;
1258 auto NewHeadOptions = std::make_unique<InputArgList>(
1262 auto NewTailOptions = std::make_unique<InputArgList>(
1269 for (Arg *A : *NewHeadOptions)
1271 for (Arg *A : *NewTailOptions)
1274 if (!CfgOptionsHead)
1275 CfgOptionsHead = std::move(NewHeadOptions);
1278 for (
auto *Opt : *NewHeadOptions)
1282 if (!CfgOptionsTail)
1283 CfgOptionsTail = std::move(NewTailOptions);
1286 for (
auto *Opt : *NewTailOptions)
1290 ConfigFiles.push_back(std::string(CfgFileName));
1294bool Driver::loadConfigFiles() {
1295 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1296 llvm::cl::tokenizeConfigFile, &
getVFS());
1300 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1301 SmallString<128> CfgDir;
1303 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1304 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1309 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1310 SmallString<128> CfgDir;
1311 llvm::sys::fs::expand_tilde(
1312 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1313 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1322 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1325 if (loadDefaultConfigFiles(ExpCtx))
1329 SmallString<128> CfgFilePath;
1331 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1334 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1335 CfgFilePath.assign(CfgFileName);
1336 if (llvm::sys::path::is_relative(CfgFilePath)) {
1337 if (
getVFS().makeAbsolute(CfgFilePath)) {
1338 Diag(diag::err_drv_cannot_open_config_file)
1339 << CfgFilePath <<
"cannot get absolute path";
1343 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1345 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1346 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1347 if (!SearchDir.empty())
1348 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1353 if (readConfigFile(CfgFilePath, ExpCtx))
1364 llvm::Triple Triple, std::string Suffix) {
1366 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1370 VersionTuple OSVersion = Triple.getOSVersion();
1371 if (!OSVersion.getMinor().has_value())
1374 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1378 if (OSVersion.getMajor() != 0) {
1379 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1380 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1386 Triple.setOSName(BaseOSName);
1387 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1390bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1393 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1397 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1400 std::string RealMode = getExecutableForDriverMode(Mode);
1401 llvm::Triple Triple;
1410 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1411 PrefixTriple.isOSUnknown())
1412 Triple = PrefixTriple;
1416 llvm::Triple RealTriple =
1418 if (Triple.str().empty()) {
1419 Triple = RealTriple;
1420 assert(!Triple.str().empty());
1425 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1439 SmallString<128> CfgFilePath;
1441 "-" + RealMode +
".cfg"))
1442 return readConfigFile(CfgFilePath, ExpCtx);
1446 if (TryModeSuffix) {
1449 return readConfigFile(CfgFilePath, ExpCtx);
1454 std::string CfgFileName = RealMode +
".cfg";
1455 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1456 if (readConfigFile(CfgFilePath, ExpCtx))
1458 }
else if (TryModeSuffix) {
1460 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1461 readConfigFile(CfgFilePath, ExpCtx))
1467 return readConfigFile(CfgFilePath, ExpCtx);
1475 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1484 if (!DriverMode.empty())
1485 setDriverMode(DriverMode);
1491 CLOptions = std::make_unique<InputArgList>(
1496 ContainsError = loadConfigFiles();
1497 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1498 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1502 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1504 if (HasConfigFileHead)
1505 for (
auto *Opt : *CLOptions)
1506 if (!Opt->getOption().matches(options::OPT_config))
1510 if (
IsCLMode() && !ContainsError) {
1512 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1514 CLModePassThroughArgList.push_back(A->getValue());
1517 if (!CLModePassThroughArgList.empty()) {
1520 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1525 for (
auto *Opt : *CLModePassThroughOptions)
1531 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1532 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1533 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1536 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1537 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1538 if (!VFS->exists(IncludeDir))
1539 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1544 bool CCCPrintPhases;
1547 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1548 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1551 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1552 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1555 Args.ClaimAllArgs(options::OPT_pipe);
1563 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1565 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1566 CCCGenericGCCName = A->getValue();
1569 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1573 if (Args.hasArg(options::OPT_fproc_stat_report))
1580 llvm::Triple T(TargetTriple);
1581 T.setOS(llvm::Triple::Win32);
1582 T.setVendor(llvm::Triple::PC);
1583 T.setEnvironment(llvm::Triple::MSVC);
1584 T.setObjectFormat(llvm::Triple::COFF);
1585 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1586 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1587 TargetTriple = T.str();
1590 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1591 StringRef TargetProfile = A->getValue();
1594 TargetTriple = *Triple;
1596 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1600 if (Args.hasArg(options::OPT_spirv)) {
1601 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1602 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1603 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1604 llvm::Triple T(TargetTriple);
1607 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1609 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1610 TargetInfo = ValidTargets.find(A->getValue());
1612 Diag(diag::err_drv_invalid_value)
1613 << A->getAsString(Args) << A->getValue();
1619 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1620 TargetTriple = T.str();
1624 Diag(diag::err_drv_dxc_missing_target_profile);
1628 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1629 TargetTriple = A->getValue();
1630 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1631 Dir =
Dir = A->getValue();
1632 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1636 if (std::optional<std::string> CompilerPathValue =
1637 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1638 StringRef CompilerPath = *CompilerPathValue;
1639 while (!CompilerPath.empty()) {
1640 std::pair<StringRef, StringRef> Split =
1641 CompilerPath.split(llvm::sys::EnvPathSeparator);
1642 PrefixDirs.push_back(std::string(Split.first));
1643 CompilerPath = Split.second;
1646 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1648 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1651 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1654 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1655 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1656 .Case(
"cwd", SaveTempsCwd)
1657 .Case(
"obj", SaveTempsObj)
1658 .Default(SaveTempsCwd);
1661 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1662 options::OPT_offload_device_only,
1663 options::OPT_offload_host_device)) {
1664 if (A->getOption().matches(options::OPT_offload_host_only))
1665 Offload = OffloadHost;
1666 else if (A->getOption().matches(options::OPT_offload_device_only))
1667 Offload = OffloadDevice;
1669 Offload = OffloadHostDevice;
1675 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1676 StringRef
Name = A->getValue();
1677 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1678 .Case(
"off", EmbedNone)
1679 .Case(
"all", EmbedBitcode)
1680 .Case(
"bitcode", EmbedBitcode)
1681 .Case(
"marker", EmbedMarker)
1684 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1687 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1691 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1692 llvm::sys::fs::remove(A->getValue());
1698 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1700 !Args.hasArg(options::OPT_fmodules) && Std &&
1701 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1702 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1703 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1704 Std->containsValue(
"c++latest"));
1707 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1708 options::OPT_fmodule_header)) {
1710 ModulesModeCXX20 =
true;
1711 if (A->getOption().matches(options::OPT_fmodule_header))
1714 StringRef ArgName = A->getValue();
1715 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1720 Diags.Report(diag::err_drv_invalid_value)
1721 << A->getAsString(Args) << ArgName;
1727 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1728 std::make_unique<InputArgList>(std::move(Args));
1738 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1739 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1741 bool MLContainsError;
1742 auto MultilibMacroDefineList =
1744 MLMacroDefinesChar,
false, MLContainsError));
1745 if (!MLContainsError) {
1746 for (
auto *Opt : *MultilibMacroDefineList) {
1753 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1757 if (!Triple.isWasm()) {
1758 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1759 StringRef TripleObjectFormat =
1760 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1761 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1762 TripleVersionName != TripleObjectFormat) {
1763 Diags.Report(diag::err_drv_triple_version_invalid)
1765 ContainsError =
true;
1770 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1771 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1772 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1780 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1781 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1783 case llvm::Triple::arm:
1784 case llvm::Triple::armeb:
1785 case llvm::Triple::thumb:
1786 case llvm::Triple::thumbeb:
1787 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1788 Diag(diag::warn_target_unrecognized_env)
1790 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1793 case llvm::Triple::aarch64:
1794 case llvm::Triple::aarch64_be:
1795 case llvm::Triple::aarch64_32:
1796 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1797 Diag(diag::warn_target_unrecognized_env)
1799 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1816 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1817 if (HasConfigFileTail && Inputs.size()) {
1820 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1821 for (Arg *A : *CfgOptionsTail)
1822 TranslatedLinkerIns.append(A);
1823 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1830 bool UseModulesDriver =
C->getArgs().hasFlag(
1831 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1833 if (UseModulesDriver) {
1834 Diags.Report(diag::remark_performing_driver_managed_module_build);
1840 const auto StdModuleManifestPath =
1843 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1844 Diags.Report(diag::remark_modules_manifest_not_found);
1846 Diags.Report(diag::remark_using_modules_manifest)
1847 << StdModuleManifestPath;
1848 if (
auto ManifestOrErr =
1850 ModulesManifest = std::move(*ManifestOrErr);
1852 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1853 return !ModuleEntry.IsStdlib;
1858 llvm::handleAllErrors(
1859 ManifestOrErr.takeError(),
1860 [&](llvm::json::ParseError &Err) {
1861 Diags.Report(diag::err_modules_manifest_failed_parse)
1864 [&](llvm::FileError &Err) {
1865 Diags.Report(diag::err_cannot_open_file)
1866 << Err.getFileName() << Err.messageWithoutFileInfo();
1874 if (TC.
getTriple().isOSBinFormatMachO())
1879 if (CCCPrintPhases) {
1886 if (UseModulesDriver)
1893 llvm::opt::ArgStringList ASL;
1894 for (
const auto *A : Args) {
1898 while (A->getAlias())
1900 A->render(Args, ASL);
1903 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1904 if (I != ASL.begin())
1906 llvm::sys::printArg(OS, *I,
true);
1911bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1912 SmallString<128> &CrashDiagDir) {
1913 using namespace llvm::sys;
1914 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1915 "Only knows about .crash files on Darwin");
1917 auto BypassSandbox = sandbox::scopedDisable();
1922 path::home_directory(CrashDiagDir);
1923 if (CrashDiagDir.starts_with(
"/var/root"))
1925 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1933 fs::file_status FileStatus;
1934 TimePoint<> LastAccessTime;
1935 SmallString<128> CrashFilePath;
1938 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1939 File != FileEnd && !EC;
File.increment(EC)) {
1943 if (fs::status(
File->path(), FileStatus))
1945 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1946 llvm::MemoryBuffer::getFile(
File->path());
1951 StringRef
Data = CrashFile.get()->getBuffer();
1952 if (!
Data.starts_with(
"Process:"))
1955 size_t ParentProcPos =
Data.find(
"Parent Process:");
1956 if (ParentProcPos == StringRef::npos)
1958 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1959 if (LineEnd == StringRef::npos)
1961 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1962 int OpenBracket = -1, CloseBracket = -1;
1963 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1964 if (ParentProcess[i] ==
'[')
1966 if (ParentProcess[i] ==
']')
1972 if (OpenBracket < 0 || CloseBracket < 0 ||
1973 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1974 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1984 const auto FileAccessTime = FileStatus.getLastModificationTime();
1985 if (FileAccessTime > LastAccessTime) {
1986 CrashFilePath.assign(
File->path());
1987 LastAccessTime = FileAccessTime;
1992 if (!CrashFilePath.empty()) {
1993 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2003 "\n********************\n\n"
2004 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2005 "Preprocessed source(s) and associated run script(s) are located at:";
2013 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2017 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2018 Level = llvm::StringSwitch<unsigned>(A->getValue())
2020 .Case(
"compiler", 1)
2032 ArgStringList SavedTemps;
2034 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2035 if (!IsLLD || Level < 2)
2042 SavedTemps = std::move(
C.getTempFiles());
2043 assert(!
C.getTempFiles().size());
2060 C.initCompilationForDiagnostics();
2065 Command NewLLDInvocation = Cmd;
2066 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2067 StringRef ReproduceOption =
2068 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2071 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2075 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2077 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2078 Diag(clang::diag::note_drv_command_failed_diag_msg)
2079 <<
"\n\n********************";
2081 Report->TemporaryFiles.push_back(TmpName);
2089 ArgStringList IRInputs;
2090 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2091 bool IgnoreInput =
false;
2097 IRInputs.push_back(it->second->getValue());
2101 }
else if (!strcmp(it->second->getValue(),
"-")) {
2102 Diag(clang::diag::note_drv_command_failed_diag_msg)
2103 <<
"Error generating preprocessed source(s) - "
2104 "ignoring input from stdin.";
2109 it = Inputs.erase(it);
2116 if (Inputs.empty() && IRInputs.empty()) {
2117 Diag(clang::diag::note_drv_command_failed_diag_msg)
2118 <<
"Error generating preprocessed source(s) - "
2119 "no preprocessable inputs.";
2126 for (
const Arg *A :
C.getArgs()) {
2127 if (A->getOption().matches(options::OPT_arch)) {
2128 StringRef ArchName = A->getValue();
2133 Diag(clang::diag::note_drv_command_failed_diag_msg)
2134 <<
"Error generating preprocessed source(s) - cannot generate "
2135 "preprocessed source with multiple -arch options.";
2140 if (!Inputs.empty()) {
2143 const ToolChain &TC =
C.getDefaultToolChain();
2144 if (TC.
getTriple().isOSBinFormatMachO())
2153 Diag(clang::diag::note_drv_command_failed_diag_msg)
2154 <<
"Error generating preprocessed source(s).";
2159 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2162 if (!FailingCommands.empty()) {
2163 Diag(clang::diag::note_drv_command_failed_diag_msg)
2164 <<
"Error generating preprocessed source(s).";
2168 const ArgStringList &TempFiles =
C.getTempFiles();
2169 if (TempFiles.empty()) {
2170 Diag(clang::diag::note_drv_command_failed_diag_msg)
2171 <<
"Error generating preprocessed source(s).";
2177 const ArgStringList &Files =
C.getTempFiles();
2182 for (
auto const *Input : IRInputs) {
2186 StringRef extension = llvm::sys::path::extension(Input);
2187 if (!extension.empty())
2188 extension = extension.drop_front();
2190 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2191 llvm::sys::path::stem(Input), extension, FD, Path);
2193 Diag(clang::diag::note_drv_command_failed_diag_msg)
2194 <<
"Error generating run script: " <<
"Failed copying IR input files"
2195 <<
" " << EC.message();
2199 EC = llvm::sys::fs::copy_file(Input, FD);
2201 Diag(clang::diag::note_drv_command_failed_diag_msg)
2202 <<
"Error generating run script: " <<
"Failed copying IR input files"
2203 <<
" " << EC.message();
2207 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2214 for (std::string &TempFile : TempFiles) {
2215 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2217 Report->TemporaryFiles.push_back(TempFile);
2218 if (ReproCrashFilename.empty()) {
2219 ReproCrashFilename = TempFile;
2220 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2222 if (StringRef(TempFile).ends_with(
".cache")) {
2225 VFS = llvm::sys::path::filename(TempFile);
2226 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2230 for (
const char *TempFile : SavedTemps)
2231 TempFiles.push_back(TempFile);
2237 llvm::sys::path::replace_extension(Script,
"sh");
2239 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2240 llvm::sys::fs::FA_Write,
2241 llvm::sys::fs::OF_Text);
2243 Diag(clang::diag::note_drv_command_failed_diag_msg)
2244 <<
"Error generating run script: " << Script <<
" " << EC.message();
2247 <<
"# Driver args: ";
2249 ScriptOS <<
"# Original command: ";
2250 Cmd.
Print(ScriptOS,
"\n",
true);
2251 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2252 if (!AdditionalInformation.empty())
2253 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2256 Report->TemporaryFiles.push_back(std::string(Script));
2257 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2261 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2263 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2264 Diag(clang::diag::note_drv_command_failed_diag_msg)
2265 << ReproCrashFilename.str();
2267 llvm::sys::path::append(CrashDiagDir,
Name);
2268 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2269 Diag(clang::diag::note_drv_command_failed_diag_msg)
2270 <<
"Crash backtrace is located in";
2271 Diag(clang::diag::note_drv_command_failed_diag_msg)
2272 << CrashDiagDir.str();
2273 Diag(clang::diag::note_drv_command_failed_diag_msg)
2274 <<
"(choose the .crash file that corresponds to your crash)";
2278 Diag(clang::diag::note_drv_command_failed_diag_msg)
2279 <<
"\n\n********************";
2289 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2300 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2301 if (
C.getArgs().hasArg(options::OPT_v))
2302 C.getJobs().Print(llvm::errs(),
"\n",
true);
2304 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2307 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2314 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2315 C.getJobs().Print(llvm::errs(),
"\n",
true);
2316 return Diags.hasErrorOccurred() ? 1 : 0;
2320 if (Diags.hasErrorOccurred())
2324 for (
auto &Job :
C.getJobs())
2325 setUpResponseFiles(
C, Job);
2327 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2330 if (FailingCommands.empty())
2336 for (
const auto &CmdPair : FailingCommands) {
2337 int CommandRes = CmdPair.first;
2338 const Command *FailingCommand = CmdPair.second;
2343 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2347 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2352 if (CommandRes == EX_IOERR) {
2372 if (CommandRes > 128 && CommandRes != 255)
2376 Diag(clang::diag::err_drv_command_signalled)
2379 Diag(clang::diag::err_drv_command_failed)
2387 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2389 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2403 const ToolChain &TC =
C.getDefaultToolChain();
2407 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2410 OS <<
"Thread model: " << A->getValue();
2416 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2421 if (!llvm::cl::getCompilerBuildConfig().empty())
2422 llvm::cl::printBuildConfig(OS);
2425 for (
auto ConfigFile : ConfigFiles)
2426 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2439 if (PassedFlags ==
"")
2443 std::vector<std::string> SuggestedCompletions;
2444 std::vector<std::string> Flags;
2456 const bool HasSpace = PassedFlags.ends_with(
",");
2460 StringRef TargetFlags = PassedFlags;
2461 while (TargetFlags !=
"") {
2463 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2464 Flags.push_back(std::string(CurFlag));
2469 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2472 const llvm::opt::OptTable &Opts =
getOpts();
2474 Cur = Flags.at(Flags.size() - 1);
2476 if (Flags.size() >= 2) {
2477 Prev = Flags.at(Flags.size() - 2);
2478 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2481 if (SuggestedCompletions.empty())
2482 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2489 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2490 llvm::outs() <<
'\n';
2496 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2500 SuggestedCompletions = Opts.findByPrefix(
2501 Cur, VisibilityMask,
2508 if (S.starts_with(Cur))
2509 SuggestedCompletions.push_back(std::string(S));
2516 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2517 if (
int X = A.compare_insensitive(B))
2519 return A.compare(B) > 0;
2522 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2529 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2530 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2534 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2537 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2541 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2546 if (
C.getArgs().hasArg(options::OPT_help) ||
2547 C.getArgs().hasArg(options::OPT__help_hidden)) {
2548 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2552 if (
C.getArgs().hasArg(options::OPT__version)) {
2558 if (
C.getArgs().hasArg(options::OPT_v) ||
2559 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2560 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2561 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2562 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2564 SuppressMissingInputWarning =
true;
2567 if (
C.getArgs().hasArg(options::OPT_v)) {
2569 llvm::errs() <<
"System configuration file directory: "
2572 llvm::errs() <<
"User configuration file directory: "
2576 const ToolChain &TC =
C.getDefaultToolChain();
2578 if (
C.getArgs().hasArg(options::OPT_v))
2581 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2586 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2587 llvm::outs() <<
"programs: =";
2588 bool separator =
false;
2592 llvm::outs() << llvm::sys::EnvPathSeparator;
2593 llvm::outs() << Path;
2598 llvm::outs() << llvm::sys::EnvPathSeparator;
2599 llvm::outs() << Path;
2602 llvm::outs() <<
"\n";
2605 StringRef sysroot =
C.getSysRoot();
2609 llvm::outs() << llvm::sys::EnvPathSeparator;
2612 llvm::outs() << sysroot << Path.substr(1);
2614 llvm::outs() << Path;
2616 llvm::outs() <<
"\n";
2620 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2626 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2627 for (
auto RuntimePath :
2629 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2630 llvm::outs() << *RuntimePath <<
'\n';
2634 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2638 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2640 for (std::size_t I = 0; I != Flags.size(); I += 2)
2641 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2647 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2648 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2652 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2653 StringRef ProgName = A->getValue();
2656 if (! ProgName.empty())
2659 llvm::outs() <<
"\n";
2663 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2664 StringRef PassedFlags = A->getValue();
2669 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2683 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2686 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2692 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2699 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2702 std::set<llvm::StringRef> SortedFlags;
2703 for (
const auto &FlagEntry : ExpandedFlags)
2704 SortedFlags.insert(FlagEntry.getKey());
2705 for (
auto Flag : SortedFlags)
2706 llvm::outs() << Flag <<
'\n';
2710 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2713 llvm::outs() <<
".\n";
2716 assert(Suffix.front() ==
'/');
2717 llvm::outs() << Suffix.substr(1) <<
"\n";
2723 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2728 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2730 llvm::outs() << Triple.getTriple() <<
"\n";
2734 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2735 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2752 std::map<Action *, unsigned> &Ids,
2754 if (
auto It = Ids.find(A); It != Ids.end())
2758 llvm::raw_string_ostream os(str);
2760 auto getSibIndent = [](
int K) -> Twine {
2764 Twine SibIndent =
Indent + getSibIndent(Kind);
2768 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2770 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2771 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2772 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2774 OA->doOnEachDependence(
2776 assert(TC &&
"Unknown host toolchain");
2788 os <<
":" << BoundArch;
2791 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2799 const char *Prefix =
"{";
2800 for (
Action *PreRequisite : *AL) {
2801 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2812 std::string offload_str;
2813 llvm::raw_string_ostream offload_os(offload_str);
2817 offload_os <<
", (" << S;
2824 auto getSelfIndent = [](
int K) -> Twine {
2828 unsigned Id = Ids.size();
2830 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2839 std::map<Action *, unsigned> Ids;
2840 for (
Action *A :
C.getActions())
2856 DerivedArgList &Args =
C.getArgs();
2858 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2863 for (Arg *A : Args) {
2864 if (A->getOption().matches(options::OPT_arch)) {
2867 llvm::Triple::ArchType
Arch =
2869 if (
Arch == llvm::Triple::UnknownArch) {
2870 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2875 if (
ArchNames.insert(A->getValue()).second)
2876 Archs.push_back(A->getValue());
2890 for (
Action* Act : SingleActions) {
2898 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2902 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2907 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2908 Actions.append(Inputs.begin(), Inputs.end());
2910 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2913 Arg *A = Args.getLastArg(options::OPT_g_Group);
2914 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2915 !A->getOption().matches(options::OPT_gstabs);
2923 if (Act->getType() == types::TY_Image) {
2925 Inputs.push_back(Actions.back());
2932 if (Args.hasArg(options::OPT_verify_debug_info)) {
2933 Action *LastAction = Actions.pop_back_val();
2935 LastAction, types::TY_Nothing));
2942 bool TypoCorrect)
const {
2954 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2955 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2967 std::string Nearest;
2968 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2969 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2970 <<
Value << Nearest;
3009 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3012 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3020 return types::TY_CXXUHeader;
3022 return types::TY_CXXSHeader;
3026 llvm_unreachable(
"should not be called in this case");
3028 return types::TY_CXXHUHeader;
3034 const llvm::opt::OptTable &Opts =
getOpts();
3038 types::ID InputType = types::TY_Nothing;
3039 Arg *InputTypeArg =
nullptr;
3042 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3043 options::OPT__SLASH_TP)) {
3044 InputTypeArg = TCTP;
3045 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3050 bool ShowNote =
false;
3052 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3054 Diag(clang::diag::warn_drv_overriding_option)
3055 <<
Previous->getSpelling() << A->getSpelling();
3061 Diag(clang::diag::note_drv_t_option_is_global);
3066 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3067 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3068 if (LastXArg && LastInputArg &&
3069 LastInputArg->getIndex() < LastXArg->getIndex())
3070 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3073 for (Arg *A : Args) {
3074 if (A->getOption().
getKind() == Option::InputClass) {
3075 const char *
Value = A->getValue();
3079 if (InputType == types::TY_Nothing) {
3082 InputTypeArg->claim();
3085 if (memcmp(
Value,
"-", 2) == 0) {
3087 Ty = types::TY_Fortran;
3089 Ty = types::TY_HLSL;
3098 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3099 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3100 : clang::diag::err_drv_unknown_stdin_type);
3109 if (
const char *Ext = strrchr(
Value,
'.'))
3118 Ty = types::TY_HLSL;
3120 Ty = types::TY_Object;
3131 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3132 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3133 << getTypeName(OldTy) << getTypeName(Ty);
3138 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3139 Ty == types::TY_Object)
3140 Ty = types::TY_LLVM_BC;
3148 if (Ty != types::TY_Object) {
3149 if (Args.hasArg(options::OPT_ObjC))
3150 Ty = types::TY_ObjC;
3151 else if (Args.hasArg(options::OPT_ObjCXX))
3152 Ty = types::TY_ObjCXX;
3159 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3163 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3164 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3167 const char *Ext = strrchr(
Value,
'.');
3169 Ty = types::TY_Object;
3173 InputTypeArg->claim();
3177 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3178 Args.hasArgNoClaim(options::OPT_hipstdpar))
3182 Inputs.push_back(std::make_pair(Ty, A));
3184 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3185 StringRef
Value = A->getValue();
3188 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3189 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3192 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3193 StringRef
Value = A->getValue();
3196 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3197 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3203 Inputs.push_back(std::make_pair(types::TY_Object, A));
3205 }
else if (A->getOption().matches(options::OPT_x)) {
3214 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3215 InputType = types::TY_Object;
3222 }
else if (A->getOption().getID() == options::OPT_U) {
3223 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3224 StringRef Val = A->getValue(0);
3225 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3227 Diag(diag::warn_slash_u_filename) << Val;
3228 Diag(diag::note_use_dashdash);
3232 if (
CCCIsCPP() && Inputs.empty()) {
3236 Inputs.push_back(std::make_pair(types::TY_C, A));
3243class OffloadingActionBuilder final {
3245 bool IsValid =
false;
3251 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3254 std::map<Action *, const Arg *> HostActionToInputArgMap;
3257 class DeviceActionBuilder {
3261 enum ActionBuilderReturnCode {
3280 DerivedArgList &Args;
3289 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3292 :
C(
C), Args(Args), Inputs(Inputs),
3293 AssociatedOffloadKind(AssociatedOffloadKind) {}
3294 virtual ~DeviceActionBuilder() {}
3299 virtual ActionBuilderReturnCode
3300 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3303 return ABRT_Inactive;
3308 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3309 return ABRT_Inactive;
3313 virtual void appendTopLevelActions(
ActionList &AL) {}
3316 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3319 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3322 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3329 virtual bool canUseBundlerUnbundler()
const {
return false; }
3333 bool isValid() {
return !ToolChains.empty(); }
3337 return AssociatedOffloadKind;
3343 class CudaActionBuilderBase :
public DeviceActionBuilder {
3347 bool CompileHostOnly =
false;
3348 bool CompileDeviceOnly =
false;
3350 bool EmitAsm =
false;
3360 TargetID(
const char *ID) :
ID(
ID) {}
3361 operator const char *() {
return ID; }
3362 operator StringRef() {
return StringRef(ID); }
3365 SmallVector<TargetID, 4> GpuArchList;
3371 Action *CudaFatBinary =
nullptr;
3374 bool IsActive =
false;
3377 bool Relocatable =
false;
3380 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3383 const CUIDOptions &CUIDOpts;
3386 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3388 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3389 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3391 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3392 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3393 options::OPT_fno_gpu_rdc,
false);
3396 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3403 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3406 if (!(IA->getType() == types::TY_CUDA ||
3407 IA->getType() == types::TY_HIP ||
3408 IA->getType() == types::TY_PP_HIP)) {
3411 return ABRT_Inactive;
3418 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3420 if (CompileHostOnly)
3421 return ABRT_Success;
3424 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3425 : types::TY_CUDA_DEVICE;
3426 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3427 CudaDeviceActions.push_back(
3428 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3431 return ABRT_Success;
3435 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3439 if (UA->getType() == types::TY_Object && !Relocatable)
3440 return ABRT_Inactive;
3442 CudaDeviceActions.clear();
3444 std::string
FileName = IA->getInputArg().getAsString(Args);
3450 const StringRef LibFileExt =
".lib";
3451 if (IA->getType() == types::TY_Object &&
3452 (!llvm::sys::path::has_extension(
FileName) ||
3454 llvm::sys::path::extension(
FileName).drop_front()) !=
3456 llvm::sys::path::extension(
FileName) == LibFileExt))
3457 return ABRT_Inactive;
3459 for (
auto Arch : GpuArchList) {
3460 CudaDeviceActions.push_back(UA);
3461 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3462 AssociatedOffloadKind);
3465 return ABRT_Success;
3468 return IsActive ? ABRT_Success : ABRT_Inactive;
3471 void appendTopLevelActions(
ActionList &AL)
override {
3473 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3474 OffloadAction::DeviceDependences Dep;
3475 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3476 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3480 if (CudaFatBinary) {
3481 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3482 CudaDeviceActions.clear();
3483 CudaFatBinary =
nullptr;
3487 if (CudaDeviceActions.empty())
3493 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3494 "Expecting one action per GPU architecture.");
3495 assert(ToolChains.size() == 1 &&
3496 "Expecting to have a single CUDA toolchain.");
3497 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3498 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3500 CudaDeviceActions.clear();
3503 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3521 assert(HostTC &&
"No toolchain for host compilation.");
3526 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3531 std::set<StringRef> GpuArchs;
3533 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3534 ToolChains.push_back(I.second);
3537 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3538 GpuArchs.insert(
Arch);
3542 for (
auto Arch : GpuArchs)
3543 GpuArchList.push_back(
Arch.data());
3545 CompileHostOnly =
C.getDriver().offloadHostOnly();
3546 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3547 EmitAsm = Args.getLastArg(options::OPT_S);
3555 class CudaActionBuilder final :
public CudaActionBuilderBase {
3557 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3559 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3560 DefaultOffloadArch = OffloadArch::CudaDefault;
3563 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3565 const std::set<StringRef> &GpuArchs)
override {
3566 return std::nullopt;
3569 ActionBuilderReturnCode
3570 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3572 PhasesTy &Phases)
override {
3574 return ABRT_Inactive;
3578 if (CudaDeviceActions.empty())
3579 return ABRT_Success;
3581 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3582 "Expecting one action per GPU architecture.");
3583 assert(!CompileHostOnly &&
3584 "Not expecting CUDA actions in host-only compilation.");
3594 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3597 for (
auto Ph : Phases) {
3602 if (Ph > FinalPhase)
3605 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3619 Action *AssembleAction = CudaDeviceActions[I];
3620 assert(AssembleAction->
getType() == types::TY_Object);
3621 assert(AssembleAction->
getInputs().size() == 1);
3627 OffloadAction::DeviceDependences DDep;
3629 DeviceActions.push_back(
3630 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3635 if (!DeviceActions.empty()) {
3637 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3639 if (!CompileDeviceOnly) {
3640 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3644 CudaFatBinary =
nullptr;
3649 CudaDeviceActions.clear();
3653 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3658 return ABRT_Success;
3662 "instructions should only occur "
3663 "before the backend phase!");
3666 for (Action *&A : CudaDeviceActions)
3667 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3669 return ABRT_Success;
3674 class HIPActionBuilder final :
public CudaActionBuilderBase {
3676 SmallVector<ActionList, 8> DeviceLinkerInputs;
3682 std::optional<bool> BundleOutput;
3683 std::optional<bool> EmitReloc;
3686 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3688 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3690 DefaultOffloadArch = OffloadArch::HIPDefault;
3692 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3693 options::OPT_fno_hip_emit_relocatable)) {
3694 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3695 options::OPT_fno_hip_emit_relocatable, false);
3699 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3700 <<
"-fhip-emit-relocatable"
3704 if (!CompileDeviceOnly) {
3705 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3706 <<
"-fhip-emit-relocatable"
3707 <<
"--offload-device-only";
3712 if (Args.hasArg(options::OPT_gpu_bundle_output,
3713 options::OPT_no_gpu_bundle_output))
3714 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3715 options::OPT_no_gpu_bundle_output,
true) &&
3716 (!EmitReloc || !*EmitReloc);
3719 bool canUseBundlerUnbundler()
const override {
return true; }
3721 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3723 const std::set<StringRef> &GpuArchs)
override {
3727 ActionBuilderReturnCode
3728 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3730 PhasesTy &Phases)
override {
3732 return ABRT_Inactive;
3738 if (CudaDeviceActions.empty())
3739 return ABRT_Success;
3742 CudaDeviceActions.size() == GpuArchList.size()) &&
3743 "Expecting one action per GPU architecture.");
3744 assert(!CompileHostOnly &&
3745 "Not expecting HIP actions in host-only compilation.");
3747 bool ShouldLink = !EmitReloc || !*EmitReloc;
3750 !EmitAsm && ShouldLink) {
3756 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3757 if (
C.getDriver().isUsingOffloadLTO()) {
3761 AL.push_back(CudaDeviceActions[I]);
3764 CudaDeviceActions[I] =
3765 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3771 if (ToolChains.front()->getTriple().isSPIRV() ||
3772 (ToolChains.front()->getTriple().isAMDGCN() &&
3773 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3777 types::ID Output = Args.hasArg(options::OPT_S)
3779 : types::TY_LLVM_BC;
3781 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3785 AssociatedOffloadKind);
3786 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3788 AssociatedOffloadKind);
3789 AL.push_back(AssembleAction);
3792 CudaDeviceActions[I] =
3793 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3802 OffloadAction::DeviceDependences DDep;
3803 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3804 AssociatedOffloadKind);
3805 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3806 DDep, CudaDeviceActions[I]->getType());
3809 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3811 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3812 types::TY_HIP_FATBIN);
3814 if (!CompileDeviceOnly) {
3815 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3816 AssociatedOffloadKind);
3819 CudaFatBinary =
nullptr;
3824 CudaDeviceActions.clear();
3827 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3830 return ABRT_Success;
3836 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3837 auto LI = DeviceLinkerInputs.begin();
3838 for (
auto *A : CudaDeviceActions) {
3845 CudaDeviceActions.clear();
3846 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3850 for (Action *&A : CudaDeviceActions)
3851 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3852 AssociatedOffloadKind);
3854 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3856 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3857 OffloadAction::DeviceDependences DDep;
3858 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3859 AssociatedOffloadKind);
3860 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3861 DDep, CudaDeviceActions[I]->getType());
3864 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3865 CudaDeviceActions.clear();
3868 return (CompileDeviceOnly &&
3869 (CurPhase == FinalPhase ||
3875 void appendLinkDeviceActions(
ActionList &AL)
override {
3876 if (DeviceLinkerInputs.size() == 0)
3879 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3880 "Linker inputs and GPU arch list sizes do not match.");
3886 for (
auto &LI : DeviceLinkerInputs) {
3888 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3892 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3895 OffloadAction::DeviceDependences DeviceLinkDeps;
3896 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3897 GpuArchList[I], AssociatedOffloadKind);
3898 Actions.push_back(
C.MakeAction<OffloadAction>(
3899 DeviceLinkDeps, DeviceLinkAction->getType()));
3902 DeviceLinkerInputs.clear();
3905 if (Args.hasArg(options::OPT_emit_llvm)) {
3913 OffloadAction::DeviceDependences DDeps;
3914 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3915 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3917 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3918 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3919 AssociatedOffloadKind);
3922 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3928 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3930 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3938 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3944 bool ShouldUseBundler;
3947 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3955 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3958 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3966 unsigned ValidBuilders = 0u;
3967 unsigned ValidBuildersSupportingBundling = 0u;
3968 for (
auto *SB : SpecializedBuilders) {
3969 IsValid = IsValid && !SB->initialize();
3972 if (SB->isValid()) {
3974 if (SB->canUseBundlerUnbundler())
3975 ++ValidBuildersSupportingBundling;
3979 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3981 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
3982 options::OPT_no_gpu_bundle_output,
true);
3985 ~OffloadingActionBuilder() {
3986 for (
auto *SB : SpecializedBuilders)
3991 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3992 assert(HostAction &&
"Invalid host action");
3993 assert(InputArg &&
"Invalid input argument");
3994 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3995 assert(Loc->second == InputArg &&
3996 "host action mapped to multiple input arguments");
4005 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4007 DeviceActionBuilder::PhasesTy &Phases) {
4011 if (SpecializedBuilders.empty())
4014 assert(HostAction &&
"Invalid host action!");
4015 recordHostAction(HostAction, InputArg);
4020 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4021 unsigned InactiveBuilders = 0u;
4022 unsigned IgnoringBuilders = 0u;
4023 for (
auto *SB : SpecializedBuilders) {
4024 if (!SB->isValid()) {
4029 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4034 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4039 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4040 OffloadKind |= SB->getAssociatedOffloadKind();
4045 if (IgnoringBuilders &&
4046 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4063 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4064 const Arg *InputArg) {
4068 recordHostAction(HostAction, InputArg);
4077 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4079 HostAction->
getType() == types::TY_PP_HIP)) {
4080 auto UnbundlingHostAction =
4085 HostAction = UnbundlingHostAction;
4086 recordHostAction(HostAction, InputArg);
4089 assert(HostAction &&
"Invalid host action!");
4092 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4093 for (
auto *SB : SpecializedBuilders) {
4097 auto RetCode = SB->addDeviceDependences(HostAction);
4101 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4102 "Host dependence not expected to be ignored.!");
4106 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4107 OffloadKind |= SB->getAssociatedOffloadKind();
4112 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4122 const Arg *InputArg) {
4124 recordHostAction(HostAction, InputArg);
4128 for (
auto *SB : SpecializedBuilders) {
4131 SB->appendTopLevelActions(OffloadAL);
4138 if (CanUseBundler && ShouldUseBundler && HostAction &&
4139 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4141 OffloadAL.push_back(HostAction);
4145 assert(HostAction == AL.back() &&
"Host action not in the list??");
4147 recordHostAction(HostAction, InputArg);
4148 AL.back() = HostAction;
4150 AL.append(OffloadAL.begin(), OffloadAL.end());
4160 void appendDeviceLinkActions(
ActionList &AL) {
4161 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4164 SB->appendLinkDeviceActions(AL);
4168 Action *makeHostLinkAction() {
4171 appendDeviceLinkActions(DeviceAL);
4172 if (DeviceAL.empty())
4177 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4180 HA = SB->appendLinkHostActions(DeviceAL);
4197 for (
auto *SB : SpecializedBuilders) {
4201 SB->appendLinkDependences(DDeps);
4205 unsigned ActiveOffloadKinds = 0u;
4206 for (
auto &I : InputArgToOffloadKindMap)
4207 ActiveOffloadKinds |= I.second;
4219 for (
auto *A : HostAction->
inputs()) {
4220 auto ArgLoc = HostActionToInputArgMap.find(A);
4221 if (ArgLoc == HostActionToInputArgMap.end())
4223 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4224 if (OFKLoc == InputArgToOffloadKindMap.end())
4236 nullptr, ActiveOffloadKinds);
4242void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4247 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4248 StringRef
V = A->getValue();
4249 if (Inputs.size() > 1 && !
V.empty() &&
4250 !llvm::sys::path::is_separator(
V.back())) {
4252 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4253 << A->getSpelling() <<
V;
4254 Args.eraseArg(options::OPT__SLASH_Fo);
4259 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4260 StringRef
V = A->getValue();
4261 if (Inputs.size() > 1 && !
V.empty() &&
4262 !llvm::sys::path::is_separator(
V.back())) {
4264 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4265 << A->getSpelling() <<
V;
4266 Args.eraseArg(options::OPT__SLASH_Fa);
4271 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4272 if (A->getValue()[0] ==
'\0') {
4274 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4275 Args.eraseArg(options::OPT__SLASH_o);
4280 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4281 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4282 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4283 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4284 Args.eraseArg(options::OPT__SLASH_Yc);
4285 Args.eraseArg(options::OPT__SLASH_Yu);
4286 YcArg = YuArg =
nullptr;
4288 if (YcArg && Inputs.size() > 1) {
4289 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4290 Args.eraseArg(options::OPT__SLASH_Yc);
4298 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4299 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4300 Args.AddFlagArg(
nullptr,
4301 getOpts().getOption(options::OPT_frtlib_add_rpath));
4305 if (Args.hasArg(options::OPT_emit_llvm) &&
4306 !Args.hasArg(options::OPT_hip_link) &&
4307 !
C.getDefaultToolChain().getTriple().isSPIRV())
4308 Diag(clang::diag::err_drv_emit_llvm_link);
4309 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4311 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4312 .starts_with_insensitive(
"lld"))
4313 Diag(clang::diag::err_drv_lto_without_lld);
4319 if (!Args.hasArg(options::OPT_dumpdir)) {
4320 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4321 Arg *Arg = Args.MakeSeparateArg(
4322 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4324 (FinalOutput ? FinalOutput->getValue()
4336 Args.eraseArg(options::OPT__SLASH_Fp);
4337 Args.eraseArg(options::OPT__SLASH_Yc);
4338 Args.eraseArg(options::OPT__SLASH_Yu);
4339 YcArg = YuArg =
nullptr;
4342 if (Args.hasArg(options::OPT_include_pch) &&
4343 Args.hasArg(options::OPT_ignore_pch)) {
4347 Args.eraseArg(options::OPT_include_pch);
4350 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4351 for (
auto &I : Inputs) {
4353 const Arg *InputArg = I.second;
4358 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4362 if (InitialPhase > FinalPhase) {
4363 if (InputArg->isClaimed())
4370 if (Args.hasArg(options::OPT_Qunused_arguments))
4376 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4377 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4381 (Args.getLastArg(options::OPT__SLASH_EP,
4382 options::OPT__SLASH_P) ||
4383 Args.getLastArg(options::OPT_E) ||
4384 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4386 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4387 << InputArg->getAsString(Args) << !!FinalPhaseArg
4388 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4390 Diag(clang::diag::warn_drv_input_file_unused)
4391 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4393 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4402 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4406 Actions.push_back(ClangClPch);
4418 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4419 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4425 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4427 if (!SuppressMissingInputWarning && Inputs.empty()) {
4428 Diag(clang::diag::err_drv_no_input_files);
4432 handleArguments(
C, Args, Inputs, Actions);
4434 bool UseNewOffloadingDriver = Args.hasFlag(
4435 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4439 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4440 !UseNewOffloadingDriver
4441 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4449 for (
auto &I : Inputs) {
4451 const Arg *InputArg = I.second;
4464 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4470 if (!UseNewOffloadingDriver)
4471 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4477 if (!UseNewOffloadingDriver)
4478 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4479 Current, InputArg, Phase, PL.back(), FullPL);
4485 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4488 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4489 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4491 LinkerInputs.push_back(Current);
4501 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4502 MergerInputs.push_back(Current);
4520 if (NewCurrent == Current)
4523 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4526 Current = NewCurrent;
4530 if (UseNewOffloadingDriver)
4534 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4538 if (Current->
getType() == types::TY_Nothing)
4544 Actions.push_back(Current);
4547 if (!UseNewOffloadingDriver)
4548 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4556 if (LinkerInputs.empty()) {
4559 if (!UseNewOffloadingDriver)
4560 OffloadBuilder->appendDeviceLinkActions(Actions);
4563 if (!LinkerInputs.empty()) {
4564 if (!UseNewOffloadingDriver)
4565 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4566 LinkerInputs.push_back(Wrapper);
4571 }
else if (UseNewOffloadingDriver ||
4572 Args.hasArg(options::OPT_offload_link)) {
4580 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4581 C.getDefaultToolChain().getTriple().isSPIRV();
4582 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4586 if (!UseNewOffloadingDriver)
4587 LA = OffloadBuilder->processHostLinkAction(LA);
4588 Actions.push_back(LA);
4592 if (!MergerInputs.empty())
4596 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4603 for (
auto &I : Inputs) {
4605 const Arg *InputArg = I.second;
4610 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4611 InputType == types::TY_Asm)
4616 for (
auto Phase : PhaseList) {
4620 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4625 if (InputType == types::TY_Object)
4632 assert(Phase == PhaseList.back() &&
4633 "merging must be final compilation step.");
4634 MergerInputs.push_back(Current);
4643 Actions.push_back(Current);
4647 if (!MergerInputs.empty())
4652 for (
auto Opt : {options::OPT_print_supported_cpus,
4653 options::OPT_print_supported_extensions,
4654 options::OPT_print_enabled_extensions}) {
4661 if (Arg *A = Args.getLastArg(Opt)) {
4662 if (Opt == options::OPT_print_supported_extensions &&
4663 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4664 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4665 !
C.getDefaultToolChain().getTriple().isARM()) {
4666 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4667 <<
"--print-supported-extensions";
4670 if (Opt == options::OPT_print_enabled_extensions &&
4671 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4672 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4673 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4674 <<
"--print-enabled-extensions";
4681 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4684 for (
auto &I : Inputs)
4689 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4695 if (TC.requiresObjcopy(Args)) {
4696 Action *LastAction = Actions.back();
4698 if (LastAction->
getType() == types::TY_Object)
4704 if (TC.requiresValidation(Args)) {
4705 Action *LastAction = Actions.back();
4707 LastAction, types::TY_DX_CONTAINER));
4711 if (TC.requiresBinaryTranslation(Args)) {
4712 Action *LastAction = Actions.back();
4716 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4717 LastAction->
getType() == types::TY_Object)
4719 LastAction, types::TY_DX_CONTAINER));
4724 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4730 const llvm::opt::DerivedArgList &Args,
4732 const llvm::Triple &Triple) {
4737 if (Triple.isNVPTX() &&
4739 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4740 <<
"CUDA" << ArchStr;
4742 }
else if (Triple.isAMDGPU() &&
4744 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4745 <<
"HIP" << ArchStr;
4753 llvm::StringMap<bool> Features;
4756 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4768static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4770 llvm::Triple Triple) {
4771 if (!Triple.isAMDGPU())
4772 return std::nullopt;
4774 std::set<StringRef> ArchSet;
4775 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4779llvm::SmallVector<StringRef>
4783 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4784 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4785 options::OPT_no_offload_arch_EQ)) {
4786 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4788 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4790 :
"--no-offload-arch");
4793 llvm::DenseSet<StringRef> Archs;
4794 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4797 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4798 for (StringRef
Arch : Arg->getValues()) {
4799 if (
Arch ==
"native" ||
Arch.empty()) {
4803 << llvm::Triple::getArchTypeName(TC.
getArch())
4804 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4808 for (
auto ArchStr : *GPUsOrErr) {
4810 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4811 if (!CanonicalStr.empty())
4812 Archs.insert(CanonicalStr);
4817 StringRef CanonicalStr =
4819 if (!CanonicalStr.empty())
4820 Archs.insert(CanonicalStr);
4825 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4826 for (StringRef
Arch : Arg->getValues()) {
4827 if (
Arch ==
"all") {
4832 Archs.erase(ArchStr);
4838 if (
auto ConflictingArchs =
4840 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4841 << ConflictingArchs->first << ConflictingArchs->second;
4844 if (Archs.empty()) {
4852 Archs.insert(StringRef());
4855 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4856 .getLastArg(options::OPT_march_EQ)) {
4857 Archs.insert(Arg->getValue());
4862 << llvm::Triple::getArchTypeName(TC.
getArch())
4863 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4864 }
else if (!ArchsOrErr->empty()) {
4865 for (
auto Arch : *ArchsOrErr)
4866 Archs.insert(Args.MakeArgStringRef(
Arch));
4868 Archs.insert(StringRef());
4873 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4874 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4882 llvm::opt::DerivedArgList &Args,
4883 const InputTy &Input, StringRef CUID,
4884 Action *HostAction)
const {
4892 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4894 bool HIPRelocatableObj =
4896 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4897 options::OPT_fno_hip_emit_relocatable,
false);
4899 if (!HIPNoRDC && HIPRelocatableObj)
4900 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4901 <<
"-fhip-emit-relocatable"
4905 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4906 <<
"-fhip-emit-relocatable"
4907 <<
"--offload-device-only";
4925 auto TCRange =
C.getOffloadToolChains(Kind);
4926 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4927 ToolChains.push_back(TI->second);
4929 if (ToolChains.empty())
4933 const Arg *InputArg = Input.second;
4942 for (
const ToolChain *TC : ToolChains) {
4944 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4945 DeviceActions.push_back(
4946 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4950 if (DeviceActions.empty())
4956 HostAction->
getType() != types::TY_Nothing &&
4966 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4975 auto *TCAndArch = TCAndArchs.begin();
4976 for (
Action *&A : DeviceActions) {
4977 if (A->
getType() == types::TY_Nothing)
4987 HostAction->
getType() != types::TY_Nothing) {
4994 TCAndArch->second.data(), Kind);
4996 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5006 for (
Action *&A : DeviceActions) {
5011 OffloadTriple && OffloadTriple->isSPIRV() &&
5012 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5013 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5014 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5015 options::OPT_no_use_spirv_backend,
5022 bool IsAMDGCNSPIRVWithBackend =
5023 IsHIPSPV && OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA &&
5026 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5027 A->
getType() != types::TY_LTO_BC) ||
5035 auto *TCAndArch = TCAndArchs.begin();
5036 for (
Action *A : DeviceActions) {
5037 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5039 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
5044 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5046 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
5055 bool ShouldBundleHIP =
5056 Args.hasFlag(options::OPT_gpu_bundle_output,
5057 options::OPT_no_gpu_bundle_output,
false) ||
5058 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5060 return A->
getType() != types::TY_Image;
5067 if (OffloadActions.empty())
5072 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5076 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5083 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5084 DDep.
add(*FatbinAction,
5087 }
else if (HIPNoRDC) {
5099 DDep.
add(*PackagerAction,
5108 nullptr,
C.getActiveOffloadKinds());
5117 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5118 return A->
getType() == types::TY_Nothing;
5122 nullptr, SingleDeviceOutput ? DDep : DDeps);
5123 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5129 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5139 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5145 llvm_unreachable(
"link action invalid here.");
5147 llvm_unreachable(
"ifsmerge action invalid here.");
5152 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5153 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5154 OutputTy = types::TY_Dependencies;
5159 if (!Args.hasFlag(options::OPT_frewrite_includes,
5160 options::OPT_fno_rewrite_includes,
false) &&
5161 !Args.hasFlag(options::OPT_frewrite_imports,
5162 options::OPT_fno_rewrite_imports,
false) &&
5163 !Args.hasFlag(options::OPT_fdirectives_only,
5164 options::OPT_fno_directives_only,
false) &&
5168 "Cannot preprocess this input type!");
5174 if (Args.hasArg(options::OPT_extract_api))
5183 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5184 (Input->
getType() == driver::types::TY_CXXModule ||
5185 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5186 !Args.getLastArg(options::OPT__precompile) &&
5187 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5192 "Cannot precompile this input type!");
5196 const char *ModName =
nullptr;
5197 if (OutputTy == types::TY_PCH) {
5198 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5199 ModName = A->getValue();
5201 OutputTy = types::TY_ModuleFile;
5204 if (Args.hasArg(options::OPT_fsyntax_only)) {
5206 OutputTy = types::TY_Nothing;
5212 if (Args.hasArg(options::OPT_fsyntax_only))
5214 if (Args.hasArg(options::OPT_rewrite_objc))
5216 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5218 types::TY_RewrittenLegacyObjC);
5219 if (Args.hasArg(options::OPT__analyze))
5221 if (Args.hasArg(options::OPT_emit_ast))
5223 if (Args.hasArg(options::OPT_emit_cir))
5225 if (Args.hasArg(options::OPT_module_file_info))
5227 if (Args.hasArg(options::OPT_verify_pch))
5229 if (Args.hasArg(options::OPT_extract_api))
5237 Args.hasFlag(options::OPT_offload_new_driver,
5238 options::OPT_no_offload_new_driver,
5245 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5246 !Args.hasArg(options::OPT_emit_llvm))
5247 Output = types::TY_PP_Asm;
5248 else if (Args.hasArg(options::OPT_S))
5249 Output = types::TY_LTO_IR;
5251 Output = types::TY_LTO_BC;
5256 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5259 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5260 options::OPT_no_use_spirv_backend,
5268 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5270 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5272 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5274 auto &DefaultToolChain =
C.getDefaultToolChain();
5275 auto DefaultToolChainTriple = DefaultToolChain.getTriple();
5280 bool EmitBitcodeForNonOffloadAMDSPIRV =
5281 !OffloadingToolChain && DefaultToolChainTriple.isSPIRV() &&
5282 DefaultToolChainTriple.getVendor() == llvm::Triple::VendorType::AMD &&
5283 !(Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_llvm));
5285 if (Args.hasArg(options::OPT_emit_llvm) ||
5286 EmitBitcodeForNonOffloadAMDSPIRV ||
5292 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5293 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5295 (Args.hasFlag(options::OPT_offload_new_driver,
5296 options::OPT_no_offload_new_driver,
5304 Args.hasArg(options::OPT_S) &&
5308 !Args.hasFlag(options::OPT_offload_new_driver,
5309 options::OPT_no_offload_new_driver,
5310 C.getActiveOffloadKinds() !=
5313 : types::TY_LLVM_BC;
5326 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5335 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5339 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5341 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5361 unsigned NumOutputs = 0;
5362 unsigned NumIfsOutputs = 0;
5363 for (
const Action *A :
C.getActions()) {
5366 if (A->
getType() == types::TY_DX_CONTAINER &&
5371 if (A->
getType() != types::TY_Nothing &&
5373 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5375 0 == NumIfsOutputs++) ||
5380 A->
getType() == types::TY_Nothing &&
5381 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5382 NumOutputs += A->
size();
5385 if (NumOutputs > 1) {
5386 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5387 FinalOutput =
nullptr;
5391 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5395 if (RawTriple.isOSBinFormatMachO())
5396 for (
const Arg *A :
C.getArgs())
5397 if (A->getOption().matches(options::OPT_arch))
5401 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5402 for (
Action *A :
C.getActions()) {
5409 const char *LinkingOutput =
nullptr;
5412 LinkingOutput = FinalOutput->getValue();
5421 LinkingOutput, CachedResults,
5428 for (
auto &J :
C.getJobs())
5429 J.InProcess =
false;
5432 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5433 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5438 const char *LinkingOutput =
nullptr;
5440 LinkingOutput = FinalOutput->getValue();
5447 using namespace llvm;
5450 <<
"output=" << LinkingOutput;
5451 outs() <<
", total="
5452 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5454 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5455 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5459 llvm::raw_string_ostream Out(Buffer);
5460 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5463 llvm::sys::printArg(Out, LinkingOutput,
true);
5464 Out <<
',' << ProcStat->TotalTime.count() <<
','
5465 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5470 llvm::sys::fs::OF_Append |
5471 llvm::sys::fs::OF_Text);
5476 llvm::errs() <<
"ERROR: Cannot lock file "
5478 <<
toString(L.takeError()) <<
"\n";
5489 bool ReportUnusedArguments =
5490 !Diags.hasErrorOccurred() &&
5491 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5494 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5496 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5499 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5500 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5502 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5506 return strstr(J.getCreator().getShortName(),
"assembler");
5508 for (Arg *A :
C.getArgs()) {
5512 if (!A->isClaimed()) {
5518 const Option &Opt = A->getOption();
5519 if (Opt.getKind() == Option::FlagClass) {
5520 bool DuplicateClaimed =
false;
5522 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5523 if (AA->isClaimed()) {
5524 DuplicateClaimed =
true;
5529 if (DuplicateClaimed)
5535 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5537 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5542 !
C.getActions().empty()) {
5543 Diag(diag::err_drv_unsupported_opt_for_target)
5545 }
else if (ReportUnusedArguments) {
5546 Diag(clang::diag::warn_drv_unused_argument)
5547 << A->getAsString(
C.getArgs());
5557class ToolSelector final {
5568 bool IsHostSelector;
5579 bool CanBeCollapsed =
true) {
5581 if (Inputs.size() != 1)
5584 Action *CurAction = *Inputs.begin();
5585 if (CanBeCollapsed &&
5591 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5595 if (!IsHostSelector) {
5596 if (OA->hasSingleDeviceDependence(
true)) {
5598 OA->getSingleDeviceDependence(
true);
5599 if (CanBeCollapsed &&
5602 SavedOffloadAction.push_back(OA);
5603 return dyn_cast<JobAction>(CurAction);
5605 }
else if (OA->hasHostDependence()) {
5606 CurAction = OA->getHostDependence();
5607 if (CanBeCollapsed &&
5610 SavedOffloadAction.push_back(OA);
5611 return dyn_cast<JobAction>(CurAction);
5616 return dyn_cast<JobAction>(CurAction);
5620 bool canCollapseAssembleAction()
const {
5621 return TC.useIntegratedAs() && !SaveTemps &&
5622 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5623 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5624 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5625 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5629 bool canCollapsePreprocessorAction()
const {
5630 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5631 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5632 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5637 struct JobActionInfo final {
5639 const JobAction *JA =
nullptr;
5647 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5648 ArrayRef<JobActionInfo> &ActionInfo,
5649 unsigned ElementNum) {
5650 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5651 for (
unsigned I = 0; I < ElementNum; ++I)
5652 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5653 ActionInfo[I].SavedOffloadAction.end());
5666 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5669 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5671 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5672 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5673 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5674 if (!AJ || !BJ || !CJ)
5678 const Tool *T = TC.SelectTool(*CJ);
5691 const Tool *BT = TC.SelectTool(*BJ);
5699 Inputs = CJ->getInputs();
5700 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5704 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5707 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5709 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5710 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5715 const Tool *T = TC.SelectTool(*BJ);
5722 Inputs = BJ->getInputs();
5723 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5727 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5730 if (ActionInfo.size() < 2)
5732 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5733 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5737 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5738 for (
auto &Input : AI.JA->getInputs())
5749 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5750 if (SaveTemps && !InputIsBitcode)
5754 const Tool *T = TC.SelectTool(*CJ);
5767 Inputs = CJ->getInputs();
5768 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5777 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5785 for (Action *A : Inputs) {
5786 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5788 NewInputs.push_back(A);
5794 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5795 PreprocessJobOffloadActions.end());
5796 NewInputs.append(PJ->input_begin(), PJ->input_end());
5802 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5804 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5806 assert(BaseAction &&
"Invalid base action.");
5822 SmallVector<JobActionInfo, 5> ActionChain(1);
5823 ActionChain.back().JA = BaseAction;
5824 while (ActionChain.back().JA) {
5825 const Action *CurAction = ActionChain.back().JA;
5828 ActionChain.resize(ActionChain.size() + 1);
5829 JobActionInfo &AI = ActionChain.back();
5833 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5837 ActionChain.pop_back();
5845 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5846 CollapsedOffloadAction);
5848 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5850 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5856 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5868 StringRef BoundArch,
5870 std::string TriplePlusArch = TC->
getTriple().normalize();
5871 if (!BoundArch.empty()) {
5872 TriplePlusArch +=
"-";
5873 TriplePlusArch += BoundArch;
5875 TriplePlusArch +=
"-";
5877 return TriplePlusArch;
5882 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5883 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5886 std::pair<const Action *, std::string> ActionTC = {
5888 auto CachedResult = CachedResults.find(ActionTC);
5889 if (CachedResult != CachedResults.end()) {
5890 return CachedResult->second;
5893 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5894 CachedResults, TargetDeviceOffloadKind);
5895 CachedResults[ActionTC] =
Result;
5900 const JobAction *JA,
const char *BaseInput,
5903 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5907 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5908 Path = A->getValue();
5909 if (llvm::sys::fs::is_directory(Path)) {
5911 llvm::sys::path::replace_extension(Tmp,
"json");
5912 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5915 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5918 Path = DumpDir->getValue();
5919 Path += llvm::sys::path::filename(BaseInput);
5921 Path = Result.getFilename();
5923 llvm::sys::path::replace_extension(Path,
"json");
5925 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5926 C.addTimeTraceFile(ResultFile, JA);
5927 C.addResultFile(ResultFile, JA);
5932 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5933 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5936 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5939 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5940 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5972 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5974 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5975 const char *DepBoundArch) {
5978 LinkingOutput, CachedResults,
5988 OA->doOnEachDependence(
5989 BuildingForOffloadDevice,
5990 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5992 C, DepA, DepTC, DepBoundArch,
false,
5993 !!DepBoundArch, LinkingOutput, CachedResults,
5997 A = BuildingForOffloadDevice
5998 ? OA->getSingleDeviceDependence(
true)
5999 : OA->getHostDependence();
6003 std::pair<const Action *, std::string> ActionTC = {
6004 OA->getHostDependence(),
6006 auto It = CachedResults.find(ActionTC);
6007 if (It != CachedResults.end()) {
6009 Inputs.append(OffloadDependencesInputInfo);
6014 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6017 const Arg &Input = IA->getInputArg();
6019 if (Input.getOption().matches(options::OPT_INPUT)) {
6020 const char *
Name = Input.getValue();
6023 return {InputInfo(A, &Input,
"")};
6026 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6027 const ToolChain *TC;
6030 if (!ArchName.empty())
6031 TC = &getToolChain(
C.getArgs(),
6033 C.getArgs(), ArchName));
6035 TC = &
C.getDefaultToolChain();
6038 MultipleArchs, LinkingOutput, CachedResults,
6039 TargetDeviceOffloadKind);
6050 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6053 return {InputInfo()};
6057 for (
const auto *OA : CollapsedOffloadActions)
6059 BuildingForOffloadDevice,
6060 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
6062 C, DepA, DepTC, DepBoundArch,
false,
6063 !!DepBoundArch, LinkingOutput, CachedResults,
6069 for (
const Action *Input : Inputs) {
6073 bool SubJobAtTopLevel =
6076 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6081 const char *BaseInput = InputInfos[0].getBaseInput();
6082 for (
auto &Info : InputInfos) {
6083 if (Info.isFilename()) {
6084 BaseInput = Info.getBaseInput();
6091 if (JA->
getType() == types::TY_dSYM)
6092 BaseInput = InputInfos[0].getFilename();
6095 if (!OffloadDependencesInputInfo.empty())
6096 InputInfos.append(OffloadDependencesInputInfo.begin(),
6097 OffloadDependencesInputInfo.end());
6100 llvm::Triple EffectiveTriple;
6102 const ArgList &Args =
6104 if (InputInfos.size() != 1) {
6108 EffectiveTriple = llvm::Triple(
6111 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6116 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6120 for (
auto &UI : UA->getDependentActionsInfo()) {
6122 "Unbundling with no offloading??");
6129 UI.DependentOffloadKind,
6130 UI.DependentToolChain->getTriple().normalize(),
6132 auto CurI = InputInfo(
6141 UnbundlingResults.push_back(CurI);
6150 Arch = UI.DependentBoundArch;
6155 UI.DependentOffloadKind)}] = {
6161 std::pair<const Action *, std::string> ActionTC = {
6163 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6164 "Result does not exist??");
6165 Result = CachedResults[ActionTC].front();
6166 }
else if (JA->
getType() == types::TY_Nothing)
6167 Result = {InputInfo(A, BaseInput)};
6177 AtTopLevel, MultipleArchs,
6180 if (T->
canEmitIR() && OffloadingPrefix.empty())
6186 <<
" - \"" << T->
getName() <<
"\", inputs: [";
6187 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6188 llvm::errs() << InputInfos[i].getAsString();
6190 llvm::errs() <<
", ";
6192 if (UnbundlingResults.empty())
6193 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6195 llvm::errs() <<
"], outputs: [";
6196 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6197 llvm::errs() << UnbundlingResults[i].getAsString();
6199 llvm::errs() <<
", ";
6201 llvm::errs() <<
"] \n";
6204 if (UnbundlingResults.empty())
6208 Args, LinkingOutput);
6214 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6215 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6227 if (ArgValue.empty()) {
6229 Filename = BaseName;
6230 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6232 llvm::sys::path::append(Filename, BaseName);
6235 if (!llvm::sys::path::has_extension(ArgValue)) {
6240 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6245 llvm::sys::path::replace_extension(Filename, Extension);
6248 return Args.MakeArgString(Filename.c_str());
6263 StringRef Suffix,
bool MultipleArchs,
6264 StringRef BoundArch,
6265 bool NeedUniqueDirectory)
const {
6267 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6268 std::optional<std::string> CrashDirectory =
6270 ? std::string(A->getValue())
6271 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6272 if (CrashDirectory) {
6273 if (!
getVFS().exists(*CrashDirectory))
6274 llvm::sys::fs::create_directories(*CrashDirectory);
6276 llvm::sys::path::append(Path, Prefix);
6277 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6278 if (std::error_code EC =
6279 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6280 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6284 if (MultipleArchs && !BoundArch.empty()) {
6285 if (NeedUniqueDirectory) {
6287 llvm::sys::path::append(TmpName,
6288 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6298 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6313 const char *BaseInput) {
6315 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6316 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6321 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6325 const char *BaseInput,
6326 StringRef OrigBoundArch,
bool AtTopLevel,
6328 StringRef OffloadingPrefix)
const {
6331 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6334 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6335 return C.addResultFile(FinalOutput->getValue(), &JA);
6339 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6341 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6343 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6344 NameArg = A->getValue();
6345 return C.addResultFile(
6355 if (JA.
getType() == types::TY_ModuleFile &&
6356 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6360 if (JA.
getType() == types::TY_PP_Asm &&
6361 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6362 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6365 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6368 if ((JA.
getType() == types::TY_Object &&
6369 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6370 JA.
getType() == types::TY_DX_CONTAINER) {
6371 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6375 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6377 C.getDefaultToolChain());
6380 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6381 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6382 StringRef
Name = llvm::sys::path::filename(BaseInput);
6383 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6389 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6390 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6394 if (JA.
getType() == types::TY_PP_Asm &&
6395 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6396 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6398 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6399 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6400 return C.addResultFile(
6405 if (JA.
getType() == types::TY_API_INFO &&
6406 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6407 C.getArgs().hasArg(options::OPT_o))
6408 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6409 <<
C.getArgs().getLastArgValue(options::OPT_o);
6416 bool SpecifiedModuleOutput =
6417 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6418 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6419 if (MultipleArchs && SpecifiedModuleOutput)
6420 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6425 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6426 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6432 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6434 StringRef
Name = llvm::sys::path::filename(BaseInput);
6435 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6436 const char *Suffix =
6441 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6442 bool NeedUniqueDirectory =
6445 Triple.isOSDarwin();
6446 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6447 NeedUniqueDirectory);
6456 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6461 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6462 llvm::sys::path::filename(BasePath));
6463 BaseName = ExternalPath;
6465 BaseName = BasePath;
6467 BaseName = llvm::sys::path::filename(BasePath);
6470 const char *NamedOutput;
6472 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6473 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6477 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6481 }
else if (JA.
getType() == types::TY_Image &&
6482 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6483 options::OPT__SLASH_o)) {
6487 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6491 }
else if (JA.
getType() == types::TY_Image) {
6501 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6502 options::OPT_fno_gpu_rdc,
false);
6504 if (UseOutExtension) {
6506 llvm::sys::path::replace_extension(Output,
"");
6508 Output += OffloadingPrefix;
6509 if (MultipleArchs && !BoundArch.empty()) {
6511 Output.append(BoundArch);
6513 if (UseOutExtension)
6515 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6518 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6519 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6520 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6523 .getLastArg(options::OPT__SLASH_o)
6528 const char *Suffix =
6530 assert(Suffix &&
"All types used for output should have a suffix.");
6532 std::string::size_type End = std::string::npos;
6534 End = BaseName.rfind(
'.');
6536 Suffixed += OffloadingPrefix;
6537 if (MultipleArchs && !BoundArch.empty()) {
6539 Suffixed.append(BoundArch);
6544 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6545 const llvm::opt::DerivedArgList &Args) {
6552 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6560 bool IsLinkerWrapper =
6562 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6563 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6564 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6566 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6570 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6574 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6575 JA.
getType() != types::TY_PCH) {
6576 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6578 llvm::sys::path::remove_filename(TempPath);
6579 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6580 llvm::sys::path::append(TempPath, OutputFileName);
6581 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6587 bool SameFile =
false;
6589 llvm::sys::fs::current_path(
Result);
6590 llvm::sys::path::append(
Result, BaseName);
6591 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6594 StringRef
Name = llvm::sys::path::filename(BaseInput);
6595 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6599 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6605 llvm::sys::path::remove_filename(BasePath);
6606 if (BasePath.empty())
6607 BasePath = NamedOutput;
6609 llvm::sys::path::append(BasePath, NamedOutput);
6610 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6613 return C.addResultFile(NamedOutput, &JA);
6619 -> std::optional<std::string> {
6622 for (
const auto &
Dir : P) {
6626 llvm::sys::path::append(P,
Name);
6627 if (llvm::sys::fs::exists(Twine(P)))
6628 return std::string(P);
6630 return std::nullopt;
6637 llvm::sys::path::append(R,
Name);
6638 if (llvm::sys::fs::exists(Twine(R)))
6639 return std::string(R);
6642 llvm::sys::path::append(P,
Name);
6643 if (llvm::sys::fs::exists(Twine(P)))
6644 return std::string(P);
6647 llvm::sys::path::append(D,
"..",
Name);
6648 if (llvm::sys::fs::exists(Twine(D)))
6649 return std::string(D);
6658 llvm::sys::path::append(R2,
"..",
"..",
Name);
6659 if (llvm::sys::fs::exists(Twine(R2)))
6660 return std::string(R2);
6662 return std::string(
Name);
6665void Driver::generatePrefixedToolNames(
6669 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6670 Names.emplace_back(
Tool);
6674 llvm::sys::path::append(Dir, Name);
6675 if (llvm::sys::fs::can_execute(Twine(Dir)))
6677 llvm::sys::path::remove_filename(Dir);
6683 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6688 if (llvm::sys::fs::is_directory(PrefixDir)) {
6691 return std::string(P);
6694 if (llvm::sys::fs::can_execute(Twine(P)))
6695 return std::string(P);
6700 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6708 for (
const auto &Path : List) {
6711 return std::string(P);
6715 if (llvm::ErrorOr<std::string> P =
6716 llvm::sys::findProgramByName(TargetSpecificExecutable))
6720 return std::string(
Name);
6725 std::string error =
"<NOT PRESENT>";
6727 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6732 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6749 llvm::sys::path::remove_filename(path);
6750 llvm::sys::path::append(path,
"libc++.modules.json");
6751 if (TC.
getVFS().exists(path))
6752 return static_cast<std::string
>(path);
6757 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6760 return evaluate(
"libc++.a").value_or(error);
6764 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6768 llvm::sys::path::remove_filename(path);
6769 llvm::sys::path::append(path,
"libstdc++.modules.json");
6770 if (TC.
getVFS().exists(path))
6771 return static_cast<std::string
>(path);
6776 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6779 return evaluate(
"libstdc++.a").value_or(error);
6788 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6790 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6794 return std::string(Path);
6799 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6801 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6805 return std::string(Path);
6810 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6814 Output = FpArg->getValue();
6818 if (!llvm::sys::path::has_extension(Output))
6821 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6822 Output = YcArg->getValue();
6825 llvm::sys::path::replace_extension(Output,
".pch");
6827 return std::string(Output);
6830const ToolChain &Driver::getOffloadToolChain(
6832 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6833 std::unique_ptr<ToolChain> &TC =
6834 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6835 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6837 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6840 switch (
Target.getOS()) {
6841 case llvm::Triple::CUDA:
6842 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6845 case llvm::Triple::AMDHSA:
6847 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6850 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6859 switch (
Target.getArch()) {
6860 case llvm::Triple::spir:
6861 case llvm::Triple::spir64:
6862 case llvm::Triple::spirv:
6863 case llvm::Triple::spirv32:
6864 case llvm::Triple::spirv64:
6867 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6871 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6875 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6879 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6893 return getToolChain(Args,
Target);
6897const ToolChain &Driver::getToolChain(
const ArgList &Args,
6898 const llvm::Triple &
Target)
const {
6900 auto &TC = ToolChains[
Target.str()];
6902 switch (
Target.getOS()) {
6903 case llvm::Triple::AIX:
6904 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6906 case llvm::Triple::Haiku:
6907 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6909 case llvm::Triple::Darwin:
6910 case llvm::Triple::MacOSX:
6911 case llvm::Triple::IOS:
6912 case llvm::Triple::TvOS:
6913 case llvm::Triple::WatchOS:
6914 case llvm::Triple::XROS:
6915 case llvm::Triple::DriverKit:
6916 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6918 case llvm::Triple::DragonFly:
6919 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6921 case llvm::Triple::OpenBSD:
6922 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6924 case llvm::Triple::NetBSD:
6925 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6927 case llvm::Triple::FreeBSD:
6929 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6932 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6934 case llvm::Triple::Linux:
6935 case llvm::Triple::ELFIAMCU:
6936 if (
Target.getArch() == llvm::Triple::hexagon)
6937 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6939 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6940 !
Target.hasEnvironment())
6941 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6944 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6946 else if (
Target.getArch() == llvm::Triple::ve)
6947 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6948 else if (
Target.isOHOSFamily())
6949 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6950 else if (
Target.isWALI())
6951 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6953 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6955 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6957 case llvm::Triple::Fuchsia:
6958 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6960 case llvm::Triple::Managarm:
6961 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6963 case llvm::Triple::Solaris:
6964 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6966 case llvm::Triple::CUDA:
6967 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6969 case llvm::Triple::AMDHSA: {
6970 if (
Target.getArch() == llvm::Triple::spirv64) {
6971 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6976 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6978 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6983 case llvm::Triple::AMDPAL:
6984 case llvm::Triple::Mesa3D:
6985 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6987 case llvm::Triple::UEFI:
6988 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6990 case llvm::Triple::Win32:
6991 switch (
Target.getEnvironment()) {
6993 if (
Target.isOSBinFormatELF())
6994 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6995 else if (
Target.isOSBinFormatMachO())
6996 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6998 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7000 case llvm::Triple::GNU:
7001 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7003 case llvm::Triple::Cygnus:
7004 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7006 case llvm::Triple::Itanium:
7007 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7010 case llvm::Triple::MSVC:
7011 case llvm::Triple::UnknownEnvironment:
7012 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7013 .starts_with_insensitive(
"bfd"))
7014 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7018 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7022 case llvm::Triple::PS4:
7023 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7025 case llvm::Triple::PS5:
7026 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7028 case llvm::Triple::Hurd:
7029 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7031 case llvm::Triple::LiteOS:
7032 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7034 case llvm::Triple::ZOS:
7035 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7037 case llvm::Triple::Vulkan:
7038 case llvm::Triple::ShaderModel:
7039 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7041 case llvm::Triple::ChipStar:
7042 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7047 switch (
Target.getArch()) {
7048 case llvm::Triple::tce:
7049 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7051 case llvm::Triple::tcele:
7052 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7054 case llvm::Triple::hexagon:
7055 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7058 case llvm::Triple::lanai:
7059 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7061 case llvm::Triple::xcore:
7062 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7064 case llvm::Triple::wasm32:
7065 case llvm::Triple::wasm64:
7066 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7068 case llvm::Triple::avr:
7069 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7071 case llvm::Triple::msp430:
7072 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7074 case llvm::Triple::riscv32:
7075 case llvm::Triple::riscv64:
7076 case llvm::Triple::riscv32be:
7077 case llvm::Triple::riscv64be:
7078 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7080 case llvm::Triple::ve:
7081 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7083 case llvm::Triple::spirv32:
7084 case llvm::Triple::spirv64:
7085 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7087 case llvm::Triple::csky:
7088 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7092 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7093 else if (
Target.isOSBinFormatELF())
7094 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7095 else if (
Target.isAppleFirmware())
7096 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7097 else if (
Target.isAppleMachO())
7098 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7099 else if (
Target.isOSBinFormatMachO())
7100 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7102 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7112 if (JA.
size() != 1 ||
7127 if (JA.
size() != 1 ||
7141 if (Args.hasArg(options::OPT_emit_static_lib))
7152 unsigned &Micro,
bool &HadExtra) {
7155 Major = Minor = Micro = 0;
7159 if (Str.consumeInteger(10, Major))
7163 if (!Str.consume_front(
"."))
7166 if (Str.consumeInteger(10, Minor))
7170 if (!Str.consume_front(
"."))
7173 if (Str.consumeInteger(10, Micro))
7191 unsigned CurDigit = 0;
7192 while (CurDigit < Digits.size()) {
7194 if (Str.consumeInteger(10, Digit))
7196 Digits[CurDigit] = Digit;
7199 if (!Str.consume_front(
"."))
7208llvm::opt::Visibility
7209Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7222const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7238 llvm_unreachable(
"Unhandled Mode");
7242 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7247 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7248 options::OPT_fno_save_optimization_record,
false))
7252 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7253 options::OPT_fno_save_optimization_record,
false))
7257 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7258 options::OPT_fno_save_optimization_record,
false))
7262 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7263 options::OPT_fno_save_optimization_record,
false))
7270 static StringRef OptName =
7272 llvm::StringRef Opt;
7273 for (StringRef Arg : Args) {
7274 if (!Arg.starts_with(OptName))
7280 return Opt.consume_front(OptName) ? Opt :
"";
7287 llvm::BumpPtrAllocator &Alloc,
7288 llvm::vfs::FileSystem *FS) {
7297 for (
const char *F : Args) {
7298 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7300 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7301 RSPQuoting = Windows;
7307 bool MarkEOLs = ClangCLMode;
7309 llvm::cl::TokenizerCallback Tokenizer;
7310 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7311 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7313 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7315 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7318 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7319 ECtx.setMarkEOLs(MarkEOLs);
7323 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7327 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7328 [](
const char *A) {
return A !=
nullptr; });
7329 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7332 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7333 Args.resize(newEnd - Args.begin());
7337 return llvm::Error::success();
7341 return SavedStrings.insert(S).first->getKeyData();
7375 llvm::StringSet<> &SavedStrings) {
7378 if (Edit[0] ==
'^') {
7379 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7380 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7381 Args.insert(Args.begin() + 1, Str);
7382 }
else if (Edit[0] ==
'+') {
7383 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7384 OS <<
"### Adding argument " << Str <<
" at end\n";
7385 Args.push_back(Str);
7386 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7387 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7388 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7389 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7390 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7392 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7394 if (Args[i] ==
nullptr)
7396 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7398 if (Repl != Args[i]) {
7399 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7403 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7404 auto Option = Edit.substr(1);
7405 for (
unsigned i = 1; i < Args.size();) {
7406 if (Option == Args[i]) {
7407 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7408 Args.erase(Args.begin() + i);
7409 if (Edit[0] ==
'X') {
7410 if (i < Args.size()) {
7411 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7412 Args.erase(Args.begin() + i);
7414 OS <<
"### Invalid X edit, end of command line!\n";
7419 }
else if (Edit[0] ==
'O') {
7420 for (
unsigned i = 1; i < Args.size();) {
7421 const char *A = Args[i];
7425 if (A[0] ==
'-' && A[1] ==
'O' &&
7426 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7427 (
'0' <= A[2] && A[2] <=
'9'))))) {
7428 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7429 Args.erase(Args.begin() + i);
7433 OS <<
"### Adding argument " << Edit <<
" at end\n";
7434 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7436 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7441 const char *OverrideStr,
7442 llvm::StringSet<> &SavedStrings,
7443 StringRef EnvVar, raw_ostream *OS) {
7445 OS = &llvm::nulls();
7447 if (OverrideStr[0] ==
'#') {
7449 OS = &llvm::nulls();
7452 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7456 const char *S = OverrideStr;
7458 const char *End = ::strchr(S,
' ');
7460 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static llvm::DenseSet< llvm::StringRef > inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static 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
This file defines functionality to support driver managed builds for compilations which use Clang mod...
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
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(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
void buildStdModuleManifestInputs(ArrayRef< StdModuleManifest::Module > ManifestEntries, Compilation &C, InputList &Inputs)
Constructs compilation inputs for each module listed in the provided Standard library module manifest...
void runModulesDriver(Compilation &C, ArrayRef< StdModuleManifest::Module > ManifestEntries)
Scans the compilation inputs for module dependencies and adjusts the compilation to build and supply ...
llvm::Expected< StdModuleManifest > readStdModuleManifest(llvm::StringRef ManifestPath, llvm::vfs::FileSystem &VFS)
Reads the Standard library module manifest at ManifestPath.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
StringRef getName(const HeaderType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.
The parsed Standard library module manifest.
std::vector< Module > Modules