Index: cfe/trunk/CMakeLists.txt =================================================================== --- cfe/trunk/CMakeLists.txt +++ cfe/trunk/CMakeLists.txt @@ -197,6 +197,15 @@ set(DEFAULT_SYSROOT "" CACHE PATH "Default to all compiler invocations for --sysroot=." ) +set(CLANG_DEFAULT_CXX_STDLIB "" CACHE STRING + "Default C++ stdlib to use (empty for architecture default, \"libstdc++\" or \"libc++\"") +if (NOT(CLANG_DEFAULT_CXX_STDLIB STREQUAL "" OR + CLANG_DEFAULT_CXX_STDLIB STREQUAL "libstdc++" OR + CLANG_DEFAULT_CXX_STDLIB STREQUAL "libc++")) + message(WARNING "Resetting default C++ stdlib to use architecture default") + set(CLANG_DEFAULT_CXX_STDLIB "") +endif() + set(CLANG_DEFAULT_OPENMP_RUNTIME "libomp" CACHE STRING "Default OpenMP runtime used by -fopenmp.") Index: cfe/trunk/include/clang/Config/config.h.cmake =================================================================== --- cfe/trunk/include/clang/Config/config.h.cmake +++ cfe/trunk/include/clang/Config/config.h.cmake @@ -8,6 +8,9 @@ /* Bug report URL. */ #define BUG_REPORT_URL "${BUG_REPORT_URL}" +/* Default C++ stdlib to use. */ +#define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}" + /* Default OpenMP runtime used by -fopenmp. */ #define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}" Index: cfe/trunk/include/clang/Config/config.h.in =================================================================== --- cfe/trunk/include/clang/Config/config.h.in +++ cfe/trunk/include/clang/Config/config.h.in @@ -8,6 +8,9 @@ /* Bug report URL. */ #undef BUG_REPORT_URL +/* Default C++ stdlib to use. */ +#undef CLANG_DEFAULT_CXX_STDLIB + /* Default OpenMP runtime used by -fopenmp. */ #undef CLANG_DEFAULT_OPENMP_RUNTIME Index: cfe/trunk/include/clang/Driver/ToolChain.h =================================================================== --- cfe/trunk/include/clang/Driver/ToolChain.h +++ cfe/trunk/include/clang/Driver/ToolChain.h @@ -256,6 +256,10 @@ return ToolChain::RLT_Libgcc; } + virtual CXXStdlibType GetDefaultCXXStdlibType() const { + return ToolChain::CST_Libstdcxx; + } + virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, bool Shared = false) const; Index: cfe/trunk/lib/Driver/ToolChain.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -9,6 +9,7 @@ #include "Tools.h" #include "clang/Basic/ObjCRuntime.h" +#include "clang/Config/config.h" #include "clang/Driver/Action.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -533,18 +534,34 @@ return GetDefaultRuntimeLibType(); } +static bool ParseCXXStdlibType(const StringRef& Name, + ToolChain::CXXStdlibType& Type) { + if (Name == "libc++") + Type = ToolChain::CST_Libcxx; + else if (Name == "libstdc++") + Type = ToolChain::CST_Libstdcxx; + else + return false; + + return true; +} + ToolChain::CXXStdlibType ToolChain::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); + ToolChain::CXXStdlibType Type; + bool HasValidType = false; + + const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); + if (A) { + HasValidType = ParseCXXStdlibType(A->getValue(), Type); + if (!HasValidType) + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); } - return ToolChain::CST_Libstdcxx; + if (!HasValidType && !ParseCXXStdlibType(CLANG_DEFAULT_CXX_STDLIB, Type)) + Type = GetDefaultCXXStdlibType(); + + return Type; } /// \brief Utility function to add a system include directory to CC1 arguments. Index: cfe/trunk/lib/Driver/ToolChains.h =================================================================== --- cfe/trunk/lib/Driver/ToolChains.h +++ cfe/trunk/lib/Driver/ToolChains.h @@ -512,6 +512,7 @@ TranslateArgs(const llvm::opt::DerivedArgList &Args, const char *BoundArch) const override; + CXXStdlibType GetDefaultCXXStdlibType() const override; ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; bool hasBlocksRuntime() const override; @@ -699,7 +700,7 @@ bool IsMathErrnoDefault() const override { return false; } bool IsObjCNonFragileABIDefault() const override { return true; } - CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + CXXStdlibType GetDefaultCXXStdlibType() const override; void AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; Index: cfe/trunk/lib/Driver/ToolChains.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains.cpp +++ cfe/trunk/lib/Driver/ToolChains.cpp @@ -65,6 +65,16 @@ bool MachO::HasNativeLLVMSupport() const { return true; } +ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const { + // Default to use libc++ on OS X 10.9+ and iOS 7+. + if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || + (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || + isTargetWatchOSBased()) + return ToolChain::CST_Libcxx; + + return ToolChain::CST_Libstdcxx; +} + /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { if (isTargetWatchOSBased()) @@ -1020,7 +1030,6 @@ const char *BoundArch) const { // First get the generic Apple args, before moving onto Darwin-specific ones. DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch); - const OptTable &Opts = getDriver().getOpts(); // If no architecture is bound, none of the translations here are relevant. if (!BoundArch) @@ -1051,14 +1060,6 @@ } } - // Default to use libc++ on OS X 10.9+ and iOS 7+. - if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || - (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || - isTargetWatchOSBased()) && - !Args.getLastArg(options::OPT_stdlib_EQ)) - DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ), - "libc++"); - // Validate the C++ standard library choice. CXXStdlibType Type = GetCXXStdlibType(*DAL); if (Type == ToolChain::CST_Libcxx) { @@ -3027,16 +3028,7 @@ Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); } -ToolChain::CXXStdlibType Bitrig::GetCXXStdlibType(const ArgList &Args) const { - if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { - StringRef Value = A->getValue(); - if (Value == "libstdc++") - return ToolChain::CST_Libstdcxx; - if (Value == "libc++") - return ToolChain::CST_Libcxx; - - getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); - } +ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const { return ToolChain::CST_Libcxx; }