Index: lib/Frontend/InitHeaderSearch.cpp =================================================================== --- lib/Frontend/InitHeaderSearch.cpp (revision 153147) +++ lib/Frontend/InitHeaderSearch.cpp (working copy) @@ -24,7 +24,9 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Regex.h" #include "clang/Config/config.h" // C_INCLUDE_DIRS @@ -57,25 +59,17 @@ bool isCXXAware, bool isUserSupplied, bool isFramework, bool IgnoreSysRoot = false); - /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu - /// libstdc++. - void AddGnuCPlusPlusIncludePaths(StringRef Base, - StringRef ArchDir, - StringRef Dir32, - StringRef Dir64, - const llvm::Triple &triple); + /// AddGnuCPlusPlusIncludePaths - Add the necessary paths for gnu libstdc++. + void AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir); + + /// AddVersionedCPlusPlusIncludePaths - Add paths with version number + void AddVersionedCPlusPlusIncludePaths(StringRef Base, + StringRef Suffix, + StringRef Arch); - /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW - /// libstdc++. - void AddMinGWCPlusPlusIncludePaths(StringRef Base, - StringRef Arch, - StringRef Version); + /// AddMinGWCIncludePaths - Add MinGW paths that should always be searched + void AddMinGWCIncludePaths(StringRef Base); - /// AddMinGW64CXXPaths - Add the necessary paths to support - /// libstdc++ of x86_64-w64-mingw32 aka mingw-w64. - void AddMinGW64CXXPaths(StringRef Base, - StringRef Version); - // AddDefaultCIncludePaths - Add paths that should always be searched. void AddDefaultCIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts); @@ -159,47 +153,49 @@ } void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base, - StringRef ArchDir, - StringRef Dir32, - StringRef Dir64, - const llvm::Triple &triple) { - // Add the base dir + StringRef ArchDir) { AddPath(Base, CXXSystem, true, false, false); - - // Add the multilib dirs - llvm::Triple::ArchType arch = triple.getArch(); - bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64; - if (is64bit) - AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, true, false, false); - else - AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, true, false, false); - - // Add the backward dir + AddPath(Base + "/" + ArchDir, CXXSystem, true, false, false); AddPath(Base + "/backward", CXXSystem, true, false, false); } -void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base, - StringRef Arch, - StringRef Version) { - AddPath(Base + "/" + Arch + "/" + Version + "/include/c++", - CXXSystem, true, false, false); - AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch, - CXXSystem, true, false, false); - AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward", - CXXSystem, true, false, false); +void InitHeaderSearch::AddVersionedCPlusPlusIncludePaths(StringRef Base, + StringRef Suffix, + StringRef Arch) { + llvm::error_code EC; + // match directories of the forms x.x and x.x.x where x can be 1 or 2 digits + llvm::Regex Regex("[0-9]{1,2}\\.[0-9]{1,2}(\\.[0-9]{1,2})?$"); + // Assumes Base is HeaderSearchOpts' ResourceDir + for (llvm::sys::fs::directory_iterator Dir(Base, EC), DirEnd; + Dir != DirEnd && !EC; Dir.increment(EC)) { + llvm::sys::fs::file_status status; + if (!Dir->status(status) && + is_directory(status) && + Regex.match(Dir->path())) { + AddPath(Dir->path() + Suffix, CXXSystem, true, false, false); + AddPath(Dir->path() + Suffix + Arch, CXXSystem, true, false, false); + AddPath(Dir->path() + Suffix + "/backward", + CXXSystem, true, false, false); + } + } } -void InitHeaderSearch::AddMinGW64CXXPaths(StringRef Base, - StringRef Version) { - // Assumes Base is HeaderSearchOpts' ResourceDir - AddPath(Base + "/../../../include/c++/" + Version, - CXXSystem, true, false, false); - AddPath(Base + "/../../../include/c++/" + Version + "/x86_64-w64-mingw32", - CXXSystem, true, false, false); - AddPath(Base + "/../../../include/c++/" + Version + "/i686-w64-mingw32", - CXXSystem, true, false, false); - AddPath(Base + "/../../../include/c++/" + Version + "/backward", - CXXSystem, true, false, false); +void InitHeaderSearch::AddMinGWCIncludePaths(StringRef Base) +{ + llvm::error_code EC; + // match directories of the forms x.x and x.x.x where x can be 1 or 2 digits + llvm::Regex Regex("[0-9]{1,2}\\.[0-9]{1,2}(\\.[0-9]{1,2})?$"); + for (llvm::sys::fs::directory_iterator Dir(Base + "/lib/gcc/mingw32", EC), + DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { + llvm::sys::fs::file_status status; + if (!Dir->status(status) && + is_directory(status) && + Regex.match(Dir->path())) { + AddPath(Dir->path() + "/include", System, true, false, false); + AddPath(Base + "/" + "include", System, true, false, false); + AddPath(Dir->path() + "/include-fixed", System, true, false, false); + } + } } void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, @@ -301,17 +297,19 @@ case llvm::Triple::MinGW32: { // mingw-w64 crt include paths llvm::sys::Path P(HSOpts.ResourceDir); - P.appendComponent("../../../i686-w64-mingw32/include"); // /i686-w64-mingw32/include + // /i686-w64-mingw32/include + P.appendComponent("../../../i686-w64-mingw32/include"); AddPath(P.str(), System, true, false, false); P = llvm::sys::Path(HSOpts.ResourceDir); - P.appendComponent("../../../x86_64-w64-mingw32/include"); // /x86_64-w64-mingw32/include + // /x86_64-w64-mingw32/include + P.appendComponent("../../../x86_64-w64-mingw32/include"); AddPath(P.str(), System, true, false, false); // mingw.org crt include paths P = llvm::sys::Path(HSOpts.ResourceDir); P.appendComponent("../../../include"); // /include AddPath(P.str(), System, true, false, false); AddPath("/mingw/include", System, true, false, false); - AddPath("c:/mingw/include", System, true, false, false); + AddMinGWCIncludePaths("c:/mingw"); } break; @@ -324,7 +322,8 @@ } void InitHeaderSearch:: -AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { +AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, + const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); // FIXME: temporary hack: hard-coded paths. @@ -333,29 +332,31 @@ default: break; case llvm::Triple::ppc: + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "powerpc-apple-darwin10"); + break; case llvm::Triple::ppc64: - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", - "powerpc-apple-darwin10", "", "ppc64", - triple); - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", - "powerpc-apple-darwin10", "", "ppc64", - triple); + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "powerpc-apple-darwin10/ppc64"); break; - case llvm::Triple::x86: + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "i686-apple-darwin10"); + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "i686-apple-darwin8"); + break; case llvm::Triple::x86_64: - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", - "i686-apple-darwin10", "", "x86_64", triple); - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", - "i686-apple-darwin8", "", "", triple); + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "i686-apple-darwin10/x86_64"); + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "i686-apple-darwin8/x86_64"); break; - case llvm::Triple::arm: case llvm::Triple::thumb: - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", - "arm-apple-darwin10", "v7", "", triple); - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", - "arm-apple-darwin10", "v6", "", triple); + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "arm-apple-darwin10/v7"); + AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", + "arm-apple-darwin10/v6"); break; } return; @@ -367,64 +368,48 @@ llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Cygwin: - // Cygwin-1.7 - AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); - AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); - // g++-4 / Cygwin-1.5 - AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2"); + AddVersionedCPlusPlusIncludePaths("/usr/lib/gcc/i686-pc-cygwin", + "/include/c++", "i686-pc-cygwin"); break; - case llvm::Triple::MinGW32: - // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32) - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.4"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.2"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.3"); - AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0"); - // mingw.org C++ include paths - AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS - AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2"); - AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1"); - AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2"); - AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0"); - AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0"); - AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0"); + case llvm::Triple::MinGW32: { + // mingw-w64 C++ include paths + StringRef Base = HSOpts.ResourceDir + "/../../../include/c++"; + AddVersionedCPlusPlusIncludePaths(Base, "", "/i686-w64-mingw32"); + AddVersionedCPlusPlusIncludePaths(Base, "", "/x86_64-w64-mingw32"); + // mingw.org C++ include paths + AddVersionedCPlusPlusIncludePaths("/mingw/lib/gcc/mingw32", + "/include/c++", "mingw32"); // MSYS + AddVersionedCPlusPlusIncludePaths("c:/mingw/lib/gcc/mingw32", + "/include/c++", "mingw32"); + } break; case llvm::Triple::DragonFly: AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false); break; case llvm::Triple::FreeBSD: - // FreeBSD 8.0 - // FreeBSD 7.3 - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple); + // Versions 7.3 and 8.0 + AddVersionedCPlusPlusIncludePaths("/usr/include/c++/", "", ""); break; case llvm::Triple::NetBSD: - AddGnuCPlusPlusIncludePaths("/usr/include/g++", "", "", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/g++", ""); break; case llvm::Triple::OpenBSD: { std::string t = triple.getTriple(); if (t.substr(0, 6) == "x86_64") t.replace(0, 6, "amd64"); - AddGnuCPlusPlusIncludePaths("/usr/include/g++", - t, "", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/g++", t); break; } case llvm::Triple::Minix: - AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", - "", "", "", triple); + AddVersionedCPlusPlusIncludePaths("/usr/gnu/include/c++", "", ""); break; case llvm::Triple::Solaris: - AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/", - "i386-pc-solaris2.11", "", "", triple); + AddVersionedCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++", + "", "i386-pc-solaris2.11"); // Solaris - Fall though.. case llvm::Triple::AuroraUX: - // AuroraUX - AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4", - "i386-pc-solaris2.11", "", "", triple); + AddVersionedCPlusPlusIncludePaths("/opt/gcc4/include/c++", + "", "i386-pc-solaris2.11"); break; default: break;