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