clang 17.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
10#include "ToolChains/Arch/ARM.h"
11#include "ToolChains/Clang.h"
12#include "ToolChains/Flang.h"
16#include "clang/Config/config.h"
17#include "clang/Driver/Action.h"
18#include "clang/Driver/Driver.h"
21#include "clang/Driver/Job.h"
25#include "llvm/ADT/STLExtras.h"
26#include "llvm/ADT/SmallString.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/Twine.h"
29#include "llvm/Config/llvm-config.h"
30#include "llvm/MC/MCTargetOptions.h"
31#include "llvm/MC/TargetRegistry.h"
32#include "llvm/Option/Arg.h"
33#include "llvm/Option/ArgList.h"
34#include "llvm/Option/OptTable.h"
35#include "llvm/Option/Option.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/FileSystem.h"
38#include "llvm/Support/FileUtilities.h"
39#include "llvm/Support/Path.h"
40#include "llvm/Support/VersionTuple.h"
41#include "llvm/Support/VirtualFileSystem.h"
42#include "llvm/TargetParser/TargetParser.h"
43#include "llvm/TargetParser/Triple.h"
44#include <cassert>
45#include <cstddef>
46#include <cstring>
47#include <string>
48
49using namespace clang;
50using namespace driver;
51using namespace tools;
52using namespace llvm;
53using namespace llvm::opt;
54
55static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
56 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
57 options::OPT_fno_rtti, options::OPT_frtti);
58}
59
60static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
61 const llvm::Triple &Triple,
62 const Arg *CachedRTTIArg) {
63 // Explicit rtti/no-rtti args
64 if (CachedRTTIArg) {
65 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
67 else
69 }
70
71 // -frtti is default, except for the PS4/PS5 and DriverKit.
72 bool NoRTTI = Triple.isPS() || Triple.isDriverKit();
74}
75
76ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
77 const ArgList &Args)
78 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
79 CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
80 auto addIfExists = [this](path_list &List, const std::string &Path) {
81 if (getVFS().exists(Path))
82 List.push_back(Path);
83 };
84
85 for (const auto &Path : getRuntimePaths())
86 addIfExists(getLibraryPaths(), Path);
87 for (const auto &Path : getStdlibPaths())
88 addIfExists(getFilePaths(), Path);
89 addIfExists(getFilePaths(), getArchSpecificLibPath());
90}
91
93ToolChain::executeToolChainProgram(StringRef Executable) const {
94 llvm::SmallString<64> OutputFile;
95 llvm::sys::fs::createTemporaryFile("toolchain-program", "txt", OutputFile);
96 llvm::FileRemover OutputRemover(OutputFile.c_str());
97 std::optional<llvm::StringRef> Redirects[] = {
98 {""},
99 OutputFile.str(),
100 {""},
101 };
102
103 std::string ErrorMessage;
104 if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects,
105 /* SecondsToWait */ 0,
106 /*MemoryLimit*/ 0, &ErrorMessage))
107 return llvm::createStringError(std::error_code(),
108 Executable + ": " + ErrorMessage);
109
110 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
111 llvm::MemoryBuffer::getFile(OutputFile.c_str());
112 if (!OutputBuf)
113 return llvm::createStringError(OutputBuf.getError(),
114 "Failed to read stdout of " + Executable +
115 ": " + OutputBuf.getError().message());
116 return std::move(*OutputBuf);
117}
118
119void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) {
120 Triple.setEnvironment(Env);
121 if (EffectiveTriple != llvm::Triple())
122 EffectiveTriple.setEnvironment(Env);
123}
124
125ToolChain::~ToolChain() = default;
126
127llvm::vfs::FileSystem &ToolChain::getVFS() const {
128 return getDriver().getVFS();
129}
130
132 return Args.hasFlag(options::OPT_fintegrated_as,
133 options::OPT_fno_integrated_as,
135}
136
138 assert(
141 "(Non-)integrated backend set incorrectly!");
142
143 bool IBackend = Args.hasFlag(options::OPT_fintegrated_objemitter,
144 options::OPT_fno_integrated_objemitter,
146
147 // Diagnose when integrated-objemitter options are not supported by this
148 // toolchain.
149 unsigned DiagID;
150 if ((IBackend && !IsIntegratedBackendSupported()) ||
151 (!IBackend && !IsNonIntegratedBackendSupported()))
152 DiagID = clang::diag::err_drv_unsupported_opt_for_target;
153 else
154 DiagID = clang::diag::warn_drv_unsupported_opt_for_target;
155 Arg *A = Args.getLastArg(options::OPT_fno_integrated_objemitter);
157 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
158 A = Args.getLastArg(options::OPT_fintegrated_objemitter);
160 D.Diag(DiagID) << A->getAsString(Args) << Triple.getTriple();
161
162 return IBackend;
163}
164
166 return ENABLE_X86_RELAX_RELOCATIONS;
167}
168
170 return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
171}
172
174ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const {
175 SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);
176 SanitizerArgsChecked = true;
177 return SanArgs;
178}
179
181 if (!XRayArguments)
182 XRayArguments.reset(new XRayArgs(*this, Args));
183 return *XRayArguments;
184}
185
186namespace {
187
188struct DriverSuffix {
189 const char *Suffix;
190 const char *ModeFlag;
191};
192
193} // namespace
194
195static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
196 // A list of known driver suffixes. Suffixes are compared against the
197 // program name in order. If there is a match, the frontend type is updated as
198 // necessary by applying the ModeFlag.
199 static const DriverSuffix DriverSuffixes[] = {
200 {"clang", nullptr},
201 {"clang++", "--driver-mode=g++"},
202 {"clang-c++", "--driver-mode=g++"},
203 {"clang-cc", nullptr},
204 {"clang-cpp", "--driver-mode=cpp"},
205 {"clang-g++", "--driver-mode=g++"},
206 {"clang-gcc", nullptr},
207 {"clang-cl", "--driver-mode=cl"},
208 {"cc", nullptr},
209 {"cpp", "--driver-mode=cpp"},
210 {"cl", "--driver-mode=cl"},
211 {"++", "--driver-mode=g++"},
212 {"flang", "--driver-mode=flang"},
213 {"clang-dxc", "--driver-mode=dxc"},
214 };
215
216 for (const auto &DS : DriverSuffixes) {
217 StringRef Suffix(DS.Suffix);
218 if (ProgName.endswith(Suffix)) {
219 Pos = ProgName.size() - Suffix.size();
220 return &DS;
221 }
222 }
223 return nullptr;
224}
225
226/// Normalize the program name from argv[0] by stripping the file extension if
227/// present and lower-casing the string on Windows.
228static std::string normalizeProgramName(llvm::StringRef Argv0) {
229 std::string ProgName = std::string(llvm::sys::path::filename(Argv0));
230 if (is_style_windows(llvm::sys::path::Style::native)) {
231 // Transform to lowercase for case insensitive file systems.
232 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
233 ::tolower);
234 }
235 return ProgName;
236}
237
238static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
239 // Try to infer frontend type and default target from the program name by
240 // comparing it against DriverSuffixes in order.
241
242 // If there is a match, the function tries to identify a target as prefix.
243 // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
244 // prefix "x86_64-linux". If such a target prefix is found, it may be
245 // added via -target as implicit first argument.
246 const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos);
247
248 if (!DS && ProgName.endswith(".exe")) {
249 // Try again after stripping the executable suffix:
250 // clang++.exe -> clang++
251 ProgName = ProgName.drop_back(StringRef(".exe").size());
252 DS = FindDriverSuffix(ProgName, Pos);
253 }
254
255 if (!DS) {
256 // Try again after stripping any trailing version number:
257 // clang++3.5 -> clang++
258 ProgName = ProgName.rtrim("0123456789.");
259 DS = FindDriverSuffix(ProgName, Pos);
260 }
261
262 if (!DS) {
263 // Try again after stripping trailing -component.
264 // clang++-tot -> clang++
265 ProgName = ProgName.slice(0, ProgName.rfind('-'));
266 DS = FindDriverSuffix(ProgName, Pos);
267 }
268 return DS;
269}
270
273 std::string ProgName = normalizeProgramName(PN);
274 size_t SuffixPos;
275 const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos);
276 if (!DS)
277 return {};
278 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
279
280 size_t LastComponent = ProgName.rfind('-', SuffixPos);
281 if (LastComponent == std::string::npos)
282 return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);
283 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
284 SuffixEnd - LastComponent - 1);
285
286 // Infer target from the prefix.
287 StringRef Prefix(ProgName);
288 Prefix = Prefix.slice(0, LastComponent);
289 std::string IgnoredError;
290 bool IsRegistered =
291 llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
292 return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag,
293 IsRegistered};
294}
295
297 // In universal driver terms, the arch name accepted by -arch isn't exactly
298 // the same as the ones that appear in the triple. Roughly speaking, this is
299 // an inverse of the darwin::getArchTypeForDarwinArchName() function.
300 switch (Triple.getArch()) {
301 case llvm::Triple::aarch64: {
302 if (getTriple().isArm64e())
303 return "arm64e";
304 return "arm64";
305 }
306 case llvm::Triple::aarch64_32:
307 return "arm64_32";
308 case llvm::Triple::ppc:
309 return "ppc";
310 case llvm::Triple::ppcle:
311 return "ppcle";
312 case llvm::Triple::ppc64:
313 return "ppc64";
314 case llvm::Triple::ppc64le:
315 return "ppc64le";
316 default:
317 return Triple.getArchName();
318 }
319}
320
321std::string ToolChain::getInputFilename(const InputInfo &Input) const {
322 return Input.getFilename();
323}
324
326ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const {
328}
329
330Tool *ToolChain::getClang() const {
331 if (!Clang)
332 Clang.reset(new tools::Clang(*this, useIntegratedBackend()));
333 return Clang.get();
334}
335
336Tool *ToolChain::getFlang() const {
337 if (!Flang)
338 Flang.reset(new tools::Flang(*this));
339 return Flang.get();
340}
341
343 return new tools::ClangAs(*this);
344}
345
347 llvm_unreachable("Linking is not supported by this toolchain");
348}
349
351 llvm_unreachable("Creating static lib is not supported by this toolchain");
352}
353
354Tool *ToolChain::getAssemble() const {
355 if (!Assemble)
356 Assemble.reset(buildAssembler());
357 return Assemble.get();
358}
359
360Tool *ToolChain::getClangAs() const {
361 if (!Assemble)
362 Assemble.reset(new tools::ClangAs(*this));
363 return Assemble.get();
364}
365
366Tool *ToolChain::getLink() const {
367 if (!Link)
368 Link.reset(buildLinker());
369 return Link.get();
370}
371
372Tool *ToolChain::getStaticLibTool() const {
373 if (!StaticLibTool)
374 StaticLibTool.reset(buildStaticLibTool());
375 return StaticLibTool.get();
376}
377
378Tool *ToolChain::getIfsMerge() const {
379 if (!IfsMerge)
380 IfsMerge.reset(new tools::ifstool::Merger(*this));
381 return IfsMerge.get();
382}
383
384Tool *ToolChain::getOffloadBundler() const {
385 if (!OffloadBundler)
386 OffloadBundler.reset(new tools::OffloadBundler(*this));
387 return OffloadBundler.get();
388}
389
390Tool *ToolChain::getOffloadPackager() const {
391 if (!OffloadPackager)
392 OffloadPackager.reset(new tools::OffloadPackager(*this));
393 return OffloadPackager.get();
394}
395
396Tool *ToolChain::getLinkerWrapper() const {
397 if (!LinkerWrapper)
398 LinkerWrapper.reset(new tools::LinkerWrapper(*this, getLink()));
399 return LinkerWrapper.get();
400}
401
403 switch (AC) {
405 return getAssemble();
406
408 return getIfsMerge();
409
411 return getLink();
412
414 return getStaticLibTool();
415
423 llvm_unreachable("Invalid tool kind.");
424
433 return getClang();
434
437 return getOffloadBundler();
438
440 return getOffloadPackager();
442 return getLinkerWrapper();
443 }
444
445 llvm_unreachable("Invalid tool kind.");
446}
447
448static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
449 const ArgList &Args) {
450 const llvm::Triple &Triple = TC.getTriple();
451 bool IsWindows = Triple.isOSWindows();
452
453 if (TC.isBareMetal())
454 return Triple.getArchName();
455
456 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
457 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
458 ? "armhf"
459 : "arm";
460
461 // For historic reasons, Android library is using i686 instead of i386.
462 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid())
463 return "i686";
464
465 if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32())
466 return "x32";
467
468 return llvm::Triple::getArchTypeName(TC.getArch());
469}
470
471StringRef ToolChain::getOSLibName() const {
472 if (Triple.isOSDarwin())
473 return "darwin";
474
475 switch (Triple.getOS()) {
476 case llvm::Triple::FreeBSD:
477 return "freebsd";
478 case llvm::Triple::NetBSD:
479 return "netbsd";
480 case llvm::Triple::OpenBSD:
481 return "openbsd";
482 case llvm::Triple::Solaris:
483 return "sunos";
484 case llvm::Triple::AIX:
485 return "aix";
486 default:
487 return getOS();
488 }
489}
490
491std::string ToolChain::getCompilerRTPath() const {
492 SmallString<128> Path(getDriver().ResourceDir);
493 if (isBareMetal()) {
494 llvm::sys::path::append(Path, "lib", getOSLibName());
495 Path += SelectedMultilib.gccSuffix();
496 } else if (Triple.isOSUnknown()) {
497 llvm::sys::path::append(Path, "lib");
498 } else {
499 llvm::sys::path::append(Path, "lib", getOSLibName());
500 }
501 return std::string(Path.str());
502}
503
504std::string ToolChain::getCompilerRTBasename(const ArgList &Args,
505 StringRef Component,
506 FileType Type) const {
507 std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type);
508 return llvm::sys::path::filename(CRTAbsolutePath).str();
509}
510
511std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
512 StringRef Component,
514 bool AddArch) const {
515 const llvm::Triple &TT = getTriple();
516 bool IsITANMSVCWindows =
517 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
518
519 const char *Prefix =
520 IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib";
521 const char *Suffix;
522 switch (Type) {
524 Suffix = IsITANMSVCWindows ? ".obj" : ".o";
525 break;
527 Suffix = IsITANMSVCWindows ? ".lib" : ".a";
528 break;
530 Suffix = TT.isOSWindows()
531 ? (TT.isWindowsGNUEnvironment() ? ".dll.a" : ".lib")
532 : ".so";
533 break;
534 }
535
536 std::string ArchAndEnv;
537 if (AddArch) {
538 StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
539 const char *Env = TT.isAndroid() ? "-android" : "";
540 ArchAndEnv = ("-" + Arch + Env).str();
541 }
542 return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();
543}
544
545std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
546 FileType Type) const {
547 // Check for runtime files in the new layout without the architecture first.
548 std::string CRTBasename =
549 buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
550 for (const auto &LibPath : getLibraryPaths()) {
551 SmallString<128> P(LibPath);
552 llvm::sys::path::append(P, CRTBasename);
553 if (getVFS().exists(P))
554 return std::string(P.str());
555 }
556
557 // Fall back to the old expected compiler-rt name if the new one does not
558 // exist.
559 CRTBasename =
560 buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
562 llvm::sys::path::append(Path, CRTBasename);
563 return std::string(Path.str());
564}
565
566const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
567 StringRef Component,
568 FileType Type) const {
569 return Args.MakeArgString(getCompilerRT(Args, Component, Type));
570}
571
573 path_list Paths;
574 auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) {
576 llvm::sys::path::append(P, "lib", Triple.str());
577 Paths.push_back(std::string(P.str()));
578 };
579
580 addPathForTriple(getTriple());
581
582 // When building with per target runtime directories, various ways of naming
583 // the Arm architecture may have been normalised to simply "arm".
584 // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
585 // Since an armv8l system can use libraries built for earlier architecture
586 // versions assuming endian and float ABI match.
587 //
588 // Original triple: armv8l-unknown-linux-gnueabihf
589 // Runtime triple: arm-unknown-linux-gnueabihf
590 //
591 // We do not do this for armeb (big endian) because doing so could make us
592 // select little endian libraries. In addition, all known armeb triples only
593 // use the "armeb" architecture name.
594 //
595 // M profile Arm is bare metal and we know they will not be using the per
596 // target runtime directory layout.
597 if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
598 llvm::Triple ArmTriple = getTriple();
599 ArmTriple.setArch(Triple::arm);
600 addPathForTriple(ArmTriple);
601 }
602
603 // Android targets may include an API level at the end. We still want to fall
604 // back on a path without the API level.
605 if (getTriple().isAndroid() &&
606 getTriple().getEnvironmentName() != "android") {
607 llvm::Triple TripleWithoutLevel = getTriple();
608 TripleWithoutLevel.setEnvironmentName("android");
609 addPathForTriple(TripleWithoutLevel);
610 }
611
612 return Paths;
613}
614
616 path_list Paths;
618 llvm::sys::path::append(P, "..", "lib", getTripleString());
619 Paths.push_back(std::string(P.str()));
620
621 return Paths;
622}
623
625 SmallString<128> Path(getDriver().ResourceDir);
626 llvm::sys::path::append(Path, "lib", getOSLibName(),
627 llvm::Triple::getArchTypeName(getArch()));
628 return std::string(Path.str());
629}
630
631bool ToolChain::needsProfileRT(const ArgList &Args) {
632 if (Args.hasArg(options::OPT_noprofilelib))
633 return false;
634
635 return Args.hasArg(options::OPT_fprofile_generate) ||
636 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
637 Args.hasArg(options::OPT_fcs_profile_generate) ||
638 Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
639 Args.hasArg(options::OPT_fprofile_instr_generate) ||
640 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
641 Args.hasArg(options::OPT_fcreate_profile) ||
642 Args.hasArg(options::OPT_forder_file_instrumentation);
643}
644
645bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
646 return Args.hasArg(options::OPT_coverage) ||
647 Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
648 false);
649}
650
652 if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang();
653 if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
656 return getClangAs();
657 return getTool(AC);
658}
659
660std::string ToolChain::GetFilePath(const char *Name) const {
661 return D.GetFilePath(Name, *this);
662}
663
664std::string ToolChain::GetProgramPath(const char *Name) const {
665 return D.GetProgramPath(Name, *this);
666}
667
668std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
669 if (LinkerIsLLD)
670 *LinkerIsLLD = false;
671
672 // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is
673 // considered as the linker flavor, e.g. "bfd", "gold", or "lld".
674 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
675 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
676
677 // --ld-path= takes precedence over -fuse-ld= and specifies the executable
678 // name. -B, COMPILER_PATH and PATH and consulted if the value does not
679 // contain a path component separator.
680 // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary
681 // that --ld-path= points to is lld.
682 if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
683 std::string Path(A->getValue());
684 if (!Path.empty()) {
685 if (llvm::sys::path::parent_path(Path).empty())
686 Path = GetProgramPath(A->getValue());
687 if (llvm::sys::fs::can_execute(Path)) {
688 if (LinkerIsLLD)
689 *LinkerIsLLD = UseLinker == "lld";
690 return std::string(Path);
691 }
692 }
693 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
695 }
696 // If we're passed -fuse-ld= with no argument, or with the argument ld,
697 // then use whatever the default system linker is.
698 if (UseLinker.empty() || UseLinker == "ld") {
699 const char *DefaultLinker = getDefaultLinker();
700 if (llvm::sys::path::is_absolute(DefaultLinker))
701 return std::string(DefaultLinker);
702 else
703 return GetProgramPath(DefaultLinker);
704 }
705
706 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
707 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
708 // to a relative path is surprising. This is more complex due to priorities
709 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
710 if (UseLinker.contains('/'))
711 getDriver().Diag(diag::warn_drv_fuse_ld_path);
712
713 if (llvm::sys::path::is_absolute(UseLinker)) {
714 // If we're passed what looks like an absolute path, don't attempt to
715 // second-guess that.
716 if (llvm::sys::fs::can_execute(UseLinker))
717 return std::string(UseLinker);
718 } else {
719 llvm::SmallString<8> LinkerName;
720 if (Triple.isOSDarwin())
721 LinkerName.append("ld64.");
722 else
723 LinkerName.append("ld.");
724 LinkerName.append(UseLinker);
725
726 std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
727 if (llvm::sys::fs::can_execute(LinkerPath)) {
728 if (LinkerIsLLD)
729 *LinkerIsLLD = UseLinker == "lld";
730 return LinkerPath;
731 }
732 }
733
734 if (A)
735 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
736
738}
739
741 // TODO: Add support for static lib archiving on Windows
742 if (Triple.isOSDarwin())
743 return GetProgramPath("libtool");
744 return GetProgramPath("llvm-ar");
745}
746
749
750 // Flang always runs the preprocessor and has no notion of "preprocessed
751 // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
752 // them differently.
753 if (D.IsFlangMode() && id == types::TY_PP_Fortran)
754 id = types::TY_Fortran;
755
756 return id;
757}
758
760 return false;
761}
762
764 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
765 switch (HostTriple.getArch()) {
766 // The A32/T32/T16 instruction sets are not separate architectures in this
767 // context.
768 case llvm::Triple::arm:
769 case llvm::Triple::armeb:
770 case llvm::Triple::thumb:
771 case llvm::Triple::thumbeb:
772 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
773 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
774 default:
775 return HostTriple.getArch() != getArch();
776 }
777}
778
780 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
781 VersionTuple());
782}
783
784llvm::ExceptionHandling
785ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const {
786 return llvm::ExceptionHandling::None;
787}
788
789bool ToolChain::isThreadModelSupported(const StringRef Model) const {
790 if (Model == "single") {
791 // FIXME: 'single' is only supported on ARM and WebAssembly so far.
792 return Triple.getArch() == llvm::Triple::arm ||
793 Triple.getArch() == llvm::Triple::armeb ||
794 Triple.getArch() == llvm::Triple::thumb ||
795 Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
796 } else if (Model == "posix")
797 return true;
798
799 return false;
800}
801
802std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
803 types::ID InputType) const {
804 switch (getTriple().getArch()) {
805 default:
806 return getTripleString();
807
808 case llvm::Triple::x86_64: {
809 llvm::Triple Triple = getTriple();
810 if (!Triple.isOSBinFormatMachO())
811 return getTripleString();
812
813 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
814 // x86_64h goes in the triple. Other -march options just use the
815 // vanilla triple we already have.
816 StringRef MArch = A->getValue();
817 if (MArch == "x86_64h")
818 Triple.setArchName(MArch);
819 }
820 return Triple.getTriple();
821 }
822 case llvm::Triple::aarch64: {
823 llvm::Triple Triple = getTriple();
824 if (!Triple.isOSBinFormatMachO())
825 return getTripleString();
826
827 if (Triple.isArm64e())
828 return getTripleString();
829
830 // FIXME: older versions of ld64 expect the "arm64" component in the actual
831 // triple string and query it to determine whether an LTO file can be
832 // handled. Remove this when we don't care any more.
833 Triple.setArchName("arm64");
834 return Triple.getTriple();
835 }
836 case llvm::Triple::aarch64_32:
837 return getTripleString();
838 case llvm::Triple::arm:
839 case llvm::Triple::armeb:
840 case llvm::Triple::thumb:
841 case llvm::Triple::thumbeb: {
842 llvm::Triple Triple = getTriple();
843 tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple);
845 return Triple.getTriple();
846 }
847 }
848}
849
850std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
851 types::ID InputType) const {
852 return ComputeLLVMTriple(Args, InputType);
853}
854
855std::string ToolChain::computeSysRoot() const {
856 return D.SysRoot;
857}
858
859void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
860 ArgStringList &CC1Args) const {
861 // Each toolchain should provide the appropriate include flags.
862}
863
865 const ArgList &DriverArgs, ArgStringList &CC1Args,
866 Action::OffloadKind DeviceOffloadKind) const {}
867
869 ArgStringList &CC1ASArgs) const {}
870
871void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
872
873void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
874 llvm::opt::ArgStringList &CmdArgs) const {
875 if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args))
876 return;
877
878 CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
879}
880
882 const ArgList &Args) const {
883 if (runtimeLibType)
884 return *runtimeLibType;
885
886 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
887 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
888
889 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
890 if (LibName == "compiler-rt")
891 runtimeLibType = ToolChain::RLT_CompilerRT;
892 else if (LibName == "libgcc")
893 runtimeLibType = ToolChain::RLT_Libgcc;
894 else if (LibName == "platform")
895 runtimeLibType = GetDefaultRuntimeLibType();
896 else {
897 if (A)
898 getDriver().Diag(diag::err_drv_invalid_rtlib_name)
899 << A->getAsString(Args);
900
901 runtimeLibType = GetDefaultRuntimeLibType();
902 }
903
904 return *runtimeLibType;
905}
906
908 const ArgList &Args) const {
909 if (unwindLibType)
910 return *unwindLibType;
911
912 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
913 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
914
915 if (LibName == "none")
916 unwindLibType = ToolChain::UNW_None;
917 else if (LibName == "platform" || LibName == "") {
919 if (RtLibType == ToolChain::RLT_CompilerRT) {
920 if (getTriple().isAndroid() || getTriple().isOSAIX())
921 unwindLibType = ToolChain::UNW_CompilerRT;
922 else
923 unwindLibType = ToolChain::UNW_None;
924 } else if (RtLibType == ToolChain::RLT_Libgcc)
925 unwindLibType = ToolChain::UNW_Libgcc;
926 } else if (LibName == "libunwind") {
927 if (GetRuntimeLibType(Args) == RLT_Libgcc)
928 getDriver().Diag(diag::err_drv_incompatible_unwindlib);
929 unwindLibType = ToolChain::UNW_CompilerRT;
930 } else if (LibName == "libgcc")
931 unwindLibType = ToolChain::UNW_Libgcc;
932 else {
933 if (A)
934 getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
935 << A->getAsString(Args);
936
937 unwindLibType = GetDefaultUnwindLibType();
938 }
939
940 return *unwindLibType;
941}
942
944 if (cxxStdlibType)
945 return *cxxStdlibType;
946
947 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
948 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
949
950 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
951 if (LibName == "libc++")
952 cxxStdlibType = ToolChain::CST_Libcxx;
953 else if (LibName == "libstdc++")
954 cxxStdlibType = ToolChain::CST_Libstdcxx;
955 else if (LibName == "platform")
956 cxxStdlibType = GetDefaultCXXStdlibType();
957 else {
958 if (A)
959 getDriver().Diag(diag::err_drv_invalid_stdlib_name)
960 << A->getAsString(Args);
961
962 cxxStdlibType = GetDefaultCXXStdlibType();
963 }
964
965 return *cxxStdlibType;
966}
967
968/// Utility function to add a system include directory to CC1 arguments.
969/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
970 ArgStringList &CC1Args,
971 const Twine &Path) {
972 CC1Args.push_back("-internal-isystem");
973 CC1Args.push_back(DriverArgs.MakeArgString(Path));
974}
975
976/// Utility function to add a system include directory with extern "C"
977/// semantics to CC1 arguments.
978///
979/// Note that this should be used rarely, and only for directories that
980/// historically and for legacy reasons are treated as having implicit extern
981/// "C" semantics. These semantics are *ignored* by and large today, but its
982/// important to preserve the preprocessor changes resulting from the
983/// classification.
984/*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
985 ArgStringList &CC1Args,
986 const Twine &Path) {
987 CC1Args.push_back("-internal-externc-isystem");
988 CC1Args.push_back(DriverArgs.MakeArgString(Path));
989}
990
991void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
992 ArgStringList &CC1Args,
993 const Twine &Path) {
994 if (llvm::sys::fs::exists(Path))
995 addExternCSystemInclude(DriverArgs, CC1Args, Path);
996}
997
998/// Utility function to add a list of system include directories to CC1.
999/*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
1000 ArgStringList &CC1Args,
1001 ArrayRef<StringRef> Paths) {
1002 for (const auto &Path : Paths) {
1003 CC1Args.push_back("-internal-isystem");
1004 CC1Args.push_back(DriverArgs.MakeArgString(Path));
1005 }
1006}
1007
1008/*static*/ std::string ToolChain::concat(StringRef Path, const Twine &A,
1009 const Twine &B, const Twine &C,
1010 const Twine &D) {
1012 llvm::sys::path::append(Result, llvm::sys::path::Style::posix, A, B, C, D);
1013 return std::string(Result);
1014}
1015
1016std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const {
1017 std::error_code EC;
1018 int MaxVersion = 0;
1019 std::string MaxVersionString;
1020 SmallString<128> Path(IncludePath);
1021 llvm::sys::path::append(Path, "c++");
1022 for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
1023 !EC && LI != LE; LI = LI.increment(EC)) {
1024 StringRef VersionText = llvm::sys::path::filename(LI->path());
1025 int Version;
1026 if (VersionText[0] == 'v' &&
1027 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
1028 if (Version > MaxVersion) {
1029 MaxVersion = Version;
1030 MaxVersionString = std::string(VersionText);
1031 }
1032 }
1033 }
1034 if (!MaxVersion)
1035 return "";
1036 return MaxVersionString;
1037}
1038
1039void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1040 ArgStringList &CC1Args) const {
1041 // Header search paths should be handled by each of the subclasses.
1042 // Historically, they have not been, and instead have been handled inside of
1043 // the CC1-layer frontend. As the logic is hoisted out, this generic function
1044 // will slowly stop being called.
1045 //
1046 // While it is being called, replicate a bit of a hack to propagate the
1047 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
1048 // header search paths with it. Once all systems are overriding this
1049 // function, the CC1 flag and this line can be removed.
1050 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
1051}
1052
1054 const llvm::opt::ArgList &DriverArgs,
1055 llvm::opt::ArgStringList &CC1Args) const {
1056 DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
1057 // This intentionally only looks at -nostdinc++, and not -nostdinc or
1058 // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain
1059 // setups with non-standard search logic for the C++ headers, while still
1060 // allowing users of the toolchain to bring their own C++ headers. Such a
1061 // toolchain likely also has non-standard search logic for the C headers and
1062 // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should
1063 // still work in that case and only be suppressed by an explicit -nostdinc++
1064 // in a project using the toolchain.
1065 if (!DriverArgs.hasArg(options::OPT_nostdincxx))
1066 for (const auto &P :
1067 DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
1068 addSystemInclude(DriverArgs, CC1Args, P);
1069}
1070
1071bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
1072 return getDriver().CCCIsCXX() &&
1073 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1074 options::OPT_nostdlibxx);
1075}
1076
1077void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
1078 ArgStringList &CmdArgs) const {
1079 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1080 "should not have called this");
1082
1083 switch (Type) {
1085 CmdArgs.push_back("-lc++");
1086 if (Args.hasArg(options::OPT_fexperimental_library))
1087 CmdArgs.push_back("-lc++experimental");
1088 break;
1089
1091 CmdArgs.push_back("-lstdc++");
1092 break;
1093 }
1094}
1095
1096void ToolChain::AddFilePathLibArgs(const ArgList &Args,
1097 ArgStringList &CmdArgs) const {
1098 for (const auto &LibPath : getFilePaths())
1099 if(LibPath.length() > 0)
1100 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
1101}
1102
1103void ToolChain::AddCCKextLibArgs(const ArgList &Args,
1104 ArgStringList &CmdArgs) const {
1105 CmdArgs.push_back("-lcc_kext");
1106}
1107
1109 std::string &Path) const {
1110 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
1111 // (to keep the linker options consistent with gcc and clang itself).
1112 if (!isOptimizationLevelFast(Args)) {
1113 // Check if -ffast-math or -funsafe-math.
1114 Arg *A =
1115 Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
1116 options::OPT_funsafe_math_optimizations,
1117 options::OPT_fno_unsafe_math_optimizations);
1118
1119 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
1120 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1121 return false;
1122 }
1123 // If crtfastmath.o exists add it to the arguments.
1124 Path = GetFilePath("crtfastmath.o");
1125 return (Path != "crtfastmath.o"); // Not found.
1126}
1127
1129 ArgStringList &CmdArgs) const {
1130 std::string Path;
1131 if (isFastMathRuntimeAvailable(Args, Path)) {
1132 CmdArgs.push_back(Args.MakeArgString(Path));
1133 return true;
1134 }
1135
1136 return false;
1137}
1138
1140ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const {
1141 return SmallVector<std::string>();
1142}
1143
1145 // Return sanitizers which don't require runtime support and are not
1146 // platform dependent.
1147
1148 SanitizerMask Res =
1149 (SanitizerKind::Undefined & ~SanitizerKind::Vptr &
1150 ~SanitizerKind::Function) |
1151 (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1152 SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1153 SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow |
1154 SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1155 SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1156 if (getTriple().getArch() == llvm::Triple::x86 ||
1157 getTriple().getArch() == llvm::Triple::x86_64 ||
1158 getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() ||
1159 getTriple().isAArch64() || getTriple().isRISCV())
1160 Res |= SanitizerKind::CFIICall;
1161 if (getTriple().getArch() == llvm::Triple::x86_64 ||
1162 getTriple().isAArch64(64) || getTriple().isRISCV())
1163 Res |= SanitizerKind::ShadowCallStack;
1164 if (getTriple().isAArch64(64))
1165 Res |= SanitizerKind::MemTag;
1166 return Res;
1167}
1168
1169void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
1170 ArgStringList &CC1Args) const {}
1171
1172void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
1173 ArgStringList &CC1Args) const {}
1174
1176ToolChain::getDeviceLibs(const ArgList &DriverArgs) const {
1177 return {};
1178}
1179
1180void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
1181 ArgStringList &CC1Args) const {}
1182
1183static VersionTuple separateMSVCFullVersion(unsigned Version) {
1184 if (Version < 100)
1185 return VersionTuple(Version);
1186
1187 if (Version < 10000)
1188 return VersionTuple(Version / 100, Version % 100);
1189
1190 unsigned Build = 0, Factor = 1;
1191 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
1192 Build = Build + (Version % 10) * Factor;
1193 return VersionTuple(Version / 100, Version % 100, Build);
1194}
1195
1196VersionTuple
1198 const llvm::opt::ArgList &Args) const {
1199 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1200 const Arg *MSCompatibilityVersion =
1201 Args.getLastArg(options::OPT_fms_compatibility_version);
1202
1203 if (MSCVersion && MSCompatibilityVersion) {
1204 if (D)
1205 D->Diag(diag::err_drv_argument_not_allowed_with)
1206 << MSCVersion->getAsString(Args)
1207 << MSCompatibilityVersion->getAsString(Args);
1208 return VersionTuple();
1209 }
1210
1211 if (MSCompatibilityVersion) {
1212 VersionTuple MSVT;
1213 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1214 if (D)
1215 D->Diag(diag::err_drv_invalid_value)
1216 << MSCompatibilityVersion->getAsString(Args)
1217 << MSCompatibilityVersion->getValue();
1218 } else {
1219 return MSVT;
1220 }
1221 }
1222
1223 if (MSCVersion) {
1224 unsigned Version = 0;
1225 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1226 if (D)
1227 D->Diag(diag::err_drv_invalid_value)
1228 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1229 } else {
1230 return separateMSVCFullVersion(Version);
1231 }
1232 }
1233
1234 return VersionTuple();
1235}
1236
1237llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
1238 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
1239 SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const {
1240 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1241 const OptTable &Opts = getDriver().getOpts();
1242 bool Modified = false;
1243
1244 // Handle -Xopenmp-target flags
1245 for (auto *A : Args) {
1246 // Exclude flags which may only apply to the host toolchain.
1247 // Do not exclude flags when the host triple (AuxTriple)
1248 // matches the current toolchain triple. If it is not present
1249 // at all, target and host share a toolchain.
1250 if (A->getOption().matches(options::OPT_m_Group)) {
1251 if (SameTripleAsHost)
1252 DAL->append(A);
1253 else
1254 Modified = true;
1255 continue;
1256 }
1257
1258 unsigned Index;
1259 unsigned Prev;
1260 bool XOpenMPTargetNoTriple =
1261 A->getOption().matches(options::OPT_Xopenmp_target);
1262
1263 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1264 llvm::Triple TT(getOpenMPTriple(A->getValue(0)));
1265
1266 // Passing device args: -Xopenmp-target=<triple> -opt=val.
1267 if (TT.getTriple() == getTripleString())
1268 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1269 else
1270 continue;
1271 } else if (XOpenMPTargetNoTriple) {
1272 // Passing device args: -Xopenmp-target -opt=val.
1273 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1274 } else {
1275 DAL->append(A);
1276 continue;
1277 }
1278
1279 // Parse the argument to -Xopenmp-target.
1280 Prev = Index;
1281 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1282 if (!XOpenMPTargetArg || Index > Prev + 1) {
1283 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1284 << A->getAsString(Args);
1285 continue;
1286 }
1287 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
1288 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
1289 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
1290 continue;
1291 }
1292 XOpenMPTargetArg->setBaseArg(A);
1293 A = XOpenMPTargetArg.release();
1294 AllocatedArgs.push_back(A);
1295 DAL->append(A);
1296 Modified = true;
1297 }
1298
1299 if (Modified)
1300 return DAL;
1301
1302 delete DAL;
1303 return nullptr;
1304}
1305
1306// TODO: Currently argument values separated by space e.g.
1307// -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be
1308// fixed.
1310 const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1311 llvm::opt::DerivedArgList *DAL,
1312 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
1313 const OptTable &Opts = getDriver().getOpts();
1314 unsigned ValuePos = 1;
1315 if (A->getOption().matches(options::OPT_Xarch_device) ||
1316 A->getOption().matches(options::OPT_Xarch_host))
1317 ValuePos = 0;
1318
1319 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
1320 unsigned Prev = Index;
1321 std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index));
1322
1323 // If the argument parsing failed or more than one argument was
1324 // consumed, the -Xarch_ argument's parameter tried to consume
1325 // extra arguments. Emit an error and ignore.
1326 //
1327 // We also want to disallow any options which would alter the
1328 // driver behavior; that isn't going to work in our model. We
1329 // use options::NoXarchOption to control this.
1330 if (!XarchArg || Index > Prev + 1) {
1331 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1332 << A->getAsString(Args);
1333 return;
1334 } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) {
1335 auto &Diags = getDriver().getDiags();
1336 unsigned DiagID =
1338 "invalid Xarch argument: '%0', not all driver "
1339 "options can be forwared via Xarch argument");
1340 Diags.Report(DiagID) << A->getAsString(Args);
1341 return;
1342 }
1343 XarchArg->setBaseArg(A);
1344 A = XarchArg.release();
1345 if (!AllocatedArgs)
1346 DAL->AddSynthesizedArg(A);
1347 else
1348 AllocatedArgs->push_back(A);
1349}
1350
1351llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs(
1352 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1354 SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
1355 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1356 bool Modified = false;
1357
1358 bool IsDevice = OFK != Action::OFK_None && OFK != Action::OFK_Host;
1359 for (Arg *A : Args) {
1360 bool NeedTrans = false;
1361 bool Skip = false;
1362 if (A->getOption().matches(options::OPT_Xarch_device)) {
1363 NeedTrans = IsDevice;
1364 Skip = !IsDevice;
1365 } else if (A->getOption().matches(options::OPT_Xarch_host)) {
1366 NeedTrans = !IsDevice;
1367 Skip = IsDevice;
1368 } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) {
1369 // Do not translate -Xarch_ options for non CUDA/HIP toolchain since
1370 // they may need special translation.
1371 // Skip this argument unless the architecture matches BoundArch
1372 if (BoundArch.empty() || A->getValue(0) != BoundArch)
1373 Skip = true;
1374 else
1375 NeedTrans = true;
1376 }
1377 if (NeedTrans || Skip)
1378 Modified = true;
1379 if (NeedTrans)
1380 TranslateXarchArgs(Args, A, DAL, AllocatedArgs);
1381 if (!Skip)
1382 DAL->append(A);
1383 }
1384
1385 if (Modified)
1386 return DAL;
1387
1388 delete DAL;
1389 return nullptr;
1390}
StringRef P
Defines types useful for describing an Objective-C runtime.
Defines the clang::SanitizerKind enum.
static const DriverSuffix * parseDriverSuffix(StringRef ProgName, size_t &Pos)
Definition: ToolChain.cpp:238
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...
Definition: ToolChain.cpp:228
static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, const ArgList &Args)
Definition: ToolChain.cpp:448
static VersionTuple separateMSVCFullVersion(unsigned Version)
Definition: ToolChain.cpp:1183
static const DriverSuffix * FindDriverSuffix(StringRef ProgName, size_t &Pos)
Definition: ToolChain.cpp:195
static llvm::opt::Arg * GetRTTIArgument(const ArgList &Args)
Definition: ToolChain.cpp:55
static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args, const llvm::Triple &Triple, const Arg *CachedRTTIArg)
Definition: ToolChain.cpp:60
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:868
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: Type.h:1566
ActionClass getKind() const
Definition: Action.h:147
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
std::string SysRoot
sysroot, if present
Definition: Driver.h:183
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
Definition: Driver.cpp:5873
DiagnosticsEngine & getDiags() const
Definition: Driver.h:390
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:144
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:388
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
Definition: Driver.cpp:5933
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:167
llvm::vfs::FileSystem & getVFS() const
Definition: Driver.h:392
std::string Dir
The path the driver executable was in, as invoked from the command line.
Definition: Driver.h:155
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Definition: Driver.h:229
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition: Driver.h:216
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
const char * getFilename() const
Definition: InputInfo.h:83
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Definition: Multilib.h:50
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:91
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,...
Definition: ToolChain.cpp:1108
virtual std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType=types::TY_INVALID) const
ComputeEffectiveClangTriple - Return the Clang triple to use for this target, which may take into acc...
Definition: ToolChain.cpp:850
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...
Definition: ToolChain.cpp:1103
virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const
Add warning options that need to be passed to cc1 for this target.
Definition: ToolChain.cpp:871
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.
Definition: ToolChain.cpp:969
path_list getStdlibPaths() const
Definition: ToolChain.cpp:615
virtual std::string computeSysRoot() const
Return the sysroot, possibly searching for a default sysroot using target-specific logic.
Definition: ToolChain.cpp:855
virtual bool useIntegratedAs() const
Check if the toolchain should use the integrated assembler.
Definition: ToolChain.cpp:131
static llvm::Triple getOpenMPTriple(StringRef TripleStr)
Definition: ToolChain.h:769
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...
Definition: ToolChain.cpp:1237
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:881
virtual UnwindTableLevel getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const
How detailed should the unwind tables be by default.
Definition: ToolChain.cpp:326
const char * getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:566
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const
Returns if the C++ standard library should be linked in.
Definition: ToolChain.cpp:1071
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.
Definition: ToolChain.cpp:984
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...
Definition: ToolChain.cpp:321
virtual Tool * buildStaticLibTool() const
Definition: ToolChain.cpp:350
virtual bool IsIntegratedBackendSupported() const
IsIntegratedBackendSupported - Does this tool chain support -fintegrated-objemitter.
Definition: ToolChain.h:409
std::string GetFilePath(const char *Name) const
Definition: ToolChain.cpp:660
path_list & getFilePaths()
Definition: ToolChain.h:278
virtual Tool * SelectTool(const JobAction &JA) const
Choose a tool to use to handle the action JA.
Definition: ToolChain.cpp:651
static bool needsProfileRT(const llvm::opt::ArgList &Args)
needsProfileRT - returns true if instrumentation profile is on.
Definition: ToolChain.cpp:631
StringRef getOS() const
Definition: ToolChain.h:255
virtual bool isBareMetal() const
isBareMetal - Is this a bare metal target.
Definition: ToolChain.h:592
virtual bool isThreadModelSupported(const StringRef Model) const
isThreadModelSupported() - Does this target support a thread model?
Definition: ToolChain.cpp:789
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:252
const Driver & getDriver() const
Definition: ToolChain.h:236
virtual std::string detectLibcxxVersion(StringRef IncludePath) const
Definition: ToolChain.cpp:1016
static std::string concat(StringRef Path, const Twine &A, const Twine &B="", const Twine &C="", const Twine &D="")
Definition: ToolChain.cpp:1008
llvm::vfs::FileSystem & getVFS() const
Definition: ToolChain.cpp:127
static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args)
Returns true if gcov instrumentation (-fprofile-arcs or –coverage) is on.
Definition: ToolChain.cpp:645
virtual std::string ComputeLLVMTriple(const llvm::opt::ArgList &Args, types::ID InputType=types::TY_INVALID) const
ComputeLLVMTriple - Return the LLVM target triple to use, after taking command line arguments into ac...
Definition: ToolChain.cpp:802
ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition: ToolChain.cpp:76
const XRayArgs & getXRayArgs() const
Definition: ToolChain.cpp:180
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 ...
Definition: ToolChain.cpp:1053
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...
Definition: ToolChain.cpp:1128
static void addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Definition: ToolChain.cpp:991
path_list getRuntimePaths() const
Definition: ToolChain.cpp:572
virtual bool useIntegratedBackend() const
Check if the toolchain should use the integrated backend.
Definition: ToolChain.cpp:137
std::string GetStaticLibToolPath() const
Returns the linker path for emitting a static library.
Definition: ToolChain.cpp:740
virtual llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const
GetExceptionModel - Return the tool chain exception model.
Definition: ToolChain.cpp:785
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...
Definition: ToolChain.cpp:1077
static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName)
Return any implicit target and/or mode flag for an invocation of the compiler driver as ProgName.
Definition: ToolChain.cpp:272
virtual bool IsIntegratedBackendDefault() const
IsIntegratedBackendDefault - Does this tool chain enable -fintegrated-objemitter by default.
Definition: ToolChain.h:405
virtual const char * getDefaultLinker() const
GetDefaultLinker - Get the default linker to use.
Definition: ToolChain.h:460
virtual Tool * buildLinker() const
Definition: ToolChain.cpp:346
const llvm::Triple & getTriple() const
Definition: ToolChain.h:238
bool defaultToIEEELongDouble() const
Check whether use IEEE binary128 as long double format by default.
Definition: ToolChain.cpp:169
virtual types::ID LookupTypeForExtension(StringRef Ext) const
LookupTypeForExtension - Return the default language type to use for the given extension.
Definition: ToolChain.cpp:747
virtual bool HasNativeLLVMSupport() const
HasNativeLTOLinker - Check whether the linker and related tools have native LLVM support.
Definition: ToolChain.cpp:759
virtual llvm::SmallVector< BitCodeLibraryInfo, 12 > getDeviceLibs(const llvm::opt::ArgList &Args) const
Get paths for device libraries.
Definition: ToolChain.cpp:1176
virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:907
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 ...
Definition: ToolChain.cpp:873
virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use system-specific CUDA includes.
Definition: ToolChain.cpp:1169
virtual std::string getCompilerRTPath() const
Definition: ToolChain.cpp:491
virtual std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args, StringRef Component, FileType Type, bool AddArch) const
Definition: ToolChain.cpp:511
virtual std::string getArchSpecificLibPath() const
Definition: ToolChain.cpp:624
std::string GetLinkerPath(bool *LinkerIsLLD=nullptr) const
Returns the linker path, respecting the -fuse-ld= argument to determine the linker suffix or name.
Definition: ToolChain.cpp:668
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:545
virtual Expected< SmallVector< std::string > > getSystemGPUArchs(const llvm::opt::ArgList &Args) const
getSystemGPUArchs - Use a tool to detect the user's availible GPUs.
Definition: ToolChain.cpp:1140
std::string GetProgramPath(const char *Name) const
Definition: ToolChain.cpp:664
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.
Definition: ToolChain.cpp:999
virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use system-specific HIP includes.
Definition: ToolChain.cpp:1172
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...
Definition: ToolChain.cpp:1039
virtual VersionTuple computeMSVCVersion(const Driver *D, const llvm::opt::ArgList &Args) const
On Windows, returns the MSVC compatibility version.
Definition: ToolChain.cpp:1197
virtual StringRef getOSLibName() const
Definition: ToolChain.cpp:471
virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add arguments to use MCU GCC toolchain includes.
Definition: ToolChain.cpp:1180
virtual CXXStdlibType GetDefaultCXXStdlibType() const
Definition: ToolChain.h:467
void AddFilePathLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option.
Definition: ToolChain.cpp:1096
std::string getTripleString() const
Definition: ToolChain.h:261
virtual RuntimeLibType GetDefaultRuntimeLibType() const
GetDefaultRuntimeLibType - Get the default runtime library variant to use.
Definition: ToolChain.h:463
StringRef getDefaultUniversalArchName() const
Provide the default architecture name (as expected by -arch) for this toolchain.
Definition: ToolChain.cpp:296
virtual Tool * buildAssembler() const
Definition: ToolChain.cpp:342
void setTripleEnvironment(llvm::Triple::EnvironmentType Env)
Definition: ToolChain.cpp:119
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.
Definition: ToolChain.cpp:868
virtual bool IsIntegratedAssemblerDefault() const
IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as by default.
Definition: ToolChain.h:401
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
Definition: ToolChain.cpp:174
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:943
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeToolChainProgram(StringRef Executable) const
Executes the given Executable and returns the stdout.
Definition: ToolChain.cpp:93
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.
Definition: ToolChain.cpp:864
path_list & getLibraryPaths()
Definition: ToolChain.h:275
virtual void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Add the clang cc1 arguments for system include paths.
Definition: ToolChain.cpp:859
virtual UnwindLibType GetDefaultUnwindLibType() const
Definition: ToolChain.h:471
virtual Tool * getTool(Action::ActionClass AC) const
Definition: ToolChain.cpp:402
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:1144
virtual bool isCrossCompiling() const
Returns true if the toolchain is targeting a non-native architecture.
Definition: ToolChain.cpp:763
std::string getCompilerRTBasename(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:504
virtual bool IsNonIntegratedBackendSupported() const
IsNonIntegratedBackendSupported - Does this tool chain support -fno-integrated-objemitter.
Definition: ToolChain.h:413
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.
Definition: ToolChain.cpp:1309
virtual bool useRelaxRelocations() const
Check whether to enable x86 relax relocations by default.
Definition: ToolChain.cpp:165
virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const
getDefaultObjCRuntime - Return the default Objective-C runtime for this platform.
Definition: ToolChain.cpp:779
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
Clang integrated assembler tool.
Definition: Clang.h:124
Clang compiler tool.
Definition: Clang.h:28
Flang compiler tool.
Definition: Flang.h:25
Linker wrapper tool.
Definition: Clang.h:176
Offload bundler tool.
Definition: Clang.h:145
Offload binary tool.
Definition: Clang.h:163
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)
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
Definition: Types.cpp:295
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
YAML serialization mapping.
Definition: Dominators.h:30
Helper structure used to pass information extracted from clang executable name such as i686-linux-and...
Definition: ToolChain.h:64