clang  19.0.0git
HeaderSearch.cpp
Go to the documentation of this file.
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"
17 #include "clang/Basic/Module.h"
21 #include "clang/Lex/HeaderMap.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/Statistic.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/ADT/STLExtras.h"
33 #include "llvm/Support/Allocator.h"
34 #include "llvm/Support/Capacity.h"
35 #include "llvm/Support/Errc.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/FileSystem.h"
38 #include "llvm/Support/Path.h"
39 #include "llvm/Support/VirtualFileSystem.h"
40 #include <algorithm>
41 #include <cassert>
42 #include <cstddef>
43 #include <cstdio>
44 #include <cstring>
45 #include <string>
46 #include <system_error>
47 #include <utility>
48 
49 using namespace clang;
50 
51 #define DEBUG_TYPE "file-search"
52 
53 ALWAYS_ENABLED_STATISTIC(NumIncluded, "Number of attempted #includes.");
55  NumMultiIncludeFileOptzn,
56  "Number of #includes skipped due to the multi-include optimization.");
57 ALWAYS_ENABLED_STATISTIC(NumFrameworkLookups, "Number of framework lookups.");
58 ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
59  "Number of subframework lookups.");
60 
61 const IdentifierInfo *
63  if (ControllingMacro) {
65  assert(External && "We must have an external source if we have a "
66  "controlling macro that is out of date.");
67  External->updateOutOfDateIdentifier(*ControllingMacro);
68  }
69  return ControllingMacro;
70  }
71 
73  return nullptr;
74 
76  return ControllingMacro;
77 }
78 
80 
81 HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
82  SourceManager &SourceMgr, DiagnosticsEngine &Diags,
83  const LangOptions &LangOpts,
84  const TargetInfo *Target)
85  : HSOpts(std::move(HSOpts)), Diags(Diags),
86  FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
87  ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
88 
90  llvm::errs() << "\n*** HeaderSearch Stats:\n"
91  << FileInfo.size() << " files tracked.\n";
92  unsigned NumOnceOnlyFiles = 0;
93  for (unsigned i = 0, e = FileInfo.size(); i != e; ++i)
94  NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
95  llvm::errs() << " " << NumOnceOnlyFiles << " #import/#pragma once files.\n";
96 
97  llvm::errs() << " " << NumIncluded << " #include/#include_next/#import.\n"
98  << " " << NumMultiIncludeFileOptzn
99  << " #includes skipped due to the multi-include optimization.\n";
100 
101  llvm::errs() << NumFrameworkLookups << " framework lookups.\n"
102  << NumSubFrameworkLookups << " subframework lookups.\n";
103 }
104 
106  std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx,
107  unsigned int systemDirIdx,
108  llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
109  assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
110  "Directory indices are unordered");
111  SearchDirs = std::move(dirs);
112  SearchDirsUsage.assign(SearchDirs.size(), false);
113  AngledDirIdx = angledDirIdx;
114  SystemDirIdx = systemDirIdx;
115  SearchDirToHSEntry = std::move(searchDirToHSEntry);
116  //LookupFileCache.clear();
117  indexInitialHeaderMaps();
118 }
119 
120 void HeaderSearch::AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
121  unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
122  SearchDirs.insert(SearchDirs.begin() + idx, dir);
123  SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false);
124  if (!isAngled)
125  AngledDirIdx++;
126  SystemDirIdx++;
127 }
128 
129 std::vector<bool> HeaderSearch::computeUserEntryUsage() const {
130  std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size());
131  for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
132  // Check whether this DirectoryLookup has been successfully used.
133  if (SearchDirsUsage[I]) {
134  auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
135  // Check whether this DirectoryLookup maps to a HeaderSearch::UserEntry.
136  if (UserEntryIdxIt != SearchDirToHSEntry.end())
137  UserEntryUsage[UserEntryIdxIt->second] = true;
138  }
139  }
140  return UserEntryUsage;
141 }
142 
143 std::vector<bool> HeaderSearch::collectVFSUsageAndClear() const {
144  std::vector<bool> VFSUsage;
145  if (!getHeaderSearchOpts().ModulesIncludeVFSUsage)
146  return VFSUsage;
147 
148  llvm::vfs::FileSystem &RootFS = FileMgr.getVirtualFileSystem();
149  // TODO: This only works if the `RedirectingFileSystem`s were all created by
150  // `createVFSFromOverlayFiles`.
151  RootFS.visit([&](llvm::vfs::FileSystem &FS) {
152  if (auto *RFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&FS)) {
153  VFSUsage.push_back(RFS->hasBeenUsed());
154  RFS->clearHasBeenUsed();
155  }
156  });
157  assert(VFSUsage.size() == getHeaderSearchOpts().VFSOverlayFiles.size() &&
158  "A different number of RedirectingFileSystem's were present than "
159  "-ivfsoverlay options passed to Clang!");
160  // VFS visit order is the opposite of VFSOverlayFiles order.
161  std::reverse(VFSUsage.begin(), VFSUsage.end());
162  return VFSUsage;
163 }
164 
165 /// CreateHeaderMap - This method returns a HeaderMap for the specified
166 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
168  // We expect the number of headermaps to be small, and almost always empty.
169  // If it ever grows, use of a linear search should be re-evaluated.
170  if (!HeaderMaps.empty()) {
171  for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
172  // Pointer equality comparison of FileEntries works because they are
173  // already uniqued by inode.
174  if (HeaderMaps[i].first == FE)
175  return HeaderMaps[i].second.get();
176  }
177 
178  if (std::unique_ptr<HeaderMap> HM = HeaderMap::Create(FE, FileMgr)) {
179  HeaderMaps.emplace_back(FE, std::move(HM));
180  return HeaderMaps.back().second.get();
181  }
182 
183  return nullptr;
184 }
185 
186 /// Get filenames for all registered header maps.
188  SmallVectorImpl<std::string> &Names) const {
189  for (auto &HM : HeaderMaps)
190  Names.push_back(std::string(HM.first.getName()));
191 }
192 
196  // The ModuleMap maybe a nullptr, when we load a cached C++ module without
197  // *.modulemap file. In this case, just return an empty string.
198  if (!ModuleMap)
199  return {};
200  return getCachedModuleFileName(Module->Name, ModuleMap->getNameAsRequested());
201 }
202 
203 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
204  bool FileMapOnly) {
205  // First check the module name to pcm file map.
206  auto i(HSOpts->PrebuiltModuleFiles.find(ModuleName));
207  if (i != HSOpts->PrebuiltModuleFiles.end())
208  return i->second;
209 
210  if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
211  return {};
212 
213  // Then go through each prebuilt module directory and try to find the pcm
214  // file.
215  for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
216  SmallString<256> Result(Dir);
217  llvm::sys::fs::make_absolute(Result);
218  if (ModuleName.contains(':'))
219  // The separator of C++20 modules partitions (':') is not good for file
220  // systems, here clang and gcc choose '-' by default since it is not a
221  // valid character of C++ indentifiers. So we could avoid conflicts.
222  llvm::sys::path::append(Result, ModuleName.split(':').first + "-" +
223  ModuleName.split(':').second +
224  ".pcm");
225  else
226  llvm::sys::path::append(Result, ModuleName + ".pcm");
227  if (getFileMgr().getFile(Result.str()))
228  return std::string(Result);
229  }
230 
231  return {};
232 }
233 
237  StringRef ModuleName = Module->Name;
238  StringRef ModuleMapPath = ModuleMap->getName();
239  StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash();
240  for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
241  SmallString<256> CachePath(Dir);
242  llvm::sys::fs::make_absolute(CachePath);
243  llvm::sys::path::append(CachePath, ModuleCacheHash);
244  std::string FileName =
245  getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
246  if (!FileName.empty() && getFileMgr().getFile(FileName))
247  return FileName;
248  }
249  return {};
250 }
251 
252 std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
253  StringRef ModuleMapPath) {
254  return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
256 }
257 
258 std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
259  StringRef ModuleMapPath,
260  StringRef CachePath) {
261  // If we don't have a module cache path or aren't supposed to use one, we
262  // can't do anything.
263  if (CachePath.empty())
264  return {};
265 
266  SmallString<256> Result(CachePath);
267  llvm::sys::fs::make_absolute(Result);
268 
269  if (HSOpts->DisableModuleHash) {
270  llvm::sys::path::append(Result, ModuleName + ".pcm");
271  } else {
272  // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
273  // ideally be globally unique to this particular module. Name collisions
274  // in the hash are safe (because any translation unit can only import one
275  // module with each name), but result in a loss of caching.
276  //
277  // To avoid false-negatives, we form as canonical a path as we can, and map
278  // to lower-case in case we're on a case-insensitive file system.
279  SmallString<128> CanonicalPath(ModuleMapPath);
280  if (getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
281  return {};
282 
283  llvm::hash_code Hash = llvm::hash_combine(CanonicalPath.str().lower());
284 
285  SmallString<128> HashStr;
286  llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36);
287  llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
288  }
289  return Result.str().str();
290 }
291 
292 Module *HeaderSearch::lookupModule(StringRef ModuleName,
293  SourceLocation ImportLoc, bool AllowSearch,
294  bool AllowExtraModuleMapSearch) {
295  // Look in the module map to determine if there is a module by this name.
296  Module *Module = ModMap.findModule(ModuleName);
297  if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
298  return Module;
299 
300  StringRef SearchName = ModuleName;
301  Module = lookupModule(ModuleName, SearchName, ImportLoc,
302  AllowExtraModuleMapSearch);
303 
304  // The facility for "private modules" -- adjacent, optional module maps named
305  // module.private.modulemap that are supposed to define private submodules --
306  // may have different flavors of names: FooPrivate, Foo_Private and Foo.Private.
307  //
308  // Foo.Private is now deprecated in favor of Foo_Private. Users of FooPrivate
309  // should also rename to Foo_Private. Representing private as submodules
310  // could force building unwanted dependencies into the parent module and cause
311  // dependency cycles.
312  if (!Module && SearchName.consume_back("_Private"))
313  Module = lookupModule(ModuleName, SearchName, ImportLoc,
314  AllowExtraModuleMapSearch);
315  if (!Module && SearchName.consume_back("Private"))
316  Module = lookupModule(ModuleName, SearchName, ImportLoc,
317  AllowExtraModuleMapSearch);
318  return Module;
319 }
320 
321 Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
322  SourceLocation ImportLoc,
323  bool AllowExtraModuleMapSearch) {
324  Module *Module = nullptr;
325 
326  // Look through the various header search paths to load any available module
327  // maps, searching for a module map that describes this module.
328  for (DirectoryLookup &Dir : search_dir_range()) {
329  if (Dir.isFramework()) {
330  // Search for or infer a module map for a framework. Here we use
331  // SearchName rather than ModuleName, to permit finding private modules
332  // named FooPrivate in buggy frameworks named Foo.
333  SmallString<128> FrameworkDirName;
334  FrameworkDirName += Dir.getFrameworkDirRef()->getName();
335  llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
336  if (auto FrameworkDir =
337  FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
338  bool IsSystem = Dir.getDirCharacteristic() != SrcMgr::C_User;
339  Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
340  if (Module)
341  break;
342  }
343  }
344 
345  // FIXME: Figure out how header maps and module maps will work together.
346 
347  // Only deal with normal search directories.
348  if (!Dir.isNormalDir())
349  continue;
350 
351  bool IsSystem = Dir.isSystemHeaderDirectory();
352  // Only returns std::nullopt if not a normal directory, which we just
353  // checked
354  DirectoryEntryRef NormalDir = *Dir.getDirRef();
355  // Search for a module map file in this directory.
356  if (loadModuleMapFile(NormalDir, IsSystem,
357  /*IsFramework*/false) == LMM_NewlyLoaded) {
358  // We just loaded a module map file; check whether the module is
359  // available now.
360  Module = ModMap.findModule(ModuleName);
361  if (Module)
362  break;
363  }
364 
365  // Search for a module map in a subdirectory with the same name as the
366  // module.
367  SmallString<128> NestedModuleMapDirName;
368  NestedModuleMapDirName = Dir.getDirRef()->getName();
369  llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
370  if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
371  /*IsFramework*/false) == LMM_NewlyLoaded){
372  // If we just loaded a module map file, look for the module again.
373  Module = ModMap.findModule(ModuleName);
374  if (Module)
375  break;
376  }
377 
378  // If we've already performed the exhaustive search for module maps in this
379  // search directory, don't do it again.
380  if (Dir.haveSearchedAllModuleMaps())
381  continue;
382 
383  // Load all module maps in the immediate subdirectories of this search
384  // directory if ModuleName was from @import.
385  if (AllowExtraModuleMapSearch)
386  loadSubdirectoryModuleMaps(Dir);
387 
388  // Look again for the module.
389  Module = ModMap.findModule(ModuleName);
390  if (Module)
391  break;
392  }
393 
394  return Module;
395 }
396 
397 void HeaderSearch::indexInitialHeaderMaps() {
398  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
399 
400  // Iterate over all filename keys and associate them with the index i.
401  for (unsigned i = 0; i != SearchDirs.size(); ++i) {
402  auto &Dir = SearchDirs[i];
403 
404  // We're concerned with only the initial contiguous run of header
405  // maps within SearchDirs, which can be 99% of SearchDirs when
406  // SearchDirs.size() is ~10000.
407  if (!Dir.isHeaderMap()) {
408  SearchDirHeaderMapIndex = std::move(Index);
409  FirstNonHeaderMapSearchDirIdx = i;
410  break;
411  }
412 
413  // Give earlier keys precedence over identical later keys.
414  auto Callback = [&](StringRef Filename) {
415  Index.try_emplace(Filename.lower(), i);
416  };
417  Dir.getHeaderMap()->forEachKey(Callback);
418  }
419 }
420 
421 //===----------------------------------------------------------------------===//
422 // File lookup within a DirectoryLookup scope
423 //===----------------------------------------------------------------------===//
424 
425 /// getName - Return the directory or filename corresponding to this lookup
426 /// object.
427 StringRef DirectoryLookup::getName() const {
428  if (isNormalDir())
429  return getDirRef()->getName();
430  if (isFramework())
431  return getFrameworkDirRef()->getName();
432  assert(isHeaderMap() && "Unknown DirectoryLookup");
433  return getHeaderMap()->getFileName();
434 }
435 
436 OptionalFileEntryRef HeaderSearch::getFileAndSuggestModule(
437  StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
438  bool IsSystemHeaderDir, Module *RequestingModule,
439  ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/,
440  bool CacheFailures /*=true*/) {
441  // If we have a module map that might map this header, load it and
442  // check whether we'll have a suggestion for a module.
443  auto File = getFileMgr().getFileRef(FileName, OpenFile, CacheFailures);
444  if (!File) {
445  // For rare, surprising errors (e.g. "out of file handles"), diag the EC
446  // message.
447  std::error_code EC = llvm::errorToErrorCode(File.takeError());
448  if (EC != llvm::errc::no_such_file_or_directory &&
449  EC != llvm::errc::invalid_argument &&
450  EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
451  Diags.Report(IncludeLoc, diag::err_cannot_open_file)
452  << FileName << EC.message();
453  }
454  return std::nullopt;
455  }
456 
457  // If there is a module that corresponds to this header, suggest it.
458  if (!findUsableModuleForHeader(
459  *File, Dir ? Dir : File->getFileEntry().getDir(), RequestingModule,
460  SuggestedModule, IsSystemHeaderDir))
461  return std::nullopt;
462 
463  return *File;
464 }
465 
466 /// LookupFile - Lookup the specified file in this search path, returning it
467 /// if it exists or returning null if not.
469  StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
470  SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
471  Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
472  bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
473  bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName,
474  bool OpenFile) const {
475  InUserSpecifiedSystemFramework = false;
476  IsInHeaderMap = false;
477  MappedName.clear();
478 
479  SmallString<1024> TmpDir;
480  if (isNormalDir()) {
481  // Concatenate the requested file onto the directory.
482  TmpDir = getDirRef()->getName();
483  llvm::sys::path::append(TmpDir, Filename);
484  if (SearchPath) {
485  StringRef SearchPathRef(getDirRef()->getName());
486  SearchPath->clear();
487  SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
488  }
489  if (RelativePath) {
490  RelativePath->clear();
491  RelativePath->append(Filename.begin(), Filename.end());
492  }
493 
494  return HS.getFileAndSuggestModule(
495  TmpDir, IncludeLoc, getDir(), isSystemHeaderDirectory(),
496  RequestingModule, SuggestedModule, OpenFile);
497  }
498 
499  if (isFramework())
500  return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
501  RequestingModule, SuggestedModule,
502  InUserSpecifiedSystemFramework, IsFrameworkFound);
503 
504  assert(isHeaderMap() && "Unknown directory lookup");
505  const HeaderMap *HM = getHeaderMap();
506  SmallString<1024> Path;
507  StringRef Dest = HM->lookupFilename(Filename, Path);
508  if (Dest.empty())
509  return std::nullopt;
510 
511  IsInHeaderMap = true;
512 
513  auto FixupSearchPathAndFindUsableModule =
515  if (SearchPath) {
516  StringRef SearchPathRef(getName());
517  SearchPath->clear();
518  SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
519  }
520  if (RelativePath) {
521  RelativePath->clear();
522  RelativePath->append(Filename.begin(), Filename.end());
523  }
524  if (!HS.findUsableModuleForHeader(File, File.getFileEntry().getDir(),
525  RequestingModule, SuggestedModule,
527  return std::nullopt;
528  }
529  return File;
530  };
531 
532  // Check if the headermap maps the filename to a framework include
533  // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
534  // framework include.
535  if (llvm::sys::path::is_relative(Dest)) {
536  MappedName.append(Dest.begin(), Dest.end());
537  Filename = StringRef(MappedName.begin(), MappedName.size());
538  Dest = HM->lookupFilename(Filename, Path);
539  }
540 
541  if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest, OpenFile)) {
542  return FixupSearchPathAndFindUsableModule(*Res);
543  }
544 
545  // Header maps need to be marked as used whenever the filename matches.
546  // The case where the target file **exists** is handled by callee of this
547  // function as part of the regular logic that applies to include search paths.
548  // The case where the target file **does not exist** is handled here:
549  HS.noteLookupUsage(HS.searchDirIdx(*this), IncludeLoc);
550  return std::nullopt;
551 }
552 
553 /// Given a framework directory, find the top-most framework directory.
554 ///
555 /// \param FileMgr The file manager to use for directory lookups.
556 /// \param DirName The name of the framework directory.
557 /// \param SubmodulePath Will be populated with the submodule path from the
558 /// returned top-level module to the originally named framework.
560 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
561  SmallVectorImpl<std::string> &SubmodulePath) {
562  assert(llvm::sys::path::extension(DirName) == ".framework" &&
563  "Not a framework directory");
564 
565  // Note: as an egregious but useful hack we use the real path here, because
566  // frameworks moving between top-level frameworks to embedded frameworks tend
567  // to be symlinked, and we base the logical structure of modules on the
568  // physical layout. In particular, we need to deal with crazy includes like
569  //
570  // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
571  //
572  // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
573  // which one should access with, e.g.,
574  //
575  // #include <Bar/Wibble.h>
576  //
577  // Similar issues occur when a top-level framework has moved into an
578  // embedded framework.
579  auto TopFrameworkDir = FileMgr.getOptionalDirectoryRef(DirName);
580 
581  if (TopFrameworkDir)
582  DirName = FileMgr.getCanonicalName(*TopFrameworkDir);
583  do {
584  // Get the parent directory name.
585  DirName = llvm::sys::path::parent_path(DirName);
586  if (DirName.empty())
587  break;
588 
589  // Determine whether this directory exists.
590  auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
591  if (!Dir)
592  break;
593 
594  // If this is a framework directory, then we're a subframework of this
595  // framework.
596  if (llvm::sys::path::extension(DirName) == ".framework") {
597  SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
598  TopFrameworkDir = *Dir;
599  }
600  } while (true);
601 
602  return TopFrameworkDir;
603 }
604 
605 static bool needModuleLookup(Module *RequestingModule,
606  bool HasSuggestedModule) {
607  return HasSuggestedModule ||
608  (RequestingModule && RequestingModule->NoUndeclaredIncludes);
609 }
610 
611 /// DoFrameworkLookup - Do a lookup of the specified file in the current
612 /// DirectoryLookup, which is a framework directory.
613 OptionalFileEntryRef DirectoryLookup::DoFrameworkLookup(
614  StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
615  SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
616  ModuleMap::KnownHeader *SuggestedModule,
617  bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
618  FileManager &FileMgr = HS.getFileMgr();
619 
620  // Framework names must have a '/' in the filename.
621  size_t SlashPos = Filename.find('/');
622  if (SlashPos == StringRef::npos)
623  return std::nullopt;
624 
625  // Find out if this is the home for the specified framework, by checking
626  // HeaderSearch. Possible answers are yes/no and unknown.
627  FrameworkCacheEntry &CacheEntry =
628  HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
629 
630  // If it is known and in some other directory, fail.
631  if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDirRef())
632  return std::nullopt;
633 
634  // Otherwise, construct the path to this framework dir.
635 
636  // FrameworkName = "/System/Library/Frameworks/"
637  SmallString<1024> FrameworkName;
638  FrameworkName += getFrameworkDirRef()->getName();
639  if (FrameworkName.empty() || FrameworkName.back() != '/')
640  FrameworkName.push_back('/');
641 
642  // FrameworkName = "/System/Library/Frameworks/Cocoa"
643  StringRef ModuleName(Filename.begin(), SlashPos);
644  FrameworkName += ModuleName;
645 
646  // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
647  FrameworkName += ".framework/";
648 
649  // If the cache entry was unresolved, populate it now.
650  if (!CacheEntry.Directory) {
651  ++NumFrameworkLookups;
652 
653  // If the framework dir doesn't exist, we fail.
654  auto Dir = FileMgr.getDirectory(FrameworkName);
655  if (!Dir)
656  return std::nullopt;
657 
658  // Otherwise, if it does, remember that this is the right direntry for this
659  // framework.
660  CacheEntry.Directory = getFrameworkDirRef();
661 
662  // If this is a user search directory, check if the framework has been
663  // user-specified as a system framework.
665  SmallString<1024> SystemFrameworkMarker(FrameworkName);
666  SystemFrameworkMarker += ".system_framework";
667  if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
668  CacheEntry.IsUserSpecifiedSystemFramework = true;
669  }
670  }
671  }
672 
673  // Set out flags.
674  InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
675  IsFrameworkFound = CacheEntry.Directory.has_value();
676 
677  if (RelativePath) {
678  RelativePath->clear();
679  RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
680  }
681 
682  // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
683  unsigned OrigSize = FrameworkName.size();
684 
685  FrameworkName += "Headers/";
686 
687  if (SearchPath) {
688  SearchPath->clear();
689  // Without trailing '/'.
690  SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
691  }
692 
693  FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
694 
695  auto File =
696  FileMgr.getOptionalFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
697  if (!File) {
698  // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
699  const char *Private = "Private";
700  FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
701  Private+strlen(Private));
702  if (SearchPath)
703  SearchPath->insert(SearchPath->begin()+OrigSize, Private,
704  Private+strlen(Private));
705 
706  File = FileMgr.getOptionalFileRef(FrameworkName,
707  /*OpenFile=*/!SuggestedModule);
708  }
709 
710  // If we found the header and are allowed to suggest a module, do so now.
711  if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
712  // Find the framework in which this header occurs.
713  StringRef FrameworkPath = File->getDir().getName();
714  bool FoundFramework = false;
715  do {
716  // Determine whether this directory exists.
717  auto Dir = FileMgr.getDirectory(FrameworkPath);
718  if (!Dir)
719  break;
720 
721  // If this is a framework directory, then we're a subframework of this
722  // framework.
723  if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
724  FoundFramework = true;
725  break;
726  }
727 
728  // Get the parent directory name.
729  FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
730  if (FrameworkPath.empty())
731  break;
732  } while (true);
733 
734  bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
735  if (FoundFramework) {
736  if (!HS.findUsableModuleForFrameworkHeader(*File, FrameworkPath,
737  RequestingModule,
738  SuggestedModule, IsSystem))
739  return std::nullopt;
740  } else {
741  if (!HS.findUsableModuleForHeader(*File, getDir(), RequestingModule,
742  SuggestedModule, IsSystem))
743  return std::nullopt;
744  }
745  }
746  if (File)
747  return *File;
748  return std::nullopt;
749 }
750 
751 void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
754  CacheLookup.HitIt = HitIt;
755  noteLookupUsage(HitIt.Idx, Loc);
756 }
757 
758 void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
759  SearchDirsUsage[HitIdx] = true;
760 
761  auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
762  if (UserEntryIdxIt != SearchDirToHSEntry.end())
763  Diags.Report(Loc, diag::remark_pp_search_path_usage)
764  << HSOpts->UserEntries[UserEntryIdxIt->second].Path;
765 }
766 
768  ModMap.setTarget(Target);
769 }
770 
771 //===----------------------------------------------------------------------===//
772 // Header File Location.
773 //===----------------------------------------------------------------------===//
774 
775 /// Return true with a diagnostic if the file that MSVC would have found
776 /// fails to match the one that Clang would have found with MSVC header search
777 /// disabled.
780  const FileEntry *FE,
781  SourceLocation IncludeLoc) {
782  if (MSFE && FE != *MSFE) {
783  Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
784  return true;
785  }
786  return false;
787 }
788 
789 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
790  assert(!Str.empty());
791  char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
792  std::copy(Str.begin(), Str.end(), CopyStr);
793  CopyStr[Str.size()] = '\0';
794  return CopyStr;
795 }
796 
797 static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader,
798  SmallVectorImpl<char> &FrameworkName,
799  SmallVectorImpl<char> &IncludeSpelling) {
800  using namespace llvm::sys;
801  path::const_iterator I = path::begin(Path);
802  path::const_iterator E = path::end(Path);
803  IsPrivateHeader = false;
804 
805  // Detect different types of framework style paths:
806  //
807  // ...Foo.framework/{Headers,PrivateHeaders}
808  // ...Foo.framework/Versions/{A,Current}/{Headers,PrivateHeaders}
809  // ...Foo.framework/Frameworks/Nested.framework/{Headers,PrivateHeaders}
810  // ...<other variations with 'Versions' like in the above path>
811  //
812  // and some other variations among these lines.
813  int FoundComp = 0;
814  while (I != E) {
815  if (*I == "Headers") {
816  ++FoundComp;
817  } else if (*I == "PrivateHeaders") {
818  ++FoundComp;
819  IsPrivateHeader = true;
820  } else if (I->ends_with(".framework")) {
821  StringRef Name = I->drop_back(10); // Drop .framework
822  // Need to reset the strings and counter to support nested frameworks.
823  FrameworkName.clear();
824  FrameworkName.append(Name.begin(), Name.end());
825  IncludeSpelling.clear();
826  IncludeSpelling.append(Name.begin(), Name.end());
827  FoundComp = 1;
828  } else if (FoundComp >= 2) {
829  IncludeSpelling.push_back('/');
830  IncludeSpelling.append(I->begin(), I->end());
831  }
832  ++I;
833  }
834 
835  return !FrameworkName.empty() && FoundComp >= 2;
836 }
837 
838 static void
840  StringRef Includer, StringRef IncludeFilename,
841  FileEntryRef IncludeFE, bool isAngled = false,
842  bool FoundByHeaderMap = false) {
843  bool IsIncluderPrivateHeader = false;
844  SmallString<128> FromFramework, ToFramework;
845  SmallString<128> FromIncludeSpelling, ToIncludeSpelling;
846  if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework,
847  FromIncludeSpelling))
848  return;
849  bool IsIncludeePrivateHeader = false;
850  bool IsIncludeeInFramework =
851  isFrameworkStylePath(IncludeFE.getName(), IsIncludeePrivateHeader,
852  ToFramework, ToIncludeSpelling);
853 
854  if (!isAngled && !FoundByHeaderMap) {
855  SmallString<128> NewInclude("<");
856  if (IsIncludeeInFramework) {
857  NewInclude += ToIncludeSpelling;
858  NewInclude += ">";
859  } else {
860  NewInclude += IncludeFilename;
861  NewInclude += ">";
862  }
863  Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
864  << IncludeFilename
865  << FixItHint::CreateReplacement(IncludeLoc, NewInclude);
866  }
867 
868  // Headers in Foo.framework/Headers should not include headers
869  // from Foo.framework/PrivateHeaders, since this violates public/private
870  // API boundaries and can cause modular dependency cycles.
871  if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
872  IsIncludeePrivateHeader && FromFramework == ToFramework)
873  Diags.Report(IncludeLoc, diag::warn_framework_include_private_from_public)
874  << IncludeFilename;
875 }
876 
877 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
878 /// return null on failure. isAngled indicates whether the file reference is
879 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
880 /// non-empty, indicates where the \#including file(s) are, in case a relative
881 /// search is needed. Microsoft mode will pass all \#including files.
883  StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
885  ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
886  SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
887  Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
888  bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
889  bool BuildSystemModule, bool OpenFile, bool CacheFailures) {
890  ConstSearchDirIterator CurDirLocal = nullptr;
891  ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
892 
893  if (IsMapped)
894  *IsMapped = false;
895 
896  if (IsFrameworkFound)
897  *IsFrameworkFound = false;
898 
899  if (SuggestedModule)
900  *SuggestedModule = ModuleMap::KnownHeader();
901 
902  // If 'Filename' is absolute, check to see if it exists and no searching.
903  if (llvm::sys::path::is_absolute(Filename)) {
904  CurDir = nullptr;
905 
906  // If this was an #include_next "/absolute/file", fail.
907  if (FromDir)
908  return std::nullopt;
909 
910  if (SearchPath)
911  SearchPath->clear();
912  if (RelativePath) {
913  RelativePath->clear();
914  RelativePath->append(Filename.begin(), Filename.end());
915  }
916  // Otherwise, just return the file.
917  return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
918  /*IsSystemHeaderDir*/ false,
919  RequestingModule, SuggestedModule, OpenFile,
920  CacheFailures);
921  }
922 
923  // This is the header that MSVC's header search would have found.
924  ModuleMap::KnownHeader MSSuggestedModule;
926 
927  // Check to see if the file is in the #includer's directory. This cannot be
928  // based on CurDir, because each includer could be a #include of a
929  // subdirectory (#include "foo/bar.h") and a subsequent include of "baz.h"
930  // should resolve to "whatever/foo/baz.h". This search is not done for <>
931  // headers.
932  if (!Includers.empty() && !isAngled) {
933  SmallString<1024> TmpDir;
934  bool First = true;
935  for (const auto &IncluderAndDir : Includers) {
936  OptionalFileEntryRef Includer = IncluderAndDir.first;
937 
938  // Concatenate the requested file onto the directory.
939  TmpDir = IncluderAndDir.second.getName();
940  llvm::sys::path::append(TmpDir, Filename);
941 
942  // FIXME: We don't cache the result of getFileInfo across the call to
943  // getFileAndSuggestModule, because it's a reference to an element of
944  // a container that could be reallocated across this call.
945  //
946  // If we have no includer, that means we're processing a #include
947  // from a module build. We should treat this as a system header if we're
948  // building a [system] module.
949  bool IncluderIsSystemHeader = [&]() {
950  if (!Includer)
951  return BuildSystemModule;
952  const HeaderFileInfo *HFI = getExistingFileInfo(*Includer);
953  assert(HFI && "includer without file info");
954  return HFI->DirInfo != SrcMgr::C_User;
955  }();
956  if (OptionalFileEntryRef FE = getFileAndSuggestModule(
957  TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
958  RequestingModule, SuggestedModule)) {
959  if (!Includer) {
960  assert(First && "only first includer can have no file");
961  return FE;
962  }
963 
964  // Leave CurDir unset.
965  // This file is a system header or C++ unfriendly if the old file is.
966  //
967  // Note that we only use one of FromHFI/ToHFI at once, due to potential
968  // reallocation of the underlying vector potentially making the first
969  // reference binding dangling.
970  const HeaderFileInfo *FromHFI = getExistingFileInfo(*Includer);
971  assert(FromHFI && "includer without file info");
972  unsigned DirInfo = FromHFI->DirInfo;
973  bool IndexHeaderMapHeader = FromHFI->IndexHeaderMapHeader;
974  StringRef Framework = FromHFI->Framework;
975 
976  HeaderFileInfo &ToHFI = getFileInfo(*FE);
977  ToHFI.DirInfo = DirInfo;
978  ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
979  ToHFI.Framework = Framework;
980 
981  if (SearchPath) {
982  StringRef SearchPathRef(IncluderAndDir.second.getName());
983  SearchPath->clear();
984  SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
985  }
986  if (RelativePath) {
987  RelativePath->clear();
988  RelativePath->append(Filename.begin(), Filename.end());
989  }
990  if (First) {
991  diagnoseFrameworkInclude(Diags, IncludeLoc,
992  IncluderAndDir.second.getName(), Filename,
993  *FE);
994  return FE;
995  }
996 
997  // Otherwise, we found the path via MSVC header search rules. If
998  // -Wmsvc-include is enabled, we have to keep searching to see if we
999  // would've found this header in -I or -isystem directories.
1000  if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1001  return FE;
1002  } else {
1003  MSFE = FE;
1004  if (SuggestedModule) {
1005  MSSuggestedModule = *SuggestedModule;
1006  *SuggestedModule = ModuleMap::KnownHeader();
1007  }
1008  break;
1009  }
1010  }
1011  First = false;
1012  }
1013  }
1014 
1015  CurDir = nullptr;
1016 
1017  // If this is a system #include, ignore the user #include locs.
1019  isAngled ? angled_dir_begin() : search_dir_begin();
1020 
1021  // If this is a #include_next request, start searching after the directory the
1022  // file was found in.
1023  if (FromDir)
1024  It = FromDir;
1025 
1026  // Cache all of the lookups performed by this method. Many headers are
1027  // multiply included, and the "pragma once" optimization prevents them from
1028  // being relex/pp'd, but they would still have to search through a
1029  // (potentially huge) series of SearchDirs to find it.
1030  LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1031 
1032  ConstSearchDirIterator NextIt = std::next(It);
1033 
1034  if (!SkipCache) {
1035  if (CacheLookup.StartIt == NextIt &&
1036  CacheLookup.RequestingModule == RequestingModule) {
1037  // HIT: Skip querying potentially lots of directories for this lookup.
1038  if (CacheLookup.HitIt)
1039  It = CacheLookup.HitIt;
1040  if (CacheLookup.MappedName) {
1041  Filename = CacheLookup.MappedName;
1042  if (IsMapped)
1043  *IsMapped = true;
1044  }
1045  } else {
1046  // MISS: This is the first query, or the previous query didn't match
1047  // our search start. We will fill in our found location below, so prime
1048  // the start point value.
1049  CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1050 
1051  if (It == search_dir_begin() && FirstNonHeaderMapSearchDirIdx > 0) {
1052  // Handle cold misses of user includes in the presence of many header
1053  // maps. We avoid searching perhaps thousands of header maps by
1054  // jumping directly to the correct one or jumping beyond all of them.
1055  auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1056  if (Iter == SearchDirHeaderMapIndex.end())
1057  // Not in index => Skip to first SearchDir after initial header maps
1058  It = search_dir_nth(FirstNonHeaderMapSearchDirIdx);
1059  else
1060  // In index => Start with a specific header map
1061  It = search_dir_nth(Iter->second);
1062  }
1063  }
1064  } else {
1065  CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1066  }
1067 
1068  SmallString<64> MappedName;
1069 
1070  // Check each directory in sequence to see if it contains this file.
1071  for (; It != search_dir_end(); ++It) {
1072  bool InUserSpecifiedSystemFramework = false;
1073  bool IsInHeaderMap = false;
1074  bool IsFrameworkFoundInDir = false;
1075  OptionalFileEntryRef File = It->LookupFile(
1076  Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1077  SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1078  IsInHeaderMap, MappedName, OpenFile);
1079  if (!MappedName.empty()) {
1080  assert(IsInHeaderMap && "MappedName should come from a header map");
1081  CacheLookup.MappedName =
1082  copyString(MappedName, LookupFileCache.getAllocator());
1083  }
1084  if (IsMapped)
1085  // A filename is mapped when a header map remapped it to a relative path
1086  // used in subsequent header search or to an absolute path pointing to an
1087  // existing file.
1088  *IsMapped |= (!MappedName.empty() || (IsInHeaderMap && File));
1089  if (IsFrameworkFound)
1090  // Because we keep a filename remapped for subsequent search directory
1091  // lookups, ignore IsFrameworkFoundInDir after the first remapping and not
1092  // just for remapping in a current search directory.
1093  *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1094  if (!File)
1095  continue;
1096 
1097  CurDir = It;
1098 
1099  IncludeNames[*File] = Filename;
1100 
1101  // This file is a system header or C++ unfriendly if the dir is.
1102  HeaderFileInfo &HFI = getFileInfo(*File);
1103  HFI.DirInfo = CurDir->getDirCharacteristic();
1104 
1105  // If the directory characteristic is User but this framework was
1106  // user-specified to be treated as a system framework, promote the
1107  // characteristic.
1108  if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
1109  HFI.DirInfo = SrcMgr::C_System;
1110 
1111  // If the filename matches a known system header prefix, override
1112  // whether the file is a system header.
1113  for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1114  if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1115  HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
1116  : SrcMgr::C_User;
1117  break;
1118  }
1119  }
1120 
1121  // Set the `Framework` info if this file is in a header map with framework
1122  // style include spelling or found in a framework dir. The header map case
1123  // is possible when building frameworks which use header maps.
1124  if (CurDir->isHeaderMap() && isAngled) {
1125  size_t SlashPos = Filename.find('/');
1126  if (SlashPos != StringRef::npos)
1127  HFI.Framework =
1128  getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos));
1129  if (CurDir->isIndexHeaderMap())
1130  HFI.IndexHeaderMapHeader = 1;
1131  } else if (CurDir->isFramework()) {
1132  size_t SlashPos = Filename.find('/');
1133  if (SlashPos != StringRef::npos)
1134  HFI.Framework =
1135  getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos));
1136  }
1137 
1138  if (checkMSVCHeaderSearch(Diags, MSFE, &File->getFileEntry(), IncludeLoc)) {
1139  if (SuggestedModule)
1140  *SuggestedModule = MSSuggestedModule;
1141  return MSFE;
1142  }
1143 
1144  bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
1145  if (!Includers.empty())
1146  diagnoseFrameworkInclude(Diags, IncludeLoc,
1147  Includers.front().second.getName(), Filename,
1148  *File, isAngled, FoundByHeaderMap);
1149 
1150  // Remember this location for the next lookup we do.
1151  cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1152  return File;
1153  }
1154 
1155  // If we are including a file with a quoted include "foo.h" from inside
1156  // a header in a framework that is currently being built, and we couldn't
1157  // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
1158  // "Foo" is the name of the framework in which the including header was found.
1159  if (!Includers.empty() && Includers.front().first && !isAngled &&
1160  !Filename.contains('/')) {
1161  const HeaderFileInfo *IncludingHFI =
1162  getExistingFileInfo(*Includers.front().first);
1163  assert(IncludingHFI && "includer without file info");
1164  if (IncludingHFI->IndexHeaderMapHeader) {
1165  SmallString<128> ScratchFilename;
1166  ScratchFilename += IncludingHFI->Framework;
1167  ScratchFilename += '/';
1168  ScratchFilename += Filename;
1169 
1171  ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, &CurDir,
1172  Includers.front(), SearchPath, RelativePath, RequestingModule,
1173  SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr);
1174 
1175  if (checkMSVCHeaderSearch(Diags, MSFE,
1176  File ? &File->getFileEntry() : nullptr,
1177  IncludeLoc)) {
1178  if (SuggestedModule)
1179  *SuggestedModule = MSSuggestedModule;
1180  return MSFE;
1181  }
1182 
1183  cacheLookupSuccess(LookupFileCache[Filename],
1184  LookupFileCache[ScratchFilename].HitIt, IncludeLoc);
1185  // FIXME: SuggestedModule.
1186  return File;
1187  }
1188  }
1189 
1190  if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
1191  if (SuggestedModule)
1192  *SuggestedModule = MSSuggestedModule;
1193  return MSFE;
1194  }
1195 
1196  // Otherwise, didn't find it. Remember we didn't find this.
1197  CacheLookup.HitIt = search_dir_end();
1198  return std::nullopt;
1199 }
1200 
1201 /// LookupSubframeworkHeader - Look up a subframework for the specified
1202 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
1203 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
1204 /// is a subframework within Carbon.framework. If so, return the FileEntry
1205 /// for the designated file, otherwise return null.
1207  StringRef Filename, FileEntryRef ContextFileEnt,
1208  SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
1209  Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {
1210  // Framework names must have a '/' in the filename. Find it.
1211  // FIXME: Should we permit '\' on Windows?
1212  size_t SlashPos = Filename.find('/');
1213  if (SlashPos == StringRef::npos)
1214  return std::nullopt;
1215 
1216  // Look up the base framework name of the ContextFileEnt.
1217  StringRef ContextName = ContextFileEnt.getName();
1218 
1219  // If the context info wasn't a framework, couldn't be a subframework.
1220  const unsigned DotFrameworkLen = 10;
1221  auto FrameworkPos = ContextName.find(".framework");
1222  if (FrameworkPos == StringRef::npos ||
1223  (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1224  ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1225  return std::nullopt;
1226 
1227  SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1228  FrameworkPos +
1229  DotFrameworkLen + 1);
1230 
1231  // Append Frameworks/HIToolbox.framework/
1232  FrameworkName += "Frameworks/";
1233  FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1234  FrameworkName += ".framework/";
1235 
1236  auto &CacheLookup =
1237  *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1238  FrameworkCacheEntry())).first;
1239 
1240  // Some other location?
1241  if (CacheLookup.second.Directory &&
1242  CacheLookup.first().size() == FrameworkName.size() &&
1243  memcmp(CacheLookup.first().data(), &FrameworkName[0],
1244  CacheLookup.first().size()) != 0)
1245  return std::nullopt;
1246 
1247  // Cache subframework.
1248  if (!CacheLookup.second.Directory) {
1249  ++NumSubFrameworkLookups;
1250 
1251  // If the framework dir doesn't exist, we fail.
1252  auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1253  if (!Dir)
1254  return std::nullopt;
1255 
1256  // Otherwise, if it does, remember that this is the right direntry for this
1257  // framework.
1258  CacheLookup.second.Directory = Dir;
1259  }
1260 
1261 
1262  if (RelativePath) {
1263  RelativePath->clear();
1264  RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1265  }
1266 
1267  // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
1268  SmallString<1024> HeadersFilename(FrameworkName);
1269  HeadersFilename += "Headers/";
1270  if (SearchPath) {
1271  SearchPath->clear();
1272  // Without trailing '/'.
1273  SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1274  }
1275 
1276  HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1277  auto File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1278  if (!File) {
1279  // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
1280  HeadersFilename = FrameworkName;
1281  HeadersFilename += "PrivateHeaders/";
1282  if (SearchPath) {
1283  SearchPath->clear();
1284  // Without trailing '/'.
1285  SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1286  }
1287 
1288  HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1289  File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1290 
1291  if (!File)
1292  return std::nullopt;
1293  }
1294 
1295  // This file is a system header or C++ unfriendly if the old file is.
1296  const HeaderFileInfo *ContextHFI = getExistingFileInfo(ContextFileEnt);
1297  assert(ContextHFI && "context file without file info");
1298  // Note that the temporary 'DirInfo' is required here, as the call to
1299  // getFileInfo could resize the vector and might invalidate 'ContextHFI'.
1300  unsigned DirInfo = ContextHFI->DirInfo;
1301  getFileInfo(*File).DirInfo = DirInfo;
1302 
1303  FrameworkName.pop_back(); // remove the trailing '/'
1304  if (!findUsableModuleForFrameworkHeader(*File, FrameworkName,
1305  RequestingModule, SuggestedModule,
1306  /*IsSystem*/ false))
1307  return std::nullopt;
1308 
1309  return *File;
1310 }
1311 
1312 //===----------------------------------------------------------------------===//
1313 // File Info Management.
1314 //===----------------------------------------------------------------------===//
1315 
1317  bool isModuleHeader,
1318  bool isTextualModuleHeader) {
1319  assert((!isModuleHeader || !isTextualModuleHeader) &&
1320  "A header can't build with a module and be textual at the same time");
1321  HFI.isModuleHeader |= isModuleHeader;
1322  if (HFI.isModuleHeader)
1323  HFI.isTextualModuleHeader = false;
1324  else
1325  HFI.isTextualModuleHeader |= isTextualModuleHeader;
1326 }
1327 
1330  (Role & ModuleMap::TextualHeader));
1331 }
1332 
1333 /// Merge the header file info provided by \p OtherHFI into the current
1334 /// header file info (\p HFI)
1336  const HeaderFileInfo &OtherHFI) {
1337  assert(OtherHFI.External && "expected to merge external HFI");
1338 
1339  HFI.isImport |= OtherHFI.isImport;
1340  HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
1342  OtherHFI.isTextualModuleHeader);
1343 
1344  if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
1345  HFI.ControllingMacro = OtherHFI.ControllingMacro;
1346  HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
1347  }
1348 
1349  HFI.DirInfo = OtherHFI.DirInfo;
1350  HFI.External = (!HFI.IsValid || HFI.External);
1351  HFI.IsValid = true;
1353 
1354  if (HFI.Framework.empty())
1355  HFI.Framework = OtherHFI.Framework;
1356 }
1357 
1359  if (FE.getUID() >= FileInfo.size())
1360  FileInfo.resize(FE.getUID() + 1);
1361 
1362  HeaderFileInfo *HFI = &FileInfo[FE.getUID()];
1363  // FIXME: Use a generation count to check whether this is really up to date.
1364  if (ExternalSource && !HFI->Resolved) {
1365  auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1366  if (ExternalHFI.IsValid) {
1367  HFI->Resolved = true;
1368  if (ExternalHFI.External)
1369  mergeHeaderFileInfo(*HFI, ExternalHFI);
1370  }
1371  }
1372 
1373  HFI->IsValid = true;
1374  // We assume the caller has local information about this header file, so it's
1375  // no longer strictly external.
1376  HFI->External = false;
1377  return *HFI;
1378 }
1379 
1381  HeaderFileInfo *HFI;
1382  if (ExternalSource) {
1383  if (FE.getUID() >= FileInfo.size())
1384  FileInfo.resize(FE.getUID() + 1);
1385 
1386  HFI = &FileInfo[FE.getUID()];
1387  // FIXME: Use a generation count to check whether this is really up to date.
1388  if (!HFI->Resolved) {
1389  auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1390  if (ExternalHFI.IsValid) {
1391  HFI->Resolved = true;
1392  if (ExternalHFI.External)
1393  mergeHeaderFileInfo(*HFI, ExternalHFI);
1394  }
1395  }
1396  } else if (FE.getUID() < FileInfo.size()) {
1397  HFI = &FileInfo[FE.getUID()];
1398  } else {
1399  HFI = nullptr;
1400  }
1401 
1402  return (HFI && HFI->IsValid) ? HFI : nullptr;
1403 }
1404 
1405 const HeaderFileInfo *
1407  HeaderFileInfo *HFI;
1408  if (FE.getUID() < FileInfo.size()) {
1409  HFI = &FileInfo[FE.getUID()];
1410  } else {
1411  HFI = nullptr;
1412  }
1413 
1414  return (HFI && HFI->IsValid && !HFI->External) ? HFI : nullptr;
1415 }
1416 
1418  // Check if we've entered this file and found an include guard or #pragma
1419  // once. Note that we dor't check for #import, because that's not a property
1420  // of the file itself.
1421  if (auto *HFI = getExistingFileInfo(File))
1422  return HFI->isPragmaOnce || HFI->ControllingMacro ||
1423  HFI->ControllingMacroID;
1424  return false;
1425 }
1426 
1429  bool isCompilingModuleHeader) {
1430  // Don't mark the file info as non-external if there's nothing to change.
1431  if (!isCompilingModuleHeader) {
1432  if ((Role & ModuleMap::ExcludedHeader))
1433  return;
1434  auto *HFI = getExistingFileInfo(FE);
1435  if (HFI && HFI->isModuleHeader)
1436  return;
1437  }
1438 
1439  auto &HFI = getFileInfo(FE);
1440  HFI.mergeModuleMembership(Role);
1441  HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1442 }
1443 
1445  FileEntryRef File, bool isImport,
1446  bool ModulesEnabled, Module *M,
1447  bool &IsFirstIncludeOfFile) {
1448  // An include file should be entered if either:
1449  // 1. This is the first include of the file.
1450  // 2. This file can be included multiple times, that is it's not an
1451  // "include-once" file.
1452  //
1453  // Include-once is controlled by these preprocessor directives.
1454  //
1455  // #pragma once
1456  // This directive is in the include file, and marks it as an include-once
1457  // file.
1458  //
1459  // #import <file>
1460  // This directive is in the includer, and indicates that the include file
1461  // should only be entered if this is the first include.
1462  ++NumIncluded;
1463  IsFirstIncludeOfFile = false;
1464  HeaderFileInfo &FileInfo = getFileInfo(File);
1465 
1466  auto MaybeReenterImportedFile = [&]() -> bool {
1467  // Modules add a wrinkle though: what's included isn't necessarily visible.
1468  // Consider this module.
1469  // module Example {
1470  // module A { header "a.h" export * }
1471  // module B { header "b.h" export * }
1472  // }
1473  // b.h includes c.h. The main file includes a.h, which will trigger a module
1474  // build of Example, and c.h will be included. However, c.h isn't visible to
1475  // the main file. Normally this is fine, the main file can just include c.h
1476  // if it needs it. If c.h is in a module, the include will translate into a
1477  // module import, this function will be skipped, and everything will work as
1478  // expected. However, if c.h is not in a module (or is `textual`), then this
1479  // function will run. If c.h is include-once, it will not be entered from
1480  // the main file and it will still not be visible.
1481 
1482  // If modules aren't enabled then there's no visibility issue. Always
1483  // respect `#pragma once`.
1484  if (!ModulesEnabled || FileInfo.isPragmaOnce)
1485  return false;
1486 
1487  // Ensure FileInfo bits are up to date.
1488  ModMap.resolveHeaderDirectives(File);
1489 
1490  // This brings up a subtlety of #import - it's not a very good indicator of
1491  // include-once. Developers are often unaware of the difference between
1492  // #include and #import, and tend to use one or the other indiscrimiately.
1493  // In order to support #include on include-once headers that lack macro
1494  // guards and `#pragma once` (which is the vast majority of Objective-C
1495  // headers), if a file is ever included with #import, it's marked as
1496  // isImport in the HeaderFileInfo and treated as include-once. This allows
1497  // #include to work in Objective-C.
1498  // #include <Foundation/Foundation.h>
1499  // #include <Foundation/NSString.h>
1500  // Foundation.h has an #import of NSString.h, and so the second #include is
1501  // skipped even though NSString.h has no `#pragma once` and no macro guard.
1502  //
1503  // However, this helpfulness causes problems with modules. If c.h is not an
1504  // include-once file, but something included it with #import anyway (as is
1505  // typical in Objective-C code), this include will be skipped and c.h will
1506  // not be visible. Consider it not include-once if it is a `textual` header
1507  // in a module.
1508  if (FileInfo.isTextualModuleHeader)
1509  return true;
1510 
1511  if (FileInfo.isCompilingModuleHeader) {
1512  // It's safer to re-enter a file whose module is being built because its
1513  // declarations will still be scoped to a single module.
1514  if (FileInfo.isModuleHeader) {
1515  // Headers marked as "builtin" are covered by the system module maps
1516  // rather than the builtin ones. Some versions of the Darwin module fail
1517  // to mark stdarg.h and stddef.h as textual. Attempt to re-enter these
1518  // files while building their module to allow them to function properly.
1519  if (ModMap.isBuiltinHeader(File))
1520  return true;
1521  } else {
1522  // Files that are excluded from their module can potentially be
1523  // re-entered from their own module. This might cause redeclaration
1524  // errors if another module saw this file first, but there's a
1525  // reasonable chance that its module will build first. However if
1526  // there's no controlling macro, then trust the #import and assume this
1527  // really is an include-once file.
1528  if (FileInfo.getControllingMacro(ExternalLookup))
1529  return true;
1530  }
1531  }
1532  // If the include file has a macro guard, then it might still not be
1533  // re-entered if the controlling macro is visibly defined. e.g. another
1534  // header in the module being built included this file and local submodule
1535  // visibility is not enabled.
1536 
1537  // It might be tempting to re-enter the include-once file if it's not
1538  // visible in an attempt to make it visible. However this will still cause
1539  // redeclaration errors against the known-but-not-visible declarations. The
1540  // include file not being visible will most likely cause "undefined x"
1541  // errors, but at least there's a slim chance of compilation succeeding.
1542  return false;
1543  };
1544 
1545  if (isImport) {
1546  // As discussed above, record that this file was ever `#import`ed, and treat
1547  // it as an include-once file from here out.
1548  FileInfo.isImport = true;
1549  if (PP.alreadyIncluded(File) && !MaybeReenterImportedFile())
1550  return false;
1551  } else {
1552  // isPragmaOnce and isImport are only set after the file has been included
1553  // at least once. If either are set then this is a repeat #include of an
1554  // include-once file.
1555  if (FileInfo.isPragmaOnce ||
1556  (FileInfo.isImport && !MaybeReenterImportedFile()))
1557  return false;
1558  }
1559 
1560  // As a final optimization, check for a macro guard and skip entering the file
1561  // if the controlling macro is defined. The macro guard will effectively erase
1562  // the file's contents, and the include would have no effect other than to
1563  // waste time opening and reading a file.
1564  if (const IdentifierInfo *ControllingMacro =
1565  FileInfo.getControllingMacro(ExternalLookup)) {
1566  // If the header corresponds to a module, check whether the macro is already
1567  // defined in that module rather than checking all visible modules. This is
1568  // mainly to cover corner cases where the same controlling macro is used in
1569  // different files in multiple modules.
1570  if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1571  : PP.isMacroDefined(ControllingMacro)) {
1572  ++NumMultiIncludeFileOptzn;
1573  return false;
1574  }
1575  }
1576 
1577  FileInfo.IsLocallyIncluded = true;
1578  IsFirstIncludeOfFile = PP.markIncluded(File);
1579  return true;
1580 }
1581 
1583  return SearchDirs.capacity()
1584  + llvm::capacity_in_bytes(FileInfo)
1585  + llvm::capacity_in_bytes(HeaderMaps)
1586  + LookupFileCache.getAllocator().getTotalMemory()
1587  + FrameworkMap.getAllocator().getTotalMemory();
1588 }
1589 
1590 unsigned HeaderSearch::searchDirIdx(const DirectoryLookup &DL) const {
1591  return &DL - &*SearchDirs.begin();
1592 }
1593 
1594 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1595  return FrameworkNames.insert(Framework).first->first();
1596 }
1597 
1598 StringRef HeaderSearch::getIncludeNameForHeader(const FileEntry *File) const {
1599  auto It = IncludeNames.find(File);
1600  if (It == IncludeNames.end())
1601  return {};
1602  return It->second;
1603 }
1604 
1605 bool HeaderSearch::hasModuleMap(StringRef FileName,
1606  const DirectoryEntry *Root,
1607  bool IsSystem) {
1608  if (!HSOpts->ImplicitModuleMaps)
1609  return false;
1610 
1611  SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
1612 
1613  StringRef DirName = FileName;
1614  do {
1615  // Get the parent directory name.
1616  DirName = llvm::sys::path::parent_path(DirName);
1617  if (DirName.empty())
1618  return false;
1619 
1620  // Determine whether this directory exists.
1621  auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1622  if (!Dir)
1623  return false;
1624 
1625  // Try to load the module map file in this directory.
1626  switch (loadModuleMapFile(*Dir, IsSystem,
1627  llvm::sys::path::extension(Dir->getName()) ==
1628  ".framework")) {
1629  case LMM_NewlyLoaded:
1630  case LMM_AlreadyLoaded:
1631  // Success. All of the directories we stepped through inherit this module
1632  // map file.
1633  for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1634  DirectoryHasModuleMap[FixUpDirectories[I]] = true;
1635  return true;
1636 
1637  case LMM_NoDirectory:
1638  case LMM_InvalidModuleMap:
1639  break;
1640  }
1641 
1642  // If we hit the top of our search, we're done.
1643  if (*Dir == Root)
1644  return false;
1645 
1646  // Keep track of all of the directories we checked, so we can mark them as
1647  // having module maps if we eventually do find a module map.
1648  FixUpDirectories.push_back(*Dir);
1649  } while (true);
1650 }
1651 
1654  bool AllowExcluded) const {
1655  if (ExternalSource) {
1656  // Make sure the external source has handled header info about this file,
1657  // which includes whether the file is part of a module.
1658  (void)getExistingFileInfo(File);
1659  }
1660  return ModMap.findModuleForHeader(File, AllowTextual, AllowExcluded);
1661 }
1662 
1665  if (ExternalSource) {
1666  // Make sure the external source has handled header info about this file,
1667  // which includes whether the file is part of a module.
1668  (void)getExistingFileInfo(File);
1669  }
1670  return ModMap.findAllModulesForHeader(File);
1671 }
1672 
1675  if (ExternalSource) {
1676  // Make sure the external source has handled header info about this file,
1677  // which includes whether the file is part of a module.
1678  (void)getExistingFileInfo(File);
1679  }
1680  return ModMap.findResolvedModulesForHeader(File);
1681 }
1682 
1684  Module *RequestingModule,
1685  ModuleMap::KnownHeader *SuggestedModule) {
1687  HS.findModuleForHeader(File, /*AllowTextual*/true);
1688 
1689  // If this module specifies [no_undeclared_includes], we cannot find any
1690  // file that's in a non-dependency module.
1691  if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
1692  HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false);
1693  if (!RequestingModule->directlyUses(Module.getModule())) {
1694  // Builtin headers are a special case. Multiple modules can use the same
1695  // builtin as a modular header (see also comment in
1696  // ShouldEnterIncludeFile()), so the builtin header may have been
1697  // "claimed" by an unrelated module. This shouldn't prevent us from
1698  // including the builtin header textually in this module.
1699  if (HS.getModuleMap().isBuiltinHeader(File)) {
1700  if (SuggestedModule)
1701  *SuggestedModule = ModuleMap::KnownHeader();
1702  return true;
1703  }
1704  // TODO: Add this module (or just its module map file) into something like
1705  // `RequestingModule->AffectingClangModules`.
1706  return false;
1707  }
1708  }
1709 
1710  if (SuggestedModule)
1711  *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
1713  : Module;
1714 
1715  return true;
1716 }
1717 
1718 bool HeaderSearch::findUsableModuleForHeader(
1719  FileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule,
1720  ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1721  if (needModuleLookup(RequestingModule, SuggestedModule)) {
1722  // If there is a module that corresponds to this header, suggest it.
1723  hasModuleMap(File.getNameAsRequested(), Root, IsSystemHeaderDir);
1724  return suggestModule(*this, File, RequestingModule, SuggestedModule);
1725  }
1726  return true;
1727 }
1728 
1729 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1730  FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
1731  ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1732  // If we're supposed to suggest a module, look for one now.
1733  if (needModuleLookup(RequestingModule, SuggestedModule)) {
1734  // Find the top-level framework based on this framework.
1735  SmallVector<std::string, 4> SubmodulePath;
1736  OptionalDirectoryEntryRef TopFrameworkDir =
1737  ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1738  assert(TopFrameworkDir && "Could not find the top-most framework dir");
1739 
1740  // Determine the name of the top-level framework.
1741  StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1742 
1743  // Load this framework module. If that succeeds, find the suggested module
1744  // for this header, if any.
1745  loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1746 
1747  // FIXME: This can find a module not part of ModuleName, which is
1748  // important so that we're consistent about whether this header
1749  // corresponds to a module. Possibly we should lock down framework modules
1750  // so that this is not possible.
1751  return suggestModule(*this, File, RequestingModule, SuggestedModule);
1752  }
1753  return true;
1754 }
1755 
1757  FileManager &FileMgr,
1758  DiagnosticsEngine &Diags) {
1759  StringRef Filename = llvm::sys::path::filename(File.getName());
1760  SmallString<128> PrivateFilename(File.getDir().getName());
1761  if (Filename == "module.map")
1762  llvm::sys::path::append(PrivateFilename, "module_private.map");
1763  else if (Filename == "module.modulemap")
1764  llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1765  else
1766  return std::nullopt;
1767  auto PMMFile = FileMgr.getOptionalFileRef(PrivateFilename);
1768  if (PMMFile) {
1769  if (Filename == "module.map")
1770  Diags.Report(diag::warn_deprecated_module_dot_map)
1771  << PrivateFilename << 1
1772  << File.getDir().getName().ends_with(".framework");
1773  }
1774  return PMMFile;
1775 }
1776 
1778  FileID ID, unsigned *Offset,
1779  StringRef OriginalModuleMapFile) {
1780  // Find the directory for the module. For frameworks, that may require going
1781  // up from the 'Modules' directory.
1783  if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
1784  Dir = FileMgr.getOptionalDirectoryRef(".");
1785  } else {
1786  if (!OriginalModuleMapFile.empty()) {
1787  // We're building a preprocessed module map. Find or invent the directory
1788  // that it originally occupied.
1789  Dir = FileMgr.getOptionalDirectoryRef(
1790  llvm::sys::path::parent_path(OriginalModuleMapFile));
1791  if (!Dir) {
1792  auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1793  Dir = FakeFile.getDir();
1794  }
1795  } else {
1796  Dir = File.getDir();
1797  }
1798 
1799  assert(Dir && "parent must exist");
1800  StringRef DirName(Dir->getName());
1801  if (llvm::sys::path::filename(DirName) == "Modules") {
1802  DirName = llvm::sys::path::parent_path(DirName);
1803  if (DirName.ends_with(".framework"))
1804  if (auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
1805  Dir = *MaybeDir;
1806  // FIXME: This assert can fail if there's a race between the above check
1807  // and the removal of the directory.
1808  assert(Dir && "parent must exist");
1809  }
1810  }
1811 
1812  assert(Dir && "module map home directory must exist");
1813  switch (loadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) {
1814  case LMM_AlreadyLoaded:
1815  case LMM_NewlyLoaded:
1816  return false;
1817  case LMM_NoDirectory:
1818  case LMM_InvalidModuleMap:
1819  return true;
1820  }
1821  llvm_unreachable("Unknown load module map result");
1822 }
1823 
1824 HeaderSearch::LoadModuleMapResult
1825 HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
1827  unsigned *Offset) {
1828  // Check whether we've already loaded this module map, and mark it as being
1829  // loaded in case we recursively try to load it from itself.
1830  auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1831  if (!AddResult.second)
1832  return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1833 
1834  if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1835  LoadedModuleMaps[File] = false;
1836  return LMM_InvalidModuleMap;
1837  }
1838 
1839  // Try to load a corresponding private module map.
1840  if (OptionalFileEntryRef PMMFile =
1841  getPrivateModuleMap(File, FileMgr, Diags)) {
1842  if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, Dir)) {
1843  LoadedModuleMaps[File] = false;
1844  return LMM_InvalidModuleMap;
1845  }
1846  }
1847 
1848  // This directory has a module map.
1849  return LMM_NewlyLoaded;
1850 }
1851 
1854  if (!HSOpts->ImplicitModuleMaps)
1855  return std::nullopt;
1856  // For frameworks, the preferred spelling is Modules/module.modulemap, but
1857  // module.map at the framework root is also accepted.
1858  SmallString<128> ModuleMapFileName(Dir.getName());
1859  if (IsFramework)
1860  llvm::sys::path::append(ModuleMapFileName, "Modules");
1861  llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1862  if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1863  return *F;
1864 
1865  // Continue to allow module.map, but warn it's deprecated.
1866  ModuleMapFileName = Dir.getName();
1867  llvm::sys::path::append(ModuleMapFileName, "module.map");
1868  if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
1869  Diags.Report(diag::warn_deprecated_module_dot_map)
1870  << ModuleMapFileName << 0 << IsFramework;
1871  return *F;
1872  }
1873 
1874  // For frameworks, allow to have a private module map with a preferred
1875  // spelling when a public module map is absent.
1876  if (IsFramework) {
1877  ModuleMapFileName = Dir.getName();
1878  llvm::sys::path::append(ModuleMapFileName, "Modules",
1879  "module.private.modulemap");
1880  if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1881  return *F;
1882  }
1883  return std::nullopt;
1884 }
1885 
1886 Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
1887  bool IsSystem) {
1888  // Try to load a module map file.
1889  switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
1890  case LMM_InvalidModuleMap:
1891  // Try to infer a module map from the framework directory.
1892  if (HSOpts->ImplicitModuleMaps)
1893  ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1894  break;
1895 
1896  case LMM_NoDirectory:
1897  return nullptr;
1898 
1899  case LMM_AlreadyLoaded:
1900  case LMM_NewlyLoaded:
1901  break;
1902  }
1903 
1904  return ModMap.findModule(Name);
1905 }
1906 
1907 HeaderSearch::LoadModuleMapResult
1908 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
1909  bool IsFramework) {
1910  if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
1911  return loadModuleMapFile(*Dir, IsSystem, IsFramework);
1912 
1913  return LMM_NoDirectory;
1914 }
1915 
1916 HeaderSearch::LoadModuleMapResult
1918  bool IsFramework) {
1919  auto KnownDir = DirectoryHasModuleMap.find(Dir);
1920  if (KnownDir != DirectoryHasModuleMap.end())
1921  return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1922 
1923  if (OptionalFileEntryRef ModuleMapFile =
1924  lookupModuleMapFile(Dir, IsFramework)) {
1925  LoadModuleMapResult Result =
1926  loadModuleMapFileImpl(*ModuleMapFile, IsSystem, Dir);
1927  // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1928  // E.g. Foo.framework/Modules/module.modulemap
1929  // ^Dir ^ModuleMapFile
1930  if (Result == LMM_NewlyLoaded)
1931  DirectoryHasModuleMap[Dir] = true;
1932  else if (Result == LMM_InvalidModuleMap)
1933  DirectoryHasModuleMap[Dir] = false;
1934  return Result;
1935  }
1936  return LMM_InvalidModuleMap;
1937 }
1938 
1940  Modules.clear();
1941 
1942  if (HSOpts->ImplicitModuleMaps) {
1943  // Load module maps for each of the header search directories.
1944  for (DirectoryLookup &DL : search_dir_range()) {
1945  bool IsSystem = DL.isSystemHeaderDirectory();
1946  if (DL.isFramework()) {
1947  std::error_code EC;
1948  SmallString<128> DirNative;
1949  llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
1950 
1951  // Search each of the ".framework" directories to load them as modules.
1952  llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1953  for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1954  DirEnd;
1955  Dir != DirEnd && !EC; Dir.increment(EC)) {
1956  if (llvm::sys::path::extension(Dir->path()) != ".framework")
1957  continue;
1958 
1959  auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
1960  if (!FrameworkDir)
1961  continue;
1962 
1963  // Load this framework module.
1964  loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1965  IsSystem);
1966  }
1967  continue;
1968  }
1969 
1970  // FIXME: Deal with header maps.
1971  if (DL.isHeaderMap())
1972  continue;
1973 
1974  // Try to load a module map file for the search directory.
1975  loadModuleMapFile(*DL.getDirRef(), IsSystem, /*IsFramework*/ false);
1976 
1977  // Try to load module map files for immediate subdirectories of this
1978  // search directory.
1979  loadSubdirectoryModuleMaps(DL);
1980  }
1981  }
1982 
1983  // Populate the list of modules.
1984  llvm::transform(ModMap.modules(), std::back_inserter(Modules),
1985  [](const auto &NameAndMod) { return NameAndMod.second; });
1986 }
1987 
1989  if (!HSOpts->ImplicitModuleMaps)
1990  return;
1991 
1992  // Load module maps for each of the header search directories.
1993  for (const DirectoryLookup &DL : search_dir_range()) {
1994  // We only care about normal header directories.
1995  if (!DL.isNormalDir())
1996  continue;
1997 
1998  // Try to load a module map file for the search directory.
1999  loadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(),
2000  DL.isFramework());
2001  }
2002 }
2003 
2004 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
2005  assert(HSOpts->ImplicitModuleMaps &&
2006  "Should not be loading subdirectory module maps");
2007 
2008  if (SearchDir.haveSearchedAllModuleMaps())
2009  return;
2010 
2011  std::error_code EC;
2012  SmallString<128> Dir = SearchDir.getDirRef()->getName();
2013  FileMgr.makeAbsolutePath(Dir);
2014  SmallString<128> DirNative;
2015  llvm::sys::path::native(Dir, DirNative);
2016  llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2017  for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2018  Dir != DirEnd && !EC; Dir.increment(EC)) {
2019  if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2020  continue;
2021  bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
2022  if (IsFramework == SearchDir.isFramework())
2023  loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
2024  SearchDir.isFramework());
2025  }
2026 
2027  SearchDir.setSearchedAllModuleMaps(true);
2028 }
2029 
2031  FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled) const {
2032  return suggestPathToFileForDiagnostics(File.getName(), /*WorkingDir=*/"",
2033  MainFile, IsAngled);
2034 }
2035 
2037  llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2038  bool *IsAngled) const {
2039  using namespace llvm::sys;
2040 
2041  llvm::SmallString<32> FilePath = File;
2042  // remove_dots switches to backslashes on windows as a side-effect!
2043  // We always want to suggest forward slashes for includes.
2044  // (not remove_dots(..., posix) as that misparses windows paths).
2045  path::remove_dots(FilePath, /*remove_dot_dot=*/true);
2046  path::native(FilePath, path::Style::posix);
2047  File = FilePath;
2048 
2049  unsigned BestPrefixLength = 0;
2050  // Checks whether `Dir` is a strict path prefix of `File`. If so and that's
2051  // the longest prefix we've seen so for it, returns true and updates the
2052  // `BestPrefixLength` accordingly.
2053  auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
2054  if (!WorkingDir.empty() && !path::is_absolute(Dir))
2055  fs::make_absolute(WorkingDir, Dir);
2056  path::remove_dots(Dir, /*remove_dot_dot=*/true);
2057  for (auto NI = path::begin(File), NE = path::end(File),
2058  DI = path::begin(Dir), DE = path::end(Dir);
2059  NI != NE; ++NI, ++DI) {
2060  if (DI == DE) {
2061  // Dir is a prefix of File, up to choice of path separators.
2062  unsigned PrefixLength = NI - path::begin(File);
2063  if (PrefixLength > BestPrefixLength) {
2064  BestPrefixLength = PrefixLength;
2065  return true;
2066  }
2067  break;
2068  }
2069 
2070  // Consider all path separators equal.
2071  if (NI->size() == 1 && DI->size() == 1 &&
2072  path::is_separator(NI->front()) && path::is_separator(DI->front()))
2073  continue;
2074 
2075  // Special case Apple .sdk folders since the search path is typically a
2076  // symlink like `iPhoneSimulator14.5.sdk` while the file is instead
2077  // located in `iPhoneSimulator.sdk` (the real folder).
2078  if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) {
2079  StringRef NBasename = path::stem(*NI);
2080  StringRef DBasename = path::stem(*DI);
2081  if (DBasename.starts_with(NBasename))
2082  continue;
2083  }
2084 
2085  if (*NI != *DI)
2086  break;
2087  }
2088  return false;
2089  };
2090 
2091  bool BestPrefixIsFramework = false;
2092  for (const DirectoryLookup &DL : search_dir_range()) {
2093  if (DL.isNormalDir()) {
2094  StringRef Dir = DL.getDirRef()->getName();
2095  if (CheckDir(Dir)) {
2096  if (IsAngled)
2097  *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2098  BestPrefixIsFramework = false;
2099  }
2100  } else if (DL.isFramework()) {
2101  StringRef Dir = DL.getFrameworkDirRef()->getName();
2102  if (CheckDir(Dir)) {
2103  // Framework includes by convention use <>.
2104  if (IsAngled)
2105  *IsAngled = BestPrefixLength;
2106  BestPrefixIsFramework = true;
2107  }
2108  }
2109  }
2110 
2111  // Try to shorten include path using TUs directory, if we couldn't find any
2112  // suitable prefix in include search paths.
2113  if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2114  if (IsAngled)
2115  *IsAngled = false;
2116  BestPrefixIsFramework = false;
2117  }
2118 
2119  // Try resolving resulting filename via reverse search in header maps,
2120  // key from header name is user preferred name for the include file.
2121  StringRef Filename = File.drop_front(BestPrefixLength);
2122  for (const DirectoryLookup &DL : search_dir_range()) {
2123  if (!DL.isHeaderMap())
2124  continue;
2125 
2126  StringRef SpelledFilename =
2127  DL.getHeaderMap()->reverseLookupFilename(Filename);
2128  if (!SpelledFilename.empty()) {
2129  Filename = SpelledFilename;
2130  BestPrefixIsFramework = false;
2131  break;
2132  }
2133  }
2134 
2135  // If the best prefix is a framework path, we need to compute the proper
2136  // include spelling for the framework header.
2137  bool IsPrivateHeader;
2138  SmallString<128> FrameworkName, IncludeSpelling;
2139  if (BestPrefixIsFramework &&
2140  isFrameworkStylePath(Filename, IsPrivateHeader, FrameworkName,
2141  IncludeSpelling)) {
2142  Filename = IncludeSpelling;
2143  }
2144  return path::convert_to_slash(Filename);
2145 }
static char ID
Definition: Arena.cpp:183
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
unsigned Offset
Definition: Format.cpp:2978
StringRef Filename
Definition: Format.cpp:2976
unsigned Iter
Definition: HTMLLogger.cpp:154
static void mergeHeaderFileInfo(HeaderFileInfo &HFI, const HeaderFileInfo &OtherHFI)
Merge the header file info provided by OtherHFI into the current header file info (HFI)
static bool suggestModule(HeaderSearch &HS, FileEntryRef File, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule)
static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File, FileManager &FileMgr, DiagnosticsEngine &Diags)
static void diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc, StringRef Includer, StringRef IncludeFilename, FileEntryRef IncludeFE, bool isAngled=false, bool FoundByHeaderMap=false)
static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags, OptionalFileEntryRef MSFE, const FileEntry *FE, SourceLocation IncludeLoc)
Return true with a diagnostic if the file that MSVC would have found fails to match the one that Clan...
static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader, SmallVectorImpl< char > &FrameworkName, SmallVectorImpl< char > &IncludeSpelling)
static const char * copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc)
ALWAYS_ENABLED_STATISTIC(NumIncluded, "Number of attempted #includes.")
static bool needModuleLookup(Module *RequestingModule, bool HasSuggestedModule)
static OptionalDirectoryEntryRef getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, SmallVectorImpl< std::string > &SubmodulePath)
Given a framework directory, find the top-most framework directory.
static void mergeHeaderFileInfoModuleBits(HeaderFileInfo &HFI, bool isModuleHeader, bool isTextualModuleHeader)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
llvm::MachO::Target Target
Definition: MachO.h:50
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::Preprocessor interface.
SourceLocation Loc
Definition: SemaObjC.cpp:755
Defines the SourceManager interface.
constexpr bool has_value() const
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:922
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
OptionalFileEntryRef LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, bool &IsInHeaderMap, SmallVectorImpl< char > &MappedName, bool OpenFile=true) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
const HeaderMap * getHeaderMap() const
getHeaderMap - Return the directory that this entry refers to.
bool isFramework() const
isFramework - True if this is a framework directory.
bool isSystemHeaderDirectory() const
Whether this describes a system header directory.
OptionalDirectoryEntryRef getFrameworkDirRef() const
void setSearchedAllModuleMaps(bool SAMM)
Specify whether we have already searched all of the subdirectories for module maps.
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
OptionalDirectoryEntryRef getDirRef() const
bool haveSearchedAllModuleMaps() const
Determine whether we have already searched this entire directory for module maps.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
bool isNormalDir() const
isNormalDir - Return true if this is a normal directory, not a header map.
Abstract interface for external sources of preprocessor information.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
unsigned getUID() const
Definition: FileEntry.h:342
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:300
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:240
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:251
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:175
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition: Diagnostic.h:135
This class represents an Apple concept known as a 'header map'.
Definition: HeaderMap.h:84
StringRef getFileName() const
Return the filename of the headermap.
Definition: HeaderMap.cpp:109
StringRef lookupFilename(StringRef Filename, SmallVectorImpl< char > &DestPath) const
If the specified relative filename is located in this HeaderMap return the filename it is mapped to,...
Definition: HeaderMap.cpp:197
static std::unique_ptr< HeaderMap > Create(FileEntryRef FE, FileManager &FM)
This attempts to load the specified file as a header map.
Definition: HeaderMap.cpp:52
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
Definition: HeaderSearch.h:253
StringRef getUniqueFrameworkName(StringRef Framework)
Retrieve a uniqued framework name.
std::vector< bool > collectVFSUsageAndClear() const
Collect which HeaderSearchOptions::VFSOverlayFiles have been meaningfully used so far and mark their ...
void AddSearchPath(const DirectoryLookup &dir, bool isAngled)
Add an additional search path.
Module * lookupModule(StringRef ModuleName, SourceLocation ImportLoc=SourceLocation(), bool AllowSearch=true, bool AllowExtraModuleMapSearch=false)
Lookup a module Search for a module with the given name.
HeaderSearch(std::shared_ptr< HeaderSearchOptions > HSOpts, SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target)
bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root, bool IsSystem)
Determine whether there is a module map that may map the header with the given file name to a (sub)mo...
std::string suggestPathToFileForDiagnostics(FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled=nullptr) const
Suggest a path by which the specified file could be found, for use in diagnostics to suggest a #inclu...
const HeaderFileInfo * getExistingLocalFileInfo(FileEntryRef FE) const
Return the headerFileInfo structure for the specified FileEntry, if it has ever been filled in locall...
void getHeaderMapFileNames(SmallVectorImpl< std::string > &Names) const
Get filenames for all registered header maps.
StringRef getIncludeNameForHeader(const FileEntry *File) const
Retrieve the include name for the header.
std::string getPrebuiltImplicitModuleFileName(Module *Module)
Retrieve the name of the prebuilt module file that should be used to load the given module.
StringRef getModuleCachePath() const
Retrieve the path to the module cache.
Definition: HeaderSearch.h:450
ConstSearchDirIterator angled_dir_begin() const
Definition: HeaderSearch.h:877
ArrayRef< ModuleMap::KnownHeader > findAllModulesForHeader(FileEntryRef File) const
Retrieve all the modules corresponding to the given file.
unsigned searchDirIdx(const DirectoryLookup &DL) const
Get the index of the given search directory.
bool isFileMultipleIncludeGuarded(FileEntryRef File) const
Determine whether this file is intended to be safe from multiple inclusions, e.g.,...
ConstSearchDirIterator search_dir_nth(size_t n) const
Definition: HeaderSearch.h:863
void loadTopLevelSystemModules()
Load all known, top-level system modules.
OptionalFileEntryRef LookupFile(StringRef Filename, SourceLocation IncludeLoc, bool isAngled, ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir, ArrayRef< std::pair< OptionalFileEntryRef, DirectoryEntryRef >> Includers, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool BuildSystemModule=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file, return null on failure.
SearchDirIterator search_dir_end()
Definition: HeaderSearch.h:857
std::vector< bool > computeUserEntryUsage() const
Determine which HeaderSearchOptions::UserEntries have been successfully used so far and mark their in...
ArrayRef< ModuleMap::KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
bool loadModuleMapFile(FileEntryRef File, bool IsSystem, FileID ID=FileID(), unsigned *Offset=nullptr, StringRef OriginalModuleMapFile=StringRef())
Read the contents of the given module map file.
void SetSearchPaths(std::vector< DirectoryLookup > dirs, unsigned angledDirIdx, unsigned systemDirIdx, llvm::DenseMap< unsigned, unsigned > searchDirToHSEntry)
Interface for setting the file search paths.
FrameworkCacheEntry & LookupFrameworkCache(StringRef FWName)
Look up the specified framework name in our framework cache.
Definition: HeaderSearch.h:537
void setTarget(const TargetInfo &Target)
Set the target information for the header search, if not already known.
const HeaderMap * CreateHeaderMap(FileEntryRef FE)
This method returns a HeaderMap for the specified FileEntry, uniquing them through the 'HeaderMaps' d...
ModuleMap::KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false) const
Retrieve the module that corresponds to the given file, if any.
SearchDirRange search_dir_range()
Definition: HeaderSearch.h:858
std::string getCachedModuleFileName(Module *Module)
Retrieve the name of the cached module file that should be used to load the given module.
FileManager & getFileMgr() const
Definition: HeaderSearch.h:388
void collectAllModules(SmallVectorImpl< Module * > &Modules)
Collect the set of all known, top-level modules.
void MarkFileModuleHeader(FileEntryRef FE, ModuleMap::ModuleHeaderRole Role, bool isCompilingModuleHeader)
Mark the specified file as part of a module.
const HeaderFileInfo * getExistingFileInfo(FileEntryRef FE) const
Return the HeaderFileInfo structure for the specified FileEntry, if it has ever been filled in (eithe...
OptionalFileEntryRef LookupSubframeworkHeader(StringRef Filename, FileEntryRef ContextFileEnt, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule)
Look up a subframework for the specified #include file.
HeaderFileInfo & getFileInfo(FileEntryRef FE)
Return the HeaderFileInfo structure for the specified FileEntry, in preparation for updating it in so...
HeaderSearchOptions & getHeaderSearchOpts() const
Retrieve the header-search options with which this header search was initialized.
Definition: HeaderSearch.h:386
OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework)
Try to find a module map file in the given directory, returning nullopt if none is found.
bool ShouldEnterIncludeFile(Preprocessor &PP, FileEntryRef File, bool isImport, bool ModulesEnabled, Module *M, bool &IsFirstIncludeOfFile)
Mark the specified file as a target of a #include, #include_next, or #import directive.
size_t getTotalMemory() const
std::string getPrebuiltModuleFileName(StringRef ModuleName, bool FileMapOnly=false)
Retrieve the name of the prebuilt module file that should be used to load a module with the given nam...
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:837
StringRef getModuleHash() const
Retrieve the module hash.
Definition: HeaderSearch.h:447
SearchDirIterator search_dir_begin()
Definition: HeaderSearch.h:856
One of these records is kept for each identifier that is lexed.
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
A header that is known to reside within a given module, whether it was included or excluded.
Definition: ModuleMap.h:159
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
Definition: ModuleMap.cpp:826
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Definition: ModuleMap.cpp:606
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
Definition: ModuleMap.cpp:109
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Definition: ModuleMap.cpp:1247
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
Definition: ModuleMap.cpp:719
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Definition: ModuleMap.cpp:1330
llvm::iterator_range< module_iterator > modules() const
Definition: ModuleMap.h:739
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Definition: ModuleMap.cpp:415
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
Definition: ModuleMap.cpp:3119
void setTarget(const TargetInfo &Target)
Set the target information.
Definition: ModuleMap.cpp:372
ModuleHeaderRole
Flags describing the role of a module header.
Definition: ModuleMap.h:127
@ ExcludedHeader
This header is explicitly excluded from the module.
Definition: ModuleMap.h:139
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Definition: ModuleMap.h:136
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Definition: ModuleMap.cpp:707
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Definition: ModuleMap.cpp:1412
Describes a module or submodule.
Definition: Module.h:105
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
Definition: Module.cpp:293
std::string Name
The name of this module.
Definition: Module.h:108
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
Definition: Module.h:373
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
bool markIncluded(FileEntryRef File)
Mark the file as included.
bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M)
Determine whether II is defined as a macro within the module M, if that is a module that we've alread...
bool isMacroDefined(StringRef Id)
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
Definition: TargetInfo.h:218
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:90
static void hash_combine(std::size_t &seed, const T &v)
llvm::APInt APInt
Definition: Integral.h:29
bool NE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:869
The JSON file list parser is used to communicate input to InstallAPI.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
Definition: Format.h:5433
#define false
Definition: stdbool.h:26
This structure is used to record entries in our framework cache.
Definition: HeaderSearch.h:176
bool IsUserSpecifiedSystemFramework
Whether this framework has been "user-specified" to be treated as if it were a system framework (even...
Definition: HeaderSearch.h:183
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
Definition: HeaderSearch.h:178
The preprocessor keeps track of this information for each file that is #included.
Definition: HeaderSearch.h:58
void mergeModuleMembership(ModuleMap::ModuleHeaderRole Role)
Update the module membership bits based on the header role.
unsigned IndexHeaderMapHeader
Whether this is a header inside a framework that is currently being built.
Definition: HeaderSearch.h:116
unsigned DirInfo
Keep track of whether this is a system header, and if so, whether it is C++ clean or not.
Definition: HeaderSearch.h:80
const IdentifierInfo * ControllingMacro
If this file has a #ifndef XXX (or equivalent) guard that protects the entire contents of the file,...
Definition: HeaderSearch.h:137
unsigned isModuleHeader
Whether this header is part of and built with a module.
Definition: HeaderSearch.h:91
const IdentifierInfo * getControllingMacro(ExternalPreprocessorSource *External)
Retrieve the controlling macro for this header file, if any.
unsigned isTextualModuleHeader
Whether this header is a textual header in a module.
Definition: HeaderSearch.h:95
unsigned isPragmaOnce
True if this is a #pragma once file.
Definition: HeaderSearch.h:73
unsigned Resolved
Whether this structure is considered to already have been "resolved", meaning that it was loaded from...
Definition: HeaderSearch.h:106
unsigned isCompilingModuleHeader
Whether this header is part of the module that we are building, even if it doesn't build with the mod...
Definition: HeaderSearch.h:101
unsigned IsValid
Whether this file has been looked up as a header.
Definition: HeaderSearch.h:120
unsigned isImport
True if this is a #import'd file.
Definition: HeaderSearch.h:69
StringRef Framework
If this header came from a framework include, this is the name of the framework.
Definition: HeaderSearch.h:141
unsigned ControllingMacroID
The ID number of the controlling macro.
Definition: HeaderSearch.h:127
unsigned IsLocallyIncluded
True if this file has been included (or imported) locally.
Definition: HeaderSearch.h:63
unsigned External
Whether this header file info was supplied by an external source, and has not changed since.
Definition: HeaderSearch.h:85