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