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