diff --git a/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.cpp b/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.cpp index 7c9e9c0..4226188 100644 --- a/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.cpp +++ b/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.cpp @@ -1870,6 +1870,87 @@ bool FreeBSD::UseSjLjExceptions() const { } } +/// \brief Helper to add the three variant paths for a libstdc++ installation. +/*static*/ bool FreeBSD::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, + const ArgList &DriverArgs, + ArgStringList &CC1Args) { + if (!llvm::sys::fs::exists(Base)) + return false; + addSystemInclude(DriverArgs, CC1Args, Base); + addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); + addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); + return true; +} + +/// \brief Helper to add an extra variant path for an (Ubuntu) multilib +/// libstdc++ installation. +/*static*/ bool FreeBSD::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, + Twine TargetArchDir, + Twine MultiLibSuffix, + const ArgList &DriverArgs, + ArgStringList &CC1Args) { + if (!addLibStdCXXIncludePaths(Base+Suffix, TargetArchDir + MultiLibSuffix, + DriverArgs, CC1Args)) + return false; + + addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix + + MultiLibSuffix); + return true; +} + +void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + // Check if libc++ has been enabled and provide its include paths if so. + if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { + // libc++ is always installed at a fixed path on Linux currently. + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/usr/include/c++/v1"); + return; + } + + // We need a detected GCC installation on Linux to provide libstdc++'s + // headers. We handled the libc++ case above. + if (!GCCInstallation.isValid()) + return; + + // By default, look for the C++ headers in an include directory adjacent to + // the lib directory of the GCC installation. Note that this is expect to be + // equivalent to '/usr/include/c++/X.Y' in almost all cases. + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef InstallDir = GCCInstallation.getInstallPath(); + StringRef Version = GCCInstallation.getVersion().Text; + StringRef TripleStr = GCCInstallation.getTriple().str(); + + if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", + "/c++/" + Version.str(), + TripleStr, + GCCInstallation.getMultiarchSuffix(), + DriverArgs, CC1Args)) + return; + + const std::string IncludePathCandidates[] = { + // Gentoo is weird and places its headers inside the GCC install, so if the + // first attempt to find the headers fails, try this pattern. + InstallDir.str() + "/include/g++-v4", + // Android standalone toolchain has C++ headers in yet another place. + LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.str(), + // Freescale SDK C++ headers are directly in /usr/include/c++, + // without a subdirectory corresponding to the gcc version. + LibDir.str() + "/../include/c++", + }; + + for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) { + if (addLibStdCXXIncludePaths(IncludePathCandidates[i], (TripleStr + + GCCInstallation.getMultiarchSuffix()), + DriverArgs, CC1Args)) + break; + } +} + /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) diff --git a/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.h b/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.h index 3afd8dd..f7f87a2 100644 --- a/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.h +++ b/llvm-3.3.src/tools/clang/lib/Driver/ToolChains.h @@ -462,9 +462,22 @@ public: virtual bool IsObjCNonFragileABIDefault() const { return true; } virtual bool UseSjLjExceptions() const; + + virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const; protected: virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; +private: + static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, + Twine TargetArchDir, + Twine MultiLibSuffix, + const ArgList &DriverArgs, + ArgStringList &CC1Args); + static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, + const ArgList &DriverArgs, + ArgStringList &CC1Args); + }; class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {