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