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