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