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