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