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/Basic/FileManager.h" 16 #include "clang/Basic/IdentifierTable.h" 17 #include "clang/Frontend/PCHContainerOperations.h" 18 #include "clang/Lex/ExternalPreprocessorSource.h" 19 #include "clang/Lex/HeaderMap.h" 20 #include "clang/Lex/HeaderSearchOptions.h" 21 #include "clang/Lex/LexDiagnostic.h" 22 #include "clang/Lex/Lexer.h" 23 #include "clang/Lex/Preprocessor.h" 24 #include "llvm/ADT/APInt.h" 25 #include "llvm/ADT/Hashing.h" 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/Support/Capacity.h" 28 #include "llvm/Support/FileSystem.h" 29 #include "llvm/Support/Path.h" 30 #include "llvm/Support/raw_ostream.h" 31 #include <cstdio> 32 #if defined(LLVM_ON_UNIX) 33 #include <limits.h> 34 #endif 35 using namespace clang; 36 37 const IdentifierInfo * 38 HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) { 39 if (ControllingMacro) { 40 if (ControllingMacro->isOutOfDate()) 41 External->updateOutOfDateIdentifier( 42 *const_cast<IdentifierInfo *>(ControllingMacro)); 43 return ControllingMacro; 44 } 45 46 if (!ControllingMacroID || !External) 47 return nullptr; 48 49 ControllingMacro = External->GetIdentifier(ControllingMacroID); 50 return ControllingMacro; 51 } 52 53 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 54 55 HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, 56 SourceManager &SourceMgr, DiagnosticsEngine &Diags, 57 const LangOptions &LangOpts, 58 const TargetInfo *Target) 59 : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()), 60 FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this), 61 LangOpts(LangOpts) { 62 AngledDirIdx = 0; 63 SystemDirIdx = 0; 64 NoCurDirSearch = false; 65 66 ExternalLookup = nullptr; 67 ExternalSource = nullptr; 68 NumIncluded = 0; 69 NumMultiIncludeFileOptzn = 0; 70 NumFrameworkLookups = NumSubFrameworkLookups = 0; 71 } 72 73 HeaderSearch::~HeaderSearch() { 74 // Delete headermaps. 75 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 76 delete HeaderMaps[i].second; 77 } 78 79 void HeaderSearch::PrintStats() { 80 fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 81 fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 82 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 83 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 84 NumOnceOnlyFiles += FileInfo[i].isImport; 85 if (MaxNumIncludes < FileInfo[i].NumIncludes) 86 MaxNumIncludes = FileInfo[i].NumIncludes; 87 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 88 } 89 fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 90 fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 91 fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 92 93 fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 94 fprintf(stderr, " %d #includes skipped due to" 95 " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 96 97 fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 98 fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 99 } 100 101 /// CreateHeaderMap - This method returns a HeaderMap for the specified 102 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. 103 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 104 // We expect the number of headermaps to be small, and almost always empty. 105 // If it ever grows, use of a linear search should be re-evaluated. 106 if (!HeaderMaps.empty()) { 107 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 108 // Pointer equality comparison of FileEntries works because they are 109 // already uniqued by inode. 110 if (HeaderMaps[i].first == FE) 111 return HeaderMaps[i].second; 112 } 113 114 if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 115 HeaderMaps.push_back(std::make_pair(FE, HM)); 116 return HM; 117 } 118 119 return nullptr; 120 } 121 122 std::string HeaderSearch::getModuleFileName(Module *Module) { 123 const FileEntry *ModuleMap = 124 getModuleMap().getModuleMapFileForUniquing(Module); 125 return getModuleFileName(Module->Name, ModuleMap->getName()); 126 } 127 128 std::string HeaderSearch::getModuleFileName(StringRef ModuleName, 129 StringRef ModuleMapPath) { 130 // If we don't have a module cache path, we can't do anything. 131 if (ModuleCachePath.empty()) 132 return std::string(); 133 134 SmallString<256> Result(ModuleCachePath); 135 llvm::sys::fs::make_absolute(Result); 136 137 if (HSOpts->DisableModuleHash) { 138 llvm::sys::path::append(Result, ModuleName + ".pcm"); 139 } else { 140 // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should 141 // ideally be globally unique to this particular module. Name collisions 142 // in the hash are safe (because any translation unit can only import one 143 // module with each name), but result in a loss of caching. 144 // 145 // To avoid false-negatives, we form as canonical a path as we can, and map 146 // to lower-case in case we're on a case-insensitive file system. 147 auto *Dir = 148 FileMgr.getDirectory(llvm::sys::path::parent_path(ModuleMapPath)); 149 if (!Dir) 150 return std::string(); 151 auto DirName = FileMgr.getCanonicalName(Dir); 152 auto FileName = llvm::sys::path::filename(ModuleMapPath); 153 154 llvm::hash_code Hash = 155 llvm::hash_combine(DirName.lower(), FileName.lower(), 156 HSOpts->ModuleFormat); 157 158 SmallString<128> HashStr; 159 llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36); 160 llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm"); 161 } 162 return Result.str().str(); 163 } 164 165 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { 166 // Look in the module map to determine if there is a module by this name. 167 Module *Module = ModMap.findModule(ModuleName); 168 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps) 169 return Module; 170 171 // Look through the various header search paths to load any available module 172 // maps, searching for a module map that describes this module. 173 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 174 if (SearchDirs[Idx].isFramework()) { 175 // Search for or infer a module map for a framework. 176 SmallString<128> FrameworkDirName; 177 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); 178 llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); 179 if (const DirectoryEntry *FrameworkDir 180 = FileMgr.getDirectory(FrameworkDirName)) { 181 bool IsSystem 182 = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 183 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 184 if (Module) 185 break; 186 } 187 } 188 189 // FIXME: Figure out how header maps and module maps will work together. 190 191 // Only deal with normal search directories. 192 if (!SearchDirs[Idx].isNormalDir()) 193 continue; 194 195 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 196 // Search for a module map file in this directory. 197 if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, 198 /*IsFramework*/false) == LMM_NewlyLoaded) { 199 // We just loaded a module map file; check whether the module is 200 // available now. 201 Module = ModMap.findModule(ModuleName); 202 if (Module) 203 break; 204 } 205 206 // Search for a module map in a subdirectory with the same name as the 207 // module. 208 SmallString<128> NestedModuleMapDirName; 209 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 210 llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 211 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem, 212 /*IsFramework*/false) == LMM_NewlyLoaded){ 213 // If we just loaded a module map file, look for the module again. 214 Module = ModMap.findModule(ModuleName); 215 if (Module) 216 break; 217 } 218 219 // If we've already performed the exhaustive search for module maps in this 220 // search directory, don't do it again. 221 if (SearchDirs[Idx].haveSearchedAllModuleMaps()) 222 continue; 223 224 // Load all module maps in the immediate subdirectories of this search 225 // directory. 226 loadSubdirectoryModuleMaps(SearchDirs[Idx]); 227 228 // Look again for the module. 229 Module = ModMap.findModule(ModuleName); 230 if (Module) 231 break; 232 } 233 234 return Module; 235 } 236 237 //===----------------------------------------------------------------------===// 238 // File lookup within a DirectoryLookup scope 239 //===----------------------------------------------------------------------===// 240 241 /// getName - Return the directory or filename corresponding to this lookup 242 /// object. 243 const char *DirectoryLookup::getName() const { 244 if (isNormalDir()) 245 return getDir()->getName(); 246 if (isFramework()) 247 return getFrameworkDir()->getName(); 248 assert(isHeaderMap() && "Unknown DirectoryLookup"); 249 return getHeaderMap()->getFileName(); 250 } 251 252 static const FileEntry * 253 getFileAndSuggestModule(HeaderSearch &HS, StringRef FileName, 254 const DirectoryEntry *Dir, bool IsSystemHeaderDir, 255 ModuleMap::KnownHeader *SuggestedModule) { 256 // If we have a module map that might map this header, load it and 257 // check whether we'll have a suggestion for a module. 258 HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir); 259 if (SuggestedModule) { 260 const FileEntry *File = HS.getFileMgr().getFile(FileName, 261 /*OpenFile=*/false); 262 if (File) { 263 // If there is a module that corresponds to this header, suggest it. 264 *SuggestedModule = HS.findModuleForHeader(File); 265 266 // FIXME: This appears to be a no-op. We loaded the module map for this 267 // directory at the start of this function. 268 if (!SuggestedModule->getModule() && 269 HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir)) 270 *SuggestedModule = HS.findModuleForHeader(File); 271 } 272 273 return File; 274 } 275 276 return HS.getFileMgr().getFile(FileName, /*openFile=*/true); 277 } 278 279 /// LookupFile - Lookup the specified file in this search path, returning it 280 /// if it exists or returning null if not. 281 const FileEntry *DirectoryLookup::LookupFile( 282 StringRef &Filename, 283 HeaderSearch &HS, 284 SmallVectorImpl<char> *SearchPath, 285 SmallVectorImpl<char> *RelativePath, 286 ModuleMap::KnownHeader *SuggestedModule, 287 bool &InUserSpecifiedSystemFramework, 288 bool &HasBeenMapped, 289 SmallVectorImpl<char> &MappedName) const { 290 InUserSpecifiedSystemFramework = false; 291 HasBeenMapped = false; 292 293 SmallString<1024> TmpDir; 294 if (isNormalDir()) { 295 // Concatenate the requested file onto the directory. 296 TmpDir = getDir()->getName(); 297 llvm::sys::path::append(TmpDir, Filename); 298 if (SearchPath) { 299 StringRef SearchPathRef(getDir()->getName()); 300 SearchPath->clear(); 301 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 302 } 303 if (RelativePath) { 304 RelativePath->clear(); 305 RelativePath->append(Filename.begin(), Filename.end()); 306 } 307 308 return getFileAndSuggestModule(HS, TmpDir, getDir(), 309 isSystemHeaderDirectory(), 310 SuggestedModule); 311 } 312 313 if (isFramework()) 314 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 315 SuggestedModule, InUserSpecifiedSystemFramework); 316 317 assert(isHeaderMap() && "Unknown directory lookup"); 318 const HeaderMap *HM = getHeaderMap(); 319 SmallString<1024> Path; 320 StringRef Dest = HM->lookupFilename(Filename, Path); 321 if (Dest.empty()) 322 return nullptr; 323 324 const FileEntry *Result; 325 326 // Check if the headermap maps the filename to a framework include 327 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the 328 // framework include. 329 if (llvm::sys::path::is_relative(Dest)) { 330 MappedName.clear(); 331 MappedName.append(Dest.begin(), Dest.end()); 332 Filename = StringRef(MappedName.begin(), MappedName.size()); 333 HasBeenMapped = true; 334 Result = HM->LookupFile(Filename, HS.getFileMgr()); 335 336 } else { 337 Result = HS.getFileMgr().getFile(Dest); 338 } 339 340 if (Result) { 341 if (SearchPath) { 342 StringRef SearchPathRef(getName()); 343 SearchPath->clear(); 344 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 345 } 346 if (RelativePath) { 347 RelativePath->clear(); 348 RelativePath->append(Filename.begin(), Filename.end()); 349 } 350 } 351 return Result; 352 } 353 354 /// \brief Given a framework directory, find the top-most framework directory. 355 /// 356 /// \param FileMgr The file manager to use for directory lookups. 357 /// \param DirName The name of the framework directory. 358 /// \param SubmodulePath Will be populated with the submodule path from the 359 /// returned top-level module to the originally named framework. 360 static const DirectoryEntry * 361 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, 362 SmallVectorImpl<std::string> &SubmodulePath) { 363 assert(llvm::sys::path::extension(DirName) == ".framework" && 364 "Not a framework directory"); 365 366 // Note: as an egregious but useful hack we use the real path here, because 367 // frameworks moving between top-level frameworks to embedded frameworks tend 368 // to be symlinked, and we base the logical structure of modules on the 369 // physical layout. In particular, we need to deal with crazy includes like 370 // 371 // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h> 372 // 373 // where 'Bar' used to be embedded in 'Foo', is now a top-level framework 374 // which one should access with, e.g., 375 // 376 // #include <Bar/Wibble.h> 377 // 378 // Similar issues occur when a top-level framework has moved into an 379 // embedded framework. 380 const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName); 381 DirName = FileMgr.getCanonicalName(TopFrameworkDir); 382 do { 383 // Get the parent directory name. 384 DirName = llvm::sys::path::parent_path(DirName); 385 if (DirName.empty()) 386 break; 387 388 // Determine whether this directory exists. 389 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 390 if (!Dir) 391 break; 392 393 // If this is a framework directory, then we're a subframework of this 394 // framework. 395 if (llvm::sys::path::extension(DirName) == ".framework") { 396 SubmodulePath.push_back(llvm::sys::path::stem(DirName)); 397 TopFrameworkDir = Dir; 398 } 399 } while (true); 400 401 return TopFrameworkDir; 402 } 403 404 /// DoFrameworkLookup - Do a lookup of the specified file in the current 405 /// DirectoryLookup, which is a framework directory. 406 const FileEntry *DirectoryLookup::DoFrameworkLookup( 407 StringRef Filename, 408 HeaderSearch &HS, 409 SmallVectorImpl<char> *SearchPath, 410 SmallVectorImpl<char> *RelativePath, 411 ModuleMap::KnownHeader *SuggestedModule, 412 bool &InUserSpecifiedSystemFramework) const 413 { 414 FileManager &FileMgr = HS.getFileMgr(); 415 416 // Framework names must have a '/' in the filename. 417 size_t SlashPos = Filename.find('/'); 418 if (SlashPos == StringRef::npos) return nullptr; 419 420 // Find out if this is the home for the specified framework, by checking 421 // HeaderSearch. Possible answers are yes/no and unknown. 422 HeaderSearch::FrameworkCacheEntry &CacheEntry = 423 HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 424 425 // If it is known and in some other directory, fail. 426 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir()) 427 return nullptr; 428 429 // Otherwise, construct the path to this framework dir. 430 431 // FrameworkName = "/System/Library/Frameworks/" 432 SmallString<1024> FrameworkName; 433 FrameworkName += getFrameworkDir()->getName(); 434 if (FrameworkName.empty() || FrameworkName.back() != '/') 435 FrameworkName.push_back('/'); 436 437 // FrameworkName = "/System/Library/Frameworks/Cocoa" 438 StringRef ModuleName(Filename.begin(), SlashPos); 439 FrameworkName += ModuleName; 440 441 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 442 FrameworkName += ".framework/"; 443 444 // If the cache entry was unresolved, populate it now. 445 if (!CacheEntry.Directory) { 446 HS.IncrementFrameworkLookupCount(); 447 448 // If the framework dir doesn't exist, we fail. 449 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName); 450 if (!Dir) return nullptr; 451 452 // Otherwise, if it does, remember that this is the right direntry for this 453 // framework. 454 CacheEntry.Directory = getFrameworkDir(); 455 456 // If this is a user search directory, check if the framework has been 457 // user-specified as a system framework. 458 if (getDirCharacteristic() == SrcMgr::C_User) { 459 SmallString<1024> SystemFrameworkMarker(FrameworkName); 460 SystemFrameworkMarker += ".system_framework"; 461 if (llvm::sys::fs::exists(SystemFrameworkMarker)) { 462 CacheEntry.IsUserSpecifiedSystemFramework = true; 463 } 464 } 465 } 466 467 // Set the 'user-specified system framework' flag. 468 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework; 469 470 if (RelativePath) { 471 RelativePath->clear(); 472 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 473 } 474 475 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 476 unsigned OrigSize = FrameworkName.size(); 477 478 FrameworkName += "Headers/"; 479 480 if (SearchPath) { 481 SearchPath->clear(); 482 // Without trailing '/'. 483 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 484 } 485 486 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 487 const FileEntry *FE = FileMgr.getFile(FrameworkName, 488 /*openFile=*/!SuggestedModule); 489 if (!FE) { 490 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 491 const char *Private = "Private"; 492 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 493 Private+strlen(Private)); 494 if (SearchPath) 495 SearchPath->insert(SearchPath->begin()+OrigSize, Private, 496 Private+strlen(Private)); 497 498 FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule); 499 } 500 501 // If we found the header and are allowed to suggest a module, do so now. 502 if (FE && SuggestedModule) { 503 // Find the framework in which this header occurs. 504 StringRef FrameworkPath = FE->getDir()->getName(); 505 bool FoundFramework = false; 506 do { 507 // Determine whether this directory exists. 508 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath); 509 if (!Dir) 510 break; 511 512 // If this is a framework directory, then we're a subframework of this 513 // framework. 514 if (llvm::sys::path::extension(FrameworkPath) == ".framework") { 515 FoundFramework = true; 516 break; 517 } 518 519 // Get the parent directory name. 520 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath); 521 if (FrameworkPath.empty()) 522 break; 523 } while (true); 524 525 if (FoundFramework) { 526 // Find the top-level framework based on this framework. 527 SmallVector<std::string, 4> SubmodulePath; 528 const DirectoryEntry *TopFrameworkDir 529 = ::getTopFrameworkDir(FileMgr, FrameworkPath, SubmodulePath); 530 531 // Determine the name of the top-level framework. 532 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 533 534 // Load this framework module. If that succeeds, find the suggested module 535 // for this header, if any. 536 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 537 HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem); 538 539 // FIXME: This can find a module not part of ModuleName, which is 540 // important so that we're consistent about whether this header 541 // corresponds to a module. Possibly we should lock down framework modules 542 // so that this is not possible. 543 *SuggestedModule = HS.findModuleForHeader(FE); 544 } else { 545 *SuggestedModule = HS.findModuleForHeader(FE); 546 } 547 } 548 return FE; 549 } 550 551 void HeaderSearch::setTarget(const TargetInfo &Target) { 552 ModMap.setTarget(Target); 553 } 554 555 556 //===----------------------------------------------------------------------===// 557 // Header File Location. 558 //===----------------------------------------------------------------------===// 559 560 /// \brief Return true with a diagnostic if the file that MSVC would have found 561 /// fails to match the one that Clang would have found with MSVC header search 562 /// disabled. 563 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags, 564 const FileEntry *MSFE, const FileEntry *FE, 565 SourceLocation IncludeLoc) { 566 if (MSFE && FE != MSFE) { 567 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName(); 568 return true; 569 } 570 return false; 571 } 572 573 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) { 574 assert(!Str.empty()); 575 char *CopyStr = Alloc.Allocate<char>(Str.size()+1); 576 std::copy(Str.begin(), Str.end(), CopyStr); 577 CopyStr[Str.size()] = '\0'; 578 return CopyStr; 579 } 580 581 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file, 582 /// return null on failure. isAngled indicates whether the file reference is 583 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if 584 /// non-empty, indicates where the \#including file(s) are, in case a relative 585 /// search is needed. Microsoft mode will pass all \#including files. 586 const FileEntry *HeaderSearch::LookupFile( 587 StringRef Filename, SourceLocation IncludeLoc, bool isAngled, 588 const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, 589 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, 590 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, 591 ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) { 592 if (SuggestedModule) 593 *SuggestedModule = ModuleMap::KnownHeader(); 594 595 // If 'Filename' is absolute, check to see if it exists and no searching. 596 if (llvm::sys::path::is_absolute(Filename)) { 597 CurDir = nullptr; 598 599 // If this was an #include_next "/absolute/file", fail. 600 if (FromDir) return nullptr; 601 602 if (SearchPath) 603 SearchPath->clear(); 604 if (RelativePath) { 605 RelativePath->clear(); 606 RelativePath->append(Filename.begin(), Filename.end()); 607 } 608 // Otherwise, just return the file. 609 const FileEntry *File = FileMgr.getFile(Filename, /*openFile=*/true); 610 if (File && SuggestedModule) { 611 // If there is a module that corresponds to this header, suggest it. 612 hasModuleMap(Filename, File->getDir(), /*SystemHeaderDir*/false); 613 *SuggestedModule = findModuleForHeader(File); 614 } 615 return File; 616 } 617 618 // This is the header that MSVC's header search would have found. 619 const FileEntry *MSFE = nullptr; 620 ModuleMap::KnownHeader MSSuggestedModule; 621 622 // Unless disabled, check to see if the file is in the #includer's 623 // directory. This cannot be based on CurDir, because each includer could be 624 // a #include of a subdirectory (#include "foo/bar.h") and a subsequent 625 // include of "baz.h" should resolve to "whatever/foo/baz.h". 626 // This search is not done for <> headers. 627 if (!Includers.empty() && !isAngled && !NoCurDirSearch) { 628 SmallString<1024> TmpDir; 629 bool First = true; 630 for (const auto &IncluderAndDir : Includers) { 631 const FileEntry *Includer = IncluderAndDir.first; 632 633 // Concatenate the requested file onto the directory. 634 // FIXME: Portability. Filename concatenation should be in sys::Path. 635 TmpDir = IncluderAndDir.second->getName(); 636 TmpDir.push_back('/'); 637 TmpDir.append(Filename.begin(), Filename.end()); 638 639 // FIXME: We don't cache the result of getFileInfo across the call to 640 // getFileAndSuggestModule, because it's a reference to an element of 641 // a container that could be reallocated across this call. 642 // 643 // FIXME: If we have no includer, that means we're processing a #include 644 // from a module build. We should treat this as a system header if we're 645 // building a [system] module. 646 bool IncluderIsSystemHeader = 647 Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User; 648 if (const FileEntry *FE = getFileAndSuggestModule( 649 *this, TmpDir, IncluderAndDir.second, 650 IncluderIsSystemHeader, SuggestedModule)) { 651 if (!Includer) { 652 assert(First && "only first includer can have no file"); 653 return FE; 654 } 655 656 // Leave CurDir unset. 657 // This file is a system header or C++ unfriendly if the old file is. 658 // 659 // Note that we only use one of FromHFI/ToHFI at once, due to potential 660 // reallocation of the underlying vector potentially making the first 661 // reference binding dangling. 662 HeaderFileInfo &FromHFI = getFileInfo(Includer); 663 unsigned DirInfo = FromHFI.DirInfo; 664 bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; 665 StringRef Framework = FromHFI.Framework; 666 667 HeaderFileInfo &ToHFI = getFileInfo(FE); 668 ToHFI.DirInfo = DirInfo; 669 ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; 670 ToHFI.Framework = Framework; 671 672 if (SearchPath) { 673 StringRef SearchPathRef(IncluderAndDir.second->getName()); 674 SearchPath->clear(); 675 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 676 } 677 if (RelativePath) { 678 RelativePath->clear(); 679 RelativePath->append(Filename.begin(), Filename.end()); 680 } 681 if (First) 682 return FE; 683 684 // Otherwise, we found the path via MSVC header search rules. If 685 // -Wmsvc-include is enabled, we have to keep searching to see if we 686 // would've found this header in -I or -isystem directories. 687 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) { 688 return FE; 689 } else { 690 MSFE = FE; 691 if (SuggestedModule) { 692 MSSuggestedModule = *SuggestedModule; 693 *SuggestedModule = ModuleMap::KnownHeader(); 694 } 695 break; 696 } 697 } 698 First = false; 699 } 700 } 701 702 CurDir = nullptr; 703 704 // If this is a system #include, ignore the user #include locs. 705 unsigned i = isAngled ? AngledDirIdx : 0; 706 707 // If this is a #include_next request, start searching after the directory the 708 // file was found in. 709 if (FromDir) 710 i = FromDir-&SearchDirs[0]; 711 712 // Cache all of the lookups performed by this method. Many headers are 713 // multiply included, and the "pragma once" optimization prevents them from 714 // being relex/pp'd, but they would still have to search through a 715 // (potentially huge) series of SearchDirs to find it. 716 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename]; 717 718 // If the entry has been previously looked up, the first value will be 719 // non-zero. If the value is equal to i (the start point of our search), then 720 // this is a matching hit. 721 if (!SkipCache && CacheLookup.StartIdx == i+1) { 722 // Skip querying potentially lots of directories for this lookup. 723 i = CacheLookup.HitIdx; 724 if (CacheLookup.MappedName) 725 Filename = CacheLookup.MappedName; 726 } else { 727 // Otherwise, this is the first query, or the previous query didn't match 728 // our search start. We will fill in our found location below, so prime the 729 // start point value. 730 CacheLookup.reset(/*StartIdx=*/i+1); 731 } 732 733 SmallString<64> MappedName; 734 735 // Check each directory in sequence to see if it contains this file. 736 for (; i != SearchDirs.size(); ++i) { 737 bool InUserSpecifiedSystemFramework = false; 738 bool HasBeenMapped = false; 739 const FileEntry *FE = 740 SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 741 SuggestedModule, InUserSpecifiedSystemFramework, 742 HasBeenMapped, MappedName); 743 if (HasBeenMapped) { 744 CacheLookup.MappedName = 745 copyString(Filename, LookupFileCache.getAllocator()); 746 } 747 if (!FE) continue; 748 749 CurDir = &SearchDirs[i]; 750 751 // This file is a system header or C++ unfriendly if the dir is. 752 HeaderFileInfo &HFI = getFileInfo(FE); 753 HFI.DirInfo = CurDir->getDirCharacteristic(); 754 755 // If the directory characteristic is User but this framework was 756 // user-specified to be treated as a system framework, promote the 757 // characteristic. 758 if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework) 759 HFI.DirInfo = SrcMgr::C_System; 760 761 // If the filename matches a known system header prefix, override 762 // whether the file is a system header. 763 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) { 764 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) { 765 HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System 766 : SrcMgr::C_User; 767 break; 768 } 769 } 770 771 // If this file is found in a header map and uses the framework style of 772 // includes, then this header is part of a framework we're building. 773 if (CurDir->isIndexHeaderMap()) { 774 size_t SlashPos = Filename.find('/'); 775 if (SlashPos != StringRef::npos) { 776 HFI.IndexHeaderMapHeader = 1; 777 HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 778 SlashPos)); 779 } 780 } 781 782 if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { 783 if (SuggestedModule) 784 *SuggestedModule = MSSuggestedModule; 785 return MSFE; 786 } 787 788 // Remember this location for the next lookup we do. 789 CacheLookup.HitIdx = i; 790 return FE; 791 } 792 793 // If we are including a file with a quoted include "foo.h" from inside 794 // a header in a framework that is currently being built, and we couldn't 795 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 796 // "Foo" is the name of the framework in which the including header was found. 797 if (!Includers.empty() && Includers.front().first && !isAngled && 798 Filename.find('/') == StringRef::npos) { 799 HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first); 800 if (IncludingHFI.IndexHeaderMapHeader) { 801 SmallString<128> ScratchFilename; 802 ScratchFilename += IncludingHFI.Framework; 803 ScratchFilename += '/'; 804 ScratchFilename += Filename; 805 806 const FileEntry *FE = LookupFile( 807 ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir, 808 Includers.front(), SearchPath, RelativePath, SuggestedModule); 809 810 if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { 811 if (SuggestedModule) 812 *SuggestedModule = MSSuggestedModule; 813 return MSFE; 814 } 815 816 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename]; 817 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx; 818 // FIXME: SuggestedModule. 819 return FE; 820 } 821 } 822 823 if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) { 824 if (SuggestedModule) 825 *SuggestedModule = MSSuggestedModule; 826 return MSFE; 827 } 828 829 // Otherwise, didn't find it. Remember we didn't find this. 830 CacheLookup.HitIdx = SearchDirs.size(); 831 return nullptr; 832 } 833 834 /// LookupSubframeworkHeader - Look up a subframework for the specified 835 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from 836 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 837 /// is a subframework within Carbon.framework. If so, return the FileEntry 838 /// for the designated file, otherwise return null. 839 const FileEntry *HeaderSearch:: 840 LookupSubframeworkHeader(StringRef Filename, 841 const FileEntry *ContextFileEnt, 842 SmallVectorImpl<char> *SearchPath, 843 SmallVectorImpl<char> *RelativePath, 844 ModuleMap::KnownHeader *SuggestedModule) { 845 assert(ContextFileEnt && "No context file?"); 846 847 // Framework names must have a '/' in the filename. Find it. 848 // FIXME: Should we permit '\' on Windows? 849 size_t SlashPos = Filename.find('/'); 850 if (SlashPos == StringRef::npos) return nullptr; 851 852 // Look up the base framework name of the ContextFileEnt. 853 const char *ContextName = ContextFileEnt->getName(); 854 855 // If the context info wasn't a framework, couldn't be a subframework. 856 const unsigned DotFrameworkLen = 10; 857 const char *FrameworkPos = strstr(ContextName, ".framework"); 858 if (FrameworkPos == nullptr || 859 (FrameworkPos[DotFrameworkLen] != '/' && 860 FrameworkPos[DotFrameworkLen] != '\\')) 861 return nullptr; 862 863 SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1); 864 865 // Append Frameworks/HIToolbox.framework/ 866 FrameworkName += "Frameworks/"; 867 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 868 FrameworkName += ".framework/"; 869 870 auto &CacheLookup = 871 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos), 872 FrameworkCacheEntry())).first; 873 874 // Some other location? 875 if (CacheLookup.second.Directory && 876 CacheLookup.first().size() == FrameworkName.size() && 877 memcmp(CacheLookup.first().data(), &FrameworkName[0], 878 CacheLookup.first().size()) != 0) 879 return nullptr; 880 881 // Cache subframework. 882 if (!CacheLookup.second.Directory) { 883 ++NumSubFrameworkLookups; 884 885 // If the framework dir doesn't exist, we fail. 886 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName); 887 if (!Dir) return nullptr; 888 889 // Otherwise, if it does, remember that this is the right direntry for this 890 // framework. 891 CacheLookup.second.Directory = Dir; 892 } 893 894 const FileEntry *FE = nullptr; 895 896 if (RelativePath) { 897 RelativePath->clear(); 898 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 899 } 900 901 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 902 SmallString<1024> HeadersFilename(FrameworkName); 903 HeadersFilename += "Headers/"; 904 if (SearchPath) { 905 SearchPath->clear(); 906 // Without trailing '/'. 907 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 908 } 909 910 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 911 if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) { 912 913 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 914 HeadersFilename = FrameworkName; 915 HeadersFilename += "PrivateHeaders/"; 916 if (SearchPath) { 917 SearchPath->clear(); 918 // Without trailing '/'. 919 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 920 } 921 922 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 923 if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) 924 return nullptr; 925 } 926 927 // This file is a system header or C++ unfriendly if the old file is. 928 // 929 // Note that the temporary 'DirInfo' is required here, as either call to 930 // getFileInfo could resize the vector and we don't want to rely on order 931 // of evaluation. 932 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 933 getFileInfo(FE).DirInfo = DirInfo; 934 935 // If we're supposed to suggest a module, look for one now. 936 if (SuggestedModule) { 937 // Find the top-level framework based on this framework. 938 FrameworkName.pop_back(); // remove the trailing '/' 939 SmallVector<std::string, 4> SubmodulePath; 940 const DirectoryEntry *TopFrameworkDir 941 = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath); 942 943 // Determine the name of the top-level framework. 944 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 945 946 // Load this framework module. If that succeeds, find the suggested module 947 // for this header, if any. 948 bool IsSystem = false; 949 if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 950 *SuggestedModule = findModuleForHeader(FE); 951 } 952 } 953 954 return FE; 955 } 956 957 //===----------------------------------------------------------------------===// 958 // File Info Management. 959 //===----------------------------------------------------------------------===// 960 961 /// \brief Merge the header file info provided by \p OtherHFI into the current 962 /// header file info (\p HFI) 963 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 964 const HeaderFileInfo &OtherHFI) { 965 HFI.isImport |= OtherHFI.isImport; 966 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 967 HFI.isModuleHeader |= OtherHFI.isModuleHeader; 968 HFI.NumIncludes += OtherHFI.NumIncludes; 969 970 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 971 HFI.ControllingMacro = OtherHFI.ControllingMacro; 972 HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 973 } 974 975 if (OtherHFI.External) { 976 HFI.DirInfo = OtherHFI.DirInfo; 977 HFI.External = OtherHFI.External; 978 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 979 } 980 981 if (HFI.Framework.empty()) 982 HFI.Framework = OtherHFI.Framework; 983 984 HFI.Resolved = true; 985 } 986 987 /// getFileInfo - Return the HeaderFileInfo structure for the specified 988 /// FileEntry. 989 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 990 if (FE->getUID() >= FileInfo.size()) 991 FileInfo.resize(FE->getUID()+1); 992 993 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 994 if (ExternalSource && !HFI.Resolved) 995 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 996 HFI.IsValid = 1; 997 return HFI; 998 } 999 1000 bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, 1001 HeaderFileInfo &Result) const { 1002 if (FE->getUID() >= FileInfo.size()) 1003 return false; 1004 const HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 1005 if (HFI.IsValid) { 1006 Result = HFI; 1007 return true; 1008 } 1009 return false; 1010 } 1011 1012 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 1013 // Check if we've ever seen this file as a header. 1014 if (File->getUID() >= FileInfo.size()) 1015 return false; 1016 1017 // Resolve header file info from the external source, if needed. 1018 HeaderFileInfo &HFI = FileInfo[File->getUID()]; 1019 if (ExternalSource && !HFI.Resolved) 1020 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 1021 1022 return HFI.isPragmaOnce || HFI.isImport || 1023 HFI.ControllingMacro || HFI.ControllingMacroID; 1024 } 1025 1026 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, 1027 ModuleMap::ModuleHeaderRole Role, 1028 bool isCompilingModuleHeader) { 1029 if (FE->getUID() >= FileInfo.size()) 1030 FileInfo.resize(FE->getUID()+1); 1031 1032 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 1033 HFI.isModuleHeader = true; 1034 HFI.isCompilingModuleHeader |= isCompilingModuleHeader; 1035 HFI.setHeaderRole(Role); 1036 } 1037 1038 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, 1039 const FileEntry *File, 1040 bool isImport, Module *M) { 1041 ++NumIncluded; // Count # of attempted #includes. 1042 1043 // Get information about this file. 1044 HeaderFileInfo &FileInfo = getFileInfo(File); 1045 1046 // If this is a #import directive, check that we have not already imported 1047 // this header. 1048 if (isImport) { 1049 // If this has already been imported, don't import it again. 1050 FileInfo.isImport = true; 1051 1052 // Has this already been #import'ed or #include'd? 1053 if (FileInfo.NumIncludes) return false; 1054 } else { 1055 // Otherwise, if this is a #include of a file that was previously #import'd 1056 // or if this is the second #include of a #pragma once file, ignore it. 1057 if (FileInfo.isImport) 1058 return false; 1059 } 1060 1061 // Next, check to see if the file is wrapped with #ifndef guards. If so, and 1062 // if the macro that guards it is defined, we know the #include has no effect. 1063 if (const IdentifierInfo *ControllingMacro 1064 = FileInfo.getControllingMacro(ExternalLookup)) { 1065 // If the header corresponds to a module, check whether the macro is already 1066 // defined in that module rather than checking in the current set of visible 1067 // modules. 1068 if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M) 1069 : PP.isMacroDefined(ControllingMacro)) { 1070 ++NumMultiIncludeFileOptzn; 1071 return false; 1072 } 1073 } 1074 1075 // Increment the number of times this file has been included. 1076 ++FileInfo.NumIncludes; 1077 1078 return true; 1079 } 1080 1081 size_t HeaderSearch::getTotalMemory() const { 1082 return SearchDirs.capacity() 1083 + llvm::capacity_in_bytes(FileInfo) 1084 + llvm::capacity_in_bytes(HeaderMaps) 1085 + LookupFileCache.getAllocator().getTotalMemory() 1086 + FrameworkMap.getAllocator().getTotalMemory(); 1087 } 1088 1089 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 1090 return FrameworkNames.insert(Framework).first->first(); 1091 } 1092 1093 bool HeaderSearch::hasModuleMap(StringRef FileName, 1094 const DirectoryEntry *Root, 1095 bool IsSystem) { 1096 if (!HSOpts->ImplicitModuleMaps) 1097 return false; 1098 1099 SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 1100 1101 StringRef DirName = FileName; 1102 do { 1103 // Get the parent directory name. 1104 DirName = llvm::sys::path::parent_path(DirName); 1105 if (DirName.empty()) 1106 return false; 1107 1108 // Determine whether this directory exists. 1109 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 1110 if (!Dir) 1111 return false; 1112 1113 // Try to load the module map file in this directory. 1114 switch (loadModuleMapFile(Dir, IsSystem, 1115 llvm::sys::path::extension(Dir->getName()) == 1116 ".framework")) { 1117 case LMM_NewlyLoaded: 1118 case LMM_AlreadyLoaded: 1119 // Success. All of the directories we stepped through inherit this module 1120 // map file. 1121 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 1122 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 1123 return true; 1124 1125 case LMM_NoDirectory: 1126 case LMM_InvalidModuleMap: 1127 break; 1128 } 1129 1130 // If we hit the top of our search, we're done. 1131 if (Dir == Root) 1132 return false; 1133 1134 // Keep track of all of the directories we checked, so we can mark them as 1135 // having module maps if we eventually do find a module map. 1136 FixUpDirectories.push_back(Dir); 1137 } while (true); 1138 } 1139 1140 ModuleMap::KnownHeader 1141 HeaderSearch::findModuleForHeader(const FileEntry *File) const { 1142 if (ExternalSource) { 1143 // Make sure the external source has handled header info about this file, 1144 // which includes whether the file is part of a module. 1145 (void)getFileInfo(File); 1146 } 1147 return ModMap.findModuleForHeader(File); 1148 } 1149 1150 static const FileEntry *getPrivateModuleMap(const FileEntry *File, 1151 FileManager &FileMgr) { 1152 StringRef Filename = llvm::sys::path::filename(File->getName()); 1153 SmallString<128> PrivateFilename(File->getDir()->getName()); 1154 if (Filename == "module.map") 1155 llvm::sys::path::append(PrivateFilename, "module_private.map"); 1156 else if (Filename == "module.modulemap") 1157 llvm::sys::path::append(PrivateFilename, "module.private.modulemap"); 1158 else 1159 return nullptr; 1160 return FileMgr.getFile(PrivateFilename); 1161 } 1162 1163 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { 1164 // Find the directory for the module. For frameworks, that may require going 1165 // up from the 'Modules' directory. 1166 const DirectoryEntry *Dir = nullptr; 1167 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) 1168 Dir = FileMgr.getDirectory("."); 1169 else { 1170 Dir = File->getDir(); 1171 StringRef DirName(Dir->getName()); 1172 if (llvm::sys::path::filename(DirName) == "Modules") { 1173 DirName = llvm::sys::path::parent_path(DirName); 1174 if (DirName.endswith(".framework")) 1175 Dir = FileMgr.getDirectory(DirName); 1176 // FIXME: This assert can fail if there's a race between the above check 1177 // and the removal of the directory. 1178 assert(Dir && "parent must exist"); 1179 } 1180 } 1181 1182 switch (loadModuleMapFileImpl(File, IsSystem, Dir)) { 1183 case LMM_AlreadyLoaded: 1184 case LMM_NewlyLoaded: 1185 return false; 1186 case LMM_NoDirectory: 1187 case LMM_InvalidModuleMap: 1188 return true; 1189 } 1190 llvm_unreachable("Unknown load module map result"); 1191 } 1192 1193 HeaderSearch::LoadModuleMapResult 1194 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, 1195 const DirectoryEntry *Dir) { 1196 assert(File && "expected FileEntry"); 1197 1198 // Check whether we've already loaded this module map, and mark it as being 1199 // loaded in case we recursively try to load it from itself. 1200 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true)); 1201 if (!AddResult.second) 1202 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1203 1204 if (ModMap.parseModuleMapFile(File, IsSystem, Dir)) { 1205 LoadedModuleMaps[File] = false; 1206 return LMM_InvalidModuleMap; 1207 } 1208 1209 // Try to load a corresponding private module map. 1210 if (const FileEntry *PMMFile = getPrivateModuleMap(File, FileMgr)) { 1211 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) { 1212 LoadedModuleMaps[File] = false; 1213 return LMM_InvalidModuleMap; 1214 } 1215 } 1216 1217 // This directory has a module map. 1218 return LMM_NewlyLoaded; 1219 } 1220 1221 const FileEntry * 1222 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { 1223 if (!HSOpts->ImplicitModuleMaps) 1224 return nullptr; 1225 // For frameworks, the preferred spelling is Modules/module.modulemap, but 1226 // module.map at the framework root is also accepted. 1227 SmallString<128> ModuleMapFileName(Dir->getName()); 1228 if (IsFramework) 1229 llvm::sys::path::append(ModuleMapFileName, "Modules"); 1230 llvm::sys::path::append(ModuleMapFileName, "module.modulemap"); 1231 if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName)) 1232 return F; 1233 1234 // Continue to allow module.map 1235 ModuleMapFileName = Dir->getName(); 1236 llvm::sys::path::append(ModuleMapFileName, "module.map"); 1237 return FileMgr.getFile(ModuleMapFileName); 1238 } 1239 1240 Module *HeaderSearch::loadFrameworkModule(StringRef Name, 1241 const DirectoryEntry *Dir, 1242 bool IsSystem) { 1243 if (Module *Module = ModMap.findModule(Name)) 1244 return Module; 1245 1246 // Try to load a module map file. 1247 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { 1248 case LMM_InvalidModuleMap: 1249 // Try to infer a module map from the framework directory. 1250 if (HSOpts->ImplicitModuleMaps) 1251 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr); 1252 break; 1253 1254 case LMM_AlreadyLoaded: 1255 case LMM_NoDirectory: 1256 return nullptr; 1257 1258 case LMM_NewlyLoaded: 1259 break; 1260 } 1261 1262 return ModMap.findModule(Name); 1263 } 1264 1265 1266 HeaderSearch::LoadModuleMapResult 1267 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem, 1268 bool IsFramework) { 1269 if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 1270 return loadModuleMapFile(Dir, IsSystem, IsFramework); 1271 1272 return LMM_NoDirectory; 1273 } 1274 1275 HeaderSearch::LoadModuleMapResult 1276 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, 1277 bool IsFramework) { 1278 auto KnownDir = DirectoryHasModuleMap.find(Dir); 1279 if (KnownDir != DirectoryHasModuleMap.end()) 1280 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1281 1282 if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) { 1283 LoadModuleMapResult Result = 1284 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir); 1285 // Add Dir explicitly in case ModuleMapFile is in a subdirectory. 1286 // E.g. Foo.framework/Modules/module.modulemap 1287 // ^Dir ^ModuleMapFile 1288 if (Result == LMM_NewlyLoaded) 1289 DirectoryHasModuleMap[Dir] = true; 1290 else if (Result == LMM_InvalidModuleMap) 1291 DirectoryHasModuleMap[Dir] = false; 1292 return Result; 1293 } 1294 return LMM_InvalidModuleMap; 1295 } 1296 1297 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { 1298 Modules.clear(); 1299 1300 if (HSOpts->ImplicitModuleMaps) { 1301 // Load module maps for each of the header search directories. 1302 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 1303 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 1304 if (SearchDirs[Idx].isFramework()) { 1305 std::error_code EC; 1306 SmallString<128> DirNative; 1307 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), 1308 DirNative); 1309 1310 // Search each of the ".framework" directories to load them as modules. 1311 for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; 1312 Dir != DirEnd && !EC; Dir.increment(EC)) { 1313 if (llvm::sys::path::extension(Dir->path()) != ".framework") 1314 continue; 1315 1316 const DirectoryEntry *FrameworkDir = 1317 FileMgr.getDirectory(Dir->path()); 1318 if (!FrameworkDir) 1319 continue; 1320 1321 // Load this framework module. 1322 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, 1323 IsSystem); 1324 } 1325 continue; 1326 } 1327 1328 // FIXME: Deal with header maps. 1329 if (SearchDirs[Idx].isHeaderMap()) 1330 continue; 1331 1332 // Try to load a module map file for the search directory. 1333 loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, 1334 /*IsFramework*/ false); 1335 1336 // Try to load module map files for immediate subdirectories of this 1337 // search directory. 1338 loadSubdirectoryModuleMaps(SearchDirs[Idx]); 1339 } 1340 } 1341 1342 // Populate the list of modules. 1343 for (ModuleMap::module_iterator M = ModMap.module_begin(), 1344 MEnd = ModMap.module_end(); 1345 M != MEnd; ++M) { 1346 Modules.push_back(M->getValue()); 1347 } 1348 } 1349 1350 void HeaderSearch::loadTopLevelSystemModules() { 1351 if (!HSOpts->ImplicitModuleMaps) 1352 return; 1353 1354 // Load module maps for each of the header search directories. 1355 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 1356 // We only care about normal header directories. 1357 if (!SearchDirs[Idx].isNormalDir()) { 1358 continue; 1359 } 1360 1361 // Try to load a module map file for the search directory. 1362 loadModuleMapFile(SearchDirs[Idx].getDir(), 1363 SearchDirs[Idx].isSystemHeaderDirectory(), 1364 SearchDirs[Idx].isFramework()); 1365 } 1366 } 1367 1368 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { 1369 assert(HSOpts->ImplicitModuleMaps && 1370 "Should not be loading subdirectory module maps"); 1371 1372 if (SearchDir.haveSearchedAllModuleMaps()) 1373 return; 1374 1375 std::error_code EC; 1376 SmallString<128> DirNative; 1377 llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); 1378 for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; 1379 Dir != DirEnd && !EC; Dir.increment(EC)) { 1380 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework"; 1381 if (IsFramework == SearchDir.isFramework()) 1382 loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), 1383 SearchDir.isFramework()); 1384 } 1385 1386 SearchDir.setSearchedAllModuleMaps(true); 1387 } 1388