clang 23.0.0git
ToolChain.cpp
Go to the documentation of this file.
1//===- ToolChain.cpp - Collections of tools for one platform --------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
12#include "ToolChains/Arch/ARM.h"
14#include "ToolChains/Clang.h"
15#include "ToolChains/Flang.h"
19#include "clang/Config/config.h"
20#include "clang/Driver/Action.h"
22#include "clang/Driver/Driver.h"
24#include "clang/Driver/Job.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/MemoryBuffer.h"
43#include "llvm/Support/Path.h"
44#include "llvm/Support/Process.h"
45#include "llvm/Support/VersionTuple.h"
46#include "llvm/Support/VirtualFileSystem.h"
47#include "llvm/TargetParser/AArch64TargetParser.h"
48#include "llvm/TargetParser/RISCVISAInfo.h"
49#include "llvm/TargetParser/TargetParser.h"
50#include "llvm/TargetParser/Triple.h"
51#include <cassert>
52#include <cstddef>
53#include <cstring>
54#include <string>
55
56using namespace clang;
57using namespace driver;
58using namespace tools;
59using namespace llvm;
60using namespace llvm::opt;
61
62static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
63 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
64 options::OPT_fno_rtti, options::OPT_frtti);
65}
66
67static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
68 const llvm::Triple &Triple,
69 const Arg *CachedRTTIArg) {
70 // Explicit rtti/no-rtti args
71 if (CachedRTTIArg) {
72 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
74 else
76 }
77
78 // -frtti is default, except for the PS4/PS5 and DriverKit.
79 bool NoRTTI = Triple.isPS() || Triple.isDriverKit();
81}
82
84 if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
85 true)) {
87 }
89}
90
91ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
92 const ArgList &Args)
93 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
94 CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)),
95 CachedExceptionsMode(CalculateExceptionsMode(Args)) {
96 auto addIfExists = [this](path_list &List, const std::string &Path) {
97 if (getVFS().exists(Path))
98 List.push_back(Path);
99 };
100
101 if (std::optional<std::string> Path = getRuntimePath())
102 getLibraryPaths().push_back(*Path);
103 if (std::optional<std::string> Path = getStdlibPath())
104 getFilePaths().push_back(*Path);
105 for (const auto &Path : getArchSpecificLibPaths())
106 addIfExists(getFilePaths(), Path);
107}
108
110 if (!SelectedMultilibs.empty())
111 return llvm::reverse(SelectedMultilibs);
112
114 return llvm::reverse(Default);
115}
116
117bool ToolChain::loadMultilibsFromYAML(const llvm::opt::ArgList &Args,
118 const Driver &D, StringRef Fallback) {
119 std::optional<std::string> MultilibPath =
120 findMultilibsYAML(Args, D, Fallback);
121 if (!MultilibPath)
122 return false;
123 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
124 D.getVFS().getBufferForFile(*MultilibPath);
125 if (!MB)
126 return false;
127
129 llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
130 MultilibSet::parseYaml(*MB.get());
131 if (ErrorOrMultilibSet.getError())
132 return false;
133
134 Multilibs = std::move(ErrorOrMultilibSet.get());
135
136 SmallVector<StringRef> CustomFlagMacroDefines;
137 bool Result =
138 Multilibs.select(D, Flags, SelectedMultilibs, &CustomFlagMacroDefines);
139
140 // Custom flag macro defines are set by processCustomFlags regardless of
141 // whether variant selection succeeds.
142 MultilibMacroDefines.clear();
143 for (StringRef Define : CustomFlagMacroDefines)
144 MultilibMacroDefines.push_back(Define.str());
145
146 if (!Result) {
147 D.Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags, " ");
149 raw_svector_ostream OS(Data);
150 for (const Multilib &M : Multilibs)
151 if (!M.isError())
152 OS << "\n" << llvm::join(M.flags(), " ");
153 D.Diag(clang::diag::note_drv_available_multilibs) << OS.str();
154
155 for (const Multilib &M : SelectedMultilibs)
156 if (M.isError())
157 D.Diag(clang::diag::err_drv_multilib_custom_error)
158 << M.getErrorMessage();
159
160 SelectedMultilibs.clear();
161 return false;
162 }
163
164 // Prepend variant-specific library paths. The YAML's parent directory is
165 // the base for file paths; getRuntimePath() is the base for runtime paths.
166 StringRef YAMLBase = llvm::sys::path::parent_path(*MultilibPath);
167 std::optional<std::string> RuntimeDir = getRuntimePath();
168 size_t FileInsertPos = 0;
169 size_t LibInsertPos = 0;
170 for (const Multilib &M : getOrderedMultilibs()) {
171 if (M.isDefault())
172 continue;
173 SmallString<128> FilePath(YAMLBase);
174 llvm::sys::path::append(FilePath, M.gccSuffix());
175 getFilePaths().insert(getFilePaths().begin() + FileInsertPos,
176 std::string(FilePath));
177 ++FileInsertPos;
178 if (RuntimeDir) {
179 SmallString<128> LibPath(*RuntimeDir);
180 llvm::sys::path::append(LibPath, M.gccSuffix());
181 getLibraryPaths().insert(getLibraryPaths().begin() + LibInsertPos,
182 std::string(LibPath));
183 ++LibInsertPos;
184 }
185 }
186
187 return true;
188}
189
190std::optional<std::string>
191ToolChain::findMultilibsYAML(const llvm::opt::ArgList &Args, const Driver &D,
192 StringRef FallbackDir) {
193 if (Arg *A = Args.getLastArg(options::OPT_multi_lib_config)) {
194 SmallString<128> MultilibPath(A->getValue());
195 if (!D.getVFS().exists(MultilibPath)) {
196 D.Diag(clang::diag::err_drv_no_such_file) << MultilibPath.str();
197 return std::nullopt;
198 }
199 return std::string(MultilibPath);
200 }
201
202 SmallString<128> MultilibPath;
203 if (!FallbackDir.empty())
204 MultilibPath = FallbackDir;
205 else if (std::optional<std::string> StdlibDir = getStdlibPath())
206 MultilibPath = *StdlibDir;
207 else
208 return std::nullopt;
209 llvm::sys::path::append(MultilibPath, "multilib.yaml");
210 if (!D.getVFS().exists(MultilibPath))
211 return std::nullopt;
212 return std::string(MultilibPath);
213}
214
215void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) {
216 Triple.setEnvironment(Env);
217 if (EffectiveTriple != llvm::Triple())
218 EffectiveTriple.setEnvironment(Env);
219}
220
221ToolChain::~ToolChain() = default;
222
223llvm::vfs::FileSystem &ToolChain::getVFS() const {
224 return getDriver().getVFS();
225}
226
228 return Args.hasFlag(options::OPT_fintegrated_as,
229 options::OPT_fno_integrated_as,
231}
232
234 assert(
237 "(Non-)integrated backend set incorrectly!");
238
239 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
240 options::OPT_fno_integrated_objemitter,
242
243 // Diagnose when integrated-objemitter options are not supported by this
244 // toolchain.
245 unsigned DiagID;
246 if ((IBackend && !IsIntegratedBackendSupported()) ||
247 (!IBackend && !IsNonIntegratedBackendSupported()))
248 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
249 else
250 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
251 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
253 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
254 A = Args.getLastArg(options::OPT_fintegrated_objemitter);
256 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
257
258 return IBackend;
259}
260
262 return ENABLE_X86_RELAX_RELOCATIONS;
263}
264
266 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
267}
268
270 const llvm::opt::ArgList &Args) {
271 for (const Arg *MultilibFlagArg :
272 Args.filtered(options::OPT_fmultilib_flag)) {
273 List.push_back(MultilibFlagArg->getAsString(Args));
274 MultilibFlagArg->claim();
275 }
276}
277
278static void getAArch64MultilibFlags(const Driver &D,
279 const llvm::Triple &Triple,
280 const llvm::opt::ArgList &Args,
282 std::vector<StringRef> Features;
283 tools::aarch64::getAArch64TargetFeatures(D, Triple, Args, Features,
284 /*ForAS=*/false,
285 /*ForMultilib=*/true);
286 const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
287 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
288 UnifiedFeatures.end());
289 std::vector<std::string> MArch;
290 for (const auto &Ext : AArch64::Extensions)
291 if (!Ext.UserVisibleName.empty())
292 if (FeatureSet.contains(Ext.PosTargetFeature))
293 MArch.push_back(Ext.UserVisibleName.str());
294 for (const auto &Ext : AArch64::Extensions)
295 if (!Ext.UserVisibleName.empty())
296 if (FeatureSet.contains(Ext.NegTargetFeature))
297 MArch.push_back(("no" + Ext.UserVisibleName).str());
298 StringRef ArchName;
299 for (const auto &ArchInfo : AArch64::ArchInfos)
300 if (FeatureSet.contains(ArchInfo->ArchFeature))
301 ArchName = ArchInfo->Name;
302 if (!ArchName.empty()) {
303 MArch.insert(MArch.begin(), ("-march=" + ArchName).str());
304 Result.push_back(llvm::join(MArch, "+"));
305 }
306
307 const Arg *BranchProtectionArg =
308 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
309 if (BranchProtectionArg) {
310 Result.push_back(BranchProtectionArg->getAsString(Args));
311 }
312
313 if (FeatureSet.contains("+strict-align"))
314 Result.push_back("-mno-unaligned-access");
315 else
316 Result.push_back("-munaligned-access");
317
318 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
319 options::OPT_mlittle_endian)) {
320 if (Endian->getOption().matches(options::OPT_mbig_endian))
321 Result.push_back(Endian->getAsString(Args));
322 }
323
324 const Arg *ABIArg = Args.getLastArgNoClaim(options::OPT_mabi_EQ);
325 if (ABIArg) {
326 Result.push_back(ABIArg->getAsString(Args));
327 }
328
329 if (const Arg *A = Args.getLastArg(options::OPT_O_Group);
330 A && A->getOption().matches(options::OPT_O)) {
331 switch (A->getValue()[0]) {
332 case 's':
333 Result.push_back("-Os");
334 break;
335 case 'z':
336 Result.push_back("-Oz");
337 break;
338 }
339 }
340}
341
342static void getARMMultilibFlags(const Driver &D, const llvm::Triple &Triple,
343 llvm::Reloc::Model RelocationModel,
344 const llvm::opt::ArgList &Args,
346 std::vector<StringRef> Features;
347 llvm::ARM::FPUKind FPUKind = tools::arm::getARMTargetFeatures(
348 D, Triple, Args, Features, false /*ForAs*/, true /*ForMultilib*/);
349 const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
350 llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
351 UnifiedFeatures.end());
352 std::vector<std::string> MArch;
353 for (const auto &Ext : ARM::ARCHExtNames)
354 if (!Ext.Name.empty())
355 if (FeatureSet.contains(Ext.Feature))
356 MArch.push_back(Ext.Name.str());
357 for (const auto &Ext : ARM::ARCHExtNames)
358 if (!Ext.Name.empty())
359 if (FeatureSet.contains(Ext.NegFeature))
360 MArch.push_back(("no" + Ext.Name).str());
361 MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
362 Result.push_back(llvm::join(MArch, "+"));
363
364 switch (FPUKind) {
365#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
366 case llvm::ARM::KIND: \
367 Result.push_back("-mfpu=" NAME); \
368 break;
369#include "llvm/TargetParser/ARMTargetParser.def"
370 default:
371 llvm_unreachable("Invalid FPUKind");
372 }
373
374 switch (arm::getARMFloatABI(D, Triple, Args)) {
375 case arm::FloatABI::Soft:
376 Result.push_back("-mfloat-abi=soft");
377 break;
378 case arm::FloatABI::SoftFP:
379 Result.push_back("-mfloat-abi=softfp");
380 break;
381 case arm::FloatABI::Hard:
382 Result.push_back("-mfloat-abi=hard");
383 break;
384 case arm::FloatABI::Invalid:
385 llvm_unreachable("Invalid float ABI");
386 }
387
388 if (RelocationModel == llvm::Reloc::ROPI ||
389 RelocationModel == llvm::Reloc::ROPI_RWPI)
390 Result.push_back("-fropi");
391 else
392 Result.push_back("-fno-ropi");
393
394 if (RelocationModel == llvm::Reloc::RWPI ||
395 RelocationModel == llvm::Reloc::ROPI_RWPI)
396 Result.push_back("-frwpi");
397 else
398 Result.push_back("-fno-rwpi");
399
400 const Arg *BranchProtectionArg =
401 Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
402 if (BranchProtectionArg) {
403 Result.push_back(BranchProtectionArg->getAsString(Args));
404 }
405
406 if (FeatureSet.contains("+strict-align"))
407 Result.push_back("-mno-unaligned-access");
408 else
409 Result.push_back("-munaligned-access");
410
411 if (Arg *Endian = Args.getLastArg(options::OPT_mbig_endian,
412 options::OPT_mlittle_endian)) {
413 if (Endian->getOption().matches(options::OPT_mbig_endian))
414 Result.push_back(Endian->getAsString(Args));
415 }
416
417 if (const Arg *A = Args.getLastArg(options::OPT_O_Group);
418 A && A->getOption().matches(options::OPT_O)) {
419 switch (A->getValue()[0]) {
420 case 's':
421 Result.push_back("-Os");
422 break;
423 case 'z':
424 Result.push_back("-Oz");
425 break;
426 }
427 }
428}
429
430static void getRISCVMultilibFlags(const Driver &D, const llvm::Triple &Triple,
431 const llvm::opt::ArgList &Args,
433 bool hasShadowCallStack) {
434 std::string Arch = riscv::getRISCVArch(Args, Triple);
435 // Canonicalize arch for easier matching
436 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
437 Arch, /*EnableExperimentalExtensions*/ true);
438 if (!llvm::errorToBool(ISAInfo.takeError()))
439 Result.push_back("-march=" + (*ISAInfo)->toString());
440
441 Result.push_back(("-mabi=" + riscv::getRISCVABI(Args, Triple)).str());
442
443 if (hasShadowCallStack)
444 Result.push_back("-fsanitize=shadow-call-stack");
445 else
446 Result.push_back("-fno-sanitize=shadow-call-stack");
447}
448
450ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
451 using namespace clang::options;
452
453 std::vector<std::string> Result;
454 const llvm::Triple Triple(ComputeEffectiveClangTriple(Args));
455 Result.push_back("--target=" + Triple.str());
456
457 // A difference of relocation model (absolutely addressed data, PIC, Arm
458 // ROPI/RWPI) is likely to change whether a particular multilib variant is
459 // compatible with a given link. Determine the relocation model of the
460 // current link, so as to add appropriate multilib flags.
461 llvm::Reloc::Model RelocationModel;
462 unsigned PICLevel;
463 bool IsPIE;
464 {
465 RegisterEffectiveTriple TripleRAII(*this, Triple);
466 std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(*this, Args);
467 }
468
469 switch (Triple.getArch()) {
470 case llvm::Triple::aarch64:
471 case llvm::Triple::aarch64_32:
472 case llvm::Triple::aarch64_be:
473 getAArch64MultilibFlags(D, Triple, Args, Result);
474 break;
475 case llvm::Triple::arm:
476 case llvm::Triple::armeb:
477 case llvm::Triple::thumb:
478 case llvm::Triple::thumbeb:
479 getARMMultilibFlags(D, Triple, RelocationModel, Args, Result);
480 break;
481 case llvm::Triple::riscv32:
482 case llvm::Triple::riscv64:
483 case llvm::Triple::riscv32be:
484 case llvm::Triple::riscv64be:
485 getRISCVMultilibFlags(D, Triple, Args, Result,
486 getSanitizerArgs(Args).hasShadowCallStack());
487 break;
488 default:
489 break;
490 }
491
493
494 // Include fno-exceptions and fno-rtti
495 // to improve multilib selection
497 Result.push_back("-fno-rtti");
498 else
499 Result.push_back("-frtti");
500
502 Result.push_back("-fno-exceptions");
503 else
504 Result.push_back("-fexceptions");
505
506 if (RelocationModel == llvm::Reloc::PIC_)
507 Result.push_back(IsPIE ? (PICLevel > 1 ? "-fPIE" : "-fpie")
508 : (PICLevel > 1 ? "-fPIC" : "-fpic"));
509 else
510 Result.push_back("-fno-pic");
511
512 // Sort and remove duplicates.
513 std::sort(Result.begin(), Result.end());
514 Result.erase(llvm::unique(Result), Result.end());
515 return Result;
516}
517
519ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const {
520 SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);
521 SanitizerArgsChecked = true;
522 return SanArgs;
523}
524
525const XRayArgs ToolChain::getXRayArgs(const llvm::opt::ArgList &JobArgs) const {
526 XRayArgs XRayArguments(*this, JobArgs);
527 return XRayArguments;
528}
529
530namespace {
531
532struct DriverSuffix {
533 const char *Suffix;
534 const char *ModeFlag;
535};
536
537} // namespace
538
539static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
540 // A list of known driver suffixes. Suffixes are compared against the
541 // program name in order. If there is a match, the frontend type is updated as
542 // necessary by applying the ModeFlag.
543 static const DriverSuffix DriverSuffixes[] = {
544 {"clang", nullptr},
545 {"clang++", "--driver-mode=g++"},
546 {"clang-c++", "--driver-mode=g++"},
547 {"clang-cc", nullptr},
548 {"clang-cpp", "--driver-mode=cpp"},
549 {"clang-g++", "--driver-mode=g++"},
550 {"clang-gcc", nullptr},
551 {"clang-cl", "--driver-mode=cl"},
552 {"cc", nullptr},
553 {"cpp", "--driver-mode=cpp"},
554 {"cl", "--driver-mode=cl"},
555 {"++", "--driver-mode=g++"},
556 {"flang", "--driver-mode=flang"},
557 // For backwards compatibility, we create a symlink for `flang` called
558 // `flang-new`. This will be removed in the future.
559 {"flang-new", "--driver-mode=flang"},
560 {"clang-dxc", "--driver-mode=dxc"},
561 };
562
563 for (const auto &DS : DriverSuffixes) {
564 StringRef Suffix(DS.Suffix);
565 if (ProgName.ends_with(Suffix)) {
566 Pos = ProgName.size() - Suffix.size();
567 return &DS;
568 }
569 }
570 return nullptr;
571}
572
573/// Normalize the program name from argv[0] by stripping the file extension if
574/// present and lower-casing the string on Windows.
575static std::string normalizeProgramName(llvm::StringRef Argv0) {
576 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
577 if (is_style_windows(llvm::sys::path::Style::native)) {
578 // Transform to lowercase for case insensitive file systems.
579 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
580 ::tolower);
581 }
582 return ProgName;
583}
584
585static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
586 // Try to infer frontend type and default target from the program name by
587 // comparing it against DriverSuffixes in order.
588
589 // If there is a match, the function tries to identify a target as prefix.
590 // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
591 // prefix "x86_64-linux". If such a target prefix is found, it may be
592 // added via -target as implicit first argument.
593 const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos);
594
595 if (!DS && ProgName.ends_with(".exe")) {
596 // Try again after stripping the executable suffix:
597 // clang++.exe -> clang++
598 ProgName = ProgName.drop_back(StringRef(".exe").size());
599 DS = FindDriverSuffix(ProgName, Pos);
600 }
601
602 if (!DS) {
603 // Try again after stripping any trailing version number:
604 // clang++3.5 -> clang++
605 ProgName = ProgName.rtrim("0123456789.");
606 DS = FindDriverSuffix(ProgName, Pos);
607 }
608
609 if (!DS) {
610 // Try again after stripping trailing -component.
611 // clang++-tot -> clang++
612 ProgName = ProgName.slice(0, ProgName.rfind('-'));
613 DS = FindDriverSuffix(ProgName, Pos);
614 }
615 return DS;
616}
617
620 std::string ProgName = normalizeProgramName(PN);
621 size_t SuffixPos;
622 const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos);
623 if (!DS)
624 return {};
625 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
626
627 size_t LastComponent = ProgName.rfind('-', SuffixPos);
628 if (LastComponent == std::string::npos)
629 return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);
630 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
631 SuffixEnd - LastComponent - 1);
632
633 // Infer target from the prefix.
634 StringRef Prefix(ProgName);
635 Prefix = Prefix.slice(0, LastComponent);
636 std::string IgnoredError;
637
638 llvm::Triple Triple(Prefix);
639 bool IsRegistered = llvm::TargetRegistry::lookupTarget(Triple, IgnoredError);
640 return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag,
641 IsRegistered};
642}
643
645 // In universal driver terms, the arch name accepted by -arch isn't exactly
646 // the same as the ones that appear in the triple. Roughly speaking, this is
647 // an inverse of the darwin::getArchTypeForDarwinArchName() function.
648 switch (Triple.getArch()) {
649 case llvm::Triple::aarch64: {
650 if (getTriple().isArm64e())
651 return "arm64e";
652 return "arm64";
653 }
654 case llvm::Triple::aarch64_32:
655 return "arm64_32";
656 case llvm::Triple::ppc:
657 return "ppc";
658 case llvm::Triple::ppcle:
659 return "ppcle";
660 case llvm::Triple::ppc64:
661 return "ppc64";
662 case llvm::Triple::ppc64le:
663 return "ppc64le";
664 default:
665 return Triple.getArchName();
666 }
667}
668
669std::string ToolChain::getInputFilename(const InputInfo &Input) const {
670 return Input.getFilename();
671}
672
674ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const {
676}
677
678Tool *ToolChain::getClang() const {
679 if (!Clang)
680 Clang.reset(new tools::Clang(*this, useIntegratedBackend()));
681 return Clang.get();
682}
683
684Tool *ToolChain::getFlang() const {
685 if (!Flang)
686 Flang.reset(new tools::Flang(*this));
687 return Flang.get();
688}
689
691 return new tools::ClangAs(*this);
692}
693
695 llvm_unreachable("Linking is not supported by this toolchain");
696}
697
699 llvm_unreachable("Creating static lib is not supported by this toolchain");
700}
701
702Tool *ToolChain::getAssemble() const {
703 if (!Assemble)
704 Assemble.reset(buildAssembler());
705 return Assemble.get();
706}
707
708Tool *ToolChain::getClangAs() const {
709 if (!Assemble)
710 Assemble.reset(new tools::ClangAs(*this));
711 return Assemble.get();
712}
713
714Tool *ToolChain::getLink() const {
715 if (!Link)
716 Link.reset(buildLinker());
717 return Link.get();
718}
719
720Tool *ToolChain::getStaticLibTool() const {
721 if (!StaticLibTool)
722 StaticLibTool.reset(buildStaticLibTool());
723 return StaticLibTool.get();
724}
725
726Tool *ToolChain::getIfsMerge() const {
727 if (!IfsMerge)
728 IfsMerge.reset(new tools::ifstool::Merger(*this));
729 return IfsMerge.get();
730}
731
732Tool *ToolChain::getOffloadBundler() const {
733 if (!OffloadBundler)
734 OffloadBundler.reset(new tools::OffloadBundler(*this));
735 return OffloadBundler.get();
736}
737
738Tool *ToolChain::getOffloadPackager() const {
739 if (!OffloadPackager)
740 OffloadPackager.reset(new tools::OffloadPackager(*this));
741 return OffloadPackager.get();
742}
743
744Tool *ToolChain::getLinkerWrapper() const {
745 if (!LinkerWrapper)
746 LinkerWrapper.reset(new tools::LinkerWrapper(*this, getLink()));
747 return LinkerWrapper.get();
748}
749
751 switch (AC) {
753 return getAssemble();
754
756 return getIfsMerge();
757
759 return getLink();
760
762 return getStaticLibTool();
763
773 llvm_unreachable("Invalid tool kind.");
774
782 return getClang();
783
786 return getOffloadBundler();
787
789 return getOffloadPackager();
791 return getLinkerWrapper();
792 }
793
794 llvm_unreachable("Invalid tool kind.");
795}
796
797static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
798 const ArgList &Args) {
799 const llvm::Triple &Triple = TC.getTriple();
800 bool IsWindows = Triple.isOSWindows();
801
802 if (TC.isBareMetal())
803 return Triple.getArchName();
804
805 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
806 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
807 ? "armhf"
808 : "arm";
809
810 // For historic reasons, Android library is using i686 instead of i386.
811 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid())
812 return "i686";
813
814 if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32())
815 return "x32";
816
817 return llvm::Triple::getArchTypeName(TC.getArch());
818}
819
820StringRef ToolChain::getOSLibName() const {
821 if (Triple.isOSDarwin())
822 return "darwin";
823
824 switch (Triple.getOS()) {
825 case llvm::Triple::FreeBSD:
826 return "freebsd";
827 case llvm::Triple::NetBSD:
828 return "netbsd";
829 case llvm::Triple::OpenBSD:
830 return "openbsd";
831 case llvm::Triple::Solaris:
832 return "sunos";
833 case llvm::Triple::AIX:
834 return "aix";
835 case llvm::Triple::Serenity:
836 return "serenity";
837 default:
838 return getOS();
839 }
840}
841
842std::string ToolChain::getCompilerRTPath() const {
843 SmallString<128> Path(getDriver().ResourceDir);
844 if (isBareMetal()) {
845 llvm::sys::path::append(Path, "lib", getOSLibName());
846 if (!SelectedMultilibs.empty()) {
847 Path += SelectedMultilibs.back().gccSuffix();
848 }
849 } else if (Triple.isOSUnknown()) {
850 llvm::sys::path::append(Path, "lib");
851 } else {
852 llvm::sys::path::append(Path, "lib", getOSLibName());
853 }
854 return std::string(Path);
855}
856
857std::string ToolChain::getCompilerRTBasename(const ArgList &Args,
858 StringRef Component,
859 FileType Type) const {
860 std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type);
861 return llvm::sys::path::filename(CRTAbsolutePath).str();
862}
863
864std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
865 StringRef Component,
866 FileType Type, bool AddArch,
867 bool IsFortran) const {
868 const llvm::Triple &TT = getTriple();
869 bool IsITANMSVCWindows =
870 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
871
872 const char *Prefix =
873 IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib";
874 const char *Suffix;
875 switch (Type) {
877 Suffix = IsITANMSVCWindows ? ".obj" : ".o";
878 break;
880 Suffix = IsITANMSVCWindows ? ".lib" : ".a";
881 break;
883 if (TT.isOSWindows())
884 Suffix = TT.isOSCygMing() ? ".dll.a" : ".lib";
885 else if (TT.isOSAIX())
886 Suffix = ".a";
887 else
888 Suffix = ".so";
889 break;
890 }
891
892 std::string ArchAndEnv;
893 if (AddArch) {
894 StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
895 const char *Env = TT.isAndroid() ? "-android" : "";
896 ArchAndEnv = ("-" + Arch + Env).str();
897 }
898
899 std::string LibName = IsFortran ? "flang_rt." : "clang_rt.";
900 return (Prefix + Twine(LibName) + Component + ArchAndEnv + Suffix).str();
901}
902
903std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
904 FileType Type, bool IsFortran) const {
905 // Check for runtime files in the new layout without the architecture first.
906 std::string CRTBasename = buildCompilerRTBasename(
907 Args, Component, Type, /*AddArch=*/false, IsFortran);
908 SmallString<128> Path;
909 for (const auto &LibPath : getLibraryPaths()) {
910 SmallString<128> P(LibPath);
911 llvm::sys::path::append(P, CRTBasename);
912 if (getVFS().exists(P))
913 return std::string(P);
914 if (Path.empty())
915 Path = P;
916 }
917
918 // Check the filename for the old layout if the new one does not exist.
919 CRTBasename = buildCompilerRTBasename(Args, Component, Type,
920 /*AddArch=*/!IsFortran, IsFortran);
922 llvm::sys::path::append(OldPath, CRTBasename);
923 if (Path.empty() || getVFS().exists(OldPath))
924 return std::string(OldPath);
925
926 // If none is found, use a file name from the new layout, which may get
927 // printed in an error message, aiding users in knowing what Clang is
928 // looking for.
929 return std::string(Path);
930}
931
932const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
933 StringRef Component,
935 bool isFortran) const {
936 return Args.MakeArgString(getCompilerRT(Args, Component, Type, isFortran));
937}
938
939/// Add Fortran runtime libs
940void ToolChain::addFortranRuntimeLibs(const ArgList &Args,
941 llvm::opt::ArgStringList &CmdArgs) const {
942 // Link flang_rt.runtime
943 // These are handled earlier on Windows by telling the frontend driver to
944 // add the correct libraries to link against as dependents in the object
945 // file.
946 if (!getTriple().isKnownWindowsMSVCEnvironment()) {
947 StringRef F128LibName = getDriver().getFlangF128MathLibrary();
948 F128LibName.consume_front_insensitive("lib");
949 if (!F128LibName.empty()) {
950 bool AsNeeded = !getTriple().isOSAIX();
951 CmdArgs.push_back("-lflang_rt.quadmath");
952 if (AsNeeded)
953 addAsNeededOption(*this, Args, CmdArgs, /*as_needed=*/true);
954 CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName));
955 if (AsNeeded)
956 addAsNeededOption(*this, Args, CmdArgs, /*as_needed=*/false);
957 }
958 addFlangRTLibPath(Args, CmdArgs);
959
960 // needs libexecinfo for backtrace functions
961 if (getTriple().isOSFreeBSD() || getTriple().isOSNetBSD() ||
962 getTriple().isOSOpenBSD() || getTriple().isOSDragonFly())
963 CmdArgs.push_back("-lexecinfo");
964 }
965
966 // libomp needs libatomic for atomic operations if using libgcc
967 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
968 options::OPT_fno_openmp, false)) {
971 if ((OMPRuntime == Driver::OMPRT_OMP &&
972 RuntimeLib == ToolChain::RLT_Libgcc) &&
973 !getTriple().isKnownWindowsMSVCEnvironment()) {
974 CmdArgs.push_back("-latomic");
975 }
976 }
977}
978
979void ToolChain::addFortranRuntimeLibraryPath(const llvm::opt::ArgList &Args,
980 ArgStringList &CmdArgs) const {
981 auto AddLibSearchPathIfExists = [&](const Twine &Path) {
982 // Linker may emit warnings about non-existing directories
983 if (!llvm::sys::fs::is_directory(Path))
984 return;
985
986 if (getTriple().isKnownWindowsMSVCEnvironment())
987 CmdArgs.push_back(Args.MakeArgString("-libpath:" + Path));
988 else
989 CmdArgs.push_back(Args.MakeArgString("-L" + Path));
990 };
991
992 // Search for flang_rt.* at the same location as clang_rt.* with
993 // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0. On most platforms, flang_rt is
994 // located at the path returned by getRuntimePath() which is already added to
995 // the library search path. This exception is for Apple-Darwin.
996 AddLibSearchPathIfExists(getCompilerRTPath());
997
998 // Fall back to the non-resource directory <driver-path>/../lib. We will
999 // probably have to refine this in the future. In particular, on some
1000 // platforms, we may need to use lib64 instead of lib.
1001 SmallString<256> DefaultLibPath =
1002 llvm::sys::path::parent_path(getDriver().Dir);
1003 llvm::sys::path::append(DefaultLibPath, "lib");
1004 AddLibSearchPathIfExists(DefaultLibPath);
1005}
1006
1007void ToolChain::addFlangRTLibPath(const ArgList &Args,
1008 llvm::opt::ArgStringList &CmdArgs) const {
1009 // Link static flang_rt.runtime.a or shared flang_rt.runtime.so.
1010 // On AIX, default to static flang-rt.
1011 if (Args.hasFlag(options::OPT_static_libflangrt,
1012 options::OPT_shared_libflangrt, getTriple().isOSAIX()))
1013 CmdArgs.push_back(
1014 getCompilerRTArgString(Args, "runtime", ToolChain::FT_Static, true));
1015 else {
1016 CmdArgs.push_back("-lflang_rt.runtime");
1017 addArchSpecificRPath(*this, Args, CmdArgs);
1018 }
1019}
1020
1021// Android target triples contain a target version. If we don't have libraries
1022// for the exact target version, we should fall back to the next newest version
1023// or a versionless path, if any.
1024std::optional<std::string>
1025ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
1026 llvm::Triple TripleWithoutLevel(getTriple());
1027 TripleWithoutLevel.setEnvironmentName("android"); // remove any version number
1028 const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
1029 unsigned TripleVersion = getTriple().getEnvironmentVersion().getMajor();
1030 unsigned BestVersion = 0;
1031
1032 SmallString<32> TripleDir;
1033 bool UsingUnversionedDir = false;
1034 std::error_code EC;
1035 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(BaseDir, EC), LE;
1036 !EC && LI != LE; LI = LI.increment(EC)) {
1037 StringRef DirName = llvm::sys::path::filename(LI->path());
1038 StringRef DirNameSuffix = DirName;
1039 if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
1040 if (DirNameSuffix.empty() && TripleDir.empty()) {
1041 TripleDir = DirName;
1042 UsingUnversionedDir = true;
1043 } else {
1044 unsigned Version;
1045 if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
1046 Version < TripleVersion) {
1047 BestVersion = Version;
1048 TripleDir = DirName;
1049 UsingUnversionedDir = false;
1050 }
1051 }
1052 }
1053 }
1054
1055 if (TripleDir.empty())
1056 return {};
1057
1058 SmallString<128> P(BaseDir);
1059 llvm::sys::path::append(P, TripleDir);
1060 if (UsingUnversionedDir)
1061 D.Diag(diag::warn_android_unversioned_fallback) << P << getTripleString();
1062 return std::string(P);
1063}
1064
1066 return (Triple.hasEnvironment()
1067 ? llvm::Triple(Triple.getArchName(), Triple.getVendorName(),
1068 llvm::Triple::getOSTypeName(Triple.getOS()),
1069 llvm::Triple::getEnvironmentTypeName(
1070 Triple.getEnvironment()))
1071 : llvm::Triple(Triple.getArchName(), Triple.getVendorName(),
1072 llvm::Triple::getOSTypeName(Triple.getOS())));
1073}
1074
1075std::optional<std::string>
1076ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
1077 auto getPathForTriple =
1078 [&](const llvm::Triple &Triple) -> std::optional<std::string> {
1079 SmallString<128> P(BaseDir);
1080 llvm::sys::path::append(P, Triple.str());
1081 if (getVFS().exists(P))
1082 return std::string(P);
1083 return {};
1084 };
1085
1086 const llvm::Triple &T = getTriple();
1087 if (auto Path = getPathForTriple(T))
1088 return *Path;
1089
1090 if (T.isOSAIX()) {
1091 llvm::Triple AIXTriple;
1092 if (T.getEnvironment() == Triple::UnknownEnvironment) {
1093 // Strip unknown environment and the OS version from the triple.
1094 AIXTriple = llvm::Triple(T.getArchName(), T.getVendorName(),
1095 llvm::Triple::getOSTypeName(T.getOS()));
1096 } else {
1097 // Strip the OS version from the triple.
1098 AIXTriple = getTripleWithoutOSVersion();
1099 }
1100 if (auto Path = getPathForTriple(AIXTriple))
1101 return *Path;
1102 }
1103
1104 if (T.isOSzOS() &&
1105 (!T.getOSVersion().empty() || !T.getEnvironmentVersion().empty())) {
1106 // Build the triple without version information
1107 const llvm::Triple &TripleWithoutVersion = getTripleWithoutOSVersion();
1108 if (auto Path = getPathForTriple(TripleWithoutVersion))
1109 return *Path;
1110 }
1111
1112 // When building with per target runtime directories, various ways of naming
1113 // the Arm architecture may have been normalised to simply "arm".
1114 // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
1115 // Since an armv8l system can use libraries built for earlier architecture
1116 // versions assuming endian and float ABI match.
1117 //
1118 // Original triple: armv8l-unknown-linux-gnueabihf
1119 // Runtime triple: arm-unknown-linux-gnueabihf
1120 //
1121 // We do not do this for armeb (big endian) because doing so could make us
1122 // select little endian libraries. In addition, all known armeb triples only
1123 // use the "armeb" architecture name.
1124 //
1125 // M profile Arm is bare metal and we know they will not be using the per
1126 // target runtime directory layout.
1127 if (T.getArch() == Triple::arm && !T.isArmMClass()) {
1128 llvm::Triple ArmTriple = T;
1129 ArmTriple.setArch(Triple::arm);
1130 if (auto Path = getPathForTriple(ArmTriple))
1131 return *Path;
1132 }
1133
1134 if (T.isAndroid())
1135 return getFallbackAndroidTargetPath(BaseDir);
1136
1137 return {};
1138}
1139
1140std::optional<std::string> ToolChain::getRuntimePath() const {
1141 SmallString<128> P(D.ResourceDir);
1142 llvm::sys::path::append(P, "lib");
1143 if (auto Ret = getTargetSubDirPath(P))
1144 return Ret;
1145 // Darwin does not use per-target runtime directory.
1146 if (Triple.isOSDarwin())
1147 return {};
1148
1149 llvm::sys::path::append(P, Triple.str());
1150 return std::string(P);
1151}
1152
1153std::optional<std::string> ToolChain::getStdlibPath() const {
1154 SmallString<128> P(D.Dir);
1155 llvm::sys::path::append(P, "..", "lib");
1156 return getTargetSubDirPath(P);
1157}
1158
1159std::optional<std::string> ToolChain::getStdlibIncludePath() const {
1160 SmallString<128> P(D.Dir);
1161 llvm::sys::path::append(P, "..", "include");
1162 return getTargetSubDirPath(P);
1163}
1164
1166 path_list Paths;
1167
1168 auto AddPath = [&](const ArrayRef<StringRef> &SS) {
1169 SmallString<128> Path(getDriver().ResourceDir);
1170 llvm::sys::path::append(Path, "lib");
1171 for (auto &S : SS)
1172 llvm::sys::path::append(Path, S);
1173 Paths.push_back(std::string(Path));
1174 };
1175
1176 AddPath({getTriple().str()});
1177 AddPath({getOSLibName(), llvm::Triple::getArchTypeName(getArch())});
1178 return Paths;
1179}
1180
1181bool ToolChain::needsProfileRT(const ArgList &Args) {
1182 if (Args.hasArg(options::OPT_noprofilelib))
1183 return false;
1184
1185 return Args.hasArg(options::OPT_fprofile_generate) ||
1186 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
1187 Args.hasArg(options::OPT_fcs_profile_generate) ||
1188 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
1189 Args.hasArg(options::OPT_fprofile_instr_generate) ||
1190 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
1191 Args.hasArg(options::OPT_fcreate_profile) ||
1192 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage) ||
1193 Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage_EQ);
1194}
1195
1196bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
1197 return Args.hasArg(options::OPT_coverage) ||
1198 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
1199 false);
1200}
1201
1203 if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang();
1204 if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
1205 Action::ActionClass AC = JA.getKind();
1207 !getTriple().isOSAIX())
1208 return getClangAs();
1209 return getTool(AC);
1210}
1211
1212std::string ToolChain::GetFilePath(const char *Name) const {
1213 return D.GetFilePath(Name, *this);
1214}
1215
1216std::string ToolChain::GetProgramPath(const char *Name) const {
1217 return D.GetProgramPath(Name, *this);
1218}
1219
1220std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
1221 if (LinkerIsLLD)
1222 *LinkerIsLLD = false;
1223
1224 // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is
1225 // considered as the linker flavor, e.g. "bfd", "gold", or "lld".
1226 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
1227 StringRef UseLinker = A ? A->getValue() : getDriver().getPreferredLinker();
1228
1229 // --ld-path= takes precedence over -fuse-ld= and specifies the executable
1230 // name. -B, COMPILER_PATH and PATH and consulted if the value does not
1231 // contain a path component separator.
1232 // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary
1233 // that --ld-path= points to is lld.
1234 if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
1235 std::string Path(A->getValue());
1236 if (!Path.empty()) {
1237 if (llvm::sys::path::parent_path(Path).empty())
1238 Path = GetProgramPath(A->getValue());
1239 if (llvm::sys::fs::can_execute(Path)) {
1240 if (LinkerIsLLD)
1241 *LinkerIsLLD = UseLinker == "lld";
1242 return std::string(Path);
1243 }
1244 }
1245 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
1247 }
1248 // If we're passed -fuse-ld= with no argument, or with the argument ld,
1249 // then use whatever the default system linker is.
1250 if (UseLinker.empty() || UseLinker == "ld") {
1251 const char *DefaultLinker = getDefaultLinker();
1252 if (llvm::sys::path::is_absolute(DefaultLinker))
1253 return std::string(DefaultLinker);
1254 else
1255 return GetProgramPath(DefaultLinker);
1256 }
1257
1258 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
1259 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
1260 // to a relative path is surprising. This is more complex due to priorities
1261 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
1262 if (UseLinker.contains('/'))
1263 getDriver().Diag(diag::warn_drv_fuse_ld_path);
1264
1265 if (llvm::sys::path::is_absolute(UseLinker)) {
1266 // If we're passed what looks like an absolute path, don't attempt to
1267 // second-guess that.
1268 if (llvm::sys::fs::can_execute(UseLinker))
1269 return std::string(UseLinker);
1270 } else {
1271 llvm::SmallString<8> LinkerName;
1272 if (Triple.isOSDarwin())
1273 LinkerName.append("ld64.");
1274 else
1275 LinkerName.append("ld.");
1276 LinkerName.append(UseLinker);
1277
1278 std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
1279 if (llvm::sys::fs::can_execute(LinkerPath)) {
1280 if (LinkerIsLLD)
1281 *LinkerIsLLD = UseLinker == "lld";
1282 return LinkerPath;
1283 }
1284 }
1285
1286 if (A)
1287 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
1288
1290}
1291
1293 // TODO: Add support for static lib archiving on Windows
1294 if (Triple.isOSDarwin())
1295 return GetProgramPath("libtool");
1296 return GetProgramPath("llvm-ar");
1297}
1298
1301
1302 // Flang always runs the preprocessor and has no notion of "preprocessed
1303 // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
1304 // them differently.
1305 if (D.IsFlangMode() && id == types::TY_PP_Fortran)
1306 id = types::TY_Fortran;
1307
1308 return id;
1309}
1310
1312 return false;
1313}
1314
1316 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
1317 switch (HostTriple.getArch()) {
1318 // The A32/T32/T16 instruction sets are not separate architectures in this
1319 // context.
1320 case llvm::Triple::arm:
1321 case llvm::Triple::armeb:
1322 case llvm::Triple::thumb:
1323 case llvm::Triple::thumbeb:
1324 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
1325 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
1326 default:
1327 return HostTriple.getArch() != getArch();
1328 }
1329}
1330
1332 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
1333 VersionTuple());
1334}
1335
1336llvm::ExceptionHandling
1337ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const {
1338 return llvm::ExceptionHandling::None;
1339}
1340
1341bool ToolChain::isThreadModelSupported(const StringRef Model) const {
1342 if (Model == "single") {
1343 // FIXME: 'single' is only supported on ARM and WebAssembly so far.
1344 return Triple.getArch() == llvm::Triple::arm ||
1345 Triple.getArch() == llvm::Triple::armeb ||
1346 Triple.getArch() == llvm::Triple::thumb ||
1347 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
1348 } else if (Model == "posix")
1349 return true;
1350
1351 return false;
1352}
1353
1354std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
1355 StringRef BoundArch,
1356 types::ID InputType) const {
1357 switch (getTriple().getArch()) {
1358 default:
1359 return getTripleString().str();
1360
1361 case llvm::Triple::x86_64: {
1362 llvm::Triple Triple = getTriple();
1363 if (!Triple.isOSBinFormatMachO())
1364 return getTripleString().str();
1365
1366 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1367 // x86_64h goes in the triple. Other -march options just use the
1368 // vanilla triple we already have.
1369 StringRef MArch = A->getValue();
1370 if (MArch == "x86_64h")
1371 Triple.setArchName(MArch);
1372 }
1373 return Triple.getTriple();
1374 }
1375 case llvm::Triple::aarch64: {
1376 llvm::Triple Triple = getTriple();
1377 if (!Triple.isOSBinFormatMachO())
1378 return Triple.getTriple();
1379
1380 if (Triple.isArm64e())
1381 return Triple.getTriple();
1382
1383 // FIXME: older versions of ld64 expect the "arm64" component in the actual
1384 // triple string and query it to determine whether an LTO file can be
1385 // handled. Remove this when we don't care any more.
1386 Triple.setArchName("arm64");
1387 return Triple.getTriple();
1388 }
1389 case llvm::Triple::aarch64_32:
1390 return getTripleString().str();
1391 case llvm::Triple::amdgcn: {
1392 llvm::Triple Triple = getTriple();
1393 tools::AMDGPU::setArchNameInTriple(getDriver(), Args, InputType, Triple);
1394 return Triple.getTriple();
1395 }
1396 case llvm::Triple::arm:
1397 case llvm::Triple::armeb:
1398 case llvm::Triple::thumb:
1399 case llvm::Triple::thumbeb: {
1400 llvm::Triple Triple = getTriple();
1401 tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple);
1403 return Triple.getTriple();
1404 }
1405 }
1406}
1407
1408std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1409 StringRef BoundArch,
1410 types::ID InputType) const {
1411 return ComputeLLVMTriple(Args, BoundArch, InputType);
1412}
1413
1414std::string ToolChain::computeSysRoot() const {
1415 return D.SysRoot;
1416}
1417
1418void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1419 ArgStringList &CC1Args) const {
1420 // Each toolchain should provide the appropriate include flags.
1421}
1422
1424 const ArgList &DriverArgs, ArgStringList &CC1Args,
1425 Action::OffloadKind DeviceOffloadKind) const {}
1426
1428 ArgStringList &CC1ASArgs) const {}
1429
1430void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
1431
1432void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
1433 llvm::opt::ArgStringList &CmdArgs) const {
1434 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args))
1435 return;
1436
1437 CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
1438}
1439
1441 const ArgList &Args) const {
1442 if (runtimeLibType)
1443 return *runtimeLibType;
1444
1445 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
1446 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
1447
1448 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
1449 if (LibName == "compiler-rt")
1450 runtimeLibType = ToolChain::RLT_CompilerRT;
1451 else if (LibName == "libgcc")
1452 runtimeLibType = ToolChain::RLT_Libgcc;
1453 else if (LibName == "platform")
1454 runtimeLibType = GetDefaultRuntimeLibType();
1455 else {
1456 if (A)
1457 getDriver().Diag(diag::err_drv_invalid_rtlib_name)
1458 << A->getAsString(Args);
1459
1460 runtimeLibType = GetDefaultRuntimeLibType();
1461 }
1462
1463 return *runtimeLibType;
1464}
1465
1467 const ArgList &Args) const {
1468 if (unwindLibType)
1469 return *unwindLibType;
1470
1471 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
1472 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
1473
1474 if (LibName == "none")
1475 unwindLibType = ToolChain::UNW_None;
1476 else if (LibName == "platform" || LibName == "") {
1478 if (RtLibType == ToolChain::RLT_CompilerRT) {
1479 if (getTriple().isAndroid() || getTriple().isOSAIX() ||
1480 getTriple().isOSSerenity())
1481 unwindLibType = ToolChain::UNW_CompilerRT;
1482 else
1483 unwindLibType = ToolChain::UNW_None;
1484 } else if (RtLibType == ToolChain::RLT_Libgcc)
1485 unwindLibType = ToolChain::UNW_Libgcc;
1486 } else if (LibName == "libunwind") {
1487 if (GetRuntimeLibType(Args) == RLT_Libgcc)
1488 getDriver().Diag(diag::err_drv_incompatible_unwindlib);
1489 unwindLibType = ToolChain::UNW_CompilerRT;
1490 } else if (LibName == "libgcc")
1491 unwindLibType = ToolChain::UNW_Libgcc;
1492 else {
1493 if (A)
1494 getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
1495 << A->getAsString(Args);
1496
1497 unwindLibType = GetDefaultUnwindLibType();
1498 }
1499
1500 return *unwindLibType;
1501}
1502
1504 if (cxxStdlibType)
1505 return *cxxStdlibType;
1506
1507 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
1508 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
1509
1510 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
1511 if (LibName == "libc++")
1512 cxxStdlibType = ToolChain::CST_Libcxx;
1513 else if (LibName == "libstdc++")
1514 cxxStdlibType = ToolChain::CST_Libstdcxx;
1515 else if (LibName == "platform")
1516 cxxStdlibType = GetDefaultCXXStdlibType();
1517 else {
1518 if (A)
1519 getDriver().Diag(diag::err_drv_invalid_stdlib_name)
1520 << A->getAsString(Args);
1521
1522 cxxStdlibType = GetDefaultCXXStdlibType();
1523 }
1524
1525 return *cxxStdlibType;
1526}
1527
1529 if (cStdlibType)
1530 return *cStdlibType;
1531
1532 const Arg *A = Args.getLastArg(options::OPT_cstdlib_EQ);
1533 StringRef LibName = A ? A->getValue() : "system";
1534
1535 if (LibName == "newlib")
1536 cStdlibType = ToolChain::CST_Newlib;
1537 else if (LibName == "picolibc")
1538 cStdlibType = ToolChain::CST_Picolibc;
1539 else if (LibName == "llvm-libc")
1540 cStdlibType = ToolChain::CST_LLVMLibC;
1541 else if (LibName == "system")
1542 cStdlibType = ToolChain::CST_System;
1543 else {
1544 if (A)
1545 getDriver().Diag(diag::err_drv_invalid_cstdlib_name)
1546 << A->getAsString(Args);
1547 cStdlibType = ToolChain::CST_System;
1548 }
1549
1550 return *cStdlibType;
1551}
1552
1553/// Utility function to add a system framework directory to CC1 arguments.
1554void ToolChain::addSystemFrameworkInclude(const llvm::opt::ArgList &DriverArgs,
1555 llvm::opt::ArgStringList &CC1Args,
1556 const Twine &Path) {
1557 CC1Args.push_back("-internal-iframework");
1558 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1559}
1560
1561/// Utility function to add a system include directory with extern "C"
1562/// semantics to CC1 arguments.
1563///
1564/// Note that this should be used rarely, and only for directories that
1565/// historically and for legacy reasons are treated as having implicit extern
1566/// "C" semantics. These semantics are *ignored* by and large today, but its
1567/// important to preserve the preprocessor changes resulting from the
1568/// classification.
1569void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
1570 ArgStringList &CC1Args,
1571 const Twine &Path) {
1572 CC1Args.push_back("-internal-externc-isystem");
1573 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1574}
1575
1576void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
1577 ArgStringList &CC1Args,
1578 const Twine &Path) {
1579 if (llvm::sys::fs::exists(Path))
1580 addExternCSystemInclude(DriverArgs, CC1Args, Path);
1581}
1582
1583/// Utility function to add a system include directory to CC1 arguments.
1584/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
1585 ArgStringList &CC1Args,
1586 const Twine &Path) {
1587 CC1Args.push_back("-internal-isystem");
1588 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1589}
1590
1591/// Utility function to add a list of system framework directories to CC1.
1592void ToolChain::addSystemFrameworkIncludes(const ArgList &DriverArgs,
1593 ArgStringList &CC1Args,
1594 ArrayRef<StringRef> Paths) {
1595 for (const auto &Path : Paths) {
1596 CC1Args.push_back("-internal-iframework");
1597 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1598 }
1599}
1600
1601/// Utility function to add a list of system include directories to CC1.
1602void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
1603 ArgStringList &CC1Args,
1604 ArrayRef<StringRef> Paths) {
1605 for (const auto &Path : Paths) {
1606 CC1Args.push_back("-internal-isystem");
1607 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1608 }
1609}
1610
1611std::string ToolChain::concat(StringRef Path, const Twine &A, const Twine &B,
1612 const Twine &C, const Twine &D) {
1614 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D);
1615 return std::string(Result);
1616}
1617
1618std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const {
1619 std::error_code EC;
1620 int MaxVersion = 0;
1621 std::string MaxVersionString;
1622 SmallString<128> Path(IncludePath);
1623 llvm::sys::path::append(Path, "c++");
1624 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
1625 !EC && LI != LE; LI = LI.increment(EC)) {
1626 StringRef VersionText = llvm::sys::path::filename(LI->path());
1627 int Version;
1628 if (VersionText[0] == 'v' &&
1629 !VersionText.substr(1).getAsInteger(10, Version)) {
1630 if (Version > MaxVersion) {
1631 MaxVersion = Version;
1632 MaxVersionString = std::string(VersionText);
1633 }
1634 }
1635 }
1636 if (!MaxVersion)
1637 return "";
1638 return MaxVersionString;
1639}
1640
1641void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1642 ArgStringList &CC1Args) const {
1643 // Header search paths should be handled by each of the subclasses.
1644 // Historically, they have not been, and instead have been handled inside of
1645 // the CC1-layer frontend. As the logic is hoisted out, this generic function
1646 // will slowly stop being called.
1647 //
1648 // While it is being called, replicate a bit of a hack to propagate the
1649 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
1650 // header search paths with it. Once all systems are overriding this
1651 // function, the CC1 flag and this line can be removed.
1652 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1653}
1654
1656 const llvm::opt::ArgList &DriverArgs,
1657 llvm::opt::ArgStringList &CC1Args) const {
1658 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1659 // This intentionally only looks at -nostdinc++, and not -nostdinc or
1660 // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain
1661 // setups with non-standard search logic for the C++ headers, while still
1662 // allowing users of the toolchain to bring their own C++ headers. Such a
1663 // toolchain likely also has non-standard search logic for the C headers and
1664 // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should
1665 // still work in that case and only be suppressed by an explicit -nostdinc++
1666 // in a project using the toolchain.
1667 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1668 for (const auto &P :
1669 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1670 addSystemInclude(DriverArgs, CC1Args, P);
1671}
1672
1673bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
1674 return getDriver().CCCIsCXX() &&
1675 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1676 options::OPT_nostdlibxx);
1677}
1678
1679void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
1680 ArgStringList &CmdArgs) const {
1681 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1682 "should not have called this");
1684
1685 switch (Type) {
1687 CmdArgs.push_back("-lc++");
1688 if (Args.hasArg(options::OPT_fexperimental_library))
1689 CmdArgs.push_back("-lc++experimental");
1690 break;
1691
1693 CmdArgs.push_back("-lstdc++");
1694 break;
1695 }
1696}
1697
1698void ToolChain::AddFilePathLibArgs(const ArgList &Args,
1699 ArgStringList &CmdArgs) const {
1700 for (const auto &LibPath : getFilePaths())
1701 if(LibPath.length() > 0)
1702 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
1703}
1704
1705void ToolChain::AddCCKextLibArgs(const ArgList &Args,
1706 ArgStringList &CmdArgs) const {
1707 CmdArgs.push_back("-lcc_kext");
1708}
1709
1711 std::string &Path) const {
1712 // Don't implicitly link in mode-changing libraries in a shared library, since
1713 // this can have very deleterious effects. See the various links from
1714 // https://github.com/llvm/llvm-project/issues/57589 for more information.
1715 bool Default = !Args.hasArgNoClaim(options::OPT_shared);
1716
1717 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
1718 // (to keep the linker options consistent with gcc and clang itself).
1719 if (Default && !isOptimizationLevelFast(Args)) {
1720 // Check if -ffast-math or -funsafe-math.
1721 Arg *A = Args.getLastArg(
1722 options::OPT_ffast_math, options::OPT_fno_fast_math,
1723 options::OPT_funsafe_math_optimizations,
1724 options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ);
1725
1726 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1727 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1728 Default = false;
1729 if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
1730 StringRef Model = A->getValue();
1731 if (Model != "fast" && Model != "aggressive")
1732 Default = false;
1733 }
1734 }
1735
1736 // Whatever decision came as a result of the above implicit settings, either
1737 // -mdaz-ftz or -mno-daz-ftz is capable of overriding it.
1738 if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default))
1739 return false;
1740
1741 // If crtfastmath.o exists add it to the arguments.
1742 Path = GetFilePath("crtfastmath.o");
1743 return (Path != "crtfastmath.o"); // Not found.
1744}
1745
1747 ArgStringList &CmdArgs) const {
1748 std::string Path;
1749 if (isFastMathRuntimeAvailable(Args, Path)) {
1750 CmdArgs.push_back(Args.MakeArgString(Path));
1751 return true;
1752 }
1753
1754 return false;
1755}
1756
1758ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const {
1759 return SmallVector<std::string>();
1760}
1761
1763 // Return sanitizers which don't require runtime support and are not
1764 // platform dependent.
1765
1766 SanitizerMask Res =
1767 (SanitizerKind::Undefined & ~SanitizerKind::Vptr) |
1768 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1769 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1770 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1771 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1772 SanitizerKind::Nullability | SanitizerKind::LocalBounds |
1773 SanitizerKind::AllocToken;
1774 if (getTriple().getArch() == llvm::Triple::x86 ||
1775 getTriple().getArch() == llvm::Triple::x86_64 ||
1776 getTriple().getArch() == llvm::Triple::arm ||
1777 getTriple().getArch() == llvm::Triple::thumb || getTriple().isWasm() ||
1778 getTriple().isAArch64() || getTriple().isRISCV() ||
1779 getTriple().isLoongArch64() ||
1780 getTriple().getArch() == llvm::Triple::hexagon)
1781 Res |= SanitizerKind::CFIICall;
1782 if (getTriple().getArch() == llvm::Triple::x86_64 ||
1783 getTriple().isAArch64(64) || getTriple().isRISCV())
1784 Res |= SanitizerKind::ShadowCallStack;
1785 if (getTriple().isAArch64(64))
1786 Res |= SanitizerKind::MemTag;
1787 if (getTriple().isBPF())
1788 Res |= SanitizerKind::KernelAddress;
1789 return Res;
1790}
1791
1792void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
1793 ArgStringList &CC1Args) const {}
1794
1795void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
1796 ArgStringList &CC1Args) const {}
1797
1798void ToolChain::addSYCLIncludeArgs(const ArgList &DriverArgs,
1799 ArgStringList &CC1Args) const {}
1800
1802ToolChain::getDeviceLibs(const ArgList &DriverArgs,
1803 const Action::OffloadKind DeviceOffloadingKind) const {
1804 return {};
1805}
1806
1807void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
1808 ArgStringList &CC1Args) const {}
1809
1810static VersionTuple separateMSVCFullVersion(unsigned Version) {
1811 if (Version < 100)
1812 return VersionTuple(Version);
1813
1814 if (Version < 10000)
1815 return VersionTuple(Version / 100, Version % 100);
1816
1817 unsigned Build = 0, Factor = 1;
1818 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1819 Build = Build + (Version % 10) * Factor;
1820 return VersionTuple(Version / 100, Version % 100, Build);
1821}
1822
1823VersionTuple
1825 const llvm::opt::ArgList &Args) const {
1826 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1827 const Arg *MSCompatibilityVersion =
1828 Args.getLastArg(options::OPT_fms_compatibility_version);
1829
1830 if (MSCVersion && MSCompatibilityVersion) {
1831 if (D)
1832 D->Diag(diag::err_drv_argument_not_allowed_with)
1833 << MSCVersion->getAsString(Args)
1834 << MSCompatibilityVersion->getAsString(Args);
1835 return VersionTuple();
1836 }
1837
1838 if (MSCompatibilityVersion) {
1839 VersionTuple MSVT;
1840 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1841 if (D)
1842 D->Diag(diag::err_drv_invalid_value)
1843 << MSCompatibilityVersion->getAsString(Args)
1844 << MSCompatibilityVersion->getValue();
1845 } else {
1846 return MSVT;
1847 }
1848 }
1849
1850 if (MSCVersion) {
1851 unsigned Version = 0;
1852 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1853 if (D)
1854 D->Diag(diag::err_drv_invalid_value)
1855 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1856 } else {
1857 return separateMSVCFullVersion(Version);
1858 }
1859 }
1860
1861 return VersionTuple();
1862}
1863
1864llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
1865 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
1866 SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const {
1867 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1868 const OptTable &Opts = getDriver().getOpts();
1869 bool Modified = false;
1870
1871 // Handle -Xopenmp-target flags
1872 for (auto *A : Args) {
1873 // Exclude flags which may only apply to the host toolchain.
1874 // Do not exclude flags when the host triple (AuxTriple)
1875 // matches the current toolchain triple. If it is not present
1876 // at all, target and host share a toolchain.
1877 if (A->getOption().matches(options::OPT_m_Group)) {
1878 // Pass certain options to the device toolchain even when the triple
1879 // differs from the host: code object version must be passed to correctly
1880 // set metadata in intermediate files; linker version must be passed
1881 // because the Darwin toolchain requires the host and device linker
1882 // versions to match (the host version is cached in
1883 // MachO::getLinkerVersion).
1884 if (SameTripleAsHost ||
1885 A->getOption().matches(options::OPT_mcode_object_version_EQ) ||
1886 A->getOption().matches(options::OPT_mlinker_version_EQ))
1887 DAL->append(A);
1888 else
1889 Modified = true;
1890 continue;
1891 }
1892
1893 unsigned Index;
1894 unsigned Prev;
1895 bool XOpenMPTargetNoTriple =
1896 A->getOption().matches(options::OPT_Xopenmp_target);
1897
1898 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1899 llvm::Triple TT = normalizeOffloadTriple(A->getValue(0));
1900
1901 // Passing device args: -Xopenmp-target=<triple> -opt=val.
1902 if (TT.isCompatibleWith(getTriple()))
1903 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1904 else
1905 continue;
1906 } else if (XOpenMPTargetNoTriple) {
1907 // Passing device args: -Xopenmp-target -opt=val.
1908 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1909 } else {
1910 DAL->append(A);
1911 continue;
1912 }
1913
1914 // Parse the argument to -Xopenmp-target.
1915 Prev = Index;
1916 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1917 if (!XOpenMPTargetArg || Index > Prev + 1) {
1918 if (!A->isClaimed()) {
1919 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1920 << A->getAsString(Args);
1921 }
1922 continue;
1923 }
1924 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1925 Args.getAllArgValues(options::OPT_offload_targets_EQ).size() != 1) {
1926 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
1927 continue;
1928 }
1929 XOpenMPTargetArg->setBaseArg(A);
1930 A = XOpenMPTargetArg.release();
1931 AllocatedArgs.push_back(A);
1932 DAL->append(A);
1933 Modified = true;
1934 }
1935
1936 if (Modified)
1937 return DAL;
1938
1939 delete DAL;
1940 return nullptr;
1941}
1942
1943// TODO: Currently argument values separated by space e.g.
1944// -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be
1945// fixed.
1947 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1948 llvm::opt::DerivedArgList *DAL,
1949 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
1950 const OptTable &Opts = getDriver().getOpts();
1951 unsigned ValuePos = 1;
1952 if (A->getOption().matches(options::OPT_Xarch_device) ||
1953 A->getOption().matches(options::OPT_Xarch_host))
1954 ValuePos = 0;
1955
1956 const InputArgList &BaseArgs = Args.getBaseArgs();
1957 unsigned Index = BaseArgs.MakeIndex(A->getValue(ValuePos));
1958 unsigned Prev = Index;
1959 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(
1960 Args, Index, llvm::opt::Visibility(options::ClangOption)));
1961
1962 // If the argument parsing failed or more than one argument was
1963 // consumed, the -Xarch_ argument's parameter tried to consume
1964 // extra arguments. Emit an error and ignore.
1965 //
1966 // We also want to disallow any options which would alter the
1967 // driver behavior; that isn't going to work in our model. We
1968 // use options::NoXarchOption to control this.
1969 if (!XarchArg || Index > Prev + 1) {
1970 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1971 << A->getAsString(Args);
1972 return;
1973 } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) {
1974 auto &Diags = getDriver().getDiags();
1975 unsigned DiagID =
1977 "invalid Xarch argument: '%0', not all driver "
1978 "options can be forwared via Xarch argument");
1979 Diags.Report(DiagID) << A->getAsString(Args);
1980 return;
1981 }
1982
1983 XarchArg->setBaseArg(A);
1984 A = XarchArg.release();
1985
1986 // Linker input arguments require custom handling. The problem is that we
1987 // have already constructed the phase actions, so we can not treat them as
1988 // "input arguments".
1989 if (A->getOption().hasFlag(options::LinkerInput)) {
1990 // Convert the argument into individual Zlinker_input_args. Need to do this
1991 // manually to avoid memory leaks with the allocated arguments.
1992 for (const char *Value : A->getValues()) {
1993 auto Opt = Opts.getOption(options::OPT_Zlinker_input);
1994 unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
1995 auto NewArg =
1996 new Arg(Opt, BaseArgs.MakeArgString(Opt.getPrefix() + Opt.getName()),
1997 Index, BaseArgs.getArgString(Index + 1), A);
1998
1999 DAL->append(NewArg);
2000 if (!AllocatedArgs)
2001 DAL->AddSynthesizedArg(NewArg);
2002 else
2003 AllocatedArgs->push_back(NewArg);
2004 }
2005 }
2006
2007 if (!AllocatedArgs)
2008 DAL->AddSynthesizedArg(A);
2009 else
2010 AllocatedArgs->push_back(A);
2011}
2012
2013/// Match any triple recognized arch aliases.
2014static bool isXArchCompatibleTripleArch(const llvm::Triple &TT,
2015 StringRef XArchVal) {
2016 llvm::Triple ParsedTriple(XArchVal);
2017 return TT.getArch() == ParsedTriple.getArch() &&
2018 TT.getSubArch() == ParsedTriple.getSubArch();
2019}
2020
2021llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs(
2022 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
2024 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
2025 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
2026 bool Modified = false;
2027
2028 bool IsDevice = OFK != Action::OFK_None && OFK != Action::OFK_Host;
2029 for (Arg *A : Args) {
2030 bool NeedTrans = false;
2031 bool Skip = false;
2032 if (A->getOption().matches(options::OPT_Xarch_device)) {
2033 NeedTrans = IsDevice;
2034 Skip = !IsDevice;
2035 } else if (A->getOption().matches(options::OPT_Xarch_host)) {
2036 NeedTrans = !IsDevice;
2037 Skip = IsDevice;
2038 } else if (A->getOption().matches(options::OPT_Xarch__)) {
2039 StringRef Val = A->getValue();
2040 NeedTrans = Val == getArchName() ||
2041 (!BoundArch.empty() && Val == BoundArch) ||
2042 isXArchCompatibleTripleArch(Triple, Val);
2043 Skip = !NeedTrans;
2044 }
2045 if (NeedTrans || Skip)
2046 Modified = true;
2047 if (NeedTrans) {
2048 A->claim();
2049 TranslateXarchArgs(Args, A, DAL, AllocatedArgs);
2050 }
2051 if (!Skip)
2052 DAL->append(A);
2053 }
2054
2055 if (Modified)
2056 return DAL;
2057
2058 delete DAL;
2059 return nullptr;
2060}
Result
Implement __builtin_bit_cast and related operations.
Defines types useful for describing an Objective-C runtime.
Defines the clang::SanitizerKind enum.
static void processMultilibCustomFlags(Multilib::flags_list &List, const llvm::opt::ArgList &Args)
static const DriverSuffix * parseDriverSuffix(StringRef ProgName, size_t &Pos)
static void getAArch64MultilibFlags(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, Multilib::flags_list &Result)
static std::string normalizeProgramName(llvm::StringRef Argv0)
Normalize the program name from argv[0] by stripping the file extension if present and lower-casing t...
static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, const ArgList &Args)
static void getRISCVMultilibFlags(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, Multilib::flags_list &Result, bool hasShadowCallStack)
static VersionTuple separateMSVCFullVersion(unsigned Version)
static const DriverSuffix * FindDriverSuffix(StringRef ProgName, size_t &Pos)
static ToolChain::ExceptionsMode CalculateExceptionsMode(const ArgList &Args)
Definition ToolChain.cpp:83
static llvm::opt::Arg * GetRTTIArgument(const ArgList &Args)
Definition ToolChain.cpp:62
static bool isXArchCompatibleTripleArch(const llvm::Triple &TT, StringRef XArchVal)
Match any triple recognized arch aliases.
static void getARMMultilibFlags(const Driver &D, const llvm::Triple &Triple, llvm::Reloc::Model RelocationModel, const llvm::opt::ArgList &Args, Multilib::flags_list &Result)
static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args, const llvm::Triple &Triple, const Arg *CachedRTTIArg)
Definition ToolChain.cpp:67
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition Diagnostic.h:914
The basic abstraction for the target Objective-C runtime.
Definition ObjCRuntime.h:28
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
Definition ObjCRuntime.h:56
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
Definition ObjCRuntime.h:53
The base class of the type hierarchy.
Definition TypeBase.h:1871
ActionClass getKind() const
Definition Action.h:152
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition Driver.h:99
DiagnosticsEngine & getDiags() const
Definition Driver.h:419
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
Definition Driver.cpp:887
DiagnosticBuilder Diag(unsigned DiagID) const
Definition Driver.h:169
StringRef getFlangF128MathLibrary() const
Definition Driver.h:463
const llvm::opt::OptTable & getOpts() const
Definition Driver.h:417
llvm::vfs::FileSystem & getVFS() const
Definition Driver.h:421
@ OMPRT_OMP
The LLVM OpenMP runtime.
Definition Driver.h:155
StringRef getPreferredLinker() const
Definition Driver.h:445
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition Driver.h:232
InputInfo - Wrapper for information about an input source.
Definition InputInfo.h:22
const char * getFilename() const
Definition InputInfo.h:83
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
Definition Multilib.cpp:479
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition Multilib.h:35
std::vector< std::string > flags_list
Definition Multilib.h:37
ToolChain - Access to tools for a single platform.
Definition ToolChain.h:92
static void normalizeOffloadTriple(llvm::Triple &TT)
Definition ToolChain.h:868
virtual bool isFastMathRuntimeAvailable(const llvm::opt::ArgList &Args, std::string &Path) const
If a runtime library exists that sets global flags for unsafe floating point math,...
virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddCCKextLibArgs - Add the system specific linker arguments to use for kernel extensions (Darwin-spec...
virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const
Add warning options that need to be passed to cc1 for this target.
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
virtual CStdlibType GetCStdlibType(const llvm::opt::ArgList &Args) const
virtual std::string computeSysRoot() const
Return the sysroot, possibly searching for a default sysroot using target-specific logic.
virtual bool useIntegratedAs() const
Check if the toolchain should use the integrated assembler.
virtual llvm::opt::DerivedArgList * TranslateOpenMPTargetArgs(const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost, SmallVectorImpl< llvm::opt::Arg * > &AllocatedArgs) const
TranslateOpenMPTargetArgs - Create a new derived argument list for that contains the OpenMP target sp...
std::optional< std::string > getStdlibPath() const
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
virtual UnwindTableLevel getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const
How detailed should the unwind tables be by default.
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const
Returns if the C++ standard library should be linked in.
static void addSystemFrameworkIncludes(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, ArrayRef< StringRef > Paths)
Utility function to add a list of system framework directories to CC1.
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory with extern "C" semantics to CC1 arguments.
virtual std::string getInputFilename(const InputInfo &Input) const
Some toolchains need to modify the file name, for example to replace the extension for object files w...
virtual Tool * buildStaticLibTool() const
virtual bool IsIntegratedBackendSupported() const
IsIntegratedBackendSupported - Does this tool chain support -fintegrated-objemitter.
Definition ToolChain.h:465
virtual void addFortranRuntimeLibraryPath(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Adds the path for the Fortran runtime libraries to CmdArgs.
std::optional< std::string > findMultilibsYAML(const llvm::opt::ArgList &Args, const Driver &D, StringRef FallbackDir={})
Load multilib configuration from a YAML file at MultilibPath,.
std::string GetFilePath(const char *Name) const
virtual void addFortranRuntimeLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Adds Fortran runtime libraries to CmdArgs.
path_list & getFilePaths()
Definition ToolChain.h:317
virtual Tool * SelectTool(const JobAction &JA) const
Choose a tool to use to handle the action JA.
static bool needsProfileRT(const llvm::opt::ArgList &Args)
needsProfileRT - returns true if instrumentation profile is on.
StringRef getOS() const
Definition ToolChain.h:296
virtual bool isBareMetal() const
isBareMetal - Is this a bare metal target.
Definition ToolChain.h:673
virtual bool isThreadModelSupported(const StringRef Model) const
isThreadModelSupported() - Does this target support a thread model?
llvm::Triple::ArchType getArch() const
Definition ToolChain.h:293
const Driver & getDriver() const
Definition ToolChain.h:277
virtual std::string detectLibcxxVersion(StringRef IncludePath) const
static std::string concat(StringRef Path, const Twine &A, const Twine &B="", const Twine &C="", const Twine &D="")
RTTIMode getRTTIMode() const
Definition ToolChain.h:349
ExceptionsMode getExceptionsMode() const
Definition ToolChain.h:352
llvm::vfs::FileSystem & getVFS() const
Multilib::flags_list getMultilibFlags(const llvm::opt::ArgList &) const
Get flags suitable for multilib selection, based on the provided clang command line arguments.
static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args)
Returns true if gcov instrumentation (-fprofile-arcs or –coverage) is on.
bool loadMultilibsFromYAML(const llvm::opt::ArgList &Args, const Driver &D, StringRef Fallback={})
Discover and load a multilib.yaml configuration.
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static, bool IsFortran=false) const
ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition ToolChain.cpp:91
static void addSystemFrameworkInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system framework directory to CC1 arguments.
SmallVector< std::string > MultilibMacroDefines
Definition ToolChain.h:209
void AddClangCXXStdlibIsystemArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
AddClangCXXStdlibIsystemArgs - Add the clang -cc1 level arguments to set the specified include paths ...
bool addFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddFastMathRuntimeIfAvailable - If a runtime library exists that sets global flags for unsafe floatin...
static void addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
virtual bool useIntegratedBackend() const
Check if the toolchain should use the integrated backend.
std::string GetStaticLibToolPath() const
Returns the linker path for emitting a static library.
virtual llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const
GetExceptionModel - Return the tool chain exception model.
virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName)
Return any implicit target and/or mode flag for an invocation of the compiler driver as ProgName.
virtual bool IsIntegratedBackendDefault() const
IsIntegratedBackendDefault - Does this tool chain enable -fintegrated-objemitter by default.
Definition ToolChain.h:461
virtual const char * getDefaultLinker() const
GetDefaultLinker - Get the default linker to use.
Definition ToolChain.h:516
virtual Tool * buildLinker() const
const llvm::Triple & getTriple() const
Definition ToolChain.h:279
bool defaultToIEEELongDouble() const
Check whether use IEEE binary128 as long double format by default.
virtual types::ID LookupTypeForExtension(StringRef Ext) const
LookupTypeForExtension - Return the default language type to use for the given extension.
virtual bool HasNativeLLVMSupport() const
HasNativeLTOLinker - Check whether the linker and related tools have native LLVM support.
virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const
void addFlangRTLibPath(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Add the path for libflang_rt.runtime.a.
std::optional< std::string > getTargetSubDirPath(StringRef BaseDir) const
Find the target-specific subdirectory for the current target triple under BaseDir,...
virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass a suitable profile runtime ...
const XRayArgs getXRayArgs(const llvm::opt::ArgList &) const
virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use system-specific CUDA includes.
OrderedMultilibs getOrderedMultilibs() const
Get selected multilibs in priority order with default fallback.
llvm::iterator_range< llvm::SmallVector< Multilib >::const_reverse_iterator > OrderedMultilibs
Definition ToolChain.h:211
StringRef getTripleString() const
Definition ToolChain.h:302
virtual std::string getCompilerRTPath() const
llvm::Triple getTripleWithoutOSVersion() const
std::string GetLinkerPath(bool *LinkerIsLLD=nullptr) const
Returns the linker path, respecting the -fuse-ld= argument to determine the linker suffix or name.
virtual std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args, StringRef Component, FileType Type, bool AddArch, bool IsFortran=false) const
virtual Expected< SmallVector< std::string > > getSystemGPUArchs(const llvm::opt::ArgList &Args) const
getSystemGPUArchs - Use a tool to detect the user's availible GPUs.
std::string GetProgramPath(const char *Name) const
static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, ArrayRef< StringRef > Paths)
Utility function to add a list of system include directories to CC1.
virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use system-specific HIP includes.
virtual void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
virtual VersionTuple computeMSVCVersion(const Driver *D, const llvm::opt::ArgList &Args) const
On Windows, returns the MSVC compatibility version.
virtual void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use system-specific SYCL includes.
virtual StringRef getOSLibName() const
virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use MCU GCC toolchain includes.
virtual CXXStdlibType GetDefaultCXXStdlibType() const
Definition ToolChain.h:523
std::optional< std::string > getStdlibIncludePath() const
virtual void AddFilePathLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option.
virtual RuntimeLibType GetDefaultRuntimeLibType() const
GetDefaultRuntimeLibType - Get the default runtime library variant to use.
Definition ToolChain.h:519
StringRef getDefaultUniversalArchName() const
Provide the default architecture name (as expected by -arch) for this toolchain.
virtual Tool * buildAssembler() const
void setTripleEnvironment(llvm::Triple::EnvironmentType Env)
virtual void addClangCC1ASTargetOptions(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1ASArgs) const
Add options that need to be passed to cc1as for this target.
virtual bool IsIntegratedAssemblerDefault() const
IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as by default.
Definition ToolChain.h:457
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
virtual llvm::SmallVector< BitCodeLibraryInfo, 12 > getDeviceLibs(const llvm::opt::ArgList &Args, const Action::OffloadKind DeviceOffloadingKind) const
Get paths for device libraries.
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
llvm::SmallVector< Multilib > SelectedMultilibs
Definition ToolChain.h:208
virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const
Add options that need to be passed to cc1 for this target.
path_list & getLibraryPaths()
Definition ToolChain.h:314
virtual void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add the clang cc1 arguments for system include paths.
virtual UnwindLibType GetDefaultUnwindLibType() const
Definition ToolChain.h:527
std::optional< std::string > getRuntimePath() const
virtual Tool * getTool(Action::ActionClass AC) const
virtual std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, StringRef BoundArch={}, types::ID InputType=types::TY_INVALID) const
ComputeEffectiveClangTriple - Return the Clang triple to use for this target, which may take into acc...
const char * getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static, bool IsFortran=false) const
virtual std::string ComputeLLVMTriple(const llvm::opt::ArgList &Args, StringRef BoundArch={}, types::ID InputType=types::TY_INVALID) const
ComputeLLVMTriple - Return the LLVM target triple to use, after taking command line arguments into ac...
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
friend class RegisterEffectiveTriple
Definition ToolChain.h:145
virtual path_list getArchSpecificLibPaths() const
virtual bool isCrossCompiling() const
Returns true if the toolchain is targeting a non-native architecture.
std::string getCompilerRTBasename(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
virtual bool IsNonIntegratedBackendSupported() const
IsNonIntegratedBackendSupported - Does this tool chain support -fno-integrated-objemitter.
Definition ToolChain.h:469
virtual void TranslateXarchArgs(const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A, llvm::opt::DerivedArgList *DAL, SmallVectorImpl< llvm::opt::Arg * > *AllocatedArgs=nullptr) const
Append the argument following A to DAL assuming A is an Xarch argument.
virtual bool useRelaxRelocations() const
Check whether to enable x86 relax relocations by default.
StringRef getArchName() const
Definition ToolChain.h:294
SmallVector< std::string, 16 > path_list
Definition ToolChain.h:94
virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const
getDefaultObjCRuntime - Return the default Objective-C runtime for this platform.
Tool - Information on a specific compilation tool.
Definition Tool.h:32
Clang integrated assembler tool.
Definition Clang.h:122
Clang compiler tool.
Definition Clang.h:28
Flang compiler tool.
Definition Flang.h:25
void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, types::ID InputType, llvm::Triple &Triple)
void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features, bool ForAS, bool ForMultilib=false)
void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, types::ID InputType, llvm::Triple &Triple)
void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple)
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args)
llvm::ARM::FPUKind getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features, bool ForAS, bool ForMultilib=false)
std::string getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition RISCV.cpp:239
StringRef getRISCVABI(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
SmallVector< StringRef > unifyTargetFeatures(ArrayRef< StringRef > Features)
If there are multiple +xxx or -xxx features, keep the last one.
void addAsNeededOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool as_needed)
std::tuple< llvm::Reloc::Model, unsigned, bool > ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args)
void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
Definition Types.cpp:309
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
The JSON file list parser is used to communicate input to InstallAPI.
@ Link
'link' clause, allowed on 'declare' construct.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
Helper structure used to pass information extracted from clang executable name such as i686-linux-and...
Definition ToolChain.h:65