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 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 BuildingModule, 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 size_t SlashPos = Filename.find('/'); 546 if (SlashPos == StringRef::npos) return 0; 547 548 // Look up the base framework name of the ContextFileEnt. 549 const char *ContextName = ContextFileEnt->getName(); 550 551 // If the context info wasn't a framework, couldn't be a subframework. 552 const char *FrameworkPos = strstr(ContextName, ".framework/"); 553 if (FrameworkPos == 0) 554 return 0; 555 556 llvm::SmallString<1024> FrameworkName(ContextName, 557 FrameworkPos+strlen(".framework/")); 558 559 // Append Frameworks/HIToolbox.framework/ 560 FrameworkName += "Frameworks/"; 561 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 562 FrameworkName += ".framework/"; 563 564 llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup = 565 FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 566 567 // Some other location? 568 if (CacheLookup.getValue() && 569 CacheLookup.getKeyLength() == FrameworkName.size() && 570 memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 571 CacheLookup.getKeyLength()) != 0) 572 return 0; 573 574 // Cache subframework. 575 if (CacheLookup.getValue() == 0) { 576 ++NumSubFrameworkLookups; 577 578 // If the framework dir doesn't exist, we fail. 579 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 580 if (Dir == 0) return 0; 581 582 // Otherwise, if it does, remember that this is the right direntry for this 583 // framework. 584 CacheLookup.setValue(Dir); 585 } 586 587 const FileEntry *FE = 0; 588 589 if (RelativePath != NULL) { 590 RelativePath->clear(); 591 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 592 } 593 594 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 595 llvm::SmallString<1024> HeadersFilename(FrameworkName); 596 HeadersFilename += "Headers/"; 597 if (SearchPath != NULL) { 598 SearchPath->clear(); 599 // Without trailing '/'. 600 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 601 } 602 603 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 604 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 605 606 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 607 HeadersFilename = FrameworkName; 608 HeadersFilename += "PrivateHeaders/"; 609 if (SearchPath != NULL) { 610 SearchPath->clear(); 611 // Without trailing '/'. 612 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 613 } 614 615 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 616 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 617 return 0; 618 } 619 620 // This file is a system header or C++ unfriendly if the old file is. 621 // 622 // Note that the temporary 'DirInfo' is required here, as either call to 623 // getFileInfo could resize the vector and we don't want to rely on order 624 // of evaluation. 625 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 626 getFileInfo(FE).DirInfo = DirInfo; 627 return FE; 628 } 629 630 //===----------------------------------------------------------------------===// 631 // File Info Management. 632 //===----------------------------------------------------------------------===// 633 634 /// \brief Merge the header file info provided by \p OtherHFI into the current 635 /// header file info (\p HFI) 636 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 637 const HeaderFileInfo &OtherHFI) { 638 HFI.isImport |= OtherHFI.isImport; 639 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 640 HFI.NumIncludes += OtherHFI.NumIncludes; 641 642 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 643 HFI.ControllingMacro = OtherHFI.ControllingMacro; 644 HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 645 } 646 647 if (OtherHFI.External) { 648 HFI.DirInfo = OtherHFI.DirInfo; 649 HFI.External = OtherHFI.External; 650 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 651 } 652 653 if (HFI.Framework.empty()) 654 HFI.Framework = OtherHFI.Framework; 655 656 HFI.Resolved = true; 657 } 658 659 /// getFileInfo - Return the HeaderFileInfo structure for the specified 660 /// FileEntry. 661 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 662 if (FE->getUID() >= FileInfo.size()) 663 FileInfo.resize(FE->getUID()+1); 664 665 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 666 if (ExternalSource && !HFI.Resolved) 667 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 668 return HFI; 669 } 670 671 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 672 // Check if we've ever seen this file as a header. 673 if (File->getUID() >= FileInfo.size()) 674 return false; 675 676 // Resolve header file info from the external source, if needed. 677 HeaderFileInfo &HFI = FileInfo[File->getUID()]; 678 if (ExternalSource && !HFI.Resolved) 679 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 680 681 return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID; 682 } 683 684 void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { 685 if (UID >= FileInfo.size()) 686 FileInfo.resize(UID+1); 687 HFI.Resolved = true; 688 FileInfo[UID] = HFI; 689 } 690 691 /// ShouldEnterIncludeFile - Mark the specified file as a target of of a 692 /// #include, #include_next, or #import directive. Return false if #including 693 /// the file will have no effect or true if we should include it. 694 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 695 ++NumIncluded; // Count # of attempted #includes. 696 697 // Get information about this file. 698 HeaderFileInfo &FileInfo = getFileInfo(File); 699 700 // If this is a #import directive, check that we have not already imported 701 // this header. 702 if (isImport) { 703 // If this has already been imported, don't import it again. 704 FileInfo.isImport = true; 705 706 // Has this already been #import'ed or #include'd? 707 if (FileInfo.NumIncludes) return false; 708 } else { 709 // Otherwise, if this is a #include of a file that was previously #import'd 710 // or if this is the second #include of a #pragma once file, ignore it. 711 if (FileInfo.isImport) 712 return false; 713 } 714 715 // Next, check to see if the file is wrapped with #ifndef guards. If so, and 716 // if the macro that guards it is defined, we know the #include has no effect. 717 if (const IdentifierInfo *ControllingMacro 718 = FileInfo.getControllingMacro(ExternalLookup)) 719 if (ControllingMacro->hasMacroDefinition()) { 720 ++NumMultiIncludeFileOptzn; 721 return false; 722 } 723 724 // Increment the number of times this file has been included. 725 ++FileInfo.NumIncludes; 726 727 return true; 728 } 729 730 size_t HeaderSearch::getTotalMemory() const { 731 return SearchDirs.capacity() 732 + llvm::capacity_in_bytes(FileInfo) 733 + llvm::capacity_in_bytes(HeaderMaps) 734 + LookupFileCache.getAllocator().getTotalMemory() 735 + FrameworkMap.getAllocator().getTotalMemory(); 736 } 737 738 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 739 return FrameworkNames.GetOrCreateValue(Framework).getKey(); 740 } 741 742 bool HeaderSearch::hasModuleMap(StringRef FileName, 743 const DirectoryEntry *Root) { 744 llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 745 746 StringRef DirName = FileName; 747 do { 748 // Get the parent directory name. 749 DirName = llvm::sys::path::parent_path(DirName); 750 if (DirName.empty()) 751 return false; 752 753 // Determine whether this directory exists. 754 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 755 if (!Dir) 756 return false; 757 758 // Try to load the module map file in this directory. 759 switch (loadModuleMapFile(Dir)) { 760 case LMM_NewlyLoaded: 761 case LMM_AlreadyLoaded: 762 // Success. All of the directories we stepped through inherit this module 763 // map file. 764 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 765 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 766 767 return true; 768 769 case LMM_NoDirectory: 770 case LMM_InvalidModuleMap: 771 break; 772 } 773 774 // If we hit the top of our search, we're done. 775 if (Dir == Root) 776 return false; 777 778 // Keep track of all of the directories we checked, so we can mark them as 779 // having module maps if we eventually do find a module map. 780 FixUpDirectories.push_back(Dir); 781 } while (true); 782 783 return false; 784 } 785 786 Module *HeaderSearch::findModuleForHeader(const FileEntry *File) { 787 if (Module *Module = ModMap.findModuleForHeader(File)) 788 return Module; 789 790 return 0; 791 } 792 793 bool HeaderSearch::loadModuleMapFile(const FileEntry *File) { 794 const DirectoryEntry *Dir = File->getDir(); 795 796 llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 797 = DirectoryHasModuleMap.find(Dir); 798 if (KnownDir != DirectoryHasModuleMap.end()) 799 return !KnownDir->second; 800 801 bool Result = ModMap.parseModuleMapFile(File); 802 if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") { 803 // If the file we loaded was a module.map, look for the corresponding 804 // module_private.map. 805 llvm::SmallString<128> PrivateFilename(Dir->getName()); 806 llvm::sys::path::append(PrivateFilename, "module_private.map"); 807 if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename)) 808 Result = ModMap.parseModuleMapFile(PrivateFile); 809 } 810 811 DirectoryHasModuleMap[Dir] = !Result; 812 return Result; 813 } 814 815 Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { 816 if (Module *Module = ModMap.findModule(Name)) 817 return Module; 818 819 if (!AllowSearch) 820 return 0; 821 822 for (unsigned I = 0, N = SearchDirs.size(); I != N; ++I) { 823 if (!SearchDirs[I].isNormalDir()) 824 continue; 825 826 switch (loadModuleMapFile(SearchDirs[I].getDir())) { 827 case LMM_AlreadyLoaded: 828 case LMM_InvalidModuleMap: 829 case LMM_NoDirectory: 830 break; 831 832 case LMM_NewlyLoaded: 833 if (Module *Module = ModMap.findModule(Name)) 834 return Module; 835 break; 836 } 837 } 838 839 return 0; 840 } 841 842 Module *HeaderSearch::getFrameworkModule(StringRef Name, 843 const DirectoryEntry *Dir) { 844 if (Module *Module = ModMap.findModule(Name)) 845 return Module; 846 847 // Try to load a module map file. 848 switch (loadModuleMapFile(Dir)) { 849 case LMM_InvalidModuleMap: 850 break; 851 852 case LMM_AlreadyLoaded: 853 case LMM_NoDirectory: 854 return 0; 855 856 case LMM_NewlyLoaded: 857 return ModMap.findModule(Name); 858 } 859 860 // Try to infer a module map. 861 return ModMap.inferFrameworkModule(Name, Dir, /*Parent=*/0); 862 } 863 864 865 HeaderSearch::LoadModuleMapResult 866 HeaderSearch::loadModuleMapFile(StringRef DirName) { 867 if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 868 return loadModuleMapFile(Dir); 869 870 return LMM_NoDirectory; 871 } 872 873 HeaderSearch::LoadModuleMapResult 874 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) { 875 llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 876 = DirectoryHasModuleMap.find(Dir); 877 if (KnownDir != DirectoryHasModuleMap.end()) 878 return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 879 880 llvm::SmallString<128> ModuleMapFileName; 881 ModuleMapFileName += Dir->getName(); 882 unsigned ModuleMapDirNameLen = ModuleMapFileName.size(); 883 llvm::sys::path::append(ModuleMapFileName, "module.map"); 884 if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 885 // We have found a module map file. Try to parse it. 886 if (ModMap.parseModuleMapFile(ModuleMapFile)) { 887 // No suitable module map. 888 DirectoryHasModuleMap[Dir] = false; 889 return LMM_InvalidModuleMap; 890 } 891 892 // This directory has a module map. 893 DirectoryHasModuleMap[Dir] = true; 894 895 // Check whether there is a private module map that we need to load as well. 896 ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen, 897 ModuleMapFileName.end()); 898 llvm::sys::path::append(ModuleMapFileName, "module_private.map"); 899 if (const FileEntry *PrivateModuleMapFile 900 = FileMgr.getFile(ModuleMapFileName)) { 901 if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) { 902 // No suitable module map. 903 DirectoryHasModuleMap[Dir] = false; 904 return LMM_InvalidModuleMap; 905 } 906 } 907 908 return LMM_NewlyLoaded; 909 } 910 911 // No suitable module map. 912 DirectoryHasModuleMap[Dir] = false; 913 return LMM_InvalidModuleMap; 914 } 915 916