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