18#include "clang/Config/config.h"
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/ADT/SmallString.h"
29#include "llvm/ADT/StringExtras.h"
30#include "llvm/ADT/StringRef.h"
31#include "llvm/ADT/Twine.h"
32#include "llvm/Config/llvm-config.h"
33#include "llvm/MC/MCTargetOptions.h"
34#include "llvm/MC/TargetRegistry.h"
35#include "llvm/Option/Arg.h"
36#include "llvm/Option/ArgList.h"
37#include "llvm/Option/OptTable.h"
38#include "llvm/Option/Option.h"
39#include "llvm/Support/ErrorHandling.h"
40#include "llvm/Support/FileSystem.h"
41#include "llvm/Support/FileUtilities.h"
42#include "llvm/Support/Path.h"
43#include "llvm/Support/VersionTuple.h"
44#include "llvm/Support/VirtualFileSystem.h"
45#include "llvm/TargetParser/AArch64TargetParser.h"
46#include "llvm/TargetParser/TargetParser.h"
47#include "llvm/TargetParser/Triple.h"
54using namespace driver;
60 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
61 options::OPT_fno_rtti, options::OPT_frtti);
65 const llvm::Triple &Triple,
66 const Arg *CachedRTTIArg) {
69 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
76 bool NoRTTI = Triple.isPS() || Triple.isDriverKit();
81 if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
93 auto addIfExists = [
this](
path_list &List,
const std::string &Path) {
109 llvm::sys::fs::createTemporaryFile(
"toolchain-program",
"txt", OutputFile);
110 llvm::FileRemover OutputRemover(OutputFile.c_str());
111 std::optional<llvm::StringRef> Redirects[] = {
117 std::string ErrorMessage;
118 if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects,
121 return llvm::createStringError(std::error_code(),
122 Executable +
": " + ErrorMessage);
124 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
125 llvm::MemoryBuffer::getFile(OutputFile.c_str());
127 return llvm::createStringError(OutputBuf.getError(),
128 "Failed to read stdout of " + Executable +
129 ": " + OutputBuf.getError().message());
130 return std::move(*OutputBuf);
134 Triple.setEnvironment(
Env);
135 if (EffectiveTriple != llvm::Triple())
136 EffectiveTriple.setEnvironment(
Env);
146 return Args.hasFlag(options::OPT_fintegrated_as,
147 options::OPT_fno_integrated_as,
155 "(Non-)integrated backend set incorrectly!");
157 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
158 options::OPT_fno_integrated_objemitter,
166 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
168 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
169 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
171 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
172 A = Args.getLastArg(options::OPT_fintegrated_objemitter);
174 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
180 return ENABLE_X86_RELAX_RELOCATIONS;
184 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE &&
getTriple().isOSLinux();
188 const llvm::Triple &Triple,
189 const llvm::opt::ArgList &Args,
191 std::vector<StringRef> Features;
195 UnifiedFeatures.end());
196 std::vector<std::string> MArch;
197 for (
const auto &Ext : AArch64::Extensions)
198 if (FeatureSet.contains(Ext.Feature))
199 MArch.push_back(Ext.Name.str());
200 for (
const auto &Ext : AArch64::Extensions)
201 if (FeatureSet.contains(Ext.NegFeature))
202 MArch.push_back((
"no" + Ext.Name).str());
204 for (
const auto &ArchInfo : AArch64::ArchInfos)
205 if (FeatureSet.contains(ArchInfo->ArchFeature))
206 ArchName = ArchInfo->Name;
207 assert(!ArchName.empty() &&
"at least one architecture should be found");
208 MArch.insert(MArch.begin(), (
"-march=" + ArchName).str());
209 Result.push_back(llvm::join(MArch,
"+"));
213 const llvm::Triple &Triple,
214 const llvm::opt::ArgList &Args,
216 std::vector<StringRef> Features;
218 D, Triple, Args, Features,
false ,
true );
221 UnifiedFeatures.end());
222 std::vector<std::string> MArch;
223 for (
const auto &Ext : ARM::ARCHExtNames)
224 if (FeatureSet.contains(Ext.Feature))
225 MArch.push_back(Ext.Name.str());
226 for (
const auto &Ext : ARM::ARCHExtNames)
227 if (FeatureSet.contains(Ext.NegFeature))
228 MArch.push_back((
"no" + Ext.Name).str());
229 MArch.insert(MArch.begin(), (
"-march=" + Triple.getArchName()).str());
230 Result.push_back(llvm::join(MArch,
"+"));
233#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
234 case llvm::ARM::KIND: \
235 Result.push_back("-mfpu=" NAME); \
237#include "llvm/TargetParser/ARMTargetParser.def"
239 llvm_unreachable(
"Invalid FPUKind");
243 case arm::FloatABI::Soft:
244 Result.push_back(
"-mfloat-abi=soft");
246 case arm::FloatABI::SoftFP:
247 Result.push_back(
"-mfloat-abi=softfp");
249 case arm::FloatABI::Hard:
250 Result.push_back(
"-mfloat-abi=hard");
252 case arm::FloatABI::Invalid:
253 llvm_unreachable(
"Invalid float ABI");
261 std::vector<std::string>
Result;
263 Result.push_back(
"--target=" + Triple.str());
265 switch (Triple.getArch()) {
266 case llvm::Triple::aarch64:
267 case llvm::Triple::aarch64_32:
268 case llvm::Triple::aarch64_be:
271 case llvm::Triple::arm:
272 case llvm::Triple::armeb:
273 case llvm::Triple::thumb:
274 case llvm::Triple::thumbeb:
284 Result.push_back(
"-fno-rtti");
286 Result.push_back(
"-frtti");
289 Result.push_back(
"-fno-exceptions");
291 Result.push_back(
"-fexceptions");
301 SanitizerArgs SanArgs(*
this, JobArgs, !SanitizerArgsChecked);
302 SanitizerArgsChecked =
true;
308 XRayArguments.reset(
new XRayArgs(*
this, Args));
309 return *XRayArguments;
316 const char *ModeFlag;
325 static const DriverSuffix DriverSuffixes[] = {
327 {
"clang++",
"--driver-mode=g++"},
328 {
"clang-c++",
"--driver-mode=g++"},
329 {
"clang-cc",
nullptr},
330 {
"clang-cpp",
"--driver-mode=cpp"},
331 {
"clang-g++",
"--driver-mode=g++"},
332 {
"clang-gcc",
nullptr},
333 {
"clang-cl",
"--driver-mode=cl"},
335 {
"cpp",
"--driver-mode=cpp"},
336 {
"cl",
"--driver-mode=cl"},
337 {
"++",
"--driver-mode=g++"},
338 {
"flang",
"--driver-mode=flang"},
339 {
"clang-dxc",
"--driver-mode=dxc"},
342 for (
const auto &DS : DriverSuffixes) {
343 StringRef Suffix(DS.Suffix);
344 if (ProgName.ends_with(Suffix)) {
345 Pos = ProgName.size() - Suffix.size();
355 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
356 if (is_style_windows(llvm::sys::path::Style::native)) {
358 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
374 if (!DS && ProgName.ends_with(
".exe")) {
377 ProgName = ProgName.drop_back(StringRef(
".exe").size());
384 ProgName = ProgName.rtrim(
"0123456789.");
391 ProgName = ProgName.slice(0, ProgName.rfind(
'-'));
404 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
406 size_t LastComponent = ProgName.rfind(
'-', SuffixPos);
407 if (LastComponent == std::string::npos)
409 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
410 SuffixEnd - LastComponent - 1);
413 StringRef Prefix(ProgName);
414 Prefix = Prefix.slice(0, LastComponent);
415 std::string IgnoredError;
417 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
426 switch (Triple.getArch()) {
427 case llvm::Triple::aarch64: {
432 case llvm::Triple::aarch64_32:
434 case llvm::Triple::ppc:
436 case llvm::Triple::ppcle:
438 case llvm::Triple::ppc64:
440 case llvm::Triple::ppc64le:
443 return Triple.getArchName();
456Tool *ToolChain::getClang()
const {
462Tool *ToolChain::getFlang()
const {
473 llvm_unreachable(
"Linking is not supported by this toolchain");
477 llvm_unreachable(
"Creating static lib is not supported by this toolchain");
480Tool *ToolChain::getAssemble()
const {
483 return Assemble.get();
486Tool *ToolChain::getClangAs()
const {
489 return Assemble.get();
492Tool *ToolChain::getLink()
const {
498Tool *ToolChain::getStaticLibTool()
const {
501 return StaticLibTool.get();
504Tool *ToolChain::getIfsMerge()
const {
507 return IfsMerge.get();
510Tool *ToolChain::getOffloadBundler()
const {
516Tool *ToolChain::getOffloadPackager()
const {
522Tool *ToolChain::getLinkerWrapper()
const {
531 return getAssemble();
534 return getIfsMerge();
540 return getStaticLibTool();
549 llvm_unreachable(
"Invalid tool kind.");
563 return getOffloadBundler();
566 return getOffloadPackager();
568 return getLinkerWrapper();
571 llvm_unreachable(
"Invalid tool kind.");
575 const ArgList &Args) {
576 const llvm::Triple &Triple = TC.
getTriple();
577 bool IsWindows = Triple.isOSWindows();
580 return Triple.getArchName();
582 if (TC.
getArch() == llvm::Triple::arm || TC.
getArch() == llvm::Triple::armeb)
588 if (TC.
getArch() == llvm::Triple::x86 && Triple.isAndroid())
591 if (TC.
getArch() == llvm::Triple::x86_64 && Triple.isX32())
594 return llvm::Triple::getArchTypeName(TC.
getArch());
598 if (Triple.isOSDarwin())
601 switch (Triple.getOS()) {
602 case llvm::Triple::FreeBSD:
604 case llvm::Triple::NetBSD:
606 case llvm::Triple::OpenBSD:
608 case llvm::Triple::Solaris:
610 case llvm::Triple::AIX:
624 }
else if (Triple.isOSUnknown()) {
625 llvm::sys::path::append(Path,
"lib");
629 return std::string(Path);
636 return llvm::sys::path::filename(CRTAbsolutePath).str();
642 bool AddArch)
const {
644 bool IsITANMSVCWindows =
645 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
652 Suffix = IsITANMSVCWindows ?
".obj" :
".o";
655 Suffix = IsITANMSVCWindows ?
".lib" :
".a";
658 Suffix = TT.isOSWindows()
659 ? (TT.isWindowsGNUEnvironment() ?
".dll.a" :
".lib")
664 std::string ArchAndEnv;
667 const char *
Env = TT.isAndroid() ?
"-android" :
"";
668 ArchAndEnv = (
"-" + Arch +
Env).str();
670 return (Prefix + Twine(
"clang_rt.") + Component + ArchAndEnv + Suffix).str();
676 std::string CRTBasename =
681 llvm::sys::path::append(
P, CRTBasename);
683 return std::string(
P);
694 llvm::sys::path::append(OldPath, CRTBasename);
695 if (Path.empty() ||
getVFS().exists(OldPath))
696 return std::string(OldPath);
701 return std::string(Path);
713std::optional<std::string>
714ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir)
const {
715 llvm::Triple TripleWithoutLevel(
getTriple());
716 TripleWithoutLevel.setEnvironmentName(
"android");
717 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
718 unsigned TripleVersion =
getTriple().getEnvironmentVersion().getMajor();
719 unsigned BestVersion = 0;
722 bool UsingUnversionedDir =
false;
724 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(BaseDir, EC), LE;
725 !EC && LI != LE; LI = LI.increment(EC)) {
726 StringRef DirName = llvm::sys::path::filename(LI->path());
727 StringRef DirNameSuffix = DirName;
728 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
729 if (DirNameSuffix.empty() && TripleDir.empty()) {
731 UsingUnversionedDir =
true;
734 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
735 Version < TripleVersion) {
736 BestVersion = Version;
738 UsingUnversionedDir =
false;
744 if (TripleDir.empty())
748 llvm::sys::path::append(
P, TripleDir);
749 if (UsingUnversionedDir)
751 return std::string(
P);
754std::optional<std::string>
756 auto getPathForTriple =
757 [&](
const llvm::Triple &Triple) -> std::optional<std::string> {
759 llvm::sys::path::append(
P, Triple.str());
761 return std::string(
P);
765 if (
auto Path = getPathForTriple(
getTriple()))
785 ArmTriple.setArch(Triple::arm);
786 if (
auto Path = getPathForTriple(ArmTriple))
791 return getFallbackAndroidTargetPath(BaseDir);
798 llvm::sys::path::append(
P,
"lib");
804 llvm::sys::path::append(
P,
"..",
"lib");
813 llvm::sys::path::append(Path,
"lib");
815 llvm::sys::path::append(Path, S);
816 Paths.push_back(std::string(Path));
825 if (Args.hasArg(options::OPT_noprofilelib))
828 return Args.hasArg(options::OPT_fprofile_generate) ||
829 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
830 Args.hasArg(options::OPT_fcs_profile_generate) ||
831 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
832 Args.hasArg(options::OPT_fprofile_instr_generate) ||
833 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
834 Args.hasArg(options::OPT_fcreate_profile) ||
835 Args.hasArg(options::OPT_forder_file_instrumentation);
839 return Args.hasArg(options::OPT_coverage) ||
840 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
846 if (
getDriver().ShouldUseClangCompiler(JA))
return getClang();
864 *LinkerIsLLD =
false;
868 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
869 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
876 if (
const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
877 std::string Path(A->getValue());
879 if (llvm::sys::path::parent_path(Path).empty())
881 if (llvm::sys::fs::can_execute(Path)) {
883 *LinkerIsLLD = UseLinker ==
"lld";
884 return std::string(Path);
887 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
892 if (UseLinker.empty() || UseLinker ==
"ld") {
894 if (llvm::sys::path::is_absolute(DefaultLinker))
895 return std::string(DefaultLinker);
904 if (UseLinker.contains(
'/'))
907 if (llvm::sys::path::is_absolute(UseLinker)) {
910 if (llvm::sys::fs::can_execute(UseLinker))
911 return std::string(UseLinker);
914 if (Triple.isOSDarwin())
915 LinkerName.append(
"ld64.");
917 LinkerName.append(
"ld.");
918 LinkerName.append(UseLinker);
921 if (llvm::sys::fs::can_execute(LinkerPath)) {
923 *LinkerIsLLD = UseLinker ==
"lld";
929 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
936 if (Triple.isOSDarwin())
948 id = types::TY_Fortran;
958 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
959 switch (HostTriple.getArch()) {
962 case llvm::Triple::arm:
963 case llvm::Triple::armeb:
964 case llvm::Triple::thumb:
965 case llvm::Triple::thumbeb:
966 return getArch() != llvm::Triple::arm &&
getArch() != llvm::Triple::thumb &&
967 getArch() != llvm::Triple::armeb &&
getArch() != llvm::Triple::thumbeb;
969 return HostTriple.getArch() !=
getArch();
978llvm::ExceptionHandling
980 return llvm::ExceptionHandling::None;
984 if (Model ==
"single") {
986 return Triple.getArch() == llvm::Triple::arm ||
987 Triple.getArch() == llvm::Triple::armeb ||
988 Triple.getArch() == llvm::Triple::thumb ||
989 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
990 }
else if (Model ==
"posix")
1002 case llvm::Triple::x86_64: {
1004 if (!Triple.isOSBinFormatMachO())
1007 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1010 StringRef MArch = A->getValue();
1011 if (MArch ==
"x86_64h")
1012 Triple.setArchName(MArch);
1014 return Triple.getTriple();
1016 case llvm::Triple::aarch64: {
1018 if (!Triple.isOSBinFormatMachO())
1021 if (Triple.isArm64e())
1027 Triple.setArchName(
"arm64");
1028 return Triple.getTriple();
1030 case llvm::Triple::aarch64_32:
1032 case llvm::Triple::arm:
1033 case llvm::Triple::armeb:
1034 case llvm::Triple::thumb:
1035 case llvm::Triple::thumbeb: {
1039 return Triple.getTriple();
1054 ArgStringList &CC1Args)
const {
1059 const ArgList &DriverArgs, ArgStringList &CC1Args,
1063 ArgStringList &CC1ASArgs)
const {}
1068 llvm::opt::ArgStringList &CmdArgs)
const {
1076 const ArgList &Args)
const {
1078 return *runtimeLibType;
1080 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
1081 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
1084 if (LibName ==
"compiler-rt")
1086 else if (LibName ==
"libgcc")
1088 else if (LibName ==
"platform")
1093 << A->getAsString(Args);
1098 return *runtimeLibType;
1102 const ArgList &Args)
const {
1104 return *unwindLibType;
1106 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
1107 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
1109 if (LibName ==
"none")
1111 else if (LibName ==
"platform" || LibName ==
"") {
1120 }
else if (LibName ==
"libunwind") {
1124 }
else if (LibName ==
"libgcc")
1129 << A->getAsString(Args);
1134 return *unwindLibType;
1139 return *cxxStdlibType;
1141 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1142 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
1145 if (LibName ==
"libc++")
1147 else if (LibName ==
"libstdc++")
1149 else if (LibName ==
"platform")
1154 << A->getAsString(Args);
1159 return *cxxStdlibType;
1164 ArgStringList &CC1Args,
1165 const Twine &Path) {
1166 CC1Args.push_back(
"-internal-isystem");
1167 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1179 ArgStringList &CC1Args,
1180 const Twine &Path) {
1181 CC1Args.push_back(
"-internal-externc-isystem");
1182 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1186 ArgStringList &CC1Args,
1187 const Twine &Path) {
1188 if (llvm::sys::fs::exists(Path))
1194 ArgStringList &CC1Args,
1196 for (
const auto &Path : Paths) {
1197 CC1Args.push_back(
"-internal-isystem");
1198 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1203 const Twine &B,
const Twine &
C,
1206 llvm::sys::path::append(
Result, llvm::sys::path::Style::posix, A, B,
C, D);
1207 return std::string(
Result);
1213 std::string MaxVersionString;
1215 llvm::sys::path::append(Path,
"c++");
1216 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(Path, EC), LE;
1217 !EC && LI != LE; LI = LI.increment(EC)) {
1218 StringRef VersionText = llvm::sys::path::filename(LI->path());
1220 if (VersionText[0] ==
'v' &&
1221 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
1222 if (Version > MaxVersion) {
1223 MaxVersion = Version;
1224 MaxVersionString = std::string(VersionText);
1230 return MaxVersionString;
1234 ArgStringList &CC1Args)
const {
1244 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1248 const llvm::opt::ArgList &DriverArgs,
1249 llvm::opt::ArgStringList &CC1Args)
const {
1250 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1259 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1260 for (
const auto &
P :
1261 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1267 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1268 options::OPT_nostdlibxx);
1272 ArgStringList &CmdArgs)
const {
1273 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1274 "should not have called this");
1279 CmdArgs.push_back(
"-lc++");
1280 if (Args.hasArg(options::OPT_fexperimental_library))
1281 CmdArgs.push_back(
"-lc++experimental");
1285 CmdArgs.push_back(
"-lstdc++");
1291 ArgStringList &CmdArgs)
const {
1293 if(LibPath.length() > 0)
1294 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
1298 ArgStringList &CmdArgs)
const {
1299 CmdArgs.push_back(
"-lcc_kext");
1303 std::string &Path)
const {
1309 Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
1310 options::OPT_funsafe_math_optimizations,
1311 options::OPT_fno_unsafe_math_optimizations);
1313 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1314 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1319 return (Path !=
"crtfastmath.o");
1323 ArgStringList &CmdArgs)
const {
1326 CmdArgs.push_back(Args.MakeArgString(Path));
1344 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1345 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1346 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1347 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1348 SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1349 if (
getTriple().getArch() == llvm::Triple::x86 ||
1350 getTriple().getArch() == llvm::Triple::x86_64 ||
1354 Res |= SanitizerKind::CFIICall;
1355 if (
getTriple().getArch() == llvm::Triple::x86_64 ||
1357 Res |= SanitizerKind::ShadowCallStack;
1359 Res |= SanitizerKind::MemTag;
1364 ArgStringList &CC1Args)
const {}
1367 ArgStringList &CC1Args)
const {}
1375 ArgStringList &CC1Args)
const {}
1379 return VersionTuple(Version);
1381 if (Version < 10000)
1382 return VersionTuple(Version / 100, Version % 100);
1384 unsigned Build = 0, Factor = 1;
1385 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1386 Build = Build + (Version % 10) * Factor;
1387 return VersionTuple(Version / 100, Version % 100, Build);
1392 const llvm::opt::ArgList &Args)
const {
1393 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1394 const Arg *MSCompatibilityVersion =
1395 Args.getLastArg(options::OPT_fms_compatibility_version);
1397 if (MSCVersion && MSCompatibilityVersion) {
1399 D->
Diag(diag::err_drv_argument_not_allowed_with)
1400 << MSCVersion->getAsString(Args)
1401 << MSCompatibilityVersion->getAsString(Args);
1402 return VersionTuple();
1405 if (MSCompatibilityVersion) {
1407 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1409 D->
Diag(diag::err_drv_invalid_value)
1410 << MSCompatibilityVersion->getAsString(Args)
1411 << MSCompatibilityVersion->getValue();
1418 unsigned Version = 0;
1419 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1421 D->
Diag(diag::err_drv_invalid_value)
1422 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1428 return VersionTuple();
1432 const llvm::opt::DerivedArgList &Args,
bool SameTripleAsHost,
1434 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1436 bool Modified =
false;
1439 for (
auto *A : Args) {
1444 if (A->getOption().matches(options::OPT_m_Group)) {
1447 if (SameTripleAsHost ||
1448 A->getOption().matches(options::OPT_mcode_object_version_EQ))
1457 bool XOpenMPTargetNoTriple =
1458 A->getOption().matches(options::OPT_Xopenmp_target);
1460 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1465 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1468 }
else if (XOpenMPTargetNoTriple) {
1470 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1478 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1479 if (!XOpenMPTargetArg || Index > Prev + 1) {
1480 getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1481 << A->getAsString(Args);
1484 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1485 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
1486 getDriver().
Diag(diag::err_drv_Xopenmp_target_missing_triple);
1489 XOpenMPTargetArg->setBaseArg(A);
1490 A = XOpenMPTargetArg.release();
1491 AllocatedArgs.push_back(A);
1507 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1508 llvm::opt::DerivedArgList *DAL,
1511 unsigned ValuePos = 1;
1512 if (A->getOption().matches(options::OPT_Xarch_device) ||
1513 A->getOption().matches(options::OPT_Xarch_host))
1516 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
1517 unsigned Prev = Index;
1518 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index));
1527 if (!XarchArg || Index > Prev + 1) {
1528 getDriver().
Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1529 << A->getAsString(Args);
1535 "invalid Xarch argument: '%0', not all driver "
1536 "options can be forwared via Xarch argument");
1537 Diags.Report(DiagID) << A->getAsString(Args);
1540 XarchArg->setBaseArg(A);
1541 A = XarchArg.release();
1543 DAL->AddSynthesizedArg(A);
1545 AllocatedArgs->push_back(A);
1549 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1552 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1553 bool Modified =
false;
1556 for (Arg *A : Args) {
1557 bool NeedTrans =
false;
1559 if (A->getOption().matches(options::OPT_Xarch_device)) {
1560 NeedTrans = IsDevice;
1562 }
else if (A->getOption().matches(options::OPT_Xarch_host)) {
1563 NeedTrans = !IsDevice;
1565 }
else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) {
1569 if (BoundArch.empty() || A->getValue(0) != BoundArch)
1574 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
@ 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
DiagnosticBuilder Diag(unsigned DiagID) 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.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
std::vector< std::string > flags_list
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.
YAML serialization mapping.
Helper structure used to pass information extracted from clang executable name such as i686-linux-and...