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