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"
14
15#include "Arch/ARM.h"
16#include "Arch/RISCV.h"
18#include "clang/Driver/Driver.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
30using namespace llvm::opt;
31using namespace clang;
32using namespace clang::driver;
33using namespace clang::driver::tools;
34using namespace clang::driver::toolchains;
35
36static 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 =
61 return Result.Multilibs.select(D, 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(D, Flags, Result.SelectedMultilibs);
96 }
97 return false;
98}
99
100static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
101 if (!D.SysRoot.empty())
102 return D.SysRoot;
103
104 SmallString<128> SysRootDir(D.Dir);
105 llvm::sys::path::append(SysRootDir, "..", "lib", "clang-runtimes");
106
107 if (IncludeTriple)
108 llvm::sys::path::append(SysRootDir, D.getTargetTriple());
109
110 return std::string(SysRootDir);
111}
112
113BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
114 const ArgList &Args)
115 : ToolChain(D, Triple, Args),
116 SysRoot(computeBaseSysRoot(D, /*IncludeTriple=*/true)) {
117 getProgramPaths().push_back(getDriver().Dir);
118
119 findMultilibs(D, Triple, Args);
121 if (!SysRoot.empty()) {
122 for (const Multilib &M : getOrderedMultilibs()) {
123 SmallString<128> Dir(SysRoot);
124 llvm::sys::path::append(Dir, M.osSuffix(), "lib");
125 getFilePaths().push_back(std::string(Dir));
126 getLibraryPaths().push_back(std::string(Dir));
127 }
128 }
129}
130
131/// Is the triple {aarch64.aarch64_be}-none-elf?
132static bool isAArch64BareMetal(const llvm::Triple &Triple) {
133 if (Triple.getArch() != llvm::Triple::aarch64 &&
134 Triple.getArch() != llvm::Triple::aarch64_be)
135 return false;
136
137 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
138 return false;
139
140 if (Triple.getOS() != llvm::Triple::UnknownOS)
141 return false;
142
143 return Triple.getEnvironmentName() == "elf";
144}
145
146static bool isRISCVBareMetal(const llvm::Triple &Triple) {
147 if (!Triple.isRISCV())
148 return false;
149
150 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
151 return false;
152
153 if (Triple.getOS() != llvm::Triple::UnknownOS)
154 return false;
155
156 return Triple.getEnvironmentName() == "elf";
157}
158
159/// Is the triple powerpc[64][le]-*-none-eabi?
160static bool isPPCBareMetal(const llvm::Triple &Triple) {
161 return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
162 Triple.getEnvironment() == llvm::Triple::EABI;
163}
164
165static void
167 StringRef MultilibPath, const ArgList &Args,
169 SmallVector<StringRef> &CustomFlagsMacroDefines) {
170 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
171 D.getVFS().getBufferForFile(MultilibPath);
172 if (!MB)
173 return;
174 Multilib::flags_list Flags = TC.getMultilibFlags(Args);
175 llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
176 MultilibSet::parseYaml(*MB.get());
177 if (ErrorOrMultilibSet.getError())
178 return;
179 Result.Multilibs = ErrorOrMultilibSet.get();
180 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs,
181 &CustomFlagsMacroDefines))
182 return;
183 D.Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags, " ");
184 std::stringstream ss;
185
186 // If multilib selection didn't complete successfully, report a list
187 // of all the configurations the user could have provided.
188 for (const Multilib &Multilib : Result.Multilibs)
189 if (!Multilib.isError())
190 ss << "\n" << llvm::join(Multilib.flags(), " ");
191 D.Diag(clang::diag::note_drv_available_multilibs) << ss.str();
192
193 // Now report any custom error messages requested by the YAML. We do
194 // this after displaying the list of available multilibs, because
195 // that list is probably large, and (in interactive use) risks
196 // scrolling the useful error message off the top of the user's
197 // terminal.
198 for (const Multilib &Multilib : Result.SelectedMultilibs)
199 if (Multilib.isError())
200 D.Diag(clang::diag::err_drv_multilib_custom_error)
202
203 // If there was an error, clear the SelectedMultilibs vector, in
204 // case it contains partial data.
205 Result.SelectedMultilibs.clear();
206}
207
208static constexpr llvm::StringLiteral MultilibFilename = "multilib.yaml";
209
210static std::optional<llvm::SmallString<128>>
211getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
212 const ArgList &Args) {
213 llvm::SmallString<128> MultilibPath;
214 if (Arg *ConfigFileArg = Args.getLastArg(options::OPT_multi_lib_config)) {
215 MultilibPath = ConfigFileArg->getValue();
216 if (!D.getVFS().exists(MultilibPath)) {
217 D.Diag(clang::diag::err_drv_no_such_file) << MultilibPath.str();
218 return {};
219 }
220 } else {
221 MultilibPath = computeBaseSysRoot(D, /*IncludeTriple=*/false);
222 llvm::sys::path::append(MultilibPath, MultilibFilename);
223 }
224 return MultilibPath;
225}
226
227void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
228 const ArgList &Args) {
230 // Look for a multilib.yaml before trying target-specific hardwired logic.
231 // If it exists, always do what it specifies.
232 std::optional<llvm::SmallString<128>> MultilibPath =
233 getMultilibConfigPath(D, Triple, Args);
234 if (!MultilibPath)
235 return;
236 if (D.getVFS().exists(*MultilibPath)) {
237 // If multilib.yaml is found, update sysroot so it doesn't use a target
238 // specific suffix
239 SysRoot = computeBaseSysRoot(D, /*IncludeTriple=*/false);
240 SmallVector<StringRef> CustomFlagMacroDefines;
241 findMultilibsFromYAML(*this, D, *MultilibPath, Args, Result,
242 CustomFlagMacroDefines);
243 SelectedMultilibs = Result.SelectedMultilibs;
244 Multilibs = Result.Multilibs;
245 MultilibMacroDefines.append(CustomFlagMacroDefines.begin(),
246 CustomFlagMacroDefines.end());
247 } else if (isRISCVBareMetal(Triple)) {
248 if (findRISCVMultilibs(D, Triple, Args, Result)) {
249 SelectedMultilibs = Result.SelectedMultilibs;
250 Multilibs = Result.Multilibs;
251 }
252 }
253}
254
255bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
256 return arm::isARMEABIBareMetal(Triple) || isAArch64BareMetal(Triple) ||
257 isRISCVBareMetal(Triple) || isPPCBareMetal(Triple);
258}
259
261 return new tools::baremetal::Linker(*this);
262}
263
265 return new tools::baremetal::StaticLibTool(*this);
266}
267
268std::string BareMetal::computeSysRoot() const { return SysRoot; }
269
270BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs() const {
271 // Get multilibs in reverse order because they're ordered most-specific last.
272 if (!SelectedMultilibs.empty())
273 return llvm::reverse(SelectedMultilibs);
274
275 // No multilibs selected so return a single default multilib.
277 return llvm::reverse(Default);
278}
279
280void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
281 ArgStringList &CC1Args) const {
282 if (DriverArgs.hasArg(options::OPT_nostdinc))
283 return;
284
285 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
286 SmallString<128> Dir(getDriver().ResourceDir);
287 llvm::sys::path::append(Dir, "include");
288 addSystemInclude(DriverArgs, CC1Args, Dir.str());
289 }
290
291 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
292 return;
293
294 if (std::optional<std::string> Path = getStdlibIncludePath())
295 addSystemInclude(DriverArgs, CC1Args, *Path);
296
297 const SmallString<128> SysRoot(computeSysRoot());
298 if (!SysRoot.empty()) {
299 for (const Multilib &M : getOrderedMultilibs()) {
300 SmallString<128> Dir(SysRoot);
301 llvm::sys::path::append(Dir, M.includeSuffix());
302 llvm::sys::path::append(Dir, "include");
303 addSystemInclude(DriverArgs, CC1Args, Dir.str());
304 }
305 }
306}
307
308void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
309 ArgStringList &CC1Args,
310 Action::OffloadKind) const {
311 CC1Args.push_back("-nostdsysteminc");
312}
313
314void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
315 ArgStringList &CC1Args) const {
316 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
317 options::OPT_nostdincxx))
318 return;
319
320 const Driver &D = getDriver();
321 std::string Target = getTripleString();
322
323 auto AddCXXIncludePath = [&](StringRef Path) {
324 std::string Version = detectLibcxxVersion(Path);
325 if (Version.empty())
326 return;
327
328 {
329 // First the per-target include dir: include/<target>/c++/v1.
330 SmallString<128> TargetDir(Path);
331 llvm::sys::path::append(TargetDir, Target, "c++", Version);
332 addSystemInclude(DriverArgs, CC1Args, TargetDir);
333 }
334
335 {
336 // Then the generic dir: include/c++/v1.
338 llvm::sys::path::append(Dir, "c++", Version);
339 addSystemInclude(DriverArgs, CC1Args, Dir);
340 }
341 };
342
343 switch (GetCXXStdlibType(DriverArgs)) {
345 SmallString<128> P(D.Dir);
346 llvm::sys::path::append(P, "..", "include");
347 AddCXXIncludePath(P);
348 break;
349 }
351 // We only support libc++ toolchain installation.
352 break;
353 }
354
355 std::string SysRoot(computeSysRoot());
356 if (SysRoot.empty())
357 return;
358
359 for (const Multilib &M : getOrderedMultilibs()) {
360 SmallString<128> Dir(SysRoot);
361 llvm::sys::path::append(Dir, M.gccSuffix());
362 switch (GetCXXStdlibType(DriverArgs)) {
364 // First check sysroot/usr/include/c++/v1 if it exists.
365 SmallString<128> TargetDir(Dir);
366 llvm::sys::path::append(TargetDir, "usr", "include", "c++", "v1");
367 if (D.getVFS().exists(TargetDir)) {
368 addSystemInclude(DriverArgs, CC1Args, TargetDir.str());
369 break;
370 }
371 // Add generic path if nothing else succeeded so far.
372 llvm::sys::path::append(Dir, "include", "c++", "v1");
373 addSystemInclude(DriverArgs, CC1Args, Dir.str());
374 break;
375 }
377 llvm::sys::path::append(Dir, "include", "c++");
378 std::error_code EC;
379 Generic_GCC::GCCVersion Version = {"", -1, -1, -1, "", "", ""};
380 // Walk the subdirs, and find the one with the newest gcc version:
381 for (llvm::vfs::directory_iterator
382 LI = D.getVFS().dir_begin(Dir.str(), EC),
383 LE;
384 !EC && LI != LE; LI = LI.increment(EC)) {
385 StringRef VersionText = llvm::sys::path::filename(LI->path());
386 auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText);
387 if (CandidateVersion.Major == -1)
388 continue;
389 if (CandidateVersion <= Version)
390 continue;
391 Version = CandidateVersion;
392 }
393 if (Version.Major != -1) {
394 llvm::sys::path::append(Dir, Version.Text);
395 addSystemInclude(DriverArgs, CC1Args, Dir.str());
396 }
397 break;
398 }
399 }
400 }
401}
402
404 const InputInfo &Output,
405 const InputInfoList &Inputs,
406 const ArgList &Args,
407 const char *LinkingOutput) const {
408 const Driver &D = getToolChain().getDriver();
409
410 // Silence warning for "clang -g foo.o -o foo"
411 Args.ClaimAllArgs(options::OPT_g_Group);
412 // and "clang -emit-llvm foo.o -o foo"
413 Args.ClaimAllArgs(options::OPT_emit_llvm);
414 // and for "clang -w foo.o -o foo". Other warning options are already
415 // handled somewhere else.
416 Args.ClaimAllArgs(options::OPT_w);
417 // Silence warnings when linking C code with a C++ '-stdlib' argument.
418 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
419
420 // ar tool command "llvm-ar <options> <output_file> <input_files>".
421 ArgStringList CmdArgs;
422 // Create and insert file members with a deterministic index.
423 CmdArgs.push_back("rcsD");
424 CmdArgs.push_back(Output.getFilename());
425
426 for (const auto &II : Inputs) {
427 if (II.isFilename()) {
428 CmdArgs.push_back(II.getFilename());
429 }
430 }
431
432 // Delete old output archive file if it already exists before generating a new
433 // archive file.
434 const char *OutputFileName = Output.getFilename();
435 if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {
436 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
437 D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
438 return;
439 }
440 }
441
442 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
443 C.addCommand(std::make_unique<Command>(JA, *this,
445 Exec, CmdArgs, Inputs, Output));
446}
447
449 const InputInfo &Output,
450 const InputInfoList &Inputs,
451 const ArgList &Args,
452 const char *LinkingOutput) const {
453 ArgStringList CmdArgs;
454
455 auto &TC = static_cast<const toolchains::BareMetal &>(getToolChain());
456 const Driver &D = getToolChain().getDriver();
457 const llvm::Triple::ArchType Arch = TC.getArch();
458 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
459
460 AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
461
462 CmdArgs.push_back("-Bstatic");
463
464 if (TC.getTriple().isRISCV() && Args.hasArg(options::OPT_mno_relax))
465 CmdArgs.push_back("--no-relax");
466
467 if (Triple.isARM() || Triple.isThumb()) {
468 bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
469 if (IsBigEndian)
470 arm::appendBE8LinkFlag(Args, CmdArgs, Triple);
471 CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
472 } else if (Triple.isAArch64()) {
473 CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
474 }
475
476 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
477 options::OPT_r)) {
478 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt0.o")));
479 }
480
481 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
482 options::OPT_s, options::OPT_t, options::OPT_r});
483
484 TC.AddFilePathLibArgs(Args, CmdArgs);
485
486 for (const auto &LibPath : TC.getLibraryPaths())
487 CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-L", LibPath)));
488
489 if (TC.ShouldLinkCXXStdlib(Args)) {
490 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
491 !Args.hasArg(options::OPT_static);
492 if (OnlyLibstdcxxStatic)
493 CmdArgs.push_back("-Bstatic");
494 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
495 if (OnlyLibstdcxxStatic)
496 CmdArgs.push_back("-Bdynamic");
497 CmdArgs.push_back("-lm");
498 }
499
500 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
501 AddRunTimeLibs(TC, D, CmdArgs, Args);
502
503 CmdArgs.push_back("-lc");
504 }
505
506 if (D.isUsingLTO()) {
507 assert(!Inputs.empty() && "Must have at least one input.");
508 // Find the first filename InputInfo object.
509 auto Input = llvm::find_if(
510 Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); });
511 if (Input == Inputs.end())
512 // For a very rare case, all of the inputs to the linker are
513 // InputArg. If that happens, just use the first InputInfo.
514 Input = Inputs.begin();
515
516 addLTOOptions(TC, Args, CmdArgs, Output, *Input,
517 D.getLTOMode() == LTOK_Thin);
518 }
519 if (TC.getTriple().isRISCV())
520 CmdArgs.push_back("-X");
521
522 // The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf
523 // and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and
524 // arm*-*-*bsd).
525 if (arm::isARMEABIBareMetal(TC.getTriple()))
526 CmdArgs.push_back("--target2=rel");
527
528 CmdArgs.push_back("-o");
529 CmdArgs.push_back(Output.getFilename());
530
531 C.addCommand(std::make_unique<Command>(
533 Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
534}
535
536// BareMetal toolchain allows all sanitizers where the compiler generates valid
537// code, ignoring all runtime library support issues on the assumption that
538// baremetal targets typically implement their own runtime support.
540 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
541 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
542 getTriple().getArch() == llvm::Triple::aarch64_be;
543 const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
545 Res |= SanitizerKind::Address;
546 Res |= SanitizerKind::KernelAddress;
547 Res |= SanitizerKind::PointerCompare;
548 Res |= SanitizerKind::PointerSubtract;
549 Res |= SanitizerKind::Fuzzer;
550 Res |= SanitizerKind::FuzzerNoLink;
551 Res |= SanitizerKind::Vptr;
552 Res |= SanitizerKind::SafeStack;
553 Res |= SanitizerKind::Thread;
554 Res |= SanitizerKind::Scudo;
555 if (IsX86_64 || IsAArch64 || IsRISCV64) {
556 Res |= SanitizerKind::HWAddress;
557 Res |= SanitizerKind::KernelHWAddress;
558 }
559 return Res;
560}
561
563BareMetal::getMultilibMacroDefinesStr(llvm::opt::ArgList &Args) const {
564 return MultilibMacroDefines;
565}
StringRef P
static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple)
Definition: BareMetal.cpp:100
static bool isRISCVBareMetal(const llvm::Triple &Triple)
Definition: BareMetal.cpp:146
static std::optional< llvm::SmallString< 128 > > getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Definition: BareMetal.cpp:211
static constexpr llvm::StringLiteral MultilibFilename
Definition: BareMetal.cpp:208
static bool isPPCBareMetal(const llvm::Triple &Triple)
Is the triple powerpc[64][le]-*-none-eabi?
Definition: BareMetal.cpp:160
static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D, StringRef MultilibPath, const ArgList &Args, DetectedMultilibs &Result, SmallVector< StringRef > &CustomFlagsMacroDefines)
Definition: BareMetal.cpp:166
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:132
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:99
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:483
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:35
const std::string & getErrorMessage() const
Definition: Multilib.h:99
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
Definition: Multilib.h:82
std::vector< std::string > flags_list
Definition: Multilib.h:37
bool isError() const
Definition: Multilib.h:97
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
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:1277
path_list & getFilePaths()
Definition: ToolChain.h:294
const Driver & getDriver() const
Definition: ToolChain.h:252
virtual std::string detectLibcxxVersion(StringRef IncludePath) const
Definition: ToolChain.cpp:1324
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:344
path_list & getProgramPaths()
Definition: ToolChain.h:297
const llvm::Triple & getTriple() const
Definition: ToolChain.h:254
std::optional< std::string > getStdlibIncludePath() const
Definition: ToolChain.cpp:907
std::string getTripleString() const
Definition: ToolChain.h:277
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1251
llvm::SmallVector< Multilib > SelectedMultilibs
Definition: ToolChain.h:201
path_list & getLibraryPaths()
Definition: ToolChain.h:291
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:1468
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:268
BareMetal(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: BareMetal.cpp:113
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition: BareMetal.cpp:539
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:314
static bool handlesTarget(const llvm::Triple &Triple)
Definition: BareMetal.cpp:255
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:280
SmallVector< std::string > getMultilibMacroDefinesStr(llvm::opt::ArgList &Args) const override
Definition: BareMetal.cpp:563
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:308
Tool * buildStaticLibTool() const override
Definition: BareMetal.cpp:264
void findMultilibs(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: BareMetal.cpp:227
Tool * buildLinker() const override
Definition: BareMetal.cpp:260
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: BareMetal.cpp:448
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: BareMetal.cpp:403
void appendBE8LinkFlag(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple)
bool isARMEABIBareMetal(const llvm::Triple &Triple)
Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
Definition: ARM.cpp:56
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:249
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 AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args)
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)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
#define true
Definition: stdbool.h:25
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:92
Struct to store and manipulate GCC versions.
Definition: Gnu.h:163
int Major
The parsed major, minor, and patch numbers.
Definition: Gnu.h:168
std::string Text
The unparsed text of the version.
Definition: Gnu.h:165
static GCCVersion Parse(StringRef VersionText)
Parse a GCCVersion object out of a string of text.
Definition: Gnu.cpp:2126