zcov: / lib/Frontend/InitHeaderSearch.cpp


Files: 1 Branches Taken: 56.1% 92 / 164
Generated: 2010-02-10 01:31 Branches Executed: 72.0% 118 / 164
Line Coverage: 68.6% 177 / 258


Programs: 2 Runs 3018


       1                 : //===--- InitHeaderSearch.cpp - Initialize header search paths ----------*-===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This file implements the InitHeaderSearch class.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Frontend/Utils.h"
      15                 : #include "clang/Basic/FileManager.h"
      16                 : #include "clang/Basic/LangOptions.h"
      17                 : #include "clang/Frontend/HeaderSearchOptions.h"
      18                 : #include "clang/Lex/HeaderSearch.h"
      19                 : #include "llvm/ADT/SmallString.h"
      20                 : #include "llvm/ADT/SmallPtrSet.h"
      21                 : #include "llvm/ADT/SmallVector.h"
      22                 : #include "llvm/ADT/StringExtras.h"
      23                 : #include "llvm/ADT/Triple.h"
      24                 : #include "llvm/ADT/Twine.h"
      25                 : #include "llvm/Support/raw_ostream.h"
      26                 : #include "llvm/System/Path.h"
      27                 : #include "llvm/Config/config.h"
      28                 : #ifdef _MSC_VER
      29                 :   #define WIN32_LEAN_AND_MEAN 1
      30                 :   #include <windows.h>
      31                 : #endif
      32                 : using namespace clang;
      33                 : using namespace clang::frontend;
      34                 : 
      35                 : namespace {
      36                 : 
      37                 : /// InitHeaderSearch - This class makes it easier to set the search paths of
      38                 : ///  a HeaderSearch object. InitHeaderSearch stores several search path lists
      39                 : ///  internally, which can be sent to a HeaderSearch object in one swoop.
                     2520: branch 1 taken
                        0: branch 2 not taken
                    10080: branch 3 taken
                     2520: branch 4 taken
      40             2520: class InitHeaderSearch {
      41                 :   std::vector<DirectoryLookup> IncludeGroup[4];
      42                 :   HeaderSearch& Headers;
      43                 :   bool Verbose;
      44                 :   std::string isysroot;
      45                 : 
      46                 : public:
      47                 : 
      48                 :   InitHeaderSearch(HeaderSearch &HS,
      49             2520:       bool verbose = false, const std::string &iSysroot = "")
                    10080: branch 1 taken
                     2520: branch 2 taken
      50             2520:     : Headers(HS), Verbose(verbose), isysroot(iSysroot) {}
      51                 : 
      52                 :   /// AddPath - Add the specified path to the specified group list.
      53                 :   void AddPath(const llvm::Twine &Path, IncludeDirGroup Group,
      54                 :                bool isCXXAware, bool isUserSupplied,
      55                 :                bool isFramework, bool IgnoreSysRoot = false);
      56                 : 
      57                 :   /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to suport a gnu
      58                 :   ///  libstdc++.
      59                 :   void AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
      60                 :                                    llvm::StringRef ArchDir,
      61                 :                                    llvm::StringRef Dir32,
      62                 :                                    llvm::StringRef Dir64,
      63                 :                                    const llvm::Triple &triple);
      64                 : 
      65                 :   /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to suport a MinGW
      66                 :   ///  libstdc++.
      67                 :   void AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
      68                 :                                      llvm::StringRef Arch,
      69                 :                                      llvm::StringRef Version);
      70                 : 
      71                 :   /// AddDelimitedPaths - Add a list of paths delimited by the system PATH
      72                 :   /// separator. The processing follows that of the CPATH variable for gcc.
      73                 :   void AddDelimitedPaths(llvm::StringRef String);
      74                 : 
      75                 :   // AddDefaultCIncludePaths - Add paths that should always be searched.
      76                 :   void AddDefaultCIncludePaths(const llvm::Triple &triple);
      77                 : 
      78                 :   // AddDefaultCPlusPlusIncludePaths -  Add paths that should be searched when
      79                 :   //  compiling c++.
      80                 :   void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple);
      81                 : 
      82                 :   /// AddDefaultSystemIncludePaths - Adds the default system include paths so
      83                 :   ///  that e.g. stdio.h is found.
      84                 :   void AddDefaultSystemIncludePaths(const LangOptions &Lang,
      85                 :                                     const llvm::Triple &triple);
      86                 : 
      87                 :   /// Realize - Merges all search path lists into one list and send it to
      88                 :   /// HeaderSearch.
      89                 :   void Realize();
      90                 : };
      91                 : 
      92                 : }
      93                 : 
      94                 : void InitHeaderSearch::AddPath(const llvm::Twine &Path,
      95                 :                                IncludeDirGroup Group, bool isCXXAware,
      96                 :                                bool isUserSupplied, bool isFramework,
      97            65603:                                bool IgnoreSysRoot) {
                    65603: branch 1 taken
                        0: branch 2 not taken
      98            65603:   assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
      99            65603:   FileManager &FM = Headers.getFileMgr();
     100                 : 
     101                 :   // Compute the actual path, taking into consideration -isysroot.
     102            65603:   llvm::SmallString<256> MappedPathStr;
     103            65603:   llvm::raw_svector_ostream MappedPath(MappedPathStr);
     104                 : 
     105                 :   // Handle isysroot.
                    65598: branch 0 taken
                        5: branch 1 taken
                    63078: branch 2 taken
                     2520: branch 3 taken
     106           131201:   if (Group == System && !IgnoreSysRoot) {
     107                 :     // FIXME: Portability.  This should be a sys::Path interface, this doesn't
     108                 :     // handle things like C:\ right, nor win32 \\network\device\blah.
                    63074: branch 1 taken
                        4: branch 2 taken
                        0: branch 4 not taken
                    63074: branch 5 taken
                        4: branch 6 taken
                    63074: branch 7 taken
     109            63078:     if (isysroot.size() != 1 || isysroot[0] != '/') // Add isysroot if present.
     110                4:       MappedPath << isysroot;
     111                 :   }
     112                 : 
     113            65603:   Path.print(MappedPath);
     114                 : 
     115                 :   // Compute the DirectoryLookup type.
     116                 :   SrcMgr::CharacteristicKind Type;
                    65603: branch 0 taken
                        0: branch 1 not taken
                        5: branch 2 taken
                    65598: branch 3 taken
     117            65608:   if (Group == Quoted || Group == Angled)
     118                5:     Type = SrcMgr::C_User;
                    58026: branch 0 taken
                     7572: branch 1 taken
     119            65598:   else if (isCXXAware)
     120            58026:     Type = SrcMgr::C_System;
     121                 :   else
     122             7572:     Type = SrcMgr::C_ExternCSystem;
     123                 : 
     124                 : 
     125                 :   // If the directory exists, add it.
                    16253: branch 2 taken
                    49350: branch 3 taken
     126            65603:   if (const DirectoryEntry *DE = FM.getDirectory(MappedPath.str())) {
     127                 :     IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied,
     128            16253:                                                   isFramework));
     129            16253:     return;
     130                 :   }
     131                 : 
     132                 :   // Check to see if this is an apple-style headermap (which are not allowed to
     133                 :   // be frameworks).
                    48750: branch 0 taken
                      600: branch 1 taken
     134            49350:   if (!isFramework) {
                        0: branch 2 not taken
                    48750: branch 3 taken
     135            48750:     if (const FileEntry *FE = FM.getFile(MappedPath.str())) {
                        0: branch 1 not taken
                        0: branch 2 not taken
     136                0:       if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
     137                 :         // It is a headermap, add it to the search path.
     138                0:         IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
     139                 :         return;
     140                 :       }
     141                 :     }
     142                 :   }
     143                 : 
                        0: branch 0 not taken
                    49350: branch 1 taken
     144            49350:   if (Verbose)
     145                 :     llvm::errs() << "ignoring nonexistent directory \""
                    49350: branch 6 taken
                    16253: branch 7 taken
                    49350: branch 9 taken
                    16253: branch 10 taken
     146                0:                  << MappedPath.str() << "\"\n";
     147                 : }
     148                 : 
     149                 : 
     150             5040: void InitHeaderSearch::AddDelimitedPaths(llvm::StringRef at) {
                     5040: branch 1 taken
                        0: branch 2 not taken
     151             5040:   if (at.empty()) // Empty string should not add '.' path.
     152             5040:     return;
     153                 : 
     154                 :   llvm::StringRef::size_type delim;
                        0: branch 1 not taken
                        0: branch 2 not taken
     155                0:   while ((delim = at.find(llvm::sys::PathSeparator)) != llvm::StringRef::npos) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     156                0:     if (delim == 0)
     157                0:       AddPath(".", Angled, false, true, false);
     158                 :     else
     159                0:       AddPath(at.substr(0, delim), Angled, false, true, false);
     160                0:     at = at.substr(delim + 1);
     161                 :   }
     162                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
     163                0:   if (at.empty())
     164                0:     AddPath(".", Angled, false, true, false);
     165                 :   else
     166                0:     AddPath(at, Angled, false, true, false);
     167                 : }
     168                 : 
     169                 : void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
     170                 :                                                    llvm::StringRef ArchDir,
     171                 :                                                    llvm::StringRef Dir32,
     172                 :                                                    llvm::StringRef Dir64,
     173            19142:                                                    const llvm::Triple &triple) {
     174                 :   // Add the base dir
     175            19142:   AddPath(Base, System, true, false, false);
     176                 : 
     177                 :   // Add the multilib dirs
     178            19142:   llvm::Triple::ArchType arch = triple.getArch();
                    19142: branch 0 taken
                        0: branch 1 not taken
                      146: branch 2 taken
                    18996: branch 3 taken
     179            19142:   bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
                      146: branch 0 taken
                    18996: branch 1 taken
     180            19142:   if (is64bit)
     181              146:     AddPath(Base + "/" + ArchDir + "/" + Dir64, System, true, false, false);
     182                 :   else
     183            18996:     AddPath(Base + "/" + ArchDir + "/" + Dir32, System, true, false, false);
     184                 : 
     185                 :   // Add the backward dir
     186            19142:   AddPath(Base + "/backward", System, true, false, false);
     187            19142: }
     188                 : 
     189                 : void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
     190                 :                                                      llvm::StringRef Arch,
     191                0:                                                      llvm::StringRef Version) {
     192                 :   AddPath(Base + "/" + Arch + "/" + Version + "/include",
     193                0:           System, true, false, false);
     194                 :   AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
     195                0:           System, true, false, false);
     196                 :   AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
     197                0:           System, true, false, false);
     198                0: }
     199                 : 
     200                 :   // FIXME: This probably should goto to some platform utils place.
     201                 : #ifdef _MSC_VER
     202                 : 
     203                 :   // Read registry string.
     204                 :   // This also supports a means to look for high-versioned keys by use
     205                 :   // of a $VERSION placeholder in the key path.
     206                 :   // $VERSION in the key path is a placeholder for the version number,
     207                 :   // causing the highest value path to be searched for and used.
     208                 :   // I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
     209                 :   // There can be additional characters in the component.  Only the numberic
     210                 :   // characters are compared.
     211                 : static bool getSystemRegistryString(const char *keyPath, const char *valueName,
     212                 :                                     char *value, size_t maxLength) {
     213                 :   HKEY hRootKey = NULL;
     214                 :   HKEY hKey = NULL;
     215                 :   const char* subKey = NULL;
     216                 :   DWORD valueType;
     217                 :   DWORD valueSize = maxLength - 1;
     218                 :   long lResult;
     219                 :   bool returnValue = false;
     220                 :   if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
     221                 :     hRootKey = HKEY_CLASSES_ROOT;
     222                 :     subKey = keyPath + 18;
     223                 :   }
     224                 :   else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
     225                 :     hRootKey = HKEY_USERS;
     226                 :     subKey = keyPath + 11;
     227                 :   }
     228                 :   else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
     229                 :     hRootKey = HKEY_LOCAL_MACHINE;
     230                 :     subKey = keyPath + 19;
     231                 :   }
     232                 :   else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
     233                 :     hRootKey = HKEY_CURRENT_USER;
     234                 :     subKey = keyPath + 18;
     235                 :   }
     236                 :   else
     237                 :     return(false);
     238                 :   const char *placeHolder = strstr(subKey, "$VERSION");
     239                 :   char bestName[256];
     240                 :   bestName[0] = '\0';
     241                 :   // If we have a $VERSION placeholder, do the highest-version search.
     242                 :   if (placeHolder) {
     243                 :     const char *keyEnd = placeHolder - 1;
     244                 :     const char *nextKey = placeHolder;
     245                 :     // Find end of previous key.
     246                 :     while ((keyEnd > subKey) && (*keyEnd != '\\'))
     247                 :       keyEnd--;
     248                 :     // Find end of key containing $VERSION.
     249                 :     while (*nextKey && (*nextKey != '\\'))
     250                 :       nextKey++;
     251                 :     size_t partialKeyLength = keyEnd - subKey;
     252                 :     char partialKey[256];
     253                 :     if (partialKeyLength > sizeof(partialKey))
     254                 :       partialKeyLength = sizeof(partialKey);
     255                 :     strncpy(partialKey, subKey, partialKeyLength);
     256                 :     partialKey[partialKeyLength] = '\0';
     257                 :     HKEY hTopKey = NULL;
     258                 :     lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
     259                 :     if (lResult == ERROR_SUCCESS) {
     260                 :       char keyName[256];
     261                 :       int bestIndex = -1;
     262                 :       double bestValue = 0.0;
     263                 :       DWORD index, size = sizeof(keyName) - 1;
     264                 :       for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
     265                 :           NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
     266                 :         const char *sp = keyName;
     267                 :         while (*sp && !isdigit(*sp))
     268                 :           sp++;
     269                 :         if (!*sp)
     270                 :           continue;
     271                 :         const char *ep = sp + 1;
     272                 :         while (*ep && (isdigit(*ep) || (*ep == '.')))
     273                 :           ep++;
     274                 :         char numBuf[32];
     275                 :         strncpy(numBuf, sp, sizeof(numBuf) - 1);
     276                 :         numBuf[sizeof(numBuf) - 1] = '\0';
     277                 :         double value = strtod(numBuf, NULL);
     278                 :         if (value > bestValue) {
     279                 :           bestIndex = (int)index;
     280                 :           bestValue = value;
     281                 :           strcpy(bestName, keyName);
     282                 :         }
     283                 :         size = sizeof(keyName) - 1;
     284                 :       }
     285                 :       // If we found the highest versioned key, open the key and get the value.
     286                 :       if (bestIndex != -1) {
     287                 :         // Append rest of key.
     288                 :         strncat(bestName, nextKey, sizeof(bestName) - 1);
     289                 :         bestName[sizeof(bestName) - 1] = '\0';
     290                 :         // Open the chosen key path remainder.
     291                 :         lResult = RegOpenKeyEx(hTopKey, bestName, 0, KEY_READ, &hKey);
     292                 :         if (lResult == ERROR_SUCCESS) {
     293                 :           lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
     294                 :             (LPBYTE)value, &valueSize);
     295                 :           if (lResult == ERROR_SUCCESS)
     296                 :             returnValue = true;
     297                 :           RegCloseKey(hKey);
     298                 :         }
     299                 :       }
     300                 :       RegCloseKey(hTopKey);
     301                 :     }
     302                 :   }
     303                 :   else {
     304                 :     lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
     305                 :     if (lResult == ERROR_SUCCESS) {
     306                 :       lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
     307                 :         (LPBYTE)value, &valueSize);
     308                 :       if (lResult == ERROR_SUCCESS)
     309                 :         returnValue = true;
     310                 :       RegCloseKey(hKey);
     311                 :     }
     312                 :   }
     313                 :   return(returnValue);
     314                 : }
     315                 : #else // _MSC_VER
     316                 :   // Read registry string.
     317                2: static bool getSystemRegistryString(const char*, const char*, char*, size_t) {
     318                2:   return(false);
     319                 : }
     320                 : #endif // _MSC_VER
     321                 : 
     322                 :   // Get Visual Studio installation directory.
     323                2: static bool getVisualStudioDir(std::string &path) {
     324                 :   char vsIDEInstallDir[256];
     325                 :   // Try the Windows registry first.
     326                 :   bool hasVCDir = getSystemRegistryString(
     327                 :     "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
     328                2:     "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
     329                 :     // If we have both vc80 and vc90, pick version we were compiled with. 
                        0: branch 0 not taken
                        2: branch 1 taken
                        2: branch 2 taken
                        2: branch 3 taken
     330                2:   if (hasVCDir && vsIDEInstallDir[0]) {
     331                0:     char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
                        0: branch 0 not taken
                        0: branch 1 not taken
     332                0:     if (p)
     333                0:       *p = '\0';
     334                0:     path = vsIDEInstallDir;
     335                0:     return(true);
     336                 :   }
     337                 :   else {
     338                 :     // Try the environment.
     339                2:     const char* vs90comntools = getenv("VS90COMNTOOLS");
     340                2:     const char* vs80comntools = getenv("VS80COMNTOOLS");
     341                2:     const char* vscomntools = NULL;
     342                 :       // If we have both vc80 and vc90, pick version we were compiled with. 
                        0: branch 0 not taken
                        2: branch 1 taken
                        2: branch 2 taken
                        2: branch 3 taken
     343                2:     if (vs90comntools && vs80comntools) {
     344                 :       #if (_MSC_VER >= 1500)  // VC90
     345                 :           vscomntools = vs90comntools;
     346                 :       #elif (_MSC_VER == 1400) // VC80
     347                 :           vscomntools = vs80comntools;
     348                 :       #else
     349                0:           vscomntools = vs90comntools;
     350                 :       #endif
     351                 :     }
                        0: branch 0 not taken
                        2: branch 1 taken
     352                2:     else if (vs90comntools)
     353                0:       vscomntools = vs90comntools;
                        0: branch 0 not taken
                        2: branch 1 taken
     354                2:     else if (vs80comntools)
     355                0:       vscomntools = vs80comntools;
                        0: branch 0 not taken
                        2: branch 1 taken
                        2: branch 2 taken
                        2: branch 3 taken
     356                2:     if (vscomntools && *vscomntools) {
     357                0:       char *p = (char*)strstr(vscomntools, "\\Common7\\Tools");
                        0: branch 0 not taken
                        0: branch 1 not taken
     358                0:       if (p)
     359                0:         *p = '\0';
     360                0:       path = vscomntools;
     361                0:       return(true);
     362                 :     }
     363                 :     else
     364                2:       return(false);
     365                 :   }
     366                 :   return(false);
     367                 : }
     368                 : 
     369                 :   // Get Windows SDK installation directory.
     370                0: static bool getWindowsSDKDir(std::string &path) {
     371                 :   char windowsSDKInstallDir[256];
     372                 :   // Try the Windows registry.
     373                 :   bool hasSDKDir = getSystemRegistryString(
     374                 :    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
     375                0:     "InstallationFolder", windowsSDKInstallDir, sizeof(windowsSDKInstallDir) - 1);
     376                 :     // If we have both vc80 and vc90, pick version we were compiled with. 
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
     377                0:   if (hasSDKDir && windowsSDKInstallDir[0]) {
     378                0:     path = windowsSDKInstallDir;
     379                0:     return(true);
     380                 :   }
     381                0:   return(false);
     382                 : }
     383                 : 
     384             2520: void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
     385                 :   // FIXME: temporary hack: hard-coded paths.
     386             2520:   llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
                        0: branch 2 not taken
                     2520: branch 3 taken
     387             2520:   if (CIncludeDirs != "") {
     388                0:     llvm::SmallVector<llvm::StringRef, 5> dirs;
     389                0:     CIncludeDirs.split(dirs, ":");
                        0: branch 2 not taken
                        0: branch 3 not taken
     390                0:     for (llvm::SmallVectorImpl<llvm::StringRef>::iterator i = dirs.begin();
     391                 :          i != dirs.end();
     392                 :          ++i) 
     393                0:       AddPath(*i, System, false, false, false);
     394                0:     return;
     395                 :   }
     396             2520:   llvm::Triple::OSType os = triple.getOS();
                        2: branch 0 taken
                        0: branch 1 not taken
                     2518: branch 2 taken
     397             2520:   switch (os) {
     398                 :   case llvm::Triple::Win32:
     399                 :     {
     400                2:       std::string VSDir;
     401                2:       std::string WindowsSDKDir;
                        0: branch 1 not taken
                        2: branch 2 taken
     402                2:       if (getVisualStudioDir(VSDir)) {
     403                0:         AddPath(VSDir + "\\VC\\include", System, false, false, false);
                        0: branch 1 not taken
                        0: branch 2 not taken
     404                0:         if (getWindowsSDKDir(WindowsSDKDir))
     405                0:           AddPath(WindowsSDKDir, System, false, false, false);
     406                 :         else
     407                 :           AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
     408                0:             System, false, false, false);
     409                 :       }
     410                 :       else {
     411                 :           // Default install paths.
     412                 :         AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
     413                2:           System, false, false, false);
     414                 :         AddPath(
     415                 :         "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
     416                2:           System, false, false, false);
     417                 :         AddPath("C:/Program Files/Microsoft Visual Studio 8/VC/include",
     418                2:           System, false, false, false);
     419                 :         AddPath(
     420                 :         "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include",
     421                2:           System, false, false, false);
     422                 :           // For some clang developers.
     423                 :         AddPath("G:/Program Files/Microsoft Visual Studio 9.0/VC/include",
     424                2:           System, false, false, false);
     425                 :         AddPath(
     426                 :         "G:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
     427                2:           System, false, false, false);
     428                2:       }
     429                 :     }
     430                2:     break;
     431                 :   case llvm::Triple::MinGW64:
     432                 :   case llvm::Triple::MinGW32:
     433                0:     AddPath("c:/mingw/include", System, true, false, false);
     434                 :     break;
     435                 :   default:
     436                 :     break;
     437                 :   }
     438                 : 
     439             2520:   AddPath("/usr/local/include", System, false, false, false);
     440             2520:   AddPath("/usr/include", System, false, false, false);
     441                 : }
     442                 : 
     443              893: void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) {
     444              893:   llvm::Triple::OSType os = triple.getOS();
     445              893:   llvm::StringRef CxxIncludeRoot(CXX_INCLUDE_ROOT);
                        0: branch 2 not taken
                      893: branch 3 taken
     446              893:   if (CxxIncludeRoot != "") {
     447                0:     llvm::StringRef CxxIncludeArch(CXX_INCLUDE_ARCH);
                        0: branch 2 not taken
                        0: branch 3 not taken
     448                0:     if (CxxIncludeArch == "")
     449                 :       AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, triple.str().c_str(),
     450                0:                                   CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple);
     451                 :     else
     452                 :       AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, CXX_INCLUDE_ARCH,
     453                0:                                   CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple);
     454                0:     return;
     455                 :   }
     456                 :   // FIXME: temporary hack: hard-coded paths.
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                       91: branch 3 taken
                        0: branch 4 not taken
                      790: branch 5 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                       12: branch 8 taken
     457              893:   switch (os) {
     458                 :   case llvm::Triple::Cygwin:
     459                 :     AddPath("/lib/gcc/i686-pc-cygwin/3.4.4/include",
     460                0:         System, true, false, false);
     461                 :     AddPath("/lib/gcc/i686-pc-cygwin/3.4.4/include/c++",
     462                0:         System, true, false, false);
     463                0:     break;
     464                 :   case llvm::Triple::MinGW64:
     465                 :     // Try gcc 4.4.0
     466                0:     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw64", "4.4.0");
     467                 :     // Try gcc 4.3.0
     468                0:     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw64", "4.3.0");
     469                 :     // Fall through.
     470                 :   case llvm::Triple::MinGW32:
     471                 :     // Try gcc 4.4.0
     472                0:     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
     473                 :     // Try gcc 4.3.0
     474                0:     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
     475                0:     break;
     476                 :   case llvm::Triple::Darwin:
     477                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
     478               91:                                 "i686-apple-darwin10", "", "x86_64", triple);
     479                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
     480               91:                                 "i686-apple-darwin8", "", "", triple);
     481               91:     break;
     482                 :   case llvm::Triple::DragonFly:
     483                0:     AddPath("/usr/include/c++/4.1", System, true, false, false);
     484                0:     break;
     485                 :   case llvm::Triple::Linux:
     486                 :     // Exherbo (2010-01-25)
     487                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
     488              790:                                 "x86_64-pc-linux-gnu", "32", "", triple);
     489                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
     490              790:                                 "i686-pc-linux-gnu", "", "", triple);
     491                 :     // Debian sid
     492                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
     493              790:                                 "x86_64-linux-gnu", "32", "", triple);
     494                 :     // Ubuntu 7.10 - Gutsy Gibbon
     495                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.3",
     496              790:                                 "i486-linux-gnu", "", "", triple);
     497                 :     // Ubuntu 9.04
     498                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.3",
     499              790:                                 "x86_64-linux-gnu","32", "", triple);
     500                 :     // Ubuntu 9.10
     501                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
     502              790:                                 "x86_64-linux-gnu", "32", "", triple);
     503                 :     // Fedora 8
     504                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
     505              790:                                 "i386-redhat-linux", "", "", triple);
     506                 :     // Fedora 9
     507                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
     508              790:                                 "i386-redhat-linux", "", "", triple);
     509                 :     // Fedora 10
     510                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
     511              790:                                 "i386-redhat-linux","", "", triple);
     512                 : 
     513                 :     // Fedora 10 x86_64
     514                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
     515              790:                                 "x86_64-redhat-linux", "32", "", triple);
     516                 : 
     517                 :     // Fedora 11
     518                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
     519              790:                                 "i586-redhat-linux","", "", triple);
     520                 : 
     521                 :     // Fedora 12
     522                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
     523              790:                                 "i686-redhat-linux","", "", triple);
     524                 : 
     525                 :     // openSUSE 11.1 32 bit
     526                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
     527              790:                                 "i586-suse-linux", "", "", triple);
     528                 :     // openSUSE 11.1 64 bit
     529                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
     530              790:                                 "x86_64-suse-linux", "32", "", triple);
     531                 :     // openSUSE 11.2
     532                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
     533              790:                                 "i586-suse-linux", "", "", triple);
     534                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
     535              790:                                 "x86_64-suse-linux", "", "", triple);
     536                 :     // Arch Linux 2008-06-24
     537                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
     538              790:                                 "i686-pc-linux-gnu", "", "", triple);
     539                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
     540              790:                                 "x86_64-unknown-linux-gnu", "", "", triple);
     541                 :     // Gentoo x86 2009.1 stable
     542                 :     AddGnuCPlusPlusIncludePaths(
     543                 :       "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4",
     544              790:       "i686-pc-linux-gnu", "", "", triple);
     545                 :     // Gentoo x86 2009.0 stable
     546                 :     AddGnuCPlusPlusIncludePaths(
     547                 :       "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4",
     548              790:       "i686-pc-linux-gnu", "", "", triple);
     549                 :     // Gentoo x86 2008.0 stable
     550                 :     AddGnuCPlusPlusIncludePaths(
     551                 :       "/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4",
     552              790:       "i686-pc-linux-gnu", "", "", triple);
     553                 :     // Ubuntu 8.10
     554                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
     555              790:                                 "i486-pc-linux-gnu", "", "", triple);
     556                 :     // Ubuntu 9.04
     557                 :     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
     558              790:                                 "i486-linux-gnu","", "", triple);
     559                 :     // Gentoo amd64 stable
     560                 :     AddGnuCPlusPlusIncludePaths(
     561                 :         "/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4",
     562              790:         "i686-pc-linux-gnu", "", "", triple);
     563              790:     break;
     564                 :   case llvm::Triple::FreeBSD:
     565                0:     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
     566                0:     break;
     567                 :   case llvm::Triple::Solaris:
     568                 :     // Solaris - Fall though..
     569                 :   case llvm::Triple::AuroraUX:
     570                 :     // AuroraUX
     571                 :     AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4",
     572                0:                                 "i386-pc-solaris2.11", "", "", triple);
     573                 :     break;
     574                 :   default:
     575                 :     break;
     576                 :   }
     577                 : }
     578                 : 
     579                 : void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,
     580             2520:                                                     const llvm::Triple &triple) {
                      893: branch 0 taken
                     1627: branch 1 taken
     581             2520:   if (Lang.CPlusPlus)
     582              893:     AddDefaultCPlusPlusIncludePaths(triple);
     583                 : 
     584             2520:   AddDefaultCIncludePaths(triple);
     585                 : 
     586                 :   // Add the default framework include paths on Darwin.
                      300: branch 1 taken
                     2220: branch 2 taken
     587             2520:   if (triple.getOS() == llvm::Triple::Darwin) {
     588              300:     AddPath("/System/Library/Frameworks", System, true, false, true);
     589              300:     AddPath("/Library/Frameworks", System, true, false, true);
     590                 :   }
     591             2520: }
     592                 : 
     593                 : /// RemoveDuplicates - If there are duplicate directory entries in the specified
     594                 : /// search list, remove the later (dead) ones.
     595                 : static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
     596             5040:                              bool Verbose) {
     597             5040:   llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
     598             5040:   llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
     599             5040:   llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
                    16253: branch 1 taken
                     5040: branch 2 taken
     600            21293:   for (unsigned i = 0; i != SearchList.size(); ++i) {
     601            16253:     unsigned DirToRemove = i;
     602                 : 
     603            16253:     const DirectoryLookup &CurEntry = SearchList[i];
     604                 : 
                    16253: branch 1 taken
                        0: branch 2 not taken
     605            16253:     if (CurEntry.isNormalDir()) {
     606                 :       // If this isn't the first time we've seen this dir, remove it.
                     9932: branch 2 taken
                     6321: branch 3 taken
     607            16253:       if (SeenDirs.insert(CurEntry.getDir()))
     608             9932:         continue;
                        0: branch 1 not taken
                        0: branch 2 not taken
     609                0:     } else if (CurEntry.isFramework()) {
     610                 :       // If this isn't the first time we've seen this framework dir, remove it.
                        0: branch 2 not taken
                        0: branch 3 not taken
     611                0:       if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()))
     612                0:         continue;
     613                 :     } else {
                        0: branch 1 not taken
                        0: branch 2 not taken
     614                0:       assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
     615                 :       // If this isn't the first time we've seen this headermap, remove it.
                        0: branch 2 not taken
                        0: branch 3 not taken
     616                0:       if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()))
     617                0:         continue;
     618                 :     }
     619                 : 
     620                 :     // If we have a normal #include dir/framework/headermap that is shadowed
     621                 :     // later in the chain by a system include location, we actually want to
     622                 :     // ignore the user's request and drop the user dir... keeping the system
     623                 :     // dir.  This is weird, but required to emulate GCC's search path correctly.
     624                 :     //
     625                 :     // Since dupes of system dirs are rare, just rescan to find the original
     626                 :     // that we're nuking instead of using a DenseMap.
                     6321: branch 1 taken
                        0: branch 2 not taken
     627             6321:     if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
     628                 :       // Find the dir that this is the same of.
     629                 :       unsigned FirstDir;
     630            15801:       for (FirstDir = 0; ; ++FirstDir) {
                        0: branch 0 not taken
                    15801: branch 1 taken
     631            15801:         assert(FirstDir != i && "Didn't find dupe?");
     632                 : 
     633            15801:         const DirectoryLookup &SearchEntry = SearchList[FirstDir];
     634                 : 
     635                 :         // If these are different lookup types, then they can't be the dupe.
                        0: branch 2 not taken
                    15801: branch 3 taken
     636            15801:         if (SearchEntry.getLookupType() != CurEntry.getLookupType())
     637                0:           continue;
     638                 : 
     639                 :         bool isSame;
                    15801: branch 1 taken
                        0: branch 2 not taken
     640            15801:         if (CurEntry.isNormalDir())
     641            15801:           isSame = SearchEntry.getDir() == CurEntry.getDir();
                        0: branch 1 not taken
                        0: branch 2 not taken
     642                0:         else if (CurEntry.isFramework())
     643                0:           isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
     644                 :         else {
                        0: branch 1 not taken
                        0: branch 2 not taken
     645                0:           assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
     646                0:           isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
     647                 :         }
     648                 : 
                     9480: branch 0 taken
                     6321: branch 1 taken
     649            15801:         if (isSame)
     650             6321:           break;
     651                 :       }
     652                 : 
     653                 :       // If the first dir in the search path is a non-system dir, zap it
     654                 :       // instead of the system one.
                        1: branch 2 taken
                     6320: branch 3 taken
     655             6321:       if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
     656                1:         DirToRemove = FirstDir;
     657                 :     }
     658                 : 
                        0: branch 0 not taken
                     6321: branch 1 taken
     659             6321:     if (Verbose) {
     660                 :       llvm::errs() << "ignoring duplicate directory \""
     661                0:                    << CurEntry.getName() << "\"\n";
                        0: branch 0 not taken
                        0: branch 1 not taken
     662                0:       if (DirToRemove != i)
     663                 :         llvm::errs() << "  as it is a non-system directory that duplicates "
     664                0:                      << "a system directory\n";
     665                 :     }
     666                 : 
     667                 :     // This is reached if the current entry is a duplicate.  Remove the
     668                 :     // DirToRemove (usually the current dir).
     669             6321:     SearchList.erase(SearchList.begin()+DirToRemove);
     670             6321:     --i;
     671             5040:   }
     672             5040: }
     673                 : 
     674                 : 
     675             2520: void InitHeaderSearch::Realize() {
     676                 :   // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
     677             2520:   std::vector<DirectoryLookup> SearchList;
     678             2520:   SearchList = IncludeGroup[Angled];
     679                 :   SearchList.insert(SearchList.end(), IncludeGroup[System].begin(),
     680             2520:                     IncludeGroup[System].end());
     681                 :   SearchList.insert(SearchList.end(), IncludeGroup[After].begin(),
     682             2520:                     IncludeGroup[After].end());
     683             2520:   RemoveDuplicates(SearchList, Verbose);
     684             2520:   RemoveDuplicates(IncludeGroup[Quoted], Verbose);
     685                 : 
     686                 :   // Prepend QUOTED list on the search list.
     687                 :   SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(),
     688             2520:                     IncludeGroup[Quoted].end());
     689                 : 
     690                 : 
     691             2520:   bool DontSearchCurDir = false;  // TODO: set to true if -I- is set?
     692                 :   Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(),
     693             2520:                          DontSearchCurDir);
     694                 : 
     695                 :   // If verbose, print the list of directories that will be searched.
                        1: branch 0 taken
                     2519: branch 1 taken
     696             2520:   if (Verbose) {
     697                1:     llvm::errs() << "#include \"...\" search starts here:\n";
     698                1:     unsigned QuotedIdx = IncludeGroup[Quoted].size();
                        3: branch 1 taken
                        1: branch 2 taken
     699                4:     for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
                        1: branch 0 taken
                        2: branch 1 taken
     700                3:       if (i == QuotedIdx)
     701                1:         llvm::errs() << "#include <...> search starts here:\n";
     702                3:       const char *Name = SearchList[i].getName();
     703                 :       const char *Suffix;
                        3: branch 2 taken
                        0: branch 3 not taken
     704                3:       if (SearchList[i].isNormalDir())
     705                3:         Suffix = "";
                        0: branch 2 not taken
                        0: branch 3 not taken
     706                0:       else if (SearchList[i].isFramework())
     707                0:         Suffix = " (framework directory)";
     708                 :       else {
                        0: branch 2 not taken
                        0: branch 3 not taken
     709                0:         assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
     710                0:         Suffix = " (headermap)";
     711                 :       }
     712                3:       llvm::errs() << " " << Name << Suffix << "\n";
     713                 :     }
     714                1:     llvm::errs() << "End of search list.\n";
     715             2520:   }
     716             2520: }
     717                 : 
     718                 : void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
     719                 :                                      const HeaderSearchOptions &HSOpts,
     720                 :                                      const LangOptions &Lang,
     721             2520:                                      const llvm::Triple &Triple) {
     722             2520:   InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot);
     723                 : 
     724                 :   // Add the user defined entries.
                        5: branch 1 taken
                     2520: branch 2 taken
     725             2525:   for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
     726                5:     const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
     727                 :     Init.AddPath(E.Path, E.Group, false, E.IsUserSupplied, E.IsFramework,
     728                5:                  false);
     729                 :   }
     730                 : 
     731                 :   // Add entries from CPATH and friends.
     732             2520:   Init.AddDelimitedPaths(HSOpts.EnvIncPath);
                      893: branch 0 taken
                     1627: branch 1 taken
                       38: branch 2 taken
                      855: branch 3 taken
     733             2558:   if (Lang.CPlusPlus && Lang.ObjC1)
     734               38:     Init.AddDelimitedPaths(HSOpts.ObjCXXEnvIncPath);
                      855: branch 0 taken
                     1627: branch 1 taken
     735             2482:   else if (Lang.CPlusPlus)
     736              855:     Init.AddDelimitedPaths(HSOpts.CXXEnvIncPath);
                      607: branch 0 taken
                     1020: branch 1 taken
     737             1627:   else if (Lang.ObjC1)
     738              607:     Init.AddDelimitedPaths(HSOpts.ObjCEnvIncPath);
     739                 :   else
     740             1020:     Init.AddDelimitedPaths(HSOpts.CEnvIncPath);
     741                 : 
                     2520: branch 0 taken
                        0: branch 1 not taken
     742             2520:   if (HSOpts.UseBuiltinIncludes) {
     743                 :     // Ignore the sys root, we *always* look for clang headers relative to
     744                 :     // supplied path.
     745             2520:     llvm::sys::Path P(HSOpts.ResourceDir);
     746             2520:     P.appendComponent("include");
     747             2520:     Init.AddPath(P.str(), System, false, false, false, /*IgnoreSysRoot=*/ true);
     748                 :   }
     749                 : 
                     2520: branch 0 taken
                        0: branch 1 not taken
     750             2520:   if (HSOpts.UseStandardIncludes)
     751             2520:     Init.AddDefaultSystemIncludePaths(Lang, Triple);
     752                 : 
     753             2520:   Init.Realize();
     754             2520: }

Generated: 2010-02-10 01:31 by zcov