Index: tools/clang/lib/Driver/MinGWToolChain.cpp =================================================================== --- tools/clang/lib/Driver/MinGWToolChain.cpp +++ tools/clang/lib/Driver/MinGWToolChain.cpp @@ -129,18 +129,20 @@ if (DriverArgs.hasArg(options::OPT_nostdlibinc)) return; - llvm::SmallString<1024> IncludeDir(GccLibDir); - llvm::sys::path::append(IncludeDir, "include"); - addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); - IncludeDir += "-fixed"; +if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) { + llvm::SmallString<1024> IncludeDir(GccLibDir); + llvm::sys::path::append(IncludeDir, "include"); + addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); + IncludeDir += "-fixed"; #ifdef LLVM_ON_UNIX - // For openSUSE. - addSystemInclude(DriverArgs, CC1Args, - "/usr/x86_64-w64-mingw32/sys-root/mingw/include"); + // For openSUSE. + addSystemInclude(DriverArgs, CC1Args, + "/usr/x86_64-w64-mingw32/sys-root/mingw/include"); #endif - addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); - addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include"); - addSystemInclude(DriverArgs, CC1Args, Base + "include"); + addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); + addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include"); + addSystemInclude(DriverArgs, CC1Args, Base + "include"); + } } void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, @@ -149,27 +151,82 @@ DriverArgs.hasArg(options::OPT_nostdincxx)) return; - // C++ includes may be found in several locations depending on distribution. - // Windows - // ------- - // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++. - // mingw-w64 msys2: $sysroot/include/c++/4.9.2 - // mingw.org: GccLibDir/include/c++ - // - // Linux - // ----- - // openSUSE: GccLibDir/include/c++ - llvm::SmallVector, 3> CppIncludeBases; - CppIncludeBases.emplace_back(Base); - llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); - CppIncludeBases.emplace_back(Base); - llvm::sys::path::append(CppIncludeBases[1], "include", "c++", Ver); - CppIncludeBases.emplace_back(GccLibDir); - llvm::sys::path::append(CppIncludeBases[2], "include", "c++"); - for (auto &CppIncludeBase : CppIncludeBases) { - CppIncludeBase += llvm::sys::path::get_separator(); - addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); - addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); - addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: + addSystemInclude(DriverArgs, CC1Args, Base + "include" + + llvm::sys::path::get_separator() + "c++" + + llvm::sys::path::get_separator() + "v1"); + break; + + case ToolChain::CST_Libstdcxx: + // C++ includes may be found in several locations depending on distribution. + // Windows + // ------- + // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++. + // mingw-w64 msys2: $sysroot/include/c++/4.9.2 + // mingw.org: GccLibDir/include/c++ + // + // Linux + // ----- + // openSUSE: GccLibDir/include/c++ + llvm::SmallVector, 3> CppIncludeBases; + CppIncludeBases.emplace_back(Base); + llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); + CppIncludeBases.emplace_back(Base); + llvm::sys::path::append(CppIncludeBases[1], "include", "c++", Ver); + CppIncludeBases.emplace_back(GccLibDir); + llvm::sys::path::append(CppIncludeBases[2], "include", "c++"); + for (auto &CppIncludeBase : CppIncludeBases) { + CppIncludeBase += llvm::sys::path::get_separator(); + addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); + addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); + addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); + } + break; + } +} + +void MinGW::AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CmdArgs) const { + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: + CmdArgs.push_back("-lc++"); + // TODO: Handle Static libc++ + //CmdArgs.push_back("-lc++abi"); + break; + + case ToolChain::CST_Libstdcxx: + CmdArgs.push_back("-lstdc++"); + // TODO: Handle Static libstdc++ + //CmdArgs.push_back("-lsupc++"); + break; + } +} + +ToolChain::RuntimeLibType MinGW::GetRuntimeLibType(const ArgList &Args) const{ + if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) { + StringRef Value = A->getValue(); + if (Value == "compiler-rt") + return ToolChain::RLT_CompilerRT; + if (Value == "libgcc") + return ToolChain::RLT_Libgcc; + getDriver().Diag(diag::err_drv_invalid_rtlib_name) + << A->getAsString(Args); + } + // TODO: Set RLT_CompilerRT to default for standalone toolchain + return ToolChain::RLT_CompilerRT; +} + +ToolChain::CXXStdlibType MinGW::GetCXXStdlibType(const ArgList &Args) const{ + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { + StringRef Value = A->getValue(); + if (Value == "libc++") + return ToolChain::CST_Libcxx; + if (Value == "libstdc++") + return ToolChain::CST_Libstdcxx; + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); } + // TODO: Set CST_Libcxx to default for standalone toolchain + return ToolChain::CST_Libcxx; } Index: tools/clang/lib/Driver/ToolChains.h =================================================================== --- tools/clang/lib/Driver/ToolChains.h +++ tools/clang/lib/Driver/ToolChains.h @@ -543,6 +543,13 @@ void AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + CXXStdlibType GetCXXStdlibType( + const llvm::opt::ArgList &Args) const override; + RuntimeLibType GetRuntimeLibType( + const llvm::opt::ArgList &Args) const override; protected: Tool *getTool(Action::ActionClass AC) const override; Index: tools/clang/lib/Driver/Tools.h =================================================================== --- tools/clang/lib/Driver/Tools.h +++ tools/clang/lib/Driver/Tools.h @@ -689,7 +689,7 @@ const char *LinkingOutput) const override; private: - void AddLibGCC(const llvm::opt::ArgList &Args, ArgStringList &CmdArgs) const; + void AddRuntime(const ToolChain &TC, const llvm::opt::ArgList &Args, ArgStringList &CmdArgs) const; }; } // end namespace MinGW Index: tools/clang/lib/Driver/Tools.cpp =================================================================== --- tools/clang/lib/Driver/Tools.cpp +++ tools/clang/lib/Driver/Tools.cpp @@ -2243,8 +2243,7 @@ // 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) @@ -2269,11 +2268,12 @@ ? "-android" : ""; - 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 + "-" + @@ -8905,20 +8905,30 @@ SplitDebugName(Args, Inputs[0])); } -void MinGW::Linker::AddLibGCC(const ArgList &Args, - ArgStringList &CmdArgs) const { +void MinGW::Linker::AddRuntime(const ToolChain &TC, const ArgList &Args, + ArgStringList &CmdArgs) const { 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"); + + switch (TC.GetRuntimeLibType(Args)) { + case ToolChain::RLT_CompilerRT: + CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins"))); + break; + + case ToolChain::RLT_Libgcc: + 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"); + } + break; } + CmdArgs.push_back("-lmoldname"); CmdArgs.push_back("-lmingwex"); CmdArgs.push_back("-lmsvcrt"); @@ -9051,7 +9061,7 @@ if (Args.hasArg(options::OPT_fopenmp)) CmdArgs.push_back("-lgomp"); - AddLibGCC(Args, CmdArgs); + AddRuntime(TC, Args, CmdArgs); if (Args.hasArg(options::OPT_pg)) CmdArgs.push_back("-lgmon"); @@ -9072,7 +9082,7 @@ if (Args.hasArg(options::OPT_static)) CmdArgs.push_back("--end-group"); else if (!LinkerName.equals_lower("lld")) - AddLibGCC(Args, CmdArgs); + AddRuntime(TC, Args, CmdArgs); } if (!Args.hasArg(options::OPT_nostartfiles)) {