clang  20.0.0git
BareMetal.cpp
Go to the documentation of this file.
1 //===-- BareMetal.cpp - Bare Metal ToolChain --------------------*- C++ -*-===//
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 
9 #include "BareMetal.h"
10 
11 #include "CommonArgs.h"
12 #include "Gnu.h"
13 #include "clang/Driver/InputInfo.h"
14 
15 #include "Arch/ARM.h"
16 #include "Arch/RISCV.h"
18 #include "clang/Driver/Driver.h"
21 #include "clang/Driver/Options.h"
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"
27 
28 #include <sstream>
29 
30 using namespace llvm::opt;
31 using namespace clang;
32 using namespace clang::driver;
33 using namespace clang::driver::tools;
34 using namespace clang::driver::toolchains;
35 
36 static bool findRISCVMultilibs(const Driver &D,
37  const llvm::Triple &TargetTriple,
38  const ArgList &Args, DetectedMultilibs &Result) {
40  std::string Arch = riscv::getRISCVArch(Args, TargetTriple);
41  StringRef Abi = tools::riscv::getRISCVABI(Args, TargetTriple);
42 
43  if (TargetTriple.isRISCV64()) {
44  MultilibBuilder Imac =
45  MultilibBuilder().flag("-march=rv64imac").flag("-mabi=lp64");
46  MultilibBuilder Imafdc = MultilibBuilder("/rv64imafdc/lp64d")
47  .flag("-march=rv64imafdc")
48  .flag("-mabi=lp64d");
49 
50  // Multilib reuse
51  bool UseImafdc =
52  (Arch == "rv64imafdc") || (Arch == "rv64gc"); // gc => imafdc
53 
54  addMultilibFlag((Arch == "rv64imac"), "-march=rv64imac", Flags);
55  addMultilibFlag(UseImafdc, "-march=rv64imafdc", Flags);
56  addMultilibFlag(Abi == "lp64", "-mabi=lp64", Flags);
57  addMultilibFlag(Abi == "lp64d", "-mabi=lp64d", Flags);
58 
59  Result.Multilibs =
60  MultilibSetBuilder().Either(Imac, Imafdc).makeMultilibSet();
61  return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
62  }
63  if (TargetTriple.isRISCV32()) {
64  MultilibBuilder Imac =
65  MultilibBuilder().flag("-march=rv32imac").flag("-mabi=ilp32");
66  MultilibBuilder I = MultilibBuilder("/rv32i/ilp32")
67  .flag("-march=rv32i")
68  .flag("-mabi=ilp32");
69  MultilibBuilder Im = MultilibBuilder("/rv32im/ilp32")
70  .flag("-march=rv32im")
71  .flag("-mabi=ilp32");
72  MultilibBuilder Iac = MultilibBuilder("/rv32iac/ilp32")
73  .flag("-march=rv32iac")
74  .flag("-mabi=ilp32");
75  MultilibBuilder Imafc = MultilibBuilder("/rv32imafc/ilp32f")
76  .flag("-march=rv32imafc")
77  .flag("-mabi=ilp32f");
78 
79  // Multilib reuse
80  bool UseI = (Arch == "rv32i") || (Arch == "rv32ic"); // ic => i
81  bool UseIm = (Arch == "rv32im") || (Arch == "rv32imc"); // imc => im
82  bool UseImafc = (Arch == "rv32imafc") || (Arch == "rv32imafdc") ||
83  (Arch == "rv32gc"); // imafdc,gc => imafc
84 
85  addMultilibFlag(UseI, "-march=rv32i", Flags);
86  addMultilibFlag(UseIm, "-march=rv32im", Flags);
87  addMultilibFlag((Arch == "rv32iac"), "-march=rv32iac", Flags);
88  addMultilibFlag((Arch == "rv32imac"), "-march=rv32imac", Flags);
89  addMultilibFlag(UseImafc, "-march=rv32imafc", Flags);
90  addMultilibFlag(Abi == "ilp32", "-mabi=ilp32", Flags);
91  addMultilibFlag(Abi == "ilp32f", "-mabi=ilp32f", Flags);
92 
93  Result.Multilibs =
94  MultilibSetBuilder().Either(I, Im, Iac, Imac, Imafc).makeMultilibSet();
95  return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
96  }
97  return false;
98 }
99 
100 BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
101  const ArgList &Args)
102  : ToolChain(D, Triple, Args) {
103  getProgramPaths().push_back(getDriver().Dir);
104 
105  findMultilibs(D, Triple, Args);
106  SmallString<128> SysRoot(computeSysRoot());
107  if (!SysRoot.empty()) {
108  for (const Multilib &M : getOrderedMultilibs()) {
109  SmallString<128> Dir(SysRoot);
110  llvm::sys::path::append(Dir, M.osSuffix(), "lib");
111  getFilePaths().push_back(std::string(Dir));
112  getLibraryPaths().push_back(std::string(Dir));
113  }
114  }
115 }
116 
117 /// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
118 static bool isARMBareMetal(const llvm::Triple &Triple) {
119  if (Triple.getArch() != llvm::Triple::arm &&
120  Triple.getArch() != llvm::Triple::thumb &&
121  Triple.getArch() != llvm::Triple::armeb &&
122  Triple.getArch() != llvm::Triple::thumbeb)
123  return false;
124 
125  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
126  return false;
127 
128  if (Triple.getOS() != llvm::Triple::UnknownOS)
129  return false;
130 
131  if (Triple.getEnvironment() != llvm::Triple::EABI &&
132  Triple.getEnvironment() != llvm::Triple::EABIHF)
133  return false;
134 
135  return true;
136 }
137 
138 /// Is the triple {aarch64.aarch64_be}-none-elf?
139 static bool isAArch64BareMetal(const llvm::Triple &Triple) {
140  if (Triple.getArch() != llvm::Triple::aarch64 &&
141  Triple.getArch() != llvm::Triple::aarch64_be)
142  return false;
143 
144  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
145  return false;
146 
147  if (Triple.getOS() != llvm::Triple::UnknownOS)
148  return false;
149 
150  return Triple.getEnvironmentName() == "elf";
151 }
152 
153 static bool isRISCVBareMetal(const llvm::Triple &Triple) {
154  if (!Triple.isRISCV())
155  return false;
156 
157  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
158  return false;
159 
160  if (Triple.getOS() != llvm::Triple::UnknownOS)
161  return false;
162 
163  return Triple.getEnvironmentName() == "elf";
164 }
165 
166 /// Is the triple powerpc[64][le]-*-none-eabi?
167 static bool isPPCBareMetal(const llvm::Triple &Triple) {
168  return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
169  Triple.getEnvironment() == llvm::Triple::EABI;
170 }
171 
172 static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
173  StringRef MultilibPath, const ArgList &Args,
174  DetectedMultilibs &Result) {
175  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
176  D.getVFS().getBufferForFile(MultilibPath);
177  if (!MB)
178  return;
179  Multilib::flags_list Flags = TC.getMultilibFlags(Args);
180  llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
181  MultilibSet::parseYaml(*MB.get());
182  if (ErrorOrMultilibSet.getError())
183  return;
184  Result.Multilibs = ErrorOrMultilibSet.get();
185  if (Result.Multilibs.select(Flags, Result.SelectedMultilibs))
186  return;
187  D.Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags, " ");
188  std::stringstream ss;
189  for (const Multilib &Multilib : Result.Multilibs)
190  ss << "\n" << llvm::join(Multilib.flags(), " ");
191  D.Diag(clang::diag::note_drv_available_multilibs) << ss.str();
192 }
193 
194 static constexpr llvm::StringLiteral MultilibFilename = "multilib.yaml";
195 
196 // Get the sysroot, before multilib takes effect.
197 static std::string computeBaseSysRoot(const Driver &D,
198  const llvm::Triple &Triple) {
199  if (!D.SysRoot.empty())
200  return D.SysRoot;
201 
202  SmallString<128> SysRootDir(D.Dir);
203  llvm::sys::path::append(SysRootDir, "..", "lib", "clang-runtimes");
204 
205  SmallString<128> MultilibPath(SysRootDir);
206  llvm::sys::path::append(MultilibPath, MultilibFilename);
207 
208  // New behaviour: if multilib.yaml is found then use clang-runtimes as the
209  // sysroot.
210  if (D.getVFS().exists(MultilibPath))
211  return std::string(SysRootDir);
212 
213  // Otherwise fall back to the old behaviour of appending the target triple.
214  llvm::sys::path::append(SysRootDir, D.getTargetTriple());
215  return std::string(SysRootDir);
216 }
217 
218 void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
219  const ArgList &Args) {
220  DetectedMultilibs Result;
221  // Look for a multilib.yaml before trying target-specific hardwired logic.
222  // If it exists, always do what it specifies.
223  llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
224  llvm::sys::path::append(MultilibPath, MultilibFilename);
225  if (D.getVFS().exists(MultilibPath)) {
226  findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
227  SelectedMultilibs = Result.SelectedMultilibs;
228  Multilibs = Result.Multilibs;
229  } else if (isRISCVBareMetal(Triple)) {
230  if (findRISCVMultilibs(D, Triple, Args, Result)) {
231  SelectedMultilibs = Result.SelectedMultilibs;
232  Multilibs = Result.Multilibs;
233  }
234  }
235 }
236 
237 bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
238  return isARMBareMetal(Triple) || isAArch64BareMetal(Triple) ||
239  isRISCVBareMetal(Triple) || isPPCBareMetal(Triple);
240 }
241 
243  return new tools::baremetal::Linker(*this);
244 }
245 
247  return new tools::baremetal::StaticLibTool(*this);
248 }
249 
250 std::string BareMetal::computeSysRoot() const {
252 }
253 
254 BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs() const {
255  // Get multilibs in reverse order because they're ordered most-specific last.
256  if (!SelectedMultilibs.empty())
257  return llvm::reverse(SelectedMultilibs);
258 
259  // No multilibs selected so return a single default multilib.
260  static const llvm::SmallVector<Multilib> Default = {Multilib()};
261  return llvm::reverse(Default);
262 }
263 
264 void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
265  ArgStringList &CC1Args) const {
266  if (DriverArgs.hasArg(options::OPT_nostdinc))
267  return;
268 
269  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
270  SmallString<128> Dir(getDriver().ResourceDir);
271  llvm::sys::path::append(Dir, "include");
272  addSystemInclude(DriverArgs, CC1Args, Dir.str());
273  }
274 
275  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
276  return;
277 
278  if (std::optional<std::string> Path = getStdlibIncludePath())
279  addSystemInclude(DriverArgs, CC1Args, *Path);
280 
281  const SmallString<128> SysRoot(computeSysRoot());
282  if (!SysRoot.empty()) {
283  for (const Multilib &M : getOrderedMultilibs()) {
284  SmallString<128> Dir(SysRoot);
285  llvm::sys::path::append(Dir, M.includeSuffix());
286  llvm::sys::path::append(Dir, "include");
287  addSystemInclude(DriverArgs, CC1Args, Dir.str());
288  }
289  }
290 }
291 
292 void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
293  ArgStringList &CC1Args,
294  Action::OffloadKind) const {
295  CC1Args.push_back("-nostdsysteminc");
296 }
297 
298 void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
299  ArgStringList &CC1Args) const {
300  if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
301  options::OPT_nostdincxx))
302  return;
303 
304  const Driver &D = getDriver();
305  std::string Target = getTripleString();
306 
307  auto AddCXXIncludePath = [&](StringRef Path) {
308  std::string Version = detectLibcxxVersion(Path);
309  if (Version.empty())
310  return;
311 
312  {
313  // First the per-target include dir: include/<target>/c++/v1.
314  SmallString<128> TargetDir(Path);
315  llvm::sys::path::append(TargetDir, Target, "c++", Version);
316  addSystemInclude(DriverArgs, CC1Args, TargetDir);
317  }
318 
319  {
320  // Then the generic dir: include/c++/v1.
321  SmallString<128> Dir(Path);
322  llvm::sys::path::append(Dir, "c++", Version);
323  addSystemInclude(DriverArgs, CC1Args, Dir);
324  }
325  };
326 
327  switch (GetCXXStdlibType(DriverArgs)) {
328  case ToolChain::CST_Libcxx: {
329  SmallString<128> P(D.Dir);
330  llvm::sys::path::append(P, "..", "include");
331  AddCXXIncludePath(P);
332  break;
333  }
335  // We only support libc++ toolchain installation.
336  break;
337  }
338 
339  std::string SysRoot(computeSysRoot());
340  if (SysRoot.empty())
341  return;
342 
343  for (const Multilib &M : getOrderedMultilibs()) {
344  SmallString<128> Dir(SysRoot);
345  llvm::sys::path::append(Dir, M.gccSuffix());
346  switch (GetCXXStdlibType(DriverArgs)) {
347  case ToolChain::CST_Libcxx: {
348  // First check sysroot/usr/include/c++/v1 if it exists.
349  SmallString<128> TargetDir(Dir);
350  llvm::sys::path::append(TargetDir, "usr", "include", "c++", "v1");
351  if (D.getVFS().exists(TargetDir)) {
352  addSystemInclude(DriverArgs, CC1Args, TargetDir.str());
353  break;
354  }
355  // Add generic path if nothing else succeeded so far.
356  llvm::sys::path::append(Dir, "include", "c++", "v1");
357  addSystemInclude(DriverArgs, CC1Args, Dir.str());
358  break;
359  }
361  llvm::sys::path::append(Dir, "include", "c++");
362  std::error_code EC;
363  Generic_GCC::GCCVersion Version = {"", -1, -1, -1, "", "", ""};
364  // Walk the subdirs, and find the one with the newest gcc version:
365  for (llvm::vfs::directory_iterator
366  LI = D.getVFS().dir_begin(Dir.str(), EC),
367  LE;
368  !EC && LI != LE; LI = LI.increment(EC)) {
369  StringRef VersionText = llvm::sys::path::filename(LI->path());
370  auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText);
371  if (CandidateVersion.Major == -1)
372  continue;
373  if (CandidateVersion <= Version)
374  continue;
375  Version = CandidateVersion;
376  }
377  if (Version.Major != -1) {
378  llvm::sys::path::append(Dir, Version.Text);
379  addSystemInclude(DriverArgs, CC1Args, Dir.str());
380  }
381  break;
382  }
383  }
384  }
385 }
386 
387 void BareMetal::AddCXXStdlibLibArgs(const ArgList &Args,
388  ArgStringList &CmdArgs) const {
389  switch (GetCXXStdlibType(Args)) {
391  CmdArgs.push_back("-lc++");
392  if (Args.hasArg(options::OPT_fexperimental_library))
393  CmdArgs.push_back("-lc++experimental");
394  CmdArgs.push_back("-lc++abi");
395  break;
397  CmdArgs.push_back("-lstdc++");
398  CmdArgs.push_back("-lsupc++");
399  break;
400  }
401  CmdArgs.push_back("-lunwind");
402 }
403 
404 void BareMetal::AddLinkRuntimeLib(const ArgList &Args,
405  ArgStringList &CmdArgs) const {
407  switch (RLT) {
409  CmdArgs.push_back(getCompilerRTArgString(Args, "builtins"));
410  return;
411  }
413  CmdArgs.push_back("-lgcc");
414  return;
415  }
416  llvm_unreachable("Unhandled RuntimeLibType.");
417 }
418 
419 void baremetal::StaticLibTool::ConstructJob(Compilation &C, const JobAction &JA,
420  const InputInfo &Output,
421  const InputInfoList &Inputs,
422  const ArgList &Args,
423  const char *LinkingOutput) const {
424  const Driver &D = getToolChain().getDriver();
425 
426  // Silence warning for "clang -g foo.o -o foo"
427  Args.ClaimAllArgs(options::OPT_g_Group);
428  // and "clang -emit-llvm foo.o -o foo"
429  Args.ClaimAllArgs(options::OPT_emit_llvm);
430  // and for "clang -w foo.o -o foo". Other warning options are already
431  // handled somewhere else.
432  Args.ClaimAllArgs(options::OPT_w);
433  // Silence warnings when linking C code with a C++ '-stdlib' argument.
434  Args.ClaimAllArgs(options::OPT_stdlib_EQ);
435 
436  // ar tool command "llvm-ar <options> <output_file> <input_files>".
437  ArgStringList CmdArgs;
438  // Create and insert file members with a deterministic index.
439  CmdArgs.push_back("rcsD");
440  CmdArgs.push_back(Output.getFilename());
441 
442  for (const auto &II : Inputs) {
443  if (II.isFilename()) {
444  CmdArgs.push_back(II.getFilename());
445  }
446  }
447 
448  // Delete old output archive file if it already exists before generating a new
449  // archive file.
450  const char *OutputFileName = Output.getFilename();
451  if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {
452  if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
453  D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
454  return;
455  }
456  }
457 
458  const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
459  C.addCommand(std::make_unique<Command>(JA, *this,
461  Exec, CmdArgs, Inputs, Output));
462 }
463 
464 void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
465  const InputInfo &Output,
466  const InputInfoList &Inputs,
467  const ArgList &Args,
468  const char *LinkingOutput) const {
469  ArgStringList CmdArgs;
470 
471  auto &TC = static_cast<const toolchains::BareMetal &>(getToolChain());
472  const Driver &D = getToolChain().getDriver();
473  const llvm::Triple::ArchType Arch = TC.getArch();
474  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
475 
476  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
477 
478  CmdArgs.push_back("-Bstatic");
479 
480  if (TC.getTriple().isRISCV() && Args.hasArg(options::OPT_mno_relax))
481  CmdArgs.push_back("--no-relax");
482 
483  if (Triple.isARM() || Triple.isThumb()) {
484  bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
485  if (IsBigEndian)
486  arm::appendBE8LinkFlag(Args, CmdArgs, Triple);
487  CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
488  } else if (Triple.isAArch64()) {
489  CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
490  }
491 
492  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
493  options::OPT_r)) {
494  CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt0.o")));
495  }
496 
497  Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
498  options::OPT_s, options::OPT_t, options::OPT_r});
499 
500  TC.AddFilePathLibArgs(Args, CmdArgs);
501 
502  for (const auto &LibPath : TC.getLibraryPaths())
503  CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-L", LibPath)));
504 
505  if (TC.ShouldLinkCXXStdlib(Args))
506  TC.AddCXXStdlibLibArgs(Args, CmdArgs);
507 
508  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
509  CmdArgs.push_back("-lc");
510  CmdArgs.push_back("-lm");
511 
512  TC.AddLinkRuntimeLib(Args, CmdArgs);
513  }
514 
515  if (D.isUsingLTO()) {
516  assert(!Inputs.empty() && "Must have at least one input.");
517  // Find the first filename InputInfo object.
518  auto Input = llvm::find_if(
519  Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); });
520  if (Input == Inputs.end())
521  // For a very rare case, all of the inputs to the linker are
522  // InputArg. If that happens, just use the first InputInfo.
523  Input = Inputs.begin();
524 
525  addLTOOptions(TC, Args, CmdArgs, Output, *Input,
526  D.getLTOMode() == LTOK_Thin);
527  }
528  if (TC.getTriple().isRISCV())
529  CmdArgs.push_back("-X");
530 
531  // The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf
532  // and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and
533  // arm*-*-*bsd).
534  if (isARMBareMetal(TC.getTriple()))
535  CmdArgs.push_back("--target2=rel");
536 
537  CmdArgs.push_back("-o");
538  CmdArgs.push_back(Output.getFilename());
539 
540  C.addCommand(std::make_unique<Command>(
542  Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
543 }
544 
545 // BareMetal toolchain allows all sanitizers where the compiler generates valid
546 // code, ignoring all runtime library support issues on the assumption that
547 // baremetal targets typically implement their own runtime support.
549  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
550  const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
551  getTriple().getArch() == llvm::Triple::aarch64_be;
552  const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
554  Res |= SanitizerKind::Address;
555  Res |= SanitizerKind::KernelAddress;
556  Res |= SanitizerKind::PointerCompare;
557  Res |= SanitizerKind::PointerSubtract;
558  Res |= SanitizerKind::Fuzzer;
559  Res |= SanitizerKind::FuzzerNoLink;
560  Res |= SanitizerKind::Vptr;
561  Res |= SanitizerKind::SafeStack;
562  Res |= SanitizerKind::Thread;
563  Res |= SanitizerKind::Scudo;
564  if (IsX86_64 || IsAArch64 || IsRISCV64) {
565  Res |= SanitizerKind::HWAddress;
566  Res |= SanitizerKind::KernelHWAddress;
567  }
568  return Res;
569 }
StringRef P
static std::string computeBaseSysRoot(const Driver &D, const llvm::Triple &Triple)
Definition: BareMetal.cpp:197
static bool isRISCVBareMetal(const llvm::Triple &Triple)
Definition: BareMetal.cpp:153
static constexpr llvm::StringLiteral MultilibFilename
Definition: BareMetal.cpp:194
static bool isPPCBareMetal(const llvm::Triple &Triple)
Is the triple powerpc[64][le]-*-none-eabi?
Definition: BareMetal.cpp:167
static bool isARMBareMetal(const llvm::Triple &Triple)
Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
Definition: BareMetal.cpp:118
static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D, StringRef MultilibPath, const ArgList &Args, DetectedMultilibs &Result)
Definition: BareMetal.cpp:172
static bool findRISCVMultilibs(const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args, DetectedMultilibs &Result)
Definition: BareMetal.cpp:36
static bool isAArch64BareMetal(const llvm::Triple &Triple)
Is the triple {aarch64.aarch64_be}-none-elf?
Definition: BareMetal.cpp:139
const Decl * D
IndirectLocalPath & Path
llvm::MachO::Target Target
Definition: MachO.h:51
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
const char * getFilename() const
Definition: InputInfo.h:83
bool isFilename() const
Definition: InputInfo.h:75
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.
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
Definition: Multilib.cpp:286
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:32
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
Definition: Multilib.h:73
std::vector< std::string > flags_list
Definition: Multilib.h:34
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
const Driver & getDriver() const
Definition: ToolChain.h:269
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:1287
path_list & getFilePaths()
Definition: ToolChain.h:311
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1199
const char * getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:815
path_list & getLibraryPaths()
Definition: ToolChain.h:308
const llvm::Triple & getTriple() const
Definition: ToolChain.h:271
virtual std::string detectLibcxxVersion(StringRef IncludePath) const
Definition: ToolChain.cpp:1334
Multilib::flags_list getMultilibFlags(const llvm::opt::ArgList &) const
Get flags suitable for multilib selection, based on the provided clang command line arguments.
Definition: ToolChain.cpp:288
std::optional< std::string > getStdlibIncludePath() const
Definition: ToolChain.cpp:925
std::string getTripleString() const
Definition: ToolChain.h:294
path_list & getProgramPaths()
Definition: ToolChain.h:314
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1261
llvm::SmallVector< Multilib > SelectedMultilibs
Definition: ToolChain.h:217
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:1478
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
std::string computeSysRoot() const override
Return the sysroot, possibly searching for a default sysroot using target-specific logic.
Definition: BareMetal.cpp:250
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition: BareMetal.cpp:548
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
Definition: BareMetal.cpp:298
static bool handlesTarget(const llvm::Triple &Triple)
Definition: BareMetal.cpp:237
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition: BareMetal.cpp:264
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition: BareMetal.cpp:292
Tool * buildStaticLibTool() const override
Definition: BareMetal.cpp:246
void findMultilibs(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: BareMetal.cpp:218
void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Definition: BareMetal.cpp:404
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition: BareMetal.cpp:387
Tool * buildLinker() const override
Definition: BareMetal.cpp:242
void appendBE8LinkFlag(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple)
bool isARMBigEndian(const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
std::string getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition: RISCV.cpp:276
StringRef getRISCVABI(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
void addMultilibFlag(bool Enabled, const StringRef Flag, Multilib::flags_list &Flags)
Flag must be a flag accepted by the driver.
void addLTOOptions(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfo &Output, const InputInfo &Input, bool IsThinLTO)
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1103
ASTEdit remove(RangeSelector S)
Removes the source selected by S.
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:93
Struct to store and manipulate GCC versions.
Definition: Gnu.h:168
int Major
The parsed major, minor, and patch numbers.
Definition: Gnu.h:173
std::string Text
The unparsed text of the version.
Definition: Gnu.h:170
static GCCVersion Parse(StringRef VersionText)
Parse a GCCVersion object out of a string of text.
Definition: Gnu.cpp:2260