InitHeaderSearch.cpp revision e1bd4e6d7c5b13462f83245865f7d9e9b6ea8486
10fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//===--- InitHeaderSearch.cpp - Initialize header search paths ----------*-===//
20fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//
30fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//                     The LLVM Compiler Infrastructure
40fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//
50fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber// This file is distributed under the University of Illinois Open Source
60fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber// License. See LICENSE.TXT for details.
70fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//
80fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//===----------------------------------------------------------------------===//
90fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//
100fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber// This file implements the InitHeaderSearch class.
110fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//
120fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber//===----------------------------------------------------------------------===//
130fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
14e1bd4e6d7c5b13462f83245865f7d9e9b6ea8486Daniel Dunbar#include "clang/Frontend/InitHeaderSearch.h"
150fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include "clang/Lex/HeaderSearch.h"
160fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include "clang/Basic/FileManager.h"
170fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include "clang/Basic/LangOptions.h"
180fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include "llvm/ADT/SmallString.h"
190fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include "llvm/ADT/SmallPtrSet.h"
200fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include "llvm/System/Path.h"
21121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis#include "llvm/Config/config.h"
220fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber#include <vector>
230fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weberusing namespace clang;
240fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
250fca022d77b89100e746f4d659b84ed5b1ee0158Nico Webervoid InitHeaderSearch::AddPath(const std::string &Path, IncludeDirGroup Group,
260fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                               bool isCXXAware, bool isUserSupplied,
276858dd3fcc2d3ac6a706a0294be1d3ac51849022Chris Lattner                               bool isFramework, bool IgnoreSysRoot) {
280fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  assert(!Path.empty() && "can't handle empty path here");
290fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  FileManager &FM = Headers.getFileMgr();
300fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
310fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // Compute the actual path, taking into consideration -isysroot.
320fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  llvm::SmallString<256> MappedPath;
330fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
340fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // Handle isysroot.
356858dd3fcc2d3ac6a706a0294be1d3ac51849022Chris Lattner  if (Group == System && !IgnoreSysRoot) {
360fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    // FIXME: Portability.  This should be a sys::Path interface, this doesn't
370fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    // handle things like C:\ right, nor win32 \\network\device\blah.
380fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    if (isysroot.size() != 1 || isysroot[0] != '/') // Add isysroot if present.
390fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      MappedPath.append(isysroot.begin(), isysroot.end());
400fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
410fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
420fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  MappedPath.append(Path.begin(), Path.end());
430fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
440fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // Compute the DirectoryLookup type.
459d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind Type;
460fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (Group == Quoted || Group == Angled)
470b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    Type = SrcMgr::C_User;
480fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  else if (isCXXAware)
490b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    Type = SrcMgr::C_System;
500fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  else
510b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    Type = SrcMgr::C_ExternCSystem;
520fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
530fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
540fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // If the directory exists, add it.
550fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (const DirectoryEntry *DE = FM.getDirectory(&MappedPath[0],
560fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                                                 &MappedPath[0]+
570fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                                                 MappedPath.size())) {
580fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied,
590fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                                                  isFramework));
600fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    return;
610fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
620fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
630fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // Check to see if this is an apple-style headermap (which are not allowed to
640fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // be frameworks).
650fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (!isFramework) {
660fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    if (const FileEntry *FE = FM.getFile(&MappedPath[0],
670fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                                         &MappedPath[0]+MappedPath.size())) {
680fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
690fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        // It is a headermap, add it to the search path.
700fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
710fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        return;
720fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      }
730fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    }
740fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
750fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
760fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (Verbose)
7750b587d02f84ccf447d835fe8fcb79aad3a3e126Chris Lattner    fprintf(stderr, "ignoring nonexistent directory \"%s\"\n",
7850b587d02f84ccf447d835fe8fcb79aad3a3e126Chris Lattner            MappedPath.c_str());
790fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber}
800fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
810fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
820fca022d77b89100e746f4d659b84ed5b1ee0158Nico Webervoid InitHeaderSearch::AddEnvVarPaths(const char *Name) {
830fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  const char* at = getenv(Name);
84bb95255e08c5d56616f5581118f5babe2c4e6ea6Daniel Dunbar  if (!at || *at == 0) // Empty string should not add '.' path.
850fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    return;
860fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
870fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  const char* delim = strchr(at, llvm::sys::PathSeparator);
880fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  while (delim != 0) {
890fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    if (delim-at == 0)
900fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      AddPath(".", Angled, false, true, false);
910fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    else
920fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      AddPath(std::string(at, std::string::size_type(delim-at)), Angled, false,
937a739401983eb9bc25c9b4b25177e116f5e5ba92Chris Lattner              true, false);
940fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    at = delim + 1;
950fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    delim = strchr(at, llvm::sys::PathSeparator);
960fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
970fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (*at == 0)
980fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath(".", Angled, false, true, false);
990fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  else
1000fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath(at, Angled, false, true, false);
1010fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber}
1020fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1030fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1040fca022d77b89100e746f4d659b84ed5b1ee0158Nico Webervoid InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang) {
1050fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // FIXME: temporary hack: hard-coded paths.
1060fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // FIXME: get these from the target?
107121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis
108121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis#ifdef LLVM_ON_WIN32
109121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis  if (Lang.CPlusPlus) {
110121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis    // Mingw32 GCC version 4
1116f541026b6dffc2801ed825d769e5fa0af95178dChris Lattner    AddPath("c:/mingw/lib/gcc/mingw32/4.3.0/include/c++",
1126f541026b6dffc2801ed825d769e5fa0af95178dChris Lattner            System, true, false, false);
1136f541026b6dffc2801ed825d769e5fa0af95178dChris Lattner    AddPath("c:/mingw/lib/gcc/mingw32/4.3.0/include/c++/mingw32",
1146f541026b6dffc2801ed825d769e5fa0af95178dChris Lattner            System, true, false, false);
1156f541026b6dffc2801ed825d769e5fa0af95178dChris Lattner    AddPath("c:/mingw/lib/gcc/mingw32/4.3.0/include/c++/backward",
1166f541026b6dffc2801ed825d769e5fa0af95178dChris Lattner            System, true, false, false);
117121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis  }
118121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis
119121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis  // Mingw32 GCC version 4
120121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis  AddPath("C:/mingw/include", System, false, false, false);
121121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis#else
122121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis
1230fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (Lang.CPlusPlus) {
1240fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.2.1", System, true, false, false);
1250fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.2.1/i686-apple-darwin10", System, true, false,
1260fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false);
1270fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.2.1/backward", System, true, false, false);
1280fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1290fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.0.0", System, true, false, false);
1300fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.0.0/i686-apple-darwin8", System, true, false,
1310fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false);
1320fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false);
1330fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1340fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    // Ubuntu 7.10 - Gutsy Gibbon
1350fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.1.3", System, true, false, false);
1360fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.1.3/i486-linux-gnu", System, true, false,
1370fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false);
1380fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.1.3/backward", System, true, false, false);
1390fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1400fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    // Fedora 8
1410fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.1.2", System, true, false, false);
1420fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.1.2/i386-redhat-linux", System, true, false,
1430fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false);
1440fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.1.2/backward", System, true, false, false);
1450fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1460fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    // Fedora 9
1470fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.0", System, true, false, false);
1480fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.0/i386-redhat-linux", System, true, false,
1490fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false);
1500fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.0/backward", System, true, false, false);
1510fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
152776caefc70360a00ee860f63d7f76288d5f41d87Zhongxing Xu    // Fedora 10
153776caefc70360a00ee860f63d7f76288d5f41d87Zhongxing Xu    AddPath("/usr/include/c++/4.3.2", System, true, false, false);
154776caefc70360a00ee860f63d7f76288d5f41d87Zhongxing Xu    AddPath("/usr/include/c++/4.3.2/i386-redhat-linux", System, true, false,
155776caefc70360a00ee860f63d7f76288d5f41d87Zhongxing Xu        false);
156776caefc70360a00ee860f63d7f76288d5f41d87Zhongxing Xu    AddPath("/usr/include/c++/4.3.2/backward", System, true, false, false);
157776caefc70360a00ee860f63d7f76288d5f41d87Zhongxing Xu
1580fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    // Arch Linux 2008-06-24
1590fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.1", System, true, false, false);
1600fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.1/i686-pc-linux-gnu", System, true, false,
1610fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false);
1620fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.1/backward", System, true, false, false);
1630fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddPath("/usr/include/c++/4.3.1/x86_64-unknown-linux-gnu", System, true,
1640fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        false, false);
1655654ffda8f44cb11e3380823a99f6556961bdc16Chris Lattner
166a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes    // Gentoo x86 stable
167a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes    AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4", System,
168a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes            true, false, false);
169a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes    AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4/"
170a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes            "i686-pc-linux-gnu", System, true, false, false);
171a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes    AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4/backward",
172a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes            System, true, false, false);
173a3d783b11fc8a48ef9a024aaacba8caf43961de5Nuno Lopes
1745654ffda8f44cb11e3380823a99f6556961bdc16Chris Lattner    // DragonFly
1755654ffda8f44cb11e3380823a99f6556961bdc16Chris Lattner    AddPath("/usr/include/c++/4.1", System, true, false, false);
17601e4b5c3bf9f529c0c873162119d56a4f9341167Chris Lattner
17701e4b5c3bf9f529c0c873162119d56a4f9341167Chris Lattner    // FreeBSD
17801e4b5c3bf9f529c0c873162119d56a4f9341167Chris Lattner    AddPath("/usr/include/c++/4.2", System, true, false, false);
1790fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
1800fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1810fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  AddPath("/usr/local/include", System, false, false, false);
1820fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1830fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  AddPath("/usr/include", System, false, false, false);
1840fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  AddPath("/System/Library/Frameworks", System, true, false, true);
1850fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  AddPath("/Library/Frameworks", System, true, false, true);
186121e3c207415fb4c105d690de384d8f3d49b0f2dArgyrios Kyrtzidis#endif
1870fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber}
1880fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
1890fca022d77b89100e746f4d659b84ed5b1ee0158Nico Webervoid InitHeaderSearch::AddDefaultEnvVarPaths(const LangOptions &Lang) {
1900fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  AddEnvVarPaths("CPATH");
1910fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (Lang.CPlusPlus && Lang.ObjC1)
1920fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddEnvVarPaths("OBJCPLUS_INCLUDE_PATH");
1930fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  else if (Lang.CPlusPlus)
1940fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddEnvVarPaths("CPLUS_INCLUDE_PATH");
1950fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  else if (Lang.ObjC1)
1960fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddEnvVarPaths("OBJC_INCLUDE_PATH");
1970fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  else
1980fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    AddEnvVarPaths("C_INCLUDE_PATH");
1990fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber}
2000fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2010fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2020fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber/// RemoveDuplicates - If there are duplicate directory entries in the specified
2030fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber/// search list, remove the later (dead) ones.
2040fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weberstatic void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
2050fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                             bool Verbose) {
2060fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
2070fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
2080fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
2090fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  for (unsigned i = 0; i != SearchList.size(); ++i) {
2107a739401983eb9bc25c9b4b25177e116f5e5ba92Chris Lattner    unsigned DirToRemove = i;
2117a739401983eb9bc25c9b4b25177e116f5e5ba92Chris Lattner
21243eee07270bf1966ea7289310066aa670c4b647fChris Lattner    const DirectoryLookup &CurEntry = SearchList[i];
21343eee07270bf1966ea7289310066aa670c4b647fChris Lattner
21443eee07270bf1966ea7289310066aa670c4b647fChris Lattner    if (CurEntry.isNormalDir()) {
2150fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      // If this isn't the first time we've seen this dir, remove it.
21643eee07270bf1966ea7289310066aa670c4b647fChris Lattner      if (SeenDirs.insert(CurEntry.getDir()))
2170fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        continue;
21843eee07270bf1966ea7289310066aa670c4b647fChris Lattner    } else if (CurEntry.isFramework()) {
2190fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      // If this isn't the first time we've seen this framework dir, remove it.
22043eee07270bf1966ea7289310066aa670c4b647fChris Lattner      if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()))
2210fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        continue;
2220fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    } else {
22343eee07270bf1966ea7289310066aa670c4b647fChris Lattner      assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
2240fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      // If this isn't the first time we've seen this headermap, remove it.
22543eee07270bf1966ea7289310066aa670c4b647fChris Lattner      if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()))
2260fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        continue;
22730f05b553db067c994966daca37e75324ee7b424Chris Lattner    }
22830f05b553db067c994966daca37e75324ee7b424Chris Lattner
22930f05b553db067c994966daca37e75324ee7b424Chris Lattner    // If we have a normal #include dir/framework/headermap that is shadowed
23030f05b553db067c994966daca37e75324ee7b424Chris Lattner    // later in the chain by a system include location, we actually want to
23130f05b553db067c994966daca37e75324ee7b424Chris Lattner    // ignore the user's request and drop the user dir... keeping the system
23230f05b553db067c994966daca37e75324ee7b424Chris Lattner    // dir.  This is weird, but required to emulate GCC's search path correctly.
23330f05b553db067c994966daca37e75324ee7b424Chris Lattner    //
23430f05b553db067c994966daca37e75324ee7b424Chris Lattner    // Since dupes of system dirs are rare, just rescan to find the original
23530f05b553db067c994966daca37e75324ee7b424Chris Lattner    // that we're nuking instead of using a DenseMap.
23643eee07270bf1966ea7289310066aa670c4b647fChris Lattner    if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
23730f05b553db067c994966daca37e75324ee7b424Chris Lattner      // Find the dir that this is the same of.
23830f05b553db067c994966daca37e75324ee7b424Chris Lattner      unsigned FirstDir;
23930f05b553db067c994966daca37e75324ee7b424Chris Lattner      for (FirstDir = 0; ; ++FirstDir) {
24030f05b553db067c994966daca37e75324ee7b424Chris Lattner        assert(FirstDir != i && "Didn't find dupe?");
24130f05b553db067c994966daca37e75324ee7b424Chris Lattner
24243eee07270bf1966ea7289310066aa670c4b647fChris Lattner        const DirectoryLookup &SearchEntry = SearchList[FirstDir];
24343eee07270bf1966ea7289310066aa670c4b647fChris Lattner
24430f05b553db067c994966daca37e75324ee7b424Chris Lattner        // If these are different lookup types, then they can't be the dupe.
24543eee07270bf1966ea7289310066aa670c4b647fChris Lattner        if (SearchEntry.getLookupType() != CurEntry.getLookupType())
24630f05b553db067c994966daca37e75324ee7b424Chris Lattner          continue;
24730f05b553db067c994966daca37e75324ee7b424Chris Lattner
24830f05b553db067c994966daca37e75324ee7b424Chris Lattner        bool isSame;
24943eee07270bf1966ea7289310066aa670c4b647fChris Lattner        if (CurEntry.isNormalDir())
25043eee07270bf1966ea7289310066aa670c4b647fChris Lattner          isSame = SearchEntry.getDir() == CurEntry.getDir();
25143eee07270bf1966ea7289310066aa670c4b647fChris Lattner        else if (CurEntry.isFramework())
25243eee07270bf1966ea7289310066aa670c4b647fChris Lattner          isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
25330f05b553db067c994966daca37e75324ee7b424Chris Lattner        else {
25443eee07270bf1966ea7289310066aa670c4b647fChris Lattner          assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
25543eee07270bf1966ea7289310066aa670c4b647fChris Lattner          isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
25630f05b553db067c994966daca37e75324ee7b424Chris Lattner        }
25730f05b553db067c994966daca37e75324ee7b424Chris Lattner
25830f05b553db067c994966daca37e75324ee7b424Chris Lattner        if (isSame)
25930f05b553db067c994966daca37e75324ee7b424Chris Lattner          break;
26030f05b553db067c994966daca37e75324ee7b424Chris Lattner      }
2610fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
26230f05b553db067c994966daca37e75324ee7b424Chris Lattner      // If the first dir in the search path is a non-system dir, zap it
26330f05b553db067c994966daca37e75324ee7b424Chris Lattner      // instead of the system one.
26430f05b553db067c994966daca37e75324ee7b424Chris Lattner      if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
26530f05b553db067c994966daca37e75324ee7b424Chris Lattner        DirToRemove = FirstDir;
26630f05b553db067c994966daca37e75324ee7b424Chris Lattner    }
26730f05b553db067c994966daca37e75324ee7b424Chris Lattner
26830f05b553db067c994966daca37e75324ee7b424Chris Lattner    if (Verbose) {
26943eee07270bf1966ea7289310066aa670c4b647fChris Lattner      fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
27043eee07270bf1966ea7289310066aa670c4b647fChris Lattner              CurEntry.getName());
27130f05b553db067c994966daca37e75324ee7b424Chris Lattner      if (DirToRemove != i)
27230f05b553db067c994966daca37e75324ee7b424Chris Lattner        fprintf(stderr, "  as it is a non-system directory that duplicates"
27330f05b553db067c994966daca37e75324ee7b424Chris Lattner                " a system directory\n");
2740fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    }
2750fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2767a739401983eb9bc25c9b4b25177e116f5e5ba92Chris Lattner    // This is reached if the current entry is a duplicate.  Remove the
2777a739401983eb9bc25c9b4b25177e116f5e5ba92Chris Lattner    // DirToRemove (usually the current dir).
2787a739401983eb9bc25c9b4b25177e116f5e5ba92Chris Lattner    SearchList.erase(SearchList.begin()+DirToRemove);
2790fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    --i;
2800fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
2810fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber}
2820fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2830fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2840fca022d77b89100e746f4d659b84ed5b1ee0158Nico Webervoid InitHeaderSearch::Realize() {
2850fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
2860fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  std::vector<DirectoryLookup> SearchList;
2870fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  SearchList = IncludeGroup[Angled];
2880fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  SearchList.insert(SearchList.end(), IncludeGroup[System].begin(),
2890fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                    IncludeGroup[System].end());
2900fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  SearchList.insert(SearchList.end(), IncludeGroup[After].begin(),
2910fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                    IncludeGroup[After].end());
2920fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  RemoveDuplicates(SearchList, Verbose);
2930fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  RemoveDuplicates(IncludeGroup[Quoted], Verbose);
2940fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2950fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // Prepend QUOTED list on the search list.
2960fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(),
2970fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                    IncludeGroup[Quoted].end());
2980fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
2990fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
3000fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  bool DontSearchCurDir = false;  // TODO: set to true if -I- is set?
3010fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(),
3020fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber                         DontSearchCurDir);
3030fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
3040fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  // If verbose, print the list of directories that will be searched.
3050fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  if (Verbose) {
3060fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    fprintf(stderr, "#include \"...\" search starts here:\n");
3070fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    unsigned QuotedIdx = IncludeGroup[Quoted].size();
3080fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
3090fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      if (i == QuotedIdx)
3100fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        fprintf(stderr, "#include <...> search starts here:\n");
3110fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      const char *Name = SearchList[i].getName();
3120fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      const char *Suffix;
3130fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      if (SearchList[i].isNormalDir())
3140fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        Suffix = "";
3150fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      else if (SearchList[i].isFramework())
3160fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        Suffix = " (framework directory)";
3170fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      else {
3180fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
3190fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber        Suffix = " (headermap)";
3200fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      }
3210fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber      fprintf(stderr, " %s%s\n", Name, Suffix);
3220fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    }
3230fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber    fprintf(stderr, "End of search list.\n");
3240fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber  }
3250fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber}
3260fca022d77b89100e746f4d659b84ed5b1ee0158Nico Weber
327