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