1 //===- ToolChain.cpp - Collections of tools for one platform --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/Driver/ToolChain.h"
10 #include "ToolChains/Arch/AArch64.h"
11 #include "ToolChains/Arch/ARM.h"
12 #include "ToolChains/Clang.h"
13 #include "ToolChains/CommonArgs.h"
14 #include "ToolChains/Flang.h"
15 #include "ToolChains/InterfaceStubs.h"
16 #include "clang/Basic/ObjCRuntime.h"
17 #include "clang/Basic/Sanitizers.h"
18 #include "clang/Config/config.h"
19 #include "clang/Driver/Action.h"
20 #include "clang/Driver/Driver.h"
21 #include "clang/Driver/DriverDiagnostic.h"
22 #include "clang/Driver/InputInfo.h"
23 #include "clang/Driver/Job.h"
24 #include "clang/Driver/Options.h"
25 #include "clang/Driver/SanitizerArgs.h"
26 #include "clang/Driver/XRayArgs.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"
53 using namespace clang
;
54 using namespace driver
;
55 using namespace tools
;
57 using namespace llvm::opt
;
59 static llvm::opt::Arg
*GetRTTIArgument(const ArgList
&Args
) {
60 return Args
.getLastArg(options::OPT_mkernel
, options::OPT_fapple_kext
,
61 options::OPT_fno_rtti
, options::OPT_frtti
);
64 static ToolChain::RTTIMode
CalculateRTTIMode(const ArgList
&Args
,
65 const llvm::Triple
&Triple
,
66 const Arg
*CachedRTTIArg
) {
67 // Explicit rtti/no-rtti args
69 if (CachedRTTIArg
->getOption().matches(options::OPT_frtti
))
70 return ToolChain::RM_Enabled
;
72 return ToolChain::RM_Disabled
;
75 // -frtti is default, except for the PS4/PS5 and DriverKit.
76 bool NoRTTI
= Triple
.isPS() || Triple
.isDriverKit();
77 return NoRTTI
? ToolChain::RM_Disabled
: ToolChain::RM_Enabled
;
80 ToolChain::ToolChain(const Driver
&D
, const llvm::Triple
&T
,
82 : D(D
), Triple(T
), Args(Args
), CachedRTTIArg(GetRTTIArgument(Args
)),
83 CachedRTTIMode(CalculateRTTIMode(Args
, Triple
, CachedRTTIArg
)) {
84 auto addIfExists
= [this](path_list
&List
, const std::string
&Path
) {
85 if (getVFS().exists(Path
))
89 if (std::optional
<std::string
> Path
= getRuntimePath())
90 getLibraryPaths().push_back(*Path
);
91 if (std::optional
<std::string
> Path
= getStdlibPath())
92 getFilePaths().push_back(*Path
);
93 for (const auto &Path
: getArchSpecificLibPaths())
94 addIfExists(getFilePaths(), Path
);
97 llvm::Expected
<std::unique_ptr
<llvm::MemoryBuffer
>>
98 ToolChain::executeToolChainProgram(StringRef Executable
) const {
99 llvm::SmallString
<64> OutputFile
;
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
,
110 /* SecondsToWait */ 0,
111 /*MemoryLimit*/ 0, &ErrorMessage
))
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
);
124 void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env
) {
125 Triple
.setEnvironment(Env
);
126 if (EffectiveTriple
!= llvm::Triple())
127 EffectiveTriple
.setEnvironment(Env
);
130 ToolChain::~ToolChain() = default;
132 llvm::vfs::FileSystem
&ToolChain::getVFS() const {
133 return getDriver().getVFS();
136 bool ToolChain::useIntegratedAs() const {
137 return Args
.hasFlag(options::OPT_fintegrated_as
,
138 options::OPT_fno_integrated_as
,
139 IsIntegratedAssemblerDefault());
142 bool ToolChain::useIntegratedBackend() const {
144 ((IsIntegratedBackendDefault() && IsIntegratedBackendSupported()) ||
145 (!IsIntegratedBackendDefault() || IsNonIntegratedBackendSupported())) &&
146 "(Non-)integrated backend set incorrectly!");
148 bool IBackend
= Args
.hasFlag(options::OPT_fintegrated_objemitter
,
149 options::OPT_fno_integrated_objemitter
,
150 IsIntegratedBackendDefault());
152 // Diagnose when integrated-objemitter options are not supported by this
155 if ((IBackend
&& !IsIntegratedBackendSupported()) ||
156 (!IBackend
&& !IsNonIntegratedBackendSupported()))
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
);
161 if (A
&& !IsNonIntegratedBackendSupported())
162 D
.Diag(DiagID
) << A
->getAsString(Args
) << Triple
.getTriple();
163 A
= Args
.getLastArg(options::OPT_fintegrated_objemitter
);
164 if (A
&& !IsIntegratedBackendSupported())
165 D
.Diag(DiagID
) << A
->getAsString(Args
) << Triple
.getTriple();
170 bool ToolChain::useRelaxRelocations() const {
171 return ENABLE_X86_RELAX_RELOCATIONS
;
174 bool ToolChain::defaultToIEEELongDouble() const {
175 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE
&& getTriple().isOSLinux();
178 static void getAArch64MultilibFlags(const Driver
&D
,
179 const llvm::Triple
&Triple
,
180 const llvm::opt::ArgList
&Args
,
181 Multilib::flags_list
&Result
) {
182 std::vector
<StringRef
> Features
;
183 tools::aarch64::getAArch64TargetFeatures(D
, Triple
, Args
, Features
, false);
184 const auto UnifiedFeatures
= tools::unifyTargetFeatures(Features
);
185 llvm::DenseSet
<StringRef
> FeatureSet(UnifiedFeatures
.begin(),
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
, "+"));
198 static void getARMMultilibFlags(const Driver
&D
,
199 const llvm::Triple
&Triple
,
200 const llvm::opt::ArgList
&Args
,
201 Multilib::flags_list
&Result
) {
202 std::vector
<StringRef
> Features
;
203 llvm::ARM::FPUKind FPUKind
= tools::arm::getARMTargetFeatures(
204 D
, Triple
, Args
, Features
, false /*ForAs*/, true /*ForMultilib*/);
205 const auto UnifiedFeatures
= tools::unifyTargetFeatures(Features
);
206 llvm::DenseSet
<StringRef
> FeatureSet(UnifiedFeatures
.begin(),
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");
228 switch (arm::getARMFloatABI(D
, Triple
, Args
)) {
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");
244 ToolChain::getMultilibFlags(const llvm::opt::ArgList
&Args
) const {
245 using namespace clang::driver::options
;
247 std::vector
<std::string
> Result
;
248 const llvm::Triple
Triple(ComputeEffectiveClangTriple(Args
));
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
:
255 getAArch64MultilibFlags(D
, Triple
, Args
, Result
);
257 case llvm::Triple::arm
:
258 case llvm::Triple::armeb
:
259 case llvm::Triple::thumb
:
260 case llvm::Triple::thumbeb
:
261 getARMMultilibFlags(D
, Triple
, Args
, Result
);
267 // Sort and remove duplicates.
268 std::sort(Result
.begin(), Result
.end());
269 Result
.erase(std::unique(Result
.begin(), Result
.end()), Result
.end());
274 ToolChain::getSanitizerArgs(const llvm::opt::ArgList
&JobArgs
) const {
275 SanitizerArgs
SanArgs(*this, JobArgs
, !SanitizerArgsChecked
);
276 SanitizerArgsChecked
= true;
280 const XRayArgs
& ToolChain::getXRayArgs() const {
282 XRayArguments
.reset(new XRayArgs(*this, Args
));
283 return *XRayArguments
;
288 struct DriverSuffix
{
290 const char *ModeFlag
;
295 static const DriverSuffix
*FindDriverSuffix(StringRef ProgName
, size_t &Pos
) {
296 // A list of known driver suffixes. Suffixes are compared against the
297 // program name in order. If there is a match, the frontend type is updated as
298 // necessary by applying the 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();
326 /// Normalize the program name from argv[0] by stripping the file extension if
327 /// present and lower-casing the string on Windows.
328 static std::string
normalizeProgramName(llvm::StringRef Argv0
) {
329 std::string ProgName
= std::string(llvm::sys::path::filename(Argv0
));
330 if (is_style_windows(llvm::sys::path::Style::native
)) {
331 // Transform to lowercase for case insensitive file systems.
332 std::transform(ProgName
.begin(), ProgName
.end(), ProgName
.begin(),
338 static const DriverSuffix
*parseDriverSuffix(StringRef ProgName
, size_t &Pos
) {
339 // Try to infer frontend type and default target from the program name by
340 // comparing it against DriverSuffixes in order.
342 // If there is a match, the function tries to identify a target as prefix.
343 // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
344 // prefix "x86_64-linux". If such a target prefix is found, it may be
345 // added via -target as implicit first argument.
346 const DriverSuffix
*DS
= FindDriverSuffix(ProgName
, Pos
);
348 if (!DS
&& ProgName
.endswith(".exe")) {
349 // Try again after stripping the executable suffix:
350 // clang++.exe -> clang++
351 ProgName
= ProgName
.drop_back(StringRef(".exe").size());
352 DS
= FindDriverSuffix(ProgName
, Pos
);
356 // Try again after stripping any trailing version number:
357 // clang++3.5 -> clang++
358 ProgName
= ProgName
.rtrim("0123456789.");
359 DS
= FindDriverSuffix(ProgName
, Pos
);
363 // Try again after stripping trailing -component.
364 // clang++-tot -> clang++
365 ProgName
= ProgName
.slice(0, ProgName
.rfind('-'));
366 DS
= FindDriverSuffix(ProgName
, Pos
);
372 ToolChain::getTargetAndModeFromProgramName(StringRef PN
) {
373 std::string ProgName
= normalizeProgramName(PN
);
375 const DriverSuffix
*DS
= parseDriverSuffix(ProgName
, SuffixPos
);
378 size_t SuffixEnd
= SuffixPos
+ strlen(DS
->Suffix
);
380 size_t LastComponent
= ProgName
.rfind('-', SuffixPos
);
381 if (LastComponent
== std::string::npos
)
382 return ParsedClangName(ProgName
.substr(0, SuffixEnd
), DS
->ModeFlag
);
383 std::string ModeSuffix
= ProgName
.substr(LastComponent
+ 1,
384 SuffixEnd
- LastComponent
- 1);
386 // Infer target from the prefix.
387 StringRef
Prefix(ProgName
);
388 Prefix
= Prefix
.slice(0, LastComponent
);
389 std::string IgnoredError
;
391 llvm::TargetRegistry::lookupTarget(std::string(Prefix
), IgnoredError
);
392 return ParsedClangName
{std::string(Prefix
), ModeSuffix
, DS
->ModeFlag
,
396 StringRef
ToolChain::getDefaultUniversalArchName() const {
397 // In universal driver terms, the arch name accepted by -arch isn't exactly
398 // the same as the ones that appear in the triple. Roughly speaking, this is
399 // an inverse of the darwin::getArchTypeForDarwinArchName() function.
400 switch (Triple
.getArch()) {
401 case llvm::Triple::aarch64
: {
402 if (getTriple().isArm64e())
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();
421 std::string
ToolChain::getInputFilename(const InputInfo
&Input
) const {
422 return Input
.getFilename();
425 ToolChain::UnwindTableLevel
426 ToolChain::getDefaultUnwindTableLevel(const ArgList
&Args
) const {
427 return UnwindTableLevel::None
;
430 unsigned ToolChain::GetDefaultDwarfVersion() const {
431 // TODO: Remove the RISC-V special case when R_RISCV_SET_ULEB128 linker
432 // support becomes more widely available.
433 return getTriple().isRISCV() ? 4 : 5;
436 Tool
*ToolChain::getClang() const {
438 Clang
.reset(new tools::Clang(*this, useIntegratedBackend()));
442 Tool
*ToolChain::getFlang() const {
444 Flang
.reset(new tools::Flang(*this));
448 Tool
*ToolChain::buildAssembler() const {
449 return new tools::ClangAs(*this);
452 Tool
*ToolChain::buildLinker() const {
453 llvm_unreachable("Linking is not supported by this toolchain");
456 Tool
*ToolChain::buildStaticLibTool() const {
457 llvm_unreachable("Creating static lib is not supported by this toolchain");
460 Tool
*ToolChain::getAssemble() const {
462 Assemble
.reset(buildAssembler());
463 return Assemble
.get();
466 Tool
*ToolChain::getClangAs() const {
468 Assemble
.reset(new tools::ClangAs(*this));
469 return Assemble
.get();
472 Tool
*ToolChain::getLink() const {
474 Link
.reset(buildLinker());
478 Tool
*ToolChain::getStaticLibTool() const {
480 StaticLibTool
.reset(buildStaticLibTool());
481 return StaticLibTool
.get();
484 Tool
*ToolChain::getIfsMerge() const {
486 IfsMerge
.reset(new tools::ifstool::Merger(*this));
487 return IfsMerge
.get();
490 Tool
*ToolChain::getOffloadBundler() const {
492 OffloadBundler
.reset(new tools::OffloadBundler(*this));
493 return OffloadBundler
.get();
496 Tool
*ToolChain::getOffloadPackager() const {
497 if (!OffloadPackager
)
498 OffloadPackager
.reset(new tools::OffloadPackager(*this));
499 return OffloadPackager
.get();
502 Tool
*ToolChain::getLinkerWrapper() const {
504 LinkerWrapper
.reset(new tools::LinkerWrapper(*this, getLink()));
505 return LinkerWrapper
.get();
508 Tool
*ToolChain::getTool(Action::ActionClass AC
) const {
510 case Action::AssembleJobClass
:
511 return getAssemble();
513 case Action::IfsMergeJobClass
:
514 return getIfsMerge();
516 case Action::LinkJobClass
:
519 case Action::StaticLibJobClass
:
520 return getStaticLibTool();
522 case Action::InputClass
:
523 case Action::BindArchClass
:
524 case Action::OffloadClass
:
525 case Action::LipoJobClass
:
526 case Action::DsymutilJobClass
:
527 case Action::VerifyDebugInfoJobClass
:
528 case Action::BinaryAnalyzeJobClass
:
529 llvm_unreachable("Invalid tool kind.");
531 case Action::CompileJobClass
:
532 case Action::PrecompileJobClass
:
533 case Action::PreprocessJobClass
:
534 case Action::ExtractAPIJobClass
:
535 case Action::AnalyzeJobClass
:
536 case Action::MigrateJobClass
:
537 case Action::VerifyPCHJobClass
:
538 case Action::BackendJobClass
:
541 case Action::OffloadBundlingJobClass
:
542 case Action::OffloadUnbundlingJobClass
:
543 return getOffloadBundler();
545 case Action::OffloadPackagerJobClass
:
546 return getOffloadPackager();
547 case Action::LinkerWrapperJobClass
:
548 return getLinkerWrapper();
551 llvm_unreachable("Invalid tool kind.");
554 static StringRef
getArchNameForCompilerRTLib(const ToolChain
&TC
,
555 const ArgList
&Args
) {
556 const llvm::Triple
&Triple
= TC
.getTriple();
557 bool IsWindows
= Triple
.isOSWindows();
559 if (TC
.isBareMetal())
560 return Triple
.getArchName();
562 if (TC
.getArch() == llvm::Triple::arm
|| TC
.getArch() == llvm::Triple::armeb
)
563 return (arm::getARMFloatABI(TC
, Args
) == arm::FloatABI::Hard
&& !IsWindows
)
567 // For historic reasons, Android library is using i686 instead of i386.
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());
577 StringRef
ToolChain::getOSLibName() const {
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
:
597 std::string
ToolChain::getCompilerRTPath() const {
598 SmallString
<128> Path(getDriver().ResourceDir
);
600 llvm::sys::path::append(Path
, "lib", getOSLibName());
601 if (!SelectedMultilibs
.empty()) {
602 Path
+= SelectedMultilibs
.back().gccSuffix();
604 } else if (Triple
.isOSUnknown()) {
605 llvm::sys::path::append(Path
, "lib");
607 llvm::sys::path::append(Path
, "lib", getOSLibName());
609 return std::string(Path
.str());
612 std::string
ToolChain::getCompilerRTBasename(const ArgList
&Args
,
614 FileType Type
) const {
615 std::string CRTAbsolutePath
= getCompilerRT(Args
, Component
, Type
);
616 return llvm::sys::path::filename(CRTAbsolutePath
).str();
619 std::string
ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList
&Args
,
622 bool AddArch
) const {
623 const llvm::Triple
&TT
= getTriple();
624 bool IsITANMSVCWindows
=
625 TT
.isWindowsMSVCEnvironment() || TT
.isWindowsItaniumEnvironment();
628 IsITANMSVCWindows
|| Type
== ToolChain::FT_Object
? "" : "lib";
631 case ToolChain::FT_Object
:
632 Suffix
= IsITANMSVCWindows
? ".obj" : ".o";
634 case ToolChain::FT_Static
:
635 Suffix
= IsITANMSVCWindows
? ".lib" : ".a";
637 case ToolChain::FT_Shared
:
638 Suffix
= TT
.isOSWindows()
639 ? (TT
.isWindowsGNUEnvironment() ? ".dll.a" : ".lib")
644 std::string ArchAndEnv
;
646 StringRef Arch
= getArchNameForCompilerRTLib(*this, Args
);
647 const char *Env
= TT
.isAndroid() ? "-android" : "";
648 ArchAndEnv
= ("-" + Arch
+ Env
).str();
650 return (Prefix
+ Twine("clang_rt.") + Component
+ ArchAndEnv
+ Suffix
).str();
653 std::string
ToolChain::getCompilerRT(const ArgList
&Args
, StringRef Component
,
654 FileType Type
) const {
655 // Check for runtime files in the new layout without the architecture first.
656 std::string CRTBasename
=
657 buildCompilerRTBasename(Args
, Component
, Type
, /*AddArch=*/false);
658 for (const auto &LibPath
: getLibraryPaths()) {
659 SmallString
<128> P(LibPath
);
660 llvm::sys::path::append(P
, CRTBasename
);
661 if (getVFS().exists(P
))
662 return std::string(P
.str());
665 // Fall back to the old expected compiler-rt name if the new one does not
668 buildCompilerRTBasename(Args
, Component
, Type
, /*AddArch=*/true);
669 SmallString
<128> Path(getCompilerRTPath());
670 llvm::sys::path::append(Path
, CRTBasename
);
671 return std::string(Path
.str());
674 const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList
&Args
,
676 FileType Type
) const {
677 return Args
.MakeArgString(getCompilerRT(Args
, Component
, Type
));
680 // Android target triples contain a target version. If we don't have libraries
681 // for the exact target version, we should fall back to the next newest version
682 // or a versionless path, if any.
683 std::optional
<std::string
>
684 ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir
) const {
685 llvm::Triple
TripleWithoutLevel(getTriple());
686 TripleWithoutLevel
.setEnvironmentName("android"); // remove any version number
687 const std::string
&TripleWithoutLevelStr
= TripleWithoutLevel
.str();
688 unsigned TripleVersion
= getTriple().getEnvironmentVersion().getMajor();
689 unsigned BestVersion
= 0;
691 SmallString
<32> TripleDir
;
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())
717 SmallString
<128> P(BaseDir
);
718 llvm::sys::path::append(P
, TripleDir
);
719 if (UsingUnversionedDir
)
720 D
.Diag(diag::warn_android_unversioned_fallback
) << P
<< getTripleString();
721 return std::string(P
);
724 std::optional
<std::string
>
725 ToolChain::getTargetSubDirPath(StringRef BaseDir
) const {
726 auto getPathForTriple
=
727 [&](const llvm::Triple
&Triple
) -> std::optional
<std::string
> {
728 SmallString
<128> P(BaseDir
);
729 llvm::sys::path::append(P
, Triple
.str());
730 if (getVFS().exists(P
))
731 return std::string(P
);
735 if (auto Path
= getPathForTriple(getTriple()))
738 // When building with per target runtime directories, various ways of naming
739 // the Arm architecture may have been normalised to simply "arm".
740 // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
741 // Since an armv8l system can use libraries built for earlier architecture
742 // versions assuming endian and float ABI match.
744 // Original triple: armv8l-unknown-linux-gnueabihf
745 // Runtime triple: arm-unknown-linux-gnueabihf
747 // We do not do this for armeb (big endian) because doing so could make us
748 // select little endian libraries. In addition, all known armeb triples only
749 // use the "armeb" architecture name.
751 // M profile Arm is bare metal and we know they will not be using the per
752 // target runtime directory layout.
753 if (getTriple().getArch() == Triple::arm
&& !getTriple().isArmMClass()) {
754 llvm::Triple ArmTriple
= getTriple();
755 ArmTriple
.setArch(Triple::arm
);
756 if (auto Path
= getPathForTriple(ArmTriple
))
760 if (getTriple().isAndroid())
761 return getFallbackAndroidTargetPath(BaseDir
);
766 std::optional
<std::string
> ToolChain::getRuntimePath() const {
767 SmallString
<128> P(D
.ResourceDir
);
768 llvm::sys::path::append(P
, "lib");
769 return getTargetSubDirPath(P
);
772 std::optional
<std::string
> ToolChain::getStdlibPath() const {
773 SmallString
<128> P(D
.Dir
);
774 llvm::sys::path::append(P
, "..", "lib");
775 return getTargetSubDirPath(P
);
778 ToolChain::path_list
ToolChain::getArchSpecificLibPaths() const {
781 auto AddPath
= [&](const ArrayRef
<StringRef
> &SS
) {
782 SmallString
<128> Path(getDriver().ResourceDir
);
783 llvm::sys::path::append(Path
, "lib");
785 llvm::sys::path::append(Path
, S
);
786 Paths
.push_back(std::string(Path
.str()));
789 AddPath({getTriple().str()});
790 AddPath({getOSLibName(), llvm::Triple::getArchTypeName(getArch())});
794 bool ToolChain::needsProfileRT(const ArgList
&Args
) {
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
);
808 bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList
&Args
) {
809 return Args
.hasArg(options::OPT_coverage
) ||
810 Args
.hasFlag(options::OPT_fprofile_arcs
, options::OPT_fno_profile_arcs
,
814 Tool
*ToolChain::SelectTool(const JobAction
&JA
) const {
815 if (D
.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA
)) return getFlang();
816 if (getDriver().ShouldUseClangCompiler(JA
)) return getClang();
817 Action::ActionClass AC
= JA
.getKind();
818 if (AC
== Action::AssembleJobClass
&& useIntegratedAs() &&
819 !getTriple().isOSAIX())
824 std::string
ToolChain::GetFilePath(const char *Name
) const {
825 return D
.GetFilePath(Name
, *this);
828 std::string
ToolChain::GetProgramPath(const char *Name
) const {
829 return D
.GetProgramPath(Name
, *this);
832 std::string
ToolChain::GetLinkerPath(bool *LinkerIsLLD
) const {
834 *LinkerIsLLD
= false;
836 // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is
837 // considered as the linker flavor, e.g. "bfd", "gold", or "lld".
838 const Arg
* A
= Args
.getLastArg(options::OPT_fuse_ld_EQ
);
839 StringRef UseLinker
= A
? A
->getValue() : CLANG_DEFAULT_LINKER
;
841 // --ld-path= takes precedence over -fuse-ld= and specifies the executable
842 // name. -B, COMPILER_PATH and PATH and consulted if the value does not
843 // contain a path component separator.
844 // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary
845 // that --ld-path= points to is lld.
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())
850 Path
= GetProgramPath(A
->getValue());
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
);
858 return GetProgramPath(getDefaultLinker());
860 // If we're passed -fuse-ld= with no argument, or with the argument ld,
861 // then use whatever the default system linker is.
862 if (UseLinker
.empty() || UseLinker
== "ld") {
863 const char *DefaultLinker
= getDefaultLinker();
864 if (llvm::sys::path::is_absolute(DefaultLinker
))
865 return std::string(DefaultLinker
);
867 return GetProgramPath(DefaultLinker
);
870 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
871 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
872 // to a relative path is surprising. This is more complex due to priorities
873 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
874 if (UseLinker
.contains('/'))
875 getDriver().Diag(diag::warn_drv_fuse_ld_path
);
877 if (llvm::sys::path::is_absolute(UseLinker
)) {
878 // If we're passed what looks like an absolute path, don't attempt to
879 // second-guess that.
880 if (llvm::sys::fs::can_execute(UseLinker
))
881 return std::string(UseLinker
);
883 llvm::SmallString
<8> LinkerName
;
884 if (Triple
.isOSDarwin())
885 LinkerName
.append("ld64.");
887 LinkerName
.append("ld.");
888 LinkerName
.append(UseLinker
);
890 std::string
LinkerPath(GetProgramPath(LinkerName
.c_str()));
891 if (llvm::sys::fs::can_execute(LinkerPath
)) {
893 *LinkerIsLLD
= UseLinker
== "lld";
899 getDriver().Diag(diag::err_drv_invalid_linker_name
) << A
->getAsString(Args
);
901 return GetProgramPath(getDefaultLinker());
904 std::string
ToolChain::GetStaticLibToolPath() const {
905 // TODO: Add support for static lib archiving on Windows
906 if (Triple
.isOSDarwin())
907 return GetProgramPath("libtool");
908 return GetProgramPath("llvm-ar");
911 types::ID
ToolChain::LookupTypeForExtension(StringRef Ext
) const {
912 types::ID id
= types::lookupTypeForExtension(Ext
);
914 // Flang always runs the preprocessor and has no notion of "preprocessed
915 // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
917 if (D
.IsFlangMode() && id
== types::TY_PP_Fortran
)
918 id
= types::TY_Fortran
;
923 bool ToolChain::HasNativeLLVMSupport() const {
927 bool ToolChain::isCrossCompiling() const {
928 llvm::Triple
HostTriple(LLVM_HOST_TRIPLE
);
929 switch (HostTriple
.getArch()) {
930 // The A32/T32/T16 instruction sets are not separate architectures in this
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();
943 ObjCRuntime
ToolChain::getDefaultObjCRuntime(bool isNonFragile
) const {
944 return ObjCRuntime(isNonFragile
? ObjCRuntime::GNUstep
: ObjCRuntime::GCC
,
948 llvm::ExceptionHandling
949 ToolChain::GetExceptionModel(const llvm::opt::ArgList
&Args
) const {
950 return llvm::ExceptionHandling::None
;
953 bool ToolChain::isThreadModelSupported(const StringRef Model
) const {
954 if (Model
== "single") {
955 // FIXME: 'single' is only supported on ARM and WebAssembly so far.
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")
966 std::string
ToolChain::ComputeLLVMTriple(const ArgList
&Args
,
967 types::ID InputType
) const {
968 switch (getTriple().getArch()) {
970 return getTripleString();
972 case llvm::Triple::x86_64
: {
973 llvm::Triple Triple
= getTriple();
974 if (!Triple
.isOSBinFormatMachO())
975 return getTripleString();
977 if (Arg
*A
= Args
.getLastArg(options::OPT_march_EQ
)) {
978 // x86_64h goes in the triple. Other -march options just use the
979 // vanilla triple we already have.
980 StringRef MArch
= A
->getValue();
981 if (MArch
== "x86_64h")
982 Triple
.setArchName(MArch
);
984 return Triple
.getTriple();
986 case llvm::Triple::aarch64
: {
987 llvm::Triple Triple
= getTriple();
988 if (!Triple
.isOSBinFormatMachO())
989 return getTripleString();
991 if (Triple
.isArm64e())
992 return getTripleString();
994 // FIXME: older versions of ld64 expect the "arm64" component in the actual
995 // triple string and query it to determine whether an LTO file can be
996 // handled. Remove this when we don't care any more.
997 Triple
.setArchName("arm64");
998 return Triple
.getTriple();
1000 case llvm::Triple::aarch64_32
:
1001 return getTripleString();
1002 case llvm::Triple::arm
:
1003 case llvm::Triple::armeb
:
1004 case llvm::Triple::thumb
:
1005 case llvm::Triple::thumbeb
: {
1006 llvm::Triple Triple
= getTriple();
1007 tools::arm::setArchNameInTriple(getDriver(), Args
, InputType
, Triple
);
1008 tools::arm::setFloatABIInTriple(getDriver(), Args
, Triple
);
1009 return Triple
.getTriple();
1014 std::string
ToolChain::ComputeEffectiveClangTriple(const ArgList
&Args
,
1015 types::ID InputType
) const {
1016 return ComputeLLVMTriple(Args
, InputType
);
1019 std::string
ToolChain::computeSysRoot() const {
1023 void ToolChain::AddClangSystemIncludeArgs(const ArgList
&DriverArgs
,
1024 ArgStringList
&CC1Args
) const {
1025 // Each toolchain should provide the appropriate include flags.
1028 void ToolChain::addClangTargetOptions(
1029 const ArgList
&DriverArgs
, ArgStringList
&CC1Args
,
1030 Action::OffloadKind DeviceOffloadKind
) const {}
1032 void ToolChain::addClangCC1ASTargetOptions(const ArgList
&Args
,
1033 ArgStringList
&CC1ASArgs
) const {}
1035 void ToolChain::addClangWarningOptions(ArgStringList
&CC1Args
) const {}
1037 void ToolChain::addProfileRTLibs(const llvm::opt::ArgList
&Args
,
1038 llvm::opt::ArgStringList
&CmdArgs
) const {
1039 if (!needsProfileRT(Args
) && !needsGCovInstrumentation(Args
))
1042 CmdArgs
.push_back(getCompilerRTArgString(Args
, "profile"));
1045 ToolChain::RuntimeLibType
ToolChain::GetRuntimeLibType(
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
;
1053 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
1054 if (LibName
== "compiler-rt")
1055 runtimeLibType
= ToolChain::RLT_CompilerRT
;
1056 else if (LibName
== "libgcc")
1057 runtimeLibType
= ToolChain::RLT_Libgcc
;
1058 else if (LibName
== "platform")
1059 runtimeLibType
= GetDefaultRuntimeLibType();
1062 getDriver().Diag(diag::err_drv_invalid_rtlib_name
)
1063 << A
->getAsString(Args
);
1065 runtimeLibType
= GetDefaultRuntimeLibType();
1068 return *runtimeLibType
;
1071 ToolChain::UnwindLibType
ToolChain::GetUnwindLibType(
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")
1080 unwindLibType
= ToolChain::UNW_None
;
1081 else if (LibName
== "platform" || LibName
== "") {
1082 ToolChain::RuntimeLibType RtLibType
= GetRuntimeLibType(Args
);
1083 if (RtLibType
== ToolChain::RLT_CompilerRT
) {
1084 if (getTriple().isAndroid() || getTriple().isOSAIX())
1085 unwindLibType
= ToolChain::UNW_CompilerRT
;
1087 unwindLibType
= ToolChain::UNW_None
;
1088 } else if (RtLibType
== ToolChain::RLT_Libgcc
)
1089 unwindLibType
= ToolChain::UNW_Libgcc
;
1090 } else if (LibName
== "libunwind") {
1091 if (GetRuntimeLibType(Args
) == RLT_Libgcc
)
1092 getDriver().Diag(diag::err_drv_incompatible_unwindlib
);
1093 unwindLibType
= ToolChain::UNW_CompilerRT
;
1094 } else if (LibName
== "libgcc")
1095 unwindLibType
= ToolChain::UNW_Libgcc
;
1098 getDriver().Diag(diag::err_drv_invalid_unwindlib_name
)
1099 << A
->getAsString(Args
);
1101 unwindLibType
= GetDefaultUnwindLibType();
1104 return *unwindLibType
;
1107 ToolChain::CXXStdlibType
ToolChain::GetCXXStdlibType(const ArgList
&Args
) const{
1109 return *cxxStdlibType
;
1111 const Arg
*A
= Args
.getLastArg(options::OPT_stdlib_EQ
);
1112 StringRef LibName
= A
? A
->getValue() : CLANG_DEFAULT_CXX_STDLIB
;
1114 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
1115 if (LibName
== "libc++")
1116 cxxStdlibType
= ToolChain::CST_Libcxx
;
1117 else if (LibName
== "libstdc++")
1118 cxxStdlibType
= ToolChain::CST_Libstdcxx
;
1119 else if (LibName
== "platform")
1120 cxxStdlibType
= GetDefaultCXXStdlibType();
1123 getDriver().Diag(diag::err_drv_invalid_stdlib_name
)
1124 << A
->getAsString(Args
);
1126 cxxStdlibType
= GetDefaultCXXStdlibType();
1129 return *cxxStdlibType
;
1132 /// Utility function to add a system include directory to CC1 arguments.
1133 /*static*/ void ToolChain::addSystemInclude(const ArgList
&DriverArgs
,
1134 ArgStringList
&CC1Args
,
1135 const Twine
&Path
) {
1136 CC1Args
.push_back("-internal-isystem");
1137 CC1Args
.push_back(DriverArgs
.MakeArgString(Path
));
1140 /// Utility function to add a system include directory with extern "C"
1141 /// semantics to CC1 arguments.
1143 /// Note that this should be used rarely, and only for directories that
1144 /// historically and for legacy reasons are treated as having implicit extern
1145 /// "C" semantics. These semantics are *ignored* by and large today, but its
1146 /// important to preserve the preprocessor changes resulting from the
1148 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList
&DriverArgs
,
1149 ArgStringList
&CC1Args
,
1150 const Twine
&Path
) {
1151 CC1Args
.push_back("-internal-externc-isystem");
1152 CC1Args
.push_back(DriverArgs
.MakeArgString(Path
));
1155 void ToolChain::addExternCSystemIncludeIfExists(const ArgList
&DriverArgs
,
1156 ArgStringList
&CC1Args
,
1157 const Twine
&Path
) {
1158 if (llvm::sys::fs::exists(Path
))
1159 addExternCSystemInclude(DriverArgs
, CC1Args
, Path
);
1162 /// Utility function to add a list of system include directories to CC1.
1163 /*static*/ void ToolChain::addSystemIncludes(const ArgList
&DriverArgs
,
1164 ArgStringList
&CC1Args
,
1165 ArrayRef
<StringRef
> Paths
) {
1166 for (const auto &Path
: Paths
) {
1167 CC1Args
.push_back("-internal-isystem");
1168 CC1Args
.push_back(DriverArgs
.MakeArgString(Path
));
1172 /*static*/ std::string
ToolChain::concat(StringRef Path
, const Twine
&A
,
1173 const Twine
&B
, const Twine
&C
,
1175 SmallString
<128> Result(Path
);
1176 llvm::sys::path::append(Result
, llvm::sys::path::Style::posix
, A
, B
, C
, D
);
1177 return std::string(Result
);
1180 std::string
ToolChain::detectLibcxxVersion(StringRef IncludePath
) const {
1183 std::string MaxVersionString
;
1184 SmallString
<128> Path(IncludePath
);
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
;
1203 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList
&DriverArgs
,
1204 ArgStringList
&CC1Args
) const {
1205 // Header search paths should be handled by each of the subclasses.
1206 // Historically, they have not been, and instead have been handled inside of
1207 // the CC1-layer frontend. As the logic is hoisted out, this generic function
1208 // will slowly stop being called.
1210 // While it is being called, replicate a bit of a hack to propagate the
1211 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
1212 // header search paths with it. Once all systems are overriding this
1213 // function, the CC1 flag and this line can be removed.
1214 DriverArgs
.AddAllArgs(CC1Args
, options::OPT_stdlib_EQ
);
1217 void ToolChain::AddClangCXXStdlibIsystemArgs(
1218 const llvm::opt::ArgList
&DriverArgs
,
1219 llvm::opt::ArgStringList
&CC1Args
) const {
1220 DriverArgs
.ClaimAllArgs(options::OPT_stdlibxx_isystem
);
1221 // This intentionally only looks at -nostdinc++, and not -nostdinc or
1222 // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain
1223 // setups with non-standard search logic for the C++ headers, while still
1224 // allowing users of the toolchain to bring their own C++ headers. Such a
1225 // toolchain likely also has non-standard search logic for the C headers and
1226 // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should
1227 // still work in that case and only be suppressed by an explicit -nostdinc++
1228 // in a project using the toolchain.
1229 if (!DriverArgs
.hasArg(options::OPT_nostdincxx
))
1230 for (const auto &P
:
1231 DriverArgs
.getAllArgValues(options::OPT_stdlibxx_isystem
))
1232 addSystemInclude(DriverArgs
, CC1Args
, P
);
1235 bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList
&Args
) const {
1236 return getDriver().CCCIsCXX() &&
1237 !Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
,
1238 options::OPT_nostdlibxx
);
1241 void ToolChain::AddCXXStdlibLibArgs(const ArgList
&Args
,
1242 ArgStringList
&CmdArgs
) const {
1243 assert(!Args
.hasArg(options::OPT_nostdlibxx
) &&
1244 "should not have called this");
1245 CXXStdlibType Type
= GetCXXStdlibType(Args
);
1248 case ToolChain::CST_Libcxx
:
1249 CmdArgs
.push_back("-lc++");
1250 if (Args
.hasArg(options::OPT_fexperimental_library
))
1251 CmdArgs
.push_back("-lc++experimental");
1254 case ToolChain::CST_Libstdcxx
:
1255 CmdArgs
.push_back("-lstdc++");
1260 void ToolChain::AddFilePathLibArgs(const ArgList
&Args
,
1261 ArgStringList
&CmdArgs
) const {
1262 for (const auto &LibPath
: getFilePaths())
1263 if(LibPath
.length() > 0)
1264 CmdArgs
.push_back(Args
.MakeArgString(StringRef("-L") + LibPath
));
1267 void ToolChain::AddCCKextLibArgs(const ArgList
&Args
,
1268 ArgStringList
&CmdArgs
) const {
1269 CmdArgs
.push_back("-lcc_kext");
1272 bool ToolChain::isFastMathRuntimeAvailable(const ArgList
&Args
,
1273 std::string
&Path
) const {
1274 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
1275 // (to keep the linker options consistent with gcc and clang itself).
1276 if (!isOptimizationLevelFast(Args
)) {
1277 // Check if -ffast-math or -funsafe-math.
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
)
1287 // If crtfastmath.o exists add it to the arguments.
1288 Path
= GetFilePath("crtfastmath.o");
1289 return (Path
!= "crtfastmath.o"); // Not found.
1292 bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList
&Args
,
1293 ArgStringList
&CmdArgs
) const {
1295 if (isFastMathRuntimeAvailable(Args
, Path
)) {
1296 CmdArgs
.push_back(Args
.MakeArgString(Path
));
1303 Expected
<SmallVector
<std::string
>>
1304 ToolChain::getSystemGPUArchs(const llvm::opt::ArgList
&Args
) const {
1305 return SmallVector
<std::string
>();
1308 SanitizerMask
ToolChain::getSupportedSanitizers() const {
1309 // Return sanitizers which don't require runtime support and are not
1310 // platform dependent.
1313 (SanitizerKind::Undefined
& ~SanitizerKind::Vptr
) |
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
||
1321 getTriple().getArch() == llvm::Triple::arm
|| getTriple().isWasm() ||
1322 getTriple().isAArch64() || getTriple().isRISCV() ||
1323 getTriple().isLoongArch64())
1324 Res
|= SanitizerKind::CFIICall
;
1325 if (getTriple().getArch() == llvm::Triple::x86_64
||
1326 getTriple().isAArch64(64) || getTriple().isRISCV())
1327 Res
|= SanitizerKind::ShadowCallStack
;
1328 if (getTriple().isAArch64(64))
1329 Res
|= SanitizerKind::MemTag
;
1333 void ToolChain::AddCudaIncludeArgs(const ArgList
&DriverArgs
,
1334 ArgStringList
&CC1Args
) const {}
1336 void ToolChain::AddHIPIncludeArgs(const ArgList
&DriverArgs
,
1337 ArgStringList
&CC1Args
) const {}
1339 llvm::SmallVector
<ToolChain::BitCodeLibraryInfo
, 12>
1340 ToolChain::getDeviceLibs(const ArgList
&DriverArgs
) const {
1344 void ToolChain::AddIAMCUIncludeArgs(const ArgList
&DriverArgs
,
1345 ArgStringList
&CC1Args
) const {}
1347 static VersionTuple
separateMSVCFullVersion(unsigned Version
) {
1349 return VersionTuple(Version
);
1351 if (Version
< 10000)
1352 return VersionTuple(Version
/ 100, Version
% 100);
1354 unsigned Build
= 0, Factor
= 1;
1355 for (; Version
> 10000; Version
= Version
/ 10, Factor
= Factor
* 10)
1356 Build
= Build
+ (Version
% 10) * Factor
;
1357 return VersionTuple(Version
/ 100, Version
% 100, Build
);
1361 ToolChain::computeMSVCVersion(const Driver
*D
,
1362 const llvm::opt::ArgList
&Args
) const {
1363 const Arg
*MSCVersion
= Args
.getLastArg(options::OPT_fmsc_version
);
1364 const Arg
*MSCompatibilityVersion
=
1365 Args
.getLastArg(options::OPT_fms_compatibility_version
);
1367 if (MSCVersion
&& MSCompatibilityVersion
) {
1369 D
->Diag(diag::err_drv_argument_not_allowed_with
)
1370 << MSCVersion
->getAsString(Args
)
1371 << MSCompatibilityVersion
->getAsString(Args
);
1372 return VersionTuple();
1375 if (MSCompatibilityVersion
) {
1377 if (MSVT
.tryParse(MSCompatibilityVersion
->getValue())) {
1379 D
->Diag(diag::err_drv_invalid_value
)
1380 << MSCompatibilityVersion
->getAsString(Args
)
1381 << MSCompatibilityVersion
->getValue();
1388 unsigned Version
= 0;
1389 if (StringRef(MSCVersion
->getValue()).getAsInteger(10, Version
)) {
1391 D
->Diag(diag::err_drv_invalid_value
)
1392 << MSCVersion
->getAsString(Args
) << MSCVersion
->getValue();
1394 return separateMSVCFullVersion(Version
);
1398 return VersionTuple();
1401 llvm::opt::DerivedArgList
*ToolChain::TranslateOpenMPTargetArgs(
1402 const llvm::opt::DerivedArgList
&Args
, bool SameTripleAsHost
,
1403 SmallVectorImpl
<llvm::opt::Arg
*> &AllocatedArgs
) const {
1404 DerivedArgList
*DAL
= new DerivedArgList(Args
.getBaseArgs());
1405 const OptTable
&Opts
= getDriver().getOpts();
1406 bool Modified
= false;
1408 // Handle -Xopenmp-target flags
1409 for (auto *A
: Args
) {
1410 // Exclude flags which may only apply to the host toolchain.
1411 // Do not exclude flags when the host triple (AuxTriple)
1412 // matches the current toolchain triple. If it is not present
1413 // at all, target and host share a toolchain.
1414 if (A
->getOption().matches(options::OPT_m_Group
)) {
1415 // Pass code object version to device toolchain
1416 // to correctly set metadata in intermediate files.
1417 if (SameTripleAsHost
||
1418 A
->getOption().matches(options::OPT_mcode_object_version_EQ
))
1427 bool XOpenMPTargetNoTriple
=
1428 A
->getOption().matches(options::OPT_Xopenmp_target
);
1430 if (A
->getOption().matches(options::OPT_Xopenmp_target_EQ
)) {
1431 llvm::Triple
TT(getOpenMPTriple(A
->getValue(0)));
1433 // Passing device args: -Xopenmp-target=<triple> -opt=val.
1434 if (TT
.getTriple() == getTripleString())
1435 Index
= Args
.getBaseArgs().MakeIndex(A
->getValue(1));
1438 } else if (XOpenMPTargetNoTriple
) {
1439 // Passing device args: -Xopenmp-target -opt=val.
1440 Index
= Args
.getBaseArgs().MakeIndex(A
->getValue(0));
1446 // Parse the argument to -Xopenmp-target.
1448 std::unique_ptr
<Arg
> XOpenMPTargetArg(Opts
.ParseOneArg(Args
, Index
));
1449 if (!XOpenMPTargetArg
|| Index
> Prev
+ 1) {
1450 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args
)
1451 << A
->getAsString(Args
);
1454 if (XOpenMPTargetNoTriple
&& XOpenMPTargetArg
&&
1455 Args
.getAllArgValues(options::OPT_fopenmp_targets_EQ
).size() != 1) {
1456 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple
);
1459 XOpenMPTargetArg
->setBaseArg(A
);
1460 A
= XOpenMPTargetArg
.release();
1461 AllocatedArgs
.push_back(A
);
1473 // TODO: Currently argument values separated by space e.g.
1474 // -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be
1476 void ToolChain::TranslateXarchArgs(
1477 const llvm::opt::DerivedArgList
&Args
, llvm::opt::Arg
*&A
,
1478 llvm::opt::DerivedArgList
*DAL
,
1479 SmallVectorImpl
<llvm::opt::Arg
*> *AllocatedArgs
) const {
1480 const OptTable
&Opts
= getDriver().getOpts();
1481 unsigned ValuePos
= 1;
1482 if (A
->getOption().matches(options::OPT_Xarch_device
) ||
1483 A
->getOption().matches(options::OPT_Xarch_host
))
1486 unsigned Index
= Args
.getBaseArgs().MakeIndex(A
->getValue(ValuePos
));
1487 unsigned Prev
= Index
;
1488 std::unique_ptr
<llvm::opt::Arg
> XarchArg(Opts
.ParseOneArg(Args
, Index
));
1490 // If the argument parsing failed or more than one argument was
1491 // consumed, the -Xarch_ argument's parameter tried to consume
1492 // extra arguments. Emit an error and ignore.
1494 // We also want to disallow any options which would alter the
1495 // driver behavior; that isn't going to work in our model. We
1496 // use options::NoXarchOption to control this.
1497 if (!XarchArg
|| Index
> Prev
+ 1) {
1498 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args
)
1499 << A
->getAsString(Args
);
1501 } else if (XarchArg
->getOption().hasFlag(options::NoXarchOption
)) {
1502 auto &Diags
= getDriver().getDiags();
1504 Diags
.getCustomDiagID(DiagnosticsEngine::Error
,
1505 "invalid Xarch argument: '%0', not all driver "
1506 "options can be forwared via Xarch argument");
1507 Diags
.Report(DiagID
) << A
->getAsString(Args
);
1510 XarchArg
->setBaseArg(A
);
1511 A
= XarchArg
.release();
1513 DAL
->AddSynthesizedArg(A
);
1515 AllocatedArgs
->push_back(A
);
1518 llvm::opt::DerivedArgList
*ToolChain::TranslateXarchArgs(
1519 const llvm::opt::DerivedArgList
&Args
, StringRef BoundArch
,
1520 Action::OffloadKind OFK
,
1521 SmallVectorImpl
<llvm::opt::Arg
*> *AllocatedArgs
) const {
1522 DerivedArgList
*DAL
= new DerivedArgList(Args
.getBaseArgs());
1523 bool Modified
= false;
1525 bool IsDevice
= OFK
!= Action::OFK_None
&& OFK
!= Action::OFK_Host
;
1526 for (Arg
*A
: Args
) {
1527 bool NeedTrans
= false;
1529 if (A
->getOption().matches(options::OPT_Xarch_device
)) {
1530 NeedTrans
= IsDevice
;
1532 } else if (A
->getOption().matches(options::OPT_Xarch_host
)) {
1533 NeedTrans
= !IsDevice
;
1535 } else if (A
->getOption().matches(options::OPT_Xarch__
) && IsDevice
) {
1536 // Do not translate -Xarch_ options for non CUDA/HIP toolchain since
1537 // they may need special translation.
1538 // Skip this argument unless the architecture matches BoundArch
1539 if (BoundArch
.empty() || A
->getValue(0) != BoundArch
)
1544 if (NeedTrans
|| Skip
)
1547 TranslateXarchArgs(Args
, A
, DAL
, AllocatedArgs
);