diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Driver/ToolChains/Gnu.cpp | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) |
Diffstat (limited to 'lib/Driver/ToolChains/Gnu.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Gnu.cpp | 199 |
1 files changed, 146 insertions, 53 deletions
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index 3755673250b2d..2ad45097dce8c 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -16,7 +16,6 @@ #include "Arch/SystemZ.h" #include "CommonArgs.h" #include "Linux.h" -#include "clang/Basic/VirtualFileSystem.h" #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" @@ -27,6 +26,7 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/Path.h" #include "llvm/Support/TargetParser.h" +#include "llvm/Support/VirtualFileSystem.h" #include <system_error> using namespace clang::driver; @@ -228,6 +228,30 @@ void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA, // The types are (hopefully) good enough. } +// On Arm the endianness of the output file is determined by the target and +// can be overridden by the pseudo-target flags '-mlittle-endian'/'-EL' and +// '-mbig-endian'/'-EB'. Unlike other targets the flag does not result in a +// normalized triple so we must handle the flag here. +static bool isArmBigEndian(const llvm::Triple &Triple, + const ArgList &Args) { + bool IsBigEndian = false; + switch (Triple.getArch()) { + case llvm::Triple::armeb: + case llvm::Triple::thumbeb: + IsBigEndian = true; + LLVM_FALLTHROUGH; + case llvm::Triple::arm: + case llvm::Triple::thumb: + if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, + options::OPT_mbig_endian)) + IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); + break; + default: + break; + } + return IsBigEndian; +} + static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { switch (T.getArch()) { case llvm::Triple::x86: @@ -237,13 +261,12 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { case llvm::Triple::aarch64: return "aarch64linux"; case llvm::Triple::aarch64_be: - return "aarch64_be_linux"; + return "aarch64linuxb"; case llvm::Triple::arm: case llvm::Triple::thumb: - return "armelf_linux_eabi"; case llvm::Triple::armeb: case llvm::Triple::thumbeb: - return "armelfb_linux_eabi"; + return isArmBigEndian(T, Args) ? "armelfb_linux_eabi" : "armelf_linux_eabi"; case llvm::Triple::ppc: return "elf32ppclinux"; case llvm::Triple::ppc64: @@ -264,11 +287,13 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { case llvm::Triple::mipsel: return "elf32ltsmip"; case llvm::Triple::mips64: - if (tools::mips::hasMipsAbiArg(Args, "n32")) + if (tools::mips::hasMipsAbiArg(Args, "n32") || + T.getEnvironment() == llvm::Triple::GNUABIN32) return "elf32btsmipn32"; return "elf64btsmip"; case llvm::Triple::mips64el: - if (tools::mips::hasMipsAbiArg(Args, "n32")) + if (tools::mips::hasMipsAbiArg(Args, "n32") || + T.getEnvironment() == llvm::Triple::GNUABIN32) return "elf32ltsmipn32"; return "elf64ltsmip"; case llvm::Triple::systemz: @@ -323,14 +348,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // handled somewhere else. Args.ClaimAllArgs(options::OPT_w); - const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - if (llvm::sys::path::stem(Exec) == "lld") { - CmdArgs.push_back("-flavor"); - CmdArgs.push_back("old-gnu"); - CmdArgs.push_back("-target"); - CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString())); - } - if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); @@ -343,8 +360,13 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_s)) CmdArgs.push_back("-s"); - if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb) - arm::appendEBLinkFlags(Args, CmdArgs, Triple); + if (Triple.isARM() || Triple.isThumb() || Triple.isAArch64()) { + bool IsBigEndian = isArmBigEndian(Triple, Args); + if (IsBigEndian) + arm::appendBE8LinkFlag(Args, CmdArgs, Triple); + IsBigEndian = IsBigEndian || Arch == llvm::Triple::aarch64_be; + CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL"); + } // Most Android ARM64 targets should enable the linker fix for erratum // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. @@ -539,6 +561,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddHIPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA, *this); + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); } @@ -645,6 +668,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, case llvm::Triple::thumb: case llvm::Triple::thumbeb: { const llvm::Triple &Triple2 = getToolChain().getTriple(); + CmdArgs.push_back(isArmBigEndian(Triple2, Args) ? "-EB" : "-EL"); switch (Triple2.getSubArch()) { case llvm::Triple::ARMSubArch_v7: CmdArgs.push_back("-mfpu=neon"); @@ -677,6 +701,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, } case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: { + CmdArgs.push_back( + getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL"); Args.AddLastArg(CmdArgs, options::OPT_march_EQ); normalizeCPUNamesForAssembler(Args, CmdArgs); @@ -791,17 +817,17 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, if (Args.hasArg(options::OPT_gsplit_dwarf) && getToolChain().getTriple().isOSLinux()) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Inputs[0])); + SplitDebugName(Args, Output)); } namespace { // Filter to remove Multilibs that don't exist as a suffix to Path class FilterNonExistent { StringRef Base, File; - vfs::FileSystem &VFS; + llvm::vfs::FileSystem &VFS; public: - FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS) + FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS) : Base(Base), File(File), VFS(VFS) {} bool operator()(const Multilib &M) { return !VFS.exists(Base + M.gccSuffix() + File); @@ -852,6 +878,10 @@ static bool isRISCV(llvm::Triple::ArchType Arch) { return Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; } +static bool isMSP430(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::msp430; +} + static Multilib makeMultilib(StringRef commonSuffix) { return Multilib(commonSuffix, commonSuffix, commonSuffix); } @@ -947,7 +977,7 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags, return false; } -static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path, +static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path, const Multilib::flags_list &Flags, FilterNonExistent &NonExistent, DetectedMultilibs &Result) { @@ -1397,6 +1427,26 @@ static void findAndroidArmMultilibs(const Driver &D, Result.Multilibs = AndroidArmMultilibs; } +static bool findMSP430Multilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + DetectedMultilibs &Result) { + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + Multilib MSP430Multilib = makeMultilib("/430"); + // FIXME: when clang starts to support msp430x ISA additional logic + // to select between multilib must be implemented + // Multilib MSP430xMultilib = makeMultilib("/large"); + + Result.Multilibs.push_back(MSP430Multilib); + Result.Multilibs.FilterOut(NonExistent); + + Multilib::flags_list Flags; + if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) + return true; + + return false; +} + static void findRISCVMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result) { @@ -1625,10 +1675,18 @@ Generic_GCC::GCCVersion Generic_GCC::GCCVersion::Parse(StringRef VersionText) { return GoodVersion; } -static llvm::StringRef getGCCToolchainDir(const ArgList &Args) { +static llvm::StringRef getGCCToolchainDir(const ArgList &Args, + llvm::StringRef SysRoot) { const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain); if (A) return A->getValue(); + + // If we have a SysRoot, ignore GCC_INSTALL_PREFIX. + // GCC_INSTALL_PREFIX specifies the gcc installation for the default + // sysroot and is likely not valid with a different sysroot. + if (!SysRoot.empty()) + return ""; + return GCC_INSTALL_PREFIX; } @@ -1660,7 +1718,7 @@ void Generic_GCC::GCCInstallationDetector::init( SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(), D.PrefixDirs.end()); - StringRef GCCToolchainDir = getGCCToolchainDir(Args); + StringRef GCCToolchainDir = getGCCToolchainDir(Args, D.SysRoot); if (GCCToolchainDir != "") { if (GCCToolchainDir.back() == '/') GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / @@ -1769,9 +1827,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( std::string PrefixDir = SysRoot.str() + "/usr/gcc"; std::error_code EC; - for (vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC), LE; + for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC), + LE; !EC && LI != LE; LI = LI.increment(EC)) { - StringRef VersionText = llvm::sys::path::filename(LI->getName()); + StringRef VersionText = llvm::sys::path::filename(LI->path()); GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); // Filter out obviously bad entries. @@ -1812,19 +1871,21 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", - "aarch64-suse-linux"}; + "aarch64-suse-linux", "aarch64-linux-android"}; static const char *const AArch64beLibDirs[] = {"/lib"}; static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu"}; static const char *const ARMLibDirs[] = {"/lib"}; - static const char *const ARMTriples[] = {"arm-linux-gnueabi"}; + static const char *const ARMTriples[] = {"arm-linux-gnueabi", + "arm-linux-androideabi"}; static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi"}; static const char *const ARMebLibDirs[] = {"/lib"}; - static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"}; + static const char *const ARMebTriples[] = {"armeb-linux-gnueabi", + "armeb-linux-androideabi"}; static const char *const ARMebHFTriples[] = { "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"}; @@ -1835,32 +1896,47 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "x86_64-redhat-linux", "x86_64-suse-linux", "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", "x86_64-unknown-linux", - "x86_64-amazon-linux"}; + "x86_64-amazon-linux", "x86_64-linux-android"}; static const char *const X32LibDirs[] = {"/libx32"}; static const char *const X86LibDirs[] = {"/lib32", "/lib"}; static const char *const X86Triples[] = { "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux", - "i486-slackware-linux", "i686-montavista-linux", "i586-linux-gnu"}; + "i486-slackware-linux", "i686-montavista-linux", "i586-linux-gnu", + "i686-linux-android", "i386-gnu", "i486-gnu", + "i586-gnu", "i686-gnu"}; static const char *const MIPSLibDirs[] = {"/lib"}; - static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux", - "mips-mti-linux-gnu", - "mips-img-linux-gnu"}; + static const char *const MIPSTriples[] = { + "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu", + "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"}; static const char *const MIPSELLibDirs[] = {"/lib"}; - static const char *const MIPSELTriples[] = {"mipsel-linux-gnu", - "mips-img-linux-gnu"}; + static const char *const MIPSELTriples[] = { + "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu", + "mipsel-linux-android"}; static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; static const char *const MIPS64Triples[] = { - "mips64-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu", - "mips64-linux-gnuabi64"}; + "mips64-linux-gnu", "mips-mti-linux-gnu", + "mips-img-linux-gnu", "mips64-linux-gnuabi64", + "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"}; static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"}; static const char *const MIPS64ELTriples[] = { - "mips64el-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu", - "mips64el-linux-gnuabi64"}; + "mips64el-linux-gnu", "mips-mti-linux-gnu", + "mips-img-linux-gnu", "mips64el-linux-gnuabi64", + "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64", + "mips64el-linux-android"}; + + static const char *const MIPSN32LibDirs[] = {"/lib32"}; + static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32", + "mipsisa64r6-linux-gnuabin32"}; + static const char *const MIPSN32ELLibDirs[] = {"/lib32"}; + static const char *const MIPSN32ELTriples[] = { + "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"}; + static const char *const MSP430LibDirs[] = {"/lib"}; + static const char *const MSP430Triples[] = {"msp430-elf"}; static const char *const PPCLibDirs[] = {"/lib32", "/lib"}; static const char *const PPCTriples[] = { @@ -2057,6 +2133,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); + BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs)); + BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples)); break; case llvm::Triple::mipsel: LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); @@ -2064,20 +2142,30 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); + BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs)); + BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); break; case llvm::Triple::mips64: LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); + BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs)); + BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples)); break; case llvm::Triple::mips64el: LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); + BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs)); + BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); break; + case llvm::Triple::msp430: + LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs)); + TripleAliases.append(begin(MSP430Triples), end(MSP430Triples)); + break; case llvm::Triple::ppc: LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); TripleAliases.append(begin(PPCTriples), end(PPCTriples)); @@ -2149,6 +2237,8 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( return false; } else if (isRISCV(TargetArch)) { findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); + } else if (isMSP430(TargetArch)) { + findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args, NeedsBiarchSuffix, Detected)) { return false; @@ -2204,6 +2294,9 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( // triple. {"i386-linux-gnu/gcc/" + CandidateTriple.str(), "../../..", (TargetArch == llvm::Triple::x86 && + TargetTriple.getOS() != llvm::Triple::Solaris)}, + {"i386-gnu/gcc/" + CandidateTriple.str(), "../../..", + (TargetArch == llvm::Triple::x86 && TargetTriple.getOS() != llvm::Triple::Solaris)}}; for (auto &Suffix : Suffixes) { @@ -2212,21 +2305,21 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( StringRef LibSuffix = Suffix.LibSuffix; std::error_code EC; - for (vfs::directory_iterator + for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC), LE; !EC && LI != LE; LI = LI.increment(EC)) { - StringRef VersionText = llvm::sys::path::filename(LI->getName()); + StringRef VersionText = llvm::sys::path::filename(LI->path()); GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); if (CandidateVersion.Major != -1) // Filter obviously bad entries. - if (!CandidateGCCInstallPaths.insert(LI->getName()).second) + if (!CandidateGCCInstallPaths.insert(LI->path()).second) continue; // Saw this path before; no need to look at it again. if (CandidateVersion.isOlderThan(4, 1, 1)) continue; if (CandidateVersion <= Version) continue; - if (!ScanGCCForMultilibs(TargetTriple, Args, LI->getName(), + if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(), NeedsBiarchSuffix)) continue; @@ -2375,7 +2468,7 @@ bool Generic_GCC::isPICDefault() const { case llvm::Triple::x86_64: return getTriple().isOSWindows(); case llvm::Triple::ppc64: - case llvm::Triple::ppc64le: + // Big endian PPC is PIC by default return !getTriple().isOSBinFormatMachO() && !getTriple().isMacOSX(); case llvm::Triple::mips64: case llvm::Triple::mips64el: @@ -2412,16 +2505,14 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const { case llvm::Triple::systemz: case llvm::Triple::mips: case llvm::Triple::mipsel: - return true; case llvm::Triple::mips64: case llvm::Triple::mips64el: - // Enabled for Debian, Android, FreeBSD and OpenBSD mips64/mipsel, as they - // can precisely identify the ABI in use (Debian) or only use N64 for MIPS64 - // (Android). Other targets are unable to distinguish N32 from N64. - if (getTriple().getEnvironment() == llvm::Triple::GNUABI64 || - getTriple().isAndroid() || - getTriple().isOSFreeBSD() || - getTriple().isOSOpenBSD()) + case llvm::Triple::msp430: + return true; + case llvm::Triple::sparc: + case llvm::Triple::sparcel: + case llvm::Triple::sparcv9: + if (getTriple().isOSSolaris() || getTriple().isOSOpenBSD()) return true; return false; default: @@ -2546,7 +2637,7 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, bool UseInitArrayDefault = getTriple().getArch() == llvm::Triple::aarch64 || getTriple().getArch() == llvm::Triple::aarch64_be || - (getTriple().getOS() == llvm::Triple::FreeBSD && + (getTriple().isOSFreeBSD() && getTriple().getOSMajorVersion() >= 12) || (getTriple().getOS() == llvm::Triple::Linux && ((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) || @@ -2554,7 +2645,9 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, getTriple().getOS() == llvm::Triple::NaCl || (getTriple().getVendor() == llvm::Triple::MipsTechnologies && !getTriple().hasEnvironment()) || - getTriple().getOS() == llvm::Triple::Solaris; + getTriple().getOS() == llvm::Triple::Solaris || + getTriple().getArch() == llvm::Triple::riscv32 || + getTriple().getArch() == llvm::Triple::riscv64; if (DriverArgs.hasFlag(options::OPT_fuse_init_array, options::OPT_fno_use_init_array, UseInitArrayDefault)) |