18#include "clang/Config/config.h"
27#include "llvm/ADT/SmallString.h"
28#include "llvm/ADT/StringExtras.h"
29#include "llvm/ADT/StringRef.h"
30#include "llvm/ADT/Twine.h"
31#include "llvm/Config/llvm-config.h"
32#include "llvm/MC/MCTargetOptions.h"
33#include "llvm/MC/TargetRegistry.h"
34#include "llvm/Option/Arg.h"
35#include "llvm/Option/ArgList.h"
36#include "llvm/Option/OptTable.h"
37#include "llvm/Option/Option.h"
38#include "llvm/Support/ErrorHandling.h"
39#include "llvm/Support/FileSystem.h"
40#include "llvm/Support/FileUtilities.h"
41#include "llvm/Support/Path.h"
42#include "llvm/Support/Process.h"
43#include "llvm/Support/VersionTuple.h"
44#include "llvm/Support/VirtualFileSystem.h"
45#include "llvm/TargetParser/AArch64TargetParser.h"
46#include "llvm/TargetParser/RISCVISAInfo.h"
47#include "llvm/TargetParser/TargetParser.h"
48#include "llvm/TargetParser/Triple.h"
55using namespace driver;
61 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
62 options::OPT_fno_rtti, options::OPT_frtti);
66 const llvm::Triple &Triple,
67 const Arg *CachedRTTIArg) {
70 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
77 bool NoRTTI = Triple.isPS() || Triple.isDriverKit();
82 if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
94 auto addIfExists = [
this](
path_list &List,
const std::string &
Path) {
108 Triple.setEnvironment(
Env);
109 if (EffectiveTriple != llvm::Triple())
110 EffectiveTriple.setEnvironment(
Env);
120 return Args.hasFlag(options::OPT_fintegrated_as,
121 options::OPT_fno_integrated_as,
129 "(Non-)integrated backend set incorrectly!");
131 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
132 options::OPT_fno_integrated_objemitter,
140 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
142 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
143 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
145 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
146 A = Args.getLastArg(options::OPT_fintegrated_objemitter);
148 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
154 return ENABLE_X86_RELAX_RELOCATIONS;
158 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE &&
getTriple().isOSLinux();
162 const llvm::opt::ArgList &Args) {
163 for (
const Arg *MultilibFlagArg :
164 Args.filtered(options::OPT_fmultilib_flag)) {
165 List.push_back(MultilibFlagArg->getAsString(Args));
166 MultilibFlagArg->claim();
171 const llvm::Triple &Triple,
172 const llvm::opt::ArgList &Args,
174 std::vector<StringRef> Features;
179 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
180 UnifiedFeatures.end());
181 std::vector<std::string> MArch;
182 for (
const auto &Ext : AArch64::Extensions)
183 if (!Ext.UserVisibleName.empty())
184 if (FeatureSet.contains(Ext.PosTargetFeature))
185 MArch.push_back(Ext.UserVisibleName.str());
186 for (
const auto &Ext : AArch64::Extensions)
187 if (!Ext.UserVisibleName.empty())
188 if (FeatureSet.contains(Ext.NegTargetFeature))
189 MArch.push_back((
"no" + Ext.UserVisibleName).str());
191 for (
const auto &ArchInfo : AArch64::ArchInfos)
192 if (FeatureSet.contains(ArchInfo->ArchFeature))
195 MArch.insert(MArch.begin(), (
"-march=" +
ArchName).str());
196 Result.push_back(llvm::join(MArch,
"+"));
199 const Arg *BranchProtectionArg =
200 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
201 if (BranchProtectionArg) {
202 Result.push_back(BranchProtectionArg->getAsString(Args));
205 if (FeatureSet.contains(
"+strict-align"))
206 Result.push_back(
"-mno-unaligned-access");
208 Result.push_back(
"-munaligned-access");
210 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
211 options::OPT_mlittle_endian)) {
212 if (Endian->getOption().matches(options::OPT_mbig_endian))
213 Result.push_back(Endian->getAsString(Args));
216 const Arg *ABIArg = Args.getLastArgNoClaim(options::OPT_mabi_EQ);
218 Result.push_back(ABIArg->getAsString(Args));
221 if (
const Arg *A = Args.getLastArg(options::OPT_O_Group);
222 A && A->getOption().matches(options::OPT_O)) {
223 switch (A->getValue()[0]) {
237 llvm::Reloc::Model RelocationModel,
238 const llvm::opt::ArgList &Args,
240 std::vector<StringRef> Features;
242 D, Triple, Args, Features,
false ,
true );
244 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
245 UnifiedFeatures.end());
246 std::vector<std::string> MArch;
247 for (
const auto &Ext : ARM::ARCHExtNames)
248 if (!Ext.Name.empty())
249 if (FeatureSet.contains(Ext.Feature))
250 MArch.push_back(Ext.Name.str());
251 for (
const auto &Ext : ARM::ARCHExtNames)
252 if (!Ext.Name.empty())
253 if (FeatureSet.contains(Ext.NegFeature))
254 MArch.push_back((
"no" + Ext.Name).str());
255 MArch.insert(MArch.begin(), (
"-march=" + Triple.getArchName()).str());
256 Result.push_back(llvm::join(MArch,
"+"));
259#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
260 case llvm::ARM::KIND: \
261 Result.push_back("-mfpu=" NAME); \
263#include "llvm/TargetParser/ARMTargetParser.def"
265 llvm_unreachable(
"Invalid FPUKind");
269 case arm::FloatABI::Soft:
270 Result.push_back(
"-mfloat-abi=soft");
272 case arm::FloatABI::SoftFP:
273 Result.push_back(
"-mfloat-abi=softfp");
275 case arm::FloatABI::Hard:
276 Result.push_back(
"-mfloat-abi=hard");
278 case arm::FloatABI::Invalid:
279 llvm_unreachable(
"Invalid float ABI");
282 if (RelocationModel == llvm::Reloc::ROPI ||
283 RelocationModel == llvm::Reloc::ROPI_RWPI)
284 Result.push_back(
"-fropi");
286 Result.push_back(
"-fno-ropi");
288 if (RelocationModel == llvm::Reloc::RWPI ||
289 RelocationModel == llvm::Reloc::ROPI_RWPI)
290 Result.push_back(
"-frwpi");
292 Result.push_back(
"-fno-rwpi");
294 const Arg *BranchProtectionArg =
295 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
296 if (BranchProtectionArg) {
297 Result.push_back(BranchProtectionArg->getAsString(Args));
300 if (FeatureSet.contains(
"+strict-align"))
301 Result.push_back(
"-mno-unaligned-access");
303 Result.push_back(
"-munaligned-access");
305 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
306 options::OPT_mlittle_endian)) {
307 if (Endian->getOption().matches(options::OPT_mbig_endian))
308 Result.push_back(Endian->getAsString(Args));
311 if (
const Arg *A = Args.getLastArg(options::OPT_O_Group);
312 A && A->getOption().matches(options::OPT_O)) {
313 switch (A->getValue()[0]) {
327 const llvm::opt::ArgList &Args,
331 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
333 if (!llvm::errorToBool(ISAInfo.takeError()))
334 Result.push_back(
"-march=" + (*ISAInfo)->toString());
343 std::vector<std::string>
Result;
345 Result.push_back(
"--target=" + Triple.str());
351 llvm::Reloc::Model RelocationModel;
356 std::tie(RelocationModel, PICLevel, IsPIE) =
ParsePICArgs(*
this, Args);
359 switch (Triple.getArch()) {
360 case llvm::Triple::aarch64:
361 case llvm::Triple::aarch64_32:
362 case llvm::Triple::aarch64_be:
365 case llvm::Triple::arm:
366 case llvm::Triple::armeb:
367 case llvm::Triple::thumb:
368 case llvm::Triple::thumbeb:
371 case llvm::Triple::riscv32:
372 case llvm::Triple::riscv64:
382 Result.push_back(
"-fno-rtti");
384 Result.push_back(
"-frtti");
387 Result.push_back(
"-fno-exceptions");
389 Result.push_back(
"-fexceptions");
391 if (RelocationModel == llvm::Reloc::PIC_)
392 Result.push_back(IsPIE ? (PICLevel > 1 ?
"-fPIE" :
"-fpie")
393 : (PICLevel > 1 ?
"-fPIC" :
"-fpic"));
395 Result.push_back(
"-fno-pic");
405 SanitizerArgs SanArgs(*
this, JobArgs, !SanitizerArgsChecked);
406 SanitizerArgsChecked =
true;
411 XRayArgs XRayArguments(*
this, JobArgs);
412 return XRayArguments;
419 const char *ModeFlag;
428 static const DriverSuffix DriverSuffixes[] = {
430 {
"clang++",
"--driver-mode=g++"},
431 {
"clang-c++",
"--driver-mode=g++"},
432 {
"clang-cc",
nullptr},
433 {
"clang-cpp",
"--driver-mode=cpp"},
434 {
"clang-g++",
"--driver-mode=g++"},
435 {
"clang-gcc",
nullptr},
436 {
"clang-cl",
"--driver-mode=cl"},
438 {
"cpp",
"--driver-mode=cpp"},
439 {
"cl",
"--driver-mode=cl"},
440 {
"++",
"--driver-mode=g++"},
441 {
"flang",
"--driver-mode=flang"},
444 {
"flang-new",
"--driver-mode=flang"},
445 {
"clang-dxc",
"--driver-mode=dxc"},
448 for (
const auto &DS : DriverSuffixes) {
449 StringRef Suffix(DS.Suffix);
450 if (ProgName.ends_with(Suffix)) {
451 Pos = ProgName.size() - Suffix.size();
461 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
462 if (is_style_windows(llvm::sys::path::Style::native)) {
464 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
480 if (!DS && ProgName.ends_with(
".exe")) {
483 ProgName = ProgName.drop_back(StringRef(
".exe").size());
490 ProgName = ProgName.rtrim(
"0123456789.");
497 ProgName = ProgName.slice(0, ProgName.rfind(
'-'));
510 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
512 size_t LastComponent = ProgName.rfind(
'-', SuffixPos);
513 if (LastComponent == std::string::npos)
515 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
516 SuffixEnd - LastComponent - 1);
519 StringRef Prefix(ProgName);
520 Prefix = Prefix.slice(0, LastComponent);
521 std::string IgnoredError;
522 bool IsRegistered = llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError);
531 switch (Triple.getArch()) {
532 case llvm::Triple::aarch64: {
537 case llvm::Triple::aarch64_32:
539 case llvm::Triple::ppc:
541 case llvm::Triple::ppcle:
543 case llvm::Triple::ppc64:
545 case llvm::Triple::ppc64le:
548 return Triple.getArchName();
561Tool *ToolChain::getClang()
const {
567Tool *ToolChain::getFlang()
const {
578 llvm_unreachable(
"Linking is not supported by this toolchain");
582 llvm_unreachable(
"Creating static lib is not supported by this toolchain");
585Tool *ToolChain::getAssemble()
const {
588 return Assemble.get();
591Tool *ToolChain::getClangAs()
const {
594 return Assemble.get();
597Tool *ToolChain::getLink()
const {
603Tool *ToolChain::getStaticLibTool()
const {
606 return StaticLibTool.get();
609Tool *ToolChain::getIfsMerge()
const {
612 return IfsMerge.get();
615Tool *ToolChain::getOffloadBundler()
const {
621Tool *ToolChain::getOffloadPackager()
const {
627Tool *ToolChain::getLinkerWrapper()
const {
636 return getAssemble();
639 return getIfsMerge();
645 return getStaticLibTool();
656 llvm_unreachable(
"Invalid tool kind.");
669 return getOffloadBundler();
672 return getOffloadPackager();
674 return getLinkerWrapper();
677 llvm_unreachable(
"Invalid tool kind.");
681 const ArgList &Args) {
682 const llvm::Triple &Triple = TC.
getTriple();
683 bool IsWindows = Triple.isOSWindows();
686 return Triple.getArchName();
688 if (TC.
getArch() == llvm::Triple::arm || TC.
getArch() == llvm::Triple::armeb)
694 if (TC.
getArch() == llvm::Triple::x86 && Triple.isAndroid())
697 if (TC.
getArch() == llvm::Triple::x86_64 && Triple.isX32())
700 return llvm::Triple::getArchTypeName(TC.
getArch());
704 if (Triple.isOSDarwin())
707 switch (Triple.getOS()) {
708 case llvm::Triple::FreeBSD:
710 case llvm::Triple::NetBSD:
712 case llvm::Triple::OpenBSD:
714 case llvm::Triple::Solaris:
716 case llvm::Triple::AIX:
730 }
else if (Triple.isOSUnknown()) {
731 llvm::sys::path::append(
Path,
"lib");
735 return std::string(
Path);
742 return llvm::sys::path::filename(CRTAbsolutePath).str();
748 bool IsFortran)
const {
750 bool IsITANMSVCWindows =
751 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
758 Suffix = IsITANMSVCWindows ?
".obj" :
".o";
761 Suffix = IsITANMSVCWindows ?
".lib" :
".a";
764 if (TT.isOSWindows())
765 Suffix = TT.isOSCygMing() ?
".dll.a" :
".lib";
766 else if (TT.isOSAIX())
773 std::string ArchAndEnv;
776 const char *
Env = TT.isAndroid() ?
"-android" :
"";
777 ArchAndEnv = (
"-" +
Arch +
Env).str();
780 std::string LibName = IsFortran ?
"flang_rt." :
"clang_rt.";
781 return (Prefix + Twine(LibName) + Component + ArchAndEnv + Suffix).str();
788 Args, Component,
Type,
false, IsFortran);
792 llvm::sys::path::append(
P, CRTBasename);
794 return std::string(
P);
801 !IsFortran, IsFortran);
803 llvm::sys::path::append(OldPath, CRTBasename);
805 return std::string(OldPath);
810 return std::string(
Path);
816 bool isFortran)
const {
822 llvm::opt::ArgStringList &CmdArgs)
const {
827 if (!
getTriple().isKnownWindowsMSVCEnvironment()) {
829 F128LibName.consume_front_insensitive(
"lib");
830 if (!F128LibName.empty()) {
832 CmdArgs.push_back(
"-lflang_rt.quadmath");
835 CmdArgs.push_back(Args.MakeArgString(
"-l" + F128LibName));
844 CmdArgs.push_back(
"-lexecinfo");
848 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
849 options::OPT_fno_openmp,
false)) {
853 CmdArgs.push_back(
"-latomic");
858 ArgStringList &CmdArgs)
const {
859 auto AddLibSearchPathIfExists = [&](
const Twine &
Path) {
861 if (!llvm::sys::fs::is_directory(
Path))
864 if (
getTriple().isKnownWindowsMSVCEnvironment())
865 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" +
Path));
867 CmdArgs.push_back(Args.MakeArgString(
"-L" +
Path));
880 llvm::sys::path::parent_path(
getDriver().Dir);
881 llvm::sys::path::append(DefaultLibPath,
"lib");
882 AddLibSearchPathIfExists(DefaultLibPath);
886 llvm::opt::ArgStringList &CmdArgs)
const {
889 if (Args.hasFlag(options::OPT_static_libflangrt,
890 options::OPT_shared_libflangrt,
getTriple().isOSAIX()))
894 CmdArgs.push_back(
"-lflang_rt.runtime");
902std::optional<std::string>
903ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir)
const {
904 llvm::Triple TripleWithoutLevel(
getTriple());
905 TripleWithoutLevel.setEnvironmentName(
"android");
906 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
907 unsigned TripleVersion =
getTriple().getEnvironmentVersion().getMajor();
908 unsigned BestVersion = 0;
911 bool UsingUnversionedDir =
false;
913 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(BaseDir, EC), LE;
914 !EC && LI != LE; LI = LI.increment(EC)) {
915 StringRef DirName = llvm::sys::path::filename(LI->path());
916 StringRef DirNameSuffix = DirName;
917 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
918 if (DirNameSuffix.empty() && TripleDir.empty()) {
920 UsingUnversionedDir =
true;
923 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
924 Version < TripleVersion) {
925 BestVersion = Version;
927 UsingUnversionedDir =
false;
933 if (TripleDir.empty())
937 llvm::sys::path::append(
P, TripleDir);
938 if (UsingUnversionedDir)
940 return std::string(
P);
944 return (Triple.hasEnvironment()
945 ? llvm::Triple(Triple.getArchName(), Triple.getVendorName(),
946 llvm::Triple::getOSTypeName(Triple.getOS()),
947 llvm::Triple::getEnvironmentTypeName(
948 Triple.getEnvironment()))
949 : llvm::Triple(Triple.getArchName(), Triple.getVendorName(),
950 llvm::Triple::getOSTypeName(Triple.getOS())));
953std::optional<std::string>
955 auto getPathForTriple =
956 [&](
const llvm::Triple &Triple) -> std::optional<std::string> {
958 llvm::sys::path::append(
P, Triple.str());
960 return std::string(
P);
965 if (
auto Path = getPathForTriple(
T))
969 llvm::Triple AIXTriple;
970 if (
T.getEnvironment() == Triple::UnknownEnvironment) {
972 AIXTriple = llvm::Triple(
T.getArchName(),
T.getVendorName(),
973 llvm::Triple::getOSTypeName(
T.getOS()));
978 if (
auto Path = getPathForTriple(AIXTriple))
983 (!
T.getOSVersion().empty() || !
T.getEnvironmentVersion().empty())) {
986 if (
auto Path = getPathForTriple(TripleWithoutVersion))
1005 if (
T.getArch() == Triple::arm && !
T.isArmMClass()) {
1006 llvm::Triple ArmTriple =
T;
1007 ArmTriple.setArch(Triple::arm);
1008 if (
auto Path = getPathForTriple(ArmTriple))
1013 return getFallbackAndroidTargetPath(BaseDir);
1020 llvm::sys::path::append(
P,
"lib");
1024 if (Triple.isOSDarwin())
1027 llvm::sys::path::append(
P, Triple.str());
1028 return std::string(
P);
1033 llvm::sys::path::append(
P,
"..",
"lib");
1039 llvm::sys::path::append(
P,
"..",
"include");
1048 llvm::sys::path::append(
Path,
"lib");
1050 llvm::sys::path::append(
Path, S);
1051 Paths.push_back(std::string(
Path));
1060 if (Args.hasArg(options::OPT_noprofilelib))
1063 return Args.hasArg(options::OPT_fprofile_generate) ||
1064 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
1065 Args.hasArg(options::OPT_fcs_profile_generate) ||
1066 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
1067 Args.hasArg(options::OPT_fprofile_instr_generate) ||
1068 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
1069 Args.hasArg(options::OPT_fcreate_profile) ||
1070 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage) ||
1071 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage_EQ);
1075 return Args.hasArg(options::OPT_coverage) ||
1076 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
1082 if (
getDriver().ShouldUseClangCompiler(JA))
return getClang();
1086 return getClangAs();
1100 *LinkerIsLLD =
false;
1104 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
1112 if (
const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
1113 std::string
Path(A->getValue());
1114 if (!
Path.empty()) {
1115 if (llvm::sys::path::parent_path(
Path).empty())
1117 if (llvm::sys::fs::can_execute(
Path)) {
1119 *LinkerIsLLD = UseLinker ==
"lld";
1120 return std::string(
Path);
1123 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
1128 if (UseLinker.empty() || UseLinker ==
"ld") {
1130 if (llvm::sys::path::is_absolute(DefaultLinker))
1131 return std::string(DefaultLinker);
1140 if (UseLinker.contains(
'/'))
1143 if (llvm::sys::path::is_absolute(UseLinker)) {
1146 if (llvm::sys::fs::can_execute(UseLinker))
1147 return std::string(UseLinker);
1150 if (Triple.isOSDarwin())
1151 LinkerName.append(
"ld64.");
1153 LinkerName.append(
"ld.");
1154 LinkerName.append(UseLinker);
1157 if (llvm::sys::fs::can_execute(LinkerPath)) {
1159 *LinkerIsLLD = UseLinker ==
"lld";
1165 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
1172 if (Triple.isOSDarwin())
1183 if (D.
IsFlangMode() &&
id == types::TY_PP_Fortran)
1184 id = types::TY_Fortran;
1194 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
1195 switch (HostTriple.getArch()) {
1198 case llvm::Triple::arm:
1199 case llvm::Triple::armeb:
1200 case llvm::Triple::thumb:
1201 case llvm::Triple::thumbeb:
1202 return getArch() != llvm::Triple::arm &&
getArch() != llvm::Triple::thumb &&
1203 getArch() != llvm::Triple::armeb &&
getArch() != llvm::Triple::thumbeb;
1205 return HostTriple.getArch() !=
getArch();
1214llvm::ExceptionHandling
1216 return llvm::ExceptionHandling::None;
1220 if (Model ==
"single") {
1222 return Triple.getArch() == llvm::Triple::arm ||
1223 Triple.getArch() == llvm::Triple::armeb ||
1224 Triple.getArch() == llvm::Triple::thumb ||
1225 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
1226 }
else if (Model ==
"posix")
1238 case llvm::Triple::x86_64: {
1240 if (!Triple.isOSBinFormatMachO())
1243 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1246 StringRef MArch = A->getValue();
1247 if (MArch ==
"x86_64h")
1248 Triple.setArchName(MArch);
1250 return Triple.getTriple();
1252 case llvm::Triple::aarch64: {
1255 if (!Triple.isOSBinFormatMachO())
1256 return Triple.getTriple();
1258 if (Triple.isArm64e())
1259 return Triple.getTriple();
1264 Triple.setArchName(
"arm64");
1265 return Triple.getTriple();
1267 case llvm::Triple::aarch64_32:
1269 case llvm::Triple::amdgcn: {
1271 if (Args.getLastArgValue(options::OPT_mcpu_EQ) ==
"amdgcnspirv")
1272 Triple.setArch(llvm::Triple::ArchType::spirv64);
1273 return Triple.getTriple();
1275 case llvm::Triple::arm:
1276 case llvm::Triple::armeb:
1277 case llvm::Triple::thumb:
1278 case llvm::Triple::thumbeb: {
1282 return Triple.getTriple();
1297 ArgStringList &CC1Args)
const {
1302 const ArgList &DriverArgs, ArgStringList &CC1Args,
1306 ArgStringList &CC1ASArgs)
const {}
1311 llvm::opt::ArgStringList &CmdArgs)
const {
1319 const ArgList &Args)
const {
1321 return *runtimeLibType;
1323 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
1324 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
1327 if (LibName ==
"compiler-rt")
1329 else if (LibName ==
"libgcc")
1331 else if (LibName ==
"platform")
1336 << A->getAsString(Args);
1341 return *runtimeLibType;
1345 const ArgList &Args)
const {
1347 return *unwindLibType;
1349 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
1350 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
1352 if (LibName ==
"none")
1354 else if (LibName ==
"platform" || LibName ==
"") {
1363 }
else if (LibName ==
"libunwind") {
1367 }
else if (LibName ==
"libgcc")
1372 << A->getAsString(Args);
1377 return *unwindLibType;
1382 return *cxxStdlibType;
1384 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1385 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
1388 if (LibName ==
"libc++")
1390 else if (LibName ==
"libstdc++")
1392 else if (LibName ==
"platform")
1397 << A->getAsString(Args);
1402 return *cxxStdlibType;
1407 llvm::opt::ArgStringList &CC1Args,
1408 const Twine &
Path) {
1409 CC1Args.push_back(
"-internal-iframework");
1410 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1422 ArgStringList &CC1Args,
1423 const Twine &
Path) {
1424 CC1Args.push_back(
"-internal-externc-isystem");
1425 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1429 ArgStringList &CC1Args,
1430 const Twine &
Path) {
1431 if (llvm::sys::fs::exists(
Path))
1437 ArgStringList &CC1Args,
1438 const Twine &
Path) {
1439 CC1Args.push_back(
"-internal-isystem");
1440 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1445 ArgStringList &CC1Args,
1447 for (
const auto &
Path : Paths) {
1448 CC1Args.push_back(
"-internal-iframework");
1449 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1455 ArgStringList &CC1Args,
1457 for (
const auto &
Path : Paths) {
1458 CC1Args.push_back(
"-internal-isystem");
1459 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1464 const Twine &
C,
const Twine &
D) {
1466 llvm::sys::path::append(
Result, llvm::sys::path::Style::posix, A, B,
C,
D);
1467 return std::string(
Result);
1473 std::string MaxVersionString;
1475 llvm::sys::path::append(
Path,
"c++");
1476 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(
Path, EC), LE;
1477 !EC && LI != LE; LI = LI.increment(EC)) {
1478 StringRef VersionText = llvm::sys::path::filename(LI->path());
1480 if (VersionText[0] ==
'v' &&
1481 !VersionText.substr(1).getAsInteger(10, Version)) {
1482 if (Version > MaxVersion) {
1483 MaxVersion = Version;
1484 MaxVersionString = std::string(VersionText);
1490 return MaxVersionString;
1494 ArgStringList &CC1Args)
const {
1504 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1508 const llvm::opt::ArgList &DriverArgs,
1509 llvm::opt::ArgStringList &CC1Args)
const {
1510 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1519 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1520 for (
const auto &
P :
1521 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1527 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1528 options::OPT_nostdlibxx);
1532 ArgStringList &CmdArgs)
const {
1533 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1534 "should not have called this");
1539 CmdArgs.push_back(
"-lc++");
1540 if (Args.hasArg(options::OPT_fexperimental_library))
1541 CmdArgs.push_back(
"-lc++experimental");
1545 CmdArgs.push_back(
"-lstdc++");
1551 ArgStringList &CmdArgs)
const {
1553 if(LibPath.length() > 0)
1554 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
1558 ArgStringList &CmdArgs)
const {
1559 CmdArgs.push_back(
"-lcc_kext");
1563 std::string &
Path)
const {
1567 bool Default = !Args.hasArgNoClaim(options::OPT_shared);
1573 Arg *A = Args.getLastArg(
1574 options::OPT_ffast_math, options::OPT_fno_fast_math,
1575 options::OPT_funsafe_math_optimizations,
1576 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ);
1578 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1579 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1581 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
1582 StringRef Model = A->getValue();
1583 if (Model !=
"fast" && Model !=
"aggressive")
1590 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz,
Default))
1595 return (
Path !=
"crtfastmath.o");
1599 ArgStringList &CmdArgs)
const {
1602 CmdArgs.push_back(Args.MakeArgString(
Path));
1620 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1621 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1622 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1623 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1624 SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1625 if (
getTriple().getArch() == llvm::Triple::x86 ||
1626 getTriple().getArch() == llvm::Triple::x86_64 ||
1627 getTriple().getArch() == llvm::Triple::arm ||
1631 Res |= SanitizerKind::CFIICall;
1632 if (
getTriple().getArch() == llvm::Triple::x86_64 ||
1634 Res |= SanitizerKind::ShadowCallStack;
1636 Res |= SanitizerKind::MemTag;
1641 ArgStringList &CC1Args)
const {}
1644 ArgStringList &CC1Args)
const {}
1647 ArgStringList &CC1Args)
const {}
1656 ArgStringList &CC1Args)
const {}
1660 return VersionTuple(Version);
1662 if (Version < 10000)
1663 return VersionTuple(Version / 100, Version % 100);
1665 unsigned Build = 0, Factor = 1;
1666 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1667 Build = Build + (Version % 10) * Factor;
1668 return VersionTuple(Version / 100, Version % 100, Build);
1673 const llvm::opt::ArgList &Args)
const {
1674 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1675 const Arg *MSCompatibilityVersion =
1676 Args.getLastArg(options::OPT_fms_compatibility_version);
1678 if (MSCVersion && MSCompatibilityVersion) {
1680 D->Diag(diag::err_drv_argument_not_allowed_with)
1681 << MSCVersion->getAsString(Args)
1682 << MSCompatibilityVersion->getAsString(Args);
1683 return VersionTuple();
1686 if (MSCompatibilityVersion) {
1688 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1690 D->Diag(diag::err_drv_invalid_value)
1691 << MSCompatibilityVersion->getAsString(Args)
1692 << MSCompatibilityVersion->getValue();
1699 unsigned Version = 0;
1700 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1702 D->Diag(diag::err_drv_invalid_value)
1703 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1709 return VersionTuple();
1713 const llvm::opt::DerivedArgList &Args,
bool SameTripleAsHost,
1715 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1717 bool Modified =
false;
1720 for (
auto *A : Args) {
1725 if (A->getOption().matches(options::OPT_m_Group)) {
1728 if (SameTripleAsHost ||
1729 A->getOption().matches(options::OPT_mcode_object_version_EQ))
1738 bool XOpenMPTargetNoTriple =
1739 A->getOption().matches(options::OPT_Xopenmp_target);
1741 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1746 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1749 }
else if (XOpenMPTargetNoTriple) {
1751 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1759 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1760 if (!XOpenMPTargetArg || Index > Prev + 1) {
1761 if (!A->isClaimed()) {
1762 getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1763 << A->getAsString(Args);
1767 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1768 Args.getAllArgValues(options::OPT_offload_targets_EQ).size() != 1) {
1769 getDriver().
Diag(diag::err_drv_Xopenmp_target_missing_triple);
1772 XOpenMPTargetArg->setBaseArg(A);
1773 A = XOpenMPTargetArg.release();
1774 AllocatedArgs.push_back(A);
1790 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1791 llvm::opt::DerivedArgList *DAL,
1794 unsigned ValuePos = 1;
1795 if (A->getOption().matches(options::OPT_Xarch_device) ||
1796 A->getOption().matches(options::OPT_Xarch_host))
1799 const InputArgList &BaseArgs = Args.getBaseArgs();
1800 unsigned Index = BaseArgs.MakeIndex(A->getValue(ValuePos));
1801 unsigned Prev = Index;
1802 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(
1812 if (!XarchArg || Index > Prev + 1) {
1813 getDriver().
Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1814 << A->getAsString(Args);
1820 "invalid Xarch argument: '%0', not all driver "
1821 "options can be forwared via Xarch argument");
1822 Diags.Report(DiagID) << A->getAsString(Args);
1826 XarchArg->setBaseArg(A);
1827 A = XarchArg.release();
1835 for (
const char *
Value : A->getValues()) {
1836 auto Opt = Opts.getOption(options::OPT_Zlinker_input);
1837 unsigned Index = BaseArgs.MakeIndex(Opt.getName(),
Value);
1839 new Arg(Opt, BaseArgs.MakeArgString(Opt.getPrefix() + Opt.getName()),
1840 Index, BaseArgs.getArgString(Index + 1), A);
1842 DAL->append(NewArg);
1844 DAL->AddSynthesizedArg(NewArg);
1846 AllocatedArgs->push_back(NewArg);
1851 DAL->AddSynthesizedArg(A);
1853 AllocatedArgs->push_back(A);
1857 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1860 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1861 bool Modified =
false;
1864 for (Arg *A : Args) {
1865 bool NeedTrans =
false;
1867 if (A->getOption().matches(options::OPT_Xarch_device)) {
1868 NeedTrans = IsDevice;
1870 }
else if (A->getOption().matches(options::OPT_Xarch_host)) {
1871 NeedTrans = !IsDevice;
1873 }
else if (A->getOption().matches(options::OPT_Xarch__)) {
1875 (!BoundArch.empty() && A->getValue() == BoundArch);
1878 if (NeedTrans ||
Skip)
Defines types useful for describing an Objective-C runtime.
Defines the clang::SanitizerKind enum.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
The basic abstraction for the target Objective-C runtime.
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
The base class of the type hierarchy.
ActionClass getKind() const
@ OffloadUnbundlingJobClass
@ BinaryTranslatorJobClass
@ OffloadBundlingJobClass
@ VerifyDebugInfoJobClass
@ OffloadPackagerJobClass
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
DiagnosticsEngine & getDiags() const
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
DiagnosticBuilder Diag(unsigned DiagID) const
StringRef getFlangF128MathLibrary() const
const llvm::opt::OptTable & getOpts() const
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_OMP
The LLVM OpenMP runtime.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
StringRef getPreferredLinker() const
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
std::vector< std::string > flags_list
Set a ToolChain's effective triple.
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
Helper structure used to pass information extracted from clang executable name such as i686-linux-and...