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 Module **SuggestedModule) const { 201 llvm::SmallString<1024> TmpDir; 202 if (isNormalDir()) { 203 // Concatenate the requested file onto the directory. 204 TmpDir = getDir()->getName(); 205 llvm::sys::path::append(TmpDir, Filename); 206 if (SearchPath != NULL) { 207 StringRef SearchPathRef(getDir()->getName()); 208 SearchPath->clear(); 209 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 210 } 211 if (RelativePath != NULL) { 212 RelativePath->clear(); 213 RelativePath->append(Filename.begin(), Filename.end()); 214 } 215 216 // If we have a module map that might map this header, load it and 217 // check whether we'll have a suggestion for a module. 218 if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) { 219 const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 220 /*openFile=*/false); 221 if (!File) 222 return File; 223 224 // If there is a module that corresponds to this header, 225 // suggest it. 226 *SuggestedModule = HS.findModuleForHeader(File); 227 return File; 228 } 229 230 return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); 231 } 232 233 if (isFramework()) 234 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 235 SuggestedModule); 236 237 assert(isHeaderMap() && "Unknown directory lookup"); 238 const FileEntry * const Result = getHeaderMap()->LookupFile( 239 Filename, HS.getFileMgr()); 240 if (Result) { 241 if (SearchPath != NULL) { 242 StringRef SearchPathRef(getName()); 243 SearchPath->clear(); 244 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 245 } 246 if (RelativePath != NULL) { 247 RelativePath->clear(); 248 RelativePath->append(Filename.begin(), Filename.end()); 249 } 250 } 251 return Result; 252 } 253 254 255 /// DoFrameworkLookup - Do a lookup of the specified file in the current 256 /// DirectoryLookup, which is a framework directory. 257 const FileEntry *DirectoryLookup::DoFrameworkLookup( 258 StringRef Filename, 259 HeaderSearch &HS, 260 SmallVectorImpl<char> *SearchPath, 261 SmallVectorImpl<char> *RelativePath, 262 Module **SuggestedModule) const 263 { 264 FileManager &FileMgr = HS.getFileMgr(); 265 266 // Framework names must have a '/' in the filename. 267 size_t SlashPos = Filename.find('/'); 268 if (SlashPos == StringRef::npos) return 0; 269 270 // Find out if this is the home for the specified framework, by checking 271 // HeaderSearch. Possible answer are yes/no and unknown. 272 const DirectoryEntry *&FrameworkDirCache = 273 HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 274 275 // If it is known and in some other directory, fail. 276 if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir()) 277 return 0; 278 279 // Otherwise, construct the path to this framework dir. 280 281 // FrameworkName = "/System/Library/Frameworks/" 282 llvm::SmallString<1024> FrameworkName; 283 FrameworkName += getFrameworkDir()->getName(); 284 if (FrameworkName.empty() || FrameworkName.back() != '/') 285 FrameworkName.push_back('/'); 286 287 // FrameworkName = "/System/Library/Frameworks/Cocoa" 288 StringRef ModuleName(Filename.begin(), SlashPos); 289 FrameworkName += ModuleName; 290 291 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 292 FrameworkName += ".framework/"; 293 294 // If the cache entry is still unresolved, query to see if the cache entry is 295 // still unresolved. If so, check its existence now. 296 if (FrameworkDirCache == 0) { 297 HS.IncrementFrameworkLookupCount(); 298 299 // If the framework dir doesn't exist, we fail. 300 // FIXME: It's probably more efficient to query this with FileMgr.getDir. 301 bool Exists; 302 if (llvm::sys::fs::exists(FrameworkName.str(), Exists) || !Exists) 303 return 0; 304 305 // Otherwise, if it does, remember that this is the right direntry for this 306 // framework. 307 FrameworkDirCache = getFrameworkDir(); 308 } 309 310 if (RelativePath != NULL) { 311 RelativePath->clear(); 312 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 313 } 314 315 // If we're allowed to look for modules, try to load or create the module 316 // corresponding to this framework. 317 Module *Module = 0; 318 if (SuggestedModule) { 319 if (const DirectoryEntry *FrameworkDir 320 = FileMgr.getDirectory(FrameworkName)) 321 Module = HS.getFrameworkModule(ModuleName, FrameworkDir); 322 } 323 324 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 325 unsigned OrigSize = FrameworkName.size(); 326 327 FrameworkName += "Headers/"; 328 329 if (SearchPath != NULL) { 330 SearchPath->clear(); 331 // Without trailing '/'. 332 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 333 } 334 335 // Determine whether this is the module we're building or not. 336 bool AutomaticImport = Module; 337 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 338 if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 339 /*openFile=*/!AutomaticImport)) { 340 if (AutomaticImport) 341 *SuggestedModule = HS.findModuleForHeader(FE); 342 return FE; 343 } 344 345 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 346 const char *Private = "Private"; 347 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 348 Private+strlen(Private)); 349 if (SearchPath != NULL) 350 SearchPath->insert(SearchPath->begin()+OrigSize, Private, 351 Private+strlen(Private)); 352 353 const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 354 /*openFile=*/!AutomaticImport); 355 if (FE && AutomaticImport) 356 *SuggestedModule = HS.findModuleForHeader(FE); 357 return FE; 358 } 359 360 361 //===----------------------------------------------------------------------===// 362 // Header File Location. 363 //===----------------------------------------------------------------------===// 364 365 366 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, 367 /// return null on failure. isAngled indicates whether the file reference is 368 /// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if 369 /// non-null, indicates where the #including file is, in case a relative search 370 /// is needed. 371 const FileEntry *HeaderSearch::LookupFile( 372 StringRef Filename, 373 bool isAngled, 374 const DirectoryLookup *FromDir, 375 const DirectoryLookup *&CurDir, 376 const FileEntry *CurFileEnt, 377 SmallVectorImpl<char> *SearchPath, 378 SmallVectorImpl<char> *RelativePath, 379 Module **SuggestedModule, 380 bool SkipCache) 381 { 382 if (SuggestedModule) 383 *SuggestedModule = 0; 384 385 // If 'Filename' is absolute, check to see if it exists and no searching. 386 if (llvm::sys::path::is_absolute(Filename)) { 387 CurDir = 0; 388 389 // If this was an #include_next "/absolute/file", fail. 390 if (FromDir) return 0; 391 392 if (SearchPath != NULL) 393 SearchPath->clear(); 394 if (RelativePath != NULL) { 395 RelativePath->clear(); 396 RelativePath->append(Filename.begin(), Filename.end()); 397 } 398 // Otherwise, just return the file. 399 return FileMgr.getFile(Filename, /*openFile=*/true); 400 } 401 402 // Unless disabled, check to see if the file is in the #includer's 403 // directory. This has to be based on CurFileEnt, not CurDir, because 404 // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and 405 // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". 406 // This search is not done for <> headers. 407 if (CurFileEnt && !isAngled && !NoCurDirSearch) { 408 llvm::SmallString<1024> TmpDir; 409 // Concatenate the requested file onto the directory. 410 // FIXME: Portability. Filename concatenation should be in sys::Path. 411 TmpDir += CurFileEnt->getDir()->getName(); 412 TmpDir.push_back('/'); 413 TmpDir.append(Filename.begin(), Filename.end()); 414 if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { 415 // Leave CurDir unset. 416 // This file is a system header or C++ unfriendly if the old file is. 417 // 418 // Note that the temporary 'DirInfo' is required here, as either call to 419 // getFileInfo could resize the vector and we don't want to rely on order 420 // of evaluation. 421 unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo; 422 getFileInfo(FE).DirInfo = DirInfo; 423 if (SearchPath != NULL) { 424 StringRef SearchPathRef(CurFileEnt->getDir()->getName()); 425 SearchPath->clear(); 426 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 427 } 428 if (RelativePath != NULL) { 429 RelativePath->clear(); 430 RelativePath->append(Filename.begin(), Filename.end()); 431 } 432 return FE; 433 } 434 } 435 436 CurDir = 0; 437 438 // If this is a system #include, ignore the user #include locs. 439 unsigned i = isAngled ? AngledDirIdx : 0; 440 441 // If this is a #include_next request, start searching after the directory the 442 // file was found in. 443 if (FromDir) 444 i = FromDir-&SearchDirs[0]; 445 446 // Cache all of the lookups performed by this method. Many headers are 447 // multiply included, and the "pragma once" optimization prevents them from 448 // being relex/pp'd, but they would still have to search through a 449 // (potentially huge) series of SearchDirs to find it. 450 std::pair<unsigned, unsigned> &CacheLookup = 451 LookupFileCache.GetOrCreateValue(Filename).getValue(); 452 453 // If the entry has been previously looked up, the first value will be 454 // non-zero. If the value is equal to i (the start point of our search), then 455 // this is a matching hit. 456 if (!SkipCache && CacheLookup.first == i+1) { 457 // Skip querying potentially lots of directories for this lookup. 458 i = CacheLookup.second; 459 } else { 460 // Otherwise, this is the first query, or the previous query didn't match 461 // our search start. We will fill in our found location below, so prime the 462 // start point value. 463 CacheLookup.first = i+1; 464 } 465 466 // Check each directory in sequence to see if it contains this file. 467 for (; i != SearchDirs.size(); ++i) { 468 const FileEntry *FE = 469 SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 470 SuggestedModule); 471 if (!FE) continue; 472 473 CurDir = &SearchDirs[i]; 474 475 // This file is a system header or C++ unfriendly if the dir is. 476 HeaderFileInfo &HFI = getFileInfo(FE); 477 HFI.DirInfo = CurDir->getDirCharacteristic(); 478 479 // If this file is found in a header map and uses the framework style of 480 // includes, then this header is part of a framework we're building. 481 if (CurDir->isIndexHeaderMap()) { 482 size_t SlashPos = Filename.find('/'); 483 if (SlashPos != StringRef::npos) { 484 HFI.IndexHeaderMapHeader = 1; 485 HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 486 SlashPos)); 487 } 488 } 489 490 // Remember this location for the next lookup we do. 491 CacheLookup.second = i; 492 return FE; 493 } 494 495 // If we are including a file with a quoted include "foo.h" from inside 496 // a header in a framework that is currently being built, and we couldn't 497 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 498 // "Foo" is the name of the framework in which the including header was found. 499 if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { 500 HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); 501 if (IncludingHFI.IndexHeaderMapHeader) { 502 llvm::SmallString<128> ScratchFilename; 503 ScratchFilename += IncludingHFI.Framework; 504 ScratchFilename += '/'; 505 ScratchFilename += Filename; 506 507 const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true, 508 FromDir, CurDir, CurFileEnt, 509 SearchPath, RelativePath, 510 SuggestedModule); 511 std::pair<unsigned, unsigned> &CacheLookup 512 = LookupFileCache.GetOrCreateValue(Filename).getValue(); 513 CacheLookup.second 514 = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second; 515 return Result; 516 } 517 } 518 519 // Otherwise, didn't find it. Remember we didn't find this. 520 CacheLookup.second = SearchDirs.size(); 521 return 0; 522 } 523 524 /// LookupSubframeworkHeader - Look up a subframework for the specified 525 /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from 526 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 527 /// is a subframework within Carbon.framework. If so, return the FileEntry 528 /// for the designated file, otherwise return null. 529 const FileEntry *HeaderSearch:: 530 LookupSubframeworkHeader(StringRef Filename, 531 const FileEntry *ContextFileEnt, 532 SmallVectorImpl<char> *SearchPath, 533 SmallVectorImpl<char> *RelativePath) { 534 assert(ContextFileEnt && "No context file?"); 535 536 // Framework names must have a '/' in the filename. Find it. 537 size_t SlashPos = Filename.find('/'); 538 if (SlashPos == StringRef::npos) return 0; 539 540 // Look up the base framework name of the ContextFileEnt. 541 const char *ContextName = ContextFileEnt->getName(); 542 543 // If the context info wasn't a framework, couldn't be a subframework. 544 const char *FrameworkPos = strstr(ContextName, ".framework/"); 545 if (FrameworkPos == 0) 546 return 0; 547 548 llvm::SmallString<1024> FrameworkName(ContextName, 549 FrameworkPos+strlen(".framework/")); 550 551 // Append Frameworks/HIToolbox.framework/ 552 FrameworkName += "Frameworks/"; 553 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 554 FrameworkName += ".framework/"; 555 556 llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup = 557 FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 558 559 // Some other location? 560 if (CacheLookup.getValue() && 561 CacheLookup.getKeyLength() == FrameworkName.size() && 562 memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 563 CacheLookup.getKeyLength()) != 0) 564 return 0; 565 566 // Cache subframework. 567 if (CacheLookup.getValue() == 0) { 568 ++NumSubFrameworkLookups; 569 570 // If the framework dir doesn't exist, we fail. 571 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 572 if (Dir == 0) return 0; 573 574 // Otherwise, if it does, remember that this is the right direntry for this 575 // framework. 576 CacheLookup.setValue(Dir); 577 } 578 579 const FileEntry *FE = 0; 580 581 if (RelativePath != NULL) { 582 RelativePath->clear(); 583 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 584 } 585 586 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 587 llvm::SmallString<1024> HeadersFilename(FrameworkName); 588 HeadersFilename += "Headers/"; 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 598 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 599 HeadersFilename = FrameworkName; 600 HeadersFilename += "PrivateHeaders/"; 601 if (SearchPath != NULL) { 602 SearchPath->clear(); 603 // Without trailing '/'. 604 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 605 } 606 607 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 608 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 609 return 0; 610 } 611 612 // This file is a system header or C++ unfriendly if the old file is. 613 // 614 // Note that the temporary 'DirInfo' is required here, as either call to 615 // getFileInfo could resize the vector and we don't want to rely on order 616 // of evaluation. 617 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 618 getFileInfo(FE).DirInfo = DirInfo; 619 return FE; 620 } 621 622 //===----------------------------------------------------------------------===// 623 // File Info Management. 624 //===----------------------------------------------------------------------===// 625 626 /// \brief Merge the header file info provided by \p OtherHFI into the current 627 /// header file info (\p HFI) 628 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 629 const HeaderFileInfo &OtherHFI) { 630 HFI.isImport |= OtherHFI.isImport; 631 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 632 HFI.NumIncludes += OtherHFI.NumIncludes; 633 634 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 635 HFI.ControllingMacro = OtherHFI.ControllingMacro; 636 HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 637 } 638 639 if (OtherHFI.External) { 640 HFI.DirInfo = OtherHFI.DirInfo; 641 HFI.External = OtherHFI.External; 642 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 643 } 644 645 if (HFI.Framework.empty()) 646 HFI.Framework = OtherHFI.Framework; 647 648 HFI.Resolved = true; 649 } 650 651 /// getFileInfo - Return the HeaderFileInfo structure for the specified 652 /// FileEntry. 653 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 654 if (FE->getUID() >= FileInfo.size()) 655 FileInfo.resize(FE->getUID()+1); 656 657 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 658 if (ExternalSource && !HFI.Resolved) 659 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 660 return HFI; 661 } 662 663 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 664 // Check if we've ever seen this file as a header. 665 if (File->getUID() >= FileInfo.size()) 666 return false; 667 668 // Resolve header file info from the external source, if needed. 669 HeaderFileInfo &HFI = FileInfo[File->getUID()]; 670 if (ExternalSource && !HFI.Resolved) 671 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 672 673 return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID; 674 } 675 676 void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { 677 if (UID >= FileInfo.size()) 678 FileInfo.resize(UID+1); 679 HFI.Resolved = true; 680 FileInfo[UID] = HFI; 681 } 682 683 /// ShouldEnterIncludeFile - Mark the specified file as a target of of a 684 /// #include, #include_next, or #import directive. Return false if #including 685 /// the file will have no effect or true if we should include it. 686 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 687 ++NumIncluded; // Count # of attempted #includes. 688 689 // Get information about this file. 690 HeaderFileInfo &FileInfo = getFileInfo(File); 691 692 // If this is a #import directive, check that we have not already imported 693 // this header. 694 if (isImport) { 695 // If this has already been imported, don't import it again. 696 FileInfo.isImport = true; 697 698 // Has this already been #import'ed or #include'd? 699 if (FileInfo.NumIncludes) return false; 700 } else { 701 // Otherwise, if this is a #include of a file that was previously #import'd 702 // or if this is the second #include of a #pragma once file, ignore it. 703 if (FileInfo.isImport) 704 return false; 705 } 706 707 // Next, check to see if the file is wrapped with #ifndef guards. If so, and 708 // if the macro that guards it is defined, we know the #include has no effect. 709 if (const IdentifierInfo *ControllingMacro 710 = FileInfo.getControllingMacro(ExternalLookup)) 711 if (ControllingMacro->hasMacroDefinition()) { 712 ++NumMultiIncludeFileOptzn; 713 return false; 714 } 715 716 // Increment the number of times this file has been included. 717 ++FileInfo.NumIncludes; 718 719 return true; 720 } 721 722 size_t HeaderSearch::getTotalMemory() const { 723 return SearchDirs.capacity() 724 + llvm::capacity_in_bytes(FileInfo) 725 + llvm::capacity_in_bytes(HeaderMaps) 726 + LookupFileCache.getAllocator().getTotalMemory() 727 + FrameworkMap.getAllocator().getTotalMemory(); 728 } 729 730 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 731 return FrameworkNames.GetOrCreateValue(Framework).getKey(); 732 } 733 734 bool HeaderSearch::hasModuleMap(StringRef FileName, 735 const DirectoryEntry *Root) { 736 llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 737 738 StringRef DirName = FileName; 739 do { 740 // Get the parent directory name. 741 DirName = llvm::sys::path::parent_path(DirName); 742 if (DirName.empty()) 743 return false; 744 745 // Determine whether this directory exists. 746 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 747 if (!Dir) 748 return false; 749 750 // Try to load the module map file in this directory. 751 switch (loadModuleMapFile(Dir)) { 752 case LMM_NewlyLoaded: 753 case LMM_AlreadyLoaded: 754 // Success. All of the directories we stepped through inherit this module 755 // map file. 756 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 757 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 758 759 return true; 760 761 case LMM_NoDirectory: 762 case LMM_InvalidModuleMap: 763 break; 764 } 765 766 // If we hit the top of our search, we're done. 767 if (Dir == Root) 768 return false; 769 770 // Keep track of all of the directories we checked, so we can mark them as 771 // having module maps if we eventually do find a module map. 772 FixUpDirectories.push_back(Dir); 773 } while (true); 774 775 return false; 776 } 777 778 Module *HeaderSearch::findModuleForHeader(const FileEntry *File) { 779 if (Module *Module = ModMap.findModuleForHeader(File)) 780 return Module; 781 782 return 0; 783 } 784 785 bool HeaderSearch::loadModuleMapFile(const FileEntry *File) { 786 const DirectoryEntry *Dir = File->getDir(); 787 788 llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 789 = DirectoryHasModuleMap.find(Dir); 790 if (KnownDir != DirectoryHasModuleMap.end()) 791 return !KnownDir->second; 792 793 bool Result = ModMap.parseModuleMapFile(File); 794 if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") { 795 // If the file we loaded was a module.map, look for the corresponding 796 // module_private.map. 797 llvm::SmallString<128> PrivateFilename(Dir->getName()); 798 llvm::sys::path::append(PrivateFilename, "module_private.map"); 799 if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename)) 800 Result = ModMap.parseModuleMapFile(PrivateFile); 801 } 802 803 DirectoryHasModuleMap[Dir] = !Result; 804 return Result; 805 } 806 807 Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { 808 if (Module *Module = ModMap.findModule(Name)) 809 return Module; 810 811 if (!AllowSearch) 812 return 0; 813 814 for (unsigned I = 0, N = SearchDirs.size(); I != N; ++I) { 815 if (!SearchDirs[I].isNormalDir()) 816 continue; 817 818 switch (loadModuleMapFile(SearchDirs[I].getDir())) { 819 case LMM_AlreadyLoaded: 820 case LMM_InvalidModuleMap: 821 case LMM_NoDirectory: 822 break; 823 824 case LMM_NewlyLoaded: 825 if (Module *Module = ModMap.findModule(Name)) 826 return Module; 827 break; 828 } 829 } 830 831 return 0; 832 } 833 834 Module *HeaderSearch::getFrameworkModule(StringRef Name, 835 const DirectoryEntry *Dir) { 836 if (Module *Module = ModMap.findModule(Name)) 837 return Module; 838 839 // Try to load a module map file. 840 switch (loadModuleMapFile(Dir)) { 841 case LMM_InvalidModuleMap: 842 break; 843 844 case LMM_AlreadyLoaded: 845 case LMM_NoDirectory: 846 return 0; 847 848 case LMM_NewlyLoaded: 849 return ModMap.findModule(Name); 850 } 851 852 // Try to infer a module map. 853 return ModMap.inferFrameworkModule(Name, Dir, /*Parent=*/0); 854 } 855 856 857 HeaderSearch::LoadModuleMapResult 858 HeaderSearch::loadModuleMapFile(StringRef DirName) { 859 if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 860 return loadModuleMapFile(Dir); 861 862 return LMM_NoDirectory; 863 } 864 865 HeaderSearch::LoadModuleMapResult 866 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) { 867 llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 868 = DirectoryHasModuleMap.find(Dir); 869 if (KnownDir != DirectoryHasModuleMap.end()) 870 return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 871 872 llvm::SmallString<128> ModuleMapFileName; 873 ModuleMapFileName += Dir->getName(); 874 unsigned ModuleMapDirNameLen = ModuleMapFileName.size(); 875 llvm::sys::path::append(ModuleMapFileName, "module.map"); 876 if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 877 // We have found a module map file. Try to parse it. 878 if (ModMap.parseModuleMapFile(ModuleMapFile)) { 879 // No suitable module map. 880 DirectoryHasModuleMap[Dir] = false; 881 return LMM_InvalidModuleMap; 882 } 883 884 // This directory has a module map. 885 DirectoryHasModuleMap[Dir] = true; 886 887 // Check whether there is a private module map that we need to load as well. 888 ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen, 889 ModuleMapFileName.end()); 890 llvm::sys::path::append(ModuleMapFileName, "module_private.map"); 891 if (const FileEntry *PrivateModuleMapFile 892 = FileMgr.getFile(ModuleMapFileName)) { 893 if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) { 894 // No suitable module map. 895 DirectoryHasModuleMap[Dir] = false; 896 return LMM_InvalidModuleMap; 897 } 898 } 899 900 return LMM_NewlyLoaded; 901 } 902 903 // No suitable module map. 904 DirectoryHasModuleMap[Dir] = false; 905 return LMM_InvalidModuleMap; 906 } 907 908