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";
59 const llvm::Triple &TargetTriple,
65 if (TargetTriple.isRISCV64()) {
69 .
flag(
"-march=rv64imafdc")
74 (
Arch ==
"rv64imafdc") || (
Arch ==
"rv64gc");
83 return Result.Multilibs.select(D, Flags,
Result.SelectedMultilibs);
85 if (TargetTriple.isRISCV32()) {
92 .
flag(
"-march=rv32im")
95 .
flag(
"-march=rv32iac")
98 .
flag(
"-march=rv32imafc")
99 .
flag(
"-mabi=ilp32f");
102 bool UseI = (
Arch ==
"rv32i") || (
Arch ==
"rv32ic");
103 bool UseIm = (
Arch ==
"rv32im") || (
Arch ==
"rv32imc");
104 bool UseImafc = (
Arch ==
"rv32imafc") || (
Arch ==
"rv32imafdc") ||
117 return Result.Multilibs.select(D, Flags,
Result.SelectedMultilibs);
123 bool IncludeTriple) {
128 llvm::sys::path::append(SysRootDir,
"..",
"lib",
"clang-runtimes");
133 return std::string(SysRootDir);
140 const llvm::opt::ArgList &Args) {
141 if (Args.getLastArg(options::OPT_gcc_toolchain) ||
142 Args.getLastArg(clang::options::OPT_gcc_install_dir_EQ)) {
157 return llvm::sys::fs::exists(GCCDir);
171 if (!SysRoot.empty())
177 if (!D.SysRoot.empty())
183 if (IsGCCInstallationValid) {
184 llvm::sys::path::append(inferredSysRoot,
GCCInstallation.getParentLibPath(),
189 llvm::sys::path::append(inferredSysRoot, D.Dir,
"..", D.getTargetTriple());
192 if (!inferredSysRoot.empty() && llvm::sys::fs::exists(inferredSysRoot))
193 return std::string(inferredSysRoot);
203 llvm::sys::path::append(Path,
"lib");
204 return std::string(Path.str());
211 StringRef InstallPath,
214 for (
const auto &Path : PathsCallback(
Multilib))
227 if (IsGCCInstallationValid) {
229 D.Diag(clang::diag::warn_drv_multilib_not_available_for_target);
241 Paths.push_back(ComputedSysRoot +
"/lib");
249 PPaths.push_back((
GCCInstallation.getParentLibPath() +
"/../bin").str());
254 if (!SysRootDir.empty()) {
257 llvm::sys::path::append(Dir, M.osSuffix(),
"lib");
266 const ArgList &Args) {
268 std::string FallbackDir =
271 SysRoot = FallbackDir;
296 if (
getTriple().isRISCV() && IsGCCInstallationValid)
302 if (
getTriple().isRISCV() && IsGCCInstallationValid)
318 ArgStringList &CC1Args)
const {
319 if (DriverArgs.hasArg(options::OPT_nostdinc))
322 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
324 llvm::sys::path::append(Dir,
"include");
328 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
337 if (!SysRootDir.empty()) {
340 llvm::sys::path::append(Dir, M.includeSuffix());
341 llvm::sys::path::append(Dir,
"include");
346 if (D.getVFS().exists(Dir)) {
347 llvm::sys::path::append(Dir,
"include");
354 ArgStringList &CC1Args,
357 CC1Args.push_back(
"-nostdsysteminc");
361 const llvm::opt::ArgList &DriverArgs,
362 llvm::opt::ArgStringList &CC1Args)
const {
363 if (!IsGCCInstallationValid)
374 ArgStringList &CC1Args)
const {
375 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
376 options::OPT_nostdincxx))
382 auto AddCXXIncludePath = [&](StringRef Path) {
390 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
397 llvm::sys::path::append(Dir,
"c++", Version);
405 llvm::sys::path::append(P,
"..",
"include");
406 AddCXXIncludePath(P);
415 if (SysRootDir.empty())
420 llvm::sys::path::append(Dir, M.gccSuffix());
425 llvm::sys::path::append(TargetDir,
"usr",
"include",
"c++",
"v1");
426 if (D.getVFS().exists(TargetDir)) {
431 llvm::sys::path::append(Dir,
"include",
"c++",
"v1");
436 llvm::sys::path::append(Dir,
"include",
"c++");
440 for (llvm::vfs::directory_iterator
441 LI = D.getVFS().dir_begin(Dir.str(), EC),
443 !EC && LI != LE; LI = LI.increment(EC)) {
444 StringRef VersionText = llvm::sys::path::filename(LI->path());
446 if (CandidateVersion.Major == -1)
448 if (CandidateVersion <= Version)
450 Version = CandidateVersion;
452 if (Version.
Major != -1) {
453 llvm::sys::path::append(Dir, Version.
Text);
463 llvm::sys::path::append(Dir,
Target,
"include",
"c++",
"v1");
464 if (D.getVFS().exists(Dir))
477 const char *LinkingOutput)
const {
481 Args.ClaimAllArgs(options::OPT_g_Group);
483 Args.ClaimAllArgs(options::OPT_emit_llvm);
486 Args.ClaimAllArgs(options::OPT_w);
488 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
491 ArgStringList CmdArgs;
493 CmdArgs.push_back(
"rcsD");
496 for (
const auto &II : Inputs) {
497 if (II.isFilename()) {
498 CmdArgs.push_back(II.getFilename());
505 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
506 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
507 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
512 const char *Exec = Args.MakeArgString(
getToolChain().GetStaticLibToolPath());
513 C.addCommand(std::make_unique<Command>(JA, *
this,
515 Exec, CmdArgs, Inputs, Output));
522 const char *LinkingOutput)
const {
523 ArgStringList CmdArgs;
527 const llvm::Triple::ArchType
Arch = TC.getArch();
528 const llvm::Triple &Triple =
getToolChain().getEffectiveTriple();
532 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
534 CmdArgs.push_back(
"-Bstatic");
536 CmdArgs.push_back(
"-pie");
537 CmdArgs.push_back(
"--no-dynamic-linker");
538 CmdArgs.push_back(
"-z");
539 CmdArgs.push_back(
"text");
542 if (
const char *LDMOption =
getLDMOption(TC.getTriple(), Args)) {
543 CmdArgs.push_back(
"-m");
544 CmdArgs.push_back(LDMOption);
546 D.
Diag(diag::err_target_unknown_triple) << Triple.str();
550 if (Triple.isRISCV()) {
551 CmdArgs.push_back(
"-X");
552 if (Args.hasArg(options::OPT_mno_relax))
553 CmdArgs.push_back(
"--no-relax");
556 if (Triple.isARM() || Triple.isThumb()) {
560 CmdArgs.push_back(IsBigEndian ?
"-EB" :
"-EL");
561 }
else if (Triple.isAArch64()) {
562 CmdArgs.push_back(
Arch == llvm::Triple::aarch64_be ?
"-EB" :
"-EL");
566 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
568 const char *CRTBegin, *CRTEnd;
570 if (!Args.hasArg(options::OPT_r)) {
571 const char *crt =
"crt0.o";
574 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(crt)));
577 auto RuntimeLib = TC.GetRuntimeLibType(Args);
578 switch (RuntimeLib) {
580 CRTBegin = IsStaticPIE ?
"crtbeginS.o" :
"crtbegin.o";
581 CRTEnd = IsStaticPIE ?
"crtendS.o" :
"crtend.o";
592 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTBegin)));
596 Args.addAllArgs(CmdArgs, {options::OPT_L});
597 TC.AddFilePathLibArgs(Args, CmdArgs);
598 Args.addAllArgs(CmdArgs, {options::OPT_u, options::OPT_T_Group,
599 options::OPT_s, options::OPT_t, options::OPT_r});
601 for (
const auto &LibPath : TC.getLibraryPaths())
602 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-L", LibPath)));
604 if (
auto LTO = TC.getLTOMode(Args); LTO !=
LTOK_None)
608 TC.addProfileRTLibs(Args, CmdArgs);
610 if (TC.ShouldLinkCXXStdlib(Args)) {
611 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
612 !Args.hasArg(options::OPT_static);
613 if (OnlyLibstdcxxStatic)
614 CmdArgs.push_back(
"-Bstatic");
615 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
616 if (OnlyLibstdcxxStatic)
617 CmdArgs.push_back(
"-Bdynamic");
618 CmdArgs.push_back(
"-lm");
621 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
622 CmdArgs.push_back(
"--start-group");
624 if (!Args.hasArg(options::OPT_nolibc))
625 CmdArgs.push_back(
"-lc");
627 CmdArgs.push_back(
"-lgloss");
628 CmdArgs.push_back(
"--end-group");
633 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTEnd)));
639 CmdArgs.push_back(
"--target2=rel");
641 CmdArgs.push_back(
"-o");
644 C.addCommand(std::make_unique<Command>(
646 Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
655 const bool IsX86_64 =
getTriple().getArch() == llvm::Triple::x86_64;
656 const bool IsAArch64 =
getTriple().getArch() == llvm::Triple::aarch64 ||
657 getTriple().getArch() == llvm::Triple::aarch64_be;
658 const bool IsRISCV64 =
getTriple().isRISCV64();
661 Res |= SanitizerKind::Address;
662 Res |= SanitizerKind::KernelAddress;
663 Res |= SanitizerKind::PointerCompare;
664 Res |= SanitizerKind::PointerSubtract;
665 Res |= SanitizerKind::Fuzzer;
666 Res |= SanitizerKind::FuzzerNoLink;
667 Res |= SanitizerKind::Vptr;
668 Res |= SanitizerKind::SafeStack;
669 Res |= SanitizerKind::Thread;
670 Res |= SanitizerKind::Scudo;
671 if (IsX86_64 || IsAArch64 || IsRISCV64) {
672 Res |= SanitizerKind::HWAddress;
673 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
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
static constexpr ResponseFileSupport AtFileCurCP()