diff options
Diffstat (limited to 'lib/Frontend/InitHeaderSearch.cpp')
-rw-r--r-- | lib/Frontend/InitHeaderSearch.cpp | 289 |
1 files changed, 180 insertions, 109 deletions
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index c0b4ebaab03b..d19ae9861ed6 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -11,12 +11,16 @@ // //===----------------------------------------------------------------------===// -#include "clang/Frontend/InitHeaderSearch.h" -#include "clang/Lex/HeaderSearch.h" +#include "clang/Frontend/Utils.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" +#include "clang/Frontend/HeaderSearchOptions.h" +#include "clang/Lex/HeaderSearch.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Path.h" #include "llvm/Config/config.h" @@ -26,6 +30,66 @@ #include <windows.h> #endif using namespace clang; +using namespace clang::frontend; + +namespace { + +/// InitHeaderSearch - This class makes it easier to set the search paths of +/// a HeaderSearch object. InitHeaderSearch stores several search path lists +/// internally, which can be sent to a HeaderSearch object in one swoop. +class InitHeaderSearch { + std::vector<DirectoryLookup> IncludeGroup[4]; + HeaderSearch& Headers; + bool Verbose; + std::string isysroot; + +public: + + InitHeaderSearch(HeaderSearch &HS, + bool verbose = false, const std::string &iSysroot = "") + : Headers(HS), Verbose(verbose), isysroot(iSysroot) {} + + /// AddPath - Add the specified path to the specified group list. + void AddPath(const llvm::StringRef &Path, IncludeDirGroup Group, + bool isCXXAware, bool isUserSupplied, + bool isFramework, bool IgnoreSysRoot = false); + + /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to suport a gnu + /// libstdc++. + void AddGnuCPlusPlusIncludePaths(const std::string &Base, + const char *ArchDir, + const char *Dir32, + const char *Dir64, + const llvm::Triple &triple); + + /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to suport a MinGW + /// libstdc++. + void AddMinGWCPlusPlusIncludePaths(const std::string &Base, + const char *Arch, + const char *Version); + + /// AddDelimitedPaths - Add a list of paths delimited by the system PATH + /// separator. The processing follows that of the CPATH variable for gcc. + void AddDelimitedPaths(const char *String); + + // AddDefaultCIncludePaths - Add paths that should always be searched. + void AddDefaultCIncludePaths(const llvm::Triple &triple); + + // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when + // compiling c++. + void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple); + + /// AddDefaultSystemIncludePaths - Adds the default system include paths so + /// that e.g. stdio.h is found. + void AddDefaultSystemIncludePaths(const LangOptions &Lang, + const llvm::Triple &triple); + + /// Realize - Merges all search path lists into one list and send it to + /// HeaderSearch. + void Realize(); +}; + +} void InitHeaderSearch::AddPath(const llvm::StringRef &Path, IncludeDirGroup Group, bool isCXXAware, @@ -82,9 +146,8 @@ void InitHeaderSearch::AddPath(const llvm::StringRef &Path, } -void InitHeaderSearch::AddEnvVarPaths(const char *Name) { - const char* at = getenv(Name); - if (!at || *at == 0) // Empty string should not add '.' path. +void InitHeaderSearch::AddDelimitedPaths(const char *at) { + if (*at == 0) // Empty string should not add '.' path. return; const char* delim = strchr(at, llvm::sys::PathSeparator); @@ -103,27 +166,30 @@ void InitHeaderSearch::AddEnvVarPaths(const char *Name) { } void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(const std::string &Base, + const char *ArchDir, const char *Dir32, const char *Dir64, const llvm::Triple &triple) { + // Add the common dirs + AddPath(Base, System, true, false, false); + AddPath(Base + "/backward", System, true, false, false); + + // Add the multilib dirs llvm::Triple::ArchType arch = triple.getArch(); bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64; - - AddPath(Base, System, true, false, false); if (is64bit) - AddPath(Base + "/" + Dir64, System, true, false, false); + AddPath(Base + "/" + ArchDir + "/" + Dir64, System, true, false, false); else - AddPath(Base + "/" + Dir32, System, true, false, false); - AddPath(Base + "/backward", System, true, false, false); + AddPath(Base + "/" + ArchDir + "/" + Dir32, System, true, false, false); } void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(const std::string &Base, const char *Arch, const char *Version) { - std::string localBase = Base + "/" + Arch + "/" + Version + "/include"; - AddPath(localBase, System, true, false, false); - AddPath(localBase + "/c++", System, true, false, false); - AddPath(localBase + "/c++/backward", System, true, false, false); + std::string localBase = Base + "/" + Arch + "/" + Version + "/include"; + AddPath(localBase, System, true, false, false); + AddPath(localBase + "/c++", System, true, false, false); + AddPath(localBase + "/c++/backward", System, true, false, false); } // FIXME: This probably should goto to some platform utils place. @@ -243,6 +309,16 @@ bool getVisualStudioDir(std::string &path) { void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) { // FIXME: temporary hack: hard-coded paths. + llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + llvm::SmallVector<llvm::StringRef, 5> dirs; + CIncludeDirs.split(dirs, ":"); + for (llvm::SmallVectorImpl<llvm::StringRef>::iterator i = dirs.begin(); + i != dirs.end(); + ++i) + AddPath(*i, System, false, false, false); + return; + } llvm::Triple::OSType os = triple.getOS(); switch (os) { case llvm::Triple::Win32: @@ -288,6 +364,17 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) { void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { llvm::Triple::OSType os = triple.getOS(); + llvm::StringRef CxxIncludeRoot(CXX_INCLUDE_ROOT); + if (CxxIncludeRoot != "") { + llvm::StringRef CxxIncludeArch(CXX_INCLUDE_ARCH); + if (CxxIncludeArch == "") + AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, triple.str().c_str(), + CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple); + else + AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, CXX_INCLUDE_ARCH, + CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple); + return; + } // FIXME: temporary hack: hard-coded paths. switch (os) { case llvm::Triple::Cygwin: @@ -310,113 +397,77 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl break; case llvm::Triple::Darwin: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", - "i686-apple-darwin10", - "i686-apple-darwin10/x86_64", - triple); + "i686-apple-darwin10", "", "x86_64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", - "i686-apple-darwin8", - "i686-apple-darwin8", - triple); + "i686-apple-darwin8", "", "", triple); break; case llvm::Triple::Linux: // Ubuntu 7.10 - Gutsy Gibbon AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.3", - "i486-linux-gnu", - "i486-linux-gnu", - triple); + "i486-linux-gnu", "", "", triple); // Ubuntu 9.04 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.3", - "x86_64-linux-gnu/32", - "x86_64-linux-gnu", - triple); + "x86_64-linux-gnu","32", "", triple); + // Ubuntu 9.10 + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1", + "x86_64-linux-gnu", "32", "", triple); // Fedora 8 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2", - "i386-redhat-linux", - "i386-redhat-linux", - triple); + "i386-redhat-linux", "", "", triple); // Fedora 9 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0", - "i386-redhat-linux", - "i386-redhat-linux", - triple); + "i386-redhat-linux", "", "", triple); // Fedora 10 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2", - "i386-redhat-linux", - "i386-redhat-linux", - triple); + "i386-redhat-linux","", "", triple); + + // Fedora 11 + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1", + "i586-redhat-linux","", "", triple); + // openSUSE 11.1 32 bit AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", - "i586-suse-linux", - "i586-suse-linux", - triple); + "i586-suse-linux", "", "", triple); // openSUSE 11.1 64 bit AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", - "x86_64-suse-linux/32", - "x86_64-suse-linux", - triple); + "x86_64-suse-linux", "32", "", triple); // openSUSE 11.2 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", - "i586-suse-linux", - "i586-suse-linux", - triple); + "i586-suse-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", - "x86_64-suse-linux", - "x86_64-suse-linux", - triple); + "x86_64-suse-linux", "", "", triple); // Arch Linux 2008-06-24 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1", - "i686-pc-linux-gnu", - "i686-pc-linux-gnu", - triple); + "i686-pc-linux-gnu", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-gnu", - triple); + "x86_64-unknown-linux-gnu", "", "", triple); // Gentoo x86 2009.1 stable AddGnuCPlusPlusIncludePaths( - "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4", - "i686-pc-linux-gnu", - "i686-pc-linux-gnu", - triple); + "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4", + "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 2009.0 stable AddGnuCPlusPlusIncludePaths( - "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4", - "i686-pc-linux-gnu", - "i686-pc-linux-gnu", - triple); + "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4", + "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 2008.0 stable AddGnuCPlusPlusIncludePaths( - "/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4", - "i686-pc-linux-gnu", - "i686-pc-linux-gnu", - triple); + "/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4", + "i686-pc-linux-gnu", "", "", triple); // Ubuntu 8.10 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", - "i486-pc-linux-gnu", - "i486-pc-linux-gnu", - triple); + "i486-pc-linux-gnu", "", "", triple); // Ubuntu 9.04 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", - "i486-linux-gnu", - "i486-linux-gnu", - triple); + "i486-linux-gnu","", "", triple); // Gentoo amd64 stable AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4", - "i686-pc-linux-gnu", - "i686-pc-linux-gnu", - triple); + "i686-pc-linux-gnu", "", "", triple); // Exherbo (2009-10-26) - AddGnuCPlusPlusIncludePaths( - "/usr/include/c++/4.4.2", - "x86_64-pc-linux-gnu/32", - "x86_64-pc-linux-gnu", - triple); - AddGnuCPlusPlusIncludePaths( - "/usr/include/c++/4.4.2", - "i686-pc-linux-gnu", - "i686-pc-linux-gnu", - triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2", + "x86_64-pc-linux-gnu", "32", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2", + "i686-pc-linux-gnu", "", "", triple); break; case llvm::Triple::FreeBSD: // DragonFly @@ -429,44 +480,27 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl case llvm::Triple::AuroraUX: // AuroraUX AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4", - "i386-pc-solaris2.11", - "i386-pc-solaris2.11", - triple); + "i386-pc-solaris2.11", "", "", triple); break; default: break; } } -void InitHeaderSearch::AddDefaultFrameworkIncludePaths(const llvm::Triple &triple) { - llvm::Triple::OSType os = triple.getOS(); - if (os != llvm::Triple::Darwin) - return; - AddPath("/System/Library/Frameworks", System, true, false, true); - AddPath("/Library/Frameworks", System, true, false, true); -} - void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang, const llvm::Triple &triple) { AddDefaultCIncludePaths(triple); - AddDefaultFrameworkIncludePaths(triple); + + // Add the default framework include paths on Darwin. + if (triple.getOS() == llvm::Triple::Darwin) { + AddPath("/System/Library/Frameworks", System, true, false, true); + AddPath("/Library/Frameworks", System, true, false, true); + } + if (Lang.CPlusPlus) AddDefaultCPlusPlusIncludePaths(triple); } -void InitHeaderSearch::AddDefaultEnvVarPaths(const LangOptions &Lang) { - AddEnvVarPaths("CPATH"); - if (Lang.CPlusPlus && Lang.ObjC1) - AddEnvVarPaths("OBJCPLUS_INCLUDE_PATH"); - else if (Lang.CPlusPlus) - AddEnvVarPaths("CPLUS_INCLUDE_PATH"); - else if (Lang.ObjC1) - AddEnvVarPaths("OBJC_INCLUDE_PATH"); - else - AddEnvVarPaths("C_INCLUDE_PATH"); -} - - /// RemoveDuplicates - If there are duplicate directory entries in the specified /// search list, remove the later (dead) ones. static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList, @@ -591,3 +625,40 @@ void InitHeaderSearch::Realize() { fprintf(stderr, "End of search list.\n"); } } + +void clang::ApplyHeaderSearchOptions(HeaderSearch &HS, + const HeaderSearchOptions &HSOpts, + const LangOptions &Lang, + const llvm::Triple &Triple) { + InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot); + + // Add the user defined entries. + for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) { + const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i]; + Init.AddPath(E.Path, E.Group, false, E.IsUserSupplied, E.IsFramework, + false); + } + + // Add entries from CPATH and friends. + Init.AddDelimitedPaths(HSOpts.EnvIncPath.c_str()); + if (Lang.CPlusPlus && Lang.ObjC1) + Init.AddDelimitedPaths(HSOpts.ObjCXXEnvIncPath.c_str()); + else if (Lang.CPlusPlus) + Init.AddDelimitedPaths(HSOpts.CXXEnvIncPath.c_str()); + else if (Lang.ObjC1) + Init.AddDelimitedPaths(HSOpts.ObjCEnvIncPath.c_str()); + else + Init.AddDelimitedPaths(HSOpts.CEnvIncPath.c_str()); + + if (!HSOpts.BuiltinIncludePath.empty()) { + // Ignore the sys root, we *always* look for clang headers relative to + // supplied path. + Init.AddPath(HSOpts.BuiltinIncludePath, System, + false, false, false, /*IgnoreSysRoot=*/ true); + } + + if (HSOpts.UseStandardIncludes) + Init.AddDefaultSystemIncludePaths(Lang, Triple); + + Init.Realize(); +} |