19#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) {
110 llvm::sys::fs::createTemporaryFile(
"toolchain-program",
"txt", OutputFile,
111 llvm::sys::fs::OF_Text);
112 llvm::FileRemover OutputRemover(OutputFile.c_str());
113 std::optional<llvm::StringRef> Redirects[] = {
119 std::string ErrorMessage;
120 int SecondsToWait = 60;
121 if (std::optional<std::string> Str =
122 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
123 if (!llvm::to_integer(*Str, SecondsToWait))
124 return llvm::createStringError(std::error_code(),
125 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
126 "an integer, got '" +
128 SecondsToWait = std::max(SecondsToWait, 0);
130 if (llvm::sys::ExecuteAndWait(Executable, {Executable}, {}, Redirects,
133 return llvm::createStringError(std::error_code(),
134 Executable +
": " + ErrorMessage);
136 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
137 llvm::MemoryBuffer::getFile(OutputFile.c_str());
139 return llvm::createStringError(OutputBuf.getError(),
140 "Failed to read stdout of " + Executable +
141 ": " + OutputBuf.getError().message());
142 return std::move(*OutputBuf);
146 Triple.setEnvironment(
Env);
147 if (EffectiveTriple != llvm::Triple())
148 EffectiveTriple.setEnvironment(
Env);
158 return Args.hasFlag(options::OPT_fintegrated_as,
159 options::OPT_fno_integrated_as,
167 "(Non-)integrated backend set incorrectly!");
169 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
170 options::OPT_fno_integrated_objemitter,
178 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
180 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
181 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
183 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
184 A = Args.getLastArg(options::OPT_fintegrated_objemitter);
186 D.
Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
192 return ENABLE_X86_RELAX_RELOCATIONS;
196 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE &&
getTriple().isOSLinux();
200 const llvm::Triple &Triple,
201 const llvm::opt::ArgList &Args,
203 std::vector<StringRef> Features;
206 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
207 UnifiedFeatures.end());
208 std::vector<std::string> MArch;
209 for (
const auto &Ext : AArch64::Extensions)
210 if (!Ext.UserVisibleName.empty())
211 if (FeatureSet.contains(Ext.PosTargetFeature))
212 MArch.push_back(Ext.UserVisibleName.str());
213 for (
const auto &Ext : AArch64::Extensions)
214 if (!Ext.UserVisibleName.empty())
215 if (FeatureSet.contains(Ext.NegTargetFeature))
216 MArch.push_back((
"no" + Ext.UserVisibleName).str());
218 for (
const auto &ArchInfo : AArch64::ArchInfos)
219 if (FeatureSet.contains(ArchInfo->ArchFeature))
220 ArchName = ArchInfo->Name;
221 assert(!ArchName.empty() &&
"at least one architecture should be found");
222 MArch.insert(MArch.begin(), (
"-march=" + ArchName).str());
223 Result.push_back(llvm::join(MArch,
"+"));
225 const Arg *BranchProtectionArg =
226 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
227 if (BranchProtectionArg) {
228 Result.push_back(BranchProtectionArg->getAsString(Args));
231 if (Arg *AlignArg = Args.getLastArg(
232 options::OPT_mstrict_align, options::OPT_mno_strict_align,
233 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
234 if (AlignArg->getOption().matches(options::OPT_mstrict_align) ||
235 AlignArg->getOption().matches(options::OPT_mno_unaligned_access))
236 Result.push_back(AlignArg->getAsString(Args));
239 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
240 options::OPT_mlittle_endian)) {
241 if (Endian->getOption().matches(options::OPT_mbig_endian))
242 Result.push_back(Endian->getAsString(Args));
245 const Arg *ABIArg = Args.getLastArgNoClaim(options::OPT_mabi_EQ);
247 Result.push_back(ABIArg->getAsString(Args));
252 const llvm::Triple &Triple,
253 const llvm::opt::ArgList &Args,
255 std::vector<StringRef> Features;
257 D, Triple, Args, Features,
false ,
true );
259 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
260 UnifiedFeatures.end());
261 std::vector<std::string> MArch;
262 for (
const auto &Ext : ARM::ARCHExtNames)
263 if (!Ext.Name.empty())
264 if (FeatureSet.contains(Ext.Feature))
265 MArch.push_back(Ext.Name.str());
266 for (
const auto &Ext : ARM::ARCHExtNames)
267 if (!Ext.Name.empty())
268 if (FeatureSet.contains(Ext.NegFeature))
269 MArch.push_back((
"no" + Ext.Name).str());
270 MArch.insert(MArch.begin(), (
"-march=" + Triple.getArchName()).str());
271 Result.push_back(llvm::join(MArch,
"+"));
274#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
275 case llvm::ARM::KIND: \
276 Result.push_back("-mfpu=" NAME); \
278#include "llvm/TargetParser/ARMTargetParser.def"
280 llvm_unreachable(
"Invalid FPUKind");
284 case arm::FloatABI::Soft:
285 Result.push_back(
"-mfloat-abi=soft");
287 case arm::FloatABI::SoftFP:
288 Result.push_back(
"-mfloat-abi=softfp");
290 case arm::FloatABI::Hard:
291 Result.push_back(
"-mfloat-abi=hard");
293 case arm::FloatABI::Invalid:
294 llvm_unreachable(
"Invalid float ABI");
297 const Arg *BranchProtectionArg =
298 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
299 if (BranchProtectionArg) {
300 Result.push_back(BranchProtectionArg->getAsString(Args));
303 if (Arg *AlignArg = Args.getLastArg(
304 options::OPT_mstrict_align, options::OPT_mno_strict_align,
305 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
306 if (AlignArg->getOption().matches(options::OPT_mstrict_align) ||
307 AlignArg->getOption().matches(options::OPT_mno_unaligned_access))
308 Result.push_back(AlignArg->getAsString(Args));
311 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
312 options::OPT_mlittle_endian)) {
313 if (Endian->getOption().matches(options::OPT_mbig_endian))
314 Result.push_back(Endian->getAsString(Args));
319 const llvm::opt::ArgList &Args,
323 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
325 if (!llvm::errorToBool(ISAInfo.takeError()))
326 Result.push_back(
"-march=" + (*ISAInfo)->toString());
335 std::vector<std::string>
Result;
337 Result.push_back(
"--target=" + Triple.str());
339 switch (Triple.getArch()) {
340 case llvm::Triple::aarch64:
341 case llvm::Triple::aarch64_32:
342 case llvm::Triple::aarch64_be:
345 case llvm::Triple::arm:
346 case llvm::Triple::armeb:
347 case llvm::Triple::thumb:
348 case llvm::Triple::thumbeb:
351 case llvm::Triple::riscv32:
352 case llvm::Triple::riscv64:
362 Result.push_back(
"-fno-rtti");
364 Result.push_back(
"-frtti");
367 Result.push_back(
"-fno-exceptions");
369 Result.push_back(
"-fexceptions");
379 SanitizerArgs SanArgs(*
this, JobArgs, !SanitizerArgsChecked);
380 SanitizerArgsChecked =
true;
386 XRayArguments.reset(
new XRayArgs(*
this, Args));
387 return *XRayArguments;
394 const char *ModeFlag;
403 static const DriverSuffix DriverSuffixes[] = {
405 {
"clang++",
"--driver-mode=g++"},
406 {
"clang-c++",
"--driver-mode=g++"},
407 {
"clang-cc",
nullptr},
408 {
"clang-cpp",
"--driver-mode=cpp"},
409 {
"clang-g++",
"--driver-mode=g++"},
410 {
"clang-gcc",
nullptr},
411 {
"clang-cl",
"--driver-mode=cl"},
413 {
"cpp",
"--driver-mode=cpp"},
414 {
"cl",
"--driver-mode=cl"},
415 {
"++",
"--driver-mode=g++"},
416 {
"flang",
"--driver-mode=flang"},
419 {
"flang-new",
"--driver-mode=flang"},
420 {
"clang-dxc",
"--driver-mode=dxc"},
423 for (
const auto &DS : DriverSuffixes) {
424 StringRef Suffix(DS.Suffix);
425 if (ProgName.ends_with(Suffix)) {
426 Pos = ProgName.size() - Suffix.size();
436 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
437 if (is_style_windows(llvm::sys::path::Style::native)) {
439 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
455 if (!DS && ProgName.ends_with(
".exe")) {
458 ProgName = ProgName.drop_back(StringRef(
".exe").size());
465 ProgName = ProgName.rtrim(
"0123456789.");
472 ProgName = ProgName.slice(0, ProgName.rfind(
'-'));
485 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
487 size_t LastComponent = ProgName.rfind(
'-', SuffixPos);
488 if (LastComponent == std::string::npos)
490 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
491 SuffixEnd - LastComponent - 1);
494 StringRef Prefix(ProgName);
495 Prefix = Prefix.slice(0, LastComponent);
496 std::string IgnoredError;
498 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
507 switch (Triple.getArch()) {
508 case llvm::Triple::aarch64: {
513 case llvm::Triple::aarch64_32:
515 case llvm::Triple::ppc:
517 case llvm::Triple::ppcle:
519 case llvm::Triple::ppc64:
521 case llvm::Triple::ppc64le:
524 return Triple.getArchName();
537Tool *ToolChain::getClang()
const {
543Tool *ToolChain::getFlang()
const {
554 llvm_unreachable(
"Linking is not supported by this toolchain");
558 llvm_unreachable(
"Creating static lib is not supported by this toolchain");
561Tool *ToolChain::getAssemble()
const {
564 return Assemble.get();
567Tool *ToolChain::getClangAs()
const {
570 return Assemble.get();
573Tool *ToolChain::getLink()
const {
579Tool *ToolChain::getStaticLibTool()
const {
582 return StaticLibTool.get();
585Tool *ToolChain::getIfsMerge()
const {
588 return IfsMerge.get();
591Tool *ToolChain::getOffloadBundler()
const {
597Tool *ToolChain::getOffloadPackager()
const {
603Tool *ToolChain::getLinkerWrapper()
const {
612 return getAssemble();
615 return getIfsMerge();
621 return getStaticLibTool();
630 llvm_unreachable(
"Invalid tool kind.");
644 return getOffloadBundler();
647 return getOffloadPackager();
649 return getLinkerWrapper();
652 llvm_unreachable(
"Invalid tool kind.");
656 const ArgList &Args) {
657 const llvm::Triple &Triple = TC.
getTriple();
658 bool IsWindows = Triple.isOSWindows();
661 return Triple.getArchName();
663 if (TC.
getArch() == llvm::Triple::arm || TC.
getArch() == llvm::Triple::armeb)
669 if (TC.
getArch() == llvm::Triple::x86 && Triple.isAndroid())
672 if (TC.
getArch() == llvm::Triple::x86_64 && Triple.isX32())
675 return llvm::Triple::getArchTypeName(TC.
getArch());
679 if (Triple.isOSDarwin())
682 switch (Triple.getOS()) {
683 case llvm::Triple::FreeBSD:
685 case llvm::Triple::NetBSD:
687 case llvm::Triple::OpenBSD:
689 case llvm::Triple::Solaris:
691 case llvm::Triple::AIX:
705 }
else if (Triple.isOSUnknown()) {
706 llvm::sys::path::append(
Path,
"lib");
710 return std::string(
Path);
717 return llvm::sys::path::filename(CRTAbsolutePath).str();
723 bool AddArch)
const {
725 bool IsITANMSVCWindows =
726 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
733 Suffix = IsITANMSVCWindows ?
".obj" :
".o";
736 Suffix = IsITANMSVCWindows ?
".lib" :
".a";
739 Suffix = TT.isOSWindows()
740 ? (TT.isWindowsGNUEnvironment() ?
".dll.a" :
".lib")
745 std::string ArchAndEnv;
748 const char *
Env = TT.isAndroid() ?
"-android" :
"";
749 ArchAndEnv = (
"-" + Arch +
Env).str();
751 return (Prefix + Twine(
"clang_rt.") + Component + ArchAndEnv + Suffix).str();
757 std::string CRTBasename =
762 llvm::sys::path::append(
P, CRTBasename);
764 return std::string(
P);
775 llvm::sys::path::append(OldPath, CRTBasename);
777 return std::string(OldPath);
782 return std::string(
Path);
794std::optional<std::string>
795ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir)
const {
796 llvm::Triple TripleWithoutLevel(
getTriple());
797 TripleWithoutLevel.setEnvironmentName(
"android");
798 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
799 unsigned TripleVersion =
getTriple().getEnvironmentVersion().getMajor();
800 unsigned BestVersion = 0;
803 bool UsingUnversionedDir =
false;
805 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(BaseDir, EC), LE;
806 !EC && LI != LE; LI = LI.increment(EC)) {
807 StringRef DirName = llvm::sys::path::filename(LI->path());
808 StringRef DirNameSuffix = DirName;
809 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
810 if (DirNameSuffix.empty() && TripleDir.empty()) {
812 UsingUnversionedDir =
true;
815 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
816 Version < TripleVersion) {
817 BestVersion = Version;
819 UsingUnversionedDir =
false;
825 if (TripleDir.empty())
829 llvm::sys::path::append(
P, TripleDir);
830 if (UsingUnversionedDir)
832 return std::string(
P);
835std::optional<std::string>
837 auto getPathForTriple =
838 [&](
const llvm::Triple &Triple) -> std::optional<std::string> {
840 llvm::sys::path::append(
P, Triple.str());
842 return std::string(
P);
866 ArmTriple.setArch(Triple::arm);
867 if (
auto Path = getPathForTriple(ArmTriple))
872 return getFallbackAndroidTargetPath(BaseDir);
879 llvm::sys::path::append(
P,
"lib");
883 if (Triple.isOSDarwin() || Triple.isOSAIX())
885 llvm::sys::path::append(
P, Triple.str());
886 return std::string(
P);
891 llvm::sys::path::append(
P,
"..",
"lib");
897 llvm::sys::path::append(
P,
"..",
"include");
906 llvm::sys::path::append(
Path,
"lib");
908 llvm::sys::path::append(
Path, S);
909 Paths.push_back(std::string(
Path));
918 if (Args.hasArg(options::OPT_noprofilelib))
921 return Args.hasArg(options::OPT_fprofile_generate) ||
922 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
923 Args.hasArg(options::OPT_fcs_profile_generate) ||
924 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
925 Args.hasArg(options::OPT_fprofile_instr_generate) ||
926 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
927 Args.hasArg(options::OPT_fcreate_profile) ||
928 Args.hasArg(options::OPT_forder_file_instrumentation) ||
929 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage) ||
930 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage_EQ);
934 return Args.hasArg(options::OPT_coverage) ||
935 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
941 if (
getDriver().ShouldUseClangCompiler(JA))
return getClang();
959 *LinkerIsLLD =
false;
963 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
964 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
971 if (
const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
972 std::string
Path(A->getValue());
974 if (llvm::sys::path::parent_path(
Path).empty())
976 if (llvm::sys::fs::can_execute(
Path)) {
978 *LinkerIsLLD = UseLinker ==
"lld";
979 return std::string(
Path);
982 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
987 if (UseLinker.empty() || UseLinker ==
"ld") {
989 if (llvm::sys::path::is_absolute(DefaultLinker))
990 return std::string(DefaultLinker);
999 if (UseLinker.contains(
'/'))
1002 if (llvm::sys::path::is_absolute(UseLinker)) {
1005 if (llvm::sys::fs::can_execute(UseLinker))
1006 return std::string(UseLinker);
1009 if (Triple.isOSDarwin())
1010 LinkerName.append(
"ld64.");
1012 LinkerName.append(
"ld.");
1013 LinkerName.append(UseLinker);
1016 if (llvm::sys::fs::can_execute(LinkerPath)) {
1018 *LinkerIsLLD = UseLinker ==
"lld";
1024 getDriver().
Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
1031 if (Triple.isOSDarwin())
1042 if (D.
IsFlangMode() &&
id == types::TY_PP_Fortran)
1043 id = types::TY_Fortran;
1053 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
1054 switch (HostTriple.getArch()) {
1057 case llvm::Triple::arm:
1058 case llvm::Triple::armeb:
1059 case llvm::Triple::thumb:
1060 case llvm::Triple::thumbeb:
1061 return getArch() != llvm::Triple::arm &&
getArch() != llvm::Triple::thumb &&
1062 getArch() != llvm::Triple::armeb &&
getArch() != llvm::Triple::thumbeb;
1064 return HostTriple.getArch() !=
getArch();
1073llvm::ExceptionHandling
1075 return llvm::ExceptionHandling::None;
1079 if (Model ==
"single") {
1081 return Triple.getArch() == llvm::Triple::arm ||
1082 Triple.getArch() == llvm::Triple::armeb ||
1083 Triple.getArch() == llvm::Triple::thumb ||
1084 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
1085 }
else if (Model ==
"posix")
1097 case llvm::Triple::x86_64: {
1099 if (!Triple.isOSBinFormatMachO())
1102 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1105 StringRef MArch = A->getValue();
1106 if (MArch ==
"x86_64h")
1107 Triple.setArchName(MArch);
1109 return Triple.getTriple();
1111 case llvm::Triple::aarch64: {
1114 if (!Triple.isOSBinFormatMachO())
1115 return Triple.getTriple();
1117 if (Triple.isArm64e())
1118 return Triple.getTriple();
1123 Triple.setArchName(
"arm64");
1124 return Triple.getTriple();
1126 case llvm::Triple::aarch64_32:
1128 case llvm::Triple::amdgcn: {
1130 if (Args.getLastArgValue(options::OPT_mcpu_EQ) ==
"amdgcnspirv")
1131 Triple.setArch(llvm::Triple::ArchType::spirv64);
1132 return Triple.getTriple();
1134 case llvm::Triple::arm:
1135 case llvm::Triple::armeb:
1136 case llvm::Triple::thumb:
1137 case llvm::Triple::thumbeb: {
1141 return Triple.getTriple();
1156 ArgStringList &CC1Args)
const {
1161 const ArgList &DriverArgs, ArgStringList &CC1Args,
1165 ArgStringList &CC1ASArgs)
const {}
1170 llvm::opt::ArgStringList &CmdArgs)
const {
1178 const ArgList &Args)
const {
1180 return *runtimeLibType;
1182 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
1183 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
1186 if (LibName ==
"compiler-rt")
1188 else if (LibName ==
"libgcc")
1190 else if (LibName ==
"platform")
1195 << A->getAsString(Args);
1200 return *runtimeLibType;
1204 const ArgList &Args)
const {
1206 return *unwindLibType;
1208 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
1209 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
1211 if (LibName ==
"none")
1213 else if (LibName ==
"platform" || LibName ==
"") {
1222 }
else if (LibName ==
"libunwind") {
1226 }
else if (LibName ==
"libgcc")
1231 << A->getAsString(Args);
1236 return *unwindLibType;
1241 return *cxxStdlibType;
1243 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1244 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
1247 if (LibName ==
"libc++")
1249 else if (LibName ==
"libstdc++")
1251 else if (LibName ==
"platform")
1256 << A->getAsString(Args);
1261 return *cxxStdlibType;
1266 ArgStringList &CC1Args,
1267 const Twine &
Path) {
1268 CC1Args.push_back(
"-internal-isystem");
1269 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1281 ArgStringList &CC1Args,
1282 const Twine &
Path) {
1283 CC1Args.push_back(
"-internal-externc-isystem");
1284 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1288 ArgStringList &CC1Args,
1289 const Twine &
Path) {
1290 if (llvm::sys::fs::exists(
Path))
1296 ArgStringList &CC1Args,
1298 for (
const auto &
Path : Paths) {
1299 CC1Args.push_back(
"-internal-isystem");
1300 CC1Args.push_back(DriverArgs.MakeArgString(
Path));
1305 const Twine &B,
const Twine &
C,
1308 llvm::sys::path::append(
Result, llvm::sys::path::Style::posix, A, B,
C,
D);
1309 return std::string(
Result);
1315 std::string MaxVersionString;
1317 llvm::sys::path::append(
Path,
"c++");
1318 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(
Path, EC), LE;
1319 !EC && LI != LE; LI = LI.increment(EC)) {
1320 StringRef VersionText = llvm::sys::path::filename(LI->path());
1322 if (VersionText[0] ==
'v' &&
1323 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
1324 if (Version > MaxVersion) {
1325 MaxVersion = Version;
1326 MaxVersionString = std::string(VersionText);
1332 return MaxVersionString;
1336 ArgStringList &CC1Args)
const {
1346 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1350 const llvm::opt::ArgList &DriverArgs,
1351 llvm::opt::ArgStringList &CC1Args)
const {
1352 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1361 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1362 for (
const auto &
P :
1363 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1369 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1370 options::OPT_nostdlibxx);
1374 ArgStringList &CmdArgs)
const {
1375 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1376 "should not have called this");
1381 CmdArgs.push_back(
"-lc++");
1382 if (Args.hasArg(options::OPT_fexperimental_library))
1383 CmdArgs.push_back(
"-lc++experimental");
1387 CmdArgs.push_back(
"-lstdc++");
1393 ArgStringList &CmdArgs)
const {
1395 if(LibPath.length() > 0)
1396 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
1400 ArgStringList &CmdArgs)
const {
1401 CmdArgs.push_back(
"-lcc_kext");
1405 std::string &
Path)
const {
1409 bool Default = !Args.hasArgNoClaim(options::OPT_shared);
1415 Arg *A = Args.getLastArg(
1416 options::OPT_ffast_math, options::OPT_fno_fast_math,
1417 options::OPT_funsafe_math_optimizations,
1418 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ);
1420 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1421 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1423 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
1424 StringRef Model = A->getValue();
1425 if (Model !=
"fast" && Model !=
"aggressive")
1432 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz,
Default))
1437 return (
Path !=
"crtfastmath.o");
1441 ArgStringList &CmdArgs)
const {
1444 CmdArgs.push_back(Args.MakeArgString(
Path));
1462 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1463 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1464 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1465 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1466 SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1467 if (
getTriple().getArch() == llvm::Triple::x86 ||
1468 getTriple().getArch() == llvm::Triple::x86_64 ||
1469 getTriple().getArch() == llvm::Triple::arm ||
1473 Res |= SanitizerKind::CFIICall;
1474 if (
getTriple().getArch() == llvm::Triple::x86_64 ||
1476 Res |= SanitizerKind::ShadowCallStack;
1478 Res |= SanitizerKind::MemTag;
1483 ArgStringList &CC1Args)
const {}
1486 ArgStringList &CC1Args)
const {}
1494 ArgStringList &CC1Args)
const {}
1498 return VersionTuple(Version);
1500 if (Version < 10000)
1501 return VersionTuple(Version / 100, Version % 100);
1503 unsigned Build = 0, Factor = 1;
1504 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1505 Build = Build + (Version % 10) * Factor;
1506 return VersionTuple(Version / 100, Version % 100, Build);
1511 const llvm::opt::ArgList &Args)
const {
1512 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1513 const Arg *MSCompatibilityVersion =
1514 Args.getLastArg(options::OPT_fms_compatibility_version);
1516 if (MSCVersion && MSCompatibilityVersion) {
1518 D->Diag(diag::err_drv_argument_not_allowed_with)
1519 << MSCVersion->getAsString(Args)
1520 << MSCompatibilityVersion->getAsString(Args);
1521 return VersionTuple();
1524 if (MSCompatibilityVersion) {
1526 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1528 D->Diag(diag::err_drv_invalid_value)
1529 << MSCompatibilityVersion->getAsString(Args)
1530 << MSCompatibilityVersion->getValue();
1537 unsigned Version = 0;
1538 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1540 D->Diag(diag::err_drv_invalid_value)
1541 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1547 return VersionTuple();
1551 const llvm::opt::DerivedArgList &Args,
bool SameTripleAsHost,
1553 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1555 bool Modified =
false;
1558 for (
auto *A : Args) {
1563 if (A->getOption().matches(options::OPT_m_Group)) {
1566 if (SameTripleAsHost ||
1567 A->getOption().matches(options::OPT_mcode_object_version_EQ))
1576 bool XOpenMPTargetNoTriple =
1577 A->getOption().matches(options::OPT_Xopenmp_target);
1579 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1584 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1587 }
else if (XOpenMPTargetNoTriple) {
1589 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1597 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1598 if (!XOpenMPTargetArg || Index > Prev + 1) {
1599 if (!A->isClaimed()) {
1600 getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1601 << A->getAsString(Args);
1605 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1606 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
1607 getDriver().
Diag(diag::err_drv_Xopenmp_target_missing_triple);
1610 XOpenMPTargetArg->setBaseArg(A);
1611 A = XOpenMPTargetArg.release();
1612 AllocatedArgs.push_back(A);
1628 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1629 llvm::opt::DerivedArgList *DAL,
1632 unsigned ValuePos = 1;
1633 if (A->getOption().matches(options::OPT_Xarch_device) ||
1634 A->getOption().matches(options::OPT_Xarch_host))
1637 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
1638 unsigned Prev = Index;
1639 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index));
1648 if (!XarchArg || Index > Prev + 1) {
1649 getDriver().
Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1650 << A->getAsString(Args);
1656 "invalid Xarch argument: '%0', not all driver "
1657 "options can be forwared via Xarch argument");
1658 Diags.Report(DiagID) << A->getAsString(Args);
1661 XarchArg->setBaseArg(A);
1662 A = XarchArg.release();
1664 DAL->AddSynthesizedArg(A);
1666 AllocatedArgs->push_back(A);
1670 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1673 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1674 bool Modified =
false;
1677 for (Arg *A : Args) {
1678 bool NeedTrans =
false;
1680 if (A->getOption().matches(options::OPT_Xarch_device)) {
1681 NeedTrans = IsDevice;
1683 }
else if (A->getOption().matches(options::OPT_Xarch_host)) {
1684 NeedTrans = !IsDevice;
1686 }
else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) {
1690 if (BoundArch.empty() || A->getValue(0) != BoundArch)
1695 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.
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...