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 (const auto &[FE, HFI] : FileInfo)
95 NumOnceOnlyFiles += (HFI.isPragmaOnce || HFI.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 HeaderFileInfo *HFI = &FileInfo[FE];
1380 // FIXME: Use a generation count to check whether this is really up to date.
1381 if (ExternalSource && !HFI->Resolved) {
1382 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1383 if (ExternalHFI.IsValid) {
1384 HFI->Resolved = true;
1385 if (ExternalHFI.External)
1386 mergeHeaderFileInfo(*HFI, ExternalHFI);
1387 }
1388 }
1389
1390 HFI->IsValid = true;
1391 // We assume the caller has local information about this header file, so it's
1392 // no longer strictly external.
1393 HFI->External = false;
1394 return *HFI;
1395}
1396
1398 HeaderFileInfo *HFI;
1399 if (ExternalSource) {
1400 HFI = &FileInfo[FE];
1401 // FIXME: Use a generation count to check whether this is really up to date.
1402 if (!HFI->Resolved) {
1403 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1404 if (ExternalHFI.IsValid) {
1405 HFI->Resolved = true;
1406 if (ExternalHFI.External)
1407 mergeHeaderFileInfo(*HFI, ExternalHFI);
1408 }
1409 }
1410 } else if (auto It = FileInfo.find(FE); It != FileInfo.end()) {
1411 HFI = &It->second;
1412 } else {
1413 HFI = nullptr;
1414 }
1415
1416 return (HFI && HFI->IsValid) ? HFI : nullptr;
1417}
1418
1420 llvm::function_ref<void(FileEntryRef, const HeaderFileInfo &)> Fn) const {
1421 for (const auto &[FE, HFI] : FileInfo)
1422 if (HFI.IsValid && !HFI.External)
1423 Fn(FE, HFI);
1424}
1425
1427 // Check if we've entered this file and found an include guard or #pragma
1428 // once. Note that we dor't check for #import, because that's not a property
1429 // of the file itself.
1430 if (auto *HFI = getExistingFileInfo(File))
1431 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1432 return false;
1433}
1434
1437 bool isCompilingModuleHeader) {
1438 // Don't mark the file info as non-external if there's nothing to change.
1439 if (!isCompilingModuleHeader) {
1441 return;
1442 auto *HFI = getExistingFileInfo(FE);
1443 if (HFI && !moduleMembershipNeedsMerge(HFI, Role))
1444 return;
1445 }
1446
1447 auto &HFI = getFileInfo(FE);
1448 HFI.mergeModuleMembership(Role);
1449 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1450}
1451
1453 FileEntryRef File, bool isImport,
1454 bool ModulesEnabled, Module *M,
1455 bool &IsFirstIncludeOfFile) {
1456 // An include file should be entered if either:
1457 // 1. This is the first include of the file.
1458 // 2. This file can be included multiple times, that is it's not an
1459 // "include-once" file.
1460 //
1461 // Include-once is controlled by these preprocessor directives.
1462 //
1463 // #pragma once
1464 // This directive is in the include file, and marks it as an include-once
1465 // file.
1466 //
1467 // #import <file>
1468 // This directive is in the includer, and indicates that the include file
1469 // should only be entered if this is the first include.
1470 ++NumIncluded;
1471 IsFirstIncludeOfFile = false;
1472 HeaderFileInfo &FileInfo = getFileInfo(File);
1473
1474 auto MaybeReenterImportedFile = [&]() -> bool {
1475 // Modules add a wrinkle though: what's included isn't necessarily visible.
1476 // Consider this module.
1477 // module Example {
1478 // module A { header "a.h" export * }
1479 // module B { header "b.h" export * }
1480 // }
1481 // b.h includes c.h. The main file includes a.h, which will trigger a module
1482 // build of Example, and c.h will be included. However, c.h isn't visible to
1483 // the main file. Normally this is fine, the main file can just include c.h
1484 // if it needs it. If c.h is in a module, the include will translate into a
1485 // module import, this function will be skipped, and everything will work as
1486 // expected. However, if c.h is not in a module (or is `textual`), then this
1487 // function will run. If c.h is include-once, it will not be entered from
1488 // the main file and it will still not be visible.
1489
1490 // If modules aren't enabled then there's no visibility issue. Always
1491 // respect `#pragma once`.
1492 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1493 return false;
1494
1495 // Ensure FileInfo bits are up to date.
1496 ModMap.resolveHeaderDirectives(File);
1497
1498 // This brings up a subtlety of #import - it's not a very good indicator of
1499 // include-once. Developers are often unaware of the difference between
1500 // #include and #import, and tend to use one or the other indiscrimiately.
1501 // In order to support #include on include-once headers that lack macro
1502 // guards and `#pragma once` (which is the vast majority of Objective-C
1503 // headers), if a file is ever included with #import, it's marked as
1504 // isImport in the HeaderFileInfo and treated as include-once. This allows
1505 // #include to work in Objective-C.
1506 // #include <Foundation/Foundation.h>
1507 // #include <Foundation/NSString.h>
1508 // Foundation.h has an #import of NSString.h, and so the second #include is
1509 // skipped even though NSString.h has no `#pragma once` and no macro guard.
1510 //
1511 // However, this helpfulness causes problems with modules. If c.h is not an
1512 // include-once file, but something included it with #import anyway (as is
1513 // typical in Objective-C code), this include will be skipped and c.h will
1514 // not be visible. Consider it not include-once if it is a `textual` header
1515 // in a module.
1516 if (FileInfo.isTextualModuleHeader)
1517 return true;
1518
1519 if (FileInfo.isCompilingModuleHeader) {
1520 // It's safer to re-enter a file whose module is being built because its
1521 // declarations will still be scoped to a single module.
1522 if (FileInfo.isModuleHeader) {
1523 // Headers marked as "builtin" are covered by the system module maps
1524 // rather than the builtin ones. Some versions of the Darwin module fail
1525 // to mark stdarg.h and stddef.h as textual. Attempt to re-enter these
1526 // files while building their module to allow them to function properly.
1527 if (ModMap.isBuiltinHeader(File))
1528 return true;
1529 } else {
1530 // Files that are excluded from their module can potentially be
1531 // re-entered from their own module. This might cause redeclaration
1532 // errors if another module saw this file first, but there's a
1533 // reasonable chance that its module will build first. However if
1534 // there's no controlling macro, then trust the #import and assume this
1535 // really is an include-once file.
1536 if (FileInfo.getControllingMacro(ExternalLookup))
1537 return true;
1538 }
1539 }
1540 // If the include file has a macro guard, then it might still not be
1541 // re-entered if the controlling macro is visibly defined. e.g. another
1542 // header in the module being built included this file and local submodule
1543 // visibility is not enabled.
1544
1545 // It might be tempting to re-enter the include-once file if it's not
1546 // visible in an attempt to make it visible. However this will still cause
1547 // redeclaration errors against the known-but-not-visible declarations. The
1548 // include file not being visible will most likely cause "undefined x"
1549 // errors, but at least there's a slim chance of compilation succeeding.
1550 return false;
1551 };
1552
1553 if (isImport) {
1554 // As discussed above, record that this file was ever `#import`ed, and treat
1555 // it as an include-once file from here out.
1556 FileInfo.isImport = true;
1557 if (PP.alreadyIncluded(File) && !MaybeReenterImportedFile())
1558 return false;
1559 } else {
1560 // isPragmaOnce and isImport are only set after the file has been included
1561 // at least once. If either are set then this is a repeat #include of an
1562 // include-once file.
1563 if (FileInfo.isPragmaOnce ||
1564 (FileInfo.isImport && !MaybeReenterImportedFile()))
1565 return false;
1566 }
1567
1568 // As a final optimization, check for a macro guard and skip entering the file
1569 // if the controlling macro is defined. The macro guard will effectively erase
1570 // the file's contents, and the include would have no effect other than to
1571 // waste time opening and reading a file.
1572 if (const IdentifierInfo *ControllingMacro =
1573 FileInfo.getControllingMacro(ExternalLookup)) {
1574 // If the header corresponds to a module, check whether the macro is already
1575 // defined in that module rather than checking all visible modules. This is
1576 // mainly to cover corner cases where the same controlling macro is used in
1577 // different files in multiple modules.
1578 if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1579 : PP.isMacroDefined(ControllingMacro)) {
1580 ++NumMultiIncludeFileOptzn;
1581 return false;
1582 }
1583 }
1584
1585 IsFirstIncludeOfFile = PP.markIncluded(File);
1586 return true;
1587}
1588
1590 return SearchDirs.capacity()
1591 + llvm::capacity_in_bytes(FileInfo)
1592 + llvm::capacity_in_bytes(HeaderMaps)
1593 + LookupFileCache.getAllocator().getTotalMemory()
1594 + FrameworkMap.getAllocator().getTotalMemory();
1595}
1596
1598 return &DL - &*SearchDirs.begin();
1599}
1600
1601StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1602 return FrameworkNames.insert(Framework).first->first();
1603}
1604
1606 auto It = IncludeNames.find(File);
1607 if (It == IncludeNames.end())
1608 return {};
1609 return It->second;
1610}
1611
1612void HeaderSearch::buildModuleMapIndex(DirectoryEntryRef Dir,
1613 ModuleMapDirectoryState &MMState) {
1614 if (!MMState.ModuleMapFile)
1615 return;
1616 const modulemap::ModuleMapFile *ParsedMM =
1617 ModMap.getParsedModuleMap(*MMState.ModuleMapFile);
1618 if (!ParsedMM)
1619 return;
1620 const modulemap::ModuleMapFile *ParsedPrivateMM = nullptr;
1621 if (MMState.PrivateModuleMapFile)
1622 ParsedPrivateMM = ModMap.getParsedModuleMap(*MMState.PrivateModuleMapFile);
1623
1624 processModuleMapForIndex(*ParsedMM, Dir, "", MMState);
1625 if (ParsedPrivateMM)
1626 processModuleMapForIndex(*ParsedPrivateMM, Dir, "", MMState);
1627}
1628
1629void HeaderSearch::addToModuleMapIndex(StringRef RelPath, StringRef ModuleName,
1630 StringRef PathPrefix,
1631 ModuleMapDirectoryState &MMState) {
1632 SmallString<128> RelFromRootPath(PathPrefix);
1633 llvm::sys::path::append(RelFromRootPath, RelPath);
1634 llvm::sys::path::native(RelFromRootPath);
1635 MMState.HeaderToModules[RelFromRootPath].push_back(ModuleName);
1636}
1637
1638void HeaderSearch::processExternModuleDeclForIndex(
1640 StringRef PathPrefix, ModuleMapDirectoryState &MMState) {
1641 StringRef FileNameRef = EMD.Path;
1642 SmallString<128> ModuleMapFileName;
1643 if (llvm::sys::path::is_relative(FileNameRef)) {
1644 ModuleMapFileName = MMDir.getName();
1645 llvm::sys::path::append(ModuleMapFileName, EMD.Path);
1646 FileNameRef = ModuleMapFileName;
1647 }
1648 if (auto EFile = FileMgr.getOptionalFileRef(FileNameRef)) {
1649 if (auto *ExtMMF = ModMap.getParsedModuleMap(*EFile)) {
1650 // Compute the new prefix by appending the extern module's directory
1651 // (from the extern declaration path) to the current prefix.
1652 SmallString<128> NewPrefix(PathPrefix);
1653 StringRef ExternDir = llvm::sys::path::parent_path(EMD.Path);
1654 if (!ExternDir.empty()) {
1655 llvm::sys::path::append(NewPrefix, ExternDir);
1656 llvm::sys::path::native(NewPrefix);
1657 }
1658 processModuleMapForIndex(*ExtMMF, EFile->getDir(), NewPrefix, MMState);
1659 }
1660 }
1661}
1662
1663void HeaderSearch::processModuleDeclForIndex(const modulemap::ModuleDecl &MD,
1664 StringRef ModuleName,
1665 DirectoryEntryRef MMDir,
1666 StringRef PathPrefix,
1667 ModuleMapDirectoryState &MMState) {
1668 // Skip inferred submodules (module *)
1669 if (MD.Id.front().first == "*")
1670 return;
1671
1672 auto ProcessDecl = llvm::makeVisitor(
1673 [&](const modulemap::HeaderDecl &HD) {
1674 if (HD.Umbrella) {
1675 MMState.UmbrellaHeaderModules.push_back(ModuleName);
1676 } else {
1677 addToModuleMapIndex(HD.Path, ModuleName, PathPrefix, MMState);
1678 }
1679 },
1680 [&](const modulemap::UmbrellaDirDecl &UDD) {
1681 SmallString<128> FullPath(PathPrefix);
1682 llvm::sys::path::append(FullPath, UDD.Path);
1683 llvm::sys::path::native(FullPath);
1684 MMState.UmbrellaDirModules.push_back(
1685 std::make_pair(std::string(FullPath), ModuleName));
1686 },
1687 [&](const modulemap::ModuleDecl &SubMD) {
1688 processModuleDeclForIndex(SubMD, ModuleName, MMDir, PathPrefix,
1689 MMState);
1690 },
1691 [&](const modulemap::ExternModuleDecl &EMD) {
1692 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix, MMState);
1693 },
1694 [](const auto &) {
1695 // Ignore other decls.
1696 });
1697
1698 for (const auto &Decl : MD.Decls) {
1699 std::visit(ProcessDecl, Decl);
1700 }
1701}
1702
1703void HeaderSearch::processModuleMapForIndex(const modulemap::ModuleMapFile &MMF,
1704 DirectoryEntryRef MMDir,
1705 StringRef PathPrefix,
1706 ModuleMapDirectoryState &MMState) {
1707 for (const auto &Decl : MMF.Decls) {
1708 std::visit(llvm::makeVisitor(
1709 [&](const modulemap::ModuleDecl &MD) {
1710 processModuleDeclForIndex(MD, MD.Id.front().first, MMDir,
1711 PathPrefix, MMState);
1712 },
1713 [&](const modulemap::ExternModuleDecl &EMD) {
1714 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix,
1715 MMState);
1716 }),
1717 Decl);
1718 }
1719}
1720
1721/// Compute relative path from DirPath to FileName by stripping the DirPath
1722/// prefix. DirPath should be derived from FileName (e.g. via parent_path) to
1723/// ensure consistent path separators. Returns empty if FileName doesn't start
1724/// with DirPath.
1725static StringRef computeRelativePath(StringRef FileName, StringRef DirPath) {
1726 if (!FileName.starts_with(DirPath))
1727 return {};
1728 StringRef RelativePath = FileName.substr(DirPath.size());
1729 while (!RelativePath.empty() &&
1730 llvm::sys::path::is_separator(RelativePath.front()))
1731 RelativePath = RelativePath.substr(1);
1732 return RelativePath;
1733}
1734
1735SmallVector<StringRef, 1> HeaderSearch::findMatchingModulesInIndex(
1736 StringRef RelativePath, const ModuleMapDirectoryState &MMState) const {
1737 SmallVector<StringRef, 1> Modules;
1738
1739 // Check for exact matches in cache.
1740 auto CachedMods = MMState.HeaderToModules.find(RelativePath);
1741 if (CachedMods != MMState.HeaderToModules.end())
1742 Modules.append(CachedMods->second.begin(), CachedMods->second.end());
1743
1744 // Check umbrella directories.
1745 for (const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
1746 if (RelativePath.starts_with(UmbrellaDir.first) || UmbrellaDir.first == ".")
1747 Modules.push_back(UmbrellaDir.second);
1748 }
1749
1750 // Add all modules corresponding to an umbrella header. We don't know which
1751 // other headers these umbrella headers include, so it's possible any one of
1752 // them includes the file. `ModuleMap::findModuleForHeader` will select the
1753 // correct module, accounting for any already known headers from other module
1754 // maps or loaded PCMs.
1755 //
1756 // TODO: Clang should strictly enforce that umbrella headers include the
1757 // other headers in their directory, or that they are referenced in
1758 // the module map. The current behavior can be order of include/import
1759 // dependent. This would allow treating umbrella headers the same as
1760 // umbrella directories here.
1761 Modules.append(MMState.UmbrellaHeaderModules.begin(),
1762 MMState.UmbrellaHeaderModules.end());
1763
1764 return Modules;
1765}
1766
1768 const DirectoryEntry *Root,
1769 bool IsSystem) {
1770 if (!HSOpts.ImplicitModuleMaps)
1771 return false;
1772
1773 StringRef DirName = FileName;
1774 const DirectoryEntry *CurDir = nullptr;
1775 do {
1776 // Get the parent directory name.
1777 DirName = llvm::sys::path::parent_path(DirName);
1778 if (DirName.empty())
1779 return false;
1780
1781 // Determine whether this directory exists.
1782 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1783 if (!Dir)
1784 return false;
1785 CurDir = *Dir;
1786
1787 bool IsFramework =
1788 llvm::sys::path::extension(Dir->getName()) == ".framework";
1789
1790 // Check if it's possible that the module map for this directory can resolve
1791 // this header.
1792 parseModuleMapFile(*Dir, IsSystem, /*ImplicitlyDiscovered=*/true,
1793 IsFramework);
1794 auto DirState = DirectoryModuleMap.find(*Dir);
1795 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1796 continue;
1797
1798 if (!HSOpts.LazyLoadModuleMaps &&
1799 Diags.isIgnored(diag::warn_mmap_deprecated_symlink_to_modular_header,
1800 SourceLocation()))
1801 return true;
1802
1803 auto &MMState = DirState->second;
1804
1805 // Build index if not already built
1806 if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() &&
1807 MMState.UmbrellaHeaderModules.empty()) {
1808 buildModuleMapIndex(*Dir, MMState);
1809 }
1810
1811 // The header cache is needed for the symlink diagnostic.
1812 if (!HSOpts.LazyLoadModuleMaps)
1813 return true;
1814
1815 // Compute relative path from directory to the file. Use DirName (which
1816 // we computed via parent_path) rather than Dir->getName() to ensure
1817 // consistent path separators.
1818 StringRef RelativePath = computeRelativePath(FileName, DirName);
1819 SmallString<128> RelativePathNative(RelativePath);
1820 llvm::sys::path::native(RelativePathNative);
1821
1822 auto ModulesToLoad =
1823 findMatchingModulesInIndex(RelativePathNative, MMState);
1824
1825 // Load all matching modules.
1826 bool LoadedAny = false;
1827 for (StringRef ModName : ModulesToLoad) {
1828 if (ModMap.findOrLoadModule(ModName)) {
1829 LoadedAny = true;
1830 }
1831 }
1832
1833 if (LoadedAny)
1834 return true;
1835
1836 // If we hit the top of our search, we're done.
1837 } while (CurDir != Root);
1838 return false;
1839}
1840
1843 bool AllowExcluded) const {
1844 if (ExternalSource) {
1845 // Make sure the external source has handled header info about this file,
1846 // which includes whether the file is part of a module.
1848 }
1849 return ModMap.findModuleForHeader(File, AllowTextual, AllowExcluded);
1850}
1851
1854 if (ExternalSource) {
1855 // Make sure the external source has handled header info about this file,
1856 // which includes whether the file is part of a module.
1858 }
1859 return ModMap.findAllModulesForHeader(File);
1860}
1861
1864 if (ExternalSource) {
1865 // Make sure the external source has handled header info about this file,
1866 // which includes whether the file is part of a module.
1868 }
1869 return ModMap.findResolvedModulesForHeader(File);
1870}
1871
1873 FileEntryRef File, clang::Module *RequestingModule,
1874 ModuleMap::KnownHeader *SuggestedModule) {
1875 // If this module specifies [no_undeclared_includes], we cannot find any
1876 // file that's in a non-dependency module.
1877 if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
1878 HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false);
1879 if (!RequestingModule->directlyUses(Module.getModule())) {
1880 // Builtin headers are a special case. Multiple modules can use the same
1881 // builtin as a modular header (see also comment in
1882 // ShouldEnterIncludeFile()), so the builtin header may have been
1883 // "claimed" by an unrelated module. This shouldn't prevent us from
1884 // including the builtin header textually in this module.
1885 if (HS.getModuleMap().isBuiltinHeader(File)) {
1886 if (SuggestedModule)
1887 *SuggestedModule = ModuleMap::KnownHeader();
1888 return true;
1889 }
1890 // TODO: Add this module (or just its module map file) into something like
1891 // `RequestingModule->AffectingClangModules`.
1892 return false;
1893 }
1894 }
1895
1896 if (SuggestedModule)
1897 *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
1899 : Module;
1900
1901 return true;
1902}
1903
1904void HeaderSearch::diagnoseUncoveredSymlink(FileEntryRef File,
1906 const DirectoryEntry *Root) {
1907 if (!Module)
1908 return;
1909
1910 if (!HSOpts.ImplicitModuleMaps || Module.getModule()->isPartOfFramework() ||
1911 !Module.getModule()->isModuleMapModule())
1912 return;
1913
1914 if (Diags.isIgnored(diag::warn_mmap_deprecated_symlink_to_modular_header,
1915 Module.getModule()->DefinitionLoc))
1916 return;
1917
1918 if (File.isDeviceFile() || File.isNamedPipe())
1919 return;
1920
1921 llvm::SmallString<128> AbsPath(File.getName());
1922 FileMgr.makeAbsolutePath(AbsPath);
1923 llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
1924
1925 // NOTE: This path may be redirected, LLVM's VFS does not model symlinks, so
1926 // it's possible this fails. The diagnostic is worded as such.
1927 llvm::SmallString<128> LinkTarget;
1928 if (llvm::sys::fs::readlink(AbsPath, LinkTarget))
1929 return;
1930
1931 // We know this file is a symlink and resolved to a module. Check that there's
1932 // a module map that would be discoverable that covers this header. This uses
1933 // VFS paths as that's how module map search works.
1934 StringRef FileName = File.getNameAsRequested();
1935 StringRef DirName = FileName;
1936 const DirectoryEntry *CurDir = nullptr;
1937
1938 // Walk up the directory tree looking for a module map that covers this path.
1939 do {
1940 DirName = llvm::sys::path::parent_path(DirName);
1941 if (DirName.empty())
1942 break;
1943
1944 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1945 if (!Dir)
1946 break;
1947 CurDir = *Dir;
1948
1949 auto DirState = DirectoryModuleMap.find(*Dir);
1950 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1951 continue;
1952
1953 // Use DirName (from parent_path) rather than Dir->getName() to ensure
1954 // consistent path separators.
1955 StringRef RelativePath = computeRelativePath(FileName, DirName);
1956 if (RelativePath.empty())
1957 continue;
1958 SmallString<128> RelativePathNative(RelativePath);
1959 llvm::sys::path::native(RelativePathNative);
1960
1961 auto MatchingModules =
1962 findMatchingModulesInIndex(RelativePathNative, DirState->second);
1963 if (!MatchingModules.empty())
1964 return; // Symlink path is covered, no diagnostic needed.
1965 } while (CurDir != Root);
1966
1967 // The symlink path is not covered by any module map.
1968 Diags.Report(diag::warn_mmap_deprecated_symlink_to_modular_header)
1969 << File.getName() << LinkTarget
1970 << Module.getModule()->getFullModuleName();
1971 Diags.Report(Module.getModule()->DefinitionLoc,
1972 diag::note_mmap_module_defined_here);
1973}
1974
1975bool HeaderSearch::findUsableModuleForHeader(
1976 FileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule,
1977 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1978 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1979 if (!HSOpts.LazyLoadModuleMaps) {
1980 // NOTE: This is required for `shadowed-submodule.m` to pass as it relies
1981 // on A1/module.modulemap being loaded even though we already know
1982 // which module the header belongs to. We will remove this behavior
1983 // as part of lazy module map loading.
1984 hasModuleMap(File.getNameAsRequested(), Root, IsSystemHeaderDir);
1985 ModuleMap::KnownHeader Module =
1986 findModuleForHeader(File, /*AllowTextual=*/true);
1987 diagnoseUncoveredSymlink(File, Module, Root);
1988 return suggestModule(*this, Module, File, RequestingModule,
1989 SuggestedModule);
1990 }
1991
1992 // First check if we already know about this header
1993 ModuleMap::KnownHeader Module =
1994 findModuleForHeader(File, /*AllowTextual=*/true);
1995
1996 // If we don't have a module yet, try to find/load module maps
1997 if (!Module) {
1998 hasModuleMap(File.getNameAsRequested(), Root, IsSystemHeaderDir);
1999 // Try again after loading module maps, this time bypassing loading module
2000 // map data from PCMs.
2001 Module = ModMap.findModuleForHeader(File, /*AllowTextual=*/true);
2002 }
2003 diagnoseUncoveredSymlink(File, Module, Root);
2004 return suggestModule(*this, Module, File, RequestingModule,
2005 SuggestedModule);
2006 }
2007 return true;
2008}
2009
2010bool HeaderSearch::findUsableModuleForFrameworkHeader(
2011 FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
2012 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
2013 // If we're supposed to suggest a module, look for one now.
2014 if (needModuleLookup(RequestingModule, SuggestedModule)) {
2015 // Find the top-level framework based on this framework.
2016 SmallVector<std::string, 4> SubmodulePath;
2017 OptionalDirectoryEntryRef TopFrameworkDir =
2018 ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
2019 assert(TopFrameworkDir && "Could not find the top-most framework dir");
2020
2021 // Determine the name of the top-level framework.
2022 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
2023
2024 // Load this framework module. If that succeeds, find the suggested module
2025 // for this header, if any.
2026 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework,
2027 /*ImplicitlyDiscovered=*/true);
2028
2029 // FIXME: This can find a module not part of ModuleName, which is
2030 // important so that we're consistent about whether this header
2031 // corresponds to a module. Possibly we should lock down framework modules
2032 // so that this is not possible.
2033 ModuleMap::KnownHeader Module =
2034 findModuleForHeader(File, /*AllowTextual=*/true);
2035 return suggestModule(*this, Module, File, RequestingModule,
2036 SuggestedModule);
2037 }
2038 return true;
2039}
2040
2043 DiagnosticsEngine &Diags,
2044 bool Diagnose = true) {
2045 StringRef Filename = llvm::sys::path::filename(File.getName());
2046 SmallString<128> PrivateFilename(File.getDir().getName());
2047 if (Filename == "module.map")
2048 llvm::sys::path::append(PrivateFilename, "module_private.map");
2049 else if (Filename == "module.modulemap")
2050 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
2051 else
2052 return std::nullopt;
2053 auto PMMFile = FileMgr.getOptionalFileRef(PrivateFilename);
2054 if (PMMFile) {
2055 if (Diagnose && Filename == "module.map")
2056 Diags.Report(diag::warn_deprecated_module_dot_map)
2057 << PrivateFilename << 1
2058 << File.getDir().getName().ends_with(".framework");
2059 }
2060 return PMMFile;
2061}
2062
2064 bool ImplicitlyDiscovered,
2065 FileID ID, unsigned *Offset,
2066 StringRef OriginalModuleMapFile) {
2067 // Find the directory for the module. For frameworks, that may require going
2068 // up from the 'Modules' directory.
2070 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
2071 Dir = FileMgr.getOptionalDirectoryRef(".");
2072 } else {
2073 if (!OriginalModuleMapFile.empty()) {
2074 // We're building a preprocessed module map. Find or invent the directory
2075 // that it originally occupied.
2076 Dir = FileMgr.getOptionalDirectoryRef(
2077 llvm::sys::path::parent_path(OriginalModuleMapFile));
2078 if (!Dir) {
2079 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
2080 Dir = FakeFile.getDir();
2081 }
2082 } else {
2083 Dir = File.getDir();
2084 }
2085
2086 assert(Dir && "parent must exist");
2087 StringRef DirName(Dir->getName());
2088 if (llvm::sys::path::filename(DirName) == "Modules") {
2089 DirName = llvm::sys::path::parent_path(DirName);
2090 if (DirName.ends_with(".framework"))
2091 if (auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
2092 Dir = *MaybeDir;
2093 // FIXME: This assert can fail if there's a race between the above check
2094 // and the removal of the directory.
2095 assert(Dir && "parent must exist");
2096 }
2097 }
2098
2099 assert(Dir && "module map home directory must exist");
2100 switch (parseAndLoadModuleMapFileImpl(File, IsSystem, ImplicitlyDiscovered,
2101 *Dir, ID, Offset,
2102 /*DiagnosePrivMMap=*/true)) {
2103 case MMR_AlreadyProcessed:
2104 case MMR_NewlyProcessed:
2105 return false;
2106 case MMR_NoDirectory:
2107 case MMR_InvalidModuleMap:
2108 return true;
2109 }
2110 llvm_unreachable("Unknown load module map result");
2111}
2112
2113HeaderSearch::ModuleMapResult HeaderSearch::parseAndLoadModuleMapFileImpl(
2114 FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered,
2115 DirectoryEntryRef Dir, FileID ID, unsigned *Offset, bool DiagnosePrivMMap) {
2116 // Check whether we've already loaded this module map, and mark it as being
2117 // loaded in case we recursively try to load it from itself.
2118 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
2119 if (!AddResult.second)
2120 return AddResult.first->second ? MMR_AlreadyProcessed
2121 : MMR_InvalidModuleMap;
2122
2123 if (ModMap.parseAndLoadModuleMapFile(File, IsSystem, ImplicitlyDiscovered,
2124 Dir, ID, Offset)) {
2125 LoadedModuleMaps[File] = false;
2126 return MMR_InvalidModuleMap;
2127 }
2128
2129 // Try to load a corresponding private module map.
2130 if (OptionalFileEntryRef PMMFile =
2131 getPrivateModuleMap(File, FileMgr, Diags, DiagnosePrivMMap)) {
2132 if (ModMap.parseAndLoadModuleMapFile(*PMMFile, IsSystem,
2133 ImplicitlyDiscovered, Dir)) {
2134 LoadedModuleMaps[File] = false;
2135 return MMR_InvalidModuleMap;
2136 }
2137 }
2138
2139 // This directory has a module map.
2140 return MMR_NewlyProcessed;
2141}
2142
2143HeaderSearch::ModuleMapResult
2144HeaderSearch::parseModuleMapFileImpl(FileEntryRef File, bool IsSystem,
2145 bool ImplicitlyDiscovered,
2146 DirectoryEntryRef Dir, FileID ID) {
2147 // Check whether we've already parsed this module map, and mark it as being
2148 // parsed in case we recursively try to parse it from itself.
2149 auto AddResult = ParsedModuleMaps.insert(std::make_pair(File, true));
2150 if (!AddResult.second)
2151 return AddResult.first->second ? MMR_AlreadyProcessed
2152 : MMR_InvalidModuleMap;
2153
2154 if (ModMap.parseModuleMapFile(File, IsSystem, ImplicitlyDiscovered, Dir,
2155 ID)) {
2156 ParsedModuleMaps[File] = false;
2157 return MMR_InvalidModuleMap;
2158 }
2159
2160 // Try to parse a corresponding private module map.
2161 if (OptionalFileEntryRef PMMFile =
2162 getPrivateModuleMap(File, FileMgr, Diags, /*Diagnose=*/false)) {
2163 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, ImplicitlyDiscovered,
2164 Dir)) {
2165 ParsedModuleMaps[File] = false;
2166 return MMR_InvalidModuleMap;
2167 }
2168 }
2169
2170 // This directory has a module map.
2171 return MMR_NewlyProcessed;
2172}
2173
2176 if (!HSOpts.ImplicitModuleMaps)
2177 return std::nullopt;
2178 // For frameworks, the preferred spelling is Modules/module.modulemap, but
2179 // module.map at the framework root is also accepted.
2180 SmallString<128> ModuleMapFileName(Dir.getName());
2181 if (IsFramework)
2182 llvm::sys::path::append(ModuleMapFileName, "Modules");
2183 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
2184 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2185 return *F;
2186
2187 // Continue to allow module.map, but warn it's deprecated.
2188 ModuleMapFileName = Dir.getName();
2189 llvm::sys::path::append(ModuleMapFileName, "module.map");
2190 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
2191 Diags.Report(diag::warn_deprecated_module_dot_map)
2192 << ModuleMapFileName << 0 << IsFramework;
2193 return *F;
2194 }
2195
2196 // For frameworks, allow to have a private module map with a preferred
2197 // spelling when a public module map is absent.
2198 if (IsFramework) {
2199 ModuleMapFileName = Dir.getName();
2200 llvm::sys::path::append(ModuleMapFileName, "Modules",
2201 "module.private.modulemap");
2202 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2203 return *F;
2204 }
2205 return std::nullopt;
2206}
2207
2208Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
2209 bool IsSystem,
2210 bool ImplicitlyDiscovered) {
2211 // Try to load a module map file.
2212 switch (parseAndLoadModuleMapFile(Dir, IsSystem, ImplicitlyDiscovered,
2213 /*IsFramework*/ true)) {
2214 case MMR_InvalidModuleMap:
2215 // Try to infer a module map from the framework directory.
2216 if (HSOpts.ImplicitModuleMaps)
2217 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
2218 break;
2219
2220 case MMR_NoDirectory:
2221 return nullptr;
2222
2223 case MMR_AlreadyProcessed:
2224 case MMR_NewlyProcessed:
2225 break;
2226 }
2227
2228 return ModMap.findOrLoadModule(Name);
2229}
2230
2231HeaderSearch::ModuleMapResult
2232HeaderSearch::parseAndLoadModuleMapFile(StringRef DirName, bool IsSystem,
2233 bool ImplicitlyDiscovered,
2234 bool IsFramework) {
2235 if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2236 return parseAndLoadModuleMapFile(*Dir, IsSystem, ImplicitlyDiscovered,
2237 IsFramework);
2238
2239 return MMR_NoDirectory;
2240}
2241
2242HeaderSearch::ModuleMapResult
2244 bool ImplicitlyDiscovered,
2245 bool IsFramework) {
2246 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2247 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2248 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2249 if (!InsertRes.second) {
2250 switch (MMState.Status) {
2251 case ModuleMapDirectoryState::Parsed:
2252 break;
2253 case ModuleMapDirectoryState::Loaded:
2254 return MMR_AlreadyProcessed;
2255 case ModuleMapDirectoryState::Invalid:
2256 return MMR_InvalidModuleMap;
2257 };
2258 }
2259
2260 if (!MMState.ModuleMapFile) {
2261 MMState.ModuleMapFile = lookupModuleMapFile(Dir, IsFramework);
2262 if (MMState.ModuleMapFile)
2263 MMState.PrivateModuleMapFile =
2264 getPrivateModuleMap(*MMState.ModuleMapFile, FileMgr, Diags);
2265 }
2266
2267 if (MMState.ModuleMapFile) {
2268 ModuleMapResult Result = parseAndLoadModuleMapFileImpl(
2269 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2270 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
2271 // E.g. Foo.framework/Modules/module.modulemap
2272 // ^Dir ^ModuleMapFile
2273 if (Result == MMR_NewlyProcessed)
2274 MMState.Status = ModuleMapDirectoryState::Loaded;
2275 else if (Result == MMR_InvalidModuleMap)
2276 MMState.Status = ModuleMapDirectoryState::Invalid;
2277 return Result;
2278 }
2279 return MMR_InvalidModuleMap;
2280}
2281
2282HeaderSearch::ModuleMapResult
2283HeaderSearch::parseModuleMapFile(StringRef DirName, bool IsSystem,
2284 bool ImplicitlyDiscovered, bool IsFramework) {
2285 if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2286 return parseModuleMapFile(*Dir, IsSystem, ImplicitlyDiscovered,
2287 IsFramework);
2288
2289 return MMR_NoDirectory;
2290}
2291
2292HeaderSearch::ModuleMapResult
2293HeaderSearch::parseModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
2294 bool ImplicitlyDiscovered, bool IsFramework) {
2295 if (!HSOpts.LazyLoadModuleMaps)
2296 return parseAndLoadModuleMapFile(Dir, IsSystem, ImplicitlyDiscovered,
2297 IsFramework);
2298
2299 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2300 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2301 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2302 if (!InsertRes.second) {
2303 switch (MMState.Status) {
2304 case ModuleMapDirectoryState::Parsed:
2305 case ModuleMapDirectoryState::Loaded:
2306 return MMR_AlreadyProcessed;
2307 case ModuleMapDirectoryState::Invalid:
2308 return MMR_InvalidModuleMap;
2309 };
2310 }
2311
2312 if (!MMState.ModuleMapFile) {
2313 MMState.ModuleMapFile = lookupModuleMapFile(Dir, IsFramework);
2314 if (MMState.ModuleMapFile)
2315 MMState.PrivateModuleMapFile =
2316 getPrivateModuleMap(*MMState.ModuleMapFile, FileMgr, Diags);
2317 }
2318
2319 if (MMState.ModuleMapFile) {
2320 ModuleMapResult Result = parseModuleMapFileImpl(
2321 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2322 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
2323 // E.g. Foo.framework/Modules/module.modulemap
2324 // ^Dir ^ModuleMapFile
2325 if (Result == MMR_NewlyProcessed)
2326 MMState.Status = ModuleMapDirectoryState::Parsed;
2327 else if (Result == MMR_InvalidModuleMap)
2328 MMState.Status = ModuleMapDirectoryState::Invalid;
2329 return Result;
2330 }
2331 return MMR_InvalidModuleMap;
2332}
2333
2335 Modules.clear();
2336
2337 if (HSOpts.ImplicitModuleMaps) {
2338 // Load module maps for each of the header search directories.
2339 for (DirectoryLookup &DL : search_dir_range()) {
2340 bool IsSystem = DL.isSystemHeaderDirectory();
2341 if (DL.isFramework()) {
2342 std::error_code EC;
2343 SmallString<128> DirNative;
2344 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
2345
2346 // Search each of the ".framework" directories to load them as modules.
2347 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2348 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
2349 DirEnd;
2350 Dir != DirEnd && !EC; Dir.increment(EC)) {
2351 if (llvm::sys::path::extension(Dir->path()) != ".framework")
2352 continue;
2353
2354 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
2355 if (!FrameworkDir)
2356 continue;
2357
2358 // Load this framework module.
2359 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2360 IsSystem, /*ImplicitlyDiscovered=*/true);
2361 }
2362 continue;
2363 }
2364
2365 // FIXME: Deal with header maps.
2366 if (DL.isHeaderMap())
2367 continue;
2368
2369 // Try to load a module map file for the search directory.
2370 parseAndLoadModuleMapFile(*DL.getDirRef(), IsSystem,
2371 /*ImplicitlyDiscovered=*/true,
2372 /*IsFramework*/ false);
2373
2374 // Try to load module map files for immediate subdirectories of this
2375 // search directory.
2376 loadSubdirectoryModuleMaps(DL);
2377 }
2378 }
2379
2380 // Populate the list of modules.
2381 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2382}
2383
2385 if (!HSOpts.ImplicitModuleMaps)
2386 return;
2387
2388 // Load module maps for each of the header search directories.
2389 for (const DirectoryLookup &DL : search_dir_range()) {
2390 // We only care about normal header directories.
2391 if (!DL.isNormalDir())
2392 continue;
2393
2394 // Try to load a module map file for the search directory.
2395 parseAndLoadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(),
2396 /*ImplicitlyDiscovered=*/true, DL.isFramework());
2397 }
2398}
2399
2400void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
2401 assert(HSOpts.ImplicitModuleMaps &&
2402 "Should not be loading subdirectory module maps");
2403
2404 if (SearchDir.haveSearchedAllModuleMaps())
2405 return;
2406
2407 std::error_code EC;
2408 SmallString<128> Dir = SearchDir.getDirRef()->getName();
2409 FileMgr.makeAbsolutePath(Dir);
2410 SmallString<128> DirNative;
2411 llvm::sys::path::native(Dir, DirNative);
2412 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2413 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2414 Dir != DirEnd && !EC; Dir.increment(EC)) {
2415 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2416 continue;
2417 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
2418 if (IsFramework == SearchDir.isFramework())
2420 Dir->path(), SearchDir.isSystemHeaderDirectory(),
2421 /*ImplicitlyDiscovered=*/true, SearchDir.isFramework());
2422 }
2423
2424 SearchDir.setSearchedAllModuleMaps(true);
2425}
2426
2428 FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled) const {
2429 return suggestPathToFileForDiagnostics(File.getName(), /*WorkingDir=*/"",
2430 MainFile, IsAngled);
2431}
2432
2434 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2435 bool *IsAngled) const {
2436 using namespace llvm::sys;
2437
2438 llvm::SmallString<32> FilePath = File;
2439 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2440 path::make_absolute(WorkingDir, FilePath);
2441 // remove_dots switches to backslashes on windows as a side-effect!
2442 // We always want to suggest forward slashes for includes.
2443 // (not remove_dots(..., posix) as that misparses windows paths).
2444 path::remove_dots(FilePath, /*remove_dot_dot=*/true);
2445 path::native(FilePath, path::Style::posix);
2446 File = FilePath;
2447
2448 unsigned BestPrefixLength = 0;
2449 // Checks whether `Dir` is a strict path prefix of `File`. If so and that's
2450 // the longest prefix we've seen so for it, returns true and updates the
2451 // `BestPrefixLength` accordingly.
2452 auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
2453 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2454 path::make_absolute(WorkingDir, Dir);
2455 path::remove_dots(Dir, /*remove_dot_dot=*/true);
2456 for (auto NI = path::begin(File), NE = path::end(File),
2457 DI = path::begin(Dir), DE = path::end(Dir);
2458 NI != NE; ++NI, ++DI) {
2459 if (DI == DE) {
2460 // Dir is a prefix of File, up to choice of path separators.
2461 unsigned PrefixLength = NI - path::begin(File);
2462 if (PrefixLength > BestPrefixLength) {
2463 BestPrefixLength = PrefixLength;
2464 return true;
2465 }
2466 break;
2467 }
2468
2469 // Consider all path separators equal.
2470 if (NI->size() == 1 && DI->size() == 1 &&
2471 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2472 continue;
2473
2474 // Special case Apple .sdk folders since the search path is typically a
2475 // symlink like `iPhoneSimulator14.5.sdk` while the file is instead
2476 // located in `iPhoneSimulator.sdk` (the real folder).
2477 if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) {
2478 StringRef NBasename = path::stem(*NI);
2479 StringRef DBasename = path::stem(*DI);
2480 if (DBasename.starts_with(NBasename))
2481 continue;
2482 }
2483
2484 if (*NI != *DI)
2485 break;
2486 }
2487 return false;
2488 };
2489
2490 bool BestPrefixIsFramework = false;
2491 for (const DirectoryLookup &DL : search_dir_range()) {
2492 if (DL.isNormalDir()) {
2493 StringRef Dir = DL.getDirRef()->getName();
2494 if (CheckDir(Dir)) {
2495 if (IsAngled)
2496 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2497 BestPrefixIsFramework = false;
2498 }
2499 } else if (DL.isFramework()) {
2500 StringRef Dir = DL.getFrameworkDirRef()->getName();
2501 if (CheckDir(Dir)) {
2502 // Framework includes by convention use <>.
2503 if (IsAngled)
2504 *IsAngled = BestPrefixLength;
2505 BestPrefixIsFramework = true;
2506 }
2507 }
2508 }
2509
2510 // Try to shorten include path using TUs directory, if we couldn't find any
2511 // suitable prefix in include search paths.
2512 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2513 if (IsAngled)
2514 *IsAngled = false;
2515 BestPrefixIsFramework = false;
2516 }
2517
2518 // Try resolving resulting filename via reverse search in header maps,
2519 // key from header name is user preferred name for the include file.
2520 StringRef Filename = File.drop_front(BestPrefixLength);
2521 for (const DirectoryLookup &DL : search_dir_range()) {
2522 if (!DL.isHeaderMap())
2523 continue;
2524
2525 StringRef SpelledFilename =
2526 DL.getHeaderMap()->reverseLookupFilename(Filename);
2527 if (!SpelledFilename.empty()) {
2528 Filename = SpelledFilename;
2529 BestPrefixIsFramework = false;
2530 break;
2531 }
2532 }
2533
2534 // If the best prefix is a framework path, we need to compute the proper
2535 // include spelling for the framework header.
2536 bool IsPrivateHeader;
2537 SmallString<128> FrameworkName, IncludeSpelling;
2538 if (BestPrefixIsFramework &&
2539 isFrameworkStylePath(Filename, IsPrivateHeader, FrameworkName,
2540 IncludeSpelling)) {
2541 Filename = IncludeSpelling;
2542 }
2543 return path::convert_to_slash(Filename);
2544}
2545
2547 SmallVectorImpl<char> &NormalizedPath) {
2548 NormalizedPath.assign(Path.begin(), Path.end());
2549 if (!NormalizedPath.empty()) {
2550 FileMgr.makeAbsolutePath(NormalizedPath);
2551 llvm::sys::path::remove_dots(NormalizedPath);
2552 }
2553}
2554
2556 FileManager &FileMgr, StringRef ModuleCachePath, bool DisableModuleHash,
2557 std::string ContextHash, size_t &NormalizedModuleCachePathLen) {
2558 SmallString<256> SpecificModuleCachePath;
2559 normalizeModuleCachePath(FileMgr, ModuleCachePath, SpecificModuleCachePath);
2560 NormalizedModuleCachePathLen = SpecificModuleCachePath.size();
2561 if (!SpecificModuleCachePath.empty() && !DisableModuleHash)
2562 llvm::sys::path::append(SpecificModuleCachePath, ContextHash);
2563 return std::string(SpecificModuleCachePath);
2564}
2565
2566void HeaderSearch::initializeModuleCachePath(std::string NewContextHash) {
2567 ContextHash = std::move(NewContextHash);
2568 SpecificModuleCachePath = createSpecificModuleCachePathImpl(
2569 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash, ContextHash,
2570 NormalizedModuleCachePathLen);
2571}
2572
2574 StringRef ModuleCachePath,
2575 bool DisableModuleHash,
2576 std::string ContextHash) {
2577 size_t NormalizedModuleCachePathLen;
2579 FileMgr, ModuleCachePath, DisableModuleHash, std::move(ContextHash),
2580 NormalizedModuleCachePathLen);
2581}
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
Cached information about one file (either on disk or in the virtual file system).
Definition FileEntry.h:273
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:52
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).
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.
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...
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.
void forEachExistingLocalFileInfo(llvm::function_ref< void(FileEntryRef, const HeaderFileInfo &)> Fn) const
Iterate HeaderFileInfo structures and their corresponding FileEntryRef, if they have ever been filled...
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:196
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