clang: lib/Driver/ToolChain.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
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"
49#include
50#include
51#include
52#include
53
54using namespace clang;
55using namespace driver;
56using namespace tools;
57using namespace llvm;
59
61 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
62 options::OPT_fno_rtti, options::OPT_frtti);
63}
64
66 const llvm::Triple &Triple,
67 const Arg *CachedRTTIArg) {
68
69 if (CachedRTTIArg) {
70 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
72 else
74 }
75
76
77 bool NoRTTI = Triple.isPS() || Triple.isDriverKit();
79}
80
82 if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
83 true)) {
85 }
87}
88
90 const ArgList &Args)
94 auto addIfExists = [this](path_list &List, const std::string &Path) {
96 List.push_back(Path);
97 };
98
105}
106
110 llvm::sys::fs::createTemporaryFile("toolchain-program", "txt", OutputFile,
111 llvm::sys::fs::OF_Text);
112 llvm::FileRemover OutputRemover(OutputFile.c_str());
113 std::optionalllvm::StringRef Redirects[] = {
114 {""},
115 OutputFile.str(),
116 {""},
117 };
118
119 std::string ErrorMessage;
120 int SecondsToWait = 60;
121 if (std::optionalstd::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 '" +
127 *Str + "'");
128 SecondsToWait = std::max(SecondsToWait, 0);
129 }
130 if (llvm::sys::ExecuteAndWait(Executable, {Executable}, {}, Redirects,
131 SecondsToWait,
132 0, &ErrorMessage))
133 return llvm::createStringError(std::error_code(),
134 Executable + ": " + ErrorMessage);
135
136 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> OutputBuf =
137 llvm::MemoryBuffer::getFile(OutputFile.c_str());
138 if (!OutputBuf)
139 return llvm::createStringError(OutputBuf.getError(),
140 "Failed to read stdout of " + Executable +
141 ": " + OutputBuf.getError().message());
142 return std::move(*OutputBuf);
143}
144
146 Triple.setEnvironment(Env);
147 if (EffectiveTriple != llvm::Triple())
148 EffectiveTriple.setEnvironment(Env);
149}
150
152
155}
156
158 return Args.hasFlag(options::OPT_fintegrated_as,
159 options::OPT_fno_integrated_as,
161}
162
164 assert(
167 "(Non-)integrated backend set incorrectly!");
168
169 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
170 options::OPT_fno_integrated_objemitter,
172
173
174
175 unsigned DiagID;
178 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
179 else
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();
187
188 return IBackend;
189}
190
192 return ENABLE_X86_RELAX_RELOCATIONS;
193}
194
196 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
197}
198
200 const llvm::opt::ArgList &Args) {
201 for (const Arg *MultilibFlagArg :
202 Args.filtered(options::OPT_fmultilib_flag)) {
203 List.push_back(MultilibFlagArg->getAsString(Args));
204 MultilibFlagArg->claim();
205 }
206}
207
209 const llvm::Triple &Triple,
210 const llvm::opt::ArgList &Args,
212 std::vector Features;
215 llvm::DenseSet FeatureSet(UnifiedFeatures.begin(),
216 UnifiedFeatures.end());
217 std::vectorstd::string MArch;
218 for (const auto &Ext : AArch64::Extensions)
219 if (!Ext.UserVisibleName.empty())
220 if (FeatureSet.contains(Ext.PosTargetFeature))
221 MArch.push_back(Ext.UserVisibleName.str());
222 for (const auto &Ext : AArch64::Extensions)
223 if (!Ext.UserVisibleName.empty())
224 if (FeatureSet.contains(Ext.NegTargetFeature))
225 MArch.push_back(("no" + Ext.UserVisibleName).str());
226 StringRef ArchName;
227 for (const auto &ArchInfo : AArch64::ArchInfos)
228 if (FeatureSet.contains(ArchInfo->ArchFeature))
229 ArchName = ArchInfo->Name;
230 assert(!ArchName.empty() && "at least one architecture should be found");
231 MArch.insert(MArch.begin(), ("-march=" + ArchName).str());
232 Result.push_back(llvm::join(MArch, "+"));
233
234 const Arg *BranchProtectionArg =
235 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
236 if (BranchProtectionArg) {
237 Result.push_back(BranchProtectionArg->getAsString(Args));
238 }
239
240 if (Arg *AlignArg = Args.getLastArg(
241 options::OPT_mstrict_align, options::OPT_mno_strict_align,
242 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
243 if (AlignArg->getOption().matches(options::OPT_mstrict_align) ||
244 AlignArg->getOption().matches(options::OPT_mno_unaligned_access))
245 Result.push_back(AlignArg->getAsString(Args));
246 }
247
248 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
249 options::OPT_mlittle_endian)) {
250 if (Endian->getOption().matches(options::OPT_mbig_endian))
251 Result.push_back(Endian->getAsString(Args));
252 }
253
254 const Arg *ABIArg = Args.getLastArgNoClaim(options::OPT_mabi_EQ);
255 if (ABIArg) {
256 Result.push_back(ABIArg->getAsString(Args));
257 }
258
260}
261
263 const llvm::Triple &Triple,
264 const llvm::opt::ArgList &Args,
266 std::vector Features;
268 D, Triple, Args, Features, false , true );
270 llvm::DenseSet FeatureSet(UnifiedFeatures.begin(),
271 UnifiedFeatures.end());
272 std::vectorstd::string MArch;
273 for (const auto &Ext : ARM::ARCHExtNames)
274 if (!Ext.Name.empty())
275 if (FeatureSet.contains(Ext.Feature))
276 MArch.push_back(Ext.Name.str());
277 for (const auto &Ext : ARM::ARCHExtNames)
278 if (!Ext.Name.empty())
279 if (FeatureSet.contains(Ext.NegFeature))
280 MArch.push_back(("no" + Ext.Name).str());
281 MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
282 Result.push_back(llvm::join(MArch, "+"));
283
284 switch (FPUKind) {
285#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
286 case llvm::ARM::KIND: \
287 Result.push_back("-mfpu=" NAME); \
288 break;
289#include "llvm/TargetParser/ARMTargetParser.def"
290 default:
291 llvm_unreachable("Invalid FPUKind");
292 }
293
295 case arm::FloatABI::Soft:
296 Result.push_back("-mfloat-abi=soft");
297 break;
298 case arm::FloatABI::SoftFP:
299 Result.push_back("-mfloat-abi=softfp");
300 break;
301 case arm::FloatABI::Hard:
302 Result.push_back("-mfloat-abi=hard");
303 break;
304 case arm::FloatABI::Invalid:
305 llvm_unreachable("Invalid float ABI");
306 }
307
308 const Arg *BranchProtectionArg =
309 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
310 if (BranchProtectionArg) {
311 Result.push_back(BranchProtectionArg->getAsString(Args));
312 }
313
314 if (Arg *AlignArg = Args.getLastArg(
315 options::OPT_mstrict_align, options::OPT_mno_strict_align,
316 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
317 if (AlignArg->getOption().matches(options::OPT_mstrict_align) ||
318 AlignArg->getOption().matches(options::OPT_mno_unaligned_access))
319 Result.push_back(AlignArg->getAsString(Args));
320 }
321
322 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
323 options::OPT_mlittle_endian)) {
324 if (Endian->getOption().matches(options::OPT_mbig_endian))
325 Result.push_back(Endian->getAsString(Args));
326 }
328}
329
331 const llvm::opt::ArgList &Args,
334
335 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
336 Arch, true);
337 if (!llvm::errorToBool(ISAInfo.takeError()))
338 Result.push_back("-march=" + (*ISAInfo)->toString());
339
341}
342
346
347 std::vectorstd::string Result;
349 Result.push_back("--target=" + Triple.str());
350
351 switch (Triple.getArch()) {
352 case llvm::Triple::aarch64:
353 case llvm::Triple::aarch64_32:
354 case llvm::Triple::aarch64_be:
356 break;
357 case llvm::Triple::arm:
358 case llvm::Triple::armeb:
359 case llvm::Triple::thumb:
360 case llvm::Triple::thumbeb:
362 break;
363 case llvm::Triple::riscv32:
364 case llvm::Triple::riscv64:
366 break;
367 default:
368 break;
369 }
370
371
372
374 Result.push_back("-fno-rtti");
375 else
376 Result.push_back("-frtti");
377
379 Result.push_back("-fno-exceptions");
380 else
381 Result.push_back("-fexceptions");
382
383
387}
388
391 SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);
392 SanitizerArgsChecked = true;
393 return SanArgs;
394}
395
397 if (!XRayArguments)
398 XRayArguments.reset(new XRayArgs(*this, Args));
399 return *XRayArguments;
400}
401
402namespace {
403
404struct DriverSuffix {
405 const char *Suffix;
406 const char *ModeFlag;
407};
408
409}
410
411static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
412
413
414
415 static const DriverSuffix DriverSuffixes[] = {
416 {"clang", nullptr},
417 {"clang++", "--driver-mode=g++"},
418 {"clang-c++", "--driver-mode=g++"},
419 {"clang-cc", nullptr},
420 {"clang-cpp", "--driver-mode=cpp"},
421 {"clang-g++", "--driver-mode=g++"},
422 {"clang-gcc", nullptr},
423 {"clang-cl", "--driver-mode=cl"},
424 {"cc", nullptr},
425 {"cpp", "--driver-mode=cpp"},
426 {"cl", "--driver-mode=cl"},
427 {"++", "--driver-mode=g++"},
428 {"flang", "--driver-mode=flang"},
429
430
431 {"flang-new", "--driver-mode=flang"},
432 {"clang-dxc", "--driver-mode=dxc"},
433 };
434
435 for (const auto &DS : DriverSuffixes) {
436 StringRef Suffix(DS.Suffix);
437 if (ProgName.ends_with(Suffix)) {
438 Pos = ProgName.size() - Suffix.size();
439 return &DS;
440 }
441 }
442 return nullptr;
443}
444
445
446
448 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
449 if (is_style_windows(llvm::sys::path::Style::native)) {
450
451 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
452 ::tolower);
453 }
454 return ProgName;
455}
456
457static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
458
459
460
461
462
463
464
466
467 if (!DS && ProgName.ends_with(".exe")) {
468
469
470 ProgName = ProgName.drop_back(StringRef(".exe").size());
472 }
473
474 if (!DS) {
475
476
477 ProgName = ProgName.rtrim("0123456789.");
479 }
480
481 if (!DS) {
482
483
484 ProgName = ProgName.slice(0, ProgName.rfind('-'));
486 }
487 return DS;
488}
489
493 size_t SuffixPos;
495 if (!DS)
496 return {};
497 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
498
499 size_t LastComponent = ProgName.rfind('-', SuffixPos);
500 if (LastComponent == std:🧵:npos)
501 return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);
502 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
503 SuffixEnd - LastComponent - 1);
504
505
506 StringRef Prefix(ProgName);
507 Prefix = Prefix.slice(0, LastComponent);
508 std::string IgnoredError;
509 bool IsRegistered =
510 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
511 return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag,
512 IsRegistered};
513}
514
516
517
518
519 switch (Triple.getArch()) {
520 case llvm::Triple::aarch64: {
522 return "arm64e";
523 return "arm64";
524 }
525 case llvm::Triple::aarch64_32:
526 return "arm64_32";
527 case llvm::Triple::ppc:
528 return "ppc";
529 case llvm::Triple::ppcle:
530 return "ppcle";
531 case llvm::Triple::ppc64:
532 return "ppc64";
533 case llvm::Triple::ppc64le:
534 return "ppc64le";
535 default:
536 return Triple.getArchName();
537 }
538}
539
542}
543
547}
548
549Tool *ToolChain::getClang() const {
552 return Clang.get();
553}
554
555Tool *ToolChain::getFlang() const {
558 return Flang.get();
559}
560
563}
564
566 llvm_unreachable("Linking is not supported by this toolchain");
567}
568
570 llvm_unreachable("Creating static lib is not supported by this toolchain");
571}
572
573Tool *ToolChain::getAssemble() const {
574 if (!Assemble)
576 return Assemble.get();
577}
578
579Tool *ToolChain::getClangAs() const {
580 if (!Assemble)
582 return Assemble.get();
583}
584
585Tool *ToolChain::getLink() const {
586 if (!Link)
588 return Link.get();
589}
590
591Tool *ToolChain::getStaticLibTool() const {
592 if (!StaticLibTool)
594 return StaticLibTool.get();
595}
596
597Tool *ToolChain::getIfsMerge() const {
598 if (!IfsMerge)
600 return IfsMerge.get();
601}
602
603Tool *ToolChain::getOffloadBundler() const {
607}
608
609Tool *ToolChain::getOffloadPackager() const {
613}
614
615Tool *ToolChain::getLinkerWrapper() const {
619}
620
622 switch (AC) {
624 return getAssemble();
625
627 return getIfsMerge();
628
630 return getLink();
631
633 return getStaticLibTool();
634
642 llvm_unreachable("Invalid tool kind.");
643
652 return getClang();
653
656 return getOffloadBundler();
657
659 return getOffloadPackager();
661 return getLinkerWrapper();
662 }
663
664 llvm_unreachable("Invalid tool kind.");
665}
666
668 const ArgList &Args) {
669 const llvm::Triple &Triple = TC.getTriple();
670 bool IsWindows = Triple.isOSWindows();
671
673 return Triple.getArchName();
674
675 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
676 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
677 ? "armhf"
678 : "arm";
679
680
681 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid())
682 return "i686";
683
684 if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32())
685 return "x32";
686
687 return llvm::Triple::getArchTypeName(TC.getArch());
688}
689
691 if (Triple.isOSDarwin())
692 return "darwin";
693
694 switch (Triple.getOS()) {
695 case llvm::Triple::FreeBSD:
696 return "freebsd";
697 case llvm::Triple::NetBSD:
698 return "netbsd";
699 case llvm::Triple::OpenBSD:
700 return "openbsd";
701 case llvm::Triple::Solaris:
702 return "sunos";
703 case llvm::Triple::AIX:
704 return "aix";
705 default:
707 }
708}
709
716 }
717 } else if (Triple.isOSUnknown()) {
718 llvm::sys::path::append(Path, "lib");
719 } else {
721 }
722 return std::string(Path);
723}
724
726 StringRef Component,
728 std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type);
729 return llvm::sys::path::filename(CRTAbsolutePath).str();
730}
731
733 StringRef Component,
735 bool AddArch) const {
736 const llvm::Triple &TT = getTriple();
737 bool IsITANMSVCWindows =
738 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
739
740 const char *Prefix =
742 const char *Suffix;
743 switch (Type) {
745 Suffix = IsITANMSVCWindows ? ".obj" : ".o";
746 break;
748 Suffix = IsITANMSVCWindows ? ".lib" : ".a";
749 break;
751 Suffix = TT.isOSWindows()
752 ? (TT.isWindowsGNUEnvironment() ? ".dll.a" : ".lib")
753 : ".so";
754 break;
755 }
756
757 std::string ArchAndEnv;
758 if (AddArch) {
760 const char *Env = TT.isAndroid() ? "-android" : "";
761 ArchAndEnv = ("-" + Arch + Env).str();
762 }
763 return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();
764}
765
768
769 std::string CRTBasename =
774 llvm::sys::path::append(P, CRTBasename);
776 return std::string(P);
777 if (Path.empty())
779 }
781 Path.clear();
782
783
784 CRTBasename =
787 llvm::sys::path::append(OldPath, CRTBasename);
788 if (Path.empty() || getVFS().exists(OldPath))
789 return std::string(OldPath);
790
791
792
793
794 return std::string(Path);
795}
796
798 StringRef Component,
801}
802
803
804
805
806std::optionalstd::string
807ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
808 llvm::Triple TripleWithoutLevel(getTriple());
809 TripleWithoutLevel.setEnvironmentName("android");
810 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
811 unsigned TripleVersion = getTriple().getEnvironmentVersion().getMajor();
812 unsigned BestVersion = 0;
813
815 bool UsingUnversionedDir = false;
816 std::error_code EC;
817 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(BaseDir, EC), LE;
818 !EC && LI != LE; LI = LI.increment(EC)) {
819 StringRef DirName = llvm::sys::path::filename(LI->path());
820 StringRef DirNameSuffix = DirName;
821 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
822 if (DirNameSuffix.empty() && TripleDir.empty()) {
823 TripleDir = DirName;
824 UsingUnversionedDir = true;
825 } else {
826 unsigned Version;
827 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
828 Version < TripleVersion) {
829 BestVersion = Version;
830 TripleDir = DirName;
831 UsingUnversionedDir = false;
832 }
833 }
834 }
835 }
836
837 if (TripleDir.empty())
838 return {};
839
841 llvm::sys::path::append(P, TripleDir);
842 if (UsingUnversionedDir)
844 return std::string(P);
845}
846
847std::optionalstd::string
849 auto getPathForTriple =
850 [&](const llvm::Triple &Triple) -> std::optionalstd::string {
852 llvm::sys::path::append(P, Triple.str());
854 return std::string(P);
855 return {};
856 };
857
859 return *Path;
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
877 llvm::Triple ArmTriple = getTriple();
878 ArmTriple.setArch(Triple::arm);
879 if (auto Path = getPathForTriple(ArmTriple))
880 return *Path;
881 }
882
884 return getFallbackAndroidTargetPath(BaseDir);
885
886 return {};
887}
888
891 llvm::sys::path::append(P, "lib");
893 return Ret;
894
895 if (Triple.isOSDarwin() || Triple.isOSAIX())
896 return {};
897 llvm::sys::path::append(P, Triple.str());
898 return std::string(P);
899}
900
903 llvm::sys::path::append(P, "..", "lib");
905}
906
909 llvm::sys::path::append(P, "..", "include");
911}
912
915
918 llvm::sys::path::append(Path, "lib");
919 for (auto &S : SS)
920 llvm::sys::path::append(Path, S);
921 Paths.push_back(std::string(Path));
922 };
923
926 return Paths;
927}
928
930 if (Args.hasArg(options::OPT_noprofilelib))
931 return false;
932
933 return Args.hasArg(options::OPT_fprofile_generate) ||
934 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
935 Args.hasArg(options::OPT_fcs_profile_generate) ||
936 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
937 Args.hasArg(options::OPT_fprofile_instr_generate) ||
938 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
939 Args.hasArg(options::OPT_fcreate_profile) ||
940 Args.hasArg(options::OPT_forder_file_instrumentation) ||
941 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage) ||
942 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage_EQ);
943}
944
946 return Args.hasArg(options::OPT_coverage) ||
947 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
948 false);
949}
950
952 if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang();
953 if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
957 return getClangAs();
959}
960
963}
964
967}
968
970 if (LinkerIsLLD)
971 *LinkerIsLLD = false;
972
973
974
975 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
976 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
977
978
979
980
981
982
983 if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
984 std::string Path(A->getValue());
985 if (.empty()) {
986 if (llvm::sys::path::parent_path(Path).empty())
988 if (llvm::sys::fs::can_execute(Path)) {
989 if (LinkerIsLLD)
990 *LinkerIsLLD = UseLinker == "lld";
991 return std::string(Path);
992 }
993 }
994 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
996 }
997
998
999 if (UseLinker.empty() || UseLinker == "ld") {
1001 if (llvm::sys::path::is_absolute(DefaultLinker))
1002 return std::string(DefaultLinker);
1003 else
1005 }
1006
1007
1008
1009
1010
1011 if (UseLinker.contains('/'))
1013
1014 if (llvm::sys::path::is_absolute(UseLinker)) {
1015
1016
1017 if (llvm::sys::fs::can_execute(UseLinker))
1018 return std::string(UseLinker);
1019 } else {
1021 if (Triple.isOSDarwin())
1022 LinkerName.append("ld64.");
1023 else
1024 LinkerName.append("ld.");
1025 LinkerName.append(UseLinker);
1026
1027 std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
1028 if (llvm::sys::fs::can_execute(LinkerPath)) {
1029 if (LinkerIsLLD)
1030 *LinkerIsLLD = UseLinker == "lld";
1031 return LinkerPath;
1032 }
1033 }
1034
1035 if (A)
1036 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
1037
1039}
1040
1042
1043 if (Triple.isOSDarwin())
1046}
1047
1050
1051
1052
1053
1054 if (D.IsFlangMode() && id == types::TY_PP_Fortran)
1055 id = types::TY_Fortran;
1056
1057 return id;
1058}
1059
1061 return false;
1062}
1063
1065 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
1066 switch (HostTriple.getArch()) {
1067
1068
1069 case llvm::Triple::arm:
1070 case llvm::Triple::armeb:
1071 case llvm::Triple::thumb:
1072 case llvm::Triple::thumbeb:
1073 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
1074 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
1075 default:
1076 return HostTriple.getArch() != getArch();
1077 }
1078}
1079
1082 VersionTuple());
1083}
1084
1085llvm::ExceptionHandling
1087 return llvm::ExceptionHandling::None;
1088}
1089
1091 if (Model == "single") {
1092
1093 return Triple.getArch() == llvm::Triple::arm ||
1094 Triple.getArch() == llvm::Triple::armeb ||
1095 Triple.getArch() == llvm::Triple::thumb ||
1096 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
1097 } else if (Model == "posix")
1098 return true;
1099
1100 return false;
1101}
1102
1106 default:
1108
1109 case llvm::Triple::x86_64: {
1110 llvm::Triple Triple = getTriple();
1111 if (!Triple.isOSBinFormatMachO())
1113
1114 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1115
1116
1117 StringRef MArch = A->getValue();
1118 if (MArch == "x86_64h")
1119 Triple.setArchName(MArch);
1120 }
1121 return Triple.getTriple();
1122 }
1123 case llvm::Triple::aarch64: {
1124 llvm::Triple Triple = getTriple();
1126 if (!Triple.isOSBinFormatMachO())
1127 return Triple.getTriple();
1128
1129 if (Triple.isArm64e())
1130 return Triple.getTriple();
1131
1132
1133
1134
1135 Triple.setArchName("arm64");
1136 return Triple.getTriple();
1137 }
1138 case llvm::Triple::aarch64_32:
1140 case llvm::Triple::amdgcn: {
1141 llvm::Triple Triple = getTriple();
1142 if (Args.getLastArgValue(options::OPT_mcpu_EQ) == "amdgcnspirv")
1143 Triple.setArch(llvm::Triple::ArchType::spirv64);
1144 return Triple.getTriple();
1145 }
1146 case llvm::Triple::arm:
1147 case llvm::Triple::armeb:
1148 case llvm::Triple::thumb:
1149 case llvm::Triple::thumbeb: {
1150 llvm::Triple Triple = getTriple();
1153 return Triple.getTriple();
1154 }
1155 }
1156}
1157
1161}
1162
1165}
1166
1168 ArgStringList &CC1Args) const {
1169
1170}
1171
1173 const ArgList &DriverArgs, ArgStringList &CC1Args,
1175
1177 ArgStringList &CC1ASArgs) const {}
1178
1180
1182 llvm::opt::ArgStringList &CmdArgs) const {
1184 return;
1185
1187}
1188
1190 const ArgList &Args) const {
1191 if (runtimeLibType)
1192 return *runtimeLibType;
1193
1194 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
1195 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
1196
1197
1198 if (LibName == "compiler-rt")
1200 else if (LibName == "libgcc")
1202 else if (LibName == "platform")
1204 else {
1205 if (A)
1206 getDriver().Diag(diag::err_drv_invalid_rtlib_name)
1207 << A->getAsString(Args);
1208
1210 }
1211
1212 return *runtimeLibType;
1213}
1214
1216 const ArgList &Args) const {
1217 if (unwindLibType)
1218 return *unwindLibType;
1219
1220 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
1221 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
1222
1223 if (LibName == "none")
1225 else if (LibName == "platform" || LibName == "") {
1230 else
1234 } else if (LibName == "libunwind") {
1236 getDriver().Diag(diag::err_drv_incompatible_unwindlib);
1238 } else if (LibName == "libgcc")
1240 else {
1241 if (A)
1242 getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
1243 << A->getAsString(Args);
1244
1246 }
1247
1248 return *unwindLibType;
1249}
1250
1252 if (cxxStdlibType)
1253 return *cxxStdlibType;
1254
1255 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1256 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
1257
1258
1259 if (LibName == "libc++")
1261 else if (LibName == "libstdc++")
1263 else if (LibName == "platform")
1265 else {
1266 if (A)
1267 getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1268 << A->getAsString(Args);
1269
1271 }
1272
1273 return *cxxStdlibType;
1274}
1275
1276
1278 ArgStringList &CC1Args,
1279 const Twine &Path) {
1280 CC1Args.push_back("-internal-isystem");
1281 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1282}
1283
1284
1285
1286
1287
1288
1289
1290
1291
1293 ArgStringList &CC1Args,
1294 const Twine &Path) {
1295 CC1Args.push_back("-internal-externc-isystem");
1296 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1297}
1298
1300 ArgStringList &CC1Args,
1301 const Twine &Path) {
1302 if (llvm::sys::fs::exists(Path))
1304}
1305
1306
1308 ArgStringList &CC1Args,
1310 for (const auto &Path : Paths) {
1311 CC1Args.push_back("-internal-isystem");
1312 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1313 }
1314}
1315
1317 const Twine &B, const Twine &C,
1318 const Twine &D) {
1320 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D);
1321 return std::string(Result);
1322}
1323
1325 std::error_code EC;
1326 int MaxVersion = 0;
1327 std::string MaxVersionString;
1329 llvm::sys::path::append(Path, "c++");
1330 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
1331 !EC && LI != LE; LI = LI.increment(EC)) {
1332 StringRef VersionText = llvm::sys::path::filename(LI->path());
1333 int Version;
1334 if (VersionText[0] == 'v' &&
1335 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
1336 if (Version > MaxVersion) {
1337 MaxVersion = Version;
1338 MaxVersionString = std::string(VersionText);
1339 }
1340 }
1341 }
1342 if (!MaxVersion)
1343 return "";
1344 return MaxVersionString;
1345}
1346
1348 ArgStringList &CC1Args) const {
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1359}
1360
1362 const llvm::opt::ArgList &DriverArgs,
1363 llvm::opt::ArgStringList &CC1Args) const {
1364 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1365
1366
1367
1368
1369
1370
1371
1372
1373 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1374 for (const auto &P :
1375 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1377}
1378
1381 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1382 options::OPT_nostdlibxx);
1383}
1384
1386 ArgStringList &CmdArgs) const {
1387 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1388 "should not have called this");
1390
1391 switch (Type) {
1393 CmdArgs.push_back("-lc++");
1394 if (Args.hasArg(options::OPT_fexperimental_library))
1395 CmdArgs.push_back("-lc++experimental");
1396 break;
1397
1399 CmdArgs.push_back("-lstdc++");
1400 break;
1401 }
1402}
1403
1405 ArgStringList &CmdArgs) const {
1407 if(LibPath.length() > 0)
1408 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
1409}
1410
1412 ArgStringList &CmdArgs) const {
1413 CmdArgs.push_back("-lcc_kext");
1414}
1415
1417 std::string &Path) const {
1418
1419
1420
1421 bool Default = !Args.hasArgNoClaim(options::OPT_shared);
1422
1423
1424
1426
1427 Arg *A = Args.getLastArg(
1428 options::OPT_ffast_math, options::OPT_fno_fast_math,
1429 options::OPT_funsafe_math_optimizations,
1430 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ);
1431
1432 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1433 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1435 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
1436 StringRef Model = A->getValue();
1437 if (Model != "fast" && Model != "aggressive")
1439 }
1440 }
1441
1442
1443
1444 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default))
1445 return false;
1446
1447
1449 return (Path != "crtfastmath.o");
1450}
1451
1453 ArgStringList &CmdArgs) const {
1454 std::string Path;
1456 CmdArgs.push_back(Args.MakeArgString(Path));
1457 return true;
1458 }
1459
1460 return false;
1461}
1462
1466}
1467
1469
1470
1471
1474 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1475 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1476 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1477 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1478 SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1479 if (getTriple().getArch() == llvm::Triple::x86 ||
1480 getTriple().getArch() == llvm::Triple::x86_64 ||
1481 getTriple().getArch() == llvm::Triple::arm ||
1482 getTriple().getArch() == llvm::Triple::thumb || getTriple().isWasm() ||
1485 Res |= SanitizerKind::CFIICall;
1486 if (getTriple().getArch() == llvm::Triple::x86_64 ||
1488 Res |= SanitizerKind::ShadowCallStack;
1490 Res |= SanitizerKind::MemTag;
1491 return Res;
1492}
1493
1495 ArgStringList &CC1Args) const {}
1496
1498 ArgStringList &CC1Args) const {}
1499
1501 ArgStringList &CC1Args) const {}
1502
1505 return {};
1506}
1507
1509 ArgStringList &CC1Args) const {}
1510
1512 if (Version < 100)
1513 return VersionTuple(Version);
1514
1515 if (Version < 10000)
1516 return VersionTuple(Version / 100, Version % 100);
1517
1518 unsigned Build = 0, Factor = 1;
1519 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1520 Build = Build + (Version % 10) * Factor;
1521 return VersionTuple(Version / 100, Version % 100, Build);
1522}
1523
1524VersionTuple
1526 const llvm::opt::ArgList &Args) const {
1527 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1528 const Arg *MSCompatibilityVersion =
1529 Args.getLastArg(options::OPT_fms_compatibility_version);
1530
1531 if (MSCVersion && MSCompatibilityVersion) {
1532 if (D)
1533 D->Diag(diag::err_drv_argument_not_allowed_with)
1534 << MSCVersion->getAsString(Args)
1535 << MSCompatibilityVersion->getAsString(Args);
1536 return VersionTuple();
1537 }
1538
1539 if (MSCompatibilityVersion) {
1540 VersionTuple MSVT;
1541 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1542 if (D)
1543 D->Diag(diag::err_drv_invalid_value)
1544 << MSCompatibilityVersion->getAsString(Args)
1545 << MSCompatibilityVersion->getValue();
1546 } else {
1547 return MSVT;
1548 }
1549 }
1550
1551 if (MSCVersion) {
1552 unsigned Version = 0;
1553 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1554 if (D)
1555 D->Diag(diag::err_drv_invalid_value)
1556 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1557 } else {
1559 }
1560 }
1561
1562 return VersionTuple();
1563}
1564
1566 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
1568 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1570 bool Modified = false;
1571
1572
1573 for (auto *A : Args) {
1574
1575
1576
1577
1578 if (A->getOption().matches(options::OPT_m_Group)) {
1579
1580
1581 if (SameTripleAsHost ||
1582 A->getOption().matches(options::OPT_mcode_object_version_EQ))
1583 DAL->append(A);
1584 else
1585 Modified = true;
1586 continue;
1587 }
1588
1589 unsigned Index;
1590 unsigned Prev;
1591 bool XOpenMPTargetNoTriple =
1592 A->getOption().matches(options::OPT_Xopenmp_target);
1593
1594 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1596
1597
1599 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1600 else
1601 continue;
1602 } else if (XOpenMPTargetNoTriple) {
1603
1604 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1605 } else {
1606 DAL->append(A);
1607 continue;
1608 }
1609
1610
1611 Prev = Index;
1612 std::unique_ptr XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1613 if (!XOpenMPTargetArg || Index > Prev + 1) {
1614 if (!A->isClaimed()) {
1615 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1616 << A->getAsString(Args);
1617 }
1618 continue;
1619 }
1620 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1621 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
1622 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
1623 continue;
1624 }
1625 XOpenMPTargetArg->setBaseArg(A);
1626 A = XOpenMPTargetArg.release();
1627 AllocatedArgs.push_back(A);
1628 DAL->append(A);
1629 Modified = true;
1630 }
1631
1632 if (Modified)
1633 return DAL;
1634
1635 delete DAL;
1636 return nullptr;
1637}
1638
1639
1640
1641
1643 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1644 llvm::opt::DerivedArgList *DAL,
1647 unsigned ValuePos = 1;
1648 if (A->getOption().matches(options::OPT_Xarch_device) ||
1649 A->getOption().matches(options::OPT_Xarch_host))
1650 ValuePos = 0;
1651
1652 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
1653 unsigned Prev = Index;
1654 std::unique_ptrllvm::opt::Arg XarchArg(Opts.ParseOneArg(Args, Index));
1655
1656
1657
1658
1659
1660
1661
1662
1663 if (!XarchArg || Index > Prev + 1) {
1664 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1665 << A->getAsString(Args);
1666 return;
1669 unsigned DiagID =
1671 "invalid Xarch argument: '%0', not all driver "
1672 "options can be forwared via Xarch argument");
1673 Diags.Report(DiagID) << A->getAsString(Args);
1674 return;
1675 }
1676 XarchArg->setBaseArg(A);
1677 A = XarchArg.release();
1678 if (!AllocatedArgs)
1679 DAL->AddSynthesizedArg(A);
1680 else
1681 AllocatedArgs->push_back(A);
1682}
1683
1685 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1688 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1689 bool Modified = false;
1690
1692 for (Arg *A : Args) {
1693 bool NeedTrans = false;
1694 bool Skip = false;
1695 if (A->getOption().matches(options::OPT_Xarch_device)) {
1696 NeedTrans = IsDevice;
1697 Skip = !IsDevice;
1698 } else if (A->getOption().matches(options::OPT_Xarch_host)) {
1699 NeedTrans = !IsDevice;
1700 Skip = IsDevice;
1701 } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) {
1702
1703
1704
1705 if (BoundArch.empty() || A->getValue(0) != BoundArch)
1706 Skip = true;
1707 else
1708 NeedTrans = true;
1709 }
1710 if (NeedTrans || Skip)
1711 Modified = true;
1712 if (NeedTrans)
1715 DAL->append(A);
1716 }
1717
1718 if (Modified)
1719 return DAL;
1720
1721 delete DAL;
1722 return nullptr;
1723}
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.
InputInfo - Wrapper for information about an input source.
const char * getFilename() const
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...