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