22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Option/ArgList.h"
24#include "llvm/Support/Path.h"
25#include "llvm/Support/VirtualFileSystem.h"
34 if (!Triple.isRISCV())
37 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
40 if (Triple.getOS() != llvm::Triple::UnknownOS)
43 return Triple.getEnvironmentName() ==
"elf";
48 return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
49 Triple.getEnvironment() == llvm::Triple::EABI;
54 return Triple.isX86() && Triple.getOS() == llvm::Triple::UnknownOS &&
55 Triple.getEnvironmentName() ==
"elf";
60 return Triple.isLoongArch() && Triple.getOS() == llvm::Triple::UnknownOS &&
61 Triple.getEnvironmentName() ==
"elf";
65 const llvm::Triple &TargetTriple,
71 if (TargetTriple.isRISCV64()) {
75 .
flag(
"-march=rv64imafdc")
80 (
Arch ==
"rv64imafdc") || (
Arch ==
"rv64gc");
89 return Result.Multilibs.select(D, Flags,
Result.SelectedMultilibs);
91 if (TargetTriple.isRISCV32()) {
98 .
flag(
"-march=rv32im")
101 .
flag(
"-march=rv32iac")
102 .
flag(
"-mabi=ilp32");
104 .
flag(
"-march=rv32imafc")
105 .
flag(
"-mabi=ilp32f");
108 bool UseI = (
Arch ==
"rv32i") || (
Arch ==
"rv32ic");
109 bool UseIm = (
Arch ==
"rv32im") || (
Arch ==
"rv32imc");
110 bool UseImafc = (
Arch ==
"rv32imafc") || (
Arch ==
"rv32imafdc") ||
123 return Result.Multilibs.select(D, Flags,
Result.SelectedMultilibs);
129 bool IncludeTriple) {
134 llvm::sys::path::append(SysRootDir,
"..",
"lib",
"clang-runtimes");
139 return std::string(SysRootDir);
146 const llvm::opt::ArgList &Args) {
147 if (Args.getLastArg(options::OPT_gcc_toolchain) ||
148 Args.getLastArg(clang::options::OPT_gcc_install_dir_EQ)) {
163 return llvm::sys::fs::exists(GCCDir);
177 if (!SysRoot.empty())
183 if (!D.SysRoot.empty())
189 if (IsGCCInstallationValid) {
190 llvm::sys::path::append(inferredSysRoot,
GCCInstallation.getParentLibPath(),
195 llvm::sys::path::append(inferredSysRoot, D.Dir,
"..", D.getTargetTriple());
198 if (!inferredSysRoot.empty() && llvm::sys::fs::exists(inferredSysRoot))
199 return std::string(inferredSysRoot);
209 llvm::sys::path::append(Path,
"lib");
210 return std::string(Path.str());
217 StringRef InstallPath,
220 for (
const auto &Path : PathsCallback(
Multilib))
233 if (IsGCCInstallationValid) {
235 D.Diag(clang::diag::warn_drv_multilib_not_available_for_target);
247 Paths.push_back(ComputedSysRoot +
"/lib");
255 PPaths.push_back((
GCCInstallation.getParentLibPath() +
"/../bin").str());
260 if (!SysRootDir.empty()) {
263 llvm::sys::path::append(Dir, M.osSuffix(),
"lib");
272 const ArgList &Args) {
274 std::string FallbackDir =
277 SysRoot = FallbackDir;
303 if (
getTriple().isRISCV() && IsGCCInstallationValid)
309 if (
getTriple().isRISCV() && IsGCCInstallationValid)
325 ArgStringList &CC1Args)
const {
326 if (DriverArgs.hasArg(options::OPT_nostdinc))
329 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
331 llvm::sys::path::append(Dir,
"include");
335 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
344 if (!SysRootDir.empty()) {
347 llvm::sys::path::append(Dir, M.includeSuffix());
348 llvm::sys::path::append(Dir,
"include");
353 if (D.getVFS().exists(Dir)) {
354 llvm::sys::path::append(Dir,
"include");
363 CC1Args.push_back(
"-nostdsysteminc");
367 const llvm::opt::ArgList &DriverArgs,
368 llvm::opt::ArgStringList &CC1Args)
const {
369 if (!IsGCCInstallationValid)
380 ArgStringList &CC1Args)
const {
381 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
382 options::OPT_nostdincxx))
388 auto AddCXXIncludePath = [&](StringRef Path) {
396 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
403 llvm::sys::path::append(Dir,
"c++", Version);
411 llvm::sys::path::append(P,
"..",
"include");
412 AddCXXIncludePath(P);
421 if (SysRootDir.empty())
426 llvm::sys::path::append(Dir, M.gccSuffix());
431 llvm::sys::path::append(TargetDir,
"usr",
"include",
"c++",
"v1");
432 if (D.getVFS().exists(TargetDir)) {
437 llvm::sys::path::append(Dir,
"include",
"c++",
"v1");
442 llvm::sys::path::append(Dir,
"include",
"c++");
446 for (llvm::vfs::directory_iterator
447 LI = D.getVFS().dir_begin(Dir.str(), EC),
449 !EC && LI != LE; LI = LI.increment(EC)) {
450 StringRef VersionText = llvm::sys::path::filename(LI->path());
452 if (CandidateVersion.Major == -1)
454 if (CandidateVersion <= Version)
456 Version = CandidateVersion;
458 if (Version.Major != -1) {
459 llvm::sys::path::append(Dir, Version.Text);
469 llvm::sys::path::append(Dir,
Target,
"include",
"c++",
"v1");
470 if (D.getVFS().exists(Dir))
483 const char *LinkingOutput)
const {
487 Args.ClaimAllArgs(options::OPT_g_Group);
489 Args.ClaimAllArgs(options::OPT_emit_llvm);
492 Args.ClaimAllArgs(options::OPT_w);
494 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
497 ArgStringList CmdArgs;
499 CmdArgs.push_back(
"rcsD");
500 Args.AddAllArgValues(CmdArgs, options::OPT_Xstatic_lib_tool);
503 for (
const auto &II : Inputs) {
504 if (II.isFilename()) {
505 CmdArgs.push_back(II.getFilename());
512 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
513 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
514 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
519 const char *Exec = Args.MakeArgString(
getToolChain().GetStaticLibToolPath());
520 C.addCommand(std::make_unique<Command>(JA, *
this,
522 Exec, CmdArgs, Inputs, Output));
529 const char *LinkingOutput)
const {
530 ArgStringList CmdArgs;
534 const llvm::Triple::ArchType
Arch = TC.getArch();
535 const llvm::Triple &Triple =
getToolChain().getEffectiveTriple();
539 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
541 CmdArgs.push_back(
"-Bstatic");
543 CmdArgs.push_back(
"-pie");
544 CmdArgs.push_back(
"--no-dynamic-linker");
545 CmdArgs.push_back(
"-z");
546 CmdArgs.push_back(
"text");
549 if (
const char *LDMOption =
getLDMOption(TC.getTriple(), Args)) {
550 CmdArgs.push_back(
"-m");
551 CmdArgs.push_back(LDMOption);
553 D.
Diag(diag::err_target_unknown_triple) << Triple.str();
557 if (Triple.isLoongArch() || Triple.isRISCV()) {
558 CmdArgs.push_back(
"-X");
559 if (Args.hasArg(options::OPT_mno_relax))
560 CmdArgs.push_back(
"--no-relax");
563 if (Triple.isARM() || Triple.isThumb()) {
567 CmdArgs.push_back(IsBigEndian ?
"-EB" :
"-EL");
568 }
else if (Triple.isAArch64()) {
569 CmdArgs.push_back(
Arch == llvm::Triple::aarch64_be ?
"-EB" :
"-EL");
573 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
575 const char *CRTBegin, *CRTEnd;
577 if (!Args.hasArg(options::OPT_r)) {
578 const char *crt =
"crt0.o";
581 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(crt)));
584 auto RuntimeLib = TC.GetRuntimeLibType(Args);
585 switch (RuntimeLib) {
587 CRTBegin = IsStaticPIE ?
"crtbeginS.o" :
"crtbegin.o";
588 CRTEnd = IsStaticPIE ?
"crtendS.o" :
"crtend.o";
599 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTBegin)));
603 Args.addAllArgs(CmdArgs, {options::OPT_L});
604 TC.AddFilePathLibArgs(Args, CmdArgs);
605 Args.addAllArgs(CmdArgs, {options::OPT_u, options::OPT_T_Group,
606 options::OPT_s, options::OPT_t, options::OPT_r});
608 for (
const auto &LibPath : TC.getLibraryPaths())
609 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-L", LibPath)));
611 if (
auto LTO = TC.getLTOMode(Args); LTO !=
LTOK_None)
615 TC.addProfileRTLibs(Args, CmdArgs);
617 if (TC.ShouldLinkCXXStdlib(Args)) {
618 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
619 !Args.hasArg(options::OPT_static);
620 if (OnlyLibstdcxxStatic)
621 CmdArgs.push_back(
"-Bstatic");
622 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
623 if (OnlyLibstdcxxStatic)
624 CmdArgs.push_back(
"-Bdynamic");
625 CmdArgs.push_back(
"-lm");
628 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
629 CmdArgs.push_back(
"--start-group");
631 if (!Args.hasArg(options::OPT_nolibc))
632 CmdArgs.push_back(
"-lc");
634 CmdArgs.push_back(
"-lgloss");
635 CmdArgs.push_back(
"--end-group");
640 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTEnd)));
646 CmdArgs.push_back(
"--target2=rel");
648 CmdArgs.push_back(
"-o");
651 C.addCommand(std::make_unique<Command>(
653 Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
662 const bool IsX86_64 =
getTriple().getArch() == llvm::Triple::x86_64;
663 const bool IsAArch64 =
getTriple().getArch() == llvm::Triple::aarch64 ||
664 getTriple().getArch() == llvm::Triple::aarch64_be;
665 const bool IsRISCV64 =
getTriple().isRISCV64();
667 Res |= SanitizerKind::Address;
668 Res |= SanitizerKind::KernelAddress;
669 Res |= SanitizerKind::PointerCompare;
670 Res |= SanitizerKind::PointerSubtract;
671 Res |= SanitizerKind::Fuzzer;
672 Res |= SanitizerKind::FuzzerNoLink;
673 Res |= SanitizerKind::Vptr;
674 Res |= SanitizerKind::SafeStack;
675 Res |= SanitizerKind::Thread;
676 Res |= SanitizerKind::Scudo;
677 if (IsX86_64 || IsAArch64 || IsRISCV64) {
678 Res |= SanitizerKind::HWAddress;
679 Res |= SanitizerKind::KernelHWAddress;
Result
Implement __builtin_bit_cast and related operations.
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
DiagnosticBuilder Diag(unsigned DiagID) const
std::string Dir
The path the driver executable was in, as invoked from the command line.
std::string getTargetTriple() const
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
MultilibBuilder & flag(StringRef Flag, bool Disallow=false)
Add a flag to the flags list Flag must be a flag accepted by the driver.
This class can be used to create a MultilibSet, and contains helper functions to add combinations of ...
MultilibSetBuilder & Either(const MultilibBuilder &M1, const MultilibBuilder &M2)
Add a set of mutually incompatible Multilib segments.
MultilibSet makeMultilibSet() const
See also MultilibSetBuilder for combining multilibs into a set.
const IncludeDirsFunc & filePathsCallback() const
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
std::vector< std::string > flags_list
const std::string & includeSuffix() const
Get the include directory suffix.
SmallVector< InputInfo, 4 > InputInfoList
Top level wrappers for InstallAPI frontend operations.
@ Result
The result type of a method or function.
Represents a bound architecture for offload / multiple architecture compilation.
static constexpr ResponseFileSupport AtFileCurCP()