InitHeaderSearch.cpp revision d944a9b7a680be2ce74aa9398e0604fdebf0338a
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#ifdef HAVE_CLANG_CONFIG_H
15# include "clang/Config/config.h"
16#endif
17
18#include "clang/Frontend/Utils.h"
19#include "clang/Basic/FileManager.h"
20#include "clang/Basic/LangOptions.h"
21#include "clang/Frontend/HeaderSearchOptions.h"
22#include "clang/Lex/HeaderSearch.h"
23#include "llvm/ADT/SmallString.h"
24#include "llvm/ADT/SmallPtrSet.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringExtras.h"
27#include "llvm/ADT/Triple.h"
28#include "llvm/ADT/Twine.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/Support/Path.h"
31#include "llvm/Config/config.h"
32#ifdef _MSC_VER
33  #define WIN32_LEAN_AND_MEAN 1
34  #include <windows.h>
35#endif
36using namespace clang;
37using namespace clang::frontend;
38
39namespace {
40
41/// InitHeaderSearch - This class makes it easier to set the search paths of
42///  a HeaderSearch object. InitHeaderSearch stores several search path lists
43///  internally, which can be sent to a HeaderSearch object in one swoop.
44class InitHeaderSearch {
45  std::vector<std::pair<IncludeDirGroup, DirectoryLookup> > IncludePath;
46  typedef std::vector<std::pair<IncludeDirGroup,
47                      DirectoryLookup> >::const_iterator path_iterator;
48  HeaderSearch &Headers;
49  bool Verbose;
50  std::string IncludeSysroot;
51  bool IsNotEmptyOrRoot;
52
53public:
54
55  InitHeaderSearch(HeaderSearch &HS, bool verbose, llvm::StringRef sysroot)
56    : Headers(HS), Verbose(verbose), IncludeSysroot(sysroot),
57      IsNotEmptyOrRoot(!(sysroot.empty() || sysroot == "/")) {
58  }
59
60  /// AddPath - Add the specified path to the specified group list.
61  void AddPath(const llvm::Twine &Path, IncludeDirGroup Group,
62               bool isCXXAware, bool isUserSupplied,
63               bool isFramework, bool IgnoreSysRoot = false);
64
65  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
66  ///  libstdc++.
67  void AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
68                                   llvm::StringRef ArchDir,
69                                   llvm::StringRef Dir32,
70                                   llvm::StringRef Dir64,
71                                   const llvm::Triple &triple);
72
73  /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
74  ///  libstdc++.
75  void AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
76                                     llvm::StringRef Arch,
77                                     llvm::StringRef Version);
78
79  /// AddMinGW64CXXPaths - Add the necessary paths to support
80  /// libstdc++ of x86_64-w64-mingw32 aka mingw-w64.
81  void AddMinGW64CXXPaths(llvm::StringRef Base,
82                          llvm::StringRef Version);
83
84  /// AddDelimitedPaths - Add a list of paths delimited by the system PATH
85  /// separator. The processing follows that of the CPATH variable for gcc.
86  void AddDelimitedPaths(llvm::StringRef String);
87
88  // AddDefaultCIncludePaths - Add paths that should always be searched.
89  void AddDefaultCIncludePaths(const llvm::Triple &triple,
90                               const HeaderSearchOptions &HSOpts);
91
92  // AddDefaultCPlusPlusIncludePaths -  Add paths that should be searched when
93  //  compiling c++.
94  void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple,
95                                       const HeaderSearchOptions &HSOpts);
96
97  /// AddDefaultSystemIncludePaths - Adds the default system include paths so
98  ///  that e.g. stdio.h is found.
99  void AddDefaultSystemIncludePaths(const LangOptions &Lang,
100                                    const llvm::Triple &triple,
101                                    const HeaderSearchOptions &HSOpts);
102
103  /// Realize - Merges all search path lists into one list and send it to
104  /// HeaderSearch.
105  void Realize(const LangOptions &Lang);
106};
107
108}  // end anonymous namespace.
109
110void InitHeaderSearch::AddPath(const llvm::Twine &Path,
111                               IncludeDirGroup Group, bool isCXXAware,
112                               bool isUserSupplied, bool isFramework,
113                               bool IgnoreSysRoot) {
114  assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
115  FileManager &FM = Headers.getFileMgr();
116
117  // Compute the actual path, taking into consideration -isysroot.
118  llvm::SmallString<256> MappedPathStorage;
119  llvm::StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
120
121  // Handle isysroot.
122  if ((Group == System || Group == CXXSystem) && !IgnoreSysRoot &&
123#if defined(_WIN32)
124      !MappedPathStr.empty() &&
125      llvm::sys::path::is_separator(MappedPathStr[0]) &&
126#else
127      llvm::sys::path::is_absolute(MappedPathStr) &&
128#endif
129      IsNotEmptyOrRoot) {
130    MappedPathStorage.clear();
131    MappedPathStr =
132      (IncludeSysroot + Path).toStringRef(MappedPathStorage);
133  }
134
135  // Compute the DirectoryLookup type.
136  SrcMgr::CharacteristicKind Type;
137  if (Group == Quoted || Group == Angled)
138    Type = SrcMgr::C_User;
139  else if (isCXXAware)
140    Type = SrcMgr::C_System;
141  else
142    Type = SrcMgr::C_ExternCSystem;
143
144
145  // If the directory exists, add it.
146  if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) {
147    IncludePath.push_back(std::make_pair(Group, DirectoryLookup(DE, Type,
148                          isUserSupplied, isFramework)));
149    return;
150  }
151
152  // Check to see if this is an apple-style headermap (which are not allowed to
153  // be frameworks).
154  if (!isFramework) {
155    if (const FileEntry *FE = FM.getFile(MappedPathStr)) {
156      if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
157        // It is a headermap, add it to the search path.
158        IncludePath.push_back(std::make_pair(Group, DirectoryLookup(HM, Type,
159                              isUserSupplied)));
160        return;
161      }
162    }
163  }
164
165  if (Verbose)
166    llvm::errs() << "ignoring nonexistent directory \""
167                 << MappedPathStr << "\"\n";
168}
169
170
171void InitHeaderSearch::AddDelimitedPaths(llvm::StringRef at) {
172  if (at.empty()) // Empty string should not add '.' path.
173    return;
174
175  llvm::StringRef::size_type delim;
176  while ((delim = at.find(llvm::sys::PathSeparator)) != llvm::StringRef::npos) {
177    if (delim == 0)
178      AddPath(".", Angled, false, true, false);
179    else
180      AddPath(at.substr(0, delim), Angled, false, true, false);
181    at = at.substr(delim + 1);
182  }
183
184  if (at.empty())
185    AddPath(".", Angled, false, true, false);
186  else
187    AddPath(at, Angled, false, true, false);
188}
189
190void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
191                                                   llvm::StringRef ArchDir,
192                                                   llvm::StringRef Dir32,
193                                                   llvm::StringRef Dir64,
194                                                   const llvm::Triple &triple) {
195  // Add the base dir
196  AddPath(Base, CXXSystem, true, false, false);
197
198  // Add the multilib dirs
199  llvm::Triple::ArchType arch = triple.getArch();
200  bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
201  if (is64bit)
202    AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, true, false, false);
203  else
204    AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, true, false, false);
205
206  // Add the backward dir
207  AddPath(Base + "/backward", CXXSystem, true, false, false);
208}
209
210void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
211                                                     llvm::StringRef Arch,
212                                                     llvm::StringRef Version) {
213  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
214          CXXSystem, true, false, false);
215  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch,
216          CXXSystem, true, false, false);
217  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
218          CXXSystem, true, false, false);
219}
220
221void InitHeaderSearch::AddMinGW64CXXPaths(llvm::StringRef Base,
222                                          llvm::StringRef Version) {
223  // Assumes Base is HeaderSearchOpts' ResourceDir
224  AddPath(Base + "/../../../include/c++/" + Version,
225          CXXSystem, true, false, false);
226  AddPath(Base + "/../../../include/c++/" + Version + "/x86_64-w64-mingw32",
227          CXXSystem, true, false, false);
228  AddPath(Base + "/../../../include/c++/" + Version + "/i686-w64-mingw32",
229          CXXSystem, true, false, false);
230  AddPath(Base + "/../../../include/c++/" + Version + "/backward",
231          CXXSystem, true, false, false);
232}
233
234  // FIXME: This probably should goto to some platform utils place.
235#ifdef _MSC_VER
236
237  // Read registry string.
238  // This also supports a means to look for high-versioned keys by use
239  // of a $VERSION placeholder in the key path.
240  // $VERSION in the key path is a placeholder for the version number,
241  // causing the highest value path to be searched for and used.
242  // I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
243  // There can be additional characters in the component.  Only the numberic
244  // characters are compared.
245static bool getSystemRegistryString(const char *keyPath, const char *valueName,
246                                    char *value, size_t maxLength) {
247  HKEY hRootKey = NULL;
248  HKEY hKey = NULL;
249  const char* subKey = NULL;
250  DWORD valueType;
251  DWORD valueSize = maxLength - 1;
252  long lResult;
253  bool returnValue = false;
254
255  if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
256    hRootKey = HKEY_CLASSES_ROOT;
257    subKey = keyPath + 18;
258  } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
259    hRootKey = HKEY_USERS;
260    subKey = keyPath + 11;
261  } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
262    hRootKey = HKEY_LOCAL_MACHINE;
263    subKey = keyPath + 19;
264  } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
265    hRootKey = HKEY_CURRENT_USER;
266    subKey = keyPath + 18;
267  }
268  else
269    return false;
270
271  const char *placeHolder = strstr(subKey, "$VERSION");
272  char bestName[256];
273  bestName[0] = '\0';
274  // If we have a $VERSION placeholder, do the highest-version search.
275  if (placeHolder) {
276    const char *keyEnd = placeHolder - 1;
277    const char *nextKey = placeHolder;
278    // Find end of previous key.
279    while ((keyEnd > subKey) && (*keyEnd != '\\'))
280      keyEnd--;
281    // Find end of key containing $VERSION.
282    while (*nextKey && (*nextKey != '\\'))
283      nextKey++;
284    size_t partialKeyLength = keyEnd - subKey;
285    char partialKey[256];
286    if (partialKeyLength > sizeof(partialKey))
287      partialKeyLength = sizeof(partialKey);
288    strncpy(partialKey, subKey, partialKeyLength);
289    partialKey[partialKeyLength] = '\0';
290    HKEY hTopKey = NULL;
291    lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
292    if (lResult == ERROR_SUCCESS) {
293      char keyName[256];
294      int bestIndex = -1;
295      double bestValue = 0.0;
296      DWORD index, size = sizeof(keyName) - 1;
297      for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
298          NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
299        const char *sp = keyName;
300        while (*sp && !isdigit(*sp))
301          sp++;
302        if (!*sp)
303          continue;
304        const char *ep = sp + 1;
305        while (*ep && (isdigit(*ep) || (*ep == '.')))
306          ep++;
307        char numBuf[32];
308        strncpy(numBuf, sp, sizeof(numBuf) - 1);
309        numBuf[sizeof(numBuf) - 1] = '\0';
310        double value = strtod(numBuf, NULL);
311        if (value > bestValue) {
312          bestIndex = (int)index;
313          bestValue = value;
314          strcpy(bestName, keyName);
315        }
316        size = sizeof(keyName) - 1;
317      }
318      // If we found the highest versioned key, open the key and get the value.
319      if (bestIndex != -1) {
320        // Append rest of key.
321        strncat(bestName, nextKey, sizeof(bestName) - 1);
322        bestName[sizeof(bestName) - 1] = '\0';
323        // Open the chosen key path remainder.
324        lResult = RegOpenKeyEx(hTopKey, bestName, 0, KEY_READ, &hKey);
325        if (lResult == ERROR_SUCCESS) {
326          lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
327            (LPBYTE)value, &valueSize);
328          if (lResult == ERROR_SUCCESS)
329            returnValue = true;
330          RegCloseKey(hKey);
331        }
332      }
333      RegCloseKey(hTopKey);
334    }
335  }
336  else {
337    lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
338    if (lResult == ERROR_SUCCESS) {
339      lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
340        (LPBYTE)value, &valueSize);
341      if (lResult == ERROR_SUCCESS)
342        returnValue = true;
343      RegCloseKey(hKey);
344    }
345  }
346  return returnValue;
347}
348#else // _MSC_VER
349  // Read registry string.
350static bool getSystemRegistryString(const char*, const char*, char*, size_t) {
351  return(false);
352}
353#endif // _MSC_VER
354
355  // Get Visual Studio installation directory.
356static bool getVisualStudioDir(std::string &path) {
357  // First check the environment variables that vsvars32.bat sets.
358  const char* vcinstalldir = getenv("VCINSTALLDIR");
359  if (vcinstalldir) {
360    char *p = const_cast<char *>(strstr(vcinstalldir, "\\VC"));
361    if (p)
362      *p = '\0';
363    path = vcinstalldir;
364    return true;
365  }
366
367  char vsIDEInstallDir[256];
368  char vsExpressIDEInstallDir[256];
369  // Then try the windows registry.
370  bool hasVCDir = getSystemRegistryString(
371    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
372    "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
373  bool hasVCExpressDir = getSystemRegistryString(
374    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
375    "InstallDir", vsExpressIDEInstallDir, sizeof(vsExpressIDEInstallDir) - 1);
376    // If we have both vc80 and vc90, pick version we were compiled with.
377  if (hasVCDir && vsIDEInstallDir[0]) {
378    char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
379    if (p)
380      *p = '\0';
381    path = vsIDEInstallDir;
382    return true;
383  }
384
385  if (hasVCExpressDir && vsExpressIDEInstallDir[0]) {
386    char *p = (char*)strstr(vsExpressIDEInstallDir, "\\Common7\\IDE");
387    if (p)
388      *p = '\0';
389    path = vsExpressIDEInstallDir;
390    return true;
391  }
392
393  // Try the environment.
394  const char *vs100comntools = getenv("VS100COMNTOOLS");
395  const char *vs90comntools = getenv("VS90COMNTOOLS");
396  const char *vs80comntools = getenv("VS80COMNTOOLS");
397  const char *vscomntools = NULL;
398
399  // Try to find the version that we were compiled with
400  if(false) {}
401  #if (_MSC_VER >= 1600)  // VC100
402  else if(vs100comntools) {
403    vscomntools = vs100comntools;
404  }
405  #elif (_MSC_VER == 1500) // VC80
406  else if(vs90comntools) {
407    vscomntools = vs90comntools;
408  }
409  #elif (_MSC_VER == 1400) // VC80
410  else if(vs80comntools) {
411    vscomntools = vs80comntools;
412  }
413  #endif
414  // Otherwise find any version we can
415  else if (vs100comntools)
416    vscomntools = vs100comntools;
417  else if (vs90comntools)
418    vscomntools = vs90comntools;
419  else if (vs80comntools)
420    vscomntools = vs80comntools;
421
422  if (vscomntools && *vscomntools) {
423    char *p = const_cast<char *>(strstr(vscomntools, "\\Common7\\Tools"));
424    if (p)
425      *p = '\0';
426    path = vscomntools;
427    return true;
428  }
429  return false;
430}
431
432  // Get Windows SDK installation directory.
433static bool getWindowsSDKDir(std::string &path) {
434  char windowsSDKInstallDir[256];
435  // Try the Windows registry.
436  bool hasSDKDir = getSystemRegistryString(
437   "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
438                                           "InstallationFolder",
439                                           windowsSDKInstallDir,
440                                           sizeof(windowsSDKInstallDir) - 1);
441    // If we have both vc80 and vc90, pick version we were compiled with.
442  if (hasSDKDir && windowsSDKInstallDir[0]) {
443    path = windowsSDKInstallDir;
444    return(true);
445  }
446  return(false);
447}
448
449void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
450                                            const HeaderSearchOptions &HSOpts) {
451  llvm::Triple::OSType os = triple.getOS();
452
453  switch (os) {
454  case llvm::Triple::FreeBSD:
455  case llvm::Triple::NetBSD:
456    break;
457  default:
458    // FIXME: temporary hack: hard-coded paths.
459    AddPath("/usr/local/include", System, true, false, false);
460    break;
461  }
462
463  // Builtin includes use #include_next directives and should be positioned
464  // just prior C include dirs.
465  if (HSOpts.UseBuiltinIncludes) {
466    // Ignore the sys root, we *always* look for clang headers relative to
467    // supplied path.
468    llvm::sys::Path P(HSOpts.ResourceDir);
469    P.appendComponent("include");
470    AddPath(P.str(), System, false, false, false, /*IgnoreSysRoot=*/ true);
471  }
472
473  // Add dirs specified via 'configure --with-c-include-dirs'.
474  llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
475  if (CIncludeDirs != "") {
476    llvm::SmallVector<llvm::StringRef, 5> dirs;
477    CIncludeDirs.split(dirs, ":");
478    for (llvm::SmallVectorImpl<llvm::StringRef>::iterator i = dirs.begin();
479         i != dirs.end();
480         ++i)
481      AddPath(*i, System, false, false, false);
482    return;
483  }
484
485  switch (os) {
486  case llvm::Triple::Win32: {
487    std::string VSDir;
488    std::string WindowsSDKDir;
489    if (getVisualStudioDir(VSDir)) {
490      AddPath(VSDir + "\\VC\\include", System, false, false, false);
491      if (getWindowsSDKDir(WindowsSDKDir))
492        AddPath(WindowsSDKDir + "\\include", System, false, false, false);
493      else
494        AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
495                System, false, false, false);
496    } else {
497      // Default install paths.
498      AddPath("C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
499              System, false, false, false);
500      AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
501              System, false, false, false);
502      AddPath(
503        "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
504        System, false, false, false);
505      AddPath("C:/Program Files/Microsoft Visual Studio 8/VC/include",
506              System, false, false, false);
507      AddPath(
508        "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include",
509        System, false, false, false);
510    }
511    break;
512  }
513  case llvm::Triple::Haiku:
514    AddPath("/boot/common/include", System, true, false, false);
515    AddPath("/boot/develop/headers/os", System, true, false, false);
516    AddPath("/boot/develop/headers/os/app", System, true, false, false);
517    AddPath("/boot/develop/headers/os/arch", System, true, false, false);
518    AddPath("/boot/develop/headers/os/device", System, true, false, false);
519    AddPath("/boot/develop/headers/os/drivers", System, true, false, false);
520    AddPath("/boot/develop/headers/os/game", System, true, false, false);
521    AddPath("/boot/develop/headers/os/interface", System, true, false, false);
522    AddPath("/boot/develop/headers/os/kernel", System, true, false, false);
523    AddPath("/boot/develop/headers/os/locale", System, true, false, false);
524    AddPath("/boot/develop/headers/os/mail", System, true, false, false);
525    AddPath("/boot/develop/headers/os/media", System, true, false, false);
526    AddPath("/boot/develop/headers/os/midi", System, true, false, false);
527    AddPath("/boot/develop/headers/os/midi2", System, true, false, false);
528    AddPath("/boot/develop/headers/os/net", System, true, false, false);
529    AddPath("/boot/develop/headers/os/storage", System, true, false, false);
530    AddPath("/boot/develop/headers/os/support", System, true, false, false);
531    AddPath("/boot/develop/headers/os/translation",
532      System, true, false, false);
533    AddPath("/boot/develop/headers/os/add-ons/graphics",
534      System, true, false, false);
535    AddPath("/boot/develop/headers/os/add-ons/input_server",
536      System, true, false, false);
537    AddPath("/boot/develop/headers/os/add-ons/screen_saver",
538      System, true, false, false);
539    AddPath("/boot/develop/headers/os/add-ons/tracker",
540      System, true, false, false);
541    AddPath("/boot/develop/headers/os/be_apps/Deskbar",
542      System, true, false, false);
543    AddPath("/boot/develop/headers/os/be_apps/NetPositive",
544      System, true, false, false);
545    AddPath("/boot/develop/headers/os/be_apps/Tracker",
546      System, true, false, false);
547    AddPath("/boot/develop/headers/cpp", System, true, false, false);
548    AddPath("/boot/develop/headers/cpp/i586-pc-haiku",
549      System, true, false, false);
550    AddPath("/boot/develop/headers/3rdparty", System, true, false, false);
551    AddPath("/boot/develop/headers/bsd", System, true, false, false);
552    AddPath("/boot/develop/headers/glibc", System, true, false, false);
553    AddPath("/boot/develop/headers/posix", System, true, false, false);
554    AddPath("/boot/develop/headers",  System, true, false, false);
555    break;
556  case llvm::Triple::Cygwin:
557    AddPath("/usr/include/w32api", System, true, false, false);
558    break;
559  case llvm::Triple::MinGW32: {
560      // mingw-w64 crt include paths
561      llvm::sys::Path P(HSOpts.ResourceDir);
562      P.appendComponent("../../../i686-w64-mingw32/include"); // <sysroot>/i686-w64-mingw32/include
563      AddPath(P.str(), System, true, false, false);
564      P = llvm::sys::Path(HSOpts.ResourceDir);
565      P.appendComponent("../../../x86_64-w64-mingw32/include"); // <sysroot>/x86_64-w64-mingw32/include
566      AddPath(P.str(), System, true, false, false);
567      // mingw.org crt include paths
568      P = llvm::sys::Path(HSOpts.ResourceDir);
569      P.appendComponent("../../../include"); // <sysroot>/include
570      AddPath(P.str(), System, true, false, false);
571      AddPath("/mingw/include", System, true, false, false);
572      AddPath("c:/mingw/include", System, true, false, false);
573    }
574    break;
575
576  case llvm::Triple::Linux:
577    // Generic Debian multiarch support:
578    if (triple.getArch() == llvm::Triple::x86_64) {
579      AddPath("/usr/include/x86_64-linux-gnu", System, false, false, false);
580      AddPath("/usr/include/i686-linux-gnu/64", System, false, false, false);
581      AddPath("/usr/include/i486-linux-gnu/64", System, false, false, false);
582    } else if (triple.getArch() == llvm::Triple::x86) {
583      AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false);
584      AddPath("/usr/include/i686-linux-gnu", System, false, false, false);
585      AddPath("/usr/include/i486-linux-gnu", System, false, false, false);
586    } else if (triple.getArch() == llvm::Triple::arm) {
587      AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false);
588    }
589  default:
590    break;
591  }
592
593  AddPath("/usr/include", System, false, false, false);
594}
595
596void InitHeaderSearch::
597AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {
598  llvm::Triple::OSType os = triple.getOS();
599  llvm::StringRef CxxIncludeRoot(CXX_INCLUDE_ROOT);
600  if (CxxIncludeRoot != "") {
601    llvm::StringRef CxxIncludeArch(CXX_INCLUDE_ARCH);
602    if (CxxIncludeArch == "")
603      AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, triple.str().c_str(),
604                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR,
605                                  triple);
606    else
607      AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, CXX_INCLUDE_ARCH,
608                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR,
609                                  triple);
610    return;
611  }
612  // FIXME: temporary hack: hard-coded paths.
613
614  if (triple.isOSDarwin()) {
615    switch (triple.getArch()) {
616    default: break;
617
618    case llvm::Triple::ppc:
619    case llvm::Triple::ppc64:
620      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
621                                  "powerpc-apple-darwin10", "", "ppc64",
622                                  triple);
623      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
624                                  "powerpc-apple-darwin10", "", "ppc64",
625                                  triple);
626      break;
627
628    case llvm::Triple::x86:
629    case llvm::Triple::x86_64:
630      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
631                                  "i686-apple-darwin10", "", "x86_64", triple);
632      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
633                                  "i686-apple-darwin8", "", "", triple);
634      break;
635
636    case llvm::Triple::arm:
637    case llvm::Triple::thumb:
638      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
639                                  "arm-apple-darwin10", "v7", "", triple);
640      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
641                                  "arm-apple-darwin10", "v6", "", triple);
642      break;
643    }
644    return;
645  }
646
647  switch (os) {
648  case llvm::Triple::Cygwin:
649    // Cygwin-1.7
650    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
651    // g++-4 / Cygwin-1.5
652    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
653    // FIXME: Do we support g++-3.4.4?
654    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "3.4.4");
655    break;
656  case llvm::Triple::MinGW32:
657    // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32)
658    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0");
659    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1");
660    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2");
661    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3");
662    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0");
663    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1");
664    // mingw.org C++ include paths
665    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
666    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
667    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
668    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
669    break;
670  case llvm::Triple::DragonFly:
671    AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false);
672    break;
673  case llvm::Triple::Linux:
674    //===------------------------------------------------------------------===//
675    // Debian based distros.
676    // Note: these distros symlink /usr/include/c++/X.Y.Z -> X.Y
677    //===------------------------------------------------------------------===//
678
679    // Ubuntu 11.11 "Oneiric Ocelot" -- gcc-4.6.0
680    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
681                                "x86_64-linux-gnu", "32", "", triple);
682    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
683                                "i686-linux-gnu", "", "64", triple);
684    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
685                                "i486-linux-gnu", "", "64", triple);
686    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
687                                "arm-linux-gnueabi", "", "", triple);
688
689    // Ubuntu 11.04 "Natty Narwhal" -- gcc-4.5.2
690    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
691                                "x86_64-linux-gnu", "32", "", triple);
692    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
693                                "i686-linux-gnu", "", "64", triple);
694    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
695                                "i486-linux-gnu", "", "64", triple);
696    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
697                                "arm-linux-gnueabi", "", "", triple);
698
699    // Ubuntu 10.10 "Maverick Meerkat" -- gcc-4.4.5
700    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
701                                "i686-linux-gnu", "", "64", triple);
702    // The rest of 10.10 is the same as previous versions.
703
704    // Ubuntu 10.04 LTS "Lucid Lynx" -- gcc-4.4.3
705    // Ubuntu 9.10 "Karmic Koala"    -- gcc-4.4.1
706    // Debian 6.0 "squeeze"          -- gcc-4.4.2
707    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
708                                "x86_64-linux-gnu", "32", "", triple);
709    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
710                                "i486-linux-gnu", "", "64", triple);
711    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
712                                "arm-linux-gnueabi", "", "", triple);
713    // Ubuntu 9.04 "Jaunty Jackalope" -- gcc-4.3.3
714    // Ubuntu 8.10 "Intrepid Ibex"    -- gcc-4.3.2
715    // Debian 5.0 "lenny"             -- gcc-4.3.2
716    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
717                                "x86_64-linux-gnu", "32", "", triple);
718    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
719                                "i486-linux-gnu", "", "64", triple);
720    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
721                                "arm-linux-gnueabi", "", "", triple);
722    // Ubuntu 8.04.4 LTS "Hardy Heron"     -- gcc-4.2.4
723    // Ubuntu 8.04.[0-3] LTS "Hardy Heron" -- gcc-4.2.3
724    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
725                                "x86_64-linux-gnu", "32", "", triple);
726    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
727                                "i486-linux-gnu", "", "64", triple);
728    // Ubuntu 7.10 "Gutsy Gibbon" -- gcc-4.1.3
729    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
730                                "x86_64-linux-gnu", "32", "", triple);
731    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
732                                "i486-linux-gnu", "", "64", triple);
733
734    //===------------------------------------------------------------------===//
735    // Redhat based distros.
736    //===------------------------------------------------------------------===//
737    // Fedora 15
738    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
739                                "x86_64-redhat-linux", "32", "", triple);
740    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
741                                "i686-redhat-linux", "", "", triple);
742    // Fedora 14
743    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1",
744                                "x86_64-redhat-linux", "32", "", triple);
745    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1",
746                                "i686-redhat-linux", "", "", triple);
747    // RHEL5(gcc44)
748    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
749                                "x86_64-redhat-linux6E", "32", "", triple);
750    // Fedora 13
751    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
752                                "x86_64-redhat-linux", "32", "", triple);
753    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
754                                "i686-redhat-linux","", "", triple);
755    // Fedora 12
756    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
757                                "x86_64-redhat-linux", "32", "", triple);
758    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
759                                "i686-redhat-linux","", "", triple);
760    // Fedora 12 (pre-FEB-2010)
761    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
762                                "x86_64-redhat-linux", "32", "", triple);
763    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
764                                "i686-redhat-linux","", "", triple);
765    // Fedora 11
766    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
767                                "x86_64-redhat-linux", "32", "", triple);
768    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
769                                "i586-redhat-linux","", "", triple);
770    // Fedora 10
771    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
772                                "x86_64-redhat-linux", "32", "", triple);
773    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
774                                "i386-redhat-linux","", "", triple);
775    // Fedora 9
776    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
777                                "x86_64-redhat-linux", "32", "", triple);
778    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
779                                "i386-redhat-linux", "", "", triple);
780    // Fedora 8
781    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
782                                "x86_64-redhat-linux", "", "", triple);
783    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
784                                "i386-redhat-linux", "", "", triple);
785
786    // RHEL 5
787    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1",
788                                "x86_64-redhat-linux", "32", "", triple);
789    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1",
790                                "i386-redhat-linux", "", "", triple);
791
792
793    //===------------------------------------------------------------------===//
794
795    // Exherbo (2010-01-25)
796    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
797                                "x86_64-pc-linux-gnu", "32", "", triple);
798    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
799                                "i686-pc-linux-gnu", "", "", triple);
800
801    // openSUSE 11.1 32 bit
802    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
803                                "i586-suse-linux", "", "", triple);
804    // openSUSE 11.1 64 bit
805    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
806                                "x86_64-suse-linux", "32", "", triple);
807    // openSUSE 11.2
808    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
809                                "i586-suse-linux", "", "", triple);
810    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
811                                "x86_64-suse-linux", "", "", triple);
812
813    // openSUSE 11.4
814    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
815                                "i586-suse-linux", "", "", triple);
816    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
817                                "x86_64-suse-linux", "", "", triple);
818
819    // openSUSE 12.1
820    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
821                                "i586-suse-linux", "", "", triple);
822    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
823                                "x86_64-suse-linux", "", "", triple);
824    // Arch Linux 2008-06-24
825    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
826                                "i686-pc-linux-gnu", "", "", triple);
827    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
828                                "x86_64-unknown-linux-gnu", "", "", triple);
829
830    // Arch Linux gcc 4.6
831    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
832                                "i686-pc-linux-gnu", "", "", triple);
833    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
834                                "x86_64-unknown-linux-gnu", "", "", triple);
835
836    // Gentoo x86 gcc 4.5.2
837    AddGnuCPlusPlusIncludePaths(
838      "/usr/lib/gcc/i686-pc-linux-gnu/4.5.2/include/g++-v4",
839      "i686-pc-linux-gnu", "", "", triple);
840    // Gentoo x86 gcc 4.4.5
841    AddGnuCPlusPlusIncludePaths(
842      "/usr/lib/gcc/i686-pc-linux-gnu/4.4.5/include/g++-v4",
843      "i686-pc-linux-gnu", "", "", triple);
844    // Gentoo x86 gcc 4.4.4
845    AddGnuCPlusPlusIncludePaths(
846      "/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include/g++-v4",
847      "i686-pc-linux-gnu", "", "", triple);
848   // Gentoo x86 2010.0 stable
849    AddGnuCPlusPlusIncludePaths(
850      "/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include/g++-v4",
851      "i686-pc-linux-gnu", "", "", triple);
852    // Gentoo x86 2009.1 stable
853    AddGnuCPlusPlusIncludePaths(
854      "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4",
855      "i686-pc-linux-gnu", "", "", triple);
856    // Gentoo x86 2009.0 stable
857    AddGnuCPlusPlusIncludePaths(
858      "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4",
859      "i686-pc-linux-gnu", "", "", triple);
860    // Gentoo x86 2008.0 stable
861    AddGnuCPlusPlusIncludePaths(
862      "/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4",
863      "i686-pc-linux-gnu", "", "", triple);
864    // Gentoo x86 llvm-gcc trunk
865    AddGnuCPlusPlusIncludePaths(
866        "/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
867        "i686-pc-linux-gnu", "", "", triple);
868
869    // Gentoo amd64 gcc 4.5.2
870    AddGnuCPlusPlusIncludePaths(
871        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4",
872        "x86_64-pc-linux-gnu", "32", "", triple);
873    // Gentoo amd64 gcc 4.4.5
874    AddGnuCPlusPlusIncludePaths(
875        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4",
876        "x86_64-pc-linux-gnu", "32", "", triple);
877    // Gentoo amd64 gcc 4.4.4
878    AddGnuCPlusPlusIncludePaths(
879        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4",
880        "x86_64-pc-linux-gnu", "32", "", triple);
881    // Gentoo amd64 gcc 4.4.3
882    AddGnuCPlusPlusIncludePaths(
883        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4",
884        "x86_64-pc-linux-gnu", "32", "", triple);
885    // Gentoo amd64 gcc 4.3.2
886    AddGnuCPlusPlusIncludePaths(
887        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.2/include/g++-v4",
888        "x86_64-pc-linux-gnu", "", "", triple);
889    // Gentoo amd64 stable
890    AddGnuCPlusPlusIncludePaths(
891        "/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4",
892        "x86_64-pc-linux-gnu", "", "", triple);
893
894    // Gentoo amd64 llvm-gcc trunk
895    AddGnuCPlusPlusIncludePaths(
896        "/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
897        "x86_64-pc-linux-gnu", "", "", triple);
898
899    break;
900  case llvm::Triple::FreeBSD:
901    // FreeBSD 8.0
902    // FreeBSD 7.3
903    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
904    break;
905  case llvm::Triple::NetBSD:
906    AddGnuCPlusPlusIncludePaths("/usr/include/g++", "", "", "", triple);
907    break;
908  case llvm::Triple::OpenBSD: {
909    std::string t = triple.getTriple();
910    if (t.substr(0, 6) == "x86_64")
911      t.replace(0, 6, "amd64");
912    AddGnuCPlusPlusIncludePaths("/usr/include/g++",
913                                t, "", "", triple);
914    break;
915  }
916  case llvm::Triple::Minix:
917    AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
918                                "", "", "", triple);
919    break;
920  case llvm::Triple::Solaris:
921    // Solaris - Fall though..
922  case llvm::Triple::AuroraUX:
923    // AuroraUX
924    AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4",
925                                "i386-pc-solaris2.11", "", "", triple);
926    break;
927  default:
928    break;
929  }
930}
931
932void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,
933                                                    const llvm::Triple &triple,
934                                            const HeaderSearchOptions &HSOpts) {
935  if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes) {
936    if (HSOpts.UseLibcxx)
937      AddPath("/usr/include/c++/v1", CXXSystem, true, false, false);
938    else
939      AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
940  }
941
942  AddDefaultCIncludePaths(triple, HSOpts);
943
944  // Add the default framework include paths on Darwin.
945  if (triple.isOSDarwin()) {
946    AddPath("/System/Library/Frameworks", System, true, false, true);
947    AddPath("/Library/Frameworks", System, true, false, true);
948  }
949}
950
951/// RemoveDuplicates - If there are duplicate directory entries in the specified
952/// search list, remove the later (dead) ones.
953static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
954                             unsigned First, bool Verbose) {
955  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
956  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
957  llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
958  for (unsigned i = First; i != SearchList.size(); ++i) {
959    unsigned DirToRemove = i;
960
961    const DirectoryLookup &CurEntry = SearchList[i];
962
963    if (CurEntry.isNormalDir()) {
964      // If this isn't the first time we've seen this dir, remove it.
965      if (SeenDirs.insert(CurEntry.getDir()))
966        continue;
967    } else if (CurEntry.isFramework()) {
968      // If this isn't the first time we've seen this framework dir, remove it.
969      if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()))
970        continue;
971    } else {
972      assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
973      // If this isn't the first time we've seen this headermap, remove it.
974      if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()))
975        continue;
976    }
977
978    // If we have a normal #include dir/framework/headermap that is shadowed
979    // later in the chain by a system include location, we actually want to
980    // ignore the user's request and drop the user dir... keeping the system
981    // dir.  This is weird, but required to emulate GCC's search path correctly.
982    //
983    // Since dupes of system dirs are rare, just rescan to find the original
984    // that we're nuking instead of using a DenseMap.
985    if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
986      // Find the dir that this is the same of.
987      unsigned FirstDir;
988      for (FirstDir = 0; ; ++FirstDir) {
989        assert(FirstDir != i && "Didn't find dupe?");
990
991        const DirectoryLookup &SearchEntry = SearchList[FirstDir];
992
993        // If these are different lookup types, then they can't be the dupe.
994        if (SearchEntry.getLookupType() != CurEntry.getLookupType())
995          continue;
996
997        bool isSame;
998        if (CurEntry.isNormalDir())
999          isSame = SearchEntry.getDir() == CurEntry.getDir();
1000        else if (CurEntry.isFramework())
1001          isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
1002        else {
1003          assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
1004          isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
1005        }
1006
1007        if (isSame)
1008          break;
1009      }
1010
1011      // If the first dir in the search path is a non-system dir, zap it
1012      // instead of the system one.
1013      if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
1014        DirToRemove = FirstDir;
1015    }
1016
1017    if (Verbose) {
1018      llvm::errs() << "ignoring duplicate directory \""
1019                   << CurEntry.getName() << "\"\n";
1020      if (DirToRemove != i)
1021        llvm::errs() << "  as it is a non-system directory that duplicates "
1022                     << "a system directory\n";
1023    }
1024
1025    // This is reached if the current entry is a duplicate.  Remove the
1026    // DirToRemove (usually the current dir).
1027    SearchList.erase(SearchList.begin()+DirToRemove);
1028    --i;
1029  }
1030}
1031
1032
1033void InitHeaderSearch::Realize(const LangOptions &Lang) {
1034  // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
1035  std::vector<DirectoryLookup> SearchList;
1036  SearchList.reserve(IncludePath.size());
1037
1038  // Quoted arguments go first.
1039  for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
1040       it != ie; ++it) {
1041    if (it->first == Quoted)
1042      SearchList.push_back(it->second);
1043  }
1044  // Deduplicate and remember index.
1045  RemoveDuplicates(SearchList, 0, Verbose);
1046  unsigned NumQuoted = SearchList.size();
1047
1048  for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
1049       it != ie; ++it) {
1050    if (it->first == Angled)
1051      SearchList.push_back(it->second);
1052  }
1053
1054  RemoveDuplicates(SearchList, NumQuoted, Verbose);
1055  unsigned NumAngled = SearchList.size();
1056
1057  for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
1058       it != ie; ++it) {
1059    if (it->first == System || (Lang.CPlusPlus && it->first == CXXSystem))
1060      SearchList.push_back(it->second);
1061  }
1062
1063  for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
1064       it != ie; ++it) {
1065    if (it->first == After)
1066      SearchList.push_back(it->second);
1067  }
1068
1069  // Remove duplicates across both the Angled and System directories.  GCC does
1070  // this and failing to remove duplicates across these two groups breaks
1071  // #include_next.
1072  RemoveDuplicates(SearchList, NumQuoted, Verbose);
1073
1074  bool DontSearchCurDir = false;  // TODO: set to true if -I- is set?
1075  Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
1076
1077  // If verbose, print the list of directories that will be searched.
1078  if (Verbose) {
1079    llvm::errs() << "#include \"...\" search starts here:\n";
1080    for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
1081      if (i == NumQuoted)
1082        llvm::errs() << "#include <...> search starts here:\n";
1083      const char *Name = SearchList[i].getName();
1084      const char *Suffix;
1085      if (SearchList[i].isNormalDir())
1086        Suffix = "";
1087      else if (SearchList[i].isFramework())
1088        Suffix = " (framework directory)";
1089      else {
1090        assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
1091        Suffix = " (headermap)";
1092      }
1093      llvm::errs() << " " << Name << Suffix << "\n";
1094    }
1095    llvm::errs() << "End of search list.\n";
1096  }
1097}
1098
1099void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
1100                                     const HeaderSearchOptions &HSOpts,
1101                                     const LangOptions &Lang,
1102                                     const llvm::Triple &Triple) {
1103  InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot);
1104
1105  // Add the user defined entries.
1106  for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
1107    const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
1108    Init.AddPath(E.Path, E.Group, false, E.IsUserSupplied, E.IsFramework,
1109                 E.IgnoreSysRoot);
1110  }
1111
1112  // Add entries from CPATH and friends.
1113  Init.AddDelimitedPaths(HSOpts.EnvIncPath);
1114  if (Lang.CPlusPlus && Lang.ObjC1)
1115    Init.AddDelimitedPaths(HSOpts.ObjCXXEnvIncPath);
1116  else if (Lang.CPlusPlus)
1117    Init.AddDelimitedPaths(HSOpts.CXXEnvIncPath);
1118  else if (Lang.ObjC1)
1119    Init.AddDelimitedPaths(HSOpts.ObjCEnvIncPath);
1120  else
1121    Init.AddDelimitedPaths(HSOpts.CEnvIncPath);
1122
1123  if (HSOpts.UseStandardIncludes)
1124    Init.AddDefaultSystemIncludePaths(Lang, Triple, HSOpts);
1125
1126  Init.Realize(Lang);
1127}
1128