Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -475,6 +475,9 @@ void AddLinkARCArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; + + void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; /// } private: Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -264,6 +264,50 @@ CmdArgs.push_back(Args.MakeArgString(P)); } +void DarwinClang::AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ); + + // Check if libc++ has been enabled and provide its include paths if so. + if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { + const std::string LibCXXIncludePathCandidates[] = { + // The primary location is within the Clang installation. + // FIXME: We shouldn't hard code 'v1' here to make Clang future proof to + // newer ABI versions. + getDriver().Dir + "/../include/c++/v1", + + // Try sysroot, e.g., DEFAULT_SYSROOT, if set + getDriver().SysRoot + "/usr/include/c++/v1", + + // libc++ was installed via macports + "/usr/include/c++/v1", + + // FIXME: We should really let cmake find this path, e.g., + // assuming we were compiled with clang: + // LIBCXX_INCLUDE_DIR=$(dirname $(dirname $(xcrun -f clang))..)/include/c++/v1 + // libc++ installed along side clang + "/Applications/Xcode.app/Contents/Developer/Toolchains/" + "XcodeDefault.xctoolchain/usr/include/c++/v1" + }; + for (const auto &IncludePath : LibCXXIncludePathCandidates) { + if (!llvm::sys::fs::exists(IncludePath)) + continue; + // Add the first candidate that exists. + addSystemInclude(DriverArgs, CC1Args, IncludePath); + break; + } + } else { + // FIXME: The libstdc++ include paths are currently added in + // InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(). + // Should they be moved here? + } +} + void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, StringRef DarwinLibName, bool AlwaysLink, bool IsEmbedded, bool AddRPath) const { Index: lib/Frontend/InitHeaderSearch.cpp =================================================================== --- lib/Frontend/InitHeaderSearch.cpp +++ lib/Frontend/InitHeaderSearch.cpp @@ -437,22 +437,6 @@ if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) { if (HSOpts.UseLibcxx) { - if (triple.isOSDarwin()) { - // On Darwin, libc++ may be installed alongside the compiler in - // include/c++/v1. - if (!HSOpts.ResourceDir.empty()) { - // Remove version from foo/lib/clang/version - StringRef NoVer = llvm::sys::path::parent_path(HSOpts.ResourceDir); - // Remove clang from foo/lib/clang - StringRef Lib = llvm::sys::path::parent_path(NoVer); - // Remove lib from foo/lib - SmallString<128> P = llvm::sys::path::parent_path(Lib); - - // Get foo/include/c++/v1 - llvm::sys::path::append(P, "include", "c++", "v1"); - AddUnmappedPath(P, CXXSystem, false); - } - } // On Solaris, include the support directory for things like xlocale and // fudged system headers. if (triple.getOS() == llvm::Triple::Solaris)