1 //===- HeaderSearch.cpp - Resolve Header File Locations -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file implements the DirectoryLookup and HeaderSearch interfaces.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/Lex/HeaderSearch.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/IdentifierTable.h"
17 #include "clang/Basic/Module.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "clang/Lex/DirectoryLookup.h"
20 #include "clang/Lex/ExternalPreprocessorSource.h"
21 #include "clang/Lex/HeaderMap.h"
22 #include "clang/Lex/HeaderSearchOptions.h"
23 #include "clang/Lex/LexDiagnostic.h"
24 #include "clang/Lex/ModuleMap.h"
25 #include "clang/Lex/Preprocessor.h"
26 #include "llvm/ADT/APInt.h"
27 #include "llvm/ADT/Hashing.h"
28 #include "llvm/ADT/SmallString.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/Support/Allocator.h"
32 #include "llvm/Support/Capacity.h"
33 #include "llvm/Support/Errc.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/FileSystem.h"
36 #include "llvm/Support/Path.h"
37 #include "llvm/Support/VirtualFileSystem.h"
38 #include <algorithm>
39 #include <cassert>
40 #include <cstddef>
41 #include <cstdio>
42 #include <cstring>
43 #include <string>
44 #include <system_error>
45 #include <utility>
46 
47 using namespace clang;
48 
49 const IdentifierInfo *
50 HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
51   if (ControllingMacro) {
52     if (ControllingMacro->isOutOfDate()) {
53       assert(External && "We must have an external source if we have a "
54                          "controlling macro that is out of date.");
55       External->updateOutOfDateIdentifier(
56           *const_cast<IdentifierInfo *>(ControllingMacro));
57     }
58     return ControllingMacro;
59   }
60 
61   if (!ControllingMacroID || !External)
62     return nullptr;
63 
64   ControllingMacro = External->GetIdentifier(ControllingMacroID);
65   return ControllingMacro;
66 }
67 
68 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() = default;
69 
70 HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
71                            SourceManager &SourceMgr, DiagnosticsEngine &Diags,
72                            const LangOptions &LangOpts,
73                            const TargetInfo *Target)
74     : HSOpts(std::move(HSOpts)), Diags(Diags),
75       FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
76       ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
77 
78 void HeaderSearch::PrintStats() {
79   fprintf(stderr, "\n*** HeaderSearch Stats:\n");
80   fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
81   unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
82   for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
83     NumOnceOnlyFiles += FileInfo[i].isImport;
84     if (MaxNumIncludes < FileInfo[i].NumIncludes)
85       MaxNumIncludes = FileInfo[i].NumIncludes;
86     NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
87   }
88   fprintf(stderr, "  %d #import/#pragma once files.\n", NumOnceOnlyFiles);
89   fprintf(stderr, "  %d included exactly once.\n", NumSingleIncludedFiles);
90   fprintf(stderr, "  %d max times a file is included.\n", MaxNumIncludes);
91 
92   fprintf(stderr, "  %d #include/#include_next/#import.\n", NumIncluded);
93   fprintf(stderr, "    %d #includes skipped due to"
94           " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
95 
96   fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
97   fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
98 }
99 
100 /// CreateHeaderMap - This method returns a HeaderMap for the specified
101 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
102 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
103   // We expect the number of headermaps to be small, and almost always empty.
104   // If it ever grows, use of a linear search should be re-evaluated.
105   if (!HeaderMaps.empty()) {
106     for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
107       // Pointer equality comparison of FileEntries works because they are
108       // already uniqued by inode.
109       if (HeaderMaps[i].first == FE)
110         return HeaderMaps[i].second.get();
111   }
112 
113   if (std::unique_ptr<HeaderMap> HM = HeaderMap::Create(FE, FileMgr)) {
114     HeaderMaps.emplace_back(FE, std::move(HM));
115     return HeaderMaps.back().second.get();
116   }
117 
118   return nullptr;
119 }
120 
121 /// Get filenames for all registered header maps.
122 void HeaderSearch::getHeaderMapFileNames(
123     SmallVectorImpl<std::string> &Names) const {
124   for (auto &HM : HeaderMaps)
125     Names.push_back(HM.first->getName());
126 }
127 
128 std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
129   const FileEntry *ModuleMap =
130       getModuleMap().getModuleMapFileForUniquing(Module);
131   return getCachedModuleFileName(Module->Name, ModuleMap->getName());
132 }
133 
134 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
135                                                     bool FileMapOnly) {
136   // First check the module name to pcm file map.
137   auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
138   if (i != HSOpts->PrebuiltModuleFiles.end())
139     return i->second;
140 
141   if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
142     return {};
143 
144   // Then go through each prebuilt module directory and try to find the pcm
145   // file.
146   for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
147     SmallString<256> Result(Dir);
148     llvm::sys::fs::make_absolute(Result);
149     llvm::sys::path::append(Result, ModuleName + ".pcm");
150     if (getFileMgr().getFile(Result.str()))
151       return Result.str().str();
152   }
153   return {};
154 }
155 
156 std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
157                                                   StringRef ModuleMapPath) {
158   // If we don't have a module cache path or aren't supposed to use one, we
159   // can't do anything.
160   if (getModuleCachePath().empty())
161     return {};
162 
163   SmallString<256> Result(getModuleCachePath());
164   llvm::sys::fs::make_absolute(Result);
165 
166   if (HSOpts->DisableModuleHash) {
167     llvm::sys::path::append(Result, ModuleName + ".pcm");
168   } else {
169     // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
170     // ideally be globally unique to this particular module. Name collisions
171     // in the hash are safe (because any translation unit can only import one
172     // module with each name), but result in a loss of caching.
173     //
174     // To avoid false-negatives, we form as canonical a path as we can, and map
175     // to lower-case in case we're on a case-insensitive file system.
176     std::string Parent = llvm::sys::path::parent_path(ModuleMapPath);
177     if (Parent.empty())
178       Parent = ".";
179     auto Dir = FileMgr.getDirectory(Parent);
180     if (!Dir)
181       return {};
182     auto DirName = FileMgr.getCanonicalName(*Dir);
183     auto FileName = llvm::sys::path::filename(ModuleMapPath);
184 
185     llvm::hash_code Hash =
186       llvm::hash_combine(DirName.lower(), FileName.lower());
187 
188     SmallString<128> HashStr;
189     llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36);
190     llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
191   }
192   return Result.str().str();
193 }
194 
195 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch,
196                                    bool AllowExtraModuleMapSearch) {
197   // Look in the module map to determine if there is a module by this name.
198   Module *Module = ModMap.findModule(ModuleName);
199   if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
200     return Module;
201 
202   StringRef SearchName = ModuleName;
203   Module = lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
204 
205   // The facility for "private modules" -- adjacent, optional module maps named
206   // module.private.modulemap that are supposed to define private submodules --
207   // may have different flavors of names: FooPrivate, Foo_Private and Foo.Private.
208   //
209   // Foo.Private is now deprecated in favor of Foo_Private. Users of FooPrivate
210   // should also rename to Foo_Private. Representing private as submodules
211   // could force building unwanted dependencies into the parent module and cause
212   // dependency cycles.
213   if (!Module && SearchName.consume_back("_Private"))
214     Module = lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
215   if (!Module && SearchName.consume_back("Private"))
216     Module = lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
217   return Module;
218 }
219 
220 Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
221                                    bool AllowExtraModuleMapSearch) {
222   Module *Module = nullptr;
223 
224   // Look through the various header search paths to load any available module
225   // maps, searching for a module map that describes this module.
226   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
227     if (SearchDirs[Idx].isFramework()) {
228       // Search for or infer a module map for a framework. Here we use
229       // SearchName rather than ModuleName, to permit finding private modules
230       // named FooPrivate in buggy frameworks named Foo.
231       SmallString<128> FrameworkDirName;
232       FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
233       llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
234       if (auto FrameworkDir = FileMgr.getDirectory(FrameworkDirName)) {
235         bool IsSystem
236           = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
237         Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
238         if (Module)
239           break;
240       }
241     }
242 
243     // FIXME: Figure out how header maps and module maps will work together.
244 
245     // Only deal with normal search directories.
246     if (!SearchDirs[Idx].isNormalDir())
247       continue;
248 
249     bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
250     // Search for a module map file in this directory.
251     if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
252                           /*IsFramework*/false) == LMM_NewlyLoaded) {
253       // We just loaded a module map file; check whether the module is
254       // available now.
255       Module = ModMap.findModule(ModuleName);
256       if (Module)
257         break;
258     }
259 
260     // Search for a module map in a subdirectory with the same name as the
261     // module.
262     SmallString<128> NestedModuleMapDirName;
263     NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
264     llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
265     if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
266                           /*IsFramework*/false) == LMM_NewlyLoaded){
267       // If we just loaded a module map file, look for the module again.
268       Module = ModMap.findModule(ModuleName);
269       if (Module)
270         break;
271     }
272 
273     // If we've already performed the exhaustive search for module maps in this
274     // search directory, don't do it again.
275     if (SearchDirs[Idx].haveSearchedAllModuleMaps())
276       continue;
277 
278     // Load all module maps in the immediate subdirectories of this search
279     // directory if ModuleName was from @import.
280     if (AllowExtraModuleMapSearch)
281       loadSubdirectoryModuleMaps(SearchDirs[Idx]);
282 
283     // Look again for the module.
284     Module = ModMap.findModule(ModuleName);
285     if (Module)
286       break;
287   }
288 
289   return Module;
290 }
291 
292 //===----------------------------------------------------------------------===//
293 // File lookup within a DirectoryLookup scope
294 //===----------------------------------------------------------------------===//
295 
296 /// getName - Return the directory or filename corresponding to this lookup
297 /// object.
298 StringRef DirectoryLookup::getName() const {
299   if (isNormalDir())
300     return getDir()->getName();
301   if (isFramework())
302     return getFrameworkDir()->getName();
303   assert(isHeaderMap() && "Unknown DirectoryLookup");
304   return getHeaderMap()->getFileName();
305 }
306 
307 const FileEntry *HeaderSearch::getFileAndSuggestModule(
308     StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
309     bool IsSystemHeaderDir, Module *RequestingModule,
310     ModuleMap::KnownHeader *SuggestedModule) {
311   // If we have a module map that might map this header, load it and
312   // check whether we'll have a suggestion for a module.
313   llvm::ErrorOr<const FileEntry *> File =
314       getFileMgr().getFile(FileName, /*OpenFile=*/true);
315   if (!File) {
316     // For rare, surprising errors (e.g. "out of file handles"), diag the EC
317     // message.
318     std::error_code EC = File.getError();
319     if (EC != llvm::errc::no_such_file_or_directory &&
320         EC != llvm::errc::invalid_argument &&
321         EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
322       Diags.Report(IncludeLoc, diag::err_cannot_open_file)
323           << FileName << EC.message();
324     }
325     return nullptr;
326   }
327 
328   // If there is a module that corresponds to this header, suggest it.
329   if (!findUsableModuleForHeader(*File, Dir ? Dir : (*File)->getDir(),
330                                  RequestingModule, SuggestedModule,
331                                  IsSystemHeaderDir))
332     return nullptr;
333 
334   return *File;
335 }
336 
337 /// LookupFile - Lookup the specified file in this search path, returning it
338 /// if it exists or returning null if not.
339 const FileEntry *DirectoryLookup::LookupFile(
340     StringRef &Filename,
341     HeaderSearch &HS,
342     SourceLocation IncludeLoc,
343     SmallVectorImpl<char> *SearchPath,
344     SmallVectorImpl<char> *RelativePath,
345     Module *RequestingModule,
346     ModuleMap::KnownHeader *SuggestedModule,
347     bool &InUserSpecifiedSystemFramework,
348     bool &IsFrameworkFound,
349     bool &HasBeenMapped,
350     SmallVectorImpl<char> &MappedName) const {
351   InUserSpecifiedSystemFramework = false;
352   HasBeenMapped = false;
353 
354   SmallString<1024> TmpDir;
355   if (isNormalDir()) {
356     // Concatenate the requested file onto the directory.
357     TmpDir = getDir()->getName();
358     llvm::sys::path::append(TmpDir, Filename);
359     if (SearchPath) {
360       StringRef SearchPathRef(getDir()->getName());
361       SearchPath->clear();
362       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
363     }
364     if (RelativePath) {
365       RelativePath->clear();
366       RelativePath->append(Filename.begin(), Filename.end());
367     }
368 
369     return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
370                                       isSystemHeaderDirectory(),
371                                       RequestingModule, SuggestedModule);
372   }
373 
374   if (isFramework())
375     return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
376                              RequestingModule, SuggestedModule,
377                              InUserSpecifiedSystemFramework, IsFrameworkFound);
378 
379   assert(isHeaderMap() && "Unknown directory lookup");
380   const HeaderMap *HM = getHeaderMap();
381   SmallString<1024> Path;
382   StringRef Dest = HM->lookupFilename(Filename, Path);
383   if (Dest.empty())
384     return nullptr;
385 
386   const FileEntry *Result;
387 
388   // Check if the headermap maps the filename to a framework include
389   // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
390   // framework include.
391   if (llvm::sys::path::is_relative(Dest)) {
392     MappedName.clear();
393     MappedName.append(Dest.begin(), Dest.end());
394     Filename = StringRef(MappedName.begin(), MappedName.size());
395     HasBeenMapped = true;
396     Result = HM->LookupFile(Filename, HS.getFileMgr());
397   } else if (auto Res = HS.getFileMgr().getFile(Dest)) {
398     Result = *Res;
399   } else {
400     Result = nullptr;
401   }
402 
403   if (Result) {
404     if (SearchPath) {
405       StringRef SearchPathRef(getName());
406       SearchPath->clear();
407       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
408     }
409     if (RelativePath) {
410       RelativePath->clear();
411       RelativePath->append(Filename.begin(), Filename.end());
412     }
413   }
414   return Result;
415 }
416 
417 /// Given a framework directory, find the top-most framework directory.
418 ///
419 /// \param FileMgr The file manager to use for directory lookups.
420 /// \param DirName The name of the framework directory.
421 /// \param SubmodulePath Will be populated with the submodule path from the
422 /// returned top-level module to the originally named framework.
423 static const DirectoryEntry *
424 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
425                    SmallVectorImpl<std::string> &SubmodulePath) {
426   assert(llvm::sys::path::extension(DirName) == ".framework" &&
427          "Not a framework directory");
428 
429   // Note: as an egregious but useful hack we use the real path here, because
430   // frameworks moving between top-level frameworks to embedded frameworks tend
431   // to be symlinked, and we base the logical structure of modules on the
432   // physical layout. In particular, we need to deal with crazy includes like
433   //
434   //   #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
435   //
436   // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
437   // which one should access with, e.g.,
438   //
439   //   #include <Bar/Wibble.h>
440   //
441   // Similar issues occur when a top-level framework has moved into an
442   // embedded framework.
443   const DirectoryEntry *TopFrameworkDir = nullptr;
444   if (auto TopFrameworkDirOrErr = FileMgr.getDirectory(DirName))
445     TopFrameworkDir = *TopFrameworkDirOrErr;
446 
447   if (TopFrameworkDir)
448     DirName = FileMgr.getCanonicalName(TopFrameworkDir);
449   do {
450     // Get the parent directory name.
451     DirName = llvm::sys::path::parent_path(DirName);
452     if (DirName.empty())
453       break;
454 
455     // Determine whether this directory exists.
456     auto Dir = FileMgr.getDirectory(DirName);
457     if (!Dir)
458       break;
459 
460     // If this is a framework directory, then we're a subframework of this
461     // framework.
462     if (llvm::sys::path::extension(DirName) == ".framework") {
463       SubmodulePath.push_back(llvm::sys::path::stem(DirName));
464       TopFrameworkDir = *Dir;
465     }
466   } while (true);
467 
468   return TopFrameworkDir;
469 }
470 
471 static bool needModuleLookup(Module *RequestingModule,
472                              bool HasSuggestedModule) {
473   return HasSuggestedModule ||
474          (RequestingModule && RequestingModule->NoUndeclaredIncludes);
475 }
476 
477 /// DoFrameworkLookup - Do a lookup of the specified file in the current
478 /// DirectoryLookup, which is a framework directory.
479 const FileEntry *DirectoryLookup::DoFrameworkLookup(
480     StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
481     SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
482     ModuleMap::KnownHeader *SuggestedModule,
483     bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
484   FileManager &FileMgr = HS.getFileMgr();
485 
486   // Framework names must have a '/' in the filename.
487   size_t SlashPos = Filename.find('/');
488   if (SlashPos == StringRef::npos) return nullptr;
489 
490   // Find out if this is the home for the specified framework, by checking
491   // HeaderSearch.  Possible answers are yes/no and unknown.
492   FrameworkCacheEntry &CacheEntry =
493     HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
494 
495   // If it is known and in some other directory, fail.
496   if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
497     return nullptr;
498 
499   // Otherwise, construct the path to this framework dir.
500 
501   // FrameworkName = "/System/Library/Frameworks/"
502   SmallString<1024> FrameworkName;
503   FrameworkName += getFrameworkDir()->getName();
504   if (FrameworkName.empty() || FrameworkName.back() != '/')
505     FrameworkName.push_back('/');
506 
507   // FrameworkName = "/System/Library/Frameworks/Cocoa"
508   StringRef ModuleName(Filename.begin(), SlashPos);
509   FrameworkName += ModuleName;
510 
511   // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
512   FrameworkName += ".framework/";
513 
514   // If the cache entry was unresolved, populate it now.
515   if (!CacheEntry.Directory) {
516     HS.IncrementFrameworkLookupCount();
517 
518     // If the framework dir doesn't exist, we fail.
519     auto Dir = FileMgr.getDirectory(FrameworkName);
520     if (!Dir) return nullptr;
521 
522     // Otherwise, if it does, remember that this is the right direntry for this
523     // framework.
524     CacheEntry.Directory = getFrameworkDir();
525 
526     // If this is a user search directory, check if the framework has been
527     // user-specified as a system framework.
528     if (getDirCharacteristic() == SrcMgr::C_User) {
529       SmallString<1024> SystemFrameworkMarker(FrameworkName);
530       SystemFrameworkMarker += ".system_framework";
531       if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
532         CacheEntry.IsUserSpecifiedSystemFramework = true;
533       }
534     }
535   }
536 
537   // Set out flags.
538   InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
539   IsFrameworkFound = CacheEntry.Directory;
540 
541   if (RelativePath) {
542     RelativePath->clear();
543     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
544   }
545 
546   // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
547   unsigned OrigSize = FrameworkName.size();
548 
549   FrameworkName += "Headers/";
550 
551   if (SearchPath) {
552     SearchPath->clear();
553     // Without trailing '/'.
554     SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
555   }
556 
557   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
558 
559   const FileEntry *FE = nullptr;
560   if (auto File = FileMgr.getFile(FrameworkName, /*OpenFile=*/!SuggestedModule))
561     FE = *File;
562 
563   if (!FE) {
564     // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
565     const char *Private = "Private";
566     FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
567                          Private+strlen(Private));
568     if (SearchPath)
569       SearchPath->insert(SearchPath->begin()+OrigSize, Private,
570                          Private+strlen(Private));
571 
572     if (auto File = FileMgr.getFile(FrameworkName,
573                                     /*OpenFile=*/!SuggestedModule))
574       FE = *File;
575   }
576 
577   // If we found the header and are allowed to suggest a module, do so now.
578   if (FE && needModuleLookup(RequestingModule, SuggestedModule)) {
579     // Find the framework in which this header occurs.
580     StringRef FrameworkPath = FE->getDir()->getName();
581     bool FoundFramework = false;
582     do {
583       // Determine whether this directory exists.
584       auto Dir = FileMgr.getDirectory(FrameworkPath);
585       if (!Dir)
586         break;
587 
588       // If this is a framework directory, then we're a subframework of this
589       // framework.
590       if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
591         FoundFramework = true;
592         break;
593       }
594 
595       // Get the parent directory name.
596       FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
597       if (FrameworkPath.empty())
598         break;
599     } while (true);
600 
601     bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
602     if (FoundFramework) {
603       if (!HS.findUsableModuleForFrameworkHeader(
604               FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
605         return nullptr;
606     } else {
607       if (!HS.findUsableModuleForHeader(FE, getDir(), RequestingModule,
608                                         SuggestedModule, IsSystem))
609         return nullptr;
610     }
611   }
612   return FE;
613 }
614 
615 void HeaderSearch::setTarget(const TargetInfo &Target) {
616   ModMap.setTarget(Target);
617 }
618 
619 //===----------------------------------------------------------------------===//
620 // Header File Location.
621 //===----------------------------------------------------------------------===//
622 
623 /// Return true with a diagnostic if the file that MSVC would have found
624 /// fails to match the one that Clang would have found with MSVC header search
625 /// disabled.
626 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
627                                   const FileEntry *MSFE, const FileEntry *FE,
628                                   SourceLocation IncludeLoc) {
629   if (MSFE && FE != MSFE) {
630     Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
631     return true;
632   }
633   return false;
634 }
635 
636 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
637   assert(!Str.empty());
638   char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
639   std::copy(Str.begin(), Str.end(), CopyStr);
640   CopyStr[Str.size()] = '\0';
641   return CopyStr;
642 }
643 
644 static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader,
645                                  SmallVectorImpl<char> &FrameworkName) {
646   using namespace llvm::sys;
647   path::const_iterator I = path::begin(Path);
648   path::const_iterator E = path::end(Path);
649   IsPrivateHeader = false;
650 
651   // Detect different types of framework style paths:
652   //
653   //   ...Foo.framework/{Headers,PrivateHeaders}
654   //   ...Foo.framework/Versions/{A,Current}/{Headers,PrivateHeaders}
655   //   ...Foo.framework/Frameworks/Nested.framework/{Headers,PrivateHeaders}
656   //   ...<other variations with 'Versions' like in the above path>
657   //
658   // and some other variations among these lines.
659   int FoundComp = 0;
660   while (I != E) {
661     if (*I == "Headers")
662       ++FoundComp;
663     if (I->endswith(".framework")) {
664       FrameworkName.append(I->begin(), I->end());
665       ++FoundComp;
666     }
667     if (*I == "PrivateHeaders") {
668       ++FoundComp;
669       IsPrivateHeader = true;
670     }
671     ++I;
672   }
673 
674   return !FrameworkName.empty() && FoundComp >= 2;
675 }
676 
677 static void
678 diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc,
679                          StringRef Includer, StringRef IncludeFilename,
680                          const FileEntry *IncludeFE, bool isAngled = false,
681                          bool FoundByHeaderMap = false) {
682   bool IsIncluderPrivateHeader = false;
683   SmallString<128> FromFramework, ToFramework;
684   if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework))
685     return;
686   bool IsIncludeePrivateHeader = false;
687   bool IsIncludeeInFramework = isFrameworkStylePath(
688       IncludeFE->getName(), IsIncludeePrivateHeader, ToFramework);
689 
690   if (!isAngled && !FoundByHeaderMap) {
691     SmallString<128> NewInclude("<");
692     if (IsIncludeeInFramework) {
693       NewInclude += StringRef(ToFramework).drop_back(10); // drop .framework
694       NewInclude += "/";
695     }
696     NewInclude += IncludeFilename;
697     NewInclude += ">";
698     Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
699         << IncludeFilename
700         << FixItHint::CreateReplacement(IncludeLoc, NewInclude);
701   }
702 
703   // Headers in Foo.framework/Headers should not include headers
704   // from Foo.framework/PrivateHeaders, since this violates public/private
705   // API boundaries and can cause modular dependency cycles.
706   if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
707       IsIncludeePrivateHeader && FromFramework == ToFramework)
708     Diags.Report(IncludeLoc, diag::warn_framework_include_private_from_public)
709         << IncludeFilename;
710 }
711 
712 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
713 /// return null on failure.  isAngled indicates whether the file reference is
714 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
715 /// non-empty, indicates where the \#including file(s) are, in case a relative
716 /// search is needed. Microsoft mode will pass all \#including files.
717 const FileEntry *HeaderSearch::LookupFile(
718     StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
719     const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
720     ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
721     SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
722     Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
723     bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
724     bool BuildSystemModule) {
725   if (IsMapped)
726     *IsMapped = false;
727 
728   if (IsFrameworkFound)
729     *IsFrameworkFound = false;
730 
731   if (SuggestedModule)
732     *SuggestedModule = ModuleMap::KnownHeader();
733 
734   // If 'Filename' is absolute, check to see if it exists and no searching.
735   if (llvm::sys::path::is_absolute(Filename)) {
736     CurDir = nullptr;
737 
738     // If this was an #include_next "/absolute/file", fail.
739     if (FromDir) return nullptr;
740 
741     if (SearchPath)
742       SearchPath->clear();
743     if (RelativePath) {
744       RelativePath->clear();
745       RelativePath->append(Filename.begin(), Filename.end());
746     }
747     // Otherwise, just return the file.
748     return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
749                                    /*IsSystemHeaderDir*/false,
750                                    RequestingModule, SuggestedModule);
751   }
752 
753   // This is the header that MSVC's header search would have found.
754   const FileEntry *MSFE = nullptr;
755   ModuleMap::KnownHeader MSSuggestedModule;
756 
757   // Unless disabled, check to see if the file is in the #includer's
758   // directory.  This cannot be based on CurDir, because each includer could be
759   // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
760   // include of "baz.h" should resolve to "whatever/foo/baz.h".
761   // This search is not done for <> headers.
762   if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
763     SmallString<1024> TmpDir;
764     bool First = true;
765     for (const auto &IncluderAndDir : Includers) {
766       const FileEntry *Includer = IncluderAndDir.first;
767 
768       // Concatenate the requested file onto the directory.
769       // FIXME: Portability.  Filename concatenation should be in sys::Path.
770       TmpDir = IncluderAndDir.second->getName();
771       TmpDir.push_back('/');
772       TmpDir.append(Filename.begin(), Filename.end());
773 
774       // FIXME: We don't cache the result of getFileInfo across the call to
775       // getFileAndSuggestModule, because it's a reference to an element of
776       // a container that could be reallocated across this call.
777       //
778       // If we have no includer, that means we're processing a #include
779       // from a module build. We should treat this as a system header if we're
780       // building a [system] module.
781       bool IncluderIsSystemHeader =
782           Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User :
783           BuildSystemModule;
784       if (const FileEntry *FE = getFileAndSuggestModule(
785               TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
786               RequestingModule, SuggestedModule)) {
787         if (!Includer) {
788           assert(First && "only first includer can have no file");
789           return FE;
790         }
791 
792         // Leave CurDir unset.
793         // This file is a system header or C++ unfriendly if the old file is.
794         //
795         // Note that we only use one of FromHFI/ToHFI at once, due to potential
796         // reallocation of the underlying vector potentially making the first
797         // reference binding dangling.
798         HeaderFileInfo &FromHFI = getFileInfo(Includer);
799         unsigned DirInfo = FromHFI.DirInfo;
800         bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
801         StringRef Framework = FromHFI.Framework;
802 
803         HeaderFileInfo &ToHFI = getFileInfo(FE);
804         ToHFI.DirInfo = DirInfo;
805         ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
806         ToHFI.Framework = Framework;
807 
808         if (SearchPath) {
809           StringRef SearchPathRef(IncluderAndDir.second->getName());
810           SearchPath->clear();
811           SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
812         }
813         if (RelativePath) {
814           RelativePath->clear();
815           RelativePath->append(Filename.begin(), Filename.end());
816         }
817         if (First) {
818           diagnoseFrameworkInclude(Diags, IncludeLoc,
819                                    IncluderAndDir.second->getName(), Filename,
820                                    FE);
821           return FE;
822         }
823 
824         // Otherwise, we found the path via MSVC header search rules.  If
825         // -Wmsvc-include is enabled, we have to keep searching to see if we
826         // would've found this header in -I or -isystem directories.
827         if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
828           return FE;
829         } else {
830           MSFE = FE;
831           if (SuggestedModule) {
832             MSSuggestedModule = *SuggestedModule;
833             *SuggestedModule = ModuleMap::KnownHeader();
834           }
835           break;
836         }
837       }
838       First = false;
839     }
840   }
841 
842   CurDir = nullptr;
843 
844   // If this is a system #include, ignore the user #include locs.
845   unsigned i = isAngled ? AngledDirIdx : 0;
846 
847   // If this is a #include_next request, start searching after the directory the
848   // file was found in.
849   if (FromDir)
850     i = FromDir-&SearchDirs[0];
851 
852   // Cache all of the lookups performed by this method.  Many headers are
853   // multiply included, and the "pragma once" optimization prevents them from
854   // being relex/pp'd, but they would still have to search through a
855   // (potentially huge) series of SearchDirs to find it.
856   LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
857 
858   // If the entry has been previously looked up, the first value will be
859   // non-zero.  If the value is equal to i (the start point of our search), then
860   // this is a matching hit.
861   if (!SkipCache && CacheLookup.StartIdx == i+1) {
862     // Skip querying potentially lots of directories for this lookup.
863     i = CacheLookup.HitIdx;
864     if (CacheLookup.MappedName) {
865       Filename = CacheLookup.MappedName;
866       if (IsMapped)
867         *IsMapped = true;
868     }
869   } else {
870     // Otherwise, this is the first query, or the previous query didn't match
871     // our search start.  We will fill in our found location below, so prime the
872     // start point value.
873     CacheLookup.reset(/*StartIdx=*/i+1);
874   }
875 
876   SmallString<64> MappedName;
877 
878   // Check each directory in sequence to see if it contains this file.
879   for (; i != SearchDirs.size(); ++i) {
880     bool InUserSpecifiedSystemFramework = false;
881     bool HasBeenMapped = false;
882     bool IsFrameworkFoundInDir = false;
883     const FileEntry *FE = SearchDirs[i].LookupFile(
884         Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
885         SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
886         HasBeenMapped, MappedName);
887     if (HasBeenMapped) {
888       CacheLookup.MappedName =
889           copyString(Filename, LookupFileCache.getAllocator());
890       if (IsMapped)
891         *IsMapped = true;
892     }
893     if (IsFrameworkFound)
894       // Because we keep a filename remapped for subsequent search directory
895       // lookups, ignore IsFrameworkFoundInDir after the first remapping and not
896       // just for remapping in a current search directory.
897       *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
898     if (!FE) continue;
899 
900     CurDir = &SearchDirs[i];
901 
902     // This file is a system header or C++ unfriendly if the dir is.
903     HeaderFileInfo &HFI = getFileInfo(FE);
904     HFI.DirInfo = CurDir->getDirCharacteristic();
905 
906     // If the directory characteristic is User but this framework was
907     // user-specified to be treated as a system framework, promote the
908     // characteristic.
909     if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
910       HFI.DirInfo = SrcMgr::C_System;
911 
912     // If the filename matches a known system header prefix, override
913     // whether the file is a system header.
914     for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
915       if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
916         HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
917                                                        : SrcMgr::C_User;
918         break;
919       }
920     }
921 
922     // If this file is found in a header map and uses the framework style of
923     // includes, then this header is part of a framework we're building.
924     if (CurDir->isIndexHeaderMap()) {
925       size_t SlashPos = Filename.find('/');
926       if (SlashPos != StringRef::npos) {
927         HFI.IndexHeaderMapHeader = 1;
928         HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
929                                                          SlashPos));
930       }
931     }
932 
933     if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
934       if (SuggestedModule)
935         *SuggestedModule = MSSuggestedModule;
936       return MSFE;
937     }
938 
939     bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
940     if (!Includers.empty())
941       diagnoseFrameworkInclude(Diags, IncludeLoc,
942                                Includers.front().second->getName(), Filename,
943                                FE, isAngled, FoundByHeaderMap);
944 
945     // Remember this location for the next lookup we do.
946     CacheLookup.HitIdx = i;
947     return FE;
948   }
949 
950   // If we are including a file with a quoted include "foo.h" from inside
951   // a header in a framework that is currently being built, and we couldn't
952   // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
953   // "Foo" is the name of the framework in which the including header was found.
954   if (!Includers.empty() && Includers.front().first && !isAngled &&
955       Filename.find('/') == StringRef::npos) {
956     HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first);
957     if (IncludingHFI.IndexHeaderMapHeader) {
958       SmallString<128> ScratchFilename;
959       ScratchFilename += IncludingHFI.Framework;
960       ScratchFilename += '/';
961       ScratchFilename += Filename;
962 
963       const FileEntry *FE = LookupFile(
964           ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir,
965           Includers.front(), SearchPath, RelativePath, RequestingModule,
966           SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr);
967 
968       if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
969         if (SuggestedModule)
970           *SuggestedModule = MSSuggestedModule;
971         return MSFE;
972       }
973 
974       LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
975       CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
976       // FIXME: SuggestedModule.
977       return FE;
978     }
979   }
980 
981   if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
982     if (SuggestedModule)
983       *SuggestedModule = MSSuggestedModule;
984     return MSFE;
985   }
986 
987   // Otherwise, didn't find it. Remember we didn't find this.
988   CacheLookup.HitIdx = SearchDirs.size();
989   return nullptr;
990 }
991 
992 /// LookupSubframeworkHeader - Look up a subframework for the specified
993 /// \#include file.  For example, if \#include'ing <HIToolbox/HIToolbox.h> from
994 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
995 /// is a subframework within Carbon.framework.  If so, return the FileEntry
996 /// for the designated file, otherwise return null.
997 const FileEntry *HeaderSearch::
998 LookupSubframeworkHeader(StringRef Filename,
999                          const FileEntry *ContextFileEnt,
1000                          SmallVectorImpl<char> *SearchPath,
1001                          SmallVectorImpl<char> *RelativePath,
1002                          Module *RequestingModule,
1003                          ModuleMap::KnownHeader *SuggestedModule) {
1004   assert(ContextFileEnt && "No context file?");
1005 
1006   // Framework names must have a '/' in the filename.  Find it.
1007   // FIXME: Should we permit '\' on Windows?
1008   size_t SlashPos = Filename.find('/');
1009   if (SlashPos == StringRef::npos) return nullptr;
1010 
1011   // Look up the base framework name of the ContextFileEnt.
1012   StringRef ContextName = ContextFileEnt->getName();
1013 
1014   // If the context info wasn't a framework, couldn't be a subframework.
1015   const unsigned DotFrameworkLen = 10;
1016   auto FrameworkPos = ContextName.find(".framework");
1017   if (FrameworkPos == StringRef::npos ||
1018       (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1019        ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1020     return nullptr;
1021 
1022   SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1023                                                           FrameworkPos +
1024                                                           DotFrameworkLen + 1);
1025 
1026   // Append Frameworks/HIToolbox.framework/
1027   FrameworkName += "Frameworks/";
1028   FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1029   FrameworkName += ".framework/";
1030 
1031   auto &CacheLookup =
1032       *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1033                                           FrameworkCacheEntry())).first;
1034 
1035   // Some other location?
1036   if (CacheLookup.second.Directory &&
1037       CacheLookup.first().size() == FrameworkName.size() &&
1038       memcmp(CacheLookup.first().data(), &FrameworkName[0],
1039              CacheLookup.first().size()) != 0)
1040     return nullptr;
1041 
1042   // Cache subframework.
1043   if (!CacheLookup.second.Directory) {
1044     ++NumSubFrameworkLookups;
1045 
1046     // If the framework dir doesn't exist, we fail.
1047     auto Dir = FileMgr.getDirectory(FrameworkName);
1048     if (!Dir) return nullptr;
1049 
1050     // Otherwise, if it does, remember that this is the right direntry for this
1051     // framework.
1052     CacheLookup.second.Directory = *Dir;
1053   }
1054 
1055   const FileEntry *FE = nullptr;
1056 
1057   if (RelativePath) {
1058     RelativePath->clear();
1059     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1060   }
1061 
1062   // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
1063   SmallString<1024> HeadersFilename(FrameworkName);
1064   HeadersFilename += "Headers/";
1065   if (SearchPath) {
1066     SearchPath->clear();
1067     // Without trailing '/'.
1068     SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1069   }
1070 
1071   HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1072   if (auto File = FileMgr.getFile(HeadersFilename, /*OpenFile=*/true))
1073     FE = *File;
1074 
1075   if (!FE) {
1076     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
1077     HeadersFilename = FrameworkName;
1078     HeadersFilename += "PrivateHeaders/";
1079     if (SearchPath) {
1080       SearchPath->clear();
1081       // Without trailing '/'.
1082       SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1083     }
1084 
1085     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1086     if (auto File = FileMgr.getFile(HeadersFilename, /*OpenFile=*/true))
1087       FE = *File;
1088 
1089     if (!FE)
1090       return nullptr;
1091   }
1092 
1093   // This file is a system header or C++ unfriendly if the old file is.
1094   //
1095   // Note that the temporary 'DirInfo' is required here, as either call to
1096   // getFileInfo could resize the vector and we don't want to rely on order
1097   // of evaluation.
1098   unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
1099   getFileInfo(FE).DirInfo = DirInfo;
1100 
1101   FrameworkName.pop_back(); // remove the trailing '/'
1102   if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
1103                                           SuggestedModule, /*IsSystem*/ false))
1104     return nullptr;
1105 
1106   return FE;
1107 }
1108 
1109 //===----------------------------------------------------------------------===//
1110 // File Info Management.
1111 //===----------------------------------------------------------------------===//
1112 
1113 /// Merge the header file info provided by \p OtherHFI into the current
1114 /// header file info (\p HFI)
1115 static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
1116                                 const HeaderFileInfo &OtherHFI) {
1117   assert(OtherHFI.External && "expected to merge external HFI");
1118 
1119   HFI.isImport |= OtherHFI.isImport;
1120   HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
1121   HFI.isModuleHeader |= OtherHFI.isModuleHeader;
1122   HFI.NumIncludes += OtherHFI.NumIncludes;
1123 
1124   if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
1125     HFI.ControllingMacro = OtherHFI.ControllingMacro;
1126     HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
1127   }
1128 
1129   HFI.DirInfo = OtherHFI.DirInfo;
1130   HFI.External = (!HFI.IsValid || HFI.External);
1131   HFI.IsValid = true;
1132   HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
1133 
1134   if (HFI.Framework.empty())
1135     HFI.Framework = OtherHFI.Framework;
1136 }
1137 
1138 /// getFileInfo - Return the HeaderFileInfo structure for the specified
1139 /// FileEntry.
1140 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
1141   if (FE->getUID() >= FileInfo.size())
1142     FileInfo.resize(FE->getUID() + 1);
1143 
1144   HeaderFileInfo *HFI = &FileInfo[FE->getUID()];
1145   // FIXME: Use a generation count to check whether this is really up to date.
1146   if (ExternalSource && !HFI->Resolved) {
1147     HFI->Resolved = true;
1148     auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1149 
1150     HFI = &FileInfo[FE->getUID()];
1151     if (ExternalHFI.External)
1152       mergeHeaderFileInfo(*HFI, ExternalHFI);
1153   }
1154 
1155   HFI->IsValid = true;
1156   // We have local information about this header file, so it's no longer
1157   // strictly external.
1158   HFI->External = false;
1159   return *HFI;
1160 }
1161 
1162 const HeaderFileInfo *
1163 HeaderSearch::getExistingFileInfo(const FileEntry *FE,
1164                                   bool WantExternal) const {
1165   // If we have an external source, ensure we have the latest information.
1166   // FIXME: Use a generation count to check whether this is really up to date.
1167   HeaderFileInfo *HFI;
1168   if (ExternalSource) {
1169     if (FE->getUID() >= FileInfo.size()) {
1170       if (!WantExternal)
1171         return nullptr;
1172       FileInfo.resize(FE->getUID() + 1);
1173     }
1174 
1175     HFI = &FileInfo[FE->getUID()];
1176     if (!WantExternal && (!HFI->IsValid || HFI->External))
1177       return nullptr;
1178     if (!HFI->Resolved) {
1179       HFI->Resolved = true;
1180       auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1181 
1182       HFI = &FileInfo[FE->getUID()];
1183       if (ExternalHFI.External)
1184         mergeHeaderFileInfo(*HFI, ExternalHFI);
1185     }
1186   } else if (FE->getUID() >= FileInfo.size()) {
1187     return nullptr;
1188   } else {
1189     HFI = &FileInfo[FE->getUID()];
1190   }
1191 
1192   if (!HFI->IsValid || (HFI->External && !WantExternal))
1193     return nullptr;
1194 
1195   return HFI;
1196 }
1197 
1198 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
1199   // Check if we've ever seen this file as a header.
1200   if (auto *HFI = getExistingFileInfo(File))
1201     return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1202            HFI->ControllingMacroID;
1203   return false;
1204 }
1205 
1206 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
1207                                         ModuleMap::ModuleHeaderRole Role,
1208                                         bool isCompilingModuleHeader) {
1209   bool isModularHeader = !(Role & ModuleMap::TextualHeader);
1210 
1211   // Don't mark the file info as non-external if there's nothing to change.
1212   if (!isCompilingModuleHeader) {
1213     if (!isModularHeader)
1214       return;
1215     auto *HFI = getExistingFileInfo(FE);
1216     if (HFI && HFI->isModuleHeader)
1217       return;
1218   }
1219 
1220   auto &HFI = getFileInfo(FE);
1221   HFI.isModuleHeader |= isModularHeader;
1222   HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1223 }
1224 
1225 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
1226                                           const FileEntry *File, bool isImport,
1227                                           bool ModulesEnabled, Module *M) {
1228   ++NumIncluded; // Count # of attempted #includes.
1229 
1230   // Get information about this file.
1231   HeaderFileInfo &FileInfo = getFileInfo(File);
1232 
1233   // FIXME: this is a workaround for the lack of proper modules-aware support
1234   // for #import / #pragma once
1235   auto TryEnterImported = [&]() -> bool {
1236     if (!ModulesEnabled)
1237       return false;
1238     // Ensure FileInfo bits are up to date.
1239     ModMap.resolveHeaderDirectives(File);
1240     // Modules with builtins are special; multiple modules use builtins as
1241     // modular headers, example:
1242     //
1243     //    module stddef { header "stddef.h" export * }
1244     //
1245     // After module map parsing, this expands to:
1246     //
1247     //    module stddef {
1248     //      header "/path_to_builtin_dirs/stddef.h"
1249     //      textual "stddef.h"
1250     //    }
1251     //
1252     // It's common that libc++ and system modules will both define such
1253     // submodules. Make sure cached results for a builtin header won't
1254     // prevent other builtin modules to potentially enter the builtin header.
1255     // Note that builtins are header guarded and the decision to actually
1256     // enter them is postponed to the controlling macros logic below.
1257     bool TryEnterHdr = false;
1258     if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
1259       TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
1260                     ModuleMap::isBuiltinHeader(
1261                         llvm::sys::path::filename(File->getName()));
1262 
1263     // Textual headers can be #imported from different modules. Since ObjC
1264     // headers find in the wild might rely only on #import and do not contain
1265     // controlling macros, be conservative and only try to enter textual headers
1266     // if such macro is present.
1267     if (!FileInfo.isModuleHeader &&
1268         FileInfo.getControllingMacro(ExternalLookup))
1269       TryEnterHdr = true;
1270     return TryEnterHdr;
1271   };
1272 
1273   // If this is a #import directive, check that we have not already imported
1274   // this header.
1275   if (isImport) {
1276     // If this has already been imported, don't import it again.
1277     FileInfo.isImport = true;
1278 
1279     // Has this already been #import'ed or #include'd?
1280     if (FileInfo.NumIncludes && !TryEnterImported())
1281       return false;
1282   } else {
1283     // Otherwise, if this is a #include of a file that was previously #import'd
1284     // or if this is the second #include of a #pragma once file, ignore it.
1285     if (FileInfo.isImport && !TryEnterImported())
1286       return false;
1287   }
1288 
1289   // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
1290   // if the macro that guards it is defined, we know the #include has no effect.
1291   if (const IdentifierInfo *ControllingMacro
1292       = FileInfo.getControllingMacro(ExternalLookup)) {
1293     // If the header corresponds to a module, check whether the macro is already
1294     // defined in that module rather than checking in the current set of visible
1295     // modules.
1296     if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1297           : PP.isMacroDefined(ControllingMacro)) {
1298       ++NumMultiIncludeFileOptzn;
1299       return false;
1300     }
1301   }
1302 
1303   // Increment the number of times this file has been included.
1304   ++FileInfo.NumIncludes;
1305 
1306   return true;
1307 }
1308 
1309 size_t HeaderSearch::getTotalMemory() const {
1310   return SearchDirs.capacity()
1311     + llvm::capacity_in_bytes(FileInfo)
1312     + llvm::capacity_in_bytes(HeaderMaps)
1313     + LookupFileCache.getAllocator().getTotalMemory()
1314     + FrameworkMap.getAllocator().getTotalMemory();
1315 }
1316 
1317 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1318   return FrameworkNames.insert(Framework).first->first();
1319 }
1320 
1321 bool HeaderSearch::hasModuleMap(StringRef FileName,
1322                                 const DirectoryEntry *Root,
1323                                 bool IsSystem) {
1324   if (!HSOpts->ImplicitModuleMaps)
1325     return false;
1326 
1327   SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
1328 
1329   StringRef DirName = FileName;
1330   do {
1331     // Get the parent directory name.
1332     DirName = llvm::sys::path::parent_path(DirName);
1333     if (DirName.empty())
1334       return false;
1335 
1336     // Determine whether this directory exists.
1337     auto Dir = FileMgr.getDirectory(DirName);
1338     if (!Dir)
1339       return false;
1340 
1341     // Try to load the module map file in this directory.
1342     switch (loadModuleMapFile(*Dir, IsSystem,
1343                               llvm::sys::path::extension((*Dir)->getName()) ==
1344                                   ".framework")) {
1345     case LMM_NewlyLoaded:
1346     case LMM_AlreadyLoaded:
1347       // Success. All of the directories we stepped through inherit this module
1348       // map file.
1349       for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1350         DirectoryHasModuleMap[FixUpDirectories[I]] = true;
1351       return true;
1352 
1353     case LMM_NoDirectory:
1354     case LMM_InvalidModuleMap:
1355       break;
1356     }
1357 
1358     // If we hit the top of our search, we're done.
1359     if (*Dir == Root)
1360       return false;
1361 
1362     // Keep track of all of the directories we checked, so we can mark them as
1363     // having module maps if we eventually do find a module map.
1364     FixUpDirectories.push_back(*Dir);
1365   } while (true);
1366 }
1367 
1368 ModuleMap::KnownHeader
1369 HeaderSearch::findModuleForHeader(const FileEntry *File,
1370                                   bool AllowTextual) const {
1371   if (ExternalSource) {
1372     // Make sure the external source has handled header info about this file,
1373     // which includes whether the file is part of a module.
1374     (void)getExistingFileInfo(File);
1375   }
1376   return ModMap.findModuleForHeader(File, AllowTextual);
1377 }
1378 
1379 static bool suggestModule(HeaderSearch &HS, const FileEntry *File,
1380                           Module *RequestingModule,
1381                           ModuleMap::KnownHeader *SuggestedModule) {
1382   ModuleMap::KnownHeader Module =
1383       HS.findModuleForHeader(File, /*AllowTextual*/true);
1384   if (SuggestedModule)
1385     *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
1386                            ? ModuleMap::KnownHeader()
1387                            : Module;
1388 
1389   // If this module specifies [no_undeclared_includes], we cannot find any
1390   // file that's in a non-dependency module.
1391   if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
1392     HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/false);
1393     if (!RequestingModule->directlyUses(Module.getModule())) {
1394       return false;
1395     }
1396   }
1397 
1398   return true;
1399 }
1400 
1401 bool HeaderSearch::findUsableModuleForHeader(
1402     const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule,
1403     ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1404   if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
1405     // If there is a module that corresponds to this header, suggest it.
1406     hasModuleMap(File->getName(), Root, IsSystemHeaderDir);
1407     return suggestModule(*this, File, RequestingModule, SuggestedModule);
1408   }
1409   return true;
1410 }
1411 
1412 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1413     const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
1414     ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1415   // If we're supposed to suggest a module, look for one now.
1416   if (needModuleLookup(RequestingModule, SuggestedModule)) {
1417     // Find the top-level framework based on this framework.
1418     SmallVector<std::string, 4> SubmodulePath;
1419     const DirectoryEntry *TopFrameworkDir
1420       = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1421 
1422     // Determine the name of the top-level framework.
1423     StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1424 
1425     // Load this framework module. If that succeeds, find the suggested module
1426     // for this header, if any.
1427     loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1428 
1429     // FIXME: This can find a module not part of ModuleName, which is
1430     // important so that we're consistent about whether this header
1431     // corresponds to a module. Possibly we should lock down framework modules
1432     // so that this is not possible.
1433     return suggestModule(*this, File, RequestingModule, SuggestedModule);
1434   }
1435   return true;
1436 }
1437 
1438 static const FileEntry *getPrivateModuleMap(const FileEntry *File,
1439                                             FileManager &FileMgr) {
1440   StringRef Filename = llvm::sys::path::filename(File->getName());
1441   SmallString<128>  PrivateFilename(File->getDir()->getName());
1442   if (Filename == "module.map")
1443     llvm::sys::path::append(PrivateFilename, "module_private.map");
1444   else if (Filename == "module.modulemap")
1445     llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1446   else
1447     return nullptr;
1448   if (auto File = FileMgr.getFile(PrivateFilename))
1449     return *File;
1450   return nullptr;
1451 }
1452 
1453 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem,
1454                                      FileID ID, unsigned *Offset,
1455                                      StringRef OriginalModuleMapFile) {
1456   // Find the directory for the module. For frameworks, that may require going
1457   // up from the 'Modules' directory.
1458   const DirectoryEntry *Dir = nullptr;
1459   if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
1460     if (auto DirOrErr = FileMgr.getDirectory("."))
1461       Dir = *DirOrErr;
1462   } else {
1463     if (!OriginalModuleMapFile.empty()) {
1464       // We're building a preprocessed module map. Find or invent the directory
1465       // that it originally occupied.
1466       auto DirOrErr = FileMgr.getDirectory(
1467           llvm::sys::path::parent_path(OriginalModuleMapFile));
1468       if (DirOrErr) {
1469         Dir = *DirOrErr;
1470       } else {
1471         auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
1472         Dir = FakeFile->getDir();
1473       }
1474     } else {
1475       Dir = File->getDir();
1476     }
1477 
1478     StringRef DirName(Dir->getName());
1479     if (llvm::sys::path::filename(DirName) == "Modules") {
1480       DirName = llvm::sys::path::parent_path(DirName);
1481       if (DirName.endswith(".framework"))
1482         if (auto DirOrErr = FileMgr.getDirectory(DirName))
1483           Dir = *DirOrErr;
1484       // FIXME: This assert can fail if there's a race between the above check
1485       // and the removal of the directory.
1486       assert(Dir && "parent must exist");
1487     }
1488   }
1489 
1490   switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1491   case LMM_AlreadyLoaded:
1492   case LMM_NewlyLoaded:
1493     return false;
1494   case LMM_NoDirectory:
1495   case LMM_InvalidModuleMap:
1496     return true;
1497   }
1498   llvm_unreachable("Unknown load module map result");
1499 }
1500 
1501 HeaderSearch::LoadModuleMapResult
1502 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem,
1503                                     const DirectoryEntry *Dir, FileID ID,
1504                                     unsigned *Offset) {
1505   assert(File && "expected FileEntry");
1506 
1507   // Check whether we've already loaded this module map, and mark it as being
1508   // loaded in case we recursively try to load it from itself.
1509   auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1510   if (!AddResult.second)
1511     return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1512 
1513   if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1514     LoadedModuleMaps[File] = false;
1515     return LMM_InvalidModuleMap;
1516   }
1517 
1518   // Try to load a corresponding private module map.
1519   if (const FileEntry *PMMFile = getPrivateModuleMap(File, FileMgr)) {
1520     if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1521       LoadedModuleMaps[File] = false;
1522       return LMM_InvalidModuleMap;
1523     }
1524   }
1525 
1526   // This directory has a module map.
1527   return LMM_NewlyLoaded;
1528 }
1529 
1530 const FileEntry *
1531 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {
1532   if (!HSOpts->ImplicitModuleMaps)
1533     return nullptr;
1534   // For frameworks, the preferred spelling is Modules/module.modulemap, but
1535   // module.map at the framework root is also accepted.
1536   SmallString<128> ModuleMapFileName(Dir->getName());
1537   if (IsFramework)
1538     llvm::sys::path::append(ModuleMapFileName, "Modules");
1539   llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1540   if (auto F = FileMgr.getFile(ModuleMapFileName))
1541     return *F;
1542 
1543   // Continue to allow module.map
1544   ModuleMapFileName = Dir->getName();
1545   llvm::sys::path::append(ModuleMapFileName, "module.map");
1546   if (auto F = FileMgr.getFile(ModuleMapFileName))
1547     return *F;
1548   return nullptr;
1549 }
1550 
1551 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1552                                           const DirectoryEntry *Dir,
1553                                           bool IsSystem) {
1554   if (Module *Module = ModMap.findModule(Name))
1555     return Module;
1556 
1557   // Try to load a module map file.
1558   switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
1559   case LMM_InvalidModuleMap:
1560     // Try to infer a module map from the framework directory.
1561     if (HSOpts->ImplicitModuleMaps)
1562       ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1563     break;
1564 
1565   case LMM_AlreadyLoaded:
1566   case LMM_NoDirectory:
1567     return nullptr;
1568 
1569   case LMM_NewlyLoaded:
1570     break;
1571   }
1572 
1573   return ModMap.findModule(Name);
1574 }
1575 
1576 HeaderSearch::LoadModuleMapResult
1577 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
1578                                 bool IsFramework) {
1579   if (auto Dir = FileMgr.getDirectory(DirName))
1580     return loadModuleMapFile(*Dir, IsSystem, IsFramework);
1581 
1582   return LMM_NoDirectory;
1583 }
1584 
1585 HeaderSearch::LoadModuleMapResult
1586 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
1587                                 bool IsFramework) {
1588   auto KnownDir = DirectoryHasModuleMap.find(Dir);
1589   if (KnownDir != DirectoryHasModuleMap.end())
1590     return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1591 
1592   if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
1593     LoadModuleMapResult Result =
1594         loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1595     // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1596     // E.g. Foo.framework/Modules/module.modulemap
1597     //      ^Dir                  ^ModuleMapFile
1598     if (Result == LMM_NewlyLoaded)
1599       DirectoryHasModuleMap[Dir] = true;
1600     else if (Result == LMM_InvalidModuleMap)
1601       DirectoryHasModuleMap[Dir] = false;
1602     return Result;
1603   }
1604   return LMM_InvalidModuleMap;
1605 }
1606 
1607 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
1608   Modules.clear();
1609 
1610   if (HSOpts->ImplicitModuleMaps) {
1611     // Load module maps for each of the header search directories.
1612     for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1613       bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1614       if (SearchDirs[Idx].isFramework()) {
1615         std::error_code EC;
1616         SmallString<128> DirNative;
1617         llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
1618                                 DirNative);
1619 
1620         // Search each of the ".framework" directories to load them as modules.
1621         llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1622         for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1623                                            DirEnd;
1624              Dir != DirEnd && !EC; Dir.increment(EC)) {
1625           if (llvm::sys::path::extension(Dir->path()) != ".framework")
1626             continue;
1627 
1628           auto FrameworkDir =
1629               FileMgr.getDirectory(Dir->path());
1630           if (!FrameworkDir)
1631             continue;
1632 
1633           // Load this framework module.
1634           loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1635                               IsSystem);
1636         }
1637         continue;
1638       }
1639 
1640       // FIXME: Deal with header maps.
1641       if (SearchDirs[Idx].isHeaderMap())
1642         continue;
1643 
1644       // Try to load a module map file for the search directory.
1645       loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
1646                         /*IsFramework*/ false);
1647 
1648       // Try to load module map files for immediate subdirectories of this
1649       // search directory.
1650       loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1651     }
1652   }
1653 
1654   // Populate the list of modules.
1655   for (ModuleMap::module_iterator M = ModMap.module_begin(),
1656                                MEnd = ModMap.module_end();
1657        M != MEnd; ++M) {
1658     Modules.push_back(M->getValue());
1659   }
1660 }
1661 
1662 void HeaderSearch::loadTopLevelSystemModules() {
1663   if (!HSOpts->ImplicitModuleMaps)
1664     return;
1665 
1666   // Load module maps for each of the header search directories.
1667   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1668     // We only care about normal header directories.
1669     if (!SearchDirs[Idx].isNormalDir()) {
1670       continue;
1671     }
1672 
1673     // Try to load a module map file for the search directory.
1674     loadModuleMapFile(SearchDirs[Idx].getDir(),
1675                       SearchDirs[Idx].isSystemHeaderDirectory(),
1676                       SearchDirs[Idx].isFramework());
1677   }
1678 }
1679 
1680 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
1681   assert(HSOpts->ImplicitModuleMaps &&
1682          "Should not be loading subdirectory module maps");
1683 
1684   if (SearchDir.haveSearchedAllModuleMaps())
1685     return;
1686 
1687   std::error_code EC;
1688   SmallString<128> Dir = SearchDir.getDir()->getName();
1689   FileMgr.makeAbsolutePath(Dir);
1690   SmallString<128> DirNative;
1691   llvm::sys::path::native(Dir, DirNative);
1692   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1693   for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1694        Dir != DirEnd && !EC; Dir.increment(EC)) {
1695     bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
1696     if (IsFramework == SearchDir.isFramework())
1697       loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
1698                         SearchDir.isFramework());
1699   }
1700 
1701   SearchDir.setSearchedAllModuleMaps(true);
1702 }
1703 
1704 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1705     const FileEntry *File, llvm::StringRef MainFile, bool *IsSystem) {
1706   // FIXME: We assume that the path name currently cached in the FileEntry is
1707   // the most appropriate one for this analysis (and that it's spelled the
1708   // same way as the corresponding header search path).
1709   return suggestPathToFileForDiagnostics(File->getName(), /*WorkingDir=*/"",
1710                                          MainFile, IsSystem);
1711 }
1712 
1713 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1714     llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1715     bool *IsSystem) {
1716   using namespace llvm::sys;
1717 
1718   unsigned BestPrefixLength = 0;
1719   // Checks whether Dir and File shares a common prefix, if they do and that's
1720   // the longest prefix we've seen so for it returns true and updates the
1721   // BestPrefixLength accordingly.
1722   auto CheckDir = [&](llvm::StringRef Dir) -> bool {
1723     llvm::SmallString<32> DirPath(Dir.begin(), Dir.end());
1724     if (!WorkingDir.empty() && !path::is_absolute(Dir))
1725       fs::make_absolute(WorkingDir, DirPath);
1726     path::remove_dots(DirPath, /*remove_dot_dot=*/true);
1727     Dir = DirPath;
1728     for (auto NI = path::begin(File), NE = path::end(File),
1729               DI = path::begin(Dir), DE = path::end(Dir);
1730          /*termination condition in loop*/; ++NI, ++DI) {
1731       // '.' components in File are ignored.
1732       while (NI != NE && *NI == ".")
1733         ++NI;
1734       if (NI == NE)
1735         break;
1736 
1737       // '.' components in Dir are ignored.
1738       while (DI != DE && *DI == ".")
1739         ++DI;
1740       if (DI == DE) {
1741         // Dir is a prefix of File, up to '.' components and choice of path
1742         // separators.
1743         unsigned PrefixLength = NI - path::begin(File);
1744         if (PrefixLength > BestPrefixLength) {
1745           BestPrefixLength = PrefixLength;
1746           return true;
1747         }
1748         break;
1749       }
1750 
1751       // Consider all path separators equal.
1752       if (NI->size() == 1 && DI->size() == 1 &&
1753           path::is_separator(NI->front()) && path::is_separator(DI->front()))
1754         continue;
1755 
1756       if (*NI != *DI)
1757         break;
1758     }
1759     return false;
1760   };
1761 
1762   for (unsigned I = 0; I != SearchDirs.size(); ++I) {
1763     // FIXME: Support this search within frameworks and header maps.
1764     if (!SearchDirs[I].isNormalDir())
1765       continue;
1766 
1767     StringRef Dir = SearchDirs[I].getDir()->getName();
1768     if (CheckDir(Dir) && IsSystem)
1769       *IsSystem = BestPrefixLength ? I >= SystemDirIdx : false;
1770   }
1771 
1772   // Try to shorten include path using TUs directory, if we couldn't find any
1773   // suitable prefix in include search paths.
1774   if (!BestPrefixLength && CheckDir(path::parent_path(MainFile)) && IsSystem)
1775     *IsSystem = false;
1776 
1777 
1778   return path::convert_to_slash(File.drop_front(BestPrefixLength));
1779 }
1780