Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1527,6 +1527,7 @@ def pthreads : Flag<["-"], "pthreads">; def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>, HelpText<"Support POSIX threads in generated code">; +def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>; def p : Flag<["-"], "p">; def pie : Flag<["-"], "pie">; def read__only__relocs : Separate<["-"], "read_only_relocs">; Index: lib/Driver/MinGWToolChain.cpp =================================================================== --- lib/Driver/MinGWToolChain.cpp +++ lib/Driver/MinGWToolChain.cpp @@ -9,6 +9,7 @@ #include "ToolChains.h" #include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" @@ -113,13 +114,16 @@ 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"; - addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include"); addSystemInclude(DriverArgs, CC1Args, Base + "include"); + + 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"; + addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); + } } void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, @@ -128,21 +132,71 @@ DriverArgs.hasArg(options::OPT_nostdincxx)) return; - // C++ includes may be found in several locations depending on distribution. - // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++. - // mingw-w64 msys2: $sysroot/include/c++/4.9.2 - // mingw.org: 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. + // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++. + // mingw-w64 msys2: $sysroot/include/c++/4.9.2 + // mingw.org: 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++"); + CmdArgs.push_back("-lc++abi"); + break; + + case ToolChain::CST_Libstdcxx: + CmdArgs.push_back("-lstdc++"); + 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); + } + 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); } + return ToolChain::CST_Libcxx; } Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ 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: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -702,7 +702,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: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2239,8 +2239,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) @@ -2266,10 +2265,12 @@ : ""; 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 + "-" + @@ -8826,20 +8827,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"); @@ -8864,6 +8875,12 @@ // handled somewhere else. Args.ClaimAllArgs(options::OPT_w); + StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "ld"); + if (Linker.equals_lower("lld")) { + CmdArgs.push_back("-flavor"); + CmdArgs.push_back("gnu"); + } + if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); @@ -8875,6 +8892,8 @@ CmdArgs.push_back("i386pe"); if (TC.getArch() == llvm::Triple::x86_64) CmdArgs.push_back("i386pep"); + if (TC.getArch() == llvm::Triple::arm) + CmdArgs.push_back("thumb2pe"); if (Args.hasArg(options::OPT_mwindows)) { CmdArgs.push_back("--subsystem"); @@ -8964,12 +8983,13 @@ 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"); - if (Args.hasArg(options::OPT_pthread)) + if (Args.hasArg(options::OPT_pthread) && + !Args.hasArg(options::OPT_no_pthread)) CmdArgs.push_back("-lpthread"); // add system libraries @@ -8985,7 +9005,8 @@ if (Args.hasArg(options::OPT_static)) CmdArgs.push_back("--end-group"); else - AddLibGCC(Args, CmdArgs); + if (!Linker.equals_lower("lld")) + AddRuntime(TC, Args, CmdArgs); } if (!Args.hasArg(options::OPT_nostartfiles)) { @@ -8995,7 +9016,7 @@ CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); } } - const char *Exec = Args.MakeArgString(TC.GetProgramPath("ld")); + const char *Exec = Args.MakeArgString(TC.GetProgramPath(Linker.data())); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); }