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 std::string *ModuleFileName, 106 std::string *UmbrellaHeader) { 107 // If we don't have a module cache path, we can't do anything. 108 if (ModuleCachePath.empty()) { 109 if (ModuleFileName) 110 ModuleFileName->clear(); 111 return 0; 112 } 113 114 // Try to find the module path. 115 llvm::SmallString<256> FileName(ModuleCachePath); 116 llvm::sys::path::append(FileName, ModuleName + ".pcm"); 117 if (ModuleFileName) 118 *ModuleFileName = FileName.str(); 119 120 if (const FileEntry *ModuleFile 121 = getFileMgr().getFile(FileName, /*OpenFile=*/false, 122 /*CacheFailure=*/false)) 123 return ModuleFile; 124 125 // We didn't find the module. If we're not supposed to look for an 126 // umbrella header, this is the end of the road. 127 if (!UmbrellaHeader) 128 return 0; 129 130 // Look in the module map to determine if there is a module by this name 131 // that has an umbrella header. 132 // FIXME: Even if it doesn't have an umbrella header, we should be able to 133 // handle the module. However, the caller isn't ready for that yet. 134 if (ModuleMap::Module *Module = ModMap.findModule(ModuleName)) { 135 if (Module->UmbrellaHeader) { 136 *UmbrellaHeader = Module->UmbrellaHeader->getName(); 137 return 0; 138 } 139 } 140 141 // Look in each of the framework directories for an umbrella header with 142 // the same name as the module. 143 llvm::SmallString<128> UmbrellaHeaderName; 144 UmbrellaHeaderName = ModuleName; 145 UmbrellaHeaderName += '/'; 146 UmbrellaHeaderName += ModuleName; 147 UmbrellaHeaderName += ".h"; 148 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 149 // Skip non-framework include paths 150 if (!SearchDirs[Idx].isFramework()) 151 continue; 152 153 // Look for the umbrella header in this directory. 154 if (const FileEntry *HeaderFile 155 = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0, 156 StringRef(), 0)) { 157 *UmbrellaHeader = HeaderFile->getName(); 158 return 0; 159 } 160 } 161 162 // We did not find an umbrella header. Clear out the UmbrellaHeader pointee 163 // so our caller knows that we failed. 164 UmbrellaHeader->clear(); 165 return 0; 166 } 167 168 //===----------------------------------------------------------------------===// 169 // File lookup within a DirectoryLookup scope 170 //===----------------------------------------------------------------------===// 171 172 /// getName - Return the directory or filename corresponding to this lookup 173 /// object. 174 const char *DirectoryLookup::getName() const { 175 if (isNormalDir()) 176 return getDir()->getName(); 177 if (isFramework()) 178 return getFrameworkDir()->getName(); 179 assert(isHeaderMap() && "Unknown DirectoryLookup"); 180 return getHeaderMap()->getFileName(); 181 } 182 183 184 /// LookupFile - Lookup the specified file in this search path, returning it 185 /// if it exists or returning null if not. 186 const FileEntry *DirectoryLookup::LookupFile( 187 StringRef Filename, 188 HeaderSearch &HS, 189 SmallVectorImpl<char> *SearchPath, 190 SmallVectorImpl<char> *RelativePath, 191 StringRef BuildingModule, 192 StringRef *SuggestedModule) const { 193 llvm::SmallString<1024> TmpDir; 194 if (isNormalDir()) { 195 // Concatenate the requested file onto the directory. 196 TmpDir = getDir()->getName(); 197 llvm::sys::path::append(TmpDir, Filename); 198 if (SearchPath != NULL) { 199 StringRef SearchPathRef(getDir()->getName()); 200 SearchPath->clear(); 201 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 202 } 203 if (RelativePath != NULL) { 204 RelativePath->clear(); 205 RelativePath->append(Filename.begin(), Filename.end()); 206 } 207 208 // If we have a module map that might map this header, load it and 209 // check whether we'll have a suggestion for a module. 210 if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) { 211 const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 212 /*openFile=*/false); 213 if (!File) 214 return File; 215 216 // If there is a module that corresponds to this header, 217 // suggest it. 218 StringRef Module = HS.findModuleForHeader(File); 219 if (!Module.empty() && Module != BuildingModule) 220 *SuggestedModule = Module; 221 222 return File; 223 } 224 225 return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); 226 } 227 228 if (isFramework()) 229 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 230 BuildingModule, SuggestedModule); 231 232 assert(isHeaderMap() && "Unknown directory lookup"); 233 const FileEntry * const Result = getHeaderMap()->LookupFile( 234 Filename, HS.getFileMgr()); 235 if (Result) { 236 if (SearchPath != NULL) { 237 StringRef SearchPathRef(getName()); 238 SearchPath->clear(); 239 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 240 } 241 if (RelativePath != NULL) { 242 RelativePath->clear(); 243 RelativePath->append(Filename.begin(), Filename.end()); 244 } 245 } 246 return Result; 247 } 248 249 250 /// DoFrameworkLookup - Do a lookup of the specified file in the current 251 /// DirectoryLookup, which is a framework directory. 252 const FileEntry *DirectoryLookup::DoFrameworkLookup( 253 StringRef Filename, 254 HeaderSearch &HS, 255 SmallVectorImpl<char> *SearchPath, 256 SmallVectorImpl<char> *RelativePath, 257 StringRef BuildingModule, 258 StringRef *SuggestedModule) const 259 { 260 FileManager &FileMgr = HS.getFileMgr(); 261 262 // Framework names must have a '/' in the filename. 263 size_t SlashPos = Filename.find('/'); 264 if (SlashPos == StringRef::npos) return 0; 265 266 // Find out if this is the home for the specified framework, by checking 267 // HeaderSearch. Possible answer are yes/no and unknown. 268 const DirectoryEntry *&FrameworkDirCache = 269 HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 270 271 // If it is known and in some other directory, fail. 272 if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir()) 273 return 0; 274 275 // Otherwise, construct the path to this framework dir. 276 277 // FrameworkName = "/System/Library/Frameworks/" 278 llvm::SmallString<1024> FrameworkName; 279 FrameworkName += getFrameworkDir()->getName(); 280 if (FrameworkName.empty() || FrameworkName.back() != '/') 281 FrameworkName.push_back('/'); 282 283 // FrameworkName = "/System/Library/Frameworks/Cocoa" 284 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 285 286 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 287 FrameworkName += ".framework/"; 288 289 // If the cache entry is still unresolved, query to see if the cache entry is 290 // still unresolved. If so, check its existence now. 291 if (FrameworkDirCache == 0) { 292 HS.IncrementFrameworkLookupCount(); 293 294 // If the framework dir doesn't exist, we fail. 295 // FIXME: It's probably more efficient to query this with FileMgr.getDir. 296 bool Exists; 297 if (llvm::sys::fs::exists(FrameworkName.str(), Exists) || !Exists) 298 return 0; 299 300 // Otherwise, if it does, remember that this is the right direntry for this 301 // framework. 302 FrameworkDirCache = getFrameworkDir(); 303 } 304 305 if (RelativePath != NULL) { 306 RelativePath->clear(); 307 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 308 } 309 310 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 311 unsigned OrigSize = FrameworkName.size(); 312 313 FrameworkName += "Headers/"; 314 315 if (SearchPath != NULL) { 316 SearchPath->clear(); 317 // Without trailing '/'. 318 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 319 } 320 321 /// Determine whether this is the module we're building or not. 322 bool AutomaticImport = SuggestedModule && 323 (BuildingModule != StringRef(Filename.begin(), SlashPos)) && 324 !Filename.substr(SlashPos + 1).startswith(".."); 325 326 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 327 if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 328 /*openFile=*/!AutomaticImport)) { 329 if (AutomaticImport) 330 *SuggestedModule = StringRef(Filename.begin(), SlashPos); 331 return FE; 332 } 333 334 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 335 const char *Private = "Private"; 336 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 337 Private+strlen(Private)); 338 if (SearchPath != NULL) 339 SearchPath->insert(SearchPath->begin()+OrigSize, Private, 340 Private+strlen(Private)); 341 342 const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 343 /*openFile=*/!AutomaticImport); 344 if (FE && AutomaticImport) 345 *SuggestedModule = StringRef(Filename.begin(), SlashPos); 346 return FE; 347 } 348 349 350 //===----------------------------------------------------------------------===// 351 // Header File Location. 352 //===----------------------------------------------------------------------===// 353 354 355 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, 356 /// return null on failure. isAngled indicates whether the file reference is 357 /// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if 358 /// non-null, indicates where the #including file is, in case a relative search 359 /// is needed. 360 const FileEntry *HeaderSearch::LookupFile( 361 StringRef Filename, 362 bool isAngled, 363 const DirectoryLookup *FromDir, 364 const DirectoryLookup *&CurDir, 365 const FileEntry *CurFileEnt, 366 SmallVectorImpl<char> *SearchPath, 367 SmallVectorImpl<char> *RelativePath, 368 StringRef *SuggestedModule) 369 { 370 if (SuggestedModule) 371 *SuggestedModule = StringRef(); 372 373 // If 'Filename' is absolute, check to see if it exists and no searching. 374 if (llvm::sys::path::is_absolute(Filename)) { 375 CurDir = 0; 376 377 // If this was an #include_next "/absolute/file", fail. 378 if (FromDir) return 0; 379 380 if (SearchPath != NULL) 381 SearchPath->clear(); 382 if (RelativePath != NULL) { 383 RelativePath->clear(); 384 RelativePath->append(Filename.begin(), Filename.end()); 385 } 386 // Otherwise, just return the file. 387 return FileMgr.getFile(Filename, /*openFile=*/true); 388 } 389 390 // Unless disabled, check to see if the file is in the #includer's 391 // directory. This has to be based on CurFileEnt, not CurDir, because 392 // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and 393 // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". 394 // This search is not done for <> headers. 395 if (CurFileEnt && !isAngled && !NoCurDirSearch) { 396 llvm::SmallString<1024> TmpDir; 397 // Concatenate the requested file onto the directory. 398 // FIXME: Portability. Filename concatenation should be in sys::Path. 399 TmpDir += CurFileEnt->getDir()->getName(); 400 TmpDir.push_back('/'); 401 TmpDir.append(Filename.begin(), Filename.end()); 402 if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { 403 // Leave CurDir unset. 404 // This file is a system header or C++ unfriendly if the old file is. 405 // 406 // Note that the temporary 'DirInfo' is required here, as either call to 407 // getFileInfo could resize the vector and we don't want to rely on order 408 // of evaluation. 409 unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo; 410 getFileInfo(FE).DirInfo = DirInfo; 411 if (SearchPath != NULL) { 412 StringRef SearchPathRef(CurFileEnt->getDir()->getName()); 413 SearchPath->clear(); 414 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 415 } 416 if (RelativePath != NULL) { 417 RelativePath->clear(); 418 RelativePath->append(Filename.begin(), Filename.end()); 419 } 420 return FE; 421 } 422 } 423 424 CurDir = 0; 425 426 // If this is a system #include, ignore the user #include locs. 427 unsigned i = isAngled ? AngledDirIdx : 0; 428 429 // If this is a #include_next request, start searching after the directory the 430 // file was found in. 431 if (FromDir) 432 i = FromDir-&SearchDirs[0]; 433 434 // Cache all of the lookups performed by this method. Many headers are 435 // multiply included, and the "pragma once" optimization prevents them from 436 // being relex/pp'd, but they would still have to search through a 437 // (potentially huge) series of SearchDirs to find it. 438 std::pair<unsigned, unsigned> &CacheLookup = 439 LookupFileCache.GetOrCreateValue(Filename).getValue(); 440 441 // If the entry has been previously looked up, the first value will be 442 // non-zero. If the value is equal to i (the start point of our search), then 443 // this is a matching hit. 444 if (CacheLookup.first == i+1) { 445 // Skip querying potentially lots of directories for this lookup. 446 i = CacheLookup.second; 447 } else { 448 // Otherwise, this is the first query, or the previous query didn't match 449 // our search start. We will fill in our found location below, so prime the 450 // start point value. 451 CacheLookup.first = i+1; 452 } 453 454 // Check each directory in sequence to see if it contains this file. 455 for (; i != SearchDirs.size(); ++i) { 456 const FileEntry *FE = 457 SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 458 BuildingModule, SuggestedModule); 459 if (!FE) continue; 460 461 CurDir = &SearchDirs[i]; 462 463 // This file is a system header or C++ unfriendly if the dir is. 464 HeaderFileInfo &HFI = getFileInfo(FE); 465 HFI.DirInfo = CurDir->getDirCharacteristic(); 466 467 // If this file is found in a header map and uses the framework style of 468 // includes, then this header is part of a framework we're building. 469 if (CurDir->isIndexHeaderMap()) { 470 size_t SlashPos = Filename.find('/'); 471 if (SlashPos != StringRef::npos) { 472 HFI.IndexHeaderMapHeader = 1; 473 HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 474 SlashPos)); 475 } 476 } 477 478 // Remember this location for the next lookup we do. 479 CacheLookup.second = i; 480 return FE; 481 } 482 483 // If we are including a file with a quoted include "foo.h" from inside 484 // a header in a framework that is currently being built, and we couldn't 485 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 486 // "Foo" is the name of the framework in which the including header was found. 487 if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { 488 HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); 489 if (IncludingHFI.IndexHeaderMapHeader) { 490 llvm::SmallString<128> ScratchFilename; 491 ScratchFilename += IncludingHFI.Framework; 492 ScratchFilename += '/'; 493 ScratchFilename += Filename; 494 495 const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true, 496 FromDir, CurDir, CurFileEnt, 497 SearchPath, RelativePath, 498 SuggestedModule); 499 std::pair<unsigned, unsigned> &CacheLookup 500 = LookupFileCache.GetOrCreateValue(Filename).getValue(); 501 CacheLookup.second 502 = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second; 503 return Result; 504 } 505 } 506 507 // Otherwise, didn't find it. Remember we didn't find this. 508 CacheLookup.second = SearchDirs.size(); 509 return 0; 510 } 511 512 /// LookupSubframeworkHeader - Look up a subframework for the specified 513 /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from 514 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 515 /// is a subframework within Carbon.framework. If so, return the FileEntry 516 /// for the designated file, otherwise return null. 517 const FileEntry *HeaderSearch:: 518 LookupSubframeworkHeader(StringRef Filename, 519 const FileEntry *ContextFileEnt, 520 SmallVectorImpl<char> *SearchPath, 521 SmallVectorImpl<char> *RelativePath) { 522 assert(ContextFileEnt && "No context file?"); 523 524 // Framework names must have a '/' in the filename. Find it. 525 size_t SlashPos = Filename.find('/'); 526 if (SlashPos == StringRef::npos) return 0; 527 528 // Look up the base framework name of the ContextFileEnt. 529 const char *ContextName = ContextFileEnt->getName(); 530 531 // If the context info wasn't a framework, couldn't be a subframework. 532 const char *FrameworkPos = strstr(ContextName, ".framework/"); 533 if (FrameworkPos == 0) 534 return 0; 535 536 llvm::SmallString<1024> FrameworkName(ContextName, 537 FrameworkPos+strlen(".framework/")); 538 539 // Append Frameworks/HIToolbox.framework/ 540 FrameworkName += "Frameworks/"; 541 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 542 FrameworkName += ".framework/"; 543 544 llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup = 545 FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 546 547 // Some other location? 548 if (CacheLookup.getValue() && 549 CacheLookup.getKeyLength() == FrameworkName.size() && 550 memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 551 CacheLookup.getKeyLength()) != 0) 552 return 0; 553 554 // Cache subframework. 555 if (CacheLookup.getValue() == 0) { 556 ++NumSubFrameworkLookups; 557 558 // If the framework dir doesn't exist, we fail. 559 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 560 if (Dir == 0) return 0; 561 562 // Otherwise, if it does, remember that this is the right direntry for this 563 // framework. 564 CacheLookup.setValue(Dir); 565 } 566 567 const FileEntry *FE = 0; 568 569 if (RelativePath != NULL) { 570 RelativePath->clear(); 571 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 572 } 573 574 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 575 llvm::SmallString<1024> HeadersFilename(FrameworkName); 576 HeadersFilename += "Headers/"; 577 if (SearchPath != NULL) { 578 SearchPath->clear(); 579 // Without trailing '/'. 580 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 581 } 582 583 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 584 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 585 586 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 587 HeadersFilename = FrameworkName; 588 HeadersFilename += "PrivateHeaders/"; 589 if (SearchPath != NULL) { 590 SearchPath->clear(); 591 // Without trailing '/'. 592 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 593 } 594 595 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 596 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 597 return 0; 598 } 599 600 // This file is a system header or C++ unfriendly if the old file is. 601 // 602 // Note that the temporary 'DirInfo' is required here, as either call to 603 // getFileInfo could resize the vector and we don't want to rely on order 604 // of evaluation. 605 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 606 getFileInfo(FE).DirInfo = DirInfo; 607 return FE; 608 } 609 610 //===----------------------------------------------------------------------===// 611 // File Info Management. 612 //===----------------------------------------------------------------------===// 613 614 /// \brief Merge the header file info provided by \p OtherHFI into the current 615 /// header file info (\p HFI) 616 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 617 const HeaderFileInfo &OtherHFI) { 618 HFI.isImport |= OtherHFI.isImport; 619 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 620 HFI.NumIncludes += OtherHFI.NumIncludes; 621 622 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 623 HFI.ControllingMacro = OtherHFI.ControllingMacro; 624 HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 625 } 626 627 if (OtherHFI.External) { 628 HFI.DirInfo = OtherHFI.DirInfo; 629 HFI.External = OtherHFI.External; 630 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 631 } 632 633 if (HFI.Framework.empty()) 634 HFI.Framework = OtherHFI.Framework; 635 636 HFI.Resolved = true; 637 } 638 639 /// getFileInfo - Return the HeaderFileInfo structure for the specified 640 /// FileEntry. 641 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 642 if (FE->getUID() >= FileInfo.size()) 643 FileInfo.resize(FE->getUID()+1); 644 645 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 646 if (ExternalSource && !HFI.Resolved) 647 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 648 return HFI; 649 } 650 651 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 652 // Check if we've ever seen this file as a header. 653 if (File->getUID() >= FileInfo.size()) 654 return false; 655 656 // Resolve header file info from the external source, if needed. 657 HeaderFileInfo &HFI = FileInfo[File->getUID()]; 658 if (ExternalSource && !HFI.Resolved) 659 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 660 661 return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID; 662 } 663 664 void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { 665 if (UID >= FileInfo.size()) 666 FileInfo.resize(UID+1); 667 HFI.Resolved = true; 668 FileInfo[UID] = HFI; 669 } 670 671 /// ShouldEnterIncludeFile - Mark the specified file as a target of of a 672 /// #include, #include_next, or #import directive. Return false if #including 673 /// the file will have no effect or true if we should include it. 674 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 675 ++NumIncluded; // Count # of attempted #includes. 676 677 // Get information about this file. 678 HeaderFileInfo &FileInfo = getFileInfo(File); 679 680 // If this is a #import directive, check that we have not already imported 681 // this header. 682 if (isImport) { 683 // If this has already been imported, don't import it again. 684 FileInfo.isImport = true; 685 686 // Has this already been #import'ed or #include'd? 687 if (FileInfo.NumIncludes) return false; 688 } else { 689 // Otherwise, if this is a #include of a file that was previously #import'd 690 // or if this is the second #include of a #pragma once file, ignore it. 691 if (FileInfo.isImport) 692 return false; 693 } 694 695 // Next, check to see if the file is wrapped with #ifndef guards. If so, and 696 // if the macro that guards it is defined, we know the #include has no effect. 697 if (const IdentifierInfo *ControllingMacro 698 = FileInfo.getControllingMacro(ExternalLookup)) 699 if (ControllingMacro->hasMacroDefinition()) { 700 ++NumMultiIncludeFileOptzn; 701 return false; 702 } 703 704 // Increment the number of times this file has been included. 705 ++FileInfo.NumIncludes; 706 707 return true; 708 } 709 710 size_t HeaderSearch::getTotalMemory() const { 711 return SearchDirs.capacity() 712 + llvm::capacity_in_bytes(FileInfo) 713 + llvm::capacity_in_bytes(HeaderMaps) 714 + LookupFileCache.getAllocator().getTotalMemory() 715 + FrameworkMap.getAllocator().getTotalMemory(); 716 } 717 718 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 719 return FrameworkNames.GetOrCreateValue(Framework).getKey(); 720 } 721 722 bool HeaderSearch::hasModuleMap(StringRef FileName, 723 const DirectoryEntry *Root) { 724 llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 725 726 StringRef DirName = FileName; 727 do { 728 // Get the parent directory name. 729 DirName = llvm::sys::path::parent_path(DirName); 730 if (DirName.empty()) 731 return false; 732 733 // Determine whether this directory exists. 734 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 735 if (!Dir) 736 return false; 737 738 llvm::DenseMap<const DirectoryEntry *, bool>::iterator 739 KnownDir = DirectoryHasModuleMap.find(Dir); 740 if (KnownDir != DirectoryHasModuleMap.end()) { 741 // We have seen this directory before. If it has no module map file, 742 // we're done. 743 if (!KnownDir->second) 744 return false; 745 746 // All of the directories we stepped through inherit this module map 747 // file. 748 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 749 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 750 751 return true; 752 } 753 754 // We have not checked for a module map file in this directory yet; 755 // do so now. 756 llvm::SmallString<128> ModuleMapFileName; 757 ModuleMapFileName += Dir->getName(); 758 llvm::sys::path::append(ModuleMapFileName, "module.map"); 759 if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 760 // We have found a module map file. Try to parse it. 761 if (!ModMap.parseModuleMapFile(ModuleMapFile)) { 762 // This directory has a module map. 763 DirectoryHasModuleMap[Dir] = true; 764 765 // All of the directories we stepped through inherit this module map 766 // file. 767 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 768 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 769 770 return true; 771 } 772 } 773 774 // This directory did not have a module map file. 775 DirectoryHasModuleMap[Dir] = false; 776 777 // Keep track of all of the directories we checked, so we can mark them as 778 // having module maps if we eventually do find a module map. 779 FixUpDirectories.push_back(Dir); 780 } while (true); 781 782 return false; 783 } 784 785 StringRef HeaderSearch::findModuleForHeader(const FileEntry *File) { 786 if (ModuleMap::Module *Module = ModMap.findModuleForHeader(File)) 787 return Module->getTopLevelModuleName(); 788 789 return StringRef(); 790 } 791 792 793