1 //===--- HeaderSearch.cpp - Resolve Header File Locations ---===// 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 DirectoryLookup and HeaderSearch interfaces. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Lex/HeaderSearch.h" 15 #include "clang/Lex/HeaderMap.h" 16 #include "clang/Lex/Lexer.h" 17 #include "clang/Basic/Diagnostic.h" 18 #include "clang/Basic/FileManager.h" 19 #include "clang/Basic/IdentifierTable.h" 20 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/Path.h" 22 #include "llvm/ADT/SmallString.h" 23 #include "llvm/Support/Capacity.h" 24 #include <cstdio> 25 using namespace clang; 26 27 const IdentifierInfo * 28 HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { 29 if (ControllingMacro) 30 return ControllingMacro; 31 32 if (!ControllingMacroID || !External) 33 return 0; 34 35 ControllingMacro = External->GetIdentifier(ControllingMacroID); 36 return ControllingMacro; 37 } 38 39 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 40 41 HeaderSearch::HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, 42 const LangOptions &LangOpts) 43 : FileMgr(FM), Diags(Diags), FrameworkMap(64), 44 ModMap(FileMgr, *Diags.getClient(), LangOpts) 45 { 46 AngledDirIdx = 0; 47 SystemDirIdx = 0; 48 NoCurDirSearch = false; 49 50 ExternalLookup = 0; 51 ExternalSource = 0; 52 NumIncluded = 0; 53 NumMultiIncludeFileOptzn = 0; 54 NumFrameworkLookups = NumSubFrameworkLookups = 0; 55 } 56 57 HeaderSearch::~HeaderSearch() { 58 // Delete headermaps. 59 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 60 delete HeaderMaps[i].second; 61 } 62 63 void HeaderSearch::PrintStats() { 64 fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 65 fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 66 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 67 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 68 NumOnceOnlyFiles += FileInfo[i].isImport; 69 if (MaxNumIncludes < FileInfo[i].NumIncludes) 70 MaxNumIncludes = FileInfo[i].NumIncludes; 71 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 72 } 73 fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 74 fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 75 fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 76 77 fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 78 fprintf(stderr, " %d #includes skipped due to" 79 " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 80 81 fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 82 fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 83 } 84 85 /// CreateHeaderMap - This method returns a HeaderMap for the specified 86 /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. 87 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 88 // We expect the number of headermaps to be small, and almost always empty. 89 // If it ever grows, use of a linear search should be re-evaluated. 90 if (!HeaderMaps.empty()) { 91 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 92 // Pointer equality comparison of FileEntries works because they are 93 // already uniqued by inode. 94 if (HeaderMaps[i].first == FE) 95 return HeaderMaps[i].second; 96 } 97 98 if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 99 HeaderMaps.push_back(std::make_pair(FE, HM)); 100 return HM; 101 } 102 103 return 0; 104 } 105 106 std::string HeaderSearch::getModuleFileName(Module *Module) { 107 // If we don't have a module cache path, we can't do anything. 108 if (ModuleCachePath.empty()) 109 return std::string(); 110 111 112 llvm::SmallString<256> Result(ModuleCachePath); 113 llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm"); 114 return Result.str().str(); 115 } 116 117 std::string HeaderSearch::getModuleFileName(StringRef ModuleName) { 118 // If we don't have a module cache path, we can't do anything. 119 if (ModuleCachePath.empty()) 120 return std::string(); 121 122 123 llvm::SmallString<256> Result(ModuleCachePath); 124 llvm::sys::path::append(Result, ModuleName + ".pcm"); 125 return Result.str().str(); 126 } 127 128 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { 129 // Look in the module map to determine if there is a module by this name. 130 Module *Module = ModMap.findModule(ModuleName); 131 if (Module || !AllowSearch) 132 return Module; 133 134 // Look through the various header search paths to load any avai;able module 135 // maps, searching for a module map that describes this module. 136 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 137 if (SearchDirs[Idx].isFramework()) { 138 // Search for or infer a module map for a framework. 139 llvm::SmallString<128> FrameworkDirName; 140 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); 141 llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); 142 if (const DirectoryEntry *FrameworkDir 143 = FileMgr.getDirectory(FrameworkDirName)) { 144 bool IsSystem 145 = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 146 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 147 if (Module) 148 break; 149 } 150 } 151 152 // FIXME: Figure out how header maps and module maps will work together. 153 154 // Only deal with normal search directories. 155 if (!SearchDirs[Idx].isNormalDir()) 156 continue; 157 158 // Search for a module map file in this directory. 159 if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) { 160 // We just loaded a module map file; check whether the module is 161 // available now. 162 Module = ModMap.findModule(ModuleName); 163 if (Module) 164 break; 165 } 166 167 // Search for a module map in a subdirectory with the same name as the 168 // module. 169 llvm::SmallString<128> NestedModuleMapDirName; 170 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 171 llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 172 if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) { 173 // If we just loaded a module map file, look for the module again. 174 Module = ModMap.findModule(ModuleName); 175 if (Module) 176 break; 177 } 178 } 179 180 return Module; 181 } 182 183 //===----------------------------------------------------------------------===// 184 // File lookup within a DirectoryLookup scope 185 //===----------------------------------------------------------------------===// 186 187 /// getName - Return the directory or filename corresponding to this lookup 188 /// object. 189 const char *DirectoryLookup::getName() const { 190 if (isNormalDir()) 191 return getDir()->getName(); 192 if (isFramework()) 193 return getFrameworkDir()->getName(); 194 assert(isHeaderMap() && "Unknown DirectoryLookup"); 195 return getHeaderMap()->getFileName(); 196 } 197 198 199 /// LookupFile - Lookup the specified file in this search path, returning it 200 /// if it exists or returning null if not. 201 const FileEntry *DirectoryLookup::LookupFile( 202 StringRef Filename, 203 HeaderSearch &HS, 204 SmallVectorImpl<char> *SearchPath, 205 SmallVectorImpl<char> *RelativePath, 206 Module **SuggestedModule) const { 207 llvm::SmallString<1024> TmpDir; 208 if (isNormalDir()) { 209 // Concatenate the requested file onto the directory. 210 TmpDir = getDir()->getName(); 211 llvm::sys::path::append(TmpDir, Filename); 212 if (SearchPath != NULL) { 213 StringRef SearchPathRef(getDir()->getName()); 214 SearchPath->clear(); 215 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 216 } 217 if (RelativePath != NULL) { 218 RelativePath->clear(); 219 RelativePath->append(Filename.begin(), Filename.end()); 220 } 221 222 // If we have a module map that might map this header, load it and 223 // check whether we'll have a suggestion for a module. 224 if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) { 225 const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 226 /*openFile=*/false); 227 if (!File) 228 return File; 229 230 // If there is a module that corresponds to this header, 231 // suggest it. 232 *SuggestedModule = HS.findModuleForHeader(File); 233 return File; 234 } 235 236 return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); 237 } 238 239 if (isFramework()) 240 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 241 SuggestedModule); 242 243 assert(isHeaderMap() && "Unknown directory lookup"); 244 const FileEntry * const Result = getHeaderMap()->LookupFile( 245 Filename, HS.getFileMgr()); 246 if (Result) { 247 if (SearchPath != NULL) { 248 StringRef SearchPathRef(getName()); 249 SearchPath->clear(); 250 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 251 } 252 if (RelativePath != NULL) { 253 RelativePath->clear(); 254 RelativePath->append(Filename.begin(), Filename.end()); 255 } 256 } 257 return Result; 258 } 259 260 261 /// DoFrameworkLookup - Do a lookup of the specified file in the current 262 /// DirectoryLookup, which is a framework directory. 263 const FileEntry *DirectoryLookup::DoFrameworkLookup( 264 StringRef Filename, 265 HeaderSearch &HS, 266 SmallVectorImpl<char> *SearchPath, 267 SmallVectorImpl<char> *RelativePath, 268 Module **SuggestedModule) const 269 { 270 FileManager &FileMgr = HS.getFileMgr(); 271 272 // Framework names must have a '/' in the filename. 273 size_t SlashPos = Filename.find('/'); 274 if (SlashPos == StringRef::npos) return 0; 275 276 // Find out if this is the home for the specified framework, by checking 277 // HeaderSearch. Possible answer are yes/no and unknown. 278 const DirectoryEntry *&FrameworkDirCache = 279 HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 280 281 // If it is known and in some other directory, fail. 282 if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir()) 283 return 0; 284 285 // Otherwise, construct the path to this framework dir. 286 287 // FrameworkName = "/System/Library/Frameworks/" 288 llvm::SmallString<1024> FrameworkName; 289 FrameworkName += getFrameworkDir()->getName(); 290 if (FrameworkName.empty() || FrameworkName.back() != '/') 291 FrameworkName.push_back('/'); 292 293 // FrameworkName = "/System/Library/Frameworks/Cocoa" 294 StringRef ModuleName(Filename.begin(), SlashPos); 295 FrameworkName += ModuleName; 296 297 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 298 FrameworkName += ".framework/"; 299 300 // If the cache entry is still unresolved, query to see if the cache entry is 301 // still unresolved. If so, check its existence now. 302 if (FrameworkDirCache == 0) { 303 HS.IncrementFrameworkLookupCount(); 304 305 // If the framework dir doesn't exist, we fail. 306 // FIXME: It's probably more efficient to query this with FileMgr.getDir. 307 bool Exists; 308 if (llvm::sys::fs::exists(FrameworkName.str(), Exists) || !Exists) 309 return 0; 310 311 // Otherwise, if it does, remember that this is the right direntry for this 312 // framework. 313 FrameworkDirCache = getFrameworkDir(); 314 } 315 316 if (RelativePath != NULL) { 317 RelativePath->clear(); 318 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 319 } 320 321 // If we're allowed to look for modules, try to load or create the module 322 // corresponding to this framework. 323 Module *Module = 0; 324 if (SuggestedModule) { 325 if (const DirectoryEntry *FrameworkDir 326 = FileMgr.getDirectory(FrameworkName)) { 327 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 328 Module = HS.loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 329 } 330 } 331 332 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 333 unsigned OrigSize = FrameworkName.size(); 334 335 FrameworkName += "Headers/"; 336 337 if (SearchPath != NULL) { 338 SearchPath->clear(); 339 // Without trailing '/'. 340 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 341 } 342 343 // Determine whether this is the module we're building or not. 344 bool AutomaticImport = Module; 345 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 346 if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 347 /*openFile=*/!AutomaticImport)) { 348 if (AutomaticImport) 349 *SuggestedModule = HS.findModuleForHeader(FE); 350 return FE; 351 } 352 353 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 354 const char *Private = "Private"; 355 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 356 Private+strlen(Private)); 357 if (SearchPath != NULL) 358 SearchPath->insert(SearchPath->begin()+OrigSize, Private, 359 Private+strlen(Private)); 360 361 const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 362 /*openFile=*/!AutomaticImport); 363 if (FE && AutomaticImport) 364 *SuggestedModule = HS.findModuleForHeader(FE); 365 return FE; 366 } 367 368 369 //===----------------------------------------------------------------------===// 370 // Header File Location. 371 //===----------------------------------------------------------------------===// 372 373 374 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, 375 /// return null on failure. isAngled indicates whether the file reference is 376 /// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if 377 /// non-null, indicates where the #including file is, in case a relative search 378 /// is needed. 379 const FileEntry *HeaderSearch::LookupFile( 380 StringRef Filename, 381 bool isAngled, 382 const DirectoryLookup *FromDir, 383 const DirectoryLookup *&CurDir, 384 const FileEntry *CurFileEnt, 385 SmallVectorImpl<char> *SearchPath, 386 SmallVectorImpl<char> *RelativePath, 387 Module **SuggestedModule, 388 bool SkipCache) 389 { 390 if (SuggestedModule) 391 *SuggestedModule = 0; 392 393 // If 'Filename' is absolute, check to see if it exists and no searching. 394 if (llvm::sys::path::is_absolute(Filename)) { 395 CurDir = 0; 396 397 // If this was an #include_next "/absolute/file", fail. 398 if (FromDir) return 0; 399 400 if (SearchPath != NULL) 401 SearchPath->clear(); 402 if (RelativePath != NULL) { 403 RelativePath->clear(); 404 RelativePath->append(Filename.begin(), Filename.end()); 405 } 406 // Otherwise, just return the file. 407 return FileMgr.getFile(Filename, /*openFile=*/true); 408 } 409 410 // Unless disabled, check to see if the file is in the #includer's 411 // directory. This has to be based on CurFileEnt, not CurDir, because 412 // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and 413 // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". 414 // This search is not done for <> headers. 415 if (CurFileEnt && !isAngled && !NoCurDirSearch) { 416 llvm::SmallString<1024> TmpDir; 417 // Concatenate the requested file onto the directory. 418 // FIXME: Portability. Filename concatenation should be in sys::Path. 419 TmpDir += CurFileEnt->getDir()->getName(); 420 TmpDir.push_back('/'); 421 TmpDir.append(Filename.begin(), Filename.end()); 422 if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { 423 // Leave CurDir unset. 424 // This file is a system header or C++ unfriendly if the old file is. 425 // 426 // Note that the temporary 'DirInfo' is required here, as either call to 427 // getFileInfo could resize the vector and we don't want to rely on order 428 // of evaluation. 429 unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo; 430 getFileInfo(FE).DirInfo = DirInfo; 431 if (SearchPath != NULL) { 432 StringRef SearchPathRef(CurFileEnt->getDir()->getName()); 433 SearchPath->clear(); 434 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 435 } 436 if (RelativePath != NULL) { 437 RelativePath->clear(); 438 RelativePath->append(Filename.begin(), Filename.end()); 439 } 440 return FE; 441 } 442 } 443 444 CurDir = 0; 445 446 // If this is a system #include, ignore the user #include locs. 447 unsigned i = isAngled ? AngledDirIdx : 0; 448 449 // If this is a #include_next request, start searching after the directory the 450 // file was found in. 451 if (FromDir) 452 i = FromDir-&SearchDirs[0]; 453 454 // Cache all of the lookups performed by this method. Many headers are 455 // multiply included, and the "pragma once" optimization prevents them from 456 // being relex/pp'd, but they would still have to search through a 457 // (potentially huge) series of SearchDirs to find it. 458 std::pair<unsigned, unsigned> &CacheLookup = 459 LookupFileCache.GetOrCreateValue(Filename).getValue(); 460 461 // If the entry has been previously looked up, the first value will be 462 // non-zero. If the value is equal to i (the start point of our search), then 463 // this is a matching hit. 464 if (!SkipCache && CacheLookup.first == i+1) { 465 // Skip querying potentially lots of directories for this lookup. 466 i = CacheLookup.second; 467 } else { 468 // Otherwise, this is the first query, or the previous query didn't match 469 // our search start. We will fill in our found location below, so prime the 470 // start point value. 471 CacheLookup.first = i+1; 472 } 473 474 // Check each directory in sequence to see if it contains this file. 475 for (; i != SearchDirs.size(); ++i) { 476 const FileEntry *FE = 477 SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 478 SuggestedModule); 479 if (!FE) continue; 480 481 CurDir = &SearchDirs[i]; 482 483 // This file is a system header or C++ unfriendly if the dir is. 484 HeaderFileInfo &HFI = getFileInfo(FE); 485 HFI.DirInfo = CurDir->getDirCharacteristic(); 486 487 // If this file is found in a header map and uses the framework style of 488 // includes, then this header is part of a framework we're building. 489 if (CurDir->isIndexHeaderMap()) { 490 size_t SlashPos = Filename.find('/'); 491 if (SlashPos != StringRef::npos) { 492 HFI.IndexHeaderMapHeader = 1; 493 HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 494 SlashPos)); 495 } 496 } 497 498 // Remember this location for the next lookup we do. 499 CacheLookup.second = i; 500 return FE; 501 } 502 503 // If we are including a file with a quoted include "foo.h" from inside 504 // a header in a framework that is currently being built, and we couldn't 505 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 506 // "Foo" is the name of the framework in which the including header was found. 507 if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { 508 HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); 509 if (IncludingHFI.IndexHeaderMapHeader) { 510 llvm::SmallString<128> ScratchFilename; 511 ScratchFilename += IncludingHFI.Framework; 512 ScratchFilename += '/'; 513 ScratchFilename += Filename; 514 515 const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true, 516 FromDir, CurDir, CurFileEnt, 517 SearchPath, RelativePath, 518 SuggestedModule); 519 std::pair<unsigned, unsigned> &CacheLookup 520 = LookupFileCache.GetOrCreateValue(Filename).getValue(); 521 CacheLookup.second 522 = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second; 523 return Result; 524 } 525 } 526 527 // Otherwise, didn't find it. Remember we didn't find this. 528 CacheLookup.second = SearchDirs.size(); 529 return 0; 530 } 531 532 /// LookupSubframeworkHeader - Look up a subframework for the specified 533 /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from 534 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 535 /// is a subframework within Carbon.framework. If so, return the FileEntry 536 /// for the designated file, otherwise return null. 537 const FileEntry *HeaderSearch:: 538 LookupSubframeworkHeader(StringRef Filename, 539 const FileEntry *ContextFileEnt, 540 SmallVectorImpl<char> *SearchPath, 541 SmallVectorImpl<char> *RelativePath) { 542 assert(ContextFileEnt && "No context file?"); 543 544 // Framework names must have a '/' in the filename. Find it. 545 // FIXME: Should we permit '\' on Windows? 546 size_t SlashPos = Filename.find('/'); 547 if (SlashPos == StringRef::npos) return 0; 548 549 // Look up the base framework name of the ContextFileEnt. 550 const char *ContextName = ContextFileEnt->getName(); 551 552 // If the context info wasn't a framework, couldn't be a subframework. 553 const unsigned DotFrameworkLen = 10; 554 const char *FrameworkPos = strstr(ContextName, ".framework"); 555 if (FrameworkPos == 0 || 556 (FrameworkPos[DotFrameworkLen] != '/' && 557 FrameworkPos[DotFrameworkLen] != '\\')) 558 return 0; 559 560 llvm::SmallString<1024> FrameworkName(ContextName, 561 FrameworkPos+DotFrameworkLen+1); 562 563 // Append Frameworks/HIToolbox.framework/ 564 FrameworkName += "Frameworks/"; 565 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 566 FrameworkName += ".framework/"; 567 568 llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup = 569 FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 570 571 // Some other location? 572 if (CacheLookup.getValue() && 573 CacheLookup.getKeyLength() == FrameworkName.size() && 574 memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 575 CacheLookup.getKeyLength()) != 0) 576 return 0; 577 578 // Cache subframework. 579 if (CacheLookup.getValue() == 0) { 580 ++NumSubFrameworkLookups; 581 582 // If the framework dir doesn't exist, we fail. 583 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 584 if (Dir == 0) return 0; 585 586 // Otherwise, if it does, remember that this is the right direntry for this 587 // framework. 588 CacheLookup.setValue(Dir); 589 } 590 591 const FileEntry *FE = 0; 592 593 if (RelativePath != NULL) { 594 RelativePath->clear(); 595 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 596 } 597 598 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 599 llvm::SmallString<1024> HeadersFilename(FrameworkName); 600 HeadersFilename += "Headers/"; 601 if (SearchPath != NULL) { 602 SearchPath->clear(); 603 // Without trailing '/'. 604 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 605 } 606 607 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 608 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 609 610 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 611 HeadersFilename = FrameworkName; 612 HeadersFilename += "PrivateHeaders/"; 613 if (SearchPath != NULL) { 614 SearchPath->clear(); 615 // Without trailing '/'. 616 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 617 } 618 619 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 620 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 621 return 0; 622 } 623 624 // This file is a system header or C++ unfriendly if the old file is. 625 // 626 // Note that the temporary 'DirInfo' is required here, as either call to 627 // getFileInfo could resize the vector and we don't want to rely on order 628 // of evaluation. 629 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 630 getFileInfo(FE).DirInfo = DirInfo; 631 return FE; 632 } 633 634 /// \brief Helper static function to normalize a path for injection into 635 /// a synthetic header. 636 /*static*/ std::string 637 HeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { 638 // Implicit include paths should be resolved relative to the current 639 // working directory first, and then use the regular header search 640 // mechanism. The proper way to handle this is to have the 641 // predefines buffer located at the current working directory, but 642 // it has no file entry. For now, workaround this by using an 643 // absolute path if we find the file here, and otherwise letting 644 // header search handle it. 645 llvm::SmallString<128> Path(File); 646 llvm::sys::fs::make_absolute(Path); 647 bool exists; 648 if (llvm::sys::fs::exists(Path.str(), exists) || !exists) 649 Path = File; 650 else if (exists) 651 FileMgr.getFile(File); 652 653 return Lexer::Stringify(Path.str()); 654 } 655 656 //===----------------------------------------------------------------------===// 657 // File Info Management. 658 //===----------------------------------------------------------------------===// 659 660 /// \brief Merge the header file info provided by \p OtherHFI into the current 661 /// header file info (\p HFI) 662 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 663 const HeaderFileInfo &OtherHFI) { 664 HFI.isImport |= OtherHFI.isImport; 665 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 666 HFI.NumIncludes += OtherHFI.NumIncludes; 667 668 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 669 HFI.ControllingMacro = OtherHFI.ControllingMacro; 670 HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 671 } 672 673 if (OtherHFI.External) { 674 HFI.DirInfo = OtherHFI.DirInfo; 675 HFI.External = OtherHFI.External; 676 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 677 } 678 679 if (HFI.Framework.empty()) 680 HFI.Framework = OtherHFI.Framework; 681 682 HFI.Resolved = true; 683 } 684 685 /// getFileInfo - Return the HeaderFileInfo structure for the specified 686 /// FileEntry. 687 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 688 if (FE->getUID() >= FileInfo.size()) 689 FileInfo.resize(FE->getUID()+1); 690 691 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 692 if (ExternalSource && !HFI.Resolved) 693 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 694 return HFI; 695 } 696 697 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 698 // Check if we've ever seen this file as a header. 699 if (File->getUID() >= FileInfo.size()) 700 return false; 701 702 // Resolve header file info from the external source, if needed. 703 HeaderFileInfo &HFI = FileInfo[File->getUID()]; 704 if (ExternalSource && !HFI.Resolved) 705 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 706 707 return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID; 708 } 709 710 void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { 711 if (UID >= FileInfo.size()) 712 FileInfo.resize(UID+1); 713 HFI.Resolved = true; 714 FileInfo[UID] = HFI; 715 } 716 717 /// ShouldEnterIncludeFile - Mark the specified file as a target of of a 718 /// #include, #include_next, or #import directive. Return false if #including 719 /// the file will have no effect or true if we should include it. 720 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 721 ++NumIncluded; // Count # of attempted #includes. 722 723 // Get information about this file. 724 HeaderFileInfo &FileInfo = getFileInfo(File); 725 726 // If this is a #import directive, check that we have not already imported 727 // this header. 728 if (isImport) { 729 // If this has already been imported, don't import it again. 730 FileInfo.isImport = true; 731 732 // Has this already been #import'ed or #include'd? 733 if (FileInfo.NumIncludes) return false; 734 } else { 735 // Otherwise, if this is a #include of a file that was previously #import'd 736 // or if this is the second #include of a #pragma once file, ignore it. 737 if (FileInfo.isImport) 738 return false; 739 } 740 741 // Next, check to see if the file is wrapped with #ifndef guards. If so, and 742 // if the macro that guards it is defined, we know the #include has no effect. 743 if (const IdentifierInfo *ControllingMacro 744 = FileInfo.getControllingMacro(ExternalLookup)) 745 if (ControllingMacro->hasMacroDefinition()) { 746 ++NumMultiIncludeFileOptzn; 747 return false; 748 } 749 750 // Increment the number of times this file has been included. 751 ++FileInfo.NumIncludes; 752 753 return true; 754 } 755 756 size_t HeaderSearch::getTotalMemory() const { 757 return SearchDirs.capacity() 758 + llvm::capacity_in_bytes(FileInfo) 759 + llvm::capacity_in_bytes(HeaderMaps) 760 + LookupFileCache.getAllocator().getTotalMemory() 761 + FrameworkMap.getAllocator().getTotalMemory(); 762 } 763 764 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 765 return FrameworkNames.GetOrCreateValue(Framework).getKey(); 766 } 767 768 bool HeaderSearch::hasModuleMap(StringRef FileName, 769 const DirectoryEntry *Root) { 770 llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 771 772 StringRef DirName = FileName; 773 do { 774 // Get the parent directory name. 775 DirName = llvm::sys::path::parent_path(DirName); 776 if (DirName.empty()) 777 return false; 778 779 // Determine whether this directory exists. 780 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 781 if (!Dir) 782 return false; 783 784 // Try to load the module map file in this directory. 785 switch (loadModuleMapFile(Dir)) { 786 case LMM_NewlyLoaded: 787 case LMM_AlreadyLoaded: 788 // Success. All of the directories we stepped through inherit this module 789 // map file. 790 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 791 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 792 793 return true; 794 795 case LMM_NoDirectory: 796 case LMM_InvalidModuleMap: 797 break; 798 } 799 800 // If we hit the top of our search, we're done. 801 if (Dir == Root) 802 return false; 803 804 // Keep track of all of the directories we checked, so we can mark them as 805 // having module maps if we eventually do find a module map. 806 FixUpDirectories.push_back(Dir); 807 } while (true); 808 } 809 810 Module *HeaderSearch::findModuleForHeader(const FileEntry *File) { 811 if (Module *Mod = ModMap.findModuleForHeader(File)) 812 return Mod; 813 814 return 0; 815 } 816 817 bool HeaderSearch::loadModuleMapFile(const FileEntry *File) { 818 const DirectoryEntry *Dir = File->getDir(); 819 820 llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 821 = DirectoryHasModuleMap.find(Dir); 822 if (KnownDir != DirectoryHasModuleMap.end()) 823 return !KnownDir->second; 824 825 bool Result = ModMap.parseModuleMapFile(File); 826 if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") { 827 // If the file we loaded was a module.map, look for the corresponding 828 // module_private.map. 829 llvm::SmallString<128> PrivateFilename(Dir->getName()); 830 llvm::sys::path::append(PrivateFilename, "module_private.map"); 831 if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename)) 832 Result = ModMap.parseModuleMapFile(PrivateFile); 833 } 834 835 DirectoryHasModuleMap[Dir] = !Result; 836 return Result; 837 } 838 839 Module *HeaderSearch::loadFrameworkModule(StringRef Name, 840 const DirectoryEntry *Dir, 841 bool IsSystem) { 842 if (Module *Module = ModMap.findModule(Name)) 843 return Module; 844 845 // Try to load a module map file. 846 switch (loadModuleMapFile(Dir)) { 847 case LMM_InvalidModuleMap: 848 break; 849 850 case LMM_AlreadyLoaded: 851 case LMM_NoDirectory: 852 return 0; 853 854 case LMM_NewlyLoaded: 855 return ModMap.findModule(Name); 856 } 857 858 // The top-level framework directory, from which we'll infer a framework 859 // module. 860 const DirectoryEntry *TopFrameworkDir = Dir; 861 862 // The path from the module we're actually looking for back to the top-level 863 // framework name. 864 llvm::SmallVector<StringRef, 2> SubmodulePath; 865 SubmodulePath.push_back(Name); 866 867 // Walk the directory structure to find any enclosing frameworks. 868 StringRef DirName = Dir->getName(); 869 do { 870 // Get the parent directory name. 871 DirName = llvm::sys::path::parent_path(DirName); 872 if (DirName.empty()) 873 break; 874 875 // Determine whether this directory exists. 876 Dir = FileMgr.getDirectory(DirName); 877 if (!Dir) 878 break; 879 880 // If this is a framework directory, then we're a subframework of this 881 // framework. 882 if (llvm::sys::path::extension(DirName) == ".framework") { 883 SubmodulePath.push_back(llvm::sys::path::stem(DirName)); 884 TopFrameworkDir = Dir; 885 } 886 } while (true); 887 888 // Try to infer a module map from the top-level framework directory. 889 Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(), 890 TopFrameworkDir, 891 IsSystem, 892 /*Parent=*/0); 893 894 // Follow the submodule path to find the requested (sub)framework module 895 // within the top-level framework module. 896 SubmodulePath.pop_back(); 897 while (!SubmodulePath.empty() && Result) { 898 Result = ModMap.lookupModuleQualified(SubmodulePath.back(), Result); 899 SubmodulePath.pop_back(); 900 } 901 return Result; 902 } 903 904 905 HeaderSearch::LoadModuleMapResult 906 HeaderSearch::loadModuleMapFile(StringRef DirName) { 907 if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 908 return loadModuleMapFile(Dir); 909 910 return LMM_NoDirectory; 911 } 912 913 HeaderSearch::LoadModuleMapResult 914 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) { 915 llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 916 = DirectoryHasModuleMap.find(Dir); 917 if (KnownDir != DirectoryHasModuleMap.end()) 918 return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 919 920 llvm::SmallString<128> ModuleMapFileName; 921 ModuleMapFileName += Dir->getName(); 922 unsigned ModuleMapDirNameLen = ModuleMapFileName.size(); 923 llvm::sys::path::append(ModuleMapFileName, "module.map"); 924 if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 925 // We have found a module map file. Try to parse it. 926 if (ModMap.parseModuleMapFile(ModuleMapFile)) { 927 // No suitable module map. 928 DirectoryHasModuleMap[Dir] = false; 929 return LMM_InvalidModuleMap; 930 } 931 932 // This directory has a module map. 933 DirectoryHasModuleMap[Dir] = true; 934 935 // Check whether there is a private module map that we need to load as well. 936 ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen, 937 ModuleMapFileName.end()); 938 llvm::sys::path::append(ModuleMapFileName, "module_private.map"); 939 if (const FileEntry *PrivateModuleMapFile 940 = FileMgr.getFile(ModuleMapFileName)) { 941 if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) { 942 // No suitable module map. 943 DirectoryHasModuleMap[Dir] = false; 944 return LMM_InvalidModuleMap; 945 } 946 } 947 948 return LMM_NewlyLoaded; 949 } 950 951 // No suitable module map. 952 DirectoryHasModuleMap[Dir] = false; 953 return LMM_InvalidModuleMap; 954 } 955 956 void HeaderSearch::collectAllModules(llvm::SmallVectorImpl<Module *> &Modules) { 957 Modules.clear(); 958 959 // Load module maps for each of the header search directories. 960 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 961 if (SearchDirs[Idx].isFramework()) { 962 llvm::error_code EC; 963 llvm::SmallString<128> DirNative; 964 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), 965 DirNative); 966 967 // Search each of the ".framework" directories to load them as modules. 968 bool IsSystem = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 969 for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 970 Dir != DirEnd && !EC; Dir.increment(EC)) { 971 if (llvm::sys::path::extension(Dir->path()) != ".framework") 972 continue; 973 974 const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); 975 if (!FrameworkDir) 976 continue; 977 978 // Load this framework module. 979 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, 980 IsSystem); 981 } 982 continue; 983 } 984 985 // FIXME: Deal with header maps. 986 if (SearchDirs[Idx].isHeaderMap()) 987 continue; 988 989 // Try to load a module map file for the search directory. 990 loadModuleMapFile(SearchDirs[Idx].getDir()); 991 992 // Try to load module map files for immediate subdirectories of this search 993 // directory. 994 llvm::error_code EC; 995 llvm::SmallString<128> DirNative; 996 llvm::sys::path::native(SearchDirs[Idx].getDir()->getName(), DirNative); 997 for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 998 Dir != DirEnd && !EC; Dir.increment(EC)) { 999 loadModuleMapFile(Dir->path()); 1000 } 1001 } 1002 1003 // Populate the list of modules. 1004 for (ModuleMap::module_iterator M = ModMap.module_begin(), 1005 MEnd = ModMap.module_end(); 1006 M != MEnd; ++M) { 1007 Modules.push_back(M->getValue()); 1008 } 1009 } 1010 1011