1//===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- 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 "Gnu.h"
10#include "Arch/ARM.h"
11#include "Arch/CSKY.h"
12#include "Arch/LoongArch.h"
13#include "Arch/Mips.h"
14#include "Arch/PPC.h"
15#include "Arch/RISCV.h"
16#include "Arch/Sparc.h"
17#include "Arch/SystemZ.h"
18#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
19#include "clang/Driver/CommonArgs.h"
20#include "clang/Driver/Compilation.h"
21#include "clang/Driver/Driver.h"
22#include "clang/Driver/MultilibBuilder.h"
23#include "clang/Driver/Options.h"
24#include "clang/Driver/Tool.h"
25#include "clang/Driver/ToolChain.h"
26#include "llvm/ADT/StringSet.h"
27#include "llvm/ADT/Twine.h"
28#include "llvm/Option/ArgList.h"
29#include "llvm/Support/CodeGen.h"
30#include "llvm/Support/Path.h"
31#include "llvm/Support/VirtualFileSystem.h"
32#include "llvm/TargetParser/RISCVISAInfo.h"
33#include "llvm/TargetParser/TargetParser.h"
34#include <system_error>
35
36using namespace clang::driver;
37using namespace clang::driver::toolchains;
38using namespace clang;
39using namespace llvm::opt;
40
41using tools::addMultilibFlag;
42using tools::addPathIfExists;
43
44static bool forwardToGCC(const Option &O) {
45 // LinkerInput options have been forwarded. Don't duplicate.
46 if (O.hasFlag(Val: options::LinkerInput))
47 return false;
48 return O.matches(options::ID: OPT_Link_Group) || O.hasFlag(Val: options::LinkOption);
49}
50
51// Switch CPU names not recognized by GNU assembler to a close CPU that it does
52// recognize, instead of a lower march from being picked in the absence of a cpu
53// flag.
54static void normalizeCPUNamesForAssembler(const ArgList &Args,
55 ArgStringList &CmdArgs) {
56 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
57 StringRef CPUArg(A->getValue());
58 if (CPUArg.equals_insensitive(RHS: "krait"))
59 CmdArgs.push_back(Elt: "-mcpu=cortex-a15");
60 else if (CPUArg.equals_insensitive(RHS: "kryo"))
61 CmdArgs.push_back(Elt: "-mcpu=cortex-a57");
62 else
63 Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
64 }
65}
66
67void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
68 const InputInfo &Output,
69 const InputInfoList &Inputs,
70 const ArgList &Args,
71 const char *LinkingOutput) const {
72 const Driver &D = getToolChain().getDriver();
73 ArgStringList CmdArgs;
74
75 for (const auto &A : Args) {
76 if (forwardToGCC(O: A->getOption())) {
77 // It is unfortunate that we have to claim here, as this means
78 // we will basically never report anything interesting for
79 // platforms using a generic gcc, even if we are just using gcc
80 // to get to the assembler.
81 A->claim();
82
83 A->render(Args, Output&: CmdArgs);
84 }
85 }
86
87 RenderExtraToolArgs(JA, CmdArgs);
88
89 // If using a driver, force the arch.
90 if (getToolChain().getTriple().isOSDarwin()) {
91 CmdArgs.push_back(Elt: "-arch");
92 CmdArgs.push_back(
93 Elt: Args.MakeArgString(Str: getToolChain().getDefaultUniversalArchName()));
94 }
95
96 // Try to force gcc to match the tool chain we want, if we recognize
97 // the arch.
98 //
99 // FIXME: The triple class should directly provide the information we want
100 // here.
101 switch (getToolChain().getArch()) {
102 default:
103 break;
104 case llvm::Triple::x86:
105 case llvm::Triple::ppc:
106 case llvm::Triple::ppcle:
107 CmdArgs.push_back(Elt: "-m32");
108 break;
109 case llvm::Triple::x86_64:
110 case llvm::Triple::ppc64:
111 case llvm::Triple::ppc64le:
112 CmdArgs.push_back(Elt: "-m64");
113 break;
114 case llvm::Triple::sparcel:
115 CmdArgs.push_back(Elt: "-EL");
116 break;
117 }
118
119 assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
120 if (Output.isFilename()) {
121 CmdArgs.push_back(Elt: "-o");
122 CmdArgs.push_back(Elt: Output.getFilename());
123 } else {
124 CmdArgs.push_back(Elt: "-fsyntax-only");
125 }
126
127 Args.AddAllArgValues(Output&: CmdArgs, options::Id0: OPT_Wa_COMMA, options::Id1: OPT_Xassembler);
128
129 // Only pass -x if gcc will understand it; otherwise hope gcc
130 // understands the suffix correctly. The main use case this would go
131 // wrong in is for linker inputs if they happened to have an odd
132 // suffix; really the only way to get this to happen is a command
133 // like '-x foobar a.c' which will treat a.c like a linker input.
134 //
135 // FIXME: For the linker case specifically, can we safely convert
136 // inputs into '-Wl,' options?
137 for (const auto &II : Inputs) {
138 // Don't try to pass LLVM or AST inputs to a generic gcc.
139 if (types::isLLVMIR(Id: II.getType()))
140 D.Diag(clang::diag::DiagID: err_drv_no_linker_llvm_support)
141 << getToolChain().getTripleString();
142 else if (II.getType() == types::TY_AST)
143 D.Diag(diag::DiagID: err_drv_no_ast_support) << getToolChain().getTripleString();
144 else if (II.getType() == types::TY_ModuleFile)
145 D.Diag(diag::DiagID: err_drv_no_module_support)
146 << getToolChain().getTripleString();
147
148 if (types::canTypeBeUserSpecified(Id: II.getType())) {
149 CmdArgs.push_back(Elt: "-x");
150 CmdArgs.push_back(Elt: types::getTypeName(Id: II.getType()));
151 }
152
153 if (II.isFilename())
154 CmdArgs.push_back(Elt: II.getFilename());
155 else {
156 const Arg &A = II.getInputArg();
157
158 // Reverse translate some rewritten options.
159 if (A.getOption().matches(options::ID: OPT_Z_reserved_lib_stdcxx)) {
160 CmdArgs.push_back(Elt: "-lstdc++");
161 continue;
162 }
163
164 // Don't render as input, we need gcc to do the translations.
165 A.render(Args, Output&: CmdArgs);
166 }
167 }
168
169 const std::string &customGCCName = D.getCCCGenericGCCName();
170 const char *GCCName;
171 if (!customGCCName.empty())
172 GCCName = customGCCName.c_str();
173 else if (D.CCCIsCXX()) {
174 GCCName = "g++";
175 } else
176 GCCName = "gcc";
177
178 const char *Exec = Args.MakeArgString(Str: getToolChain().GetProgramPath(Name: GCCName));
179 C.addCommand(C: std::make_unique<Command>(args: JA, args: *this,
180 args: ResponseFileSupport::AtFileCurCP(),
181 args&: Exec, args&: CmdArgs, args: Inputs, args: Output));
182}
183
184void tools::gcc::Preprocessor::RenderExtraToolArgs(
185 const JobAction &JA, ArgStringList &CmdArgs) const {
186 CmdArgs.push_back(Elt: "-E");
187}
188
189void tools::gcc::Compiler::RenderExtraToolArgs(const JobAction &JA,
190 ArgStringList &CmdArgs) const {
191 const Driver &D = getToolChain().getDriver();
192
193 switch (JA.getType()) {
194 // If -flto, etc. are present then make sure not to force assembly output.
195 case types::TY_LLVM_IR:
196 case types::TY_LTO_IR:
197 case types::TY_LLVM_BC:
198 case types::TY_LTO_BC:
199 CmdArgs.push_back(Elt: "-c");
200 break;
201 // We assume we've got an "integrated" assembler in that gcc will produce an
202 // object file itself.
203 case types::TY_Object:
204 CmdArgs.push_back(Elt: "-c");
205 break;
206 case types::TY_PP_Asm:
207 CmdArgs.push_back(Elt: "-S");
208 break;
209 case types::TY_Nothing:
210 CmdArgs.push_back(Elt: "-fsyntax-only");
211 break;
212 default:
213 D.Diag(diag::DiagID: err_drv_invalid_gcc_output_type) << getTypeName(Id: JA.getType());
214 }
215}
216
217void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
218 ArgStringList &CmdArgs) const {
219 // The types are (hopefully) good enough.
220}
221
222static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
223 switch (T.getArch()) {
224 case llvm::Triple::x86:
225 if (T.isOSIAMCU())
226 return "elf_iamcu";
227 return "elf_i386";
228 case llvm::Triple::aarch64:
229 return "aarch64linux";
230 case llvm::Triple::aarch64_be:
231 return "aarch64linuxb";
232 case llvm::Triple::arm:
233 case llvm::Triple::thumb:
234 case llvm::Triple::armeb:
235 case llvm::Triple::thumbeb:
236 return tools::arm::isARMBigEndian(Triple: T, Args) ? "armelfb_linux_eabi"
237 : "armelf_linux_eabi";
238 case llvm::Triple::m68k:
239 return "m68kelf";
240 case llvm::Triple::ppc:
241 if (T.isOSLinux())
242 return "elf32ppclinux";
243 return "elf32ppc";
244 case llvm::Triple::ppcle:
245 if (T.isOSLinux())
246 return "elf32lppclinux";
247 return "elf32lppc";
248 case llvm::Triple::ppc64:
249 return "elf64ppc";
250 case llvm::Triple::ppc64le:
251 return "elf64lppc";
252 case llvm::Triple::riscv32:
253 return "elf32lriscv";
254 case llvm::Triple::riscv64:
255 return "elf64lriscv";
256 case llvm::Triple::sparc:
257 case llvm::Triple::sparcel:
258 return "elf32_sparc";
259 case llvm::Triple::sparcv9:
260 return "elf64_sparc";
261 case llvm::Triple::loongarch32:
262 return "elf32loongarch";
263 case llvm::Triple::loongarch64:
264 return "elf64loongarch";
265 case llvm::Triple::mips:
266 return "elf32btsmip";
267 case llvm::Triple::mipsel:
268 return "elf32ltsmip";
269 case llvm::Triple::mips64:
270 if (tools::mips::hasMipsAbiArg(Args, Value: "n32") || T.isABIN32())
271 return "elf32btsmipn32";
272 return "elf64btsmip";
273 case llvm::Triple::mips64el:
274 if (tools::mips::hasMipsAbiArg(Args, Value: "n32") || T.isABIN32())
275 return "elf32ltsmipn32";
276 return "elf64ltsmip";
277 case llvm::Triple::systemz:
278 return "elf64_s390";
279 case llvm::Triple::x86_64:
280 if (T.isX32())
281 return "elf32_x86_64";
282 return "elf_x86_64";
283 case llvm::Triple::ve:
284 return "elf64ve";
285 case llvm::Triple::csky:
286 return "cskyelf_linux";
287 default:
288 return nullptr;
289 }
290}
291
292static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
293 bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
294 if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {
295 const Driver &D = TC.getDriver();
296 const llvm::opt::OptTable &Opts = D.getOpts();
297 StringRef StaticPIEName = Opts.getOptionName(options::id: OPT_static_pie);
298 StringRef NoPIEName = Opts.getOptionName(options::id: OPT_nopie);
299 D.Diag(diag::DiagID: err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;
300 }
301 return HasStaticPIE;
302}
303
304static bool getStatic(const ArgList &Args) {
305 return Args.hasArg(options::OPT_static) &&
306 !Args.hasArg(options::OPT_static_pie);
307}
308
309void tools::gnutools::StaticLibTool::ConstructJob(
310 Compilation &C, const JobAction &JA, const InputInfo &Output,
311 const InputInfoList &Inputs, const ArgList &Args,
312 const char *LinkingOutput) const {
313 const Driver &D = getToolChain().getDriver();
314
315 // Silence warning for "clang -g foo.o -o foo"
316 Args.ClaimAllArgs(options::OPT_g_Group);
317 // and "clang -emit-llvm foo.o -o foo"
318 Args.ClaimAllArgs(options::OPT_emit_llvm);
319 // and for "clang -w foo.o -o foo". Other warning options are already
320 // handled somewhere else.
321 Args.ClaimAllArgs(options::OPT_w);
322 // Silence warnings when linking C code with a C++ '-stdlib' argument.
323 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
324
325 // ar tool command "llvm-ar <options> <output_file> <input_files>".
326 ArgStringList CmdArgs;
327 // Create and insert file members with a deterministic index.
328 CmdArgs.push_back(Elt: "rcsD");
329 CmdArgs.push_back(Elt: Output.getFilename());
330
331 for (const auto &II : Inputs) {
332 if (II.isFilename()) {
333 CmdArgs.push_back(Elt: II.getFilename());
334 }
335 }
336
337 // Delete old output archive file if it already exists before generating a new
338 // archive file.
339 auto OutputFileName = Output.getFilename();
340 if (Output.isFilename() && llvm::sys::fs::exists(Path: OutputFileName)) {
341 if (std::error_code EC = llvm::sys::fs::remove(path: OutputFileName)) {
342 D.Diag(diag::DiagID: err_drv_unable_to_remove_file) << EC.message();
343 return;
344 }
345 }
346
347 const char *Exec = Args.MakeArgString(Str: getToolChain().GetStaticLibToolPath());
348 C.addCommand(C: std::make_unique<Command>(args: JA, args: *this,
349 args: ResponseFileSupport::AtFileCurCP(),
350 args&: Exec, args&: CmdArgs, args: Inputs, args: Output));
351}
352
353void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
354 const InputInfo &Output,
355 const InputInfoList &Inputs,
356 const ArgList &Args,
357 const char *LinkingOutput) const {
358 // FIXME: The Linker class constructor takes a ToolChain and not a
359 // Generic_ELF, so the static_cast might return a reference to a invalid
360 // instance (see PR45061). Ideally, the Linker constructor needs to take a
361 // Generic_ELF instead.
362 const auto &ToolChain = static_cast<const Generic_ELF &>(getToolChain());
363 const Driver &D = ToolChain.getDriver();
364
365 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
366
367 const llvm::Triple::ArchType Arch = ToolChain.getArch();
368 const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily();
369 const bool isAndroid = ToolChain.getTriple().isAndroid();
370 const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
371 const bool IsVE = ToolChain.getTriple().isVE();
372 const bool IsStaticPIE = getStaticPIE(Args, TC: ToolChain);
373 const bool IsStatic = getStatic(Args);
374 const bool HasCRTBeginEndFiles =
375 ToolChain.getTriple().hasEnvironment() ||
376 (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);
377
378 ArgStringList CmdArgs;
379
380 // Silence warning for "clang -g foo.o -o foo"
381 Args.ClaimAllArgs(options::OPT_g_Group);
382 // and "clang -emit-llvm foo.o -o foo"
383 Args.ClaimAllArgs(options::OPT_emit_llvm);
384 // and for "clang -w foo.o -o foo". Other warning options are already
385 // handled somewhere else.
386 Args.ClaimAllArgs(options::OPT_w);
387
388 if (!D.SysRoot.empty())
389 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "--sysroot=" + D.SysRoot));
390
391 if (Args.hasArg(options::OPT_s))
392 CmdArgs.push_back(Elt: "-s");
393
394 if (Triple.isARM() || Triple.isThumb()) {
395 bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
396 if (IsBigEndian)
397 arm::appendBE8LinkFlag(Args, CmdArgs, Triple);
398 CmdArgs.push_back(Elt: IsBigEndian ? "-EB" : "-EL");
399 } else if (Triple.isAArch64()) {
400 CmdArgs.push_back(Elt: Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
401 }
402
403 // Most Android ARM64 targets should enable the linker fix for erratum
404 // 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
405 if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) {
406 std::string CPU = getCPUName(D, Args, T: Triple);
407 if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
408 CmdArgs.push_back(Elt: "--fix-cortex-a53-843419");
409 }
410
411 ToolChain.addExtraOpts(CmdArgs);
412
413 CmdArgs.push_back(Elt: "--eh-frame-hdr");
414
415 if (const char *LDMOption = getLDMOption(T: ToolChain.getTriple(), Args)) {
416 CmdArgs.push_back(Elt: "-m");
417 CmdArgs.push_back(Elt: LDMOption);
418 } else {
419 D.Diag(diag::DiagID: err_target_unknown_triple) << Triple.str();
420 return;
421 }
422
423 if (Triple.isLoongArch() || Triple.isRISCV()) {
424 CmdArgs.push_back(Elt: "-X");
425 if (Args.hasArg(options::OPT_mno_relax))
426 CmdArgs.push_back(Elt: "--no-relax");
427 }
428
429 const bool IsShared = Args.hasArg(options::OPT_shared);
430 if (IsShared)
431 CmdArgs.push_back(Elt: "-shared");
432 bool IsPIE = false;
433 if (IsStaticPIE) {
434 CmdArgs.push_back(Elt: "-static");
435 CmdArgs.push_back(Elt: "-pie");
436 CmdArgs.push_back(Elt: "--no-dynamic-linker");
437 CmdArgs.push_back(Elt: "-z");
438 CmdArgs.push_back(Elt: "text");
439 } else if (IsStatic) {
440 CmdArgs.push_back(Elt: "-static");
441 } else if (!Args.hasArg(options::OPT_r)) {
442 if (Args.hasArg(options::OPT_rdynamic))
443 CmdArgs.push_back(Elt: "-export-dynamic");
444 if (!IsShared) {
445 IsPIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie,
446 ToolChain.isPIEDefault(Args));
447 if (IsPIE)
448 CmdArgs.push_back(Elt: "-pie");
449 CmdArgs.push_back(Elt: "-dynamic-linker");
450 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine(D.DyldPrefix) +
451 ToolChain.getDynamicLinker(Args)));
452 }
453 }
454
455 CmdArgs.push_back(Elt: "-o");
456 CmdArgs.push_back(Elt: Output.getFilename());
457
458 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
459 options::OPT_r)) {
460 if (!isAndroid && !IsIAMCU) {
461 const char *crt1 = nullptr;
462 if (!Args.hasArg(options::OPT_shared)) {
463 if (Args.hasArg(options::OPT_pg))
464 crt1 = "gcrt1.o";
465 else if (IsPIE)
466 crt1 = "Scrt1.o";
467 else if (IsStaticPIE)
468 crt1 = "rcrt1.o";
469 else
470 crt1 = "crt1.o";
471 }
472 if (crt1)
473 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: crt1)));
474
475 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: "crti.o")));
476 }
477
478 if (IsVE) {
479 CmdArgs.push_back(Elt: "-z");
480 CmdArgs.push_back(Elt: "max-page-size=0x4000000");
481 }
482
483 if (IsIAMCU)
484 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: "crt0.o")));
485 else if (HasCRTBeginEndFiles) {
486 std::string P;
487 if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
488 !isAndroid) {
489 std::string crtbegin = ToolChain.getCompilerRT(Args, Component: "crtbegin",
490 Type: ToolChain::FT_Object);
491 if (ToolChain.getVFS().exists(Path: crtbegin))
492 P = crtbegin;
493 }
494 if (P.empty()) {
495 const char *crtbegin;
496 if (Args.hasArg(options::OPT_shared))
497 crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
498 else if (IsStatic)
499 crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
500 else if (IsPIE || IsStaticPIE)
501 crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
502 else
503 crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
504 P = ToolChain.GetFilePath(Name: crtbegin);
505 }
506 CmdArgs.push_back(Elt: Args.MakeArgString(Str: P));
507 }
508
509 // Add crtfastmath.o if available and fast math is enabled.
510 ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs);
511
512 if (isAndroid && Args.hasFlag(options::OPT_fandroid_pad_segment,
513 options::OPT_fno_android_pad_segment, false))
514 CmdArgs.push_back(
515 Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: "crt_pad_segment.o")));
516 }
517
518 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
519
520 ToolChain.AddFilePathLibArgs(Args, CmdArgs);
521
522 if (D.isUsingLTO())
523 addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs,
524 IsThinLTO: D.getLTOMode() == LTOK_Thin);
525
526 if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
527 CmdArgs.push_back(Elt: "--no-demangle");
528
529 bool NeedsSanitizerDeps = addSanitizerRuntimes(TC: ToolChain, Args, CmdArgs);
530 bool NeedsXRayDeps = addXRayRuntime(TC: ToolChain, Args, CmdArgs);
531 addLinkerCompressDebugSectionsOption(TC: ToolChain, Args, CmdArgs);
532 AddLinkerInputs(TC: ToolChain, Inputs, Args, CmdArgs, JA);
533
534 addHIPRuntimeLibArgs(TC: ToolChain, C, Args, CmdArgs);
535
536 // The profile runtime also needs access to system libraries.
537 getToolChain().addProfileRTLibs(Args, CmdArgs);
538
539 if (D.CCCIsCXX() &&
540 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
541 options::OPT_r)) {
542 if (ToolChain.ShouldLinkCXXStdlib(Args)) {
543 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
544 !Args.hasArg(options::OPT_static);
545 if (OnlyLibstdcxxStatic)
546 CmdArgs.push_back(Elt: "-Bstatic");
547 ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
548 if (OnlyLibstdcxxStatic)
549 CmdArgs.push_back(Elt: "-Bdynamic");
550 }
551 CmdArgs.push_back(Elt: "-lm");
552 }
553
554 // Silence warnings when linking C code with a C++ '-stdlib' argument.
555 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
556
557 // Additional linker set-up and flags for Fortran. This is required in order
558 // to generate executables. As Fortran runtime depends on the C runtime,
559 // these dependencies need to be listed before the C runtime below (i.e.
560 // AddRunTimeLibs).
561 if (D.IsFlangMode() &&
562 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
563 ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
564 ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
565 CmdArgs.push_back(Elt: "-lm");
566 }
567
568 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) {
569 if (!Args.hasArg(options::OPT_nodefaultlibs)) {
570 if (IsStatic || IsStaticPIE)
571 CmdArgs.push_back(Elt: "--start-group");
572
573 if (NeedsSanitizerDeps)
574 linkSanitizerRuntimeDeps(TC: ToolChain, Args, CmdArgs);
575
576 if (NeedsXRayDeps)
577 linkXRayRuntimeDeps(TC: ToolChain, Args, CmdArgs);
578
579 bool WantPthread = Args.hasArg(options::OPT_pthread) ||
580 Args.hasArg(options::OPT_pthreads);
581
582 // Use the static OpenMP runtime with -static-openmp
583 bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
584 !Args.hasArg(options::OPT_static);
585
586 // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that
587 // require librt. Most modern Linux platforms do, but some may not.
588 if (addOpenMPRuntime(C, CmdArgs, TC: ToolChain, Args, ForceStaticHostRuntime: StaticOpenMP,
589 IsOffloadingHost: JA.isHostOffloading(OKind: Action::OFK_OpenMP),
590 /* GompNeedsRT= */ true))
591 // OpenMP runtimes implies pthreads when using the GNU toolchain.
592 // FIXME: Does this really make sense for all GNU toolchains?
593 WantPthread = true;
594
595 AddRunTimeLibs(TC: ToolChain, D, CmdArgs, Args);
596
597 // LLVM support for atomics on 32-bit SPARC V8+ is incomplete, so
598 // forcibly link with libatomic as a workaround.
599 // TODO: Issue #41880 and D118021.
600 if (getToolChain().getTriple().getArch() == llvm::Triple::sparc) {
601 CmdArgs.push_back(Elt: "--push-state");
602 CmdArgs.push_back(Elt: "--as-needed");
603 CmdArgs.push_back(Elt: "-latomic");
604 CmdArgs.push_back(Elt: "--pop-state");
605 }
606
607 // We don't need libpthread neither for bionic (Android) nor for musl,
608 // (used by OHOS as runtime library).
609 if (WantPthread && !isAndroid && !isOHOSFamily)
610 CmdArgs.push_back(Elt: "-lpthread");
611
612 if (Args.hasArg(options::OPT_fsplit_stack))
613 CmdArgs.push_back(Elt: "--wrap=pthread_create");
614
615 if (!Args.hasArg(options::OPT_nolibc))
616 CmdArgs.push_back(Elt: "-lc");
617
618 // Add IAMCU specific libs, if needed.
619 if (IsIAMCU)
620 CmdArgs.push_back(Elt: "-lgloss");
621
622 if (IsStatic || IsStaticPIE)
623 CmdArgs.push_back(Elt: "--end-group");
624 else
625 AddRunTimeLibs(TC: ToolChain, D, CmdArgs, Args);
626
627 // Add IAMCU specific libs (outside the group), if needed.
628 if (IsIAMCU) {
629 CmdArgs.push_back(Elt: "--as-needed");
630 CmdArgs.push_back(Elt: "-lsoftfp");
631 CmdArgs.push_back(Elt: "--no-as-needed");
632 }
633 }
634
635 if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
636 if (HasCRTBeginEndFiles) {
637 std::string P;
638 if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
639 !isAndroid) {
640 std::string crtend = ToolChain.getCompilerRT(Args, Component: "crtend",
641 Type: ToolChain::FT_Object);
642 if (ToolChain.getVFS().exists(Path: crtend))
643 P = crtend;
644 }
645 if (P.empty()) {
646 const char *crtend;
647 if (Args.hasArg(options::OPT_shared))
648 crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
649 else if (IsPIE || IsStaticPIE)
650 crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
651 else
652 crtend = isAndroid ? "crtend_android.o" : "crtend.o";
653 P = ToolChain.GetFilePath(Name: crtend);
654 }
655 CmdArgs.push_back(Elt: Args.MakeArgString(Str: P));
656 }
657 if (!isAndroid)
658 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: "crtn.o")));
659 }
660 }
661
662 Args.addAllArgs(CmdArgs, {options::OPT_T, options::OPT_t});
663
664 const char *Exec = Args.MakeArgString(Str: ToolChain.GetLinkerPath());
665 C.addCommand(C: std::make_unique<Command>(args: JA, args: *this,
666 args: ResponseFileSupport::AtFileCurCP(),
667 args&: Exec, args&: CmdArgs, args: Inputs, args: Output));
668}
669
670void tools::gnutools::Assembler::ConstructJob(Compilation &C,
671 const JobAction &JA,
672 const InputInfo &Output,
673 const InputInfoList &Inputs,
674 const ArgList &Args,
675 const char *LinkingOutput) const {
676 const auto &D = getToolChain().getDriver();
677
678 claimNoWarnArgs(Args);
679
680 ArgStringList CmdArgs;
681
682 llvm::Reloc::Model RelocationModel;
683 unsigned PICLevel;
684 bool IsPIE;
685 const char *DefaultAssembler = "as";
686 // Enforce GNU as on Solaris; the native assembler's input syntax isn't fully
687 // compatible.
688 if (getToolChain().getTriple().isOSSolaris())
689 DefaultAssembler = "gas";
690 std::tie(args&: RelocationModel, args&: PICLevel, args&: IsPIE) =
691 ParsePICArgs(ToolChain: getToolChain(), Args);
692
693 if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) {
694 if (A->getOption().getID() == options::OPT_gz) {
695 CmdArgs.push_back(Elt: "--compress-debug-sections");
696 } else {
697 StringRef Value = A->getValue();
698 if (Value == "none" || Value == "zlib" || Value == "zstd") {
699 CmdArgs.push_back(
700 Elt: Args.MakeArgString(Str: "--compress-debug-sections=" + Twine(Value)));
701 } else {
702 D.Diag(diag::err_drv_unsupported_option_argument)
703 << A->getSpelling() << Value;
704 }
705 }
706 }
707
708 switch (getToolChain().getArch()) {
709 default:
710 break;
711 // Add --32/--64 to make sure we get the format we want.
712 // This is incomplete
713 case llvm::Triple::x86:
714 CmdArgs.push_back(Elt: "--32");
715 break;
716 case llvm::Triple::x86_64:
717 if (getToolChain().getTriple().isX32())
718 CmdArgs.push_back(Elt: "--x32");
719 else
720 CmdArgs.push_back(Elt: "--64");
721 break;
722 case llvm::Triple::ppc: {
723 CmdArgs.push_back(Elt: "-a32");
724 CmdArgs.push_back(Elt: "-mppc");
725 CmdArgs.push_back(Elt: "-mbig-endian");
726 CmdArgs.push_back(Elt: ppc::getPPCAsmModeForCPU(
727 Name: getCPUName(D, Args, T: getToolChain().getTriple())));
728 break;
729 }
730 case llvm::Triple::ppcle: {
731 CmdArgs.push_back(Elt: "-a32");
732 CmdArgs.push_back(Elt: "-mppc");
733 CmdArgs.push_back(Elt: "-mlittle-endian");
734 CmdArgs.push_back(Elt: ppc::getPPCAsmModeForCPU(
735 Name: getCPUName(D, Args, T: getToolChain().getTriple())));
736 break;
737 }
738 case llvm::Triple::ppc64: {
739 CmdArgs.push_back(Elt: "-a64");
740 CmdArgs.push_back(Elt: "-mppc64");
741 CmdArgs.push_back(Elt: "-mbig-endian");
742 CmdArgs.push_back(Elt: ppc::getPPCAsmModeForCPU(
743 Name: getCPUName(D, Args, T: getToolChain().getTriple())));
744 break;
745 }
746 case llvm::Triple::ppc64le: {
747 CmdArgs.push_back(Elt: "-a64");
748 CmdArgs.push_back(Elt: "-mppc64");
749 CmdArgs.push_back(Elt: "-mlittle-endian");
750 CmdArgs.push_back(Elt: ppc::getPPCAsmModeForCPU(
751 Name: getCPUName(D, Args, T: getToolChain().getTriple())));
752 break;
753 }
754 case llvm::Triple::riscv32:
755 case llvm::Triple::riscv64: {
756 StringRef ABIName = riscv::getRISCVABI(Args, Triple: getToolChain().getTriple());
757 CmdArgs.push_back(Elt: "-mabi");
758 CmdArgs.push_back(Elt: ABIName.data());
759 std::string MArchName =
760 riscv::getRISCVArch(Args, Triple: getToolChain().getTriple());
761 CmdArgs.push_back(Elt: "-march");
762 CmdArgs.push_back(Elt: Args.MakeArgString(Str: MArchName));
763 if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
764 Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);
765 break;
766 }
767 case llvm::Triple::sparc:
768 case llvm::Triple::sparcel: {
769 CmdArgs.push_back(Elt: "-32");
770 std::string CPU = getCPUName(D, Args, T: getToolChain().getTriple());
771 CmdArgs.push_back(
772 Elt: sparc::getSparcAsmModeForCPU(Name: CPU, Triple: getToolChain().getTriple()));
773 AddAssemblerKPIC(ToolChain: getToolChain(), Args, CmdArgs);
774 break;
775 }
776 case llvm::Triple::sparcv9: {
777 CmdArgs.push_back(Elt: "-64");
778 std::string CPU = getCPUName(D, Args, T: getToolChain().getTriple());
779 CmdArgs.push_back(
780 Elt: sparc::getSparcAsmModeForCPU(Name: CPU, Triple: getToolChain().getTriple()));
781 AddAssemblerKPIC(ToolChain: getToolChain(), Args, CmdArgs);
782 break;
783 }
784 case llvm::Triple::arm:
785 case llvm::Triple::armeb:
786 case llvm::Triple::thumb:
787 case llvm::Triple::thumbeb: {
788 const llvm::Triple &Triple2 = getToolChain().getTriple();
789 CmdArgs.push_back(Elt: arm::isARMBigEndian(Triple: Triple2, Args) ? "-EB" : "-EL");
790 switch (Triple2.getSubArch()) {
791 case llvm::Triple::ARMSubArch_v7:
792 CmdArgs.push_back(Elt: "-mfpu=neon");
793 break;
794 case llvm::Triple::ARMSubArch_v8:
795 CmdArgs.push_back(Elt: "-mfpu=crypto-neon-fp-armv8");
796 break;
797 default:
798 break;
799 }
800
801 switch (arm::getARMFloatABI(TC: getToolChain(), Args)) {
802 case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");
803 case arm::FloatABI::Soft:
804 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mfloat-abi=soft"));
805 break;
806 case arm::FloatABI::SoftFP:
807 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mfloat-abi=softfp"));
808 break;
809 case arm::FloatABI::Hard:
810 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mfloat-abi=hard"));
811 break;
812 }
813
814 Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
815 normalizeCPUNamesForAssembler(Args, CmdArgs);
816
817 Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
818 // The integrated assembler doesn't implement e_flags setting behavior for
819 // -meabi=gnu (gcc -mabi={apcs-gnu,atpcs} passes -meabi=gnu to gas). For
820 // compatibility we accept but warn.
821 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
822 A->ignoreTargetSpecific();
823 break;
824 }
825 case llvm::Triple::aarch64:
826 case llvm::Triple::aarch64_be: {
827 CmdArgs.push_back(
828 Elt: getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL");
829 Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
830 normalizeCPUNamesForAssembler(Args, CmdArgs);
831
832 break;
833 }
834 // TODO: handle loongarch32.
835 case llvm::Triple::loongarch64: {
836 StringRef ABIName =
837 loongarch::getLoongArchABI(D, Args, Triple: getToolChain().getTriple());
838 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mabi=" + ABIName));
839 break;
840 }
841 case llvm::Triple::mips:
842 case llvm::Triple::mipsel:
843 case llvm::Triple::mips64:
844 case llvm::Triple::mips64el: {
845 StringRef CPUName;
846 StringRef ABIName;
847 mips::getMipsCPUAndABI(Args, Triple: getToolChain().getTriple(), CPUName, ABIName);
848 ABIName = mips::getGnuCompatibleMipsABIName(ABI: ABIName);
849
850 CmdArgs.push_back(Elt: "-march");
851 CmdArgs.push_back(Elt: CPUName.data());
852
853 CmdArgs.push_back(Elt: "-mabi");
854 CmdArgs.push_back(Elt: ABIName.data());
855
856 // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
857 // or -mshared (not implemented) is in effect.
858 if (RelocationModel == llvm::Reloc::Static)
859 CmdArgs.push_back(Elt: "-mno-shared");
860
861 // LLVM doesn't support -mplt yet and acts as if it is always given.
862 // However, -mplt has no effect with the N64 ABI.
863 if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls))
864 CmdArgs.push_back(Elt: "-call_nonpic");
865
866 if (getToolChain().getTriple().isLittleEndian())
867 CmdArgs.push_back(Elt: "-EL");
868 else
869 CmdArgs.push_back(Elt: "-EB");
870
871 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
872 if (StringRef(A->getValue()) == "2008")
873 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mnan=2008"));
874 }
875
876 // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
877 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
878 options::OPT_mfp64)) {
879 A->claim();
880 A->render(Args, Output&: CmdArgs);
881 } else if (mips::shouldUseFPXX(
882 Args, Triple: getToolChain().getTriple(), CPUName, ABIName,
883 FloatABI: mips::getMipsFloatABI(D: getToolChain().getDriver(), Args,
884 Triple: getToolChain().getTriple())))
885 CmdArgs.push_back(Elt: "-mfpxx");
886
887 // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
888 // -mno-mips16 is actually -no-mips16.
889 if (Arg *A =
890 Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {
891 if (A->getOption().matches(options::OPT_mips16)) {
892 A->claim();
893 A->render(Args, Output&: CmdArgs);
894 } else {
895 A->claim();
896 CmdArgs.push_back(Elt: "-no-mips16");
897 }
898 }
899
900 Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
901 options::OPT_mno_micromips);
902 Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
903 Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
904
905 if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
906 // Do not use AddLastArg because not all versions of MIPS assembler
907 // support -mmsa / -mno-msa options.
908 if (A->getOption().matches(options::OPT_mmsa))
909 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mmsa"));
910 }
911
912 Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
913 options::OPT_msoft_float);
914
915 Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,
916 options::OPT_msingle_float);
917
918 Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
919 options::OPT_mno_odd_spreg);
920
921 AddAssemblerKPIC(ToolChain: getToolChain(), Args, CmdArgs);
922 break;
923 }
924 case llvm::Triple::systemz: {
925 // Always pass an -march option, since our default of z10 is later
926 // than the GNU assembler's default.
927 std::string CPUName =
928 systemz::getSystemZTargetCPU(Args, T: getToolChain().getTriple());
929 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-march=" + CPUName));
930 break;
931 }
932 case llvm::Triple::ve:
933 DefaultAssembler = "nas";
934 }
935
936 for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
937 options::OPT_fdebug_prefix_map_EQ)) {
938 StringRef Map = A->getValue();
939 if (!Map.contains('='))
940 D.Diag(diag::err_drv_invalid_argument_to_option)
941 << Map << A->getOption().getName();
942 else {
943 CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map"));
944 CmdArgs.push_back(Args.MakeArgString(Map));
945 }
946 A->claim();
947 }
948
949 Args.AddAllArgs(CmdArgs, options::OPT_I);
950 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
951
952 CmdArgs.push_back(Elt: "-o");
953 CmdArgs.push_back(Elt: Output.getFilename());
954
955 for (const auto &II : Inputs)
956 CmdArgs.push_back(Elt: II.getFilename());
957
958 if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group,
959 options::OPT_gdwarf_2, options::OPT_gdwarf_3,
960 options::OPT_gdwarf_4, options::OPT_gdwarf_5,
961 options::OPT_gdwarf))
962 if (!A->getOption().matches(options::OPT_g0)) {
963 Args.AddLastArg(CmdArgs, options::OPT_g_Flag);
964
965 unsigned DwarfVersion = getDwarfVersion(TC: getToolChain(), Args);
966 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-gdwarf-" + Twine(DwarfVersion)));
967 }
968
969 const char *Exec =
970 Args.MakeArgString(Str: getToolChain().GetProgramPath(Name: DefaultAssembler));
971 C.addCommand(C: std::make_unique<Command>(args: JA, args: *this,
972 args: ResponseFileSupport::AtFileCurCP(),
973 args&: Exec, args&: CmdArgs, args: Inputs, args: Output));
974
975 // Handle the debug info splitting at object creation time if we're
976 // creating an object.
977 // TODO: Currently only works on linux with newer objcopy.
978 if (Args.hasArg(options::OPT_gsplit_dwarf) &&
979 getToolChain().getTriple().isOSLinux())
980 SplitDebugInfo(TC: getToolChain(), C, T: *this, JA, Args, Output,
981 OutFile: SplitDebugName(JA, Args, Input: Inputs[0], Output));
982}
983
984namespace {
985// Filter to remove Multilibs that don't exist as a suffix to Path
986class FilterNonExistent {
987 StringRef Base, File;
988 llvm::vfs::FileSystem &VFS;
989
990public:
991 FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS)
992 : Base(Base), File(File), VFS(VFS) {}
993 bool operator()(const Multilib &M) {
994 return !VFS.exists(Path: Base + M.gccSuffix() + File);
995 }
996};
997} // end anonymous namespace
998
999static bool isSoftFloatABI(const ArgList &Args) {
1000 Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
1001 options::OPT_mfloat_abi_EQ);
1002 if (!A)
1003 return false;
1004
1005 return A->getOption().matches(options::OPT_msoft_float) ||
1006 (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
1007 A->getValue() == StringRef("soft"));
1008}
1009
1010static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
1011 return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
1012}
1013
1014static bool isMipsEL(llvm::Triple::ArchType Arch) {
1015 return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
1016}
1017
1018static bool isMips16(const ArgList &Args) {
1019 Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
1020 return A && A->getOption().matches(options::OPT_mips16);
1021}
1022
1023static bool isMicroMips(const ArgList &Args) {
1024 Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
1025 return A && A->getOption().matches(options::OPT_mmicromips);
1026}
1027
1028static bool isMSP430(llvm::Triple::ArchType Arch) {
1029 return Arch == llvm::Triple::msp430;
1030}
1031
1032static bool findMipsCsMultilibs(const Driver &D,
1033 const Multilib::flags_list &Flags,
1034 FilterNonExistent &NonExistent,
1035 DetectedMultilibs &Result) {
1036 // Check for Code Sourcery toolchain multilibs
1037 MultilibSet CSMipsMultilibs;
1038 {
1039 auto MArchMips16 = MultilibBuilder("/mips16").flag(Flag: "-m32").flag(Flag: "-mips16");
1040
1041 auto MArchMicroMips =
1042 MultilibBuilder("/micromips").flag(Flag: "-m32").flag(Flag: "-mmicromips");
1043
1044 auto MArchDefault = MultilibBuilder("")
1045 .flag(Flag: "-mips16", /*Disallow=*/true)
1046 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1047
1048 auto UCLibc = MultilibBuilder("/uclibc").flag(Flag: "-muclibc");
1049
1050 auto SoftFloat = MultilibBuilder("/soft-float").flag(Flag: "-msoft-float");
1051
1052 auto Nan2008 = MultilibBuilder("/nan2008").flag(Flag: "-mnan=2008");
1053
1054 auto DefaultFloat = MultilibBuilder("")
1055 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1056 .flag(Flag: "-mnan=2008", /*Disallow=*/true);
1057
1058 auto BigEndian =
1059 MultilibBuilder("").flag(Flag: "-EB").flag(Flag: "-EL", /*Disallow=*/true);
1060
1061 auto LittleEndian =
1062 MultilibBuilder("/el").flag(Flag: "-EL").flag(Flag: "-EB", /*Disallow=*/true);
1063
1064 // Note that this one's osSuffix is ""
1065 auto MAbi64 = MultilibBuilder("")
1066 .gccSuffix(S: "/64")
1067 .includeSuffix(S: "/64")
1068 .flag(Flag: "-mabi=n64")
1069 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1070 .flag(Flag: "-m32", /*Disallow=*/true);
1071
1072 CSMipsMultilibs =
1073 MultilibSetBuilder()
1074 .Either(M1: MArchMips16, M2: MArchMicroMips, M3: MArchDefault)
1075 .Maybe(M: UCLibc)
1076 .Either(M1: SoftFloat, M2: Nan2008, M3: DefaultFloat)
1077 .FilterOut(Regex: "/micromips/nan2008")
1078 .FilterOut(Regex: "/mips16/nan2008")
1079 .Either(M1: BigEndian, M2: LittleEndian)
1080 .Maybe(M: MAbi64)
1081 .FilterOut(Regex: "/mips16.*/64")
1082 .FilterOut(Regex: "/micromips.*/64")
1083 .makeMultilibSet()
1084 .FilterOut(F: NonExistent)
1085 .setIncludeDirsCallback([](const Multilib &M) {
1086 std::vector<std::string> Dirs({"/include"});
1087 if (StringRef(M.includeSuffix()).starts_with(Prefix: "/uclibc"))
1088 Dirs.push_back(
1089 x: "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
1090 else
1091 Dirs.push_back(x: "/../../../../mips-linux-gnu/libc/usr/include");
1092 return Dirs;
1093 });
1094 }
1095
1096 MultilibSet DebianMipsMultilibs;
1097 {
1098 MultilibBuilder MAbiN32 =
1099 MultilibBuilder().gccSuffix(S: "/n32").includeSuffix(S: "/n32").flag(
1100 Flag: "-mabi=n32");
1101
1102 MultilibBuilder M64 = MultilibBuilder()
1103 .gccSuffix(S: "/64")
1104 .includeSuffix(S: "/64")
1105 .flag(Flag: "-m64")
1106 .flag(Flag: "-m32", /*Disallow=*/true)
1107 .flag(Flag: "-mabi=n32", /*Disallow=*/true);
1108
1109 MultilibBuilder M32 = MultilibBuilder()
1110 .gccSuffix(S: "/32")
1111 .flag(Flag: "-m64", /*Disallow=*/true)
1112 .flag(Flag: "-m32")
1113 .flag(Flag: "-mabi=n32", /*Disallow=*/true);
1114
1115 DebianMipsMultilibs = MultilibSetBuilder()
1116 .Either(M1: M32, M2: M64, M3: MAbiN32)
1117 .makeMultilibSet()
1118 .FilterOut(F: NonExistent);
1119 }
1120
1121 // Sort candidates. Toolchain that best meets the directories tree goes first.
1122 // Then select the first toolchains matches command line flags.
1123 MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
1124 if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
1125 std::iter_swap(a: Candidates, b: Candidates + 1);
1126 for (const MultilibSet *Candidate : Candidates) {
1127 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {
1128 if (Candidate == &DebianMipsMultilibs)
1129 Result.BiarchSibling = Multilib();
1130 Result.Multilibs = *Candidate;
1131 return true;
1132 }
1133 }
1134 return false;
1135}
1136
1137static bool findMipsMuslMultilibs(const Driver &D,
1138 const Multilib::flags_list &Flags,
1139 FilterNonExistent &NonExistent,
1140 DetectedMultilibs &Result) {
1141 // Musl toolchain multilibs
1142 MultilibSet MuslMipsMultilibs;
1143 {
1144 auto MArchMipsR2 = MultilibBuilder("")
1145 .osSuffix(S: "/mips-r2-hard-musl")
1146 .flag(Flag: "-EB")
1147 .flag(Flag: "-EL", /*Disallow=*/true)
1148 .flag(Flag: "-march=mips32r2");
1149
1150 auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl")
1151 .flag(Flag: "-EB", /*Disallow=*/true)
1152 .flag(Flag: "-EL")
1153 .flag(Flag: "-march=mips32r2");
1154
1155 MuslMipsMultilibs = MultilibSetBuilder()
1156 .Either(M1: MArchMipsR2, M2: MArchMipselR2)
1157 .makeMultilibSet();
1158
1159 // Specify the callback that computes the include directories.
1160 MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
1161 return std::vector<std::string>(
1162 {"/../sysroot" + M.osSuffix() + "/usr/include"});
1163 });
1164 }
1165 if (MuslMipsMultilibs.select(D, Flags, Result.SelectedMultilibs)) {
1166 Result.Multilibs = MuslMipsMultilibs;
1167 return true;
1168 }
1169 return false;
1170}
1171
1172static bool findMipsMtiMultilibs(const Driver &D,
1173 const Multilib::flags_list &Flags,
1174 FilterNonExistent &NonExistent,
1175 DetectedMultilibs &Result) {
1176 // CodeScape MTI toolchain v1.2 and early.
1177 MultilibSet MtiMipsMultilibsV1;
1178 {
1179 auto MArchMips32 = MultilibBuilder("/mips32")
1180 .flag(Flag: "-m32")
1181 .flag(Flag: "-m64", /*Disallow=*/true)
1182 .flag(Flag: "-mmicromips", /*Disallow=*/true)
1183 .flag(Flag: "-march=mips32");
1184
1185 auto MArchMicroMips = MultilibBuilder("/micromips")
1186 .flag(Flag: "-m32")
1187 .flag(Flag: "-m64", /*Disallow=*/true)
1188 .flag(Flag: "-mmicromips");
1189
1190 auto MArchMips64r2 = MultilibBuilder("/mips64r2")
1191 .flag(Flag: "-m32", /*Disallow=*/true)
1192 .flag(Flag: "-m64")
1193 .flag(Flag: "-march=mips64r2");
1194
1195 auto MArchMips64 = MultilibBuilder("/mips64")
1196 .flag(Flag: "-m32", /*Disallow=*/true)
1197 .flag(Flag: "-m64")
1198 .flag(Flag: "-march=mips64r2", /*Disallow=*/true);
1199
1200 auto MArchDefault = MultilibBuilder("")
1201 .flag(Flag: "-m32")
1202 .flag(Flag: "-m64", /*Disallow=*/true)
1203 .flag(Flag: "-mmicromips", /*Disallow=*/true)
1204 .flag(Flag: "-march=mips32r2");
1205
1206 auto Mips16 = MultilibBuilder("/mips16").flag(Flag: "-mips16");
1207
1208 auto UCLibc = MultilibBuilder("/uclibc").flag(Flag: "-muclibc");
1209
1210 auto MAbi64 = MultilibBuilder("/64")
1211 .flag(Flag: "-mabi=n64")
1212 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1213 .flag(Flag: "-m32", /*Disallow=*/true);
1214
1215 auto BigEndian =
1216 MultilibBuilder("").flag(Flag: "-EB").flag(Flag: "-EL", /*Disallow=*/true);
1217
1218 auto LittleEndian =
1219 MultilibBuilder("/el").flag(Flag: "-EL").flag(Flag: "-EB", /*Disallow=*/true);
1220
1221 auto SoftFloat = MultilibBuilder("/sof").flag(Flag: "-msoft-float");
1222
1223 auto Nan2008 = MultilibBuilder("/nan2008").flag(Flag: "-mnan=2008");
1224
1225 MtiMipsMultilibsV1 =
1226 MultilibSetBuilder()
1227 .Either(M1: MArchMips32, M2: MArchMicroMips, M3: MArchMips64r2, M4: MArchMips64,
1228 M5: MArchDefault)
1229 .Maybe(M: UCLibc)
1230 .Maybe(M: Mips16)
1231 .FilterOut(Regex: "/mips64/mips16")
1232 .FilterOut(Regex: "/mips64r2/mips16")
1233 .FilterOut(Regex: "/micromips/mips16")
1234 .Maybe(M: MAbi64)
1235 .FilterOut(Regex: "/micromips/64")
1236 .FilterOut(Regex: "/mips32/64")
1237 .FilterOut(Regex: "^/64")
1238 .FilterOut(Regex: "/mips16/64")
1239 .Either(M1: BigEndian, M2: LittleEndian)
1240 .Maybe(M: SoftFloat)
1241 .Maybe(M: Nan2008)
1242 .FilterOut(Regex: ".*sof/nan2008")
1243 .makeMultilibSet()
1244 .FilterOut(F: NonExistent)
1245 .setIncludeDirsCallback([](const Multilib &M) {
1246 std::vector<std::string> Dirs({"/include"});
1247 if (StringRef(M.includeSuffix()).starts_with(Prefix: "/uclibc"))
1248 Dirs.push_back(x: "/../../../../sysroot/uclibc/usr/include");
1249 else
1250 Dirs.push_back(x: "/../../../../sysroot/usr/include");
1251 return Dirs;
1252 });
1253 }
1254
1255 // CodeScape IMG toolchain starting from v1.3.
1256 MultilibSet MtiMipsMultilibsV2;
1257 {
1258 auto BeHard = MultilibBuilder("/mips-r2-hard")
1259 .flag(Flag: "-EB")
1260 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1261 .flag(Flag: "-mnan=2008", /*Disallow=*/true)
1262 .flag(Flag: "-muclibc", /*Disallow=*/true);
1263 auto BeSoft = MultilibBuilder("/mips-r2-soft")
1264 .flag(Flag: "-EB")
1265 .flag(Flag: "-msoft-float")
1266 .flag(Flag: "-mnan=2008", /*Disallow=*/true);
1267 auto ElHard = MultilibBuilder("/mipsel-r2-hard")
1268 .flag(Flag: "-EL")
1269 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1270 .flag(Flag: "-mnan=2008", /*Disallow=*/true)
1271 .flag(Flag: "-muclibc", /*Disallow=*/true);
1272 auto ElSoft = MultilibBuilder("/mipsel-r2-soft")
1273 .flag(Flag: "-EL")
1274 .flag(Flag: "-msoft-float")
1275 .flag(Flag: "-mnan=2008", /*Disallow=*/true)
1276 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1277 auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008")
1278 .flag(Flag: "-EB")
1279 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1280 .flag(Flag: "-mnan=2008")
1281 .flag(Flag: "-muclibc", /*Disallow=*/true);
1282 auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008")
1283 .flag(Flag: "-EL")
1284 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1285 .flag(Flag: "-mnan=2008")
1286 .flag(Flag: "-muclibc", /*Disallow=*/true)
1287 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1288 auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc")
1289 .flag(Flag: "-EB")
1290 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1291 .flag(Flag: "-mnan=2008")
1292 .flag(Flag: "-muclibc");
1293 auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc")
1294 .flag(Flag: "-EL")
1295 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1296 .flag(Flag: "-mnan=2008")
1297 .flag(Flag: "-muclibc");
1298 auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc")
1299 .flag(Flag: "-EB")
1300 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1301 .flag(Flag: "-mnan=2008", /*Disallow=*/true)
1302 .flag(Flag: "-muclibc");
1303 auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc")
1304 .flag(Flag: "-EL")
1305 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1306 .flag(Flag: "-mnan=2008", /*Disallow=*/true)
1307 .flag(Flag: "-muclibc");
1308 auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008")
1309 .flag(Flag: "-EL")
1310 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1311 .flag(Flag: "-mnan=2008")
1312 .flag(Flag: "-mmicromips");
1313 auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft")
1314 .flag(Flag: "-EL")
1315 .flag(Flag: "-msoft-float")
1316 .flag(Flag: "-mnan=2008", /*Disallow=*/true)
1317 .flag(Flag: "-mmicromips");
1318
1319 auto O32 = MultilibBuilder("/lib")
1320 .osSuffix(S: "")
1321 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1322 .flag(Flag: "-mabi=n64", /*Disallow=*/true);
1323 auto N32 = MultilibBuilder("/lib32")
1324 .osSuffix(S: "")
1325 .flag(Flag: "-mabi=n32")
1326 .flag(Flag: "-mabi=n64", /*Disallow=*/true);
1327 auto N64 = MultilibBuilder("/lib64")
1328 .osSuffix(S: "")
1329 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1330 .flag(Flag: "-mabi=n64");
1331
1332 MtiMipsMultilibsV2 =
1333 MultilibSetBuilder()
1334 .Either(Ms: {BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
1335 BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
1336 ElHardUclibc, ElMicroHardNan, ElMicroSoft})
1337 .Either(M1: O32, M2: N32, M3: N64)
1338 .makeMultilibSet()
1339 .FilterOut(F: NonExistent)
1340 .setIncludeDirsCallback([](const Multilib &M) {
1341 return std::vector<std::string>({"/../../../../sysroot" +
1342 M.includeSuffix() +
1343 "/../usr/include"});
1344 })
1345 .setFilePathsCallback([](const Multilib &M) {
1346 return std::vector<std::string>(
1347 {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
1348 });
1349 }
1350 for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
1351 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {
1352 Result.Multilibs = *Candidate;
1353 return true;
1354 }
1355 }
1356 return false;
1357}
1358
1359static bool findMipsImgMultilibs(const Driver &D,
1360 const Multilib::flags_list &Flags,
1361 FilterNonExistent &NonExistent,
1362 DetectedMultilibs &Result) {
1363 // CodeScape IMG toolchain v1.2 and early.
1364 MultilibSet ImgMultilibsV1;
1365 {
1366 auto Mips64r6 = MultilibBuilder("/mips64r6")
1367 .flag(Flag: "-m64")
1368 .flag(Flag: "-m32", /*Disallow=*/true);
1369
1370 auto LittleEndian =
1371 MultilibBuilder("/el").flag(Flag: "-EL").flag(Flag: "-EB", /*Disallow=*/true);
1372
1373 auto MAbi64 = MultilibBuilder("/64")
1374 .flag(Flag: "-mabi=n64")
1375 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1376 .flag(Flag: "-m32", /*Disallow=*/true);
1377
1378 ImgMultilibsV1 =
1379 MultilibSetBuilder()
1380 .Maybe(M: Mips64r6)
1381 .Maybe(M: MAbi64)
1382 .Maybe(M: LittleEndian)
1383 .makeMultilibSet()
1384 .FilterOut(F: NonExistent)
1385 .setIncludeDirsCallback([](const Multilib &M) {
1386 return std::vector<std::string>(
1387 {"/include", "/../../../../sysroot/usr/include"});
1388 });
1389 }
1390
1391 // CodeScape IMG toolchain starting from v1.3.
1392 MultilibSet ImgMultilibsV2;
1393 {
1394 auto BeHard = MultilibBuilder("/mips-r6-hard")
1395 .flag(Flag: "-EB")
1396 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1397 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1398 auto BeSoft = MultilibBuilder("/mips-r6-soft")
1399 .flag(Flag: "-EB")
1400 .flag(Flag: "-msoft-float")
1401 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1402 auto ElHard = MultilibBuilder("/mipsel-r6-hard")
1403 .flag(Flag: "-EL")
1404 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1405 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1406 auto ElSoft = MultilibBuilder("/mipsel-r6-soft")
1407 .flag(Flag: "-EL")
1408 .flag(Flag: "-msoft-float")
1409 .flag(Flag: "-mmicromips", /*Disallow=*/true);
1410 auto BeMicroHard = MultilibBuilder("/micromips-r6-hard")
1411 .flag(Flag: "-EB")
1412 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1413 .flag(Flag: "-mmicromips");
1414 auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft")
1415 .flag(Flag: "-EB")
1416 .flag(Flag: "-msoft-float")
1417 .flag(Flag: "-mmicromips");
1418 auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard")
1419 .flag(Flag: "-EL")
1420 .flag(Flag: "-msoft-float", /*Disallow=*/true)
1421 .flag(Flag: "-mmicromips");
1422 auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft")
1423 .flag(Flag: "-EL")
1424 .flag(Flag: "-msoft-float")
1425 .flag(Flag: "-mmicromips");
1426
1427 auto O32 = MultilibBuilder("/lib")
1428 .osSuffix(S: "")
1429 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1430 .flag(Flag: "-mabi=n64", /*Disallow=*/true);
1431 auto N32 = MultilibBuilder("/lib32")
1432 .osSuffix(S: "")
1433 .flag(Flag: "-mabi=n32")
1434 .flag(Flag: "-mabi=n64", /*Disallow=*/true);
1435 auto N64 = MultilibBuilder("/lib64")
1436 .osSuffix(S: "")
1437 .flag(Flag: "-mabi=n32", /*Disallow=*/true)
1438 .flag(Flag: "-mabi=n64");
1439
1440 ImgMultilibsV2 =
1441 MultilibSetBuilder()
1442 .Either(Ms: {BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
1443 ElMicroHard, ElMicroSoft})
1444 .Either(M1: O32, M2: N32, M3: N64)
1445 .makeMultilibSet()
1446 .FilterOut(F: NonExistent)
1447 .setIncludeDirsCallback([](const Multilib &M) {
1448 return std::vector<std::string>({"/../../../../sysroot" +
1449 M.includeSuffix() +
1450 "/../usr/include"});
1451 })
1452 .setFilePathsCallback([](const Multilib &M) {
1453 return std::vector<std::string>(
1454 {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
1455 });
1456 }
1457 for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
1458 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {
1459 Result.Multilibs = *Candidate;
1460 return true;
1461 }
1462 }
1463 return false;
1464}
1465
1466bool clang::driver::findMIPSMultilibs(const Driver &D,
1467 const llvm::Triple &TargetTriple,
1468 StringRef Path, const ArgList &Args,
1469 DetectedMultilibs &Result) {
1470 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
1471
1472 StringRef CPUName;
1473 StringRef ABIName;
1474 tools::mips::getMipsCPUAndABI(Args, Triple: TargetTriple, CPUName, ABIName);
1475
1476 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
1477
1478 Multilib::flags_list Flags;
1479 addMultilibFlag(Enabled: TargetTriple.isMIPS32(), Flag: "-m32", Flags);
1480 addMultilibFlag(Enabled: TargetTriple.isMIPS64(), Flag: "-m64", Flags);
1481 addMultilibFlag(Enabled: isMips16(Args), Flag: "-mips16", Flags);
1482 addMultilibFlag(Enabled: CPUName == "mips32", Flag: "-march=mips32", Flags);
1483 addMultilibFlag(Enabled: CPUName == "mips32r2" || CPUName == "mips32r3" ||
1484 CPUName == "mips32r5" || CPUName == "p5600",
1485 Flag: "-march=mips32r2", Flags);
1486 addMultilibFlag(Enabled: CPUName == "mips32r6", Flag: "-march=mips32r6", Flags);
1487 addMultilibFlag(Enabled: CPUName == "mips64", Flag: "-march=mips64", Flags);
1488 addMultilibFlag(Enabled: CPUName == "mips64r2" || CPUName == "mips64r3" ||
1489 CPUName == "mips64r5" || CPUName == "octeon" ||
1490 CPUName == "octeon+",
1491 Flag: "-march=mips64r2", Flags);
1492 addMultilibFlag(Enabled: CPUName == "mips64r6" || CPUName == "i6400" ||
1493 CPUName == "i6500",
1494 Flag: "-march=mips64r6", Flags);
1495 addMultilibFlag(Enabled: isMicroMips(Args), Flag: "-mmicromips", Flags);
1496 addMultilibFlag(Enabled: tools::mips::isUCLibc(Args), Flag: "-muclibc", Flags);
1497 addMultilibFlag(Enabled: tools::mips::isNaN2008(D, Args, Triple: TargetTriple), Flag: "-mnan=2008",
1498 Flags);
1499 addMultilibFlag(Enabled: ABIName == "n32", Flag: "-mabi=n32", Flags);
1500 addMultilibFlag(Enabled: ABIName == "n64", Flag: "-mabi=n64", Flags);
1501 addMultilibFlag(Enabled: isSoftFloatABI(Args), Flag: "-msoft-float", Flags);
1502 addMultilibFlag(Enabled: !isSoftFloatABI(Args), Flag: "-mhard-float", Flags);
1503 addMultilibFlag(Enabled: isMipsEL(Arch: TargetArch), Flag: "-EL", Flags);
1504 addMultilibFlag(Enabled: !isMipsEL(Arch: TargetArch), Flag: "-EB", Flags);
1505
1506 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
1507 TargetTriple.getOS() == llvm::Triple::Linux &&
1508 TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
1509 return findMipsMuslMultilibs(D, Flags, NonExistent, Result);
1510
1511 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
1512 TargetTriple.getOS() == llvm::Triple::Linux &&
1513 TargetTriple.isGNUEnvironment())
1514 return findMipsMtiMultilibs(D, Flags, NonExistent, Result);
1515
1516 if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
1517 TargetTriple.getOS() == llvm::Triple::Linux &&
1518 TargetTriple.isGNUEnvironment())
1519 return findMipsImgMultilibs(D, Flags, NonExistent, Result);
1520
1521 if (findMipsCsMultilibs(D, Flags, NonExistent, Result))
1522 return true;
1523
1524 // Fallback to the regular toolchain-tree structure.
1525 Multilib Default;
1526 Result.Multilibs.push_back(M: Default);
1527 Result.Multilibs.FilterOut(F: NonExistent);
1528
1529 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs)) {
1530 Result.BiarchSibling = Multilib();
1531 return true;
1532 }
1533
1534 return false;
1535}
1536
1537static void findAndroidArmMultilibs(const Driver &D,
1538 const llvm::Triple &TargetTriple,
1539 StringRef Path, const ArgList &Args,
1540 DetectedMultilibs &Result) {
1541 // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
1542 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
1543 MultilibBuilder ArmV7Multilib = MultilibBuilder("/armv7-a")
1544 .flag(Flag: "-march=armv7-a")
1545 .flag(Flag: "-mthumb", /*Disallow=*/true);
1546 MultilibBuilder ThumbMultilib = MultilibBuilder("/thumb")
1547 .flag(Flag: "-march=armv7-a", /*Disallow=*/true)
1548 .flag(Flag: "-mthumb");
1549 MultilibBuilder ArmV7ThumbMultilib =
1550 MultilibBuilder("/armv7-a/thumb").flag(Flag: "-march=armv7-a").flag(Flag: "-mthumb");
1551 MultilibBuilder DefaultMultilib =
1552 MultilibBuilder("")
1553 .flag(Flag: "-march=armv7-a", /*Disallow=*/true)
1554 .flag(Flag: "-mthumb", /*Disallow=*/true);
1555 MultilibSet AndroidArmMultilibs =
1556 MultilibSetBuilder()
1557 .Either(M1: ThumbMultilib, M2: ArmV7Multilib, M3: ArmV7ThumbMultilib,
1558 M4: DefaultMultilib)
1559 .makeMultilibSet()
1560 .FilterOut(F: NonExistent);
1561
1562 Multilib::flags_list Flags;
1563 llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
1564 bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
1565 bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
1566 bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
1567 bool IsThumbMode = IsThumbArch ||
1568 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
1569 (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB);
1570 bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
1571 (llvm::ARM::parseArchVersion(Arch) == 7 ||
1572 (IsArmArch && Arch == "" && IsV7SubArch));
1573 addMultilibFlag(Enabled: IsArmV7Mode, Flag: "-march=armv7-a", Flags);
1574 addMultilibFlag(Enabled: IsThumbMode, Flag: "-mthumb", Flags);
1575
1576 if (AndroidArmMultilibs.select(D, Flags, Result.SelectedMultilibs))
1577 Result.Multilibs = AndroidArmMultilibs;
1578}
1579
1580static bool findMSP430Multilibs(const Driver &D,
1581 const llvm::Triple &TargetTriple,
1582 StringRef Path, const ArgList &Args,
1583 DetectedMultilibs &Result) {
1584 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
1585 MultilibBuilder WithoutExceptions =
1586 MultilibBuilder("/430").flag(Flag: "-exceptions", /*Disallow=*/true);
1587 MultilibBuilder WithExceptions =
1588 MultilibBuilder("/430/exceptions").flag(Flag: "-exceptions");
1589
1590 // FIXME: when clang starts to support msp430x ISA additional logic
1591 // to select between multilib must be implemented
1592 // MultilibBuilder MSP430xMultilib = MultilibBuilder("/large");
1593
1594 Result.Multilibs.push_back(M: WithoutExceptions.makeMultilib());
1595 Result.Multilibs.push_back(M: WithExceptions.makeMultilib());
1596 Result.Multilibs.FilterOut(F: NonExistent);
1597
1598 Multilib::flags_list Flags;
1599 addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,
1600 options::OPT_fno_exceptions, false),
1601 "-exceptions", Flags);
1602 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))
1603 return true;
1604
1605 return false;
1606}
1607
1608static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
1609 StringRef Path, const ArgList &Args,
1610 DetectedMultilibs &Result) {
1611 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
1612
1613 tools::csky::FloatABI TheFloatABI = tools::csky::getCSKYFloatABI(D, Args);
1614 std::optional<llvm::StringRef> Res =
1615 tools::csky::getCSKYArchName(D, Args, Triple: TargetTriple);
1616
1617 if (!Res)
1618 return;
1619 auto ARCHName = *Res;
1620
1621 Multilib::flags_list Flags;
1622 addMultilibFlag(Enabled: TheFloatABI == tools::csky::FloatABI::Hard, Flag: "-hard-fp",
1623 Flags);
1624 addMultilibFlag(Enabled: TheFloatABI == tools::csky::FloatABI::SoftFP, Flag: "-soft-fp",
1625 Flags);
1626 addMultilibFlag(Enabled: TheFloatABI == tools::csky::FloatABI::Soft, Flag: "-soft", Flags);
1627 addMultilibFlag(Enabled: ARCHName == "ck801", Flag: "-march=ck801", Flags);
1628 addMultilibFlag(Enabled: ARCHName == "ck802", Flag: "-march=ck802", Flags);
1629 addMultilibFlag(Enabled: ARCHName == "ck803", Flag: "-march=ck803", Flags);
1630 addMultilibFlag(Enabled: ARCHName == "ck804", Flag: "-march=ck804", Flags);
1631 addMultilibFlag(Enabled: ARCHName == "ck805", Flag: "-march=ck805", Flags);
1632 addMultilibFlag(Enabled: ARCHName == "ck807", Flag: "-march=ck807", Flags);
1633 addMultilibFlag(Enabled: ARCHName == "ck810", Flag: "-march=ck810", Flags);
1634 addMultilibFlag(Enabled: ARCHName == "ck810v", Flag: "-march=ck810v", Flags);
1635 addMultilibFlag(Enabled: ARCHName == "ck860", Flag: "-march=ck860", Flags);
1636 addMultilibFlag(Enabled: ARCHName == "ck860v", Flag: "-march=ck860v", Flags);
1637
1638 bool isBigEndian = false;
1639 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
1640 options::OPT_mbig_endian))
1641 isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
1642 addMultilibFlag(Enabled: isBigEndian, Flag: "-EB", Flags);
1643
1644 auto HardFloat = MultilibBuilder("/hard-fp").flag(Flag: "-hard-fp");
1645 auto SoftFpFloat = MultilibBuilder("/soft-fp").flag(Flag: "-soft-fp");
1646 auto SoftFloat = MultilibBuilder("").flag(Flag: "-soft");
1647 auto Arch801 = MultilibBuilder("/ck801").flag(Flag: "-march=ck801");
1648 auto Arch802 = MultilibBuilder("/ck802").flag(Flag: "-march=ck802");
1649 auto Arch803 = MultilibBuilder("/ck803").flag(Flag: "-march=ck803");
1650 // CK804 use the same library as CK803
1651 auto Arch804 = MultilibBuilder("/ck803").flag(Flag: "-march=ck804");
1652 auto Arch805 = MultilibBuilder("/ck805").flag(Flag: "-march=ck805");
1653 auto Arch807 = MultilibBuilder("/ck807").flag(Flag: "-march=ck807");
1654 auto Arch810 = MultilibBuilder("").flag(Flag: "-march=ck810");
1655 auto Arch810v = MultilibBuilder("/ck810v").flag(Flag: "-march=ck810v");
1656 auto Arch860 = MultilibBuilder("/ck860").flag(Flag: "-march=ck860");
1657 auto Arch860v = MultilibBuilder("/ck860v").flag(Flag: "-march=ck860v");
1658 auto BigEndian = MultilibBuilder("/big").flag(Flag: "-EB");
1659
1660 MultilibSet CSKYMultilibs =
1661 MultilibSetBuilder()
1662 .Maybe(M: BigEndian)
1663 .Either(Ms: {Arch801, Arch802, Arch803, Arch804, Arch805, Arch807,
1664 Arch810, Arch810v, Arch860, Arch860v})
1665 .Either(M1: HardFloat, M2: SoftFpFloat, M3: SoftFloat)
1666 .makeMultilibSet()
1667 .FilterOut(F: NonExistent);
1668
1669 if (CSKYMultilibs.select(D, Flags, Result.SelectedMultilibs))
1670 Result.Multilibs = CSKYMultilibs;
1671}
1672
1673/// Extend the multi-lib re-use selection mechanism for RISC-V.
1674/// This function will try to re-use multi-lib if they are compatible.
1675/// Definition of compatible:
1676/// - ABI must be the same.
1677/// - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
1678/// is a subset of march=rv32imc.
1679/// - march that contains atomic extension can't reuse multi-lib that
1680/// doesn't have atomic, vice versa. e.g. multi-lib=march=rv32im and
1681/// march=rv32ima are not compatible, because software and hardware
1682/// atomic operation can't work together correctly.
1683static bool
1684selectRISCVMultilib(const Driver &D, const MultilibSet &RISCVMultilibSet,
1685 StringRef Arch, const Multilib::flags_list &Flags,
1686 llvm::SmallVectorImpl<Multilib> &SelectedMultilibs) {
1687 // Try to find the perfect matching multi-lib first.
1688 if (RISCVMultilibSet.select(D, Flags, SelectedMultilibs))
1689 return true;
1690
1691 Multilib::flags_list NewFlags;
1692 std::vector<MultilibBuilder> NewMultilibs;
1693
1694 llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> ParseResult =
1695 llvm::RISCVISAInfo::parseArchString(
1696 Arch, /*EnableExperimentalExtension=*/true,
1697 /*ExperimentalExtensionVersionCheck=*/false);
1698 // Ignore any error here, we assume it will be handled in another place.
1699 if (llvm::errorToBool(Err: ParseResult.takeError()))
1700 return false;
1701
1702 auto &ISAInfo = *ParseResult;
1703
1704 addMultilibFlag(Enabled: ISAInfo->getXLen() == 32, Flag: "-m32", Flags&: NewFlags);
1705 addMultilibFlag(Enabled: ISAInfo->getXLen() == 64, Flag: "-m64", Flags&: NewFlags);
1706
1707 // Collect all flags except march=*
1708 for (StringRef Flag : Flags) {
1709 if (Flag.starts_with(Prefix: "!march=") || Flag.starts_with(Prefix: "-march="))
1710 continue;
1711
1712 NewFlags.push_back(x: Flag.str());
1713 }
1714
1715 llvm::StringSet<> AllArchExts;
1716 // Reconstruct multi-lib list, and break march option into separated
1717 // extension. e.g. march=rv32im -> +i +m
1718 for (const auto &M : RISCVMultilibSet) {
1719 bool Skip = false;
1720
1721 MultilibBuilder NewMultilib =
1722 MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
1723 for (StringRef Flag : M.flags()) {
1724 // Add back all flags except -march.
1725 if (!Flag.consume_front(Prefix: "-march=")) {
1726 NewMultilib.flag(Flag);
1727 continue;
1728 }
1729
1730 // Break down -march into individual extension.
1731 llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> MLConfigParseResult =
1732 llvm::RISCVISAInfo::parseArchString(
1733 Arch: Flag, /*EnableExperimentalExtension=*/true,
1734 /*ExperimentalExtensionVersionCheck=*/false);
1735 // Ignore any error here, we assume it will handled in another place.
1736 if (llvm::errorToBool(Err: MLConfigParseResult.takeError())) {
1737 // We might get a parsing error if rv32e in the list, we could just skip
1738 // that and process the rest of multi-lib configs.
1739 Skip = true;
1740 continue;
1741 }
1742 auto &MLConfigISAInfo = *MLConfigParseResult;
1743
1744 for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) {
1745 auto ExtName = MLConfigArchExt.first;
1746 NewMultilib.flag(Flag: Twine("-", ExtName).str());
1747
1748 if (AllArchExts.insert(key: ExtName).second) {
1749 addMultilibFlag(Enabled: ISAInfo->hasExtension(Ext: ExtName),
1750 Flag: Twine("-", ExtName).str(), Flags&: NewFlags);
1751 }
1752 }
1753
1754 // Check the XLEN explicitly.
1755 if (MLConfigISAInfo->getXLen() == 32) {
1756 NewMultilib.flag(Flag: "-m32");
1757 NewMultilib.flag(Flag: "-m64", /*Disallow*/ true);
1758 } else {
1759 NewMultilib.flag(Flag: "-m32", /*Disallow*/ true);
1760 NewMultilib.flag(Flag: "-m64");
1761 }
1762
1763 // Atomic extension must be explicitly checked, soft and hard atomic
1764 // operation never co-work correctly.
1765 if (!MLConfigISAInfo->hasExtension(Ext: "a"))
1766 NewMultilib.flag(Flag: "-a", /*Disallow*/ true);
1767 }
1768
1769 if (Skip)
1770 continue;
1771
1772 NewMultilibs.emplace_back(args&: NewMultilib);
1773 }
1774
1775 // Build an internal used only multi-lib list, used for checking any
1776 // compatible multi-lib.
1777 MultilibSet NewRISCVMultilibs =
1778 MultilibSetBuilder().Either(Ms: NewMultilibs).makeMultilibSet();
1779
1780 if (NewRISCVMultilibs.select(D, Flags: NewFlags, SelectedMultilibs))
1781 for (const Multilib &NewSelectedM : SelectedMultilibs)
1782 for (const auto &M : RISCVMultilibSet)
1783 // Look up the corresponding multi-lib entry in original multi-lib set.
1784 if (M.gccSuffix() == NewSelectedM.gccSuffix())
1785 return true;
1786
1787 return false;
1788}
1789
1790static void findRISCVBareMetalMultilibs(const Driver &D,
1791 const llvm::Triple &TargetTriple,
1792 StringRef Path, const ArgList &Args,
1793 DetectedMultilibs &Result) {
1794 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
1795 struct RiscvMultilib {
1796 StringRef march;
1797 StringRef mabi;
1798 };
1799 // currently only support the set of multilibs like riscv-gnu-toolchain does.
1800 // TODO: support MULTILIB_REUSE
1801 constexpr RiscvMultilib RISCVMultilibSet[] = {
1802 {.march: "rv32i", .mabi: "ilp32"}, {.march: "rv32im", .mabi: "ilp32"}, {.march: "rv32iac", .mabi: "ilp32"},
1803 {.march: "rv32imac", .mabi: "ilp32"}, {.march: "rv32imafc", .mabi: "ilp32f"}, {.march: "rv64imac", .mabi: "lp64"},
1804 {.march: "rv64imafdc", .mabi: "lp64d"}};
1805
1806 std::vector<MultilibBuilder> Ms;
1807 for (auto Element : RISCVMultilibSet) {
1808 // multilib path rule is ${march}/${mabi}
1809 Ms.emplace_back(
1810 args&: MultilibBuilder(
1811 (Twine(Element.march) + "/" + Twine(Element.mabi)).str())
1812 .flag(Flag: Twine("-march=", Element.march).str())
1813 .flag(Flag: Twine("-mabi=", Element.mabi).str()));
1814 }
1815 MultilibSet RISCVMultilibs =
1816 MultilibSetBuilder()
1817 .Either(Ms)
1818 .makeMultilibSet()
1819 .FilterOut(F: NonExistent)
1820 .setFilePathsCallback([](const Multilib &M) {
1821 return std::vector<std::string>(
1822 {M.gccSuffix(),
1823 "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(),
1824 "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()});
1825 });
1826
1827 Multilib::flags_list Flags;
1828 llvm::StringSet<> Added_ABIs;
1829 StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple: TargetTriple);
1830 std::string MArch = tools::riscv::getRISCVArch(Args, Triple: TargetTriple);
1831 for (auto Element : RISCVMultilibSet) {
1832 addMultilibFlag(Enabled: MArch == Element.march,
1833 Flag: Twine("-march=", Element.march).str().c_str(), Flags);
1834 if (!Added_ABIs.count(Key: Element.mabi)) {
1835 Added_ABIs.insert(key: Element.mabi);
1836 addMultilibFlag(Enabled: ABIName == Element.mabi,
1837 Flag: Twine("-mabi=", Element.mabi).str().c_str(), Flags);
1838 }
1839 }
1840
1841 if (selectRISCVMultilib(D, RISCVMultilibSet: RISCVMultilibs, Arch: MArch, Flags,
1842 SelectedMultilibs&: Result.SelectedMultilibs))
1843 Result.Multilibs = RISCVMultilibs;
1844}
1845
1846static void findRISCVMultilibs(const Driver &D,
1847 const llvm::Triple &TargetTriple, StringRef Path,
1848 const ArgList &Args, DetectedMultilibs &Result) {
1849 if (TargetTriple.getOS() == llvm::Triple::UnknownOS)
1850 return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result);
1851
1852 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
1853 MultilibBuilder Ilp32 =
1854 MultilibBuilder("lib32/ilp32").flag(Flag: "-m32").flag(Flag: "-mabi=ilp32");
1855 MultilibBuilder Ilp32f =
1856 MultilibBuilder("lib32/ilp32f").flag(Flag: "-m32").flag(Flag: "-mabi=ilp32f");
1857 MultilibBuilder Ilp32d =
1858 MultilibBuilder("lib32/ilp32d").flag(Flag: "-m32").flag(Flag: "-mabi=ilp32d");
1859 MultilibBuilder Lp64 =
1860 MultilibBuilder("lib64/lp64").flag(Flag: "-m64").flag(Flag: "-mabi=lp64");
1861 MultilibBuilder Lp64f =
1862 MultilibBuilder("lib64/lp64f").flag(Flag: "-m64").flag(Flag: "-mabi=lp64f");
1863 MultilibBuilder Lp64d =
1864 MultilibBuilder("lib64/lp64d").flag(Flag: "-m64").flag(Flag: "-mabi=lp64d");
1865 MultilibSet RISCVMultilibs =
1866 MultilibSetBuilder()
1867 .Either(Ms: {Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
1868 .makeMultilibSet()
1869 .FilterOut(F: NonExistent);
1870
1871 Multilib::flags_list Flags;
1872 bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
1873 StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple: TargetTriple);
1874
1875 addMultilibFlag(Enabled: !IsRV64, Flag: "-m32", Flags);
1876 addMultilibFlag(Enabled: IsRV64, Flag: "-m64", Flags);
1877 addMultilibFlag(Enabled: ABIName == "ilp32", Flag: "-mabi=ilp32", Flags);
1878 addMultilibFlag(Enabled: ABIName == "ilp32f", Flag: "-mabi=ilp32f", Flags);
1879 addMultilibFlag(Enabled: ABIName == "ilp32d", Flag: "-mabi=ilp32d", Flags);
1880 addMultilibFlag(Enabled: ABIName == "lp64", Flag: "-mabi=lp64", Flags);
1881 addMultilibFlag(Enabled: ABIName == "lp64f", Flag: "-mabi=lp64f", Flags);
1882 addMultilibFlag(Enabled: ABIName == "lp64d", Flag: "-mabi=lp64d", Flags);
1883
1884 if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))
1885 Result.Multilibs = RISCVMultilibs;
1886}
1887
1888static bool findBiarchMultilibs(const Driver &D,
1889 const llvm::Triple &TargetTriple,
1890 StringRef Path, const ArgList &Args,
1891 bool NeedsBiarchSuffix,
1892 DetectedMultilibs &Result) {
1893 MultilibBuilder DefaultBuilder;
1894
1895 // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
1896 // in what would normally be GCCInstallPath and put the 64-bit
1897 // libs in a subdirectory named 64. The simple logic we follow is that
1898 // *if* there is a subdirectory of the right name with crtbegin.o in it,
1899 // we use that. If not, and if not a biarch triple alias, we look for
1900 // crtbegin.o without the subdirectory.
1901
1902 StringRef Suff64 = "/64";
1903 // Solaris uses platform-specific suffixes instead of /64.
1904 if (TargetTriple.isOSSolaris()) {
1905 switch (TargetTriple.getArch()) {
1906 case llvm::Triple::x86:
1907 case llvm::Triple::x86_64:
1908 Suff64 = "/amd64";
1909 break;
1910 case llvm::Triple::sparc:
1911 case llvm::Triple::sparcv9:
1912 Suff64 = "/sparcv9";
1913 break;
1914 default:
1915 break;
1916 }
1917 }
1918
1919 Multilib Alt64 = MultilibBuilder()
1920 .gccSuffix(S: Suff64)
1921 .includeSuffix(S: Suff64)
1922 .flag(Flag: "-m32", /*Disallow=*/true)
1923 .flag(Flag: "-m64")
1924 .flag(Flag: "-mx32", /*Disallow=*/true)
1925 .makeMultilib();
1926 Multilib Alt32 = MultilibBuilder()
1927 .gccSuffix(S: "/32")
1928 .includeSuffix(S: "/32")
1929 .flag(Flag: "-m32")
1930 .flag(Flag: "-m64", /*Disallow=*/true)
1931 .flag(Flag: "-mx32", /*Disallow=*/true)
1932 .makeMultilib();
1933 Multilib Altx32 = MultilibBuilder()
1934 .gccSuffix(S: "/x32")
1935 .includeSuffix(S: "/x32")
1936 .flag(Flag: "-m32", /*Disallow=*/true)
1937 .flag(Flag: "-m64", /*Disallow=*/true)
1938 .flag(Flag: "-mx32")
1939 .makeMultilib();
1940 Multilib Alt32sparc = MultilibBuilder()
1941 .gccSuffix(S: "/sparcv8plus")
1942 .includeSuffix(S: "/sparcv8plus")
1943 .flag(Flag: "-m32")
1944 .flag(Flag: "-m64", /*Disallow=*/true)
1945 .makeMultilib();
1946
1947 // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
1948 FilterNonExistent NonExistent(
1949 Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());
1950
1951 // Determine default multilib from: 32, 64, x32
1952 // Also handle cases such as 64 on 32, 32 on 64, etc.
1953 enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
1954 const bool IsX32 = TargetTriple.isX32();
1955 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
1956 Want = WANT64;
1957 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc))
1958 Want = WANT64;
1959 else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
1960 Want = WANT64;
1961 else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
1962 Want = WANT32;
1963 else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc))
1964 Want = WANT64;
1965 else {
1966 if (TargetTriple.isArch32Bit())
1967 Want = NeedsBiarchSuffix ? WANT64 : WANT32;
1968 else if (IsX32)
1969 Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
1970 else
1971 Want = NeedsBiarchSuffix ? WANT32 : WANT64;
1972 }
1973
1974 if (Want == WANT32)
1975 DefaultBuilder.flag(Flag: "-m32")
1976 .flag(Flag: "-m64", /*Disallow=*/true)
1977 .flag(Flag: "-mx32", /*Disallow=*/true);
1978 else if (Want == WANT64)
1979 DefaultBuilder.flag(Flag: "-m32", /*Disallow=*/true)
1980 .flag(Flag: "-m64")
1981 .flag(Flag: "-mx32", /*Disallow=*/true);
1982 else if (Want == WANTX32)
1983 DefaultBuilder.flag(Flag: "-m32", /*Disallow=*/true)
1984 .flag(Flag: "-m64", /*Disallow=*/true)
1985 .flag(Flag: "-mx32");
1986 else
1987 return false;
1988
1989 Multilib Default = DefaultBuilder.makeMultilib();
1990
1991 Result.Multilibs.push_back(M: Default);
1992 Result.Multilibs.push_back(M: Alt64);
1993 Result.Multilibs.push_back(M: Alt32);
1994 Result.Multilibs.push_back(M: Altx32);
1995 Result.Multilibs.push_back(M: Alt32sparc);
1996
1997 Result.Multilibs.FilterOut(F: NonExistent);
1998
1999 Multilib::flags_list Flags;
2000 addMultilibFlag(Enabled: TargetTriple.isArch64Bit() && !IsX32, Flag: "-m64", Flags);
2001 addMultilibFlag(Enabled: TargetTriple.isArch32Bit(), Flag: "-m32", Flags);
2002 addMultilibFlag(Enabled: TargetTriple.isArch64Bit() && IsX32, Flag: "-mx32", Flags);
2003
2004 if (!Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))
2005 return false;
2006
2007 if (Result.SelectedMultilibs.back() == Alt64 ||
2008 Result.SelectedMultilibs.back() == Alt32 ||
2009 Result.SelectedMultilibs.back() == Altx32 ||
2010 Result.SelectedMultilibs.back() == Alt32sparc)
2011 Result.BiarchSibling = Default;
2012
2013 return true;
2014}
2015
2016/// Generic_GCC - A tool chain using the 'gcc' command to perform
2017/// all subcommands; this relies on gcc translating the majority of
2018/// command line options.
2019
2020/// Less-than for GCCVersion, implementing a Strict Weak Ordering.
2021bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
2022 int RHSPatch,
2023 StringRef RHSPatchSuffix) const {
2024 if (Major != RHSMajor)
2025 return Major < RHSMajor;
2026 if (Minor != RHSMinor) {
2027 // Note that versions without a specified minor sort higher than those with
2028 // a minor.
2029 if (RHSMinor == -1)
2030 return true;
2031 if (Minor == -1)
2032 return false;
2033 return Minor < RHSMinor;
2034 }
2035 if (Patch != RHSPatch) {
2036 // Note that versions without a specified patch sort higher than those with
2037 // a patch.
2038 if (RHSPatch == -1)
2039 return true;
2040 if (Patch == -1)
2041 return false;
2042
2043 // Otherwise just sort on the patch itself.
2044 return Patch < RHSPatch;
2045 }
2046 if (PatchSuffix != RHSPatchSuffix) {
2047 // Sort empty suffixes higher.
2048 if (RHSPatchSuffix.empty())
2049 return true;
2050 if (PatchSuffix.empty())
2051 return false;
2052
2053 // Provide a lexicographic sort to make this a total ordering.
2054 return PatchSuffix < RHSPatchSuffix;
2055 }
2056
2057 // The versions are equal.
2058 return false;
2059}
2060
2061/// Parse a GCCVersion object out of a string of text.
2062///
2063/// This is the primary means of forming GCCVersion objects.
2064/*static*/
2065Generic_GCC::GCCVersion Generic_GCC::GCCVersion::Parse(StringRef VersionText) {
2066 const GCCVersion BadVersion = {.Text: VersionText.str(), .Major: -1, .Minor: -1, .Patch: -1, .MajorStr: "", .MinorStr: "", .PatchSuffix: ""};
2067 std::pair<StringRef, StringRef> First = VersionText.split(Separator: '.');
2068 std::pair<StringRef, StringRef> Second = First.second.split(Separator: '.');
2069
2070 StringRef MajorStr = First.first;
2071 StringRef MinorStr = Second.first;
2072 StringRef PatchStr = Second.second;
2073
2074 GCCVersion GoodVersion = {.Text: VersionText.str(), .Major: -1, .Minor: -1, .Patch: -1, .MajorStr: "", .MinorStr: "", .PatchSuffix: ""};
2075
2076 // Parse version number strings such as:
2077 // 5
2078 // 4.4
2079 // 4.4-patched
2080 // 4.4.0
2081 // 4.4.x
2082 // 4.4.2-rc4
2083 // 4.4.x-patched
2084 // 10-win32
2085 // Split on '.', handle 1, 2 or 3 such segments. Each segment must contain
2086 // purely a number, except for the last one, where a non-number suffix
2087 // is stored in PatchSuffix. The third segment is allowed to not contain
2088 // a number at all.
2089
2090 auto TryParseLastNumber = [&](StringRef Segment, int &Number,
2091 std::string &OutStr) -> bool {
2092 // Look for a number prefix and parse that, and split out any trailing
2093 // string into GoodVersion.PatchSuffix.
2094
2095 if (size_t EndNumber = Segment.find_first_not_of(Chars: "0123456789")) {
2096 StringRef NumberStr = Segment.slice(Start: 0, End: EndNumber);
2097 if (NumberStr.getAsInteger(Radix: 10, Result&: Number) || Number < 0)
2098 return false;
2099 OutStr = NumberStr;
2100 GoodVersion.PatchSuffix = Segment.substr(Start: EndNumber);
2101 return true;
2102 }
2103 return false;
2104 };
2105 auto TryParseNumber = [](StringRef Segment, int &Number) -> bool {
2106 if (Segment.getAsInteger(Radix: 10, Result&: Number) || Number < 0)
2107 return false;
2108 return true;
2109 };
2110
2111 if (MinorStr.empty()) {
2112 // If no minor string, major is the last segment
2113 if (!TryParseLastNumber(MajorStr, GoodVersion.Major, GoodVersion.MajorStr))
2114 return BadVersion;
2115 return GoodVersion;
2116 }
2117
2118 if (!TryParseNumber(MajorStr, GoodVersion.Major))
2119 return BadVersion;
2120 GoodVersion.MajorStr = MajorStr;
2121
2122 if (PatchStr.empty()) {
2123 // If no patch string, minor is the last segment
2124 if (!TryParseLastNumber(MinorStr, GoodVersion.Minor, GoodVersion.MinorStr))
2125 return BadVersion;
2126 return GoodVersion;
2127 }
2128
2129 if (!TryParseNumber(MinorStr, GoodVersion.Minor))
2130 return BadVersion;
2131 GoodVersion.MinorStr = MinorStr;
2132
2133 // For the last segment, tolerate a missing number.
2134 std::string DummyStr;
2135 TryParseLastNumber(PatchStr, GoodVersion.Patch, DummyStr);
2136 return GoodVersion;
2137}
2138
2139static llvm::StringRef getGCCToolchainDir(const ArgList &Args,
2140 llvm::StringRef SysRoot) {
2141 const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain);
2142 if (A)
2143 return A->getValue();
2144
2145 // If we have a SysRoot, ignore GCC_INSTALL_PREFIX.
2146 // GCC_INSTALL_PREFIX specifies the gcc installation for the default
2147 // sysroot and is likely not valid with a different sysroot.
2148 if (!SysRoot.empty())
2149 return "";
2150
2151 return GCC_INSTALL_PREFIX;
2152}
2153
2154/// Initialize a GCCInstallationDetector from the driver.
2155///
2156/// This performs all of the autodetection and sets up the various paths.
2157/// Once constructed, a GCCInstallationDetector is essentially immutable.
2158///
2159/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
2160/// should instead pull the target out of the driver. This is currently
2161/// necessary because the driver doesn't store the final version of the target
2162/// triple.
2163void Generic_GCC::GCCInstallationDetector::init(
2164 const llvm::Triple &TargetTriple, const ArgList &Args) {
2165 llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
2166 ? TargetTriple.get64BitArchVariant()
2167 : TargetTriple.get32BitArchVariant();
2168 // The library directories which may contain GCC installations.
2169 SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
2170 // The compatible GCC triples for this particular architecture.
2171 SmallVector<StringRef, 16> CandidateTripleAliases;
2172 SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
2173 // Add some triples that we want to check first.
2174 CandidateTripleAliases.push_back(Elt: TargetTriple.str());
2175 std::string TripleNoVendor, BiarchTripleNoVendor;
2176 if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor) {
2177 StringRef OSEnv = TargetTriple.getOSAndEnvironmentName();
2178 if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32)
2179 OSEnv = "linux-gnu";
2180 TripleNoVendor = (TargetTriple.getArchName().str() + '-' + OSEnv).str();
2181 CandidateTripleAliases.push_back(Elt: TripleNoVendor);
2182 if (BiarchVariantTriple.getArch() != llvm::Triple::UnknownArch) {
2183 BiarchTripleNoVendor =
2184 (BiarchVariantTriple.getArchName().str() + '-' + OSEnv).str();
2185 CandidateBiarchTripleAliases.push_back(Elt: BiarchTripleNoVendor);
2186 }
2187 }
2188
2189 CollectLibDirsAndTriples(TargetTriple, BiarchTriple: BiarchVariantTriple, LibDirs&: CandidateLibDirs,
2190 TripleAliases&: CandidateTripleAliases, BiarchLibDirs&: CandidateBiarchLibDirs,
2191 BiarchTripleAliases&: CandidateBiarchTripleAliases);
2192
2193 // If --gcc-install-dir= is specified, skip filesystem detection.
2194 if (const Arg *A =
2195 Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ);
2196 A && A->getValue()[0]) {
2197 StringRef InstallDir = A->getValue();
2198 if (!ScanGCCForMultilibs(TargetTriple, Args, Path: InstallDir, NeedsBiarchSuffix: false)) {
2199 D.Diag(diag::err_drv_invalid_gcc_install_dir) << InstallDir;
2200 } else {
2201 (void)InstallDir.consume_back(Suffix: "/");
2202 StringRef VersionText = llvm::sys::path::filename(path: InstallDir);
2203 StringRef TripleText =
2204 llvm::sys::path::filename(path: llvm::sys::path::parent_path(path: InstallDir));
2205
2206 Version = GCCVersion::Parse(VersionText);
2207 GCCTriple.setTriple(TripleText);
2208 GCCInstallPath = std::string(InstallDir);
2209 GCCParentLibPath = GCCInstallPath + "/../../..";
2210 IsValid = true;
2211 }
2212 return;
2213 }
2214
2215 // If --gcc-triple is specified use this instead of trying to
2216 // auto-detect a triple.
2217 if (const Arg *A =
2218 Args.getLastArg(clang::driver::options::OPT_gcc_triple_EQ)) {
2219 StringRef GCCTriple = A->getValue();
2220 CandidateTripleAliases.clear();
2221 CandidateTripleAliases.push_back(Elt: GCCTriple);
2222 }
2223
2224 // Compute the set of prefixes for our search.
2225 SmallVector<std::string, 8> Prefixes;
2226 StringRef GCCToolchainDir = getGCCToolchainDir(Args, SysRoot: D.SysRoot);
2227 if (GCCToolchainDir != "") {
2228 if (GCCToolchainDir.back() == '/')
2229 GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
2230
2231 Prefixes.push_back(Elt: std::string(GCCToolchainDir));
2232 } else {
2233 // If we have a SysRoot, try that first.
2234 if (!D.SysRoot.empty()) {
2235 Prefixes.push_back(Elt: D.SysRoot);
2236 AddDefaultGCCPrefixes(TargetTriple, Prefixes, SysRoot: D.SysRoot);
2237 }
2238
2239 // Then look for gcc installed alongside clang.
2240 Prefixes.push_back(Elt: D.Dir + "/..");
2241
2242 // Next, look for prefix(es) that correspond to distribution-supplied gcc
2243 // installations.
2244 if (D.SysRoot.empty()) {
2245 // Typically /usr.
2246 AddDefaultGCCPrefixes(TargetTriple, Prefixes, SysRoot: D.SysRoot);
2247 }
2248
2249 // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided.
2250 // This avoids accidentally enforcing the system GCC version when using a
2251 // custom toolchain.
2252 SmallVector<StringRef, 16> GentooTestTriples;
2253 // Try to match an exact triple as target triple first.
2254 // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for
2255 // x86_64-gentoo-linux-gnu. But "clang -target x86_64-gentoo-linux-gnu"
2256 // may pick the libraries for x86_64-pc-linux-gnu even when exact matching
2257 // triple x86_64-gentoo-linux-gnu is present.
2258 GentooTestTriples.push_back(Elt: TargetTriple.str());
2259 GentooTestTriples.append(in_start: CandidateTripleAliases.begin(),
2260 in_end: CandidateTripleAliases.end());
2261 if (ScanGentooConfigs(TargetTriple, Args, CandidateTriples: GentooTestTriples,
2262 BiarchTriples: CandidateBiarchTripleAliases))
2263 return;
2264 }
2265
2266 // Loop over the various components which exist and select the best GCC
2267 // installation available. GCC installs are ranked by version number.
2268 const GCCVersion VersionZero = GCCVersion::Parse(VersionText: "0.0.0");
2269 Version = VersionZero;
2270 for (const std::string &Prefix : Prefixes) {
2271 auto &VFS = D.getVFS();
2272 if (!VFS.exists(Path: Prefix))
2273 continue;
2274 for (StringRef Suffix : CandidateLibDirs) {
2275 const std::string LibDir = concat(Path: Prefix, A: Suffix);
2276 if (!VFS.exists(Path: LibDir))
2277 continue;
2278 // Maybe filter out <libdir>/gcc and <libdir>/gcc-cross.
2279 bool GCCDirExists = VFS.exists(Path: LibDir + "/gcc");
2280 bool GCCCrossDirExists = VFS.exists(Path: LibDir + "/gcc-cross");
2281 for (StringRef Candidate : CandidateTripleAliases)
2282 ScanLibDirForGCCTriple(TargetArch: TargetTriple, Args, LibDir, CandidateTriple: Candidate, NeedsBiarchSuffix: false,
2283 GCCDirExists, GCCCrossDirExists);
2284 }
2285 for (StringRef Suffix : CandidateBiarchLibDirs) {
2286 const std::string LibDir = Prefix + Suffix.str();
2287 if (!VFS.exists(Path: LibDir))
2288 continue;
2289 bool GCCDirExists = VFS.exists(Path: LibDir + "/gcc");
2290 bool GCCCrossDirExists = VFS.exists(Path: LibDir + "/gcc-cross");
2291 for (StringRef Candidate : CandidateBiarchTripleAliases)
2292 ScanLibDirForGCCTriple(TargetArch: TargetTriple, Args, LibDir, CandidateTriple: Candidate, NeedsBiarchSuffix: true,
2293 GCCDirExists, GCCCrossDirExists);
2294 }
2295
2296 // Skip other prefixes once a GCC installation is found.
2297 if (Version > VersionZero)
2298 break;
2299 }
2300}
2301
2302void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
2303 for (const auto &InstallPath : CandidateGCCInstallPaths)
2304 OS << "Found candidate GCC installation: " << InstallPath << "\n";
2305
2306 if (!GCCInstallPath.empty())
2307 OS << "Selected GCC installation: " << GCCInstallPath << "\n";
2308
2309 for (const auto &Multilib : Multilibs)
2310 OS << "Candidate multilib: " << Multilib << "\n";
2311
2312 if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
2313 OS << "Selected multilib: " << SelectedMultilib << "\n";
2314}
2315
2316bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
2317 if (BiarchSibling) {
2318 M = *BiarchSibling;
2319 return true;
2320 }
2321 return false;
2322}
2323
2324void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
2325 const llvm::Triple &TargetTriple, SmallVectorImpl<std::string> &Prefixes,
2326 StringRef SysRoot) {
2327
2328 if (TargetTriple.isOSHaiku()) {
2329 Prefixes.push_back(Elt: concat(Path: SysRoot, A: "/boot/system/develop/tools"));
2330 return;
2331 }
2332
2333 if (TargetTriple.isOSSolaris()) {
2334 // Solaris is a special case.
2335 // The GCC installation is under
2336 // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/
2337 // so we need to find those /usr/gcc/*/lib/gcc libdirs and go with
2338 // /usr/gcc/<version> as a prefix.
2339
2340 SmallVector<std::pair<GCCVersion, std::string>, 8> SolarisPrefixes;
2341 std::string PrefixDir = concat(Path: SysRoot, A: "/usr/gcc");
2342 std::error_code EC;
2343 for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Dir: PrefixDir, EC),
2344 LE;
2345 !EC && LI != LE; LI = LI.increment(EC)) {
2346 StringRef VersionText = llvm::sys::path::filename(path: LI->path());
2347 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
2348
2349 // Filter out obviously bad entries.
2350 if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(RHSMajor: 4, RHSMinor: 1, RHSPatch: 1))
2351 continue;
2352
2353 std::string CandidatePrefix = PrefixDir + "/" + VersionText.str();
2354 std::string CandidateLibPath = CandidatePrefix + "/lib/gcc";
2355 if (!D.getVFS().exists(Path: CandidateLibPath))
2356 continue;
2357
2358 SolarisPrefixes.emplace_back(
2359 Args: std::make_pair(x&: CandidateVersion, y&: CandidatePrefix));
2360 }
2361 // Sort in reverse order so GCCInstallationDetector::init picks the latest.
2362 std::sort(first: SolarisPrefixes.rbegin(), last: SolarisPrefixes.rend());
2363 for (auto p : SolarisPrefixes)
2364 Prefixes.emplace_back(Args&: p.second);
2365 return;
2366 }
2367
2368 // For Linux, if --sysroot is not specified, look for RHEL/CentOS devtoolsets
2369 // and gcc-toolsets.
2370 if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&
2371 D.getVFS().exists(Path: "/opt/rh")) {
2372 // TODO: We may want to remove this, since the functionality
2373 // can be achieved using config files.
2374 Prefixes.push_back(Elt: "/opt/rh/gcc-toolset-12/root/usr");
2375 Prefixes.push_back(Elt: "/opt/rh/gcc-toolset-11/root/usr");
2376 Prefixes.push_back(Elt: "/opt/rh/gcc-toolset-10/root/usr");
2377 Prefixes.push_back(Elt: "/opt/rh/devtoolset-12/root/usr");
2378 Prefixes.push_back(Elt: "/opt/rh/devtoolset-11/root/usr");
2379 Prefixes.push_back(Elt: "/opt/rh/devtoolset-10/root/usr");
2380 Prefixes.push_back(Elt: "/opt/rh/devtoolset-9/root/usr");
2381 Prefixes.push_back(Elt: "/opt/rh/devtoolset-8/root/usr");
2382 Prefixes.push_back(Elt: "/opt/rh/devtoolset-7/root/usr");
2383 Prefixes.push_back(Elt: "/opt/rh/devtoolset-6/root/usr");
2384 Prefixes.push_back(Elt: "/opt/rh/devtoolset-4/root/usr");
2385 Prefixes.push_back(Elt: "/opt/rh/devtoolset-3/root/usr");
2386 Prefixes.push_back(Elt: "/opt/rh/devtoolset-2/root/usr");
2387 }
2388
2389 // Fall back to /usr which is used by most non-Solaris systems.
2390 Prefixes.push_back(Elt: concat(Path: SysRoot, A: "/usr"));
2391}
2392
2393/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
2394 const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
2395 SmallVectorImpl<StringRef> &LibDirs,
2396 SmallVectorImpl<StringRef> &TripleAliases,
2397 SmallVectorImpl<StringRef> &BiarchLibDirs,
2398 SmallVectorImpl<StringRef> &BiarchTripleAliases) {
2399 // Declare a bunch of static data sets that we'll select between below. These
2400 // are specifically designed to always refer to string literals to avoid any
2401 // lifetime or initialization issues.
2402 //
2403 // The *Triples variables hard code some triples so that, for example,
2404 // --target=aarch64 (incomplete triple) can detect lib/aarch64-linux-gnu.
2405 // They are not needed when the user has correct LLVM_DEFAULT_TARGET_TRIPLE
2406 // and always uses the full --target (e.g. --target=aarch64-linux-gnu). The
2407 // lists should shrink over time. Please don't add more elements to *Triples.
2408 static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
2409 static const char *const AArch64Triples[] = {
2410 "aarch64-none-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux"};
2411 static const char *const AArch64beLibDirs[] = {"/lib"};
2412 static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu"};
2413
2414 static const char *const ARMLibDirs[] = {"/lib"};
2415 static const char *const ARMTriples[] = {"arm-linux-gnueabi"};
2416 static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
2417 "armv7hl-redhat-linux-gnueabi",
2418 "armv6hl-suse-linux-gnueabi",
2419 "armv7hl-suse-linux-gnueabi"};
2420 static const char *const ARMebLibDirs[] = {"/lib"};
2421 static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"};
2422 static const char *const ARMebHFTriples[] = {
2423 "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
2424
2425 static const char *const AVRLibDirs[] = {"/lib"};
2426 static const char *const AVRTriples[] = {"avr"};
2427
2428 static const char *const CSKYLibDirs[] = {"/lib"};
2429 static const char *const CSKYTriples[] = {
2430 "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"};
2431
2432 static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
2433 static const char *const X86_64Triples[] = {
2434 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
2435 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
2436 "x86_64-redhat-linux", "x86_64-suse-linux",
2437 "x86_64-manbo-linux-gnu", "x86_64-slackware-linux",
2438 "x86_64-unknown-linux", "x86_64-amazon-linux"};
2439 static const char *const X32Triples[] = {"x86_64-linux-gnux32",
2440 "x86_64-pc-linux-gnux32"};
2441 static const char *const X32LibDirs[] = {"/libx32", "/lib"};
2442 static const char *const X86LibDirs[] = {"/lib32", "/lib"};
2443 static const char *const X86Triples[] = {
2444 "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu",
2445 "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux",
2446 "i586-suse-linux", "i686-montavista-linux",
2447 };
2448
2449 static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"};
2450 static const char *const LoongArch64Triples[] = {
2451 "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"};
2452
2453 static const char *const M68kLibDirs[] = {"/lib"};
2454 static const char *const M68kTriples[] = {"m68k-unknown-linux-gnu",
2455 "m68k-suse-linux"};
2456
2457 static const char *const MIPSLibDirs[] = {"/libo32", "/lib"};
2458 static const char *const MIPSTriples[] = {
2459 "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu",
2460 "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"};
2461 static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"};
2462 static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",
2463 "mips-img-linux-gnu"};
2464
2465 static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
2466 static const char *const MIPS64Triples[] = {
2467 "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64-linux-gnuabi64",
2468 "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"};
2469 static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};
2470 static const char *const MIPS64ELTriples[] = {
2471 "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64el-linux-gnuabi64",
2472 "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64"};
2473
2474 static const char *const MIPSN32LibDirs[] = {"/lib32"};
2475 static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32",
2476 "mipsisa64r6-linux-gnuabin32"};
2477 static const char *const MIPSN32ELLibDirs[] = {"/lib32"};
2478 static const char *const MIPSN32ELTriples[] = {
2479 "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"};
2480
2481 static const char *const MSP430LibDirs[] = {"/lib"};
2482 static const char *const MSP430Triples[] = {"msp430-elf"};
2483
2484 static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
2485 static const char *const PPCTriples[] = {
2486 "powerpc-unknown-linux-gnu",
2487 // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
2488 // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
2489 "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};
2490 static const char *const PPCLELibDirs[] = {"/lib32", "/lib"};
2491 static const char *const PPCLETriples[] = {"powerpcle-unknown-linux-gnu",
2492 "powerpcle-linux-musl"};
2493
2494 static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
2495 static const char *const PPC64Triples[] = {"powerpc64-unknown-linux-gnu",
2496 "powerpc64-suse-linux",
2497 "ppc64-redhat-linux"};
2498 static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
2499 static const char *const PPC64LETriples[] = {
2500 "powerpc64le-unknown-linux-gnu", "powerpc64le-none-linux-gnu",
2501 "powerpc64le-suse-linux", "ppc64le-redhat-linux"};
2502
2503 static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"};
2504 static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",
2505 "riscv32-unknown-elf"};
2506 static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
2507 static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
2508 "riscv64-unknown-elf"};
2509
2510 static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
2511 static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
2512 "sparcv8-linux-gnu"};
2513 static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
2514 static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
2515 "sparcv9-linux-gnu"};
2516
2517 static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
2518 static const char *const SystemZTriples[] = {
2519 "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", "s390x-suse-linux",
2520 "s390x-redhat-linux"};
2521
2522 using std::begin;
2523 using std::end;
2524
2525 if (TargetTriple.isOSSolaris()) {
2526 static const char *const SolarisLibDirs[] = {"/lib"};
2527 static const char *const SolarisSparcV8Triples[] = {
2528 "sparc-sun-solaris2.11"};
2529 static const char *const SolarisSparcV9Triples[] = {
2530 "sparcv9-sun-solaris2.11"};
2531 static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11"};
2532 static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11"};
2533 LibDirs.append(in_start: begin(arr: SolarisLibDirs), in_end: end(arr: SolarisLibDirs));
2534 BiarchLibDirs.append(in_start: begin(arr: SolarisLibDirs), in_end: end(arr: SolarisLibDirs));
2535 switch (TargetTriple.getArch()) {
2536 case llvm::Triple::x86:
2537 TripleAliases.append(in_start: begin(arr: SolarisX86Triples), in_end: end(arr: SolarisX86Triples));
2538 BiarchTripleAliases.append(in_start: begin(arr: SolarisX86_64Triples),
2539 in_end: end(arr: SolarisX86_64Triples));
2540 break;
2541 case llvm::Triple::x86_64:
2542 TripleAliases.append(in_start: begin(arr: SolarisX86_64Triples),
2543 in_end: end(arr: SolarisX86_64Triples));
2544 BiarchTripleAliases.append(in_start: begin(arr: SolarisX86Triples),
2545 in_end: end(arr: SolarisX86Triples));
2546 break;
2547 case llvm::Triple::sparc:
2548 TripleAliases.append(in_start: begin(arr: SolarisSparcV8Triples),
2549 in_end: end(arr: SolarisSparcV8Triples));
2550 BiarchTripleAliases.append(in_start: begin(arr: SolarisSparcV9Triples),
2551 in_end: end(arr: SolarisSparcV9Triples));
2552 break;
2553 case llvm::Triple::sparcv9:
2554 TripleAliases.append(in_start: begin(arr: SolarisSparcV9Triples),
2555 in_end: end(arr: SolarisSparcV9Triples));
2556 BiarchTripleAliases.append(in_start: begin(arr: SolarisSparcV8Triples),
2557 in_end: end(arr: SolarisSparcV8Triples));
2558 break;
2559 default:
2560 break;
2561 }
2562 return;
2563 }
2564
2565 // Android targets should not use GNU/Linux tools or libraries.
2566 if (TargetTriple.isAndroid()) {
2567 static const char *const AArch64AndroidTriples[] = {
2568 "aarch64-linux-android"};
2569 static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"};
2570 static const char *const X86AndroidTriples[] = {"i686-linux-android"};
2571 static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"};
2572
2573 switch (TargetTriple.getArch()) {
2574 case llvm::Triple::aarch64:
2575 LibDirs.append(in_start: begin(arr: AArch64LibDirs), in_end: end(arr: AArch64LibDirs));
2576 TripleAliases.append(in_start: begin(arr: AArch64AndroidTriples),
2577 in_end: end(arr: AArch64AndroidTriples));
2578 break;
2579 case llvm::Triple::arm:
2580 case llvm::Triple::thumb:
2581 LibDirs.append(in_start: begin(arr: ARMLibDirs), in_end: end(arr: ARMLibDirs));
2582 TripleAliases.append(in_start: begin(arr: ARMAndroidTriples), in_end: end(arr: ARMAndroidTriples));
2583 break;
2584 case llvm::Triple::x86_64:
2585 LibDirs.append(in_start: begin(arr: X86_64LibDirs), in_end: end(arr: X86_64LibDirs));
2586 TripleAliases.append(in_start: begin(arr: X86_64AndroidTriples),
2587 in_end: end(arr: X86_64AndroidTriples));
2588 BiarchLibDirs.append(in_start: begin(arr: X86LibDirs), in_end: end(arr: X86LibDirs));
2589 BiarchTripleAliases.append(in_start: begin(arr: X86AndroidTriples),
2590 in_end: end(arr: X86AndroidTriples));
2591 break;
2592 case llvm::Triple::x86:
2593 LibDirs.append(in_start: begin(arr: X86LibDirs), in_end: end(arr: X86LibDirs));
2594 TripleAliases.append(in_start: begin(arr: X86AndroidTriples), in_end: end(arr: X86AndroidTriples));
2595 BiarchLibDirs.append(in_start: begin(arr: X86_64LibDirs), in_end: end(arr: X86_64LibDirs));
2596 BiarchTripleAliases.append(in_start: begin(arr: X86_64AndroidTriples),
2597 in_end: end(arr: X86_64AndroidTriples));
2598 break;
2599 default:
2600 break;
2601 }
2602
2603 return;
2604 }
2605
2606 if (TargetTriple.isOSHurd()) {
2607 switch (TargetTriple.getArch()) {
2608 case llvm::Triple::x86_64:
2609 LibDirs.append(in_start: begin(arr: X86_64LibDirs), in_end: end(arr: X86_64LibDirs));
2610 TripleAliases.push_back(Elt: "x86_64-gnu");
2611 break;
2612 case llvm::Triple::x86:
2613 LibDirs.append(in_start: begin(arr: X86LibDirs), in_end: end(arr: X86LibDirs));
2614 TripleAliases.push_back(Elt: "i686-gnu");
2615 break;
2616 default:
2617 break;
2618 }
2619
2620 return;
2621 }
2622
2623 if (TargetTriple.isWindowsCygwinEnvironment()) {
2624 LibDirs.push_back(Elt: "/lib");
2625 switch (TargetTriple.getArch()) {
2626 case llvm::Triple::x86_64:
2627 TripleAliases.append(IL: {"x86_64-pc-cygwin", "x86_64-pc-msys"});
2628 break;
2629 case llvm::Triple::x86:
2630 TripleAliases.append(IL: {"i686-pc-cygwin", "i686-pc-msys"});
2631 break;
2632 default:
2633 break;
2634 }
2635
2636 return;
2637 }
2638
2639 switch (TargetTriple.getArch()) {
2640 case llvm::Triple::aarch64:
2641 LibDirs.append(in_start: begin(arr: AArch64LibDirs), in_end: end(arr: AArch64LibDirs));
2642 TripleAliases.append(in_start: begin(arr: AArch64Triples), in_end: end(arr: AArch64Triples));
2643 BiarchLibDirs.append(in_start: begin(arr: AArch64LibDirs), in_end: end(arr: AArch64LibDirs));
2644 BiarchTripleAliases.append(in_start: begin(arr: AArch64Triples), in_end: end(arr: AArch64Triples));
2645 break;
2646 case llvm::Triple::aarch64_be:
2647 LibDirs.append(in_start: begin(arr: AArch64beLibDirs), in_end: end(arr: AArch64beLibDirs));
2648 TripleAliases.append(in_start: begin(arr: AArch64beTriples), in_end: end(arr: AArch64beTriples));
2649 BiarchLibDirs.append(in_start: begin(arr: AArch64beLibDirs), in_end: end(arr: AArch64beLibDirs));
2650 BiarchTripleAliases.append(in_start: begin(arr: AArch64beTriples), in_end: end(arr: AArch64beTriples));
2651 break;
2652 case llvm::Triple::arm:
2653 case llvm::Triple::thumb:
2654 LibDirs.append(in_start: begin(arr: ARMLibDirs), in_end: end(arr: ARMLibDirs));
2655 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||
2656 TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||
2657 TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||
2658 TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {
2659 TripleAliases.append(in_start: begin(arr: ARMHFTriples), in_end: end(arr: ARMHFTriples));
2660 } else {
2661 TripleAliases.append(in_start: begin(arr: ARMTriples), in_end: end(arr: ARMTriples));
2662 }
2663 break;
2664 case llvm::Triple::armeb:
2665 case llvm::Triple::thumbeb:
2666 LibDirs.append(in_start: begin(arr: ARMebLibDirs), in_end: end(arr: ARMebLibDirs));
2667 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||
2668 TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||
2669 TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||
2670 TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {
2671 TripleAliases.append(in_start: begin(arr: ARMebHFTriples), in_end: end(arr: ARMebHFTriples));
2672 } else {
2673 TripleAliases.append(in_start: begin(arr: ARMebTriples), in_end: end(arr: ARMebTriples));
2674 }
2675 break;
2676 case llvm::Triple::avr:
2677 LibDirs.append(in_start: begin(arr: AVRLibDirs), in_end: end(arr: AVRLibDirs));
2678 TripleAliases.append(in_start: begin(arr: AVRTriples), in_end: end(arr: AVRTriples));
2679 break;
2680 case llvm::Triple::csky:
2681 LibDirs.append(in_start: begin(arr: CSKYLibDirs), in_end: end(arr: CSKYLibDirs));
2682 TripleAliases.append(in_start: begin(arr: CSKYTriples), in_end: end(arr: CSKYTriples));
2683 break;
2684 case llvm::Triple::x86_64:
2685 if (TargetTriple.isX32()) {
2686 LibDirs.append(in_start: begin(arr: X32LibDirs), in_end: end(arr: X32LibDirs));
2687 TripleAliases.append(in_start: begin(arr: X32Triples), in_end: end(arr: X32Triples));
2688 BiarchLibDirs.append(in_start: begin(arr: X86_64LibDirs), in_end: end(arr: X86_64LibDirs));
2689 BiarchTripleAliases.append(in_start: begin(arr: X86_64Triples), in_end: end(arr: X86_64Triples));
2690 } else {
2691 LibDirs.append(in_start: begin(arr: X86_64LibDirs), in_end: end(arr: X86_64LibDirs));
2692 TripleAliases.append(in_start: begin(arr: X86_64Triples), in_end: end(arr: X86_64Triples));
2693 BiarchLibDirs.append(in_start: begin(arr: X32LibDirs), in_end: end(arr: X32LibDirs));
2694 BiarchTripleAliases.append(in_start: begin(arr: X32Triples), in_end: end(arr: X32Triples));
2695 }
2696 BiarchLibDirs.append(in_start: begin(arr: X86LibDirs), in_end: end(arr: X86LibDirs));
2697 BiarchTripleAliases.append(in_start: begin(arr: X86Triples), in_end: end(arr: X86Triples));
2698 break;
2699 case llvm::Triple::x86:
2700 LibDirs.append(in_start: begin(arr: X86LibDirs), in_end: end(arr: X86LibDirs));
2701 // MCU toolchain is 32 bit only and its triple alias is TargetTriple
2702 // itself, which will be appended below.
2703 if (!TargetTriple.isOSIAMCU()) {
2704 TripleAliases.append(in_start: begin(arr: X86Triples), in_end: end(arr: X86Triples));
2705 BiarchLibDirs.append(in_start: begin(arr: X86_64LibDirs), in_end: end(arr: X86_64LibDirs));
2706 BiarchTripleAliases.append(in_start: begin(arr: X86_64Triples), in_end: end(arr: X86_64Triples));
2707 BiarchLibDirs.append(in_start: begin(arr: X32LibDirs), in_end: end(arr: X32LibDirs));
2708 BiarchTripleAliases.append(in_start: begin(arr: X32Triples), in_end: end(arr: X32Triples));
2709 }
2710 break;
2711 // TODO: Handle loongarch32.
2712 case llvm::Triple::loongarch64:
2713 LibDirs.append(in_start: begin(arr: LoongArch64LibDirs), in_end: end(arr: LoongArch64LibDirs));
2714 TripleAliases.append(in_start: begin(arr: LoongArch64Triples), in_end: end(arr: LoongArch64Triples));
2715 break;
2716 case llvm::Triple::m68k:
2717 LibDirs.append(in_start: begin(arr: M68kLibDirs), in_end: end(arr: M68kLibDirs));
2718 TripleAliases.append(in_start: begin(arr: M68kTriples), in_end: end(arr: M68kTriples));
2719 break;
2720 case llvm::Triple::mips:
2721 LibDirs.append(in_start: begin(arr: MIPSLibDirs), in_end: end(arr: MIPSLibDirs));
2722 TripleAliases.append(in_start: begin(arr: MIPSTriples), in_end: end(arr: MIPSTriples));
2723 BiarchLibDirs.append(in_start: begin(arr: MIPS64LibDirs), in_end: end(arr: MIPS64LibDirs));
2724 BiarchTripleAliases.append(in_start: begin(arr: MIPS64Triples), in_end: end(arr: MIPS64Triples));
2725 BiarchLibDirs.append(in_start: begin(arr: MIPSN32LibDirs), in_end: end(arr: MIPSN32LibDirs));
2726 BiarchTripleAliases.append(in_start: begin(arr: MIPSN32Triples), in_end: end(arr: MIPSN32Triples));
2727 break;
2728 case llvm::Triple::mipsel:
2729 LibDirs.append(in_start: begin(arr: MIPSELLibDirs), in_end: end(arr: MIPSELLibDirs));
2730 TripleAliases.append(in_start: begin(arr: MIPSELTriples), in_end: end(arr: MIPSELTriples));
2731 TripleAliases.append(in_start: begin(arr: MIPSTriples), in_end: end(arr: MIPSTriples));
2732 BiarchLibDirs.append(in_start: begin(arr: MIPS64ELLibDirs), in_end: end(arr: MIPS64ELLibDirs));
2733 BiarchTripleAliases.append(in_start: begin(arr: MIPS64ELTriples), in_end: end(arr: MIPS64ELTriples));
2734 BiarchLibDirs.append(in_start: begin(arr: MIPSN32ELLibDirs), in_end: end(arr: MIPSN32ELLibDirs));
2735 BiarchTripleAliases.append(in_start: begin(arr: MIPSN32ELTriples), in_end: end(arr: MIPSN32ELTriples));
2736 break;
2737 case llvm::Triple::mips64:
2738 LibDirs.append(in_start: begin(arr: MIPS64LibDirs), in_end: end(arr: MIPS64LibDirs));
2739 TripleAliases.append(in_start: begin(arr: MIPS64Triples), in_end: end(arr: MIPS64Triples));
2740 BiarchLibDirs.append(in_start: begin(arr: MIPSLibDirs), in_end: end(arr: MIPSLibDirs));
2741 BiarchTripleAliases.append(in_start: begin(arr: MIPSTriples), in_end: end(arr: MIPSTriples));
2742 BiarchLibDirs.append(in_start: begin(arr: MIPSN32LibDirs), in_end: end(arr: MIPSN32LibDirs));
2743 BiarchTripleAliases.append(in_start: begin(arr: MIPSN32Triples), in_end: end(arr: MIPSN32Triples));
2744 break;
2745 case llvm::Triple::mips64el:
2746 LibDirs.append(in_start: begin(arr: MIPS64ELLibDirs), in_end: end(arr: MIPS64ELLibDirs));
2747 TripleAliases.append(in_start: begin(arr: MIPS64ELTriples), in_end: end(arr: MIPS64ELTriples));
2748 BiarchLibDirs.append(in_start: begin(arr: MIPSELLibDirs), in_end: end(arr: MIPSELLibDirs));
2749 BiarchTripleAliases.append(in_start: begin(arr: MIPSELTriples), in_end: end(arr: MIPSELTriples));
2750 BiarchLibDirs.append(in_start: begin(arr: MIPSN32ELLibDirs), in_end: end(arr: MIPSN32ELLibDirs));
2751 BiarchTripleAliases.append(in_start: begin(arr: MIPSN32ELTriples), in_end: end(arr: MIPSN32ELTriples));
2752 BiarchTripleAliases.append(in_start: begin(arr: MIPSTriples), in_end: end(arr: MIPSTriples));
2753 break;
2754 case llvm::Triple::msp430:
2755 LibDirs.append(in_start: begin(arr: MSP430LibDirs), in_end: end(arr: MSP430LibDirs));
2756 TripleAliases.append(in_start: begin(arr: MSP430Triples), in_end: end(arr: MSP430Triples));
2757 break;
2758 case llvm::Triple::ppc:
2759 LibDirs.append(in_start: begin(arr: PPCLibDirs), in_end: end(arr: PPCLibDirs));
2760 TripleAliases.append(in_start: begin(arr: PPCTriples), in_end: end(arr: PPCTriples));
2761 BiarchLibDirs.append(in_start: begin(arr: PPC64LibDirs), in_end: end(arr: PPC64LibDirs));
2762 BiarchTripleAliases.append(in_start: begin(arr: PPC64Triples), in_end: end(arr: PPC64Triples));
2763 break;
2764 case llvm::Triple::ppcle:
2765 LibDirs.append(in_start: begin(arr: PPCLELibDirs), in_end: end(arr: PPCLELibDirs));
2766 TripleAliases.append(in_start: begin(arr: PPCLETriples), in_end: end(arr: PPCLETriples));
2767 BiarchLibDirs.append(in_start: begin(arr: PPC64LELibDirs), in_end: end(arr: PPC64LELibDirs));
2768 BiarchTripleAliases.append(in_start: begin(arr: PPC64LETriples), in_end: end(arr: PPC64LETriples));
2769 break;
2770 case llvm::Triple::ppc64:
2771 LibDirs.append(in_start: begin(arr: PPC64LibDirs), in_end: end(arr: PPC64LibDirs));
2772 TripleAliases.append(in_start: begin(arr: PPC64Triples), in_end: end(arr: PPC64Triples));
2773 BiarchLibDirs.append(in_start: begin(arr: PPCLibDirs), in_end: end(arr: PPCLibDirs));
2774 BiarchTripleAliases.append(in_start: begin(arr: PPCTriples), in_end: end(arr: PPCTriples));
2775 break;
2776 case llvm::Triple::ppc64le:
2777 LibDirs.append(in_start: begin(arr: PPC64LELibDirs), in_end: end(arr: PPC64LELibDirs));
2778 TripleAliases.append(in_start: begin(arr: PPC64LETriples), in_end: end(arr: PPC64LETriples));
2779 BiarchLibDirs.append(in_start: begin(arr: PPCLELibDirs), in_end: end(arr: PPCLELibDirs));
2780 BiarchTripleAliases.append(in_start: begin(arr: PPCLETriples), in_end: end(arr: PPCLETriples));
2781 break;
2782 case llvm::Triple::riscv32:
2783 LibDirs.append(in_start: begin(arr: RISCV32LibDirs), in_end: end(arr: RISCV32LibDirs));
2784 TripleAliases.append(in_start: begin(arr: RISCV32Triples), in_end: end(arr: RISCV32Triples));
2785 BiarchLibDirs.append(in_start: begin(arr: RISCV64LibDirs), in_end: end(arr: RISCV64LibDirs));
2786 BiarchTripleAliases.append(in_start: begin(arr: RISCV64Triples), in_end: end(arr: RISCV64Triples));
2787 break;
2788 case llvm::Triple::riscv64:
2789 LibDirs.append(in_start: begin(arr: RISCV64LibDirs), in_end: end(arr: RISCV64LibDirs));
2790 TripleAliases.append(in_start: begin(arr: RISCV64Triples), in_end: end(arr: RISCV64Triples));
2791 BiarchLibDirs.append(in_start: begin(arr: RISCV32LibDirs), in_end: end(arr: RISCV32LibDirs));
2792 BiarchTripleAliases.append(in_start: begin(arr: RISCV32Triples), in_end: end(arr: RISCV32Triples));
2793 break;
2794 case llvm::Triple::sparc:
2795 case llvm::Triple::sparcel:
2796 LibDirs.append(in_start: begin(arr: SPARCv8LibDirs), in_end: end(arr: SPARCv8LibDirs));
2797 TripleAliases.append(in_start: begin(arr: SPARCv8Triples), in_end: end(arr: SPARCv8Triples));
2798 BiarchLibDirs.append(in_start: begin(arr: SPARCv9LibDirs), in_end: end(arr: SPARCv9LibDirs));
2799 BiarchTripleAliases.append(in_start: begin(arr: SPARCv9Triples), in_end: end(arr: SPARCv9Triples));
2800 break;
2801 case llvm::Triple::sparcv9:
2802 LibDirs.append(in_start: begin(arr: SPARCv9LibDirs), in_end: end(arr: SPARCv9LibDirs));
2803 TripleAliases.append(in_start: begin(arr: SPARCv9Triples), in_end: end(arr: SPARCv9Triples));
2804 BiarchLibDirs.append(in_start: begin(arr: SPARCv8LibDirs), in_end: end(arr: SPARCv8LibDirs));
2805 BiarchTripleAliases.append(in_start: begin(arr: SPARCv8Triples), in_end: end(arr: SPARCv8Triples));
2806 break;
2807 case llvm::Triple::systemz:
2808 LibDirs.append(in_start: begin(arr: SystemZLibDirs), in_end: end(arr: SystemZLibDirs));
2809 TripleAliases.append(in_start: begin(arr: SystemZTriples), in_end: end(arr: SystemZTriples));
2810 break;
2811 default:
2812 // By default, just rely on the standard lib directories and the original
2813 // triple.
2814 break;
2815 }
2816
2817 // Also include the multiarch variant if it's different.
2818 if (TargetTriple.str() != BiarchTriple.str())
2819 BiarchTripleAliases.push_back(Elt: BiarchTriple.str());
2820}
2821
2822bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
2823 const llvm::Triple &TargetTriple, const ArgList &Args,
2824 StringRef Path, bool NeedsBiarchSuffix) {
2825 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
2826 DetectedMultilibs Detected;
2827
2828 // Android standalone toolchain could have multilibs for ARM and Thumb.
2829 // Debian mips multilibs behave more like the rest of the biarch ones,
2830 // so handle them there
2831 if (isArmOrThumbArch(Arch: TargetArch) && TargetTriple.isAndroid()) {
2832 // It should also work without multilibs in a simplified toolchain.
2833 findAndroidArmMultilibs(D, TargetTriple, Path, Args, Result&: Detected);
2834 } else if (TargetTriple.isCSKY()) {
2835 findCSKYMultilibs(D, TargetTriple, Path, Args, Result&: Detected);
2836 } else if (TargetTriple.isMIPS()) {
2837 if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Result&: Detected))
2838 return false;
2839 } else if (TargetTriple.isRISCV()) {
2840 findRISCVMultilibs(D, TargetTriple, Path, Args, Result&: Detected);
2841 } else if (isMSP430(Arch: TargetArch)) {
2842 findMSP430Multilibs(D, TargetTriple, Path, Args, Result&: Detected);
2843 } else if (TargetArch == llvm::Triple::avr) {
2844 // AVR has no multilibs.
2845 } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args,
2846 NeedsBiarchSuffix, Result&: Detected)) {
2847 return false;
2848 }
2849
2850 Multilibs = Detected.Multilibs;
2851 SelectedMultilib = Detected.SelectedMultilibs.empty()
2852 ? Multilib()
2853 : Detected.SelectedMultilibs.back();
2854 BiarchSibling = Detected.BiarchSibling;
2855
2856 return true;
2857}
2858
2859void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
2860 const llvm::Triple &TargetTriple, const ArgList &Args,
2861 const std::string &LibDir, StringRef CandidateTriple,
2862 bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) {
2863 // Locations relative to the system lib directory where GCC's triple-specific
2864 // directories might reside.
2865 struct GCCLibSuffix {
2866 // Path from system lib directory to GCC triple-specific directory.
2867 std::string LibSuffix;
2868 // Path from GCC triple-specific directory back to system lib directory.
2869 // This is one '..' component per component in LibSuffix.
2870 StringRef ReversePath;
2871 // Whether this library suffix is relevant for the triple.
2872 bool Active;
2873 } Suffixes[] = {
2874 // This is the normal place.
2875 {.LibSuffix: "gcc/" + CandidateTriple.str(), .ReversePath: "../..", .Active: GCCDirExists},
2876
2877 // Debian puts cross-compilers in gcc-cross.
2878 {.LibSuffix: "gcc-cross/" + CandidateTriple.str(), .ReversePath: "../..", .Active: GCCCrossDirExists},
2879
2880 // The Freescale PPC SDK has the gcc libraries in
2881 // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do
2882 // this on Freescale triples, though, since some systems put a *lot* of
2883 // files in that location, not just GCC installation data.
2884 {.LibSuffix: CandidateTriple.str(), .ReversePath: "..",
2885 .Active: TargetTriple.getVendor() == llvm::Triple::Freescale ||
2886 TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};
2887
2888 for (auto &Suffix : Suffixes) {
2889 if (!Suffix.Active)
2890 continue;
2891
2892 StringRef LibSuffix = Suffix.LibSuffix;
2893 std::error_code EC;
2894 for (llvm::vfs::directory_iterator
2895 LI = D.getVFS().dir_begin(Dir: LibDir + "/" + LibSuffix, EC),
2896 LE;
2897 !EC && LI != LE; LI = LI.increment(EC)) {
2898 StringRef VersionText = llvm::sys::path::filename(path: LI->path());
2899 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
2900 if (CandidateVersion.Major != -1) // Filter obviously bad entries.
2901 if (!CandidateGCCInstallPaths.insert(x: std::string(LI->path())).second)
2902 continue; // Saw this path before; no need to look at it again.
2903 if (CandidateVersion.isOlderThan(RHSMajor: 4, RHSMinor: 1, RHSPatch: 1))
2904 continue;
2905 if (CandidateVersion <= Version)
2906 continue;
2907
2908 if (!ScanGCCForMultilibs(TargetTriple, Args, Path: LI->path(),
2909 NeedsBiarchSuffix))
2910 continue;
2911
2912 Version = CandidateVersion;
2913 GCCTriple.setTriple(CandidateTriple);
2914 // FIXME: We hack together the directory name here instead of
2915 // using LI to ensure stable path separators across Windows and
2916 // Linux.
2917 GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();
2918 GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();
2919 IsValid = true;
2920 }
2921 }
2922}
2923
2924bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(
2925 const llvm::Triple &TargetTriple, const ArgList &Args,
2926 const SmallVectorImpl<StringRef> &CandidateTriples,
2927 const SmallVectorImpl<StringRef> &CandidateBiarchTriples) {
2928 if (!D.getVFS().exists(Path: concat(Path: D.SysRoot, A: GentooConfigDir)))
2929 return false;
2930
2931 for (StringRef CandidateTriple : CandidateTriples) {
2932 if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))
2933 return true;
2934 }
2935
2936 for (StringRef CandidateTriple : CandidateBiarchTriples) {
2937 if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, NeedsBiarchSuffix: true))
2938 return true;
2939 }
2940 return false;
2941}
2942
2943bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(
2944 const llvm::Triple &TargetTriple, const ArgList &Args,
2945 StringRef CandidateTriple, bool NeedsBiarchSuffix) {
2946 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
2947 D.getVFS().getBufferForFile(Name: concat(Path: D.SysRoot, A: GentooConfigDir,
2948 B: "/config-" + CandidateTriple.str()));
2949 if (File) {
2950 SmallVector<StringRef, 2> Lines;
2951 File.get()->getBuffer().split(A&: Lines, Separator: "\n");
2952 for (StringRef Line : Lines) {
2953 Line = Line.trim();
2954 // CURRENT=triple-version
2955 if (!Line.consume_front(Prefix: "CURRENT="))
2956 continue;
2957 // Process the config file pointed to by CURRENT.
2958 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile =
2959 D.getVFS().getBufferForFile(
2960 Name: concat(Path: D.SysRoot, A: GentooConfigDir, B: "/" + Line));
2961 std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit(Separator: '-');
2962 // List of paths to scan for libraries.
2963 SmallVector<StringRef, 4> GentooScanPaths;
2964 // Scan the Config file to find installed GCC libraries path.
2965 // Typical content of the GCC config file:
2966 // LDPATH="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x:/usr/lib/gcc/
2967 // (continued from previous line) x86_64-pc-linux-gnu/4.9.x/32"
2968 // MANPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/man"
2969 // INFOPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/info"
2970 // STDCXX_INCDIR="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4"
2971 // We are looking for the paths listed in LDPATH=... .
2972 if (ConfigFile) {
2973 SmallVector<StringRef, 2> ConfigLines;
2974 ConfigFile.get()->getBuffer().split(A&: ConfigLines, Separator: "\n");
2975 for (StringRef ConfLine : ConfigLines) {
2976 ConfLine = ConfLine.trim();
2977 if (ConfLine.consume_front(Prefix: "LDPATH=")) {
2978 // Drop '"' from front and back if present.
2979 ConfLine.consume_back(Suffix: "\"");
2980 ConfLine.consume_front(Prefix: "\"");
2981 // Get all paths sperated by ':'
2982 ConfLine.split(A&: GentooScanPaths, Separator: ':', MaxSplit: -1, /*AllowEmpty*/ KeepEmpty: false);
2983 }
2984 }
2985 }
2986 // Test the path based on the version in /etc/env.d/gcc/config-{tuple}.
2987 std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/"
2988 + ActiveVersion.second.str();
2989 GentooScanPaths.push_back(Elt: StringRef(basePath));
2990
2991 // Scan all paths for GCC libraries.
2992 for (const auto &GentooScanPath : GentooScanPaths) {
2993 std::string GentooPath = concat(Path: D.SysRoot, A: GentooScanPath);
2994 if (D.getVFS().exists(Path: GentooPath + "/crtbegin.o")) {
2995 if (!ScanGCCForMultilibs(TargetTriple, Args, Path: GentooPath,
2996 NeedsBiarchSuffix))
2997 continue;
2998
2999 Version = GCCVersion::Parse(VersionText: ActiveVersion.second);
3000 GCCInstallPath = GentooPath;
3001 GCCParentLibPath = GentooPath + std::string("/../../..");
3002 GCCTriple.setTriple(ActiveVersion.first);
3003 IsValid = true;
3004 return true;
3005 }
3006 }
3007 }
3008 }
3009
3010 return false;
3011}
3012
3013Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
3014 const ArgList &Args)
3015 : ToolChain(D, Triple, Args), GCCInstallation(D),
3016 CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args),
3017 SYCLInstallation(D, Triple, Args) {
3018 getProgramPaths().push_back(Elt: getDriver().Dir);
3019}
3020
3021Generic_GCC::~Generic_GCC() {}
3022
3023Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
3024 switch (AC) {
3025 case Action::PreprocessJobClass:
3026 if (!Preprocess)
3027 Preprocess.reset(p: new clang::driver::tools::gcc::Preprocessor(*this));
3028 return Preprocess.get();
3029 case Action::CompileJobClass:
3030 if (!Compile)
3031 Compile.reset(p: new tools::gcc::Compiler(*this));
3032 return Compile.get();
3033 default:
3034 return ToolChain::getTool(AC);
3035 }
3036}
3037
3038Tool *Generic_GCC::buildAssembler() const {
3039 return new tools::gnutools::Assembler(*this);
3040}
3041
3042Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }
3043
3044void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
3045 // Print the information about how we detected the GCC installation.
3046 GCCInstallation.print(OS);
3047 CudaInstallation->print(OS);
3048 RocmInstallation->print(OS);
3049}
3050
3051ToolChain::UnwindTableLevel
3052Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const {
3053 switch (getArch()) {
3054 case llvm::Triple::aarch64:
3055 case llvm::Triple::aarch64_be:
3056 case llvm::Triple::ppc:
3057 case llvm::Triple::ppcle:
3058 case llvm::Triple::ppc64:
3059 case llvm::Triple::ppc64le:
3060 case llvm::Triple::riscv32:
3061 case llvm::Triple::riscv64:
3062 case llvm::Triple::x86:
3063 case llvm::Triple::x86_64:
3064 return UnwindTableLevel::Asynchronous;
3065 default:
3066 return UnwindTableLevel::None;
3067 }
3068}
3069
3070bool Generic_GCC::isPICDefault() const {
3071 switch (getArch()) {
3072 case llvm::Triple::x86_64:
3073 return getTriple().isOSWindows();
3074 case llvm::Triple::mips64:
3075 case llvm::Triple::mips64el:
3076 return true;
3077 default:
3078 return false;
3079 }
3080}
3081
3082bool Generic_GCC::isPIEDefault(const llvm::opt::ArgList &Args) const {
3083 return false;
3084}
3085
3086bool Generic_GCC::isPICDefaultForced() const {
3087 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
3088}
3089
3090bool Generic_GCC::IsIntegratedAssemblerDefault() const {
3091 switch (getTriple().getArch()) {
3092 case llvm::Triple::nvptx:
3093 case llvm::Triple::nvptx64:
3094 case llvm::Triple::xcore:
3095 return false;
3096 default:
3097 return true;
3098 }
3099}
3100
3101void Generic_GCC::PushPPaths(ToolChain::path_list &PPaths) {
3102 // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
3103 // least) put various tools in a triple-prefixed directory off of the parent
3104 // of the GCC installation. We use the GCC triple here to ensure that we end
3105 // up with tools that support the same amount of cross compiling as the
3106 // detected GCC installation. For example, if we find a GCC installation
3107 // targeting x86_64, but it is a bi-arch GCC installation, it can also be
3108 // used to target i386.
3109 if (GCCInstallation.isValid()) {
3110 PPaths.push_back(Elt: Twine(GCCInstallation.getParentLibPath() + "/../" +
3111 GCCInstallation.getTriple().str() + "/bin")
3112 .str());
3113 }
3114}
3115
3116void Generic_GCC::AddMultilibPaths(const Driver &D,
3117 const std::string &SysRoot,
3118 const std::string &OSLibDir,
3119 const std::string &MultiarchTriple,
3120 path_list &Paths) {
3121 // Add the multilib suffixed paths where they are available.
3122 if (GCCInstallation.isValid()) {
3123 assert(!SelectedMultilibs.empty());
3124 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
3125 const std::string &LibPath =
3126 std::string(GCCInstallation.getParentLibPath());
3127
3128 // Sourcery CodeBench MIPS toolchain holds some libraries under
3129 // a biarch-like suffix of the GCC installation.
3130 if (const auto &PathsCallback = Multilibs.filePathsCallback())
3131 for (const auto &Path : PathsCallback(SelectedMultilibs.back()))
3132 addPathIfExists(D, Path: GCCInstallation.getInstallPath() + Path, Paths);
3133
3134 // Add lib/gcc/$triple/$version, with an optional /multilib suffix.
3135 addPathIfExists(D,
3136 Path: GCCInstallation.getInstallPath() +
3137 SelectedMultilibs.back().gccSuffix(),
3138 Paths);
3139
3140 // Add lib/gcc/$triple/$libdir
3141 // For GCC built with --enable-version-specific-runtime-libs.
3142 addPathIfExists(D, Path: GCCInstallation.getInstallPath() + "/../" + OSLibDir,
3143 Paths);
3144
3145 // GCC cross compiling toolchains will install target libraries which ship
3146 // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
3147 // any part of the GCC installation in
3148 // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
3149 // debatable, but is the reality today. We need to search this tree even
3150 // when we have a sysroot somewhere else. It is the responsibility of
3151 // whomever is doing the cross build targeting a sysroot using a GCC
3152 // installation that is *not* within the system root to ensure two things:
3153 //
3154 // 1) Any DSOs that are linked in from this tree or from the install path
3155 // above must be present on the system root and found via an
3156 // appropriate rpath.
3157 // 2) There must not be libraries installed into
3158 // <prefix>/<triple>/<libdir> unless they should be preferred over
3159 // those within the system root.
3160 //
3161 // Note that this matches the GCC behavior. See the below comment for where
3162 // Clang diverges from GCC's behavior.
3163 addPathIfExists(D,
3164 Path: LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +
3165 SelectedMultilibs.back().osSuffix(),
3166 Paths);
3167
3168 // If the GCC installation we found is inside of the sysroot, we want to
3169 // prefer libraries installed in the parent prefix of the GCC installation.
3170 // It is important to *not* use these paths when the GCC installation is
3171 // outside of the system root as that can pick up unintended libraries.
3172 // This usually happens when there is an external cross compiler on the
3173 // host system, and a more minimal sysroot available that is the target of
3174 // the cross. Note that GCC does include some of these directories in some
3175 // configurations but this seems somewhere between questionable and simply
3176 // a bug.
3177 if (StringRef(LibPath).starts_with(Prefix: SysRoot))
3178 addPathIfExists(D, Path: LibPath + "/../" + OSLibDir, Paths);
3179 }
3180}
3181
3182void Generic_GCC::AddMultiarchPaths(const Driver &D,
3183 const std::string &SysRoot,
3184 const std::string &OSLibDir,
3185 path_list &Paths) {
3186 if (GCCInstallation.isValid()) {
3187 const std::string &LibPath =
3188 std::string(GCCInstallation.getParentLibPath());
3189 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
3190 const Multilib &Multilib = GCCInstallation.getMultilib();
3191 addPathIfExists(
3192 D, Path: LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(),
3193 Paths);
3194 }
3195}
3196
3197void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs,
3198 ArgStringList &CC1Args) const {
3199 // Add include directories specific to the selected multilib set and multilib.
3200 if (!GCCInstallation.isValid())
3201 return;
3202 // gcc TOOL_INCLUDE_DIR.
3203 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
3204 std::string LibPath(GCCInstallation.getParentLibPath());
3205 addSystemInclude(DriverArgs, CC1Args,
3206 Path: Twine(LibPath) + "/../" + GCCTriple.str() + "/include");
3207
3208 const auto &Callback = Multilibs.includeDirsCallback();
3209 if (Callback) {
3210 for (const auto &Path : Callback(GCCInstallation.getMultilib()))
3211 addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
3212 Path: GCCInstallation.getInstallPath() + Path);
3213 }
3214}
3215
3216void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3217 ArgStringList &CC1Args) const {
3218 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,
3219 options::OPT_nostdlibinc))
3220 return;
3221
3222 switch (GetCXXStdlibType(Args: DriverArgs)) {
3223 case ToolChain::CST_Libcxx:
3224 addLibCxxIncludePaths(DriverArgs, CC1Args);
3225 break;
3226
3227 case ToolChain::CST_Libstdcxx:
3228 addLibStdCxxIncludePaths(DriverArgs, CC1Args);
3229 break;
3230 }
3231}
3232
3233void Generic_GCC::addSYCLIncludeArgs(const ArgList &DriverArgs,
3234 ArgStringList &CC1Args) const {
3235 SYCLInstallation->addSYCLIncludeArgs(DriverArgs, CC1Args);
3236}
3237
3238void
3239Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
3240 llvm::opt::ArgStringList &CC1Args) const {
3241 const Driver &D = getDriver();
3242 std::string SysRoot = computeSysRoot();
3243 if (SysRoot.empty())
3244 SysRoot = llvm::sys::path::get_separator();
3245
3246 auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {
3247 std::string Version = detectLibcxxVersion(IncludePath: Path);
3248 if (Version.empty())
3249 return false;
3250
3251 // First add the per-target include path if it exists.
3252 bool TargetDirExists = false;
3253 std::optional<std::string> TargetIncludeDir = getTargetSubDirPath(BaseDir: Path);
3254 if (TargetIncludeDir) {
3255 SmallString<128> TargetDir(*TargetIncludeDir);
3256 llvm::sys::path::append(path&: TargetDir, a: "c++", b: Version);
3257 if (D.getVFS().exists(Path: TargetDir)) {
3258 addSystemInclude(DriverArgs, CC1Args, Path: TargetDir);
3259 TargetDirExists = true;
3260 }
3261 }
3262 if (TargetDirRequired && !TargetDirExists)
3263 return false;
3264
3265 // Second add the generic one.
3266 SmallString<128> GenericDir(Path);
3267 llvm::sys::path::append(path&: GenericDir, a: "c++", b: Version);
3268 addSystemInclude(DriverArgs, CC1Args, Path: GenericDir);
3269 return true;
3270 };
3271
3272 // Android only uses the libc++ headers installed alongside the toolchain if
3273 // they contain an Android-specific target include path, otherwise they're
3274 // incompatible with the NDK libraries.
3275 SmallString<128> DriverIncludeDir(getDriver().Dir);
3276 llvm::sys::path::append(path&: DriverIncludeDir, a: "..", b: "include");
3277 if (AddIncludePath(DriverIncludeDir,
3278 /*TargetDirRequired=*/getTriple().isAndroid()))
3279 return;
3280 // If this is a development, non-installed, clang, libcxx will
3281 // not be found at ../include/c++ but it likely to be found at
3282 // one of the following two locations:
3283 SmallString<128> UsrLocalIncludeDir(SysRoot);
3284 llvm::sys::path::append(path&: UsrLocalIncludeDir, a: "usr", b: "local", c: "include");
3285 if (AddIncludePath(UsrLocalIncludeDir))
3286 return;
3287 SmallString<128> UsrIncludeDir(SysRoot);
3288 llvm::sys::path::append(path&: UsrIncludeDir, a: "usr", b: "include");
3289 if (AddIncludePath(UsrIncludeDir))
3290 return;
3291}
3292
3293bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
3294 Twine IncludeSuffix,
3295 const llvm::opt::ArgList &DriverArgs,
3296 llvm::opt::ArgStringList &CC1Args,
3297 bool DetectDebian) const {
3298 if (!getVFS().exists(Path: IncludeDir))
3299 return false;
3300
3301 // Debian native gcc uses g++-multiarch-incdir.diff which uses
3302 // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of
3303 // include/c++/10/x86_64-linux-gnu$IncludeSuffix.
3304 std::string Dir = IncludeDir.str();
3305 StringRef Include =
3306 llvm::sys::path::parent_path(path: llvm::sys::path::parent_path(path: Dir));
3307 std::string Path =
3308 (Include + "/" + Triple + Dir.substr(pos: Include.size()) + IncludeSuffix)
3309 .str();
3310 if (DetectDebian && !getVFS().exists(Path))
3311 return false;
3312
3313 // GPLUSPLUS_INCLUDE_DIR
3314 addSystemInclude(DriverArgs, CC1Args, Path: IncludeDir);
3315 // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent
3316 // include directory.
3317 if (DetectDebian)
3318 addSystemInclude(DriverArgs, CC1Args, Path);
3319 else if (!Triple.empty())
3320 addSystemInclude(DriverArgs, CC1Args,
3321 Path: IncludeDir + "/" + Triple + IncludeSuffix);
3322 // GPLUSPLUS_BACKWARD_INCLUDE_DIR
3323 addSystemInclude(DriverArgs, CC1Args, Path: IncludeDir + "/backward");
3324 return true;
3325}
3326
3327bool Generic_GCC::addGCCLibStdCxxIncludePaths(
3328 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
3329 StringRef DebianMultiarch) const {
3330 assert(GCCInstallation.isValid());
3331
3332 // By default, look for the C++ headers in an include directory adjacent to
3333 // the lib directory of the GCC installation. Note that this is expect to be
3334 // equivalent to '/usr/include/c++/X.Y' in almost all cases.
3335 StringRef LibDir = GCCInstallation.getParentLibPath();
3336 StringRef InstallDir = GCCInstallation.getInstallPath();
3337 StringRef TripleStr = GCCInstallation.getTriple().str();
3338 const Multilib &Multilib = GCCInstallation.getMultilib();
3339 const GCCVersion &Version = GCCInstallation.getVersion();
3340
3341 // Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty).
3342 if (addLibStdCXXIncludePaths(
3343 IncludeDir: LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text,
3344 Triple: TripleStr, IncludeSuffix: Multilib.includeSuffix(), DriverArgs, CC1Args))
3345 return true;
3346
3347 // Try /gcc/$triple/$version/include/c++/ (gcc --print-multiarch is not
3348 // empty). Like above but for GCC built with
3349 // --enable-version-specific-runtime-libs.
3350 if (addLibStdCXXIncludePaths(IncludeDir: LibDir.str() + "/gcc/" + TripleStr + "/" +
3351 Version.Text + "/include/c++/",
3352 Triple: TripleStr, IncludeSuffix: Multilib.includeSuffix(), DriverArgs,
3353 CC1Args))
3354 return true;
3355
3356 // Detect Debian g++-multiarch-incdir.diff.
3357 if (addLibStdCXXIncludePaths(IncludeDir: LibDir.str() + "/../include/c++/" + Version.Text,
3358 Triple: DebianMultiarch, IncludeSuffix: Multilib.includeSuffix(),
3359 DriverArgs, CC1Args, /*Debian=*/DetectDebian: true))
3360 return true;
3361
3362 // Try /../include/c++/$version (gcc --print-multiarch is empty).
3363 if (addLibStdCXXIncludePaths(IncludeDir: LibDir.str() + "/../include/c++/" + Version.Text,
3364 Triple: TripleStr, IncludeSuffix: Multilib.includeSuffix(), DriverArgs,
3365 CC1Args))
3366 return true;
3367
3368 // Otherwise, fall back on a bunch of options which don't use multiarch
3369 // layouts for simplicity.
3370 const std::string LibStdCXXIncludePathCandidates[] = {
3371 // Gentoo is weird and places its headers inside the GCC install,
3372 // so if the first attempt to find the headers fails, try these patterns.
3373 InstallDir.str() + "/include/g++-v" + Version.Text,
3374 InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
3375 Version.MinorStr,
3376 InstallDir.str() + "/include/g++-v" + Version.MajorStr,
3377 };
3378
3379 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
3380 if (addLibStdCXXIncludePaths(IncludeDir: IncludePath, Triple: TripleStr,
3381 IncludeSuffix: Multilib.includeSuffix(), DriverArgs, CC1Args))
3382 return true;
3383 }
3384 return false;
3385}
3386
3387void
3388Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
3389 llvm::opt::ArgStringList &CC1Args) const {
3390 if (GCCInstallation.isValid()) {
3391 addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args,
3392 DebianMultiarch: GCCInstallation.getTriple().str());
3393 }
3394}
3395
3396llvm::opt::DerivedArgList *
3397Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args,
3398 StringRef BoundArch,
3399 Action::OffloadKind DeviceOffloadKind) const {
3400 if (DeviceOffloadKind != Action::OFK_SYCL &&
3401 DeviceOffloadKind != Action::OFK_OpenMP)
3402 return nullptr;
3403
3404 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
3405
3406 // Filter all the arguments we don't care passing to the offloading
3407 // toolchain as they can mess up with the creation of a shared library.
3408 const llvm::DenseSet<unsigned> OpenMPFiltered{
3409 options::OPT_shared, options::OPT_dynamic, options::OPT_static,
3410 options::OPT_fPIE, options::OPT_fno_PIE, options::OPT_fpie,
3411 options::OPT_fno_pie};
3412 for (auto *A : Args)
3413 if (DeviceOffloadKind != Action::OFK_OpenMP ||
3414 !OpenMPFiltered.contains(V: A->getOption().getID()))
3415 DAL->append(A);
3416
3417 // Request a shared library for CPU offloading. Given that these options
3418 // are decided implicitly, they do not refer to any base argument.
3419 const OptTable &Opts = getDriver().getOpts();
3420 if (DeviceOffloadKind == Action::OFK_OpenMP) {
3421 DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared));
3422 DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC));
3423 }
3424
3425 // Add the bound architecture to the arguments list if present.
3426 if (!BoundArch.empty()) {
3427 options::ID Opt =
3428 getTriple().isARM() || getTriple().isPPC() || getTriple().isAArch64()
3429 ? options::OPT_mcpu_EQ
3430 : options::OPT_march_EQ;
3431 DAL->eraseArg(Id: Opt);
3432 DAL->AddJoinedArg(BaseArg: nullptr, Opt: Opts.getOption(Opt), Value: BoundArch);
3433 }
3434 return DAL;
3435}
3436
3437void Generic_ELF::anchor() {}
3438
3439void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
3440 ArgStringList &CC1Args,
3441 Action::OffloadKind) const {
3442 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
3443 options::OPT_fno_use_init_array, true))
3444 CC1Args.push_back(Elt: "-fno-use-init-array");
3445}
3446

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/Driver/ToolChains/Gnu.cpp