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();
84 auto addIfExists = [
this](
path_list &List,
const std::string &Path) {
100 llvm::sys::fs::createTemporaryFile(
"toolchain-program",
"txt", OutputFile);
101 llvm::FileRemover OutputRemover(OutputFile.c_str());
102 std::optional<llvm::StringRef> Redirects[] = {
108 std::string ErrorMessage;
109 if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects,
112 return llvm::createStringError(std::error_code(),
113 Executable +
": " + ErrorMessage);
115 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
116 llvm::MemoryBuffer::getFile(OutputFile.c_str());
118 return llvm::createStringError(OutputBuf.getError(),
119 "Failed to read stdout of " + Executable +
120 ": " + OutputBuf.getError().message());
121 return std::move(*OutputBuf);
125 Triple.setEnvironment(
Env);
126 if (EffectiveTriple != llvm::Triple())
127 EffectiveTriple.setEnvironment(
Env);
137 return Args.hasFlag(options::OPT_fintegrated_as,
138 options::OPT_fno_integrated_as,
146 "(Non-)integrated backend set incorrectly!");
148 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
149 options::OPT_fno_integrated_objemitter,
157 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
159 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
160 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
162 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
163 A = Args.getLastArg(options::OPT_fintegrated_objemitter);
165 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
171 return ENABLE_X86_RELAX_RELOCATIONS;
175 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE &&
getTriple().isOSLinux();
179 const llvm::Triple &Triple,
180 const llvm::opt::ArgList &Args,
182 std::vector<StringRef> Features;
186 UnifiedFeatures.end());
187 std::vector<std::string> MArch;
188 for (
const auto &Ext : AArch64::Extensions)
189 if (FeatureSet.contains(Ext.Feature))
190 MArch.push_back(Ext.Name.str());
191 for (
const auto &Ext : AArch64::Extensions)
192 if (FeatureSet.contains(Ext.NegFeature))
193 MArch.push_back((
"no" + Ext.Name).str());
194 MArch.insert(MArch.begin(), (
"-march=" + Triple.getArchName()).str());
195 Result.push_back(llvm::join(MArch,
"+"));
199 const llvm::Triple &Triple,
200 const llvm::opt::ArgList &Args,
202 std::vector<StringRef> Features;
204 D, Triple, Args, Features,
false ,
true );
207 UnifiedFeatures.end());
208 std::vector<std::string> MArch;
209 for (
const auto &Ext : ARM::ARCHExtNames)
210 if (FeatureSet.contains(Ext.Feature))
211 MArch.push_back(Ext.Name.str());
212 for (
const auto &Ext : ARM::ARCHExtNames)
213 if (FeatureSet.contains(Ext.NegFeature))
214 MArch.push_back((
"no" + Ext.Name).str());
215 MArch.insert(MArch.begin(), (
"-march=" + Triple.getArchName()).str());
216 Result.push_back(llvm::join(MArch,
"+"));
219#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
220 case llvm::ARM::KIND: \
221 Result.push_back("-mfpu=" NAME); \
223#include "llvm/TargetParser/ARMTargetParser.def"
225 llvm_unreachable(
"Invalid FPUKind");
229 case arm::FloatABI::Soft:
230 Result.push_back(
"-mfloat-abi=soft");
232 case arm::FloatABI::SoftFP:
233 Result.push_back(
"-mfloat-abi=softfp");
235 case arm::FloatABI::Hard:
236 Result.push_back(
"-mfloat-abi=hard");
238 case arm::FloatABI::Invalid:
239 llvm_unreachable(
"Invalid float ABI");
247 std::vector<std::string>
Result;
249 Result.push_back(
"--target=" + Triple.str());
251 switch (Triple.getArch()) {
252 case llvm::Triple::aarch64:
253 case llvm::Triple::aarch64_32:
254 case llvm::Triple::aarch64_be:
257 case llvm::Triple::arm:
258 case llvm::Triple::armeb:
259 case llvm::Triple::thumb:
260 case llvm::Triple::thumbeb:
275 SanitizerArgs SanArgs(*
this, JobArgs, !SanitizerArgsChecked);
276 SanitizerArgsChecked =
true;
282 XRayArguments.reset(
new XRayArgs(*
this, Args));
283 return *XRayArguments;
290 const char *ModeFlag;
299 static const DriverSuffix DriverSuffixes[] = {
301 {
"clang++",
"--driver-mode=g++"},
302 {
"clang-c++",
"--driver-mode=g++"},
303 {
"clang-cc",
nullptr},
304 {
"clang-cpp",
"--driver-mode=cpp"},
305 {
"clang-g++",
"--driver-mode=g++"},
306 {
"clang-gcc",
nullptr},
307 {
"clang-cl",
"--driver-mode=cl"},
309 {
"cpp",
"--driver-mode=cpp"},
310 {
"cl",
"--driver-mode=cl"},
311 {
"++",
"--driver-mode=g++"},
312 {
"flang",
"--driver-mode=flang"},
313 {
"clang-dxc",
"--driver-mode=dxc"},
316 for (
const auto &DS : DriverSuffixes) {
317 StringRef Suffix(DS.Suffix);
318 if (ProgName.endswith(Suffix)) {
319 Pos = ProgName.size() - Suffix.size();
329 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
330 if (is_style_windows(llvm::sys::path::Style::native)) {
332 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
348 if (!DS && ProgName.endswith(
".exe")) {
351 ProgName = ProgName.drop_back(StringRef(
".exe").size());
358 ProgName = ProgName.rtrim(
"0123456789.");
365 ProgName = ProgName.slice(0, ProgName.rfind(
'-'));
378 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
380 size_t LastComponent = ProgName.rfind(
'-', SuffixPos);
381 if (LastComponent == std::string::npos)
383 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
384 SuffixEnd - LastComponent - 1);
387 StringRef Prefix(ProgName);
388 Prefix = Prefix.slice(0, LastComponent);
389 std::string IgnoredError;
391 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
400 switch (Triple.getArch()) {
401 case llvm::Triple::aarch64: {
406 case llvm::Triple::aarch64_32:
408 case llvm::Triple::ppc:
410 case llvm::Triple::ppcle:
412 case llvm::Triple::ppc64:
414 case llvm::Triple::ppc64le:
417 return Triple.getArchName();
436Tool *ToolChain::getClang()
const {
442Tool *ToolChain::getFlang()
const {
453 llvm_unreachable(
"Linking is not supported by this toolchain");
457 llvm_unreachable(
"Creating static lib is not supported by this toolchain");
460Tool *ToolChain::getAssemble()
const {
463 return Assemble.get();
466Tool *ToolChain::getClangAs()
const {
469 return Assemble.get();
472Tool *ToolChain::getLink()
const {
478Tool *ToolChain::getStaticLibTool()
const {
481 return StaticLibTool.get();
484Tool *ToolChain::getIfsMerge()
const {
487 return IfsMerge.get();
490Tool *ToolChain::getOffloadBundler()
const {
496Tool *ToolChain::getOffloadPackager()
const {
502Tool *ToolChain::getLinkerWrapper()
const {
511 return getAssemble();
514 return getIfsMerge();
520 return getStaticLibTool();
529 llvm_unreachable(
"Invalid tool kind.");
543 return getOffloadBundler();
546 return getOffloadPackager();
548 return getLinkerWrapper();
551 llvm_unreachable(
"Invalid tool kind.");
555 const ArgList &Args) {
556 const llvm::Triple &Triple = TC.
getTriple();
557 bool IsWindows = Triple.isOSWindows();
560 return Triple.getArchName();
562 if (TC.
getArch() == llvm::Triple::arm || TC.
getArch() == llvm::Triple::armeb)
568 if (TC.
getArch() == llvm::Triple::x86 && Triple.isAndroid())
571 if (TC.
getArch() == llvm::Triple::x86_64 && Triple.isX32())
574 return llvm::Triple::getArchTypeName(TC.
getArch());
578 if (Triple.isOSDarwin())
581 switch (Triple.getOS()) {
582 case llvm::Triple::FreeBSD:
584 case llvm::Triple::NetBSD:
586 case llvm::Triple::OpenBSD:
588 case llvm::Triple::Solaris:
590 case llvm::Triple::AIX:
604 }
else if (Triple.isOSUnknown()) {
605 llvm::sys::path::append(Path,
"lib");
609 return std::string(Path.str());
616 return llvm::sys::path::filename(CRTAbsolutePath).str();
622 bool AddArch)
const {
624 bool IsITANMSVCWindows =
625 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
632 Suffix = IsITANMSVCWindows ?
".obj" :
".o";
635 Suffix = IsITANMSVCWindows ?
".lib" :
".a";
638 Suffix = TT.isOSWindows()
639 ? (TT.isWindowsGNUEnvironment() ?
".dll.a" :
".lib")
644 std::string ArchAndEnv;
647 const char *
Env = TT.isAndroid() ?
"-android" :
"";
648 ArchAndEnv = (
"-" + Arch +
Env).str();
650 return (Prefix + Twine(
"clang_rt.") + Component + ArchAndEnv + Suffix).str();
656 std::string CRTBasename =
660 llvm::sys::path::append(
P, CRTBasename);
662 return std::string(
P.str());
670 llvm::sys::path::append(Path, CRTBasename);
671 return std::string(Path.str());
683std::optional<std::string>
684ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir)
const {
685 llvm::Triple TripleWithoutLevel(
getTriple());
686 TripleWithoutLevel.setEnvironmentName(
"android");
687 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
688 unsigned TripleVersion =
getTriple().getEnvironmentVersion().getMajor();
689 unsigned BestVersion = 0;
692 bool UsingUnversionedDir =
false;
694 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(BaseDir, EC), LE;
695 !EC && LI != LE; LI = LI.increment(EC)) {
696 StringRef DirName = llvm::sys::path::filename(LI->path());
697 StringRef DirNameSuffix = DirName;
698 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
699 if (DirNameSuffix.empty() && TripleDir.empty()) {
701 UsingUnversionedDir =
true;
704 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
705 Version < TripleVersion) {
706 BestVersion = Version;
708 UsingUnversionedDir =
false;
714 if (TripleDir.empty())
718 llvm::sys::path::append(
P, TripleDir);
719 if (UsingUnversionedDir)
721 return std::string(
P);
724std::optional<std::string>
726 auto getPathForTriple =
727 [&](
const llvm::Triple &Triple) -> std::optional<std::string> {
729 llvm::sys::path::append(
P, Triple.str());
731 return std::string(
P);
735 if (
auto Path = getPathForTriple(
getTriple()))
755 ArmTriple.setArch(Triple::arm);
756 if (
auto Path = getPathForTriple(ArmTriple))
761 return getFallbackAndroidTargetPath(BaseDir);
768 llvm::sys::path::append(
P,
"lib");
774 llvm::sys::path::append(
P,
"..",
"lib");
783 llvm::sys::path::append(Path,
"lib");
785 llvm::sys::path::append(Path, S);
786 Paths.push_back(std::string(Path.str()));
795 if (Args.hasArg(options::OPT_noprofilelib))
798 return Args.hasArg(options::OPT_fprofile_generate) ||
799 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
800 Args.hasArg(options::OPT_fcs_profile_generate) ||
801 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
802 Args.hasArg(options::OPT_fprofile_instr_generate) ||
803 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
804 Args.hasArg(options::OPT_fcreate_profile) ||
805 Args.hasArg(options::OPT_forder_file_instrumentation);
809 return Args.hasArg(options::OPT_coverage) ||
810 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
816 if (
getDriver().ShouldUseClangCompiler(JA))
return getClang();
834 *LinkerIsLLD =
false;
838 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
839 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
846 if (
const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
847 std::string Path(A->getValue());
849 if (llvm::sys::path::parent_path(Path).empty())
851 if (llvm::sys::fs::can_execute(Path)) {
853 *LinkerIsLLD = UseLinker ==
"lld";
854 return std::string(Path);
857 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
862 if (UseLinker.empty() || UseLinker ==
"ld") {
864 if (llvm::sys::path::is_absolute(DefaultLinker))
865 return std::string(DefaultLinker);
874 if (UseLinker.contains(
'/'))
877 if (llvm::sys::path::is_absolute(UseLinker)) {
880 if (llvm::sys::fs::can_execute(UseLinker))
881 return std::string(UseLinker);
884 if (Triple.isOSDarwin())
885 LinkerName.append(
"ld64.");
887 LinkerName.append(
"ld.");
888 LinkerName.append(UseLinker);
891 if (llvm::sys::fs::can_execute(LinkerPath)) {
893 *LinkerIsLLD = UseLinker ==
"lld";
899 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
906 if (Triple.isOSDarwin())
918 id = types::TY_Fortran;
928 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
929 switch (HostTriple.getArch()) {
932 case llvm::Triple::arm:
933 case llvm::Triple::armeb:
934 case llvm::Triple::thumb:
935 case llvm::Triple::thumbeb:
936 return getArch() != llvm::Triple::arm &&
getArch() != llvm::Triple::thumb &&
937 getArch() != llvm::Triple::armeb &&
getArch() != llvm::Triple::thumbeb;
939 return HostTriple.getArch() !=
getArch();
948llvm::ExceptionHandling
950 return llvm::ExceptionHandling::None;
954 if (Model ==
"single") {
956 return Triple.getArch() == llvm::Triple::arm ||
957 Triple.getArch() == llvm::Triple::armeb ||
958 Triple.getArch() == llvm::Triple::thumb ||
959 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
960 }
else if (Model ==
"posix")
972 case llvm::Triple::x86_64: {
974 if (!Triple.isOSBinFormatMachO())
977 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
980 StringRef MArch = A->getValue();
981 if (MArch ==
"x86_64h")
982 Triple.setArchName(MArch);
984 return Triple.getTriple();
986 case llvm::Triple::aarch64: {
988 if (!Triple.isOSBinFormatMachO())
991 if (Triple.isArm64e())
997 Triple.setArchName(
"arm64");
998 return Triple.getTriple();
1000 case llvm::Triple::aarch64_32:
1002 case llvm::Triple::arm:
1003 case llvm::Triple::armeb:
1004 case llvm::Triple::thumb:
1005 case llvm::Triple::thumbeb: {
1009 return Triple.getTriple();
1024 ArgStringList &CC1Args)
const {
1029 const ArgList &DriverArgs, ArgStringList &CC1Args,
1033 ArgStringList &CC1ASArgs)
const {}
1038 llvm::opt::ArgStringList &CmdArgs)
const {
1046 const ArgList &Args)
const {
1048 return *runtimeLibType;
1050 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
1051 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
1054 if (LibName ==
"compiler-rt")
1056 else if (LibName ==
"libgcc")
1058 else if (LibName ==
"platform")
1063 << A->getAsString(Args);
1068 return *runtimeLibType;
1072 const ArgList &Args)
const {
1074 return *unwindLibType;
1076 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
1077 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
1079 if (LibName ==
"none")
1081 else if (LibName ==
"platform" || LibName ==
"") {
1090 }
else if (LibName ==
"libunwind") {
1094 }
else if (LibName ==
"libgcc")
1099 << A->getAsString(Args);
1104 return *unwindLibType;
1109 return *cxxStdlibType;
1111 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1112 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
1115 if (LibName ==
"libc++")
1117 else if (LibName ==
"libstdc++")
1119 else if (LibName ==
"platform")
1124 << A->getAsString(Args);
1129 return *cxxStdlibType;
1134 ArgStringList &CC1Args,
1135 const Twine &Path) {
1136 CC1Args.push_back(
"-internal-isystem");
1137 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1149 ArgStringList &CC1Args,
1150 const Twine &Path) {
1151 CC1Args.push_back(
"-internal-externc-isystem");
1152 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1156 ArgStringList &CC1Args,
1157 const Twine &Path) {
1158 if (llvm::sys::fs::exists(Path))
1164 ArgStringList &CC1Args,
1166 for (
const auto &Path : Paths) {
1167 CC1Args.push_back(
"-internal-isystem");
1168 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1173 const Twine &B,
const Twine &
C,
1176 llvm::sys::path::append(
Result, llvm::sys::path::Style::posix, A, B,
C, D);
1177 return std::string(
Result);
1183 std::string MaxVersionString;
1185 llvm::sys::path::append(Path,
"c++");
1186 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(Path, EC), LE;
1187 !EC && LI != LE; LI = LI.increment(EC)) {
1188 StringRef VersionText = llvm::sys::path::filename(LI->path());
1190 if (VersionText[0] ==
'v' &&
1191 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
1192 if (Version > MaxVersion) {
1193 MaxVersion = Version;
1194 MaxVersionString = std::string(VersionText);
1200 return MaxVersionString;
1204 ArgStringList &CC1Args)
const {
1214 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1218 const llvm::opt::ArgList &DriverArgs,
1219 llvm::opt::ArgStringList &CC1Args)
const {
1220 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1229 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1230 for (
const auto &
P :
1231 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1237 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1238 options::OPT_nostdlibxx);
1242 ArgStringList &CmdArgs)
const {
1243 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1244 "should not have called this");
1249 CmdArgs.push_back(
"-lc++");
1250 if (Args.hasArg(options::OPT_fexperimental_library))
1251 CmdArgs.push_back(
"-lc++experimental");
1255 CmdArgs.push_back(
"-lstdc++");
1261 ArgStringList &CmdArgs)
const {
1263 if(LibPath.length() > 0)
1264 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
1268 ArgStringList &CmdArgs)
const {
1269 CmdArgs.push_back(
"-lcc_kext");
1273 std::string &Path)
const {
1279 Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
1280 options::OPT_funsafe_math_optimizations,
1281 options::OPT_fno_unsafe_math_optimizations);
1283 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1284 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1289 return (Path !=
"crtfastmath.o");
1293 ArgStringList &CmdArgs)
const {
1296 CmdArgs.push_back(Args.MakeArgString(Path));
1314 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1315 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1316 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1317 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1318 SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1319 if (
getTriple().getArch() == llvm::Triple::x86 ||
1320 getTriple().getArch() == llvm::Triple::x86_64 ||
1323 Res |= SanitizerKind::CFIICall;
1324 if (
getTriple().getArch() == llvm::Triple::x86_64 ||
1326 Res |= SanitizerKind::ShadowCallStack;
1328 Res |= SanitizerKind::MemTag;
1333 ArgStringList &CC1Args)
const {}
1336 ArgStringList &CC1Args)
const {}
1344 ArgStringList &CC1Args)
const {}
1348 return VersionTuple(Version);
1350 if (Version < 10000)
1351 return VersionTuple(Version / 100, Version % 100);
1353 unsigned Build = 0, Factor = 1;
1354 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1355 Build = Build + (Version % 10) * Factor;
1356 return VersionTuple(Version / 100, Version % 100, Build);
1361 const llvm::opt::ArgList &Args)
const {
1362 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1363 const Arg *MSCompatibilityVersion =
1364 Args.getLastArg(options::OPT_fms_compatibility_version);
1366 if (MSCVersion && MSCompatibilityVersion) {
1368 D->
Diag(diag::err_drv_argument_not_allowed_with)
1369 << MSCVersion->getAsString(Args)
1370 << MSCompatibilityVersion->getAsString(Args);
1371 return VersionTuple();
1374 if (MSCompatibilityVersion) {
1376 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1378 D->
Diag(diag::err_drv_invalid_value)
1379 << MSCompatibilityVersion->getAsString(Args)
1380 << MSCompatibilityVersion->getValue();
1387 unsigned Version = 0;
1388 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1390 D->
Diag(diag::err_drv_invalid_value)
1391 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1397 return VersionTuple();
1401 const llvm::opt::DerivedArgList &Args,
bool SameTripleAsHost,
1403 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1405 bool Modified =
false;
1408 for (
auto *A : Args) {
1413 if (A->getOption().matches(options::OPT_m_Group)) {
1416 if (SameTripleAsHost ||
1417 A->getOption().matches(options::OPT_mcode_object_version_EQ))
1426 bool XOpenMPTargetNoTriple =
1427 A->getOption().matches(options::OPT_Xopenmp_target);
1429 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1434 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1437 }
else if (XOpenMPTargetNoTriple) {
1439 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1447 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1448 if (!XOpenMPTargetArg || Index > Prev + 1) {
1449 getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1450 << A->getAsString(Args);
1453 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1454 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
1455 getDriver().
Diag(diag::err_drv_Xopenmp_target_missing_triple);
1458 XOpenMPTargetArg->setBaseArg(A);
1459 A = XOpenMPTargetArg.release();
1460 AllocatedArgs.push_back(A);
1476 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1477 llvm::opt::DerivedArgList *DAL,
1480 unsigned ValuePos = 1;
1481 if (A->getOption().matches(options::OPT_Xarch_device) ||
1482 A->getOption().matches(options::OPT_Xarch_host))
1485 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
1486 unsigned Prev = Index;
1487 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index));
1496 if (!XarchArg || Index > Prev + 1) {
1497 getDriver().
Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1498 << A->getAsString(Args);
1504 "invalid Xarch argument: '%0', not all driver "
1505 "options can be forwared via Xarch argument");
1506 Diags.Report(DiagID) << A->getAsString(Args);
1509 XarchArg->setBaseArg(A);
1510 A = XarchArg.release();
1512 DAL->AddSynthesizedArg(A);
1514 AllocatedArgs->push_back(A);
1518 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1521 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1522 bool Modified =
false;
1525 for (Arg *A : Args) {
1526 bool NeedTrans =
false;
1528 if (A->getOption().matches(options::OPT_Xarch_device)) {
1529 NeedTrans = IsDevice;
1531 }
else if (A->getOption().matches(options::OPT_Xarch_host)) {
1532 NeedTrans = !IsDevice;
1534 }
else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) {
1538 if (BoundArch.empty() || A->getValue(0) != BoundArch)
1543 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)
@ C
Languages that the frontend can parse and compile.
@ 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...