clang: lib/Driver/ToolChains/Gnu.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

20#include "clang/Config/config.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

40using namespace clang;

42

45

47

49 return false;

50 return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption);

51}

52

53

54

55

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

72 const ArgList &Args,

73 const char *LinkingOutput) const {

75 ArgStringList CmdArgs;

76

77 for (const auto &A : Args) {

79

80

81

82

83 A->claim();

84

85 A->render(Args, CmdArgs);

86 }

87 }

88

90

91

92 if (getToolChain().getTriple().isOSDarwin()) {

93 CmdArgs.push_back("-arch");

94 CmdArgs.push_back(

95 Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));

96 }

97

98

99

100

101

102

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.");

123 CmdArgs.push_back("-o");

125 } else {

126 CmdArgs.push_back("-fsyntax-only");

127 }

128

129 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);

130

131

132

133

134

135

136

137

138

139 for (const auto &II : Inputs) {

140

142 D.Diag(clang::diag::err_drv_no_linker_llvm_support)

144 else if (II.getType() == types::TY_AST)

146 else if (II.getType() == types::TY_ModuleFile)

147 D.Diag(diag::err_drv_no_module_support)

149

151 CmdArgs.push_back("-x");

153 }

154

155 if (II.isFilename())

156 CmdArgs.push_back(II.getFilename());

157 else {

158 const Arg &A = II.getInputArg();

159

160

161 if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {

162 CmdArgs.push_back("-lstdc++");

163 continue;

164 }

165

166

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(JA, *this,

183 Exec, CmdArgs, Inputs, Output));

184}

185

187 const JobAction &JA, ArgStringList &CmdArgs) const {

188 CmdArgs.push_back("-E");

189}

190

192 ArgStringList &CmdArgs) const {

193 const Driver &D = getToolChain().getDriver();

194

196

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

204

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

220 ArgStringList &CmdArgs) const {

221

222}

223

224static 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:

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:

273 return "elf32btsmipn32";

274 return "elf64btsmip";

275 case llvm::Triple::mips64el:

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

295 bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);

296 if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {

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

307 return Args.hasArg(options::OPT_static) &&

308 !Args.hasArg(options::OPT_static_pie);

309}

310

313 const InputInfoList &Inputs, const ArgList &Args,

314 const char *LinkingOutput) const {

315 const Driver &D = getToolChain().getDriver();

316

317

318 Args.ClaimAllArgs(options::OPT_g_Group);

319

320 Args.ClaimAllArgs(options::OPT_emit_llvm);

321

322

323 Args.ClaimAllArgs(options::OPT_w);

324

325 Args.ClaimAllArgs(options::OPT_stdlib_EQ);

326

327

328 ArgStringList CmdArgs;

329

330 CmdArgs.push_back("rcsD");

332

333 for (const auto &II : Inputs) {

334 if (II.isFilename()) {

335 CmdArgs.push_back(II.getFilename());

336 }

337 }

338

339

340

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(JA, *this,

352 Exec, CmdArgs, Inputs, Output));

353}

354

358 const ArgList &Args,

359 const char *LinkingOutput) const {

360

361

362

363

366

367 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();

368

376 const bool HasCRTBeginEndFiles =

378 (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);

379

380 ArgStringList CmdArgs;

381

382

383 Args.ClaimAllArgs(options::OPT_g_Group);

384

385 Args.ClaimAllArgs(options::OPT_emit_llvm);

386

387

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()) {

398 if (IsBigEndian)

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

406

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

414

415 CmdArgs.push_back("--eh-frame-hdr");

416

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.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");

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,

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");

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)

476

478 }

479

480 if (IsVE) {

481 CmdArgs.push_back("-z");

482 CmdArgs.push_back("max-page-size=0x4000000");

483 }

484

485 if (IsIAMCU)

487 else if (HasCRTBeginEndFiles) {

488 std::string P;

490 !isAndroid) {

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";

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";

507 }

508 CmdArgs.push_back(Args.MakeArgString(P));

509 }

510

511

513

514 if (isAndroid && Args.hasFlag(options::OPT_fandroid_pad_segment,

515 options::OPT_fno_android_pad_segment, false))

516 CmdArgs.push_back(

518 }

519

520 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});

521

523

524 if (D.isUsingLTO()) {

525 assert(!Inputs.empty() && "Must have at least one input.");

526

527 auto Input = llvm::find_if(

529 if (Input == Inputs.end())

530

531

532 Input = Inputs.begin();

533

536 }

537

538 if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))

539 CmdArgs.push_back("--no-demangle");

540

545

547

548

549 getToolChain().addProfileRTLibs(Args, CmdArgs);

550

551 if (D.CCCIsCXX() &&

552 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,

553 options::OPT_r)) {

555 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&

556 !Args.hasArg(options::OPT_static);

557 if (OnlyLibstdcxxStatic)

558 CmdArgs.push_back("-Bstatic");

560 if (OnlyLibstdcxxStatic)

561 CmdArgs.push_back("-Bdynamic");

562 }

563 CmdArgs.push_back("-lm");

564 }

565

566

567 Args.ClaimAllArgs(options::OPT_stdlib_EQ);

568

569

570

571

572

573 if (D.IsFlangMode() &&

574 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {

577 CmdArgs.push_back("-lm");

578 }

579

580 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) {

581 if (!Args.hasArg(options::OPT_nodefaultlibs)) {

583 CmdArgs.push_back("--start-group");

584

585 if (NeedsSanitizerDeps)

587

588 if (NeedsXRayDeps)

590

591 bool WantPthread = Args.hasArg(options::OPT_pthread) ||

592 Args.hasArg(options::OPT_pthreads);

593

594

595 bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&

596 !Args.hasArg(options::OPT_static);

597

598

599

602 true))

603

604

605 WantPthread = true;

606

608

609

610

611

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

620

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

631 if (IsIAMCU)

632 CmdArgs.push_back("-lgloss");

633

635 CmdArgs.push_back("--end-group");

636 else

638

639

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;

651 !isAndroid) {

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";

666 }

667 CmdArgs.push_back(Args.MakeArgString(P));

668 }

669 if (!isAndroid)

671 }

672 }

673

674 Args.addAllArgs(CmdArgs, {options::OPT_T, options::OPT_t});

675

677 C.addCommand(std::make_unique(JA, *this,

679 Exec, CmdArgs, Inputs, Output));

680}

681

686 const ArgList &Args,

687 const char *LinkingOutput) const {

688 const auto &D = getToolChain().getDriver();

689

691

692 ArgStringList CmdArgs;

693

694 llvm::Reloc::Model RelocationModel;

695 unsigned PICLevel;

696 bool IsPIE;

697 const char *DefaultAssembler = "as";

698

699

700 if (getToolChain().getTriple().isOSSolaris())

701 DefaultAssembler = "gas";

702 std::tie(RelocationModel, PICLevel, IsPIE) =

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

724

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");

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");

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");

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");

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 =

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(

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(

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();

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

816 CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));

817 break;

819 CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));

820 break;

822 CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));

823 break;

824 }

825

826 Args.AddLastArg(CmdArgs, options::OPT_march_EQ);

828

829 Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);

830

831

832

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);

843

844 break;

845 }

846

847 case llvm::Triple::loongarch64: {

848 StringRef ABIName =

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;

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

869

870 if (RelocationModel == llvm::Reloc::Static)

871 CmdArgs.push_back("-mno-shared");

872

873

874

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

889 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,

890 options::OPT_mfp64)) {

891 A->claim();

892 A->render(Args, CmdArgs);

894 Args, getToolChain().getTriple(), CPUName, ABIName,

896 getToolChain().getTriple())))

897 CmdArgs.push_back("-mfpxx");

898

899

900

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

919

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

934 break;

935 }

936 case llvm::Triple::systemz: {

937

938

939 std::string CPUName =

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");

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(JA, *this,

985 Exec, CmdArgs, Inputs, Output));

986

987

988

989

990 if (Args.hasArg(options::OPT_gsplit_dwarf) &&

991 getToolChain().getTriple().isOSLinux())

992 SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,

994}

995

996namespace {

997

998class FilterNonExistent {

1000 llvm::vfs::FileSystem &VFS;

1001

1002public:

1003 FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS)

1005 bool operator()(const Multilib &M) {

1007 }

1008};

1009}

1010

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

1023 return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;

1024}

1025

1026static bool isMipsEL(llvm::Triple::ArchType Arch) {

1027 return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;

1028}

1029

1031 Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);

1032 return A && A->getOption().matches(options::OPT_mips16);

1033}

1034

1036 Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);

1037 return A && A->getOption().matches(options::OPT_mmicromips);

1038}

1039

1040static bool isMSP430(llvm::Triple::ArchType Arch) {

1041 return Arch == llvm::Triple::msp430;

1042}

1043

1046 FilterNonExistent &NonExistent,

1048

1050 {

1052

1053 auto MArchMicroMips =

1055

1057 .flag("-mips16", true)

1058 .flag("-mmicromips", true);

1059

1061

1063

1065

1067 .flag("-msoft-float", true)

1068 .flag("-mnan=2008", true);

1069

1070 auto BigEndian =

1072

1073 auto LittleEndian =

1075

1076

1079 .includeSuffix("/64")

1080 .flag("-mabi=n64")

1081 .flag("-mabi=n32", true)

1082 .flag("-m32", true);

1083

1084 CSMipsMultilibs =

1086 .Either(MArchMips16, MArchMicroMips, MArchDefault)

1088 .Either(SoftFloat, Nan2008, DefaultFloat)

1089 .FilterOut("/micromips/nan2008")

1091 .Either(BigEndian, LittleEndian)

1098 std::vectorstd::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

1109 {

1112 "-mabi=n32");

1113

1116 .includeSuffix("/64")

1117 .flag("-m64")

1118 .flag("-m32", true)

1119 .flag("-mabi=n32", true);

1120

1123 .flag("-m64", true)

1124 .flag("-m32")

1125 .flag("-mabi=n32", true);

1126

1128 .Either(M32, M64, MAbiN32)

1131 }

1132

1133

1134

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)

1142 Result.Multilibs = *Candidate;

1143 return true;

1144 }

1145 }

1146 return false;

1147}

1148

1150 llvm::vfs::FileSystem &VFS, StringRef Path,

1152 FilterNonExistent &NonExistent,

1154

1161

1166 .flag("-march=mips32r2"),

1168 .flag("-march=mips32r6"))

1171

1176 .flag("-march=mips32"),

1178 .flag("-march=mips32r2"),

1180 .flag("-march=mips32r6"))

1183

1184 MultilibSet *MS = &AndroidMipsMultilibs;

1185 if (VFS.exists(Path + "/mips-r6"))

1186 MS = &AndroidMipselMultilibs;

1187 else if (VFS.exists(Path + "/32"))

1188 MS = &AndroidMips64elMultilibs;

1189 if (MS->select(D, Flags, Result.SelectedMultilibs)) {

1190 Result.Multilibs = *MS;

1191 return true;

1192 }

1193 return false;

1194}

1195

1198 FilterNonExistent &NonExistent,

1200

1202 {

1204 .osSuffix("/mips-r2-hard-musl")

1205 .flag("-EB")

1206 .flag("-EL", true)

1207 .flag("-march=mips32r2");

1208

1209 auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl")

1210 .flag("-EB", true)

1211 .flag("-EL")

1212 .flag("-march=mips32r2");

1213

1215 .Either(MArchMipsR2, MArchMipselR2)

1217

1218

1220 return std::vectorstd::string(

1221 {"/../sysroot" + M.osSuffix() + "/usr/include"});

1222 });

1223 }

1224 if (MuslMipsMultilibs.select(D, Flags, Result.SelectedMultilibs)) {

1225 Result.Multilibs = MuslMipsMultilibs;

1226 return true;

1227 }

1228 return false;

1229}

1230

1233 FilterNonExistent &NonExistent,

1235

1237 {

1239 .flag("-m32")

1240 .flag("-m64", true)

1241 .flag("-mmicromips", true)

1242 .flag("-march=mips32");

1243

1245 .flag("-m32")

1246 .flag("-m64", true)

1247 .flag("-mmicromips");

1248

1250 .flag("-m32", true)

1251 .flag("-m64")

1252 .flag("-march=mips64r2");

1253

1255 .flag("-m32", true)

1256 .flag("-m64")

1257 .flag("-march=mips64r2", true);

1258

1260 .flag("-m32")

1261 .flag("-m64", true)

1262 .flag("-mmicromips", true)

1263 .flag("-march=mips32r2");

1264

1266

1268

1270 .flag("-mabi=n64")

1271 .flag("-mabi=n32", true)

1272 .flag("-m32", true);

1273

1274 auto BigEndian =

1276

1277 auto LittleEndian =

1279

1281

1283

1284 MtiMipsMultilibsV1 =

1286 .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,

1287 MArchDefault)

1298 .Either(BigEndian, LittleEndian)

1299 .Maybe(SoftFloat)

1305 std::vectorstd::string Dirs({"/include"});

1306 if (StringRef(M.includeSuffix()).starts_with("/uclibc"))

1307 Dirs.push_back("/../../../../sysroot/uclibc/usr/include");

1308 else

1309 Dirs.push_back("/../../../../sysroot/usr/include");

1310 return Dirs;

1311 });

1312 }

1313

1314

1316 {

1318 .flag("-EB")

1319 .flag("-msoft-float", true)

1320 .flag("-mnan=2008", true)

1321 .flag("-muclibc", true);

1323 .flag("-EB")

1324 .flag("-msoft-float")

1325 .flag("-mnan=2008", true);

1327 .flag("-EL")

1328 .flag("-msoft-float", true)

1329 .flag("-mnan=2008", true)

1330 .flag("-muclibc", true);

1332 .flag("-EL")

1333 .flag("-msoft-float")

1334 .flag("-mnan=2008", true)

1335 .flag("-mmicromips", true);

1336 auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008")

1337 .flag("-EB")

1338 .flag("-msoft-float", true)

1339 .flag("-mnan=2008")

1340 .flag("-muclibc", true);

1341 auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008")

1342 .flag("-EL")

1343 .flag("-msoft-float", true)

1344 .flag("-mnan=2008")

1345 .flag("-muclibc", true)

1346 .flag("-mmicromips", true);

1347 auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc")

1348 .flag("-EB")

1349 .flag("-msoft-float", true)

1350 .flag("-mnan=2008")

1351 .flag("-muclibc");

1352 auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc")

1353 .flag("-EL")

1354 .flag("-msoft-float", true)

1355 .flag("-mnan=2008")

1356 .flag("-muclibc");

1357 auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc")

1358 .flag("-EB")

1359 .flag("-msoft-float", true)

1360 .flag("-mnan=2008", true)

1361 .flag("-muclibc");

1362 auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc")

1363 .flag("-EL")

1364 .flag("-msoft-float", true)

1365 .flag("-mnan=2008", true)

1366 .flag("-muclibc");

1367 auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008")

1368 .flag("-EL")

1369 .flag("-msoft-float", true)

1370 .flag("-mnan=2008")

1371 .flag("-mmicromips");

1372 auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft")

1373 .flag("-EL")

1374 .flag("-msoft-float")

1375 .flag("-mnan=2008", true)

1376 .flag("-mmicromips");

1377

1380 .flag("-mabi=n32", true)

1381 .flag("-mabi=n64", true);

1384 .flag("-mabi=n32")

1385 .flag("-mabi=n64", true);

1388 .flag("-mabi=n32", true)

1389 .flag("-mabi=n64");

1390

1391 MtiMipsMultilibsV2 =

1393 .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,

1394 BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,

1395 ElHardUclibc, ElMicroHardNan, ElMicroSoft})

1396 .Either(O32, N32, N64)

1400 return std::vectorstd::string({"/../../../../sysroot" +

1402 "/../usr/include"});

1403 })

1404 .setFilePathsCallback([](const Multilib &M) {

1405 return std::vectorstd::string(

1406 {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});

1407 });

1408 }

1409 for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {

1410 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {

1411 Result.Multilibs = *Candidate;

1412 return true;

1413 }

1414 }

1415 return false;

1416}

1417

1420 FilterNonExistent &NonExistent,

1422

1424 {

1426 .flag("-m64")

1427 .flag("-m32", true);

1428

1429 auto LittleEndian =

1431

1433 .flag("-mabi=n64")

1434 .flag("-mabi=n32", true)

1435 .flag("-m32", true);

1436

1437 ImgMultilibsV1 =

1439 .Maybe(Mips64r6)

1441 .Maybe(LittleEndian)

1445 return std::vectorstd::string(

1446 {"/include", "/../../../../sysroot/usr/include"});

1447 });

1448 }

1449

1450

1452 {

1454 .flag("-EB")

1455 .flag("-msoft-float", true)

1456 .flag("-mmicromips", true);

1458 .flag("-EB")

1459 .flag("-msoft-float")

1460 .flag("-mmicromips", true);

1462 .flag("-EL")

1463 .flag("-msoft-float", true)

1464 .flag("-mmicromips", true);

1466 .flag("-EL")

1467 .flag("-msoft-float")

1468 .flag("-mmicromips", true);

1469 auto BeMicroHard = MultilibBuilder("/micromips-r6-hard")

1470 .flag("-EB")

1471 .flag("-msoft-float", true)

1472 .flag("-mmicromips");

1473 auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft")

1474 .flag("-EB")

1475 .flag("-msoft-float")

1476 .flag("-mmicromips");

1477 auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard")

1478 .flag("-EL")

1479 .flag("-msoft-float", true)

1480 .flag("-mmicromips");

1481 auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft")

1482 .flag("-EL")

1483 .flag("-msoft-float")

1484 .flag("-mmicromips");

1485

1488 .flag("-mabi=n32", true)

1489 .flag("-mabi=n64", true);

1492 .flag("-mabi=n32")

1493 .flag("-mabi=n64", true);

1496 .flag("-mabi=n32", true)

1497 .flag("-mabi=n64");

1498

1499 ImgMultilibsV2 =

1501 .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,

1502 ElMicroHard, ElMicroSoft})

1503 .Either(O32, N32, N64)

1507 return std::vectorstd::string({"/../../../../sysroot" +

1509 "/../usr/include"});

1510 })

1511 .setFilePathsCallback([](const Multilib &M) {

1512 return std::vectorstd::string(

1513 {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});

1514 });

1515 }

1516 for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {

1517 if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {

1518 Result.Multilibs = *Candidate;

1519 return true;

1520 }

1521 }

1522 return false;

1523}

1524

1526 const llvm::Triple &TargetTriple,

1527 StringRef Path, const ArgList &Args,

1529 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1530

1531 StringRef CPUName;

1532 StringRef ABIName;

1534

1535 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();

1536

1538 addMultilibFlag(TargetTriple.isMIPS32(), "-m32", Flags);

1539 addMultilibFlag(TargetTriple.isMIPS64(), "-m64", Flags);

1541 addMultilibFlag(CPUName == "mips32", "-march=mips32", Flags);

1542 addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||

1543 CPUName == "mips32r5" || CPUName == "p5600",

1544 "-march=mips32r2", Flags);

1545 addMultilibFlag(CPUName == "mips32r6", "-march=mips32r6", Flags);

1546 addMultilibFlag(CPUName == "mips64", "-march=mips64", Flags);

1547 addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||

1548 CPUName == "mips64r5" || CPUName == "octeon" ||

1549 CPUName == "octeon+",

1550 "-march=mips64r2", Flags);

1551 addMultilibFlag(CPUName == "mips64r6", "-march=mips64r6", Flags);

1555 Flags);

1562

1563 if (TargetTriple.isAndroid())

1566

1567 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&

1568 TargetTriple.getOS() == llvm::Triple::Linux &&

1569 TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)

1571

1572 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&

1573 TargetTriple.getOS() == llvm::Triple::Linux &&

1574 TargetTriple.isGNUEnvironment())

1576

1577 if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&

1578 TargetTriple.getOS() == llvm::Triple::Linux &&

1579 TargetTriple.isGNUEnvironment())

1581

1583 return true;

1584

1585

1588 Result.Multilibs.FilterOut(NonExistent);

1589

1590 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs)) {

1592 return true;

1593 }

1594

1595 return false;

1596}

1597

1599 const llvm::Triple &TargetTriple,

1600 StringRef Path, const ArgList &Args,

1602

1603 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1605 .flag("-march=armv7-a")

1606 .flag("-mthumb", true);

1608 .flag("-march=armv7-a", true)

1609 .flag("-mthumb");

1614 .flag("-march=armv7-a", true)

1615 .flag("-mthumb", true);

1618 .Either(ThumbMultilib, ArmV7Multilib, ArmV7ThumbMultilib,

1619 DefaultMultilib)

1622

1624 llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);

1625 bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;

1626 bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;

1627 bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;

1628 bool IsThumbMode = IsThumbArch ||

1629 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||

1630 (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB);

1631 bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&

1632 (llvm::ARM::parseArchVersion(Arch) == 7 ||

1633 (IsArmArch && Arch == "" && IsV7SubArch));

1634 addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags);

1635 addMultilibFlag(IsThumbMode, "-mthumb", Flags);

1636

1637 if (AndroidArmMultilibs.select(D, Flags, Result.SelectedMultilibs))

1638 Result.Multilibs = AndroidArmMultilibs;

1639}

1640

1642 const llvm::Triple &TargetTriple,

1643 StringRef Path, const ArgList &Args,

1645 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1650

1651

1652

1653

1654

1657 Result.Multilibs.FilterOut(NonExistent);

1658

1660 addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,

1661 options::OPT_fno_exceptions, false),

1662 "-exceptions", Flags);

1663 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))

1664 return true;

1665

1666 return false;

1667}

1668

1670 StringRef Path, const ArgList &Args,

1672 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1673

1675 std::optionalllvm::StringRef Res =

1677

1678 if (!Res)

1679 return;

1680 auto ARCHName = *Res;

1681

1684 Flags);

1686 Flags);

1688 addMultilibFlag(ARCHName == "ck801", "-march=ck801", Flags);

1689 addMultilibFlag(ARCHName == "ck802", "-march=ck802", Flags);

1690 addMultilibFlag(ARCHName == "ck803", "-march=ck803", Flags);

1691 addMultilibFlag(ARCHName == "ck804", "-march=ck804", Flags);

1692 addMultilibFlag(ARCHName == "ck805", "-march=ck805", Flags);

1693 addMultilibFlag(ARCHName == "ck807", "-march=ck807", Flags);

1694 addMultilibFlag(ARCHName == "ck810", "-march=ck810", Flags);

1695 addMultilibFlag(ARCHName == "ck810v", "-march=ck810v", Flags);

1696 addMultilibFlag(ARCHName == "ck860", "-march=ck860", Flags);

1697 addMultilibFlag(ARCHName == "ck860v", "-march=ck860v", Flags);

1698

1699 bool isBigEndian = false;

1700 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,

1701 options::OPT_mbig_endian))

1702 isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);

1703 addMultilibFlag(isBigEndian, "-EB", Flags);

1704

1711

1720

1723 .Maybe(BigEndian)

1724 .Either({Arch801, Arch802, Arch803, Arch804, Arch805, Arch807,

1725 Arch810, Arch810v, Arch860, Arch860v})

1726 .Either(HardFloat, SoftFpFloat, SoftFloat)

1729

1730 if (CSKYMultilibs.select(D, Flags, Result.SelectedMultilibs))

1731 Result.Multilibs = CSKYMultilibs;

1732}

1733

1734

1735

1736

1737

1738

1739

1740

1741

1742

1743

1744static bool

1748

1749 if (RISCVMultilibSet.select(D, Flags, SelectedMultilibs))

1750 return true;

1751

1753 std::vector NewMultilibs;

1754

1756 llvm::RISCVISAInfo::parseArchString(

1757 Arch, true,

1758 false);

1759

1760 if (llvm::errorToBool(ParseResult.takeError()))

1761 return false;

1762

1763 auto &ISAInfo = *ParseResult;

1764

1765 addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);

1766 addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);

1767

1768

1769 for (StringRef Flag : Flags) {

1770 if (Flag.starts_with("!march=") || Flag.starts_with("-march="))

1771 continue;

1772

1773 NewFlags.push_back(Flag.str());

1774 }

1775

1776 llvm::StringSet<> AllArchExts;

1777

1778

1779 for (const auto &M : RISCVMultilibSet) {

1780 bool Skip = false;

1781

1783 MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());

1784 for (StringRef Flag : M.flags()) {

1785

1786 if (!Flag.consume_front("-march=")) {

1787 NewMultilib.flag(Flag);

1788 continue;

1789 }

1790

1791

1793 llvm::RISCVISAInfo::parseArchString(

1794 Flag, true,

1795 false);

1796

1797 if (llvm::errorToBool(MLConfigParseResult.takeError())) {

1798

1799

1800 Skip = true;

1801 continue;

1802 }

1803 auto &MLConfigISAInfo = *MLConfigParseResult;

1804

1805 for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) {

1806 auto ExtName = MLConfigArchExt.first;

1807 NewMultilib.flag(Twine("-", ExtName).str());

1808

1809 if (AllArchExts.insert(ExtName).second) {

1810 addMultilibFlag(ISAInfo->hasExtension(ExtName),

1811 Twine("-", ExtName).str(), NewFlags);

1812 }

1813 }

1814

1815

1816 if (MLConfigISAInfo->getXLen() == 32) {

1817 NewMultilib.flag("-m32");

1818 NewMultilib.flag("-m64", true);

1819 } else {

1820 NewMultilib.flag("-m32", true);

1821 NewMultilib.flag("-m64");

1822 }

1823

1824

1825

1826 if (!MLConfigISAInfo->hasExtension("a"))

1827 NewMultilib.flag("-a", true);

1828 }

1829

1831 continue;

1832

1833 NewMultilibs.emplace_back(NewMultilib);

1834 }

1835

1836

1837

1840

1841 if (NewRISCVMultilibs.select(D, NewFlags, SelectedMultilibs))

1842 for (const Multilib &NewSelectedM : SelectedMultilibs)

1843 for (const auto &M : RISCVMultilibSet)

1844

1845 if (M.gccSuffix() == NewSelectedM.gccSuffix())

1846 return true;

1847

1848 return false;

1849}

1850

1852 const llvm::Triple &TargetTriple,

1853 StringRef Path, const ArgList &Args,

1855 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1856 struct RiscvMultilib {

1857 StringRef march;

1858 StringRef mabi;

1859 };

1860

1861

1862 constexpr RiscvMultilib RISCVMultilibSet[] = {

1863 {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"},

1864 {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},

1865 {"rv64imafdc", "lp64d"}};

1866

1867 std::vector Ms;

1868 for (auto Element : RISCVMultilibSet) {

1869

1870 Ms.emplace_back(

1872 (Twine(Element.march) + "/" + Twine(Element.mabi)).str())

1873 .flag(Twine("-march=", Element.march).str())

1874 .flag(Twine("-mabi=", Element.mabi).str()));

1875 }

1882 return std::vectorstd::string(

1884 "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(),

1885 "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()});

1886 });

1887

1889 llvm::StringSet<> Added_ABIs;

1892 for (auto Element : RISCVMultilibSet) {

1893 addMultilibFlag(MArch == Element.march,

1894 Twine("-march=", Element.march).str().c_str(), Flags);

1895 if (!Added_ABIs.count(Element.mabi)) {

1896 Added_ABIs.insert(Element.mabi);

1897 addMultilibFlag(ABIName == Element.mabi,

1898 Twine("-mabi=", Element.mabi).str().c_str(), Flags);

1899 }

1900 }

1901

1903 Result.SelectedMultilibs))

1904 Result.Multilibs = RISCVMultilibs;

1905}

1906

1908 const llvm::Triple &TargetTriple, StringRef Path,

1910 if (TargetTriple.getOS() == llvm::Triple::UnknownOS)

1912

1913 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());

1928 .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})

1929 .makeMultilibSet()

1931

1933 bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;

1935

1936 addMultilibFlag(!IsRV64, "-m32", Flags);

1937 addMultilibFlag(IsRV64, "-m64", Flags);

1938 addMultilibFlag(ABIName == "ilp32", "-mabi=ilp32", Flags);

1939 addMultilibFlag(ABIName == "ilp32f", "-mabi=ilp32f", Flags);

1940 addMultilibFlag(ABIName == "ilp32d", "-mabi=ilp32d", Flags);

1941 addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);

1942 addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);

1943 addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);

1944

1945 if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))

1946 Result.Multilibs = RISCVMultilibs;

1947}

1948

1950 const llvm::Triple &TargetTriple,

1951 StringRef Path, const ArgList &Args,

1952 bool NeedsBiarchSuffix,

1955

1956

1957

1958

1959

1960

1961

1962

1963 StringRef Suff64 = "/64";

1964

1965 if (TargetTriple.isOSSolaris()) {

1966 switch (TargetTriple.getArch()) {

1967 case llvm::Triple::x86:

1968 case llvm::Triple::x86_64:

1969 Suff64 = "/amd64";

1970 break;

1971 case llvm::Triple::sparc:

1972 case llvm::Triple::sparcv9:

1973 Suff64 = "/sparcv9";

1974 break;

1975 default:

1976 break;

1977 }

1978 }

1979

1982 .includeSuffix(Suff64)

1983 .flag("-m32", true)

1984 .flag("-m64")

1985 .flag("-mx32", true)

1986 .makeMultilib();

1989 .includeSuffix("/32")

1990 .flag("-m32")

1991 .flag("-m64", true)

1992 .flag("-mx32", true)

1993 .makeMultilib();

1996 .includeSuffix("/x32")

1997 .flag("-m32", true)

1998 .flag("-m64", true)

1999 .flag("-mx32")

2000 .makeMultilib();

2003 .includeSuffix("/sparcv8plus")

2004 .flag("-m32")

2005 .flag("-m64", true)

2006 .makeMultilib();

2007

2008

2009 FilterNonExistent NonExistent(

2010 Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());

2011

2012

2013

2014 enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;

2015 const bool IsX32 = TargetTriple.isX32();

2016 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))

2017 Want = WANT64;

2018 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc))

2019 Want = WANT64;

2020 else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))

2021 Want = WANT64;

2022 else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))

2023 Want = WANT32;

2024 else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc))

2025 Want = WANT64;

2026 else {

2027 if (TargetTriple.isArch32Bit())

2028 Want = NeedsBiarchSuffix ? WANT64 : WANT32;

2029 else if (IsX32)

2030 Want = NeedsBiarchSuffix ? WANT64 : WANTX32;

2031 else

2032 Want = NeedsBiarchSuffix ? WANT32 : WANT64;

2033 }

2034

2035 if (Want == WANT32)

2036 DefaultBuilder.flag("-m32")

2037 .flag("-m64", true)

2038 .flag("-mx32", true);

2039 else if (Want == WANT64)

2040 DefaultBuilder.flag("-m32", true)

2041 .flag("-m64")

2042 .flag("-mx32", true);

2043 else if (Want == WANTX32)

2044 DefaultBuilder.flag("-m32", true)

2045 .flag("-m64", true)

2046 .flag("-mx32");

2047 else

2048 return false;

2049

2051

2053 Result.Multilibs.push_back(Alt64);

2054 Result.Multilibs.push_back(Alt32);

2055 Result.Multilibs.push_back(Altx32);

2056 Result.Multilibs.push_back(Alt32sparc);

2057

2058 Result.Multilibs.FilterOut(NonExistent);

2059

2061 addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "-m64", Flags);

2062 addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags);

2063 addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags);

2064

2065 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))

2066 return false;

2067

2068 if (Result.SelectedMultilibs.back() == Alt64 ||

2069 Result.SelectedMultilibs.back() == Alt32 ||

2070 Result.SelectedMultilibs.back() == Altx32 ||

2071 Result.SelectedMultilibs.back() == Alt32sparc)

2073

2074 return true;

2075}

2076

2077

2078

2079

2080

2081

2083 int RHSPatch,

2084 StringRef RHSPatchSuffix) const {

2085 if (Major != RHSMajor)

2086 return Major < RHSMajor;

2087 if (Minor != RHSMinor) {

2088

2089

2090 if (RHSMinor == -1)

2091 return true;

2092 if (Minor == -1)

2093 return false;

2094 return Minor < RHSMinor;

2095 }

2096 if (Patch != RHSPatch) {

2097

2098

2099 if (RHSPatch == -1)

2100 return true;

2101 if (Patch == -1)

2102 return false;

2103

2104

2105 return Patch < RHSPatch;

2106 }

2107 if (PatchSuffix != RHSPatchSuffix) {

2108

2109 if (RHSPatchSuffix.empty())

2110 return true;

2111 if (PatchSuffix.empty())

2112 return false;

2113

2114

2115 return PatchSuffix < RHSPatchSuffix;

2116 }

2117

2118

2119 return false;

2120}

2121

2122

2123

2124

2125

2127 const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};

2128 std::pair<StringRef, StringRef> First = VersionText.split('.');

2129 std::pair<StringRef, StringRef> Second = First.second.split('.');

2130

2131 StringRef MajorStr = First.first;

2132 StringRef MinorStr = Second.first;

2133 StringRef PatchStr = Second.second;

2134

2135 GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};

2136

2137

2138

2139

2140

2141

2142

2143

2144

2145

2146

2147

2148

2149

2150

2151 auto TryParseLastNumber = [&](StringRef Segment, int &Number,

2152 std::string &OutStr) -> bool {

2153

2154

2155

2156 if (size_t EndNumber = Segment.find_first_not_of("0123456789")) {

2157 StringRef NumberStr = Segment.slice(0, EndNumber);

2158 if (NumberStr.getAsInteger(10, Number) || Number < 0)

2159 return false;

2160 OutStr = NumberStr;

2161 GoodVersion.PatchSuffix = Segment.substr(EndNumber);

2162 return true;

2163 }

2164 return false;

2165 };

2166 auto TryParseNumber = [](StringRef Segment, int &Number) -> bool {

2167 if (Segment.getAsInteger(10, Number) || Number < 0)

2168 return false;

2169 return true;

2170 };

2171

2172 if (MinorStr.empty()) {

2173

2174 if (!TryParseLastNumber(MajorStr, GoodVersion.Major, GoodVersion.MajorStr))

2175 return BadVersion;

2176 return GoodVersion;

2177 }

2178

2179 if (!TryParseNumber(MajorStr, GoodVersion.Major))

2180 return BadVersion;

2181 GoodVersion.MajorStr = MajorStr;

2182

2183 if (PatchStr.empty()) {

2184

2185 if (!TryParseLastNumber(MinorStr, GoodVersion.Minor, GoodVersion.MinorStr))

2186 return BadVersion;

2187 return GoodVersion;

2188 }

2189

2190 if (!TryParseNumber(MinorStr, GoodVersion.Minor))

2191 return BadVersion;

2192 GoodVersion.MinorStr = MinorStr;

2193

2194

2195 std::string DummyStr;

2196 TryParseLastNumber(PatchStr, GoodVersion.Patch, DummyStr);

2197 return GoodVersion;

2198}

2199

2201 llvm::StringRef SysRoot) {

2202 const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain);

2203 if (A)

2204 return A->getValue();

2205

2206

2207

2208

2209 if (!SysRoot.empty())

2210 return "";

2211

2212 return GCC_INSTALL_PREFIX;

2213}

2214

2215

2216

2217

2218

2219

2220

2221

2222

2223

2225 const llvm::Triple &TargetTriple, const ArgList &Args) {

2226 llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()

2227 ? TargetTriple.get64BitArchVariant()

2228 : TargetTriple.get32BitArchVariant();

2229

2231

2234

2235 CandidateTripleAliases.push_back(TargetTriple.str());

2236 std::string TripleNoVendor, BiarchTripleNoVendor;

2237 if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor) {

2238 StringRef OSEnv = TargetTriple.getOSAndEnvironmentName();

2239 if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32)

2240 OSEnv = "linux-gnu";

2241 TripleNoVendor = (TargetTriple.getArchName().str() + '-' + OSEnv).str();

2242 CandidateTripleAliases.push_back(TripleNoVendor);

2243 if (BiarchVariantTriple.getArch() != llvm::Triple::UnknownArch) {

2244 BiarchTripleNoVendor =

2245 (BiarchVariantTriple.getArchName().str() + '-' + OSEnv).str();

2246 CandidateBiarchTripleAliases.push_back(BiarchTripleNoVendor);

2247 }

2248 }

2249

2250 CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,

2251 CandidateTripleAliases, CandidateBiarchLibDirs,

2252 CandidateBiarchTripleAliases);

2253

2254

2255 if (const Arg *A =

2256 Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ);

2257 A && A->getValue()[0]) {

2258 StringRef InstallDir = A->getValue();

2259 if (!ScanGCCForMultilibs(TargetTriple, Args, InstallDir, false)) {

2260 D.Diag(diag::err_drv_invalid_gcc_install_dir) << InstallDir;

2261 } else {

2262 (void)InstallDir.consume_back("/");

2263 StringRef VersionText = llvm::sys::path::filename(InstallDir);

2264 StringRef TripleText =

2265 llvm::sys::path::filename(llvm::sys::path::parent_path(InstallDir));

2266

2267 Version = GCCVersion::Parse(VersionText);

2268 GCCTriple.setTriple(TripleText);

2269 GCCInstallPath = std::string(InstallDir);

2270 GCCParentLibPath = GCCInstallPath + "/../../..";

2271 IsValid = true;

2272 }

2273 return;

2274 }

2275

2276

2277

2278 if (const Arg *A =

2279 Args.getLastArg(clang::driver::options::OPT_gcc_triple_EQ)) {

2280 StringRef GCCTriple = A->getValue();

2281 CandidateTripleAliases.clear();

2282 CandidateTripleAliases.push_back(GCCTriple);

2283 }

2284

2285

2288 if (GCCToolchainDir != "") {

2289 if (GCCToolchainDir.back() == '/')

2290 GCCToolchainDir = GCCToolchainDir.drop_back();

2291

2292 Prefixes.push_back(std::string(GCCToolchainDir));

2293 } else {

2294

2295 if (D.SysRoot.empty()) {

2296 Prefixes.push_back(D.SysRoot);

2297 AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);

2298 }

2299

2300

2301 Prefixes.push_back(D.Dir + "/..");

2302

2303

2304

2305 if (D.SysRoot.empty()) {

2306

2307 AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot);

2308 }

2309

2310

2311

2312

2314

2315

2316

2317

2318

2319 GentooTestTriples.push_back(TargetTriple.str());

2320 GentooTestTriples.append(CandidateTripleAliases.begin(),

2321 CandidateTripleAliases.end());

2322 if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples,

2323 CandidateBiarchTripleAliases))

2324 return;

2325 }

2326

2327

2328

2329 const GCCVersion VersionZero = GCCVersion::Parse("0.0.0");

2330 Version = VersionZero;

2331 for (const std::string &Prefix : Prefixes) {

2332 auto &VFS = D.getVFS();

2333 if (!VFS.exists(Prefix))

2334 continue;

2335 for (StringRef Suffix : CandidateLibDirs) {

2336 const std::string LibDir = concat(Prefix, Suffix);

2337 if (!VFS.exists(LibDir))

2338 continue;

2339

2340 bool GCCDirExists = VFS.exists(LibDir + "/gcc");

2341 bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");

2342 for (StringRef Candidate : CandidateTripleAliases)

2343 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false,

2344 GCCDirExists, GCCCrossDirExists);

2345 }

2346 for (StringRef Suffix : CandidateBiarchLibDirs) {

2347 const std::string LibDir = Prefix + Suffix.str();

2348 if (!VFS.exists(LibDir))

2349 continue;

2350 bool GCCDirExists = VFS.exists(LibDir + "/gcc");

2351 bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");

2352 for (StringRef Candidate : CandidateBiarchTripleAliases)

2353 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true,

2354 GCCDirExists, GCCCrossDirExists);

2355 }

2356

2357

2358 if (Version > VersionZero)

2359 break;

2360 }

2361}

2362

2364 for (const auto &InstallPath : CandidateGCCInstallPaths)

2365 OS << "Found candidate GCC installation: " << InstallPath << "\n";

2366

2367 if (!GCCInstallPath.empty())

2368 OS << "Selected GCC installation: " << GCCInstallPath << "\n";

2369

2370 for (const auto &Multilib : Multilibs)

2371 OS << "Candidate multilib: " << Multilib << "\n";

2372

2373 if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())

2374 OS << "Selected multilib: " << SelectedMultilib << "\n";

2375}

2376

2378 if (BiarchSibling) {

2379 M = *BiarchSibling;

2380 return true;

2381 }

2382 return false;

2383}

2384

2385void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(

2387 StringRef SysRoot) {

2388

2389 if (TargetTriple.isOSHaiku()) {

2390 Prefixes.push_back(concat(SysRoot, "/boot/system/develop/tools"));

2391 return;

2392 }

2393

2394 if (TargetTriple.isOSSolaris()) {

2395

2396

2397

2398

2399

2400

2402 std::string PrefixDir = concat(SysRoot, "/usr/gcc");

2403 std::error_code EC;

2404 for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),

2405 LE;

2406 !EC && LI != LE; LI = LI.increment(EC)) {

2407 StringRef VersionText = llvm::sys::path::filename(LI->path());

2408 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);

2409

2410

2411 if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(4, 1, 1))

2412 continue;

2413

2414 std::string CandidatePrefix = PrefixDir + "/" + VersionText.str();

2415 std::string CandidateLibPath = CandidatePrefix + "/lib/gcc";

2416 if (D.getVFS().exists(CandidateLibPath))

2417 continue;

2418

2419 SolarisPrefixes.emplace_back(

2420 std::make_pair(CandidateVersion, CandidatePrefix));

2421 }

2422

2423 std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend());

2424 for (auto p : SolarisPrefixes)

2425 Prefixes.emplace_back(p.second);

2426 return;

2427 }

2428

2429

2430

2431 if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&

2432 D.getVFS().exists("/opt/rh")) {

2433

2434

2435 Prefixes.push_back("/opt/rh/gcc-toolset-12/root/usr");

2436 Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr");

2437 Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr");

2438 Prefixes.push_back("/opt/rh/devtoolset-12/root/usr");

2439 Prefixes.push_back("/opt/rh/devtoolset-11/root/usr");

2440 Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");

2441 Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");

2442 Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");

2443 Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");

2444 Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");

2445 Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");

2446 Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");

2447 Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");

2448 }

2449

2450

2451 Prefixes.push_back(concat(SysRoot, "/usr"));

2452}

2453

2454 void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(

2455 const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,

2460

2461

2462

2463

2464

2465

2466

2467

2468

2469 static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};

2470 static const char *const AArch64Triples[] = {

2471 "aarch64-none-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux"};

2472 static const char *const AArch64beLibDirs[] = {"/lib"};

2473 static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu"};

2474

2475 static const char *const ARMLibDirs[] = {"/lib"};

2476 static const char *const ARMTriples[] = {"arm-linux-gnueabi"};

2477 static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",

2478 "armv7hl-redhat-linux-gnueabi",

2479 "armv6hl-suse-linux-gnueabi",

2480 "armv7hl-suse-linux-gnueabi"};

2481 static const char *const ARMebLibDirs[] = {"/lib"};

2482 static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"};

2483 static const char *const ARMebHFTriples[] = {

2484 "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};

2485

2486 static const char *const AVRLibDirs[] = {"/lib"};

2487 static const char *const AVRTriples[] = {"avr"};

2488

2489 static const char *const CSKYLibDirs[] = {"/lib"};

2490 static const char *const CSKYTriples[] = {

2491 "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"};

2492

2493 static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};

2494 static const char *const X86_64Triples[] = {

2495 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",

2496 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",

2497 "x86_64-redhat-linux", "x86_64-suse-linux",

2498 "x86_64-manbo-linux-gnu", "x86_64-slackware-linux",

2499 "x86_64-unknown-linux", "x86_64-amazon-linux"};

2500 static const char *const X32Triples[] = {"x86_64-linux-gnux32",

2501 "x86_64-pc-linux-gnux32"};

2502 static const char *const X32LibDirs[] = {"/libx32", "/lib"};

2503 static const char *const X86LibDirs[] = {"/lib32", "/lib"};

2504 static const char *const X86Triples[] = {

2505 "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu",

2506 "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux",

2507 "i586-suse-linux", "i686-montavista-linux",

2508 };

2509

2510 static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"};

2511 static const char *const LoongArch64Triples[] = {

2512 "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"};

2513

2514 static const char *const M68kLibDirs[] = {"/lib"};

2515 static const char *const M68kTriples[] = {"m68k-unknown-linux-gnu",

2516 "m68k-suse-linux"};

2517

2518 static const char *const MIPSLibDirs[] = {"/libo32", "/lib"};

2519 static const char *const MIPSTriples[] = {

2520 "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu",

2521 "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"};

2522 static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"};

2523 static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",

2524 "mips-img-linux-gnu"};

2525

2526 static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};

2527 static const char *const MIPS64Triples[] = {

2528 "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64-linux-gnuabi64",

2529 "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"};

2530 static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};

2531 static const char *const MIPS64ELTriples[] = {

2532 "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64el-linux-gnuabi64",

2533 "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64"};

2534

2535 static const char *const MIPSN32LibDirs[] = {"/lib32"};

2536 static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32",

2537 "mipsisa64r6-linux-gnuabin32"};

2538 static const char *const MIPSN32ELLibDirs[] = {"/lib32"};

2539 static const char *const MIPSN32ELTriples[] = {

2540 "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"};

2541

2542 static const char *const MSP430LibDirs[] = {"/lib"};

2543 static const char *const MSP430Triples[] = {"msp430-elf"};

2544

2545 static const char *const PPCLibDirs[] = {"/lib32", "/lib"};

2546 static const char *const PPCTriples[] = {

2547 "powerpc-unknown-linux-gnu",

2548

2549

2550 "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};

2551 static const char *const PPCLELibDirs[] = {"/lib32", "/lib"};

2552 static const char *const PPCLETriples[] = {"powerpcle-unknown-linux-gnu",

2553 "powerpcle-linux-musl"};

2554

2555 static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};

2556 static const char *const PPC64Triples[] = {"powerpc64-unknown-linux-gnu",

2557 "powerpc64-suse-linux",

2558 "ppc64-redhat-linux"};

2559 static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};

2560 static const char *const PPC64LETriples[] = {

2561 "powerpc64le-unknown-linux-gnu", "powerpc64le-none-linux-gnu",

2562 "powerpc64le-suse-linux", "ppc64le-redhat-linux"};

2563

2564 static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"};

2565 static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",

2566 "riscv32-unknown-elf"};

2567 static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};

2568 static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",

2569 "riscv64-unknown-elf"};

2570

2571 static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};

2572 static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",

2573 "sparcv8-linux-gnu"};

2574 static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};

2575 static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",

2576 "sparcv9-linux-gnu"};

2577

2578 static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};

2579 static const char *const SystemZTriples[] = {

2580 "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", "s390x-suse-linux",

2581 "s390x-redhat-linux"};

2582

2583 using std::begin;

2584 using std::end;

2585

2586 if (TargetTriple.isOSSolaris()) {

2587 static const char *const SolarisLibDirs[] = {"/lib"};

2588 static const char *const SolarisSparcV8Triples[] = {

2589 "sparc-sun-solaris2.11"};

2590 static const char *const SolarisSparcV9Triples[] = {

2591 "sparcv9-sun-solaris2.11"};

2592 static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11"};

2593 static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11"};

2594 LibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));

2595 BiarchLibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs));

2596 switch (TargetTriple.getArch()) {

2597 case llvm::Triple::x86:

2598 TripleAliases.append(begin(SolarisX86Triples), end(SolarisX86Triples));

2599 BiarchTripleAliases.append(begin(SolarisX86_64Triples),

2600 end(SolarisX86_64Triples));

2601 break;

2602 case llvm::Triple::x86_64:

2603 TripleAliases.append(begin(SolarisX86_64Triples),

2604 end(SolarisX86_64Triples));

2605 BiarchTripleAliases.append(begin(SolarisX86Triples),

2606 end(SolarisX86Triples));

2607 break;

2608 case llvm::Triple::sparc:

2609 TripleAliases.append(begin(SolarisSparcV8Triples),

2610 end(SolarisSparcV8Triples));

2611 BiarchTripleAliases.append(begin(SolarisSparcV9Triples),

2612 end(SolarisSparcV9Triples));

2613 break;

2614 case llvm::Triple::sparcv9:

2615 TripleAliases.append(begin(SolarisSparcV9Triples),

2616 end(SolarisSparcV9Triples));

2617 BiarchTripleAliases.append(begin(SolarisSparcV8Triples),

2618 end(SolarisSparcV8Triples));

2619 break;

2620 default:

2621 break;

2622 }

2623 return;

2624 }

2625

2626

2627 if (TargetTriple.isAndroid()) {

2628 static const char *const AArch64AndroidTriples[] = {

2629 "aarch64-linux-android"};

2630 static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"};

2631 static const char *const X86AndroidTriples[] = {"i686-linux-android"};

2632 static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"};

2633

2634 switch (TargetTriple.getArch()) {

2635 case llvm::Triple::aarch64:

2636 LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

2637 TripleAliases.append(begin(AArch64AndroidTriples),

2638 end(AArch64AndroidTriples));

2639 break;

2640 case llvm::Triple::arm:

2641 case llvm::Triple::thumb:

2642 LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));

2643 TripleAliases.append(begin(ARMAndroidTriples), end(ARMAndroidTriples));

2644 break;

2645 case llvm::Triple::x86_64:

2646 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2647 TripleAliases.append(begin(X86_64AndroidTriples),

2648 end(X86_64AndroidTriples));

2649 BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2650 BiarchTripleAliases.append(begin(X86AndroidTriples),

2651 end(X86AndroidTriples));

2652 break;

2653 case llvm::Triple::x86:

2654 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2655 TripleAliases.append(begin(X86AndroidTriples), end(X86AndroidTriples));

2656 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2657 BiarchTripleAliases.append(begin(X86_64AndroidTriples),

2658 end(X86_64AndroidTriples));

2659 break;

2660 default:

2661 break;

2662 }

2663

2664 return;

2665 }

2666

2667 if (TargetTriple.isOSHurd()) {

2668 switch (TargetTriple.getArch()) {

2669 case llvm::Triple::x86_64:

2670 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2671 TripleAliases.push_back("x86_64-gnu");

2672 break;

2673 case llvm::Triple::x86:

2674 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2675 TripleAliases.push_back("i686-gnu");

2676 break;

2677 default:

2678 break;

2679 }

2680

2681 return;

2682 }

2683

2684 switch (TargetTriple.getArch()) {

2685 case llvm::Triple::aarch64:

2686 LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

2687 TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));

2688 BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

2689 BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));

2690 break;

2691 case llvm::Triple::aarch64_be:

2692 LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));

2693 TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));

2694 BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));

2695 BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));

2696 break;

2697 case llvm::Triple::arm:

2698 case llvm::Triple::thumb:

2699 LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));

2700 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||

2701 TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||

2702 TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||

2703 TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {

2704 TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));

2705 } else {

2706 TripleAliases.append(begin(ARMTriples), end(ARMTriples));

2707 }

2708 break;

2709 case llvm::Triple::armeb:

2710 case llvm::Triple::thumbeb:

2711 LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));

2712 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF ||

2713 TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||

2714 TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF ||

2715 TargetTriple.getEnvironment() == llvm::Triple::EABIHF) {

2716 TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));

2717 } else {

2718 TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));

2719 }

2720 break;

2721 case llvm::Triple::avr:

2722 LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs));

2723 TripleAliases.append(begin(AVRTriples), end(AVRTriples));

2724 break;

2725 case llvm::Triple::csky:

2726 LibDirs.append(begin(CSKYLibDirs), end(CSKYLibDirs));

2727 TripleAliases.append(begin(CSKYTriples), end(CSKYTriples));

2728 break;

2729 case llvm::Triple::x86_64:

2730 if (TargetTriple.isX32()) {

2731 LibDirs.append(begin(X32LibDirs), end(X32LibDirs));

2732 TripleAliases.append(begin(X32Triples), end(X32Triples));

2733 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2734 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));

2735 } else {

2736 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2737 TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));

2738 BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));

2739 BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));

2740 }

2741 BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2742 BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));

2743 break;

2744 case llvm::Triple::x86:

2745 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));

2746

2747

2748 if (!TargetTriple.isOSIAMCU()) {

2749 TripleAliases.append(begin(X86Triples), end(X86Triples));

2750 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));

2751 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));

2752 BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));

2753 BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));

2754 }

2755 break;

2756

2757 case llvm::Triple::loongarch64:

2758 LibDirs.append(begin(LoongArch64LibDirs), end(LoongArch64LibDirs));

2759 TripleAliases.append(begin(LoongArch64Triples), end(LoongArch64Triples));

2760 break;

2761 case llvm::Triple::m68k:

2762 LibDirs.append(begin(M68kLibDirs), end(M68kLibDirs));

2763 TripleAliases.append(begin(M68kTriples), end(M68kTriples));

2764 break;

2765 case llvm::Triple::mips:

2766 LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));

2767 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2768 BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));

2769 BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));

2770 BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));

2771 BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));

2772 break;

2773 case llvm::Triple::mipsel:

2774 LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));

2775 TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));

2776 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2777 BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));

2778 BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));

2779 BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));

2780 BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));

2781 break;

2782 case llvm::Triple::mips64:

2783 LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));

2784 TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));

2785 BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));

2786 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2787 BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs));

2788 BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples));

2789 break;

2790 case llvm::Triple::mips64el:

2791 LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));

2792 TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));

2793 BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));

2794 BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));

2795 BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs));

2796 BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));

2797 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));

2798 break;

2799 case llvm::Triple::msp430:

2800 LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs));

2801 TripleAliases.append(begin(MSP430Triples), end(MSP430Triples));

2802 break;

2803 case llvm::Triple::ppc:

2804 LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));

2805 TripleAliases.append(begin(PPCTriples), end(PPCTriples));

2806 BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));

2807 BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));

2808 break;

2809 case llvm::Triple::ppcle:

2810 LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));

2811 TripleAliases.append(begin(PPCLETriples), end(PPCLETriples));

2812 BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));

2813 BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));

2814 break;

2815 case llvm::Triple::ppc64:

2816 LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));

2817 TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));

2818 BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));

2819 BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));

2820 break;

2821 case llvm::Triple::ppc64le:

2822 LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));

2823 TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));

2824 BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));

2825 BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples));

2826 break;

2827 case llvm::Triple::riscv32:

2828 LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));

2829 TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));

2830 BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));

2831 BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));

2832 break;

2833 case llvm::Triple::riscv64:

2834 LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));

2835 TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));

2836 BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));

2837 BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));

2838 break;

2839 case llvm::Triple::sparc:

2840 case llvm::Triple::sparcel:

2841 LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));

2842 TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));

2843 BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));

2844 BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));

2845 break;

2846 case llvm::Triple::sparcv9:

2847 LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));

2848 TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));

2849 BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));

2850 BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));

2851 break;

2852 case llvm::Triple::systemz:

2853 LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));

2854 TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));

2855 break;

2856 default:

2857

2858

2859 break;

2860 }

2861

2862

2863 if (TargetTriple.str() != BiarchTriple.str())

2864 BiarchTripleAliases.push_back(BiarchTriple.str());

2865}

2866

2867bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(

2868 const llvm::Triple &TargetTriple, const ArgList &Args,

2869 StringRef Path, bool NeedsBiarchSuffix) {

2870 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();

2872

2873

2874

2875

2876 if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {

2877

2879 } else if (TargetTriple.isCSKY()) {

2881 } else if (TargetTriple.isMIPS()) {

2883 return false;

2884 } else if (TargetTriple.isRISCV()) {

2886 } else if (isMSP430(TargetArch)) {

2888 } else if (TargetArch == llvm::Triple::avr) {

2889

2891 NeedsBiarchSuffix, Detected)) {

2892 return false;

2893 }

2894

2898 : Detected.SelectedMultilibs.back();

2900

2901 return true;

2902}

2903

2904void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(

2905 const llvm::Triple &TargetTriple, const ArgList &Args,

2906 const std::string &LibDir, StringRef CandidateTriple,

2907 bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) {

2908

2909

2910 struct GCCLibSuffix {

2911

2912 std::string LibSuffix;

2913

2914

2915 StringRef ReversePath;

2916

2917 bool Active;

2919

2920 {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists},

2921

2922

2923 {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists},

2924

2925

2926

2927

2928

2929 {CandidateTriple.str(), "..",

2930 TargetTriple.getVendor() == llvm::Triple::Freescale ||

2931 TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};

2932

2933 for (auto &Suffix : Suffixes) {

2934 if (!Suffix.Active)

2935 continue;

2936

2937 StringRef LibSuffix = Suffix.LibSuffix;

2938 std::error_code EC;

2939 for (llvm::vfs::directory_iterator

2940 LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC),

2941 LE;

2942 !EC && LI != LE; LI = LI.increment(EC)) {

2943 StringRef VersionText = llvm::sys::path::filename(LI->path());

2944 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);

2945 if (CandidateVersion.Major != -1)

2946 if (!CandidateGCCInstallPaths.insert(std::string(LI->path())).second)

2947 continue;

2948 if (CandidateVersion.isOlderThan(4, 1, 1))

2949 continue;

2950 if (CandidateVersion <= Version)

2951 continue;

2952

2953 if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),

2954 NeedsBiarchSuffix))

2955 continue;

2956

2957 Version = CandidateVersion;

2958 GCCTriple.setTriple(CandidateTriple);

2959

2960

2961

2962 GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();

2963 GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();

2964 IsValid = true;

2965 }

2966 }

2967}

2968

2969bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(

2970 const llvm::Triple &TargetTriple, const ArgList &Args,

2973 if (D.getVFS().exists(concat(D.SysRoot, GentooConfigDir)))

2974 return false;

2975

2976 for (StringRef CandidateTriple : CandidateTriples) {

2977 if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))

2978 return true;

2979 }

2980

2981 for (StringRef CandidateTriple : CandidateBiarchTriples) {

2982 if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true))

2983 return true;

2984 }

2985 return false;

2986}

2987

2988bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(

2989 const llvm::Triple &TargetTriple, const ArgList &Args,

2990 StringRef CandidateTriple, bool NeedsBiarchSuffix) {

2991 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> File =

2992 D.getVFS().getBufferForFile(concat(D.SysRoot, GentooConfigDir,

2993 "/config-" + CandidateTriple.str()));

2996 File.get()->getBuffer().split(Lines, "\n");

2997 for (StringRef Line : Lines) {

2999

3000 if (Line.consume_front("CURRENT="))

3001 continue;

3002

3003 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> ConfigFile =

3004 D.getVFS().getBufferForFile(

3005 concat(D.SysRoot, GentooConfigDir, "/" + Line));

3006 std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-');

3007

3009

3010

3011

3012

3013

3014

3015

3016

3017 if (ConfigFile) {

3019 ConfigFile.get()->getBuffer().split(ConfigLines, "\n");

3020 for (StringRef ConfLine : ConfigLines) {

3021 ConfLine = ConfLine.trim();

3022 if (ConfLine.consume_front("LDPATH=")) {

3023

3024 ConfLine.consume_back("\"");

3025 ConfLine.consume_front("\"");

3026

3027 ConfLine.split(GentooScanPaths, ':', -1, false);

3028 }

3029 }

3030 }

3031

3032 std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/"

3033 + ActiveVersion.second.str();

3034 GentooScanPaths.push_back(StringRef(basePath));

3035

3036

3037 for (const auto &GentooScanPath : GentooScanPaths) {

3038 std::string GentooPath = concat(D.SysRoot, GentooScanPath);

3039 if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {

3040 if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath,

3041 NeedsBiarchSuffix))

3042 continue;

3043

3044 Version = GCCVersion::Parse(ActiveVersion.second);

3045 GCCInstallPath = GentooPath;

3046 GCCParentLibPath = GentooPath + std::string("/../../..");

3047 GCCTriple.setTriple(ActiveVersion.first);

3048 IsValid = true;

3049 return true;

3050 }

3051 }

3052 }

3053 }

3054

3055 return false;

3056}

3057

3059 const ArgList &Args)

3060 : ToolChain(D, Triple, Args), GCCInstallation(D),

3061 CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args),

3062 SYCLInstallation(D, Triple, Args) {

3064}

3065

3067

3069 switch (AC) {

3071 if (!Preprocess)

3073 return Preprocess.get();

3075 if (!Compile)

3077 return Compile.get();

3078 default:

3080 }

3081}

3082

3085}

3086

3088

3090

3094}

3095

3099 case llvm::Triple::aarch64:

3100 case llvm::Triple::aarch64_be:

3101 case llvm::Triple::ppc:

3102 case llvm::Triple::ppcle:

3103 case llvm::Triple::ppc64:

3104 case llvm::Triple::ppc64le:

3105 case llvm::Triple::riscv32:

3106 case llvm::Triple::riscv64:

3107 case llvm::Triple::x86:

3108 case llvm::Triple::x86_64:

3110 default:

3112 }

3113}

3114

3117 case llvm::Triple::x86_64:

3118 return getTriple().isOSWindows();

3119 case llvm::Triple::mips64:

3120 case llvm::Triple::mips64el:

3121 return true;

3122 default:

3123 return false;

3124 }

3125}

3126

3128 return false;

3129}

3130

3132 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();

3133}

3134

3137 case llvm::Triple::nvptx:

3138 case llvm::Triple::nvptx64:

3139 case llvm::Triple::xcore:

3140 return false;

3141 default:

3142 return true;

3143 }

3144}

3145

3147

3148

3149

3150

3151

3152

3153

3157 .str());

3158 }

3159}

3160

3162 const std::string &SysRoot,

3163 const std::string &OSLibDir,

3164 const std::string &MultiarchTriple,

3166

3170 const std::string &LibPath =

3172

3173

3174

3178

3179

3180 addPathIfExists(D,

3183 Paths);

3184

3185

3186

3188 Paths);

3189

3190

3191

3192

3193

3194

3195

3196

3197

3198

3199

3200

3201

3202

3203

3204

3205

3206

3207

3208 addPathIfExists(D,

3209 LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +

3211 Paths);

3212

3213

3214

3215

3216

3217

3218

3219

3220

3221

3222 if (StringRef(LibPath).starts_with(SysRoot))

3223 addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);

3224 }

3225}

3226

3228 const std::string &SysRoot,

3229 const std::string &OSLibDir,

3232 const std::string &LibPath =

3236 addPathIfExists(

3237 D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(),

3238 Paths);

3239 }

3240}

3241

3243 ArgStringList &CC1Args) const {

3244

3246 return;

3247

3251 Twine(LibPath) + "/../" + GCCTriple.str() + "/include");

3252

3254 if (Callback) {

3258 }

3259}

3260

3262 ArgStringList &CC1Args) const {

3263 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,

3264 options::OPT_nostdlibinc))

3265 return;

3266

3270 break;

3271

3274 break;

3275 }

3276}

3277

3279 ArgStringList &CC1Args) const {

3281}

3282

3283void

3285 llvm::opt::ArgStringList &CC1Args) const {

3288 if (SysRoot.empty())

3289 SysRoot = llvm::sys::path::get_separator();

3290

3291 auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {

3293 if (Version.empty())

3294 return false;

3295

3296

3297 bool TargetDirExists = false;

3299 if (TargetIncludeDir) {

3301 llvm::sys::path::append(TargetDir, "c++", Version);

3302 if (D.getVFS().exists(TargetDir)) {

3304 TargetDirExists = true;

3305 }

3306 }

3307 if (TargetDirRequired && !TargetDirExists)

3308 return false;

3309

3310

3312 llvm::sys::path::append(GenericDir, "c++", Version);

3314 return true;

3315 };

3316

3317

3318

3319

3321 llvm::sys::path::append(DriverIncludeDir, "..", "include");

3322 if (AddIncludePath(DriverIncludeDir,

3323 getTriple().isAndroid()))

3324 return;

3325

3326

3327

3329 llvm::sys::path::append(UsrLocalIncludeDir, "usr", "local", "include");

3330 if (AddIncludePath(UsrLocalIncludeDir))

3331 return;

3333 llvm::sys::path::append(UsrIncludeDir, "usr", "include");

3334 if (AddIncludePath(UsrIncludeDir))

3335 return;

3336}

3337

3339 Twine IncludeSuffix,

3340 const llvm::opt::ArgList &DriverArgs,

3341 llvm::opt::ArgStringList &CC1Args,

3342 bool DetectDebian) const {

3343 if (getVFS().exists(IncludeDir))

3344 return false;

3345

3346

3347

3348

3349 std::string Dir = IncludeDir.str();

3350 StringRef Include =

3351 llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir));

3352 std::string Path =

3353 (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix)

3354 .str();

3355 if (DetectDebian && getVFS().exists(Path))

3356 return false;

3357

3358

3360

3361

3362 if (DetectDebian)

3364 else if (!Triple.empty())

3366 IncludeDir + "/" + Triple + IncludeSuffix);

3367

3368 addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");

3369 return true;

3370}

3371

3373 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,

3374 StringRef DebianMultiarch) const {

3376

3377

3378

3379

3385

3386

3388 LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text,

3390 return true;

3391

3392

3393

3394

3396 Version.Text + "/include/c++/",

3398 CC1Args))

3399 return true;

3400

3401

3404 DriverArgs, CC1Args, true))

3405 return true;

3406

3407

3410 CC1Args))

3411 return true;

3412

3413

3414

3415 const std::string LibStdCXXIncludePathCandidates[] = {

3416

3417

3418 InstallDir.str() + "/include/g++-v" + Version.Text,

3419 InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +

3421 InstallDir.str() + "/include/g++-v" + Version.MajorStr,

3422 };

3423

3424 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {

3427 return true;

3428 }

3429 return false;

3430}

3431

3432void

3434 llvm::opt::ArgStringList &CC1Args) const {

3438 }

3439}

3440

3441llvm::opt::DerivedArgList *

3444

3445

3446

3447

3448

3450 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());

3452

3453

3454

3455 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_shared));

3456 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_fPIC));

3457

3458

3459

3460 for (auto *A : Args) {

3461 switch ((options::ID)A->getOption().getID()) {

3462 default:

3463 DAL->append(A);

3464 break;

3465 case options::OPT_shared:

3466 case options::OPT_dynamic:

3467 case options::OPT_static:

3468 case options::OPT_fPIC:

3469 case options::OPT_fno_PIC:

3470 case options::OPT_fpic:

3471 case options::OPT_fno_pic:

3472 case options::OPT_fPIE:

3473 case options::OPT_fno_PIE:

3474 case options::OPT_fpie:

3475 case options::OPT_fno_pie:

3476 break;

3477 }

3478 }

3479 return DAL;

3480 }

3481 return nullptr;

3482}

3483

3484void Generic_ELF::anchor() {}

3485

3487 ArgStringList &CC1Args,

3489 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,

3490 options::OPT_fno_use_init_array, true))

3491 CC1Args.push_back("-fno-use-init-array");

3492}

static constexpr CPUSuffix Suffixes[]

static bool findMipsAndroidMultilibs(const Driver &D, llvm::vfs::FileSystem &VFS, StringRef Path, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static void findAndroidArmMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static bool findMipsCsMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static bool isArmOrThumbArch(llvm::Triple::ArchType Arch)

static bool selectRISCVMultilib(const Driver &D, const MultilibSet &RISCVMultilibSet, StringRef Arch, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &SelectedMultilibs)

Extend the multi-lib re-use selection mechanism for RISC-V.

static void normalizeCPUNamesForAssembler(const ArgList &Args, ArgStringList &CmdArgs)

static bool findBiarchMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, bool NeedsBiarchSuffix, DetectedMultilibs &Result)

static bool isMips16(const ArgList &Args)

static llvm::StringRef getGCCToolchainDir(const ArgList &Args, llvm::StringRef SysRoot)

static bool findMSP430Multilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static bool getStatic(const ArgList &Args)

static bool isMipsEL(llvm::Triple::ArchType Arch)

static const char * getLDMOption(const llvm::Triple &T, const ArgList &Args)

static bool findMipsMuslMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static void findRISCVBareMetalMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result)

static bool isMSP430(llvm::Triple::ArchType Arch)

static bool isSoftFloatABI(const ArgList &Args)

static bool getStaticPIE(const ArgList &Args, const ToolChain &TC)

static bool findMipsImgMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static bool forwardToGCC(const Option &O)

static bool findMipsMtiMultilibs(const Driver &D, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result)

static bool isMicroMips(const ArgList &Args)

types::ID getType() const

bool isHostOffloading(unsigned int OKind) const

Check if this action have any offload kinds.

Compilation - A set of tasks to perform for a single driver invocation.

Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...

const llvm::opt::OptTable & getOpts() const

InputInfo - Wrapper for information about an input source.

const char * getFilename() const

This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.

MultilibBuilder & flag(StringRef Flag, bool Disallow=false)

Add a flag to the flags list Flag must be a flag accepted by the driver.

const std::string & gccSuffix() const

Get the detected GCC installation path suffix for the multi-arch target variant.

const std::string & osSuffix() const

Get the detected os path suffix for the multi-arch target variant.

Multilib makeMultilib() const

This class can be used to create a MultilibSet, and contains helper functions to add combinations of ...

MultilibSetBuilder & Maybe(const MultilibBuilder &M)

Add an optional Multilib segment.

MultilibSetBuilder & FilterOut(const char *Regex)

Filter out those Multilibs whose gccSuffix matches the given expression.

MultilibSetBuilder & Either(const MultilibBuilder &M1, const MultilibBuilder &M2)

Add a set of mutually incompatible Multilib segments.

MultilibSet makeMultilibSet() const

See also MultilibSetBuilder for combining multilibs into a set.

bool select(const Driver &D, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &, llvm::SmallVector< StringRef > *=nullptr) const

Select compatible variants,.

MultilibSet & setFilePathsCallback(IncludeDirsFunc F)

MultilibSet & FilterOut(FilterCallback F)

Filter out some subset of the Multilibs using a user defined callback.

const IncludeDirsFunc & filePathsCallback() const

const IncludeDirsFunc & includeDirsCallback() const

MultilibSet & setIncludeDirsCallback(IncludeDirsFunc F)

This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.

const std::string & gccSuffix() const

Get the detected GCC installation path suffix for the multi-arch target variant.

const std::string & osSuffix() const

Get the detected os path suffix for the multi-arch target variant.

std::vector< std::string > flags_list

const std::string & includeSuffix() const

Get the include directory suffix.

bool isDefault() const

Check whether the default is selected.

bool isLLVMIR(ID Id)

Is this LLVM IR.

const char * getTypeName(ID Id)

getTypeName - Return the name of the type for Id.

bool canTypeBeUserSpecified(ID Id)

canTypeBeUserSpecified - Can this type be specified on the command line (by the type name); this is u...

bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const llvm::opt::ArgList &Args, DetectedMultilibs &Result)

The JSON file list parser is used to communicate input to InstallAPI.

@ Result

The result type of a method or function.

const FunctionProtoType * T

MultilibSet Multilibs

The set of multilibs that the detected installation supports.

std::optional< Multilib > BiarchSibling

On Biarch systems, this corresponds to the default multilib when targeting the non-default multilib.

llvm::SmallVector< Multilib > SelectedMultilibs

The multilibs appropriate for the given flags.

static constexpr ResponseFileSupport AtFileCurCP()