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