diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -390,6 +390,11 @@ "-ftest-module-file-extension argument '%0' is not of the required form " "'blockname:major:minor:hashed:user info'">; +def warn_drv_multilib_fallback : Warning< + "%0 option unrecognized in multi-lib configuration when parsing config " + "from GCC, falling back to built-in multi-lib configuration.">, + InGroup; + def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">, InGroup>; def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -767,6 +767,7 @@ def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">; def MisleadingIndentation : DiagGroup<"misleading-indentation">; +def MultilibFallback : DiagGroup<"multilib-fallback">; // This covers both the deprecated case (in C++98) // and the extension case (in C++11 onwards). diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.h b/clang/lib/Driver/ToolChains/Arch/RISCV.h --- a/clang/lib/Driver/ToolChains/Arch/RISCV.h +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.h @@ -26,6 +26,7 @@ const llvm::Triple &Triple); StringRef getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); +StringRef getRISCVCodeModel(const llvm::opt::ArgList &Args); } // end namespace riscv } // namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -735,3 +735,14 @@ return "rv64imafdc"; } } + +StringRef riscv::getRISCVCodeModel(const llvm::opt::ArgList &Args) { + // Default code model is 'small' (what GCC calls 'medlow'). + StringRef CodeModel; + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + CodeModel = A->getValue(); + else + CodeModel = "small"; + + return CodeModel; +} diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -215,6 +215,9 @@ // Gentoo-specific toolchain configurations are stored here. const std::string GentooConfigDir = "/etc/env.d/gcc"; + /// Verbose message during detect multilib + std::string MultilibVerboseMessages; + public: explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -25,6 +25,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/VirtualFileSystem.h" #include @@ -1585,10 +1586,198 @@ return false; } +static std::string findGCCPath(const Driver &D, llvm::StringRef BasePath) { + SmallString<128> GCCPath; + llvm::sys::path::append(GCCPath, BasePath, "bin", + D.getTargetTriple() + "-gcc"); + + if (llvm::sys::fs::exists(GCCPath)) + return GCCPath.str().str(); + + return ""; +} + +static std::string getGCCPath(const Driver &D, const ArgList &Args) { + + // Find GCC from -gcc-toolchain if given. + if (const Arg *A = + Args.getLastArg(clang::driver::options::OPT_gcc_toolchain)) { + return findGCCPath(D, A->getValue()); + } else { + // Try to find GCC from GCC_INSTALL_PREFIX if define. + llvm::StringRef GCCInstallPrefix = GCC_INSTALL_PREFIX; + std::string GCCPath; + if (!GCCInstallPrefix.empty()) + GCCPath = findGCCPath(D, GCCInstallPrefix); + else { + // Try to find GCC from the same folder as driver. + SmallString<128> GCCBasePath; + llvm::sys::path::append(GCCBasePath, D.Dir, ".."); + GCCPath = findGCCPath(D, GCCBasePath); + } + return GCCPath; + } +} + +static bool scanRISCVGCCMultilibConfig(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + StringRef MultilibOutput, + DetectedMultilibs &Result, + std::string &MultilibVerboseMessages) { + bool Verbose = Args.hasArg(options::OPT_v); + llvm::StringSet<> AllABI; + llvm::StringSet<> AllArch; + llvm::StringSet<> AllMCmodel; + Multilib::flags_list Flags; + + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + + // Get current ABI, Arch, and code model. + StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); + StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple); + StringRef CodeModel = tools::riscv::getRISCVCodeModel(Args); + + // Turns it into option style, to make it able to compare + // to multi-lib option list. + std::string CurrentABIOpt = Twine("mabi=", ABIName).str(); + std::string CurrentArchOpt = Twine("march=", MArch).str(); + std::string CurrentMCmodelOpt = llvm::StringSwitch(CodeModel) + .Case("medium", "mcmodel=medany") + .Default("mcmodel=medlow"); + + llvm::ErrorOr> File = + D.getVFS().getBufferForFile(MultilibOutput); + std::vector Ms; + + if (!File) { + // Ooops, some thing wrong during open file, let's fallback. + if (Verbose) + MultilibVerboseMessages += "Failed to read file in an attempt to obtain " + "the multilib configuration from GCC\n"; + return false; + } + + SmallVector Lines; + File.get()->getBuffer().split(Lines, "\n"); + for (StringRef Line : Lines) { + Line = Line.trim(); + + if (Line.empty()) + continue; + // Format for multi-lib: + // ;@opt1@opt2 + // For example: + // rv32ec/ilp32e;@march=rv32ec@mabi=ilp32e + // -march=rv32ec and -mabi=ilp32e using rv32ec/ilp32e. + auto MultilibInfo = Line.split(';'); + StringRef Path = MultilibInfo.first; + + // Skip default multi-lib path. + // Clang has implied a default multi-lib rule there, + // so we don't need to add it manually. + if (Path == ".") + continue; + + StringRef Options = MultilibInfo.second.substr(1); + SmallVector OptionList; + Options.split(OptionList, '@'); + // multilib path rule is ${march}/${mabi} + auto Multilib = makeMultilib(Path); + for (StringRef Option : OptionList) { + Multilib.flag(Twine("+", Option).str()); + + // Gather all used option from multi-lib config. + if (Option.startswith("march=")) { + if (!AllArch.contains(Option)) { + // Make sure every option we only process once + AllArch.insert(Option); + addMultilibFlag(CurrentArchOpt == Option, Option.str().c_str(), + Flags); + } + } else if (Option.startswith("mabi=")) { + if (!AllABI.contains(Option)) { + AllABI.insert(Option); + addMultilibFlag(CurrentABIOpt == Option, Option.str().c_str(), Flags); + } + } else if (Option.startswith("mcmodel=")) { + if (!AllMCmodel.contains(Option)) { + AllMCmodel.insert(Option); + addMultilibFlag(CurrentMCmodelOpt == Option, Option.str().c_str(), + Flags); + } + } else { + // Got unrecognized option in multi-lib config, fallback. + D.Diag(diag::warn_drv_multilib_fallback) << Option; + return false; + } + } + Ms.emplace_back(Multilib); + } + + MultilibSet RISCVMultilibs = + MultilibSet().FilterOut(NonExistent).Either(ArrayRef(Ms)); + + RISCVMultilibs.select(Flags, Result.SelectedMultilib); + + Result.Multilibs = RISCVMultilibs; + + return true; +} + +static bool getRISCVMultilibFromGCC(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + DetectedMultilibs &Result, + std::string &MultilibVerboseMessages) { + bool Verbose = Args.hasArg(options::OPT_v); + // Try to find where is GCC. + std::string GCCPath = getGCCPath(D, Args); + + // Not found? fallback to built-in multi-lib. + if (GCCPath.empty()) { + if (Verbose) + MultilibVerboseMessages += "Failed to find GCC in an attempt to obtain " + "the multilib configuration\n"; + return false; + } + + if (Verbose) + MultilibVerboseMessages += + "Attempt to obtain the multilib configuration from '" + GCCPath + "'\n"; + + // Ask GCC's multi-lib config via --print-multi-lib. + StringRef GCCArgs[] = {{GCCPath}, {"--print-multi-lib"}}; + std::string MultilibOutput = D.GetTemporaryPath("gcc-output-", ""); + Optional Redirects[] = {None, {MultilibOutput}, {""}}; + + int RC = llvm::sys::ExecuteAndWait(GCCPath, GCCArgs, None, Redirects); + + // Any failed happen? let fallback to built-in multi-lib. + if (RC != 0) { + if (Verbose) + MultilibVerboseMessages += + "Failed to execute '" + GCCPath + + "' in an attempt to obtain the multilib configuration from GCC\n"; + return false; + } + + // Parsing output of --print-multi-lib, and use that info to determine + // which multi-lib should be used. + return scanRISCVGCCMultilibConfig(D, TargetTriple, Path, Args, MultilibOutput, + Result, MultilibVerboseMessages); +} + static void findRISCVBareMetalMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, - DetectedMultilibs &Result) { + DetectedMultilibs &Result, + std::string &MultilibVerboseMessages) { + // Try to get multilib from GCC first. + if (getRISCVMultilibFromGCC(D, TargetTriple, Path, Args, Result, + MultilibVerboseMessages)) + return; + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); struct RiscvMultilib { StringRef march; @@ -1641,9 +1830,11 @@ static void findRISCVMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, - const ArgList &Args, DetectedMultilibs &Result) { + const ArgList &Args, DetectedMultilibs &Result, + std::string &MultilibVerboseMessages) { if (TargetTriple.getOS() == llvm::Triple::UnknownOS) - return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result); + return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result, + MultilibVerboseMessages); FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32"); @@ -2000,6 +2191,9 @@ if (!GCCInstallPath.empty()) OS << "Selected GCC installation: " << GCCInstallPath << "\n"; + if (!MultilibVerboseMessages.empty()) + OS << MultilibVerboseMessages; + for (const auto &Multilib : Multilibs) OS << "Candidate multilib: " << Multilib << "\n"; @@ -2482,7 +2676,8 @@ if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) return false; } else if (TargetTriple.isRISCV()) { - findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); + findRISCVMultilibs(D, TargetTriple, Path, Args, Detected, + MultilibVerboseMessages); } else if (isMSP430(TargetArch)) { findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); } else if (TargetArch == llvm::Triple::avr) { diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/bin/riscv32-unknown-elf-gcc b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/bin/riscv32-unknown-elf-gcc new file mode 100755 --- /dev/null +++ b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/bin/riscv32-unknown-elf-gcc @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +print("rv32iac/ilp32;@march=rv32iac@mabi=ilp32") +print("rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f") +print("rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d") diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/crtend.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32iac/ilp32/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32iac/ilp32/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32iac/ilp32/crtend.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32iac/ilp32/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32imafc/ilp32f/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32imafc/ilp32f/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32imafc/ilp32f/crtend.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv32imafc/ilp32f/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv64imafdc/lp64d/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv64imafdc/lp64d/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv64imafdc/lp64d/crtend.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/lib/gcc/riscv32-unknown-elf/8.2.0/rv64imafdc/lp64d/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/crt0.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv32iac/ilp32/crt0.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv32iac/ilp32/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv32imafc/ilp32f/crt0.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv32imafc/ilp32f/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv64imac/lp64/crt0.o b/clang/test/Driver/Inputs/multilib_riscv32_elf_sdk/riscv32-unknown-elf/lib/rv64imac/lp64/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/bin/riscv64-unknown-elf-gcc b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/bin/riscv64-unknown-elf-gcc new file mode 100755 --- /dev/null +++ b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/bin/riscv64-unknown-elf-gcc @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +print("rv32iac/ilp32;@march=rv32iac@mabi=ilp32") +print("rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f") +print("rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d") diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/crtend.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32iac/ilp32/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32iac/ilp32/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32iac/ilp32/crtend.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32iac/ilp32/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32imafc/ilp32f/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32imafc/ilp32f/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32imafc/ilp32f/crtend.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32imafc/ilp32f/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv64imafdc/lp64d/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv64imafdc/lp64d/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv64imafdc/lp64d/crtend.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv64imafdc/lp64d/crtend.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv32iac/ilp32/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv32iac/ilp32/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv32imafc/ilp32f/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv32imafc/ilp32f/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv64imac/lp64/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk/riscv64-unknown-elf/lib/rv64imac/lp64/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/bin/riscv64-unknown-elf-gcc b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/bin/riscv64-unknown-elf-gcc new file mode 100755 --- /dev/null +++ b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/bin/riscv64-unknown-elf-gcc @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +print("rv32iac/ilp32;@march=rv32iac@mabi=ilp32") +print("rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f") +print("rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d@xxx") diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/riscv64-unknown-elf/lib/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad/riscv64-unknown-elf/lib/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/bin/riscv64-unknown-elf-gcc b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/bin/riscv64-unknown-elf-gcc new file mode 100755 --- /dev/null +++ b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/bin/riscv64-unknown-elf-gcc @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 +import sys + +sys.exit(1) diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/riscv64-unknown-elf/lib/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad2/riscv64-unknown-elf/lib/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad3/bin/.keep b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad3/bin/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad3/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad3/lib/gcc/riscv64-unknown-elf/8.2.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad3/riscv64-unknown-elf/lib/crt0.o b/clang/test/Driver/Inputs/multilib_riscv64_elf_sdk_bad3/riscv64-unknown-elf/lib/crt0.o new file mode 100644 diff --git a/clang/test/Driver/riscv-toolchain-gcc-multilib.c b/clang/test/Driver/riscv-toolchain-gcc-multilib.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/riscv-toolchain-gcc-multilib.c @@ -0,0 +1,64 @@ +// Test case for scanning input of GCC output as multilib config +// Skip this test on Windows, we can't create a dummy GCC to output +// multilib config, ExecuteAndWait only execute *.exe file. +// UNSUPPORTED: system-windows + +// RUN: %clang %s \ +// RUN: -target riscv32-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv32_elf_sdk \ +// RUN: --print-multi-lib \ +// RUN: | FileCheck -check-prefix=C-RV32-GCC-MULTI-LIB %s +// C-RV32-GCC-MULTI-LIB: rv32iac/ilp32;@march=rv32iac@mabi=ilp32 +// C-RV32-GCC-MULTI-LIB-NEXT: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f +// C-RV32-GCC-MULTI-LIB-NEXT: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d +// C-RV32-GCC-MULTI-LIB-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -### -v \ +// RUN: -target riscv32-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv32_elf_sdk 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32-GCC-MULTI-LIB-V %s +// C-RV32-GCC-MULTI-LIB-V: Candidate multilib: rv32iac/ilp32;@march=rv32iac@mabi=ilp32 +// C-RV32-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f +// C-RV32-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk \ +// RUN: --print-multi-lib \ +// RUN: | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB %s +// C-RV64-GCC-MULTI-LIB: rv32iac/ilp32;@march=rv32iac@mabi=ilp32 +// C-RV64-GCC-MULTI-LIB-NEXT: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f +// C-RV64-GCC-MULTI-LIB-NEXT: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d +// C-RV64-GCC-MULTI-LIB-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -### -v \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB-V %s +// C-RV64-GCC-MULTI-LIB-V: Candidate multilib: rv32iac/ilp32;@march=rv32iac@mabi=ilp32 +// C-RV64-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv32imafc/ilp32f;@march=rv32iac@mabi=ilp32f +// C-RV64-GCC-MULTI-LIB-V-NEXT: Candidate multilib: rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk_bad \ +// RUN: --print-multi-lib 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB-BAD %s +// C-RV64-GCC-MULTI-LIB-BAD: warning: xxx option unrecognized in multi-lib configuration when parsing config from GCC, falling back to built-in multi-lib configuration. [-Wmultilib-fallback] + +// RUN: %clang %s \ +// RUN: -### -v \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk_bad2 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64-GCC-MULTI-LIB-BAD-V %s +// C-RV64-GCC-MULTI-LIB-BAD-V: Attempt to obtain the multilib configuration from '{{.*}}gcc{{(.exe)?}}' +// C-RV64-GCC-MULTI-LIB-BAD-V-NEXT: Failed to execute '{{.*}}gcc{{(.exe)?}}' in an attempt to obtain the multilib configuration from GCC + +// RUN: %clang %s \ +// RUN: -### -v \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv64_elf_sdk_bad3 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64-GCC-NOT-FOUND %s +// C-RV64-GCC-NOT-FOUND: Failed to find GCC in an attempt to obtain the multilib configuration