comparison clang/lib/Lex/HeaderSearch.cpp @ 252:1f2b6ac9f198 llvm-original

LLVM16-1
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 18 Aug 2023 09:04:13 +0900
parents c4bab56944e8
children
comparison
equal deleted inserted replaced
237:c80f45b162ad 252:1f2b6ac9f198
169 for (auto &HM : HeaderMaps) 169 for (auto &HM : HeaderMaps)
170 Names.push_back(std::string(HM.first->getName())); 170 Names.push_back(std::string(HM.first->getName()));
171 } 171 }
172 172
173 std::string HeaderSearch::getCachedModuleFileName(Module *Module) { 173 std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
174 Optional<FileEntryRef> ModuleMap = 174 OptionalFileEntryRef ModuleMap =
175 getModuleMap().getModuleMapFileForUniquing(Module); 175 getModuleMap().getModuleMapFileForUniquing(Module);
176 // The ModuleMap maybe a nullptr, when we load a cached C++ module without 176 // The ModuleMap maybe a nullptr, when we load a cached C++ module without
177 // *.modulemap file. In this case, just return an empty string. 177 // *.modulemap file. In this case, just return an empty string.
178 if (!ModuleMap) 178 if (!ModuleMap)
179 return {}; 179 return {};
210 210
211 return {}; 211 return {};
212 } 212 }
213 213
214 std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) { 214 std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
215 Optional<FileEntryRef> ModuleMap = 215 OptionalFileEntryRef ModuleMap =
216 getModuleMap().getModuleMapFileForUniquing(Module); 216 getModuleMap().getModuleMapFileForUniquing(Module);
217 StringRef ModuleName = Module->Name; 217 StringRef ModuleName = Module->Name;
218 StringRef ModuleMapPath = ModuleMap->getName(); 218 StringRef ModuleMapPath = ModuleMap->getName();
219 StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash(); 219 StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash();
220 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) { 220 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
309 if (Dir.isFramework()) { 309 if (Dir.isFramework()) {
310 // Search for or infer a module map for a framework. Here we use 310 // Search for or infer a module map for a framework. Here we use
311 // SearchName rather than ModuleName, to permit finding private modules 311 // SearchName rather than ModuleName, to permit finding private modules
312 // named FooPrivate in buggy frameworks named Foo. 312 // named FooPrivate in buggy frameworks named Foo.
313 SmallString<128> FrameworkDirName; 313 SmallString<128> FrameworkDirName;
314 FrameworkDirName += Dir.getFrameworkDir()->getName(); 314 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
315 llvm::sys::path::append(FrameworkDirName, SearchName + ".framework"); 315 llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
316 if (auto FrameworkDir = 316 if (auto FrameworkDir =
317 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) { 317 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
318 bool IsSystem = Dir.getDirCharacteristic() != SrcMgr::C_User; 318 bool IsSystem = Dir.getDirCharacteristic() != SrcMgr::C_User;
319 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem); 319 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
327 // Only deal with normal search directories. 327 // Only deal with normal search directories.
328 if (!Dir.isNormalDir()) 328 if (!Dir.isNormalDir())
329 continue; 329 continue;
330 330
331 bool IsSystem = Dir.isSystemHeaderDirectory(); 331 bool IsSystem = Dir.isSystemHeaderDirectory();
332 // Only returns None if not a normal directory, which we just checked 332 // Only returns std::nullopt if not a normal directory, which we just
333 // checked
333 DirectoryEntryRef NormalDir = *Dir.getDirRef(); 334 DirectoryEntryRef NormalDir = *Dir.getDirRef();
334 // Search for a module map file in this directory. 335 // Search for a module map file in this directory.
335 if (loadModuleMapFile(NormalDir, IsSystem, 336 if (loadModuleMapFile(NormalDir, IsSystem,
336 /*IsFramework*/false) == LMM_NewlyLoaded) { 337 /*IsFramework*/false) == LMM_NewlyLoaded) {
337 // We just loaded a module map file; check whether the module is 338 // We just loaded a module map file; check whether the module is
342 } 343 }
343 344
344 // Search for a module map in a subdirectory with the same name as the 345 // Search for a module map in a subdirectory with the same name as the
345 // module. 346 // module.
346 SmallString<128> NestedModuleMapDirName; 347 SmallString<128> NestedModuleMapDirName;
347 NestedModuleMapDirName = Dir.getDir()->getName(); 348 NestedModuleMapDirName = Dir.getDirRef()->getName();
348 llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 349 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
349 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem, 350 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
350 /*IsFramework*/false) == LMM_NewlyLoaded){ 351 /*IsFramework*/false) == LMM_NewlyLoaded){
351 // If we just loaded a module map file, look for the module again. 352 // If we just loaded a module map file, look for the module again.
352 Module = ModMap.findModule(ModuleName); 353 Module = ModMap.findModule(ModuleName);
375 376
376 void HeaderSearch::indexInitialHeaderMaps() { 377 void HeaderSearch::indexInitialHeaderMaps() {
377 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size()); 378 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
378 379
379 // Iterate over all filename keys and associate them with the index i. 380 // Iterate over all filename keys and associate them with the index i.
380 unsigned i = 0; 381 for (unsigned i = 0; i != SearchDirs.size(); ++i) {
381 for (; i != SearchDirs.size(); ++i) {
382 auto &Dir = SearchDirs[i]; 382 auto &Dir = SearchDirs[i];
383 383
384 // We're concerned with only the initial contiguous run of header 384 // We're concerned with only the initial contiguous run of header
385 // maps within SearchDirs, which can be 99% of SearchDirs when 385 // maps within SearchDirs, which can be 99% of SearchDirs when
386 // SearchDirs.size() is ~10000. 386 // SearchDirs.size() is ~10000.
387 if (!Dir.isHeaderMap()) 387 if (!Dir.isHeaderMap()) {
388 SearchDirHeaderMapIndex = std::move(Index);
389 FirstNonHeaderMapSearchDirIdx = i;
388 break; 390 break;
391 }
389 392
390 // Give earlier keys precedence over identical later keys. 393 // Give earlier keys precedence over identical later keys.
391 auto Callback = [&](StringRef Filename) { 394 auto Callback = [&](StringRef Filename) {
392 Index.try_emplace(Filename.lower(), i); 395 Index.try_emplace(Filename.lower(), i);
393 }; 396 };
394 Dir.getHeaderMap()->forEachKey(Callback); 397 Dir.getHeaderMap()->forEachKey(Callback);
395 } 398 }
396
397 SearchDirHeaderMapIndex = std::move(Index);
398 FirstNonHeaderMapSearchDirIdx = i;
399 } 399 }
400 400
401 //===----------------------------------------------------------------------===// 401 //===----------------------------------------------------------------------===//
402 // File lookup within a DirectoryLookup scope 402 // File lookup within a DirectoryLookup scope
403 //===----------------------------------------------------------------------===// 403 //===----------------------------------------------------------------------===//
404 404
405 /// getName - Return the directory or filename corresponding to this lookup 405 /// getName - Return the directory or filename corresponding to this lookup
406 /// object. 406 /// object.
407 StringRef DirectoryLookup::getName() const { 407 StringRef DirectoryLookup::getName() const {
408 // FIXME: Use the name from \c DirectoryEntryRef.
409 if (isNormalDir()) 408 if (isNormalDir())
410 return getDir()->getName(); 409 return getDirRef()->getName();
411 if (isFramework()) 410 if (isFramework())
412 return getFrameworkDir()->getName(); 411 return getFrameworkDirRef()->getName();
413 assert(isHeaderMap() && "Unknown DirectoryLookup"); 412 assert(isHeaderMap() && "Unknown DirectoryLookup");
414 return getHeaderMap()->getFileName(); 413 return getHeaderMap()->getFileName();
415 } 414 }
416 415
417 Optional<FileEntryRef> HeaderSearch::getFileAndSuggestModule( 416 OptionalFileEntryRef HeaderSearch::getFileAndSuggestModule(
418 StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir, 417 StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
419 bool IsSystemHeaderDir, Module *RequestingModule, 418 bool IsSystemHeaderDir, Module *RequestingModule,
420 ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/, 419 ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/,
421 bool CacheFailures /*=true*/) { 420 bool CacheFailures /*=true*/) {
422 // If we have a module map that might map this header, load it and 421 // If we have a module map that might map this header, load it and
430 EC != llvm::errc::invalid_argument && 429 EC != llvm::errc::invalid_argument &&
431 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) { 430 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
432 Diags.Report(IncludeLoc, diag::err_cannot_open_file) 431 Diags.Report(IncludeLoc, diag::err_cannot_open_file)
433 << FileName << EC.message(); 432 << FileName << EC.message();
434 } 433 }
435 return None; 434 return std::nullopt;
436 } 435 }
437 436
438 // If there is a module that corresponds to this header, suggest it. 437 // If there is a module that corresponds to this header, suggest it.
439 if (!findUsableModuleForHeader( 438 if (!findUsableModuleForHeader(
440 &File->getFileEntry(), Dir ? Dir : File->getFileEntry().getDir(), 439 *File, Dir ? Dir : File->getFileEntry().getDir(), RequestingModule,
441 RequestingModule, SuggestedModule, IsSystemHeaderDir)) 440 SuggestedModule, IsSystemHeaderDir))
442 return None; 441 return std::nullopt;
443 442
444 return *File; 443 return *File;
445 } 444 }
446 445
447 /// LookupFile - Lookup the specified file in this search path, returning it 446 /// LookupFile - Lookup the specified file in this search path, returning it
448 /// if it exists or returning null if not. 447 /// if it exists or returning null if not.
449 Optional<FileEntryRef> DirectoryLookup::LookupFile( 448 OptionalFileEntryRef DirectoryLookup::LookupFile(
450 StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, 449 StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
451 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, 450 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
452 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, 451 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
453 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, 452 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
454 bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName, 453 bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName,
485 assert(isHeaderMap() && "Unknown directory lookup"); 484 assert(isHeaderMap() && "Unknown directory lookup");
486 const HeaderMap *HM = getHeaderMap(); 485 const HeaderMap *HM = getHeaderMap();
487 SmallString<1024> Path; 486 SmallString<1024> Path;
488 StringRef Dest = HM->lookupFilename(Filename, Path); 487 StringRef Dest = HM->lookupFilename(Filename, Path);
489 if (Dest.empty()) 488 if (Dest.empty())
490 return None; 489 return std::nullopt;
491 490
492 IsInHeaderMap = true; 491 IsInHeaderMap = true;
493 492
494 auto FixupSearchPath = [&]() { 493 auto FixupSearchPathAndFindUsableModule =
494 [&](FileEntryRef File) -> OptionalFileEntryRef {
495 if (SearchPath) { 495 if (SearchPath) {
496 StringRef SearchPathRef(getName()); 496 StringRef SearchPathRef(getName());
497 SearchPath->clear(); 497 SearchPath->clear();
498 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 498 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
499 } 499 }
500 if (RelativePath) { 500 if (RelativePath) {
501 RelativePath->clear(); 501 RelativePath->clear();
502 RelativePath->append(Filename.begin(), Filename.end()); 502 RelativePath->append(Filename.begin(), Filename.end());
503 } 503 }
504 if (!HS.findUsableModuleForHeader(File, File.getFileEntry().getDir(),
505 RequestingModule, SuggestedModule,
506 isSystemHeaderDirectory())) {
507 return std::nullopt;
508 }
509 return File;
504 }; 510 };
505 511
506 // Check if the headermap maps the filename to a framework include 512 // Check if the headermap maps the filename to a framework include
507 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the 513 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
508 // framework include. 514 // framework include.
511 Filename = StringRef(MappedName.begin(), MappedName.size()); 517 Filename = StringRef(MappedName.begin(), MappedName.size());
512 Dest = HM->lookupFilename(Filename, Path); 518 Dest = HM->lookupFilename(Filename, Path);
513 } 519 }
514 520
515 if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest, OpenFile)) { 521 if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest, OpenFile)) {
516 FixupSearchPath(); 522 return FixupSearchPathAndFindUsableModule(*Res);
517 return *Res;
518 } 523 }
519 524
520 // Header maps need to be marked as used whenever the filename matches. 525 // Header maps need to be marked as used whenever the filename matches.
521 // The case where the target file **exists** is handled by callee of this 526 // The case where the target file **exists** is handled by callee of this
522 // function as part of the regular logic that applies to include search paths. 527 // function as part of the regular logic that applies to include search paths.
523 // The case where the target file **does not exist** is handled here: 528 // The case where the target file **does not exist** is handled here:
524 HS.noteLookupUsage(HS.searchDirIdx(*this), IncludeLoc); 529 HS.noteLookupUsage(HS.searchDirIdx(*this), IncludeLoc);
525 return None; 530 return std::nullopt;
526 } 531 }
527 532
528 /// Given a framework directory, find the top-most framework directory. 533 /// Given a framework directory, find the top-most framework directory.
529 /// 534 ///
530 /// \param FileMgr The file manager to use for directory lookups. 535 /// \param FileMgr The file manager to use for directory lookups.
531 /// \param DirName The name of the framework directory. 536 /// \param DirName The name of the framework directory.
532 /// \param SubmodulePath Will be populated with the submodule path from the 537 /// \param SubmodulePath Will be populated with the submodule path from the
533 /// returned top-level module to the originally named framework. 538 /// returned top-level module to the originally named framework.
534 static Optional<DirectoryEntryRef> 539 static OptionalDirectoryEntryRef
535 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, 540 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
536 SmallVectorImpl<std::string> &SubmodulePath) { 541 SmallVectorImpl<std::string> &SubmodulePath) {
537 assert(llvm::sys::path::extension(DirName) == ".framework" && 542 assert(llvm::sys::path::extension(DirName) == ".framework" &&
538 "Not a framework directory"); 543 "Not a framework directory");
539 544
583 (RequestingModule && RequestingModule->NoUndeclaredIncludes); 588 (RequestingModule && RequestingModule->NoUndeclaredIncludes);
584 } 589 }
585 590
586 /// DoFrameworkLookup - Do a lookup of the specified file in the current 591 /// DoFrameworkLookup - Do a lookup of the specified file in the current
587 /// DirectoryLookup, which is a framework directory. 592 /// DirectoryLookup, which is a framework directory.
588 Optional<FileEntryRef> DirectoryLookup::DoFrameworkLookup( 593 OptionalFileEntryRef DirectoryLookup::DoFrameworkLookup(
589 StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, 594 StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
590 SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 595 SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
591 ModuleMap::KnownHeader *SuggestedModule, 596 ModuleMap::KnownHeader *SuggestedModule,
592 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const { 597 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
593 FileManager &FileMgr = HS.getFileMgr(); 598 FileManager &FileMgr = HS.getFileMgr();
594 599
595 // Framework names must have a '/' in the filename. 600 // Framework names must have a '/' in the filename.
596 size_t SlashPos = Filename.find('/'); 601 size_t SlashPos = Filename.find('/');
597 if (SlashPos == StringRef::npos) 602 if (SlashPos == StringRef::npos)
598 return None; 603 return std::nullopt;
599 604
600 // Find out if this is the home for the specified framework, by checking 605 // Find out if this is the home for the specified framework, by checking
601 // HeaderSearch. Possible answers are yes/no and unknown. 606 // HeaderSearch. Possible answers are yes/no and unknown.
602 FrameworkCacheEntry &CacheEntry = 607 FrameworkCacheEntry &CacheEntry =
603 HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 608 HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
604 609
605 // If it is known and in some other directory, fail. 610 // If it is known and in some other directory, fail.
606 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDirRef()) 611 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDirRef())
607 return None; 612 return std::nullopt;
608 613
609 // Otherwise, construct the path to this framework dir. 614 // Otherwise, construct the path to this framework dir.
610 615
611 // FrameworkName = "/System/Library/Frameworks/" 616 // FrameworkName = "/System/Library/Frameworks/"
612 SmallString<1024> FrameworkName; 617 SmallString<1024> FrameworkName;
626 ++NumFrameworkLookups; 631 ++NumFrameworkLookups;
627 632
628 // If the framework dir doesn't exist, we fail. 633 // If the framework dir doesn't exist, we fail.
629 auto Dir = FileMgr.getDirectory(FrameworkName); 634 auto Dir = FileMgr.getDirectory(FrameworkName);
630 if (!Dir) 635 if (!Dir)
631 return None; 636 return std::nullopt;
632 637
633 // Otherwise, if it does, remember that this is the right direntry for this 638 // Otherwise, if it does, remember that this is the right direntry for this
634 // framework. 639 // framework.
635 CacheEntry.Directory = getFrameworkDirRef(); 640 CacheEntry.Directory = getFrameworkDirRef();
636 641
683 } 688 }
684 689
685 // If we found the header and are allowed to suggest a module, do so now. 690 // If we found the header and are allowed to suggest a module, do so now.
686 if (File && needModuleLookup(RequestingModule, SuggestedModule)) { 691 if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
687 // Find the framework in which this header occurs. 692 // Find the framework in which this header occurs.
688 StringRef FrameworkPath = File->getFileEntry().getDir()->getName(); 693 StringRef FrameworkPath = File->getDir().getName();
689 bool FoundFramework = false; 694 bool FoundFramework = false;
690 do { 695 do {
691 // Determine whether this directory exists. 696 // Determine whether this directory exists.
692 auto Dir = FileMgr.getDirectory(FrameworkPath); 697 auto Dir = FileMgr.getDirectory(FrameworkPath);
693 if (!Dir) 698 if (!Dir)
706 break; 711 break;
707 } while (true); 712 } while (true);
708 713
709 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 714 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
710 if (FoundFramework) { 715 if (FoundFramework) {
711 if (!HS.findUsableModuleForFrameworkHeader( 716 if (!HS.findUsableModuleForFrameworkHeader(*File, FrameworkPath,
712 &File->getFileEntry(), FrameworkPath, RequestingModule, 717 RequestingModule,
713 SuggestedModule, IsSystem)) 718 SuggestedModule, IsSystem))
714 return None; 719 return std::nullopt;
715 } else { 720 } else {
716 if (!HS.findUsableModuleForHeader(&File->getFileEntry(), getDir(), 721 if (!HS.findUsableModuleForHeader(*File, getDir(), RequestingModule,
717 RequestingModule, SuggestedModule, 722 SuggestedModule, IsSystem))
718 IsSystem)) 723 return std::nullopt;
719 return None;
720 } 724 }
721 } 725 }
722 if (File) 726 if (File)
723 return *File; 727 return *File;
724 return None; 728 return std::nullopt;
725 } 729 }
726 730
727 void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup, 731 void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
728 ConstSearchDirIterator HitIt, 732 ConstSearchDirIterator HitIt,
729 SourceLocation Loc) { 733 SourceLocation Loc) {
852 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file, 856 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
853 /// return null on failure. isAngled indicates whether the file reference is 857 /// return null on failure. isAngled indicates whether the file reference is
854 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if 858 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
855 /// non-empty, indicates where the \#including file(s) are, in case a relative 859 /// non-empty, indicates where the \#including file(s) are, in case a relative
856 /// search is needed. Microsoft mode will pass all \#including files. 860 /// search is needed. Microsoft mode will pass all \#including files.
857 Optional<FileEntryRef> HeaderSearch::LookupFile( 861 OptionalFileEntryRef HeaderSearch::LookupFile(
858 StringRef Filename, SourceLocation IncludeLoc, bool isAngled, 862 StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
859 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg, 863 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
860 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, 864 ArrayRef<std::pair<const FileEntry *, DirectoryEntryRef>> Includers,
861 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, 865 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
862 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, 866 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
863 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache, 867 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
864 bool BuildSystemModule, bool OpenFile, bool CacheFailures) { 868 bool BuildSystemModule, bool OpenFile, bool CacheFailures) {
865 ConstSearchDirIterator CurDirLocal = nullptr; 869 ConstSearchDirIterator CurDirLocal = nullptr;
878 if (llvm::sys::path::is_absolute(Filename)) { 882 if (llvm::sys::path::is_absolute(Filename)) {
879 CurDir = nullptr; 883 CurDir = nullptr;
880 884
881 // If this was an #include_next "/absolute/file", fail. 885 // If this was an #include_next "/absolute/file", fail.
882 if (FromDir) 886 if (FromDir)
883 return None; 887 return std::nullopt;
884 888
885 if (SearchPath) 889 if (SearchPath)
886 SearchPath->clear(); 890 SearchPath->clear();
887 if (RelativePath) { 891 if (RelativePath) {
888 RelativePath->clear(); 892 RelativePath->clear();
895 CacheFailures); 899 CacheFailures);
896 } 900 }
897 901
898 // This is the header that MSVC's header search would have found. 902 // This is the header that MSVC's header search would have found.
899 ModuleMap::KnownHeader MSSuggestedModule; 903 ModuleMap::KnownHeader MSSuggestedModule;
900 Optional<FileEntryRef> MSFE; 904 OptionalFileEntryRef MSFE;
901 905
902 // Unless disabled, check to see if the file is in the #includer's 906 // Unless disabled, check to see if the file is in the #includer's
903 // directory. This cannot be based on CurDir, because each includer could be 907 // directory. This cannot be based on CurDir, because each includer could be
904 // a #include of a subdirectory (#include "foo/bar.h") and a subsequent 908 // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
905 // include of "baz.h" should resolve to "whatever/foo/baz.h". 909 // include of "baz.h" should resolve to "whatever/foo/baz.h".
910 for (const auto &IncluderAndDir : Includers) { 914 for (const auto &IncluderAndDir : Includers) {
911 const FileEntry *Includer = IncluderAndDir.first; 915 const FileEntry *Includer = IncluderAndDir.first;
912 916
913 // Concatenate the requested file onto the directory. 917 // Concatenate the requested file onto the directory.
914 // FIXME: Portability. Filename concatenation should be in sys::Path. 918 // FIXME: Portability. Filename concatenation should be in sys::Path.
915 TmpDir = IncluderAndDir.second->getName(); 919 TmpDir = IncluderAndDir.second.getName();
916 TmpDir.push_back('/'); 920 TmpDir.push_back('/');
917 TmpDir.append(Filename.begin(), Filename.end()); 921 TmpDir.append(Filename.begin(), Filename.end());
918 922
919 // FIXME: We don't cache the result of getFileInfo across the call to 923 // FIXME: We don't cache the result of getFileInfo across the call to
920 // getFileAndSuggestModule, because it's a reference to an element of 924 // getFileAndSuggestModule, because it's a reference to an element of
924 // from a module build. We should treat this as a system header if we're 928 // from a module build. We should treat this as a system header if we're
925 // building a [system] module. 929 // building a [system] module.
926 bool IncluderIsSystemHeader = 930 bool IncluderIsSystemHeader =
927 Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User : 931 Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User :
928 BuildSystemModule; 932 BuildSystemModule;
929 if (Optional<FileEntryRef> FE = getFileAndSuggestModule( 933 if (OptionalFileEntryRef FE = getFileAndSuggestModule(
930 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader, 934 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
931 RequestingModule, SuggestedModule)) { 935 RequestingModule, SuggestedModule)) {
932 if (!Includer) { 936 if (!Includer) {
933 assert(First && "only first includer can have no file"); 937 assert(First && "only first includer can have no file");
934 return FE; 938 return FE;
949 ToHFI.DirInfo = DirInfo; 953 ToHFI.DirInfo = DirInfo;
950 ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; 954 ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
951 ToHFI.Framework = Framework; 955 ToHFI.Framework = Framework;
952 956
953 if (SearchPath) { 957 if (SearchPath) {
954 StringRef SearchPathRef(IncluderAndDir.second->getName()); 958 StringRef SearchPathRef(IncluderAndDir.second.getName());
955 SearchPath->clear(); 959 SearchPath->clear();
956 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 960 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
957 } 961 }
958 if (RelativePath) { 962 if (RelativePath) {
959 RelativePath->clear(); 963 RelativePath->clear();
960 RelativePath->append(Filename.begin(), Filename.end()); 964 RelativePath->append(Filename.begin(), Filename.end());
961 } 965 }
962 if (First) { 966 if (First) {
963 diagnoseFrameworkInclude(Diags, IncludeLoc, 967 diagnoseFrameworkInclude(Diags, IncludeLoc,
964 IncluderAndDir.second->getName(), Filename, 968 IncluderAndDir.second.getName(), Filename,
965 &FE->getFileEntry()); 969 &FE->getFileEntry());
966 return FE; 970 return FE;
967 } 971 }
968 972
969 // Otherwise, we found the path via MSVC header search rules. If 973 // Otherwise, we found the path via MSVC header search rules. If
1002 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename]; 1006 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1003 1007
1004 ConstSearchDirIterator NextIt = std::next(It); 1008 ConstSearchDirIterator NextIt = std::next(It);
1005 1009
1006 if (!SkipCache) { 1010 if (!SkipCache) {
1007 if (CacheLookup.StartIt == NextIt) { 1011 if (CacheLookup.StartIt == NextIt &&
1012 CacheLookup.RequestingModule == RequestingModule) {
1008 // HIT: Skip querying potentially lots of directories for this lookup. 1013 // HIT: Skip querying potentially lots of directories for this lookup.
1009 if (CacheLookup.HitIt) 1014 if (CacheLookup.HitIt)
1010 It = CacheLookup.HitIt; 1015 It = CacheLookup.HitIt;
1011 if (CacheLookup.MappedName) { 1016 if (CacheLookup.MappedName) {
1012 Filename = CacheLookup.MappedName; 1017 Filename = CacheLookup.MappedName;
1015 } 1020 }
1016 } else { 1021 } else {
1017 // MISS: This is the first query, or the previous query didn't match 1022 // MISS: This is the first query, or the previous query didn't match
1018 // our search start. We will fill in our found location below, so prime 1023 // our search start. We will fill in our found location below, so prime
1019 // the start point value. 1024 // the start point value.
1020 CacheLookup.reset(/*NewStartIt=*/NextIt); 1025 CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1021 1026
1022 if (It == search_dir_begin() && FirstNonHeaderMapSearchDirIdx > 0) { 1027 if (It == search_dir_begin() && FirstNonHeaderMapSearchDirIdx > 0) {
1023 // Handle cold misses of user includes in the presence of many header 1028 // Handle cold misses of user includes in the presence of many header
1024 // maps. We avoid searching perhaps thousands of header maps by 1029 // maps. We avoid searching perhaps thousands of header maps by
1025 // jumping directly to the correct one or jumping beyond all of them. 1030 // jumping directly to the correct one or jumping beyond all of them.
1030 else 1035 else
1031 // In index => Start with a specific header map 1036 // In index => Start with a specific header map
1032 It = search_dir_nth(Iter->second); 1037 It = search_dir_nth(Iter->second);
1033 } 1038 }
1034 } 1039 }
1035 } else 1040 } else {
1036 CacheLookup.reset(/*NewStartIt=*/NextIt); 1041 CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1042 }
1037 1043
1038 SmallString<64> MappedName; 1044 SmallString<64> MappedName;
1039 1045
1040 // Check each directory in sequence to see if it contains this file. 1046 // Check each directory in sequence to see if it contains this file.
1041 for (; It != search_dir_end(); ++It) { 1047 for (; It != search_dir_end(); ++It) {
1042 bool InUserSpecifiedSystemFramework = false; 1048 bool InUserSpecifiedSystemFramework = false;
1043 bool IsInHeaderMap = false; 1049 bool IsInHeaderMap = false;
1044 bool IsFrameworkFoundInDir = false; 1050 bool IsFrameworkFoundInDir = false;
1045 Optional<FileEntryRef> File = It->LookupFile( 1051 OptionalFileEntryRef File = It->LookupFile(
1046 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule, 1052 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1047 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir, 1053 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1048 IsInHeaderMap, MappedName, OpenFile); 1054 IsInHeaderMap, MappedName, OpenFile);
1049 if (!MappedName.empty()) { 1055 if (!MappedName.empty()) {
1050 assert(IsInHeaderMap && "MappedName should come from a header map"); 1056 assert(IsInHeaderMap && "MappedName should come from a header map");
1114 } 1120 }
1115 1121
1116 bool FoundByHeaderMap = !IsMapped ? false : *IsMapped; 1122 bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
1117 if (!Includers.empty()) 1123 if (!Includers.empty())
1118 diagnoseFrameworkInclude( 1124 diagnoseFrameworkInclude(
1119 Diags, IncludeLoc, Includers.front().second->getName(), Filename, 1125 Diags, IncludeLoc, Includers.front().second.getName(), Filename,
1120 &File->getFileEntry(), isAngled, FoundByHeaderMap); 1126 &File->getFileEntry(), isAngled, FoundByHeaderMap);
1121 1127
1122 // Remember this location for the next lookup we do. 1128 // Remember this location for the next lookup we do.
1123 cacheLookupSuccess(CacheLookup, It, IncludeLoc); 1129 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1124 return File; 1130 return File;
1135 SmallString<128> ScratchFilename; 1141 SmallString<128> ScratchFilename;
1136 ScratchFilename += IncludingHFI.Framework; 1142 ScratchFilename += IncludingHFI.Framework;
1137 ScratchFilename += '/'; 1143 ScratchFilename += '/';
1138 ScratchFilename += Filename; 1144 ScratchFilename += Filename;
1139 1145
1140 Optional<FileEntryRef> File = LookupFile( 1146 OptionalFileEntryRef File = LookupFile(
1141 ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, &CurDir, 1147 ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, &CurDir,
1142 Includers.front(), SearchPath, RelativePath, RequestingModule, 1148 Includers.front(), SearchPath, RelativePath, RequestingModule,
1143 SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr); 1149 SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr);
1144 1150
1145 if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr, 1151 if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr,
1164 return MSFE; 1170 return MSFE;
1165 } 1171 }
1166 1172
1167 // Otherwise, didn't find it. Remember we didn't find this. 1173 // Otherwise, didn't find it. Remember we didn't find this.
1168 CacheLookup.HitIt = search_dir_end(); 1174 CacheLookup.HitIt = search_dir_end();
1169 return None; 1175 return std::nullopt;
1170 } 1176 }
1171 1177
1172 /// LookupSubframeworkHeader - Look up a subframework for the specified 1178 /// LookupSubframeworkHeader - Look up a subframework for the specified
1173 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from 1179 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
1174 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 1180 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
1175 /// is a subframework within Carbon.framework. If so, return the FileEntry 1181 /// is a subframework within Carbon.framework. If so, return the FileEntry
1176 /// for the designated file, otherwise return null. 1182 /// for the designated file, otherwise return null.
1177 Optional<FileEntryRef> HeaderSearch::LookupSubframeworkHeader( 1183 OptionalFileEntryRef HeaderSearch::LookupSubframeworkHeader(
1178 StringRef Filename, const FileEntry *ContextFileEnt, 1184 StringRef Filename, const FileEntry *ContextFileEnt,
1179 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, 1185 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
1180 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) { 1186 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {
1181 assert(ContextFileEnt && "No context file?"); 1187 assert(ContextFileEnt && "No context file?");
1182 1188
1183 // Framework names must have a '/' in the filename. Find it. 1189 // Framework names must have a '/' in the filename. Find it.
1184 // FIXME: Should we permit '\' on Windows? 1190 // FIXME: Should we permit '\' on Windows?
1185 size_t SlashPos = Filename.find('/'); 1191 size_t SlashPos = Filename.find('/');
1186 if (SlashPos == StringRef::npos) 1192 if (SlashPos == StringRef::npos)
1187 return None; 1193 return std::nullopt;
1188 1194
1189 // Look up the base framework name of the ContextFileEnt. 1195 // Look up the base framework name of the ContextFileEnt.
1190 StringRef ContextName = ContextFileEnt->getName(); 1196 StringRef ContextName = ContextFileEnt->getName();
1191 1197
1192 // If the context info wasn't a framework, couldn't be a subframework. 1198 // If the context info wasn't a framework, couldn't be a subframework.
1193 const unsigned DotFrameworkLen = 10; 1199 const unsigned DotFrameworkLen = 10;
1194 auto FrameworkPos = ContextName.find(".framework"); 1200 auto FrameworkPos = ContextName.find(".framework");
1195 if (FrameworkPos == StringRef::npos || 1201 if (FrameworkPos == StringRef::npos ||
1196 (ContextName[FrameworkPos + DotFrameworkLen] != '/' && 1202 (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1197 ContextName[FrameworkPos + DotFrameworkLen] != '\\')) 1203 ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1198 return None; 1204 return std::nullopt;
1199 1205
1200 SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() + 1206 SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1201 FrameworkPos + 1207 FrameworkPos +
1202 DotFrameworkLen + 1); 1208 DotFrameworkLen + 1);
1203 1209
1213 // Some other location? 1219 // Some other location?
1214 if (CacheLookup.second.Directory && 1220 if (CacheLookup.second.Directory &&
1215 CacheLookup.first().size() == FrameworkName.size() && 1221 CacheLookup.first().size() == FrameworkName.size() &&
1216 memcmp(CacheLookup.first().data(), &FrameworkName[0], 1222 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1217 CacheLookup.first().size()) != 0) 1223 CacheLookup.first().size()) != 0)
1218 return None; 1224 return std::nullopt;
1219 1225
1220 // Cache subframework. 1226 // Cache subframework.
1221 if (!CacheLookup.second.Directory) { 1227 if (!CacheLookup.second.Directory) {
1222 ++NumSubFrameworkLookups; 1228 ++NumSubFrameworkLookups;
1223 1229
1224 // If the framework dir doesn't exist, we fail. 1230 // If the framework dir doesn't exist, we fail.
1225 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName); 1231 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1226 if (!Dir) 1232 if (!Dir)
1227 return None; 1233 return std::nullopt;
1228 1234
1229 // Otherwise, if it does, remember that this is the right direntry for this 1235 // Otherwise, if it does, remember that this is the right direntry for this
1230 // framework. 1236 // framework.
1231 CacheLookup.second.Directory = Dir; 1237 CacheLookup.second.Directory = Dir;
1232 } 1238 }
1260 1266
1261 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 1267 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1262 File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true); 1268 File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1263 1269
1264 if (!File) 1270 if (!File)
1265 return None; 1271 return std::nullopt;
1266 } 1272 }
1267 1273
1268 // This file is a system header or C++ unfriendly if the old file is. 1274 // This file is a system header or C++ unfriendly if the old file is.
1269 // 1275 //
1270 // Note that the temporary 'DirInfo' is required here, as either call to 1276 // Note that the temporary 'DirInfo' is required here, as either call to
1272 // of evaluation. 1278 // of evaluation.
1273 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 1279 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
1274 getFileInfo(&File->getFileEntry()).DirInfo = DirInfo; 1280 getFileInfo(&File->getFileEntry()).DirInfo = DirInfo;
1275 1281
1276 FrameworkName.pop_back(); // remove the trailing '/' 1282 FrameworkName.pop_back(); // remove the trailing '/'
1277 if (!findUsableModuleForFrameworkHeader(&File->getFileEntry(), FrameworkName, 1283 if (!findUsableModuleForFrameworkHeader(*File, FrameworkName,
1278 RequestingModule, SuggestedModule, 1284 RequestingModule, SuggestedModule,
1279 /*IsSystem*/ false)) 1285 /*IsSystem*/ false))
1280 return None; 1286 return std::nullopt;
1281 1287
1282 return *File; 1288 return *File;
1283 } 1289 }
1284 1290
1285 //===----------------------------------------------------------------------===// 1291 //===----------------------------------------------------------------------===//
1368 return nullptr; 1374 return nullptr;
1369 1375
1370 return HFI; 1376 return HFI;
1371 } 1377 }
1372 1378
1373 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 1379 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) const {
1374 // Check if we've entered this file and found an include guard or #pragma 1380 // Check if we've entered this file and found an include guard or #pragma
1375 // once. Note that we dor't check for #import, because that's not a property 1381 // once. Note that we dor't check for #import, because that's not a property
1376 // of the file itself. 1382 // of the file itself.
1377 if (auto *HFI = getExistingFileInfo(File)) 1383 if (auto *HFI = getExistingFileInfo(File))
1378 return HFI->isPragmaOnce || HFI->ControllingMacro || 1384 return HFI->isPragmaOnce || HFI->ControllingMacro ||
1552 FixUpDirectories.push_back(*Dir); 1558 FixUpDirectories.push_back(*Dir);
1553 } while (true); 1559 } while (true);
1554 } 1560 }
1555 1561
1556 ModuleMap::KnownHeader 1562 ModuleMap::KnownHeader
1557 HeaderSearch::findModuleForHeader(const FileEntry *File, bool AllowTextual, 1563 HeaderSearch::findModuleForHeader(FileEntryRef File, bool AllowTextual,
1558 bool AllowExcluded) const { 1564 bool AllowExcluded) const {
1559 if (ExternalSource) { 1565 if (ExternalSource) {
1560 // Make sure the external source has handled header info about this file, 1566 // Make sure the external source has handled header info about this file,
1561 // which includes whether the file is part of a module. 1567 // which includes whether the file is part of a module.
1562 (void)getExistingFileInfo(File); 1568 (void)getExistingFileInfo(File);
1563 } 1569 }
1564 return ModMap.findModuleForHeader(File, AllowTextual, AllowExcluded); 1570 return ModMap.findModuleForHeader(File, AllowTextual, AllowExcluded);
1565 } 1571 }
1566 1572
1567 ArrayRef<ModuleMap::KnownHeader> 1573 ArrayRef<ModuleMap::KnownHeader>
1568 HeaderSearch::findAllModulesForHeader(const FileEntry *File) const { 1574 HeaderSearch::findAllModulesForHeader(FileEntryRef File) const {
1569 if (ExternalSource) { 1575 if (ExternalSource) {
1570 // Make sure the external source has handled header info about this file, 1576 // Make sure the external source has handled header info about this file,
1571 // which includes whether the file is part of a module. 1577 // which includes whether the file is part of a module.
1572 (void)getExistingFileInfo(File); 1578 (void)getExistingFileInfo(File);
1573 } 1579 }
1574 return ModMap.findAllModulesForHeader(File); 1580 return ModMap.findAllModulesForHeader(File);
1575 } 1581 }
1576 1582
1577 static bool suggestModule(HeaderSearch &HS, const FileEntry *File, 1583 ArrayRef<ModuleMap::KnownHeader>
1584 HeaderSearch::findResolvedModulesForHeader(const FileEntry *File) const {
1585 if (ExternalSource) {
1586 // Make sure the external source has handled header info about this file,
1587 // which includes whether the file is part of a module.
1588 (void)getExistingFileInfo(File);
1589 }
1590 return ModMap.findResolvedModulesForHeader(File);
1591 }
1592
1593 static bool suggestModule(HeaderSearch &HS, FileEntryRef File,
1578 Module *RequestingModule, 1594 Module *RequestingModule,
1579 ModuleMap::KnownHeader *SuggestedModule) { 1595 ModuleMap::KnownHeader *SuggestedModule) {
1580 ModuleMap::KnownHeader Module = 1596 ModuleMap::KnownHeader Module =
1581 HS.findModuleForHeader(File, /*AllowTextual*/true); 1597 HS.findModuleForHeader(File, /*AllowTextual*/true);
1582 1598
1608 1624
1609 return true; 1625 return true;
1610 } 1626 }
1611 1627
1612 bool HeaderSearch::findUsableModuleForHeader( 1628 bool HeaderSearch::findUsableModuleForHeader(
1613 const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule, 1629 FileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule,
1614 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) { 1630 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1615 if (File && needModuleLookup(RequestingModule, SuggestedModule)) { 1631 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1616 // If there is a module that corresponds to this header, suggest it. 1632 // If there is a module that corresponds to this header, suggest it.
1617 hasModuleMap(File->getName(), Root, IsSystemHeaderDir); 1633 hasModuleMap(File.getName(), Root, IsSystemHeaderDir);
1618 return suggestModule(*this, File, RequestingModule, SuggestedModule); 1634 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1619 } 1635 }
1620 return true; 1636 return true;
1621 } 1637 }
1622 1638
1623 bool HeaderSearch::findUsableModuleForFrameworkHeader( 1639 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1624 const FileEntry *File, StringRef FrameworkName, Module *RequestingModule, 1640 FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
1625 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) { 1641 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1626 // If we're supposed to suggest a module, look for one now. 1642 // If we're supposed to suggest a module, look for one now.
1627 if (needModuleLookup(RequestingModule, SuggestedModule)) { 1643 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1628 // Find the top-level framework based on this framework. 1644 // Find the top-level framework based on this framework.
1629 SmallVector<std::string, 4> SubmodulePath; 1645 SmallVector<std::string, 4> SubmodulePath;
1630 Optional<DirectoryEntryRef> TopFrameworkDir = 1646 OptionalDirectoryEntryRef TopFrameworkDir =
1631 ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath); 1647 ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1632 assert(TopFrameworkDir && "Could not find the top-most framework dir"); 1648 assert(TopFrameworkDir && "Could not find the top-most framework dir");
1633 1649
1634 // Determine the name of the top-level framework. 1650 // Determine the name of the top-level framework.
1635 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 1651 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1645 return suggestModule(*this, File, RequestingModule, SuggestedModule); 1661 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1646 } 1662 }
1647 return true; 1663 return true;
1648 } 1664 }
1649 1665
1650 static const FileEntry *getPrivateModuleMap(const FileEntry *File, 1666 static const FileEntry *getPrivateModuleMap(FileEntryRef File,
1651 FileManager &FileMgr) { 1667 FileManager &FileMgr) {
1652 StringRef Filename = llvm::sys::path::filename(File->getName()); 1668 StringRef Filename = llvm::sys::path::filename(File.getName());
1653 SmallString<128> PrivateFilename(File->getDir()->getName()); 1669 SmallString<128> PrivateFilename(File.getDir().getName());
1654 if (Filename == "module.map") 1670 if (Filename == "module.map")
1655 llvm::sys::path::append(PrivateFilename, "module_private.map"); 1671 llvm::sys::path::append(PrivateFilename, "module_private.map");
1656 else if (Filename == "module.modulemap") 1672 else if (Filename == "module.modulemap")
1657 llvm::sys::path::append(PrivateFilename, "module.private.modulemap"); 1673 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1658 else 1674 else
1660 if (auto File = FileMgr.getFile(PrivateFilename)) 1676 if (auto File = FileMgr.getFile(PrivateFilename))
1661 return *File; 1677 return *File;
1662 return nullptr; 1678 return nullptr;
1663 } 1679 }
1664 1680
1665 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem, 1681 bool HeaderSearch::loadModuleMapFile(FileEntryRef File, bool IsSystem,
1666 FileID ID, unsigned *Offset, 1682 FileID ID, unsigned *Offset,
1667 StringRef OriginalModuleMapFile) { 1683 StringRef OriginalModuleMapFile) {
1668 // Find the directory for the module. For frameworks, that may require going 1684 // Find the directory for the module. For frameworks, that may require going
1669 // up from the 'Modules' directory. 1685 // up from the 'Modules' directory.
1670 Optional<DirectoryEntryRef> Dir; 1686 OptionalDirectoryEntryRef Dir;
1671 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) { 1687 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
1672 Dir = FileMgr.getOptionalDirectoryRef("."); 1688 Dir = FileMgr.getOptionalDirectoryRef(".");
1673 } else { 1689 } else {
1674 if (!OriginalModuleMapFile.empty()) { 1690 if (!OriginalModuleMapFile.empty()) {
1675 // We're building a preprocessed module map. Find or invent the directory 1691 // We're building a preprocessed module map. Find or invent the directory
1679 if (!Dir) { 1695 if (!Dir) {
1680 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0); 1696 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1681 Dir = FakeFile.getDir(); 1697 Dir = FakeFile.getDir();
1682 } 1698 }
1683 } else { 1699 } else {
1684 // TODO: Replace with `Dir = File.getDir()` when `File` is switched to 1700 Dir = File.getDir();
1685 // `FileEntryRef`.
1686 Dir = FileMgr.getOptionalDirectoryRef(File->getDir()->getName());
1687 } 1701 }
1688 1702
1689 assert(Dir && "parent must exist"); 1703 assert(Dir && "parent must exist");
1690 StringRef DirName(Dir->getName()); 1704 StringRef DirName(Dir->getName());
1691 if (llvm::sys::path::filename(DirName) == "Modules") { 1705 if (llvm::sys::path::filename(DirName) == "Modules") {
1710 } 1724 }
1711 llvm_unreachable("Unknown load module map result"); 1725 llvm_unreachable("Unknown load module map result");
1712 } 1726 }
1713 1727
1714 HeaderSearch::LoadModuleMapResult 1728 HeaderSearch::LoadModuleMapResult
1715 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, 1729 HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
1716 DirectoryEntryRef Dir, FileID ID, 1730 DirectoryEntryRef Dir, FileID ID,
1717 unsigned *Offset) { 1731 unsigned *Offset) {
1718 assert(File && "expected FileEntry");
1719
1720 // Check whether we've already loaded this module map, and mark it as being 1732 // Check whether we've already loaded this module map, and mark it as being
1721 // loaded in case we recursively try to load it from itself. 1733 // loaded in case we recursively try to load it from itself.
1722 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true)); 1734 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1723 if (!AddResult.second) 1735 if (!AddResult.second)
1724 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1736 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1738 1750
1739 // This directory has a module map. 1751 // This directory has a module map.
1740 return LMM_NewlyLoaded; 1752 return LMM_NewlyLoaded;
1741 } 1753 }
1742 1754
1743 const FileEntry * 1755 OptionalFileEntryRef
1744 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { 1756 HeaderSearch::lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework) {
1745 if (!HSOpts->ImplicitModuleMaps) 1757 if (!HSOpts->ImplicitModuleMaps)
1746 return nullptr; 1758 return std::nullopt;
1747 // For frameworks, the preferred spelling is Modules/module.modulemap, but 1759 // For frameworks, the preferred spelling is Modules/module.modulemap, but
1748 // module.map at the framework root is also accepted. 1760 // module.map at the framework root is also accepted.
1749 SmallString<128> ModuleMapFileName(Dir->getName()); 1761 SmallString<128> ModuleMapFileName(Dir.getName());
1750 if (IsFramework) 1762 if (IsFramework)
1751 llvm::sys::path::append(ModuleMapFileName, "Modules"); 1763 llvm::sys::path::append(ModuleMapFileName, "Modules");
1752 llvm::sys::path::append(ModuleMapFileName, "module.modulemap"); 1764 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1753 if (auto F = FileMgr.getFile(ModuleMapFileName)) 1765 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1754 return *F; 1766 return *F;
1755 1767
1756 // Continue to allow module.map 1768 // Continue to allow module.map
1757 ModuleMapFileName = Dir->getName(); 1769 ModuleMapFileName = Dir.getName();
1758 llvm::sys::path::append(ModuleMapFileName, "module.map"); 1770 llvm::sys::path::append(ModuleMapFileName, "module.map");
1759 if (auto F = FileMgr.getFile(ModuleMapFileName)) 1771 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1760 return *F; 1772 return *F;
1761 1773
1762 // For frameworks, allow to have a private module map with a preferred 1774 // For frameworks, allow to have a private module map with a preferred
1763 // spelling when a public module map is absent. 1775 // spelling when a public module map is absent.
1764 if (IsFramework) { 1776 if (IsFramework) {
1765 ModuleMapFileName = Dir->getName(); 1777 ModuleMapFileName = Dir.getName();
1766 llvm::sys::path::append(ModuleMapFileName, "Modules", 1778 llvm::sys::path::append(ModuleMapFileName, "Modules",
1767 "module.private.modulemap"); 1779 "module.private.modulemap");
1768 if (auto F = FileMgr.getFile(ModuleMapFileName)) 1780 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1769 return *F; 1781 return *F;
1770 } 1782 }
1771 return nullptr; 1783 return std::nullopt;
1772 } 1784 }
1773 1785
1774 Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir, 1786 Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
1775 bool IsSystem) { 1787 bool IsSystem) {
1776 if (Module *Module = ModMap.findModule(Name))
1777 return Module;
1778
1779 // Try to load a module map file. 1788 // Try to load a module map file.
1780 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { 1789 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
1781 case LMM_InvalidModuleMap: 1790 case LMM_InvalidModuleMap:
1782 // Try to infer a module map from the framework directory. 1791 // Try to infer a module map from the framework directory.
1783 if (HSOpts->ImplicitModuleMaps) 1792 if (HSOpts->ImplicitModuleMaps)
1784 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr); 1793 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1785 break; 1794 break;
1786 1795
1787 case LMM_AlreadyLoaded:
1788 case LMM_NoDirectory: 1796 case LMM_NoDirectory:
1789 return nullptr; 1797 return nullptr;
1790 1798
1799 case LMM_AlreadyLoaded:
1791 case LMM_NewlyLoaded: 1800 case LMM_NewlyLoaded:
1792 break; 1801 break;
1793 } 1802 }
1794 1803
1795 return ModMap.findModule(Name); 1804 return ModMap.findModule(Name);
1809 bool IsFramework) { 1818 bool IsFramework) {
1810 auto KnownDir = DirectoryHasModuleMap.find(Dir); 1819 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1811 if (KnownDir != DirectoryHasModuleMap.end()) 1820 if (KnownDir != DirectoryHasModuleMap.end())
1812 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1821 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1813 1822
1814 if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) { 1823 if (OptionalFileEntryRef ModuleMapFile =
1824 lookupModuleMapFile(Dir, IsFramework)) {
1815 LoadModuleMapResult Result = 1825 LoadModuleMapResult Result =
1816 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir); 1826 loadModuleMapFileImpl(*ModuleMapFile, IsSystem, Dir);
1817 // Add Dir explicitly in case ModuleMapFile is in a subdirectory. 1827 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1818 // E.g. Foo.framework/Modules/module.modulemap 1828 // E.g. Foo.framework/Modules/module.modulemap
1819 // ^Dir ^ModuleMapFile 1829 // ^Dir ^ModuleMapFile
1820 if (Result == LMM_NewlyLoaded) 1830 if (Result == LMM_NewlyLoaded)
1821 DirectoryHasModuleMap[Dir] = true; 1831 DirectoryHasModuleMap[Dir] = true;
1834 for (DirectoryLookup &DL : search_dir_range()) { 1844 for (DirectoryLookup &DL : search_dir_range()) {
1835 bool IsSystem = DL.isSystemHeaderDirectory(); 1845 bool IsSystem = DL.isSystemHeaderDirectory();
1836 if (DL.isFramework()) { 1846 if (DL.isFramework()) {
1837 std::error_code EC; 1847 std::error_code EC;
1838 SmallString<128> DirNative; 1848 SmallString<128> DirNative;
1839 llvm::sys::path::native(DL.getFrameworkDir()->getName(), DirNative); 1849 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
1840 1850
1841 // Search each of the ".framework" directories to load them as modules. 1851 // Search each of the ".framework" directories to load them as modules.
1842 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); 1852 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1843 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), 1853 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1844 DirEnd; 1854 DirEnd;
1897 1907
1898 if (SearchDir.haveSearchedAllModuleMaps()) 1908 if (SearchDir.haveSearchedAllModuleMaps())
1899 return; 1909 return;
1900 1910
1901 std::error_code EC; 1911 std::error_code EC;
1902 SmallString<128> Dir = SearchDir.getDir()->getName(); 1912 SmallString<128> Dir = SearchDir.getDirRef()->getName();
1903 FileMgr.makeAbsolutePath(Dir); 1913 FileMgr.makeAbsolutePath(Dir);
1904 SmallString<128> DirNative; 1914 SmallString<128> DirNative;
1905 llvm::sys::path::native(Dir, DirNative); 1915 llvm::sys::path::native(Dir, DirNative);
1906 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); 1916 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1907 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; 1917 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1908 Dir != DirEnd && !EC; Dir.increment(EC)) { 1918 Dir != DirEnd && !EC; Dir.increment(EC)) {
1919 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
1920 continue;
1909 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework"; 1921 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
1910 if (IsFramework == SearchDir.isFramework()) 1922 if (IsFramework == SearchDir.isFramework())
1911 loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), 1923 loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
1912 SearchDir.isFramework()); 1924 SearchDir.isFramework());
1913 } 1925 }
1914 1926
1915 SearchDir.setSearchedAllModuleMaps(true); 1927 SearchDir.setSearchedAllModuleMaps(true);
1916 } 1928 }
1917 1929
1918 std::string HeaderSearch::suggestPathToFileForDiagnostics( 1930 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1919 const FileEntry *File, llvm::StringRef MainFile, bool *IsSystem) { 1931 const FileEntry *File, llvm::StringRef MainFile, bool *IsAngled) const {
1920 // FIXME: We assume that the path name currently cached in the FileEntry is 1932 // FIXME: We assume that the path name currently cached in the FileEntry is
1921 // the most appropriate one for this analysis (and that it's spelled the 1933 // the most appropriate one for this analysis (and that it's spelled the
1922 // same way as the corresponding header search path). 1934 // same way as the corresponding header search path).
1923 return suggestPathToFileForDiagnostics(File->getName(), /*WorkingDir=*/"", 1935 return suggestPathToFileForDiagnostics(File->getName(), /*WorkingDir=*/"",
1924 MainFile, IsSystem); 1936 MainFile, IsAngled);
1925 } 1937 }
1926 1938
1927 std::string HeaderSearch::suggestPathToFileForDiagnostics( 1939 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1928 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile, 1940 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1929 bool *IsSystem) { 1941 bool *IsAngled) const {
1930 using namespace llvm::sys; 1942 using namespace llvm::sys;
1943
1944 llvm::SmallString<32> FilePath = File;
1945 // remove_dots switches to backslashes on windows as a side-effect!
1946 // We always want to suggest forward slashes for includes.
1947 // (not remove_dots(..., posix) as that misparses windows paths).
1948 path::remove_dots(FilePath, /*remove_dot_dot=*/true);
1949 path::native(FilePath, path::Style::posix);
1950 File = FilePath;
1931 1951
1932 unsigned BestPrefixLength = 0; 1952 unsigned BestPrefixLength = 0;
1933 // Checks whether `Dir` is a strict path prefix of `File`. If so and that's 1953 // Checks whether `Dir` is a strict path prefix of `File`. If so and that's
1934 // the longest prefix we've seen so for it, returns true and updates the 1954 // the longest prefix we've seen so for it, returns true and updates the
1935 // `BestPrefixLength` accordingly. 1955 // `BestPrefixLength` accordingly.
1936 auto CheckDir = [&](llvm::StringRef Dir) -> bool { 1956 auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
1937 llvm::SmallString<32> DirPath(Dir.begin(), Dir.end());
1938 if (!WorkingDir.empty() && !path::is_absolute(Dir)) 1957 if (!WorkingDir.empty() && !path::is_absolute(Dir))
1939 fs::make_absolute(WorkingDir, DirPath); 1958 fs::make_absolute(WorkingDir, Dir);
1940 path::remove_dots(DirPath, /*remove_dot_dot=*/true); 1959 path::remove_dots(Dir, /*remove_dot_dot=*/true);
1941 Dir = DirPath;
1942 for (auto NI = path::begin(File), NE = path::end(File), 1960 for (auto NI = path::begin(File), NE = path::end(File),
1943 DI = path::begin(Dir), DE = path::end(Dir); 1961 DI = path::begin(Dir), DE = path::end(Dir);
1944 /*termination condition in loop*/; ++NI, ++DI) { 1962 NI != NE; ++NI, ++DI) {
1945 // '.' components in File are ignored.
1946 while (NI != NE && *NI == ".")
1947 ++NI;
1948 if (NI == NE)
1949 break;
1950
1951 // '.' components in Dir are ignored.
1952 while (DI != DE && *DI == ".")
1953 ++DI;
1954 if (DI == DE) { 1963 if (DI == DE) {
1955 // Dir is a prefix of File, up to '.' components and choice of path 1964 // Dir is a prefix of File, up to choice of path separators.
1956 // separators.
1957 unsigned PrefixLength = NI - path::begin(File); 1965 unsigned PrefixLength = NI - path::begin(File);
1958 if (PrefixLength > BestPrefixLength) { 1966 if (PrefixLength > BestPrefixLength) {
1959 BestPrefixLength = PrefixLength; 1967 BestPrefixLength = PrefixLength;
1960 return true; 1968 return true;
1961 } 1969 }
1984 }; 1992 };
1985 1993
1986 bool BestPrefixIsFramework = false; 1994 bool BestPrefixIsFramework = false;
1987 for (const DirectoryLookup &DL : search_dir_range()) { 1995 for (const DirectoryLookup &DL : search_dir_range()) {
1988 if (DL.isNormalDir()) { 1996 if (DL.isNormalDir()) {
1989 StringRef Dir = DL.getDir()->getName(); 1997 StringRef Dir = DL.getDirRef()->getName();
1990 if (CheckDir(Dir)) { 1998 if (CheckDir(Dir)) {
1991 if (IsSystem) 1999 if (IsAngled)
1992 *IsSystem = BestPrefixLength && isSystem(DL.getDirCharacteristic()); 2000 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
1993 BestPrefixIsFramework = false; 2001 BestPrefixIsFramework = false;
1994 } 2002 }
1995 } else if (DL.isFramework()) { 2003 } else if (DL.isFramework()) {
1996 StringRef Dir = DL.getFrameworkDir()->getName(); 2004 StringRef Dir = DL.getFrameworkDirRef()->getName();
1997 if (CheckDir(Dir)) { 2005 if (CheckDir(Dir)) {
1998 if (IsSystem) 2006 // Framework includes by convention use <>.
1999 *IsSystem = BestPrefixLength && isSystem(DL.getDirCharacteristic()); 2007 if (IsAngled)
2008 *IsAngled = BestPrefixLength;
2000 BestPrefixIsFramework = true; 2009 BestPrefixIsFramework = true;
2001 } 2010 }
2002 } 2011 }
2003 } 2012 }
2004 2013
2005 // Try to shorten include path using TUs directory, if we couldn't find any 2014 // Try to shorten include path using TUs directory, if we couldn't find any
2006 // suitable prefix in include search paths. 2015 // suitable prefix in include search paths.
2007 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) { 2016 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2008 if (IsSystem) 2017 if (IsAngled)
2009 *IsSystem = false; 2018 *IsAngled = false;
2010 BestPrefixIsFramework = false; 2019 BestPrefixIsFramework = false;
2011 } 2020 }
2012 2021
2013 // Try resolving resulting filename via reverse search in header maps, 2022 // Try resolving resulting filename via reverse search in header maps,
2014 // key from header name is user preferred name for the include file. 2023 // key from header name is user preferred name for the include file.