22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Option/ArgList.h"
24#include "llvm/Support/Path.h"
25#include "llvm/Support/VirtualFileSystem.h"
26#include "llvm/Support/raw_ostream.h"
37 const llvm::Triple &TargetTriple,
43 if (TargetTriple.isRISCV64()) {
47 .
flag(
"-march=rv64imafdc")
52 (Arch ==
"rv64imafdc") || (Arch ==
"rv64gc");
61 return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
63 if (TargetTriple.isRISCV32()) {
70 .
flag(
"-march=rv32im")
73 .
flag(
"-march=rv32iac")
76 .
flag(
"-march=rv32imafc")
77 .
flag(
"-mabi=ilp32f");
80 bool UseI = (Arch ==
"rv32i") || (Arch ==
"rv32ic");
81 bool UseIm = (Arch ==
"rv32im") || (Arch ==
"rv32imc");
82 bool UseImafc = (Arch ==
"rv32imafc") || (Arch ==
"rv32imafdc") ||
95 return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
109 if (!SysRoot.empty()) {
110 for (
const Multilib &M : getOrderedMultilibs()) {
112 llvm::sys::path::append(Dir, M.osSuffix(),
"lib");
121 if (Triple.getArch() != llvm::Triple::arm &&
122 Triple.getArch() != llvm::Triple::thumb &&
123 Triple.getArch() != llvm::Triple::armeb &&
124 Triple.getArch() != llvm::Triple::thumbeb)
127 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
130 if (Triple.getOS() != llvm::Triple::UnknownOS)
133 if (Triple.getEnvironment() != llvm::Triple::EABI &&
134 Triple.getEnvironment() != llvm::Triple::EABIHF)
142 if (Triple.getArch() != llvm::Triple::aarch64 &&
143 Triple.getArch() != llvm::Triple::aarch64_be)
146 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
149 if (Triple.getOS() != llvm::Triple::UnknownOS)
152 return Triple.getEnvironmentName() ==
"elf";
156 if (!Triple.isRISCV())
159 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
162 if (Triple.getOS() != llvm::Triple::UnknownOS)
165 return Triple.getEnvironmentName() ==
"elf";
170 return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
171 Triple.getEnvironment() == llvm::Triple::EABI;
175 StringRef MultilibPath,
const ArgList &Args,
177 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
178 D.
getVFS().getBufferForFile(MultilibPath);
182 llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
184 if (ErrorOrMultilibSet.getError())
186 Result.Multilibs = ErrorOrMultilibSet.get();
187 if (
Result.Multilibs.select(Flags,
Result.SelectedMultilibs))
189 D.
Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags,
" ");
190 std::stringstream ss;
193 D.
Diag(clang::diag::note_drv_available_multilibs) << ss.str();
200 const llvm::Triple &Triple) {
205 llvm::sys::path::append(SysRootDir,
"..",
"lib",
"clang-runtimes");
212 if (D.
getVFS().exists(MultilibPath))
213 return std::string(SysRootDir);
217 return std::string(SysRootDir);
221 const ArgList &Args) {
254BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs()
const {
265 ArgStringList &CC1Args)
const {
266 if (DriverArgs.hasArg(options::OPT_nostdinc))
269 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
271 llvm::sys::path::append(Dir,
"include");
275 if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
277 if (!SysRoot.empty()) {
278 for (
const Multilib &M : getOrderedMultilibs()) {
280 llvm::sys::path::append(Dir, M.includeSuffix());
281 llvm::sys::path::append(Dir,
"include");
289 ArgStringList &CC1Args,
291 CC1Args.push_back(
"-nostdsysteminc");
295 ArgStringList &CC1Args)
const {
296 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
297 DriverArgs.hasArg(options::OPT_nostdlibinc) ||
298 DriverArgs.hasArg(options::OPT_nostdincxx))
306 for (
const Multilib &M : getOrderedMultilibs()) {
308 llvm::sys::path::append(Dir, M.gccSuffix());
313 llvm::sys::path::append(TargetDir,
"usr",
"include",
"c++",
"v1");
314 if (D.
getVFS().exists(TargetDir)) {
319 llvm::sys::path::append(Dir,
"include",
"c++",
"v1");
324 llvm::sys::path::append(Dir,
"include",
"c++");
328 for (llvm::vfs::directory_iterator
329 LI = D.
getVFS().dir_begin(Dir.str(), EC),
331 !EC && LI != LE; LI = LI.increment(EC)) {
332 StringRef VersionText = llvm::sys::path::filename(LI->path());
334 if (CandidateVersion.Major == -1)
336 if (CandidateVersion <= Version)
338 Version = CandidateVersion;
340 if (Version.
Major != -1) {
341 llvm::sys::path::append(Dir, Version.
Text);
351 ArgStringList &CmdArgs)
const {
354 CmdArgs.push_back(
"-lc++");
355 if (Args.hasArg(options::OPT_fexperimental_library))
356 CmdArgs.push_back(
"-lc++experimental");
357 CmdArgs.push_back(
"-lc++abi");
360 CmdArgs.push_back(
"-lstdc++");
361 CmdArgs.push_back(
"-lsupc++");
364 CmdArgs.push_back(
"-lunwind");
368 ArgStringList &CmdArgs)
const {
373 llvm::StringRef BaseName = llvm::sys::path::filename(
FileName);
374 BaseName.consume_front(
"lib");
375 BaseName.consume_back(
".a");
376 CmdArgs.push_back(Args.MakeArgString(
"-l" + BaseName));
380 CmdArgs.push_back(
"-lgcc");
383 llvm_unreachable(
"Unhandled RuntimeLibType.");
390 const char *LinkingOutput)
const {
391 const Driver &D = getToolChain().getDriver();
394 Args.ClaimAllArgs(options::OPT_g_Group);
396 Args.ClaimAllArgs(options::OPT_emit_llvm);
399 Args.ClaimAllArgs(options::OPT_w);
401 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
404 ArgStringList CmdArgs;
406 CmdArgs.push_back(
"rcsD");
409 for (
const auto &II : Inputs) {
410 if (II.isFilename()) {
411 CmdArgs.push_back(II.getFilename());
418 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
419 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
420 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
425 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
426 C.addCommand(std::make_unique<Command>(JA, *
this,
428 Exec, CmdArgs, Inputs, Output));
435 const char *LinkingOutput)
const {
436 ArgStringList CmdArgs;
439 const llvm::Triple::ArchType Arch = TC.
getArch();
440 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
444 CmdArgs.push_back(
"-Bstatic");
446 if (Triple.isARM() || Triple.isThumb()) {
450 CmdArgs.push_back(IsBigEndian ?
"-EB" :
"-EL");
451 }
else if (Triple.isAArch64()) {
452 CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ?
"-EB" :
"-EL");
455 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
456 options::OPT_s, options::OPT_t, options::OPT_r});
458 TC.AddFilePathLibArgs(Args, CmdArgs);
460 for (
const auto &LibPath : TC.getLibraryPaths())
461 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-L", LibPath)));
463 const std::string
FileName = TC.getCompilerRT(Args,
"builtins");
465 llvm::sys::path::remove_filename(PathBuf);
466 CmdArgs.push_back(Args.MakeArgString(
"-L" + PathBuf));
468 if (TC.ShouldLinkCXXStdlib(Args))
469 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
471 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
472 CmdArgs.push_back(
"-lc");
473 CmdArgs.push_back(
"-lm");
475 TC.AddLinkRuntimeLib(Args, CmdArgs);
478 if (TC.getTriple().isRISCV())
479 CmdArgs.push_back(
"-X");
485 CmdArgs.push_back(
"--target2=rel");
487 CmdArgs.push_back(
"-o");
490 C.addCommand(std::make_unique<Command>(
492 Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
499 const bool IsX86_64 =
getTriple().getArch() == llvm::Triple::x86_64;
500 const bool IsAArch64 =
getTriple().getArch() == llvm::Triple::aarch64 ||
501 getTriple().getArch() == llvm::Triple::aarch64_be;
502 const bool IsRISCV64 =
getTriple().getArch() == llvm::Triple::riscv64;
504 Res |= SanitizerKind::Address;
505 Res |= SanitizerKind::KernelAddress;
506 Res |= SanitizerKind::PointerCompare;
507 Res |= SanitizerKind::PointerSubtract;
508 Res |= SanitizerKind::Fuzzer;
509 Res |= SanitizerKind::FuzzerNoLink;
510 Res |= SanitizerKind::Vptr;
511 Res |= SanitizerKind::SafeStack;
512 Res |= SanitizerKind::Thread;
513 Res |= SanitizerKind::Scudo;
514 if (IsX86_64 || IsAArch64 || IsRISCV64) {
515 Res |= SanitizerKind::HWAddress;
516 Res |= SanitizerKind::KernelHWAddress;
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
llvm::vfs::FileSystem & getVFS() 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
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
std::vector< std::string > flags_list
@ Result
The result type of a method or function.
static constexpr ResponseFileSupport AtFileCurCP()