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