aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r--lib/Driver/Tools.cpp276
1 files changed, 188 insertions, 88 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 8c11992f1f82..19ebbb91ffc7 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -502,11 +502,46 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) {
}
}
+// ARM tools start.
+
+// Get SubArch (vN).
+static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
+ llvm::StringRef Arch = Triple.getArchName();
+ return llvm::ARMTargetParser::parseArchVersion(Arch);
+}
+
+// True if M-profile.
+static bool isARMMProfile(const llvm::Triple &Triple) {
+ llvm::StringRef Arch = Triple.getArchName();
+ unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch);
+ return Profile == llvm::ARM::PK_M;
+}
+
+// Get Arch/CPU from args.
+static void getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
+ llvm::StringRef &CPU, bool FromAs = false) {
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ CPU = A->getValue();
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+ Arch = A->getValue();
+ if (!FromAs)
+ return;
+
+ for (const Arg *A :
+ Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
+ StringRef Value = A->getValue();
+ if (Value.startswith("-mcpu="))
+ CPU = Value.substr(6);
+ if (Value.startswith("-march="))
+ Arch = Value.substr(7);
+ }
+}
+
// Handle -mhwdiv=.
+// FIXME: Use ARMTargetParser.
static void getARMHWDivFeatures(const Driver &D, const Arg *A,
- const ArgList &Args,
+ const ArgList &Args, StringRef HWDiv,
std::vector<const char *> &Features) {
- StringRef HWDiv = A->getValue();
if (HWDiv == "arm") {
Features.push_back("+hwdiv-arm");
Features.push_back("-hwdiv");
@@ -525,23 +560,32 @@ static void getARMHWDivFeatures(const Driver &D, const Arg *A,
// Handle -mfpu=.
static void getARMFPUFeatures(const Driver &D, const Arg *A,
- const ArgList &Args,
+ const ArgList &Args, StringRef FPU,
std::vector<const char *> &Features) {
- StringRef FPU = A->getValue();
unsigned FPUID = llvm::ARMTargetParser::parseFPU(FPU);
if (!llvm::ARMTargetParser::getFPUFeatures(FPUID, Features))
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
-static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
- llvm::StringRef Arch = Triple.getArchName();
- return llvm::ARMTargetParser::parseArchVersion(Arch);
+// Check if -march is valid by checking if it can be canonicalised and parsed.
+// getARMArch is used here instead of just checking the -march value in order
+// to handle -march=native correctly.
+static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
+ llvm::StringRef ArchName,
+ const llvm::Triple &Triple) {
+ std::string MArch = arm::getARMArch(ArchName, Triple);
+ if (llvm::ARMTargetParser::parseArch(MArch) == llvm::ARM::AK_INVALID)
+ D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
-static bool isARMMProfile(const llvm::Triple &Triple) {
- llvm::StringRef Arch = Triple.getArchName();
- unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch);
- return Profile == llvm::ARM::PK_M;
+// Check -mcpu=. Needs ArchName to handle -mcpu=generic.
+static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
+ llvm::StringRef CPUName, llvm::StringRef ArchName,
+ const llvm::Triple &Triple) {
+ std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
+ std::string Arch = arm::getARMArch(ArchName, Triple);
+ if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0)
+ D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
// Select the float ABI as determined by -msoft-float, -mhard-float, and
@@ -641,6 +685,9 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
bool KernelOrKext =
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
+ const Arg *WaCPU = nullptr, *WaFPU = nullptr;
+ const Arg *WaHDiv = nullptr, *WaArch = nullptr;
+
if (!ForAS) {
// FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
// yet (it uses the -mfloat-abi and -msoft-float options), and it is
@@ -661,31 +708,75 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
// Use software floating point argument passing?
if (FloatABI != "hard")
Features.push_back("+soft-float-abi");
+ } else {
+ // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
+ // to the assembler correctly.
+ for (const Arg *A :
+ Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
+ StringRef Value = A->getValue();
+ if (Value.startswith("-mfpu=")) {
+ WaFPU = A;
+ } else if (Value.startswith("-mcpu=")) {
+ WaCPU = A;
+ } else if (Value.startswith("-mhwdiv=")) {
+ WaHDiv = A;
+ } else if (Value.startswith("-march=")) {
+ WaArch = A;
+ }
+ }
}
- // Honor -mfpu=.
- if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
- getARMFPUFeatures(D, A, Args, Features);
- if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
- getARMHWDivFeatures(D, A, Args, Features);
-
- // Check if -march is valid by checking if it can be canonicalised and parsed.
- // getARMArch is used here instead of just checking the -march value in order
- // to handle -march=native correctly.
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- std::string Arch = arm::getARMArch(Args, Triple);
- if (llvm::ARMTargetParser::parseArch(Arch) == llvm::ARM::AK_INVALID)
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
- }
-
- // We do a similar thing with -mcpu, but here things are complicated because
- // the only function we have to check if a cpu is valid is
- // getLLVMArchSuffixForARM which also needs an architecture.
- if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- std::string CPU = arm::getARMTargetCPU(Args, Triple);
- std::string Arch = arm::getARMArch(Args, Triple);
- if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0)
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+ // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
+ const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
+ if (WaFPU) {
+ if (FPUArg)
+ D.Diag(clang::diag::warn_drv_unused_argument)
+ << FPUArg->getAsString(Args);
+ getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6),
+ Features);
+ } else if (FPUArg) {
+ getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
+ }
+
+ // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
+ const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
+ if (WaHDiv) {
+ if (HDivArg)
+ D.Diag(clang::diag::warn_drv_unused_argument)
+ << HDivArg->getAsString(Args);
+ getARMHWDivFeatures(D, WaHDiv, Args,
+ StringRef(WaHDiv->getValue()).substr(8), Features);
+ } else if (HDivArg)
+ getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
+
+ // Check -march. ClangAs gives preference to -Wa,-march=.
+ const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
+ StringRef ArchName;
+ if (WaArch) {
+ if (ArchArg)
+ D.Diag(clang::diag::warn_drv_unused_argument)
+ << ArchArg->getAsString(Args);
+ ArchName = StringRef(WaArch->getValue()).substr(7);
+ checkARMArchName(D, WaArch, Args, ArchName, Triple);
+ // FIXME: Set Arch.
+ D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
+ } else if (ArchArg) {
+ ArchName = ArchArg->getValue();
+ checkARMArchName(D, ArchArg, Args, ArchName, Triple);
+ }
+
+ // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
+ const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
+ StringRef CPUName;
+ if (WaCPU) {
+ if (CPUArg)
+ D.Diag(clang::diag::warn_drv_unused_argument)
+ << CPUArg->getAsString(Args);
+ CPUName = StringRef(WaCPU->getValue()).substr(6);
+ checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Triple);
+ } else if (CPUArg) {
+ CPUName = CPUArg->getValue();
+ checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Triple);
}
// Setting -msoft-float effectively disables NEON because of the GCC
@@ -836,6 +927,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs,
CmdArgs.push_back("-arm-reserve-r9");
}
}
+// ARM tools end.
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
/// targeting.
@@ -1463,7 +1555,8 @@ static const char *getX86TargetCPU(const ArgList &Args,
}
}
-static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) {
+static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
+ bool FromAs = false) {
switch (T.getArch()) {
default:
return "";
@@ -1475,9 +1568,11 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) {
case llvm::Triple::arm:
case llvm::Triple::armeb:
case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- return arm::getARMTargetCPU(Args, T);
-
+ case llvm::Triple::thumbeb: {
+ StringRef MArch, MCPU;
+ getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
+ return arm::getARMTargetCPU(MCPU, MArch, T);
+ }
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -2198,12 +2293,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
A->claim();
- for (const StringRef Value : A->getValues()) {
- if (TakeNextArg) {
- CmdArgs.push_back(Value.data());
- TakeNextArg = false;
- continue;
- }
+ for (const StringRef Value : A->getValues()) {
+ if (TakeNextArg) {
+ CmdArgs.push_back(Value.data());
+ TakeNextArg = false;
+ continue;
+ }
if (Value == "-force_cpusubtype_ALL") {
// Do nothing, this is the default and we don't support anything else.
@@ -2227,6 +2322,9 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
TakeNextArg = true;
} else if (Value.startswith("-gdwarf-")) {
CmdArgs.push_back(Value.data());
+ } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
+ Value.startswith("-mhwdiv") || Value.startswith("-march")) {
+ // Do nothing, we'll validate it later.
} else {
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Value;
@@ -2243,8 +2341,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
// Until ARM libraries are build separately, we have them all in one library
static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) {
- if (TC.getTriple().isOSWindows() &&
- !TC.getTriple().isWindowsItaniumEnvironment() &&
+ if (TC.getTriple().isWindowsMSVCEnvironment() &&
TC.getArch() == llvm::Triple::x86)
return "i386";
if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
@@ -2270,10 +2367,12 @@ SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component,
: "";
bool IsOSWindows = TC.getTriple().isOSWindows();
+ bool IsITANMSVCWindows = TC.getTriple().isWindowsMSVCEnvironment() ||
+ TC.getTriple().isWindowsItaniumEnvironment();
StringRef Arch = getArchNameForCompilerRTLib(TC);
- const char *Prefix = IsOSWindows ? "" : "lib";
+ const char *Prefix = IsITANMSVCWindows ? "" : "lib";
const char *Suffix =
- Shared ? (IsOSWindows ? ".dll" : ".so") : (IsOSWindows ? ".lib" : ".a");
+ Shared ? (IsOSWindows ? ".dll" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a");
SmallString<128> Path = getCompilerRTLibDir(TC);
llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
@@ -2750,8 +2849,7 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
if (ProfileGenerateArg && ProfileUseArg)
D.Diag(diag::err_drv_argument_not_allowed_with)
- << ProfileGenerateArg->getSpelling()
- << ProfileUseArg->getSpelling();
+ << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
if (ProfileGenerateArg &&
ProfileGenerateArg->getOption().matches(
@@ -2907,8 +3005,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
"Invalid action for clang tool.");
- if (JA.getType() == types::TY_LTO_IR ||
- JA.getType() == types::TY_LTO_BC) {
+ if (JA.getType() == types::TY_LTO_IR || JA.getType() == types::TY_LTO_BC) {
CmdArgs.push_back("-flto");
}
if (JA.getType() == types::TY_Nothing) {
@@ -3434,7 +3531,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
// Add the target cpu
- std::string CPU = getCPUName(Args, Triple);
+ std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
if (!CPU.empty()) {
CmdArgs.push_back("-target-cpu");
CmdArgs.push_back(Args.MakeArgString(CPU));
@@ -3952,9 +4049,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
- // AltiVec language extensions aren't relevant for assembling.
- if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
+ // AltiVec-like language extensions aren't relevant for assembling.
+ if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) {
Args.AddLastArg(CmdArgs, options::OPT_faltivec);
+ Args.AddLastArg(CmdArgs, options::OPT_fzvector);
+ }
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
@@ -3999,6 +4098,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
<< "ppc/ppc64/ppc64le";
}
+ // -fzvector is incompatible with -faltivec.
+ if (Arg *A = Args.getLastArg(options::OPT_fzvector))
+ if (Args.hasArg(options::OPT_faltivec))
+ D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
+ << "-faltivec";
+
if (getToolChain().SupportsProfiling())
Args.AddLastArg(CmdArgs, options::OPT_pg);
@@ -4234,8 +4339,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
llvm::sys::path::append(Path, "modules");
} else if (Path.empty()) {
// No module path was provided: use the default.
- llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
- Path);
+ llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
llvm::sys::path::append(Path, "org.llvm.clang.");
appendUserToPath(Path);
llvm::sys::path::append(Path, "ModuleCache");
@@ -5270,7 +5374,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
// Add the target cpu
const llvm::Triple Triple(TripleStr);
- std::string CPU = getCPUName(Args, Triple);
+ std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true);
if (!CPU.empty()) {
CmdArgs.push_back("-target-cpu");
CmdArgs.push_back(Args.MakeArgString(CPU));
@@ -5775,16 +5879,12 @@ void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
// Hexagon tools end.
-const std::string arm::getARMArch(const ArgList &Args,
- const llvm::Triple &Triple) {
+const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
std::string MArch;
- if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- // Otherwise, if we have -march= choose the base CPU for that arch.
- MArch = A->getValue();
- } else {
- // Otherwise, use the Arch from the triple.
+ if (!Arch.empty())
+ MArch = Arch;
+ else
MArch = Triple.getArchName();
- }
MArch = StringRef(MArch).lower();
// Handle -march=native.
@@ -5805,9 +5905,8 @@ const std::string arm::getARMArch(const ArgList &Args,
return MArch;
}
/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
-const char *arm::getARMCPUForMArch(const ArgList &Args,
- const llvm::Triple &Triple) {
- std::string MArch = getARMArch(Args, Triple);
+const char *arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
+ std::string MArch = getARMArch(Arch, Triple);
// getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
// here means an -march=native that we can't handle, so instead return no CPU.
if (MArch.empty())
@@ -5823,12 +5922,12 @@ const char *arm::getARMCPUForMArch(const ArgList &Args,
}
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
-std::string arm::getARMTargetCPU(const ArgList &Args,
+std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
const llvm::Triple &Triple) {
// FIXME: Warn on inconsistent use of -mcpu and -march.
// If we have -mcpu=, use that.
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- std::string MCPU = StringRef(A->getValue()).lower();
+ if (!CPU.empty()) {
+ std::string MCPU = StringRef(CPU).lower();
// Handle -mcpu=native.
if (MCPU == "native")
return llvm::sys::getHostCPUName();
@@ -5836,7 +5935,7 @@ std::string arm::getARMTargetCPU(const ArgList &Args,
return MCPU;
}
- return getARMCPUForMArch(Args, Triple);
+ return getARMCPUForMArch(Arch, Triple);
}
/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
@@ -7335,8 +7434,11 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::armeb:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb: {
- std::string MArch = arm::getARMTargetCPU(Args, getToolChain().getTriple());
- CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
+ StringRef MArch, MCPU;
+ getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
+ std::string Arch =
+ arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
+ CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
break;
}
@@ -7816,6 +7918,7 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
ArgStringList &CmdArgs, const ArgList &Args) {
bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
+ bool isCygMing = Triple.isOSCygMing();
bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
Args.hasArg(options::OPT_static);
if (!D.CCCIsCXX())
@@ -7825,10 +7928,10 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
if (D.CCCIsCXX())
CmdArgs.push_back("-lgcc");
} else {
- if (!D.CCCIsCXX())
+ if (!D.CCCIsCXX() && !isCygMing)
CmdArgs.push_back("--as-needed");
CmdArgs.push_back("-lgcc_s");
- if (!D.CCCIsCXX())
+ if (!D.CCCIsCXX() && !isCygMing)
CmdArgs.push_back("--no-as-needed");
}
@@ -7863,13 +7966,15 @@ static std::string getLinuxDynamicLinker(const ArgList &Args,
else if (Arch == llvm::Triple::aarch64_be)
return "/lib/ld-linux-aarch64_be.so.1";
else if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
- if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+ if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF ||
+ tools::arm::getARMFloatABI(ToolChain.getDriver(), Args, ToolChain.getTriple()) == "hard")
return "/lib/ld-linux-armhf.so.3";
else
return "/lib/ld-linux.so.3";
} else if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb) {
// TODO: check which dynamic linker name.
- if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+ if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF ||
+ tools::arm::getARMFloatABI(ToolChain.getDriver(), Args, ToolChain.getTriple()) == "hard")
return "/lib/ld-linux-armhf.so.3";
else
return "/lib/ld-linux.so.3";
@@ -8910,15 +9015,10 @@ void MinGW::Linker::AddLibGCC(const ArgList &Args,
if (Args.hasArg(options::OPT_mthreads))
CmdArgs.push_back("-lmingwthrd");
CmdArgs.push_back("-lmingw32");
- if (Args.hasArg(options::OPT_shared) ||
- Args.hasArg(options::OPT_shared_libgcc) ||
- !Args.hasArg(options::OPT_static_libgcc)) {
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("-lgcc");
- } else {
- CmdArgs.push_back("-lgcc");
- CmdArgs.push_back("-lgcc_eh");
- }
+
+ // Add libgcc or compiler-rt.
+ AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
+
CmdArgs.push_back("-lmoldname");
CmdArgs.push_back("-lmingwex");
CmdArgs.push_back("-lmsvcrt");