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 *
64 if (!External)
65 return nullptr;
66
68 External->GetIdentifier(LazyControllingMacro.getID());
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 llvm::sys::fs::make_absolute(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 llvm::sys::fs::make_absolute(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
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.
568getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
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 (llvm::sys::fs::exists(SystemFrameworkMarker)) {
676 CacheEntry.IsUserSpecifiedSystemFramework = true;
677 }
678 }
679 }
680
681 // Set out flags.
682 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
683 IsFrameworkFound = CacheEntry.Directory.has_value();
684
685 if (RelativePath) {
686 RelativePath->clear();
687 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
688 }
689
690 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
691 unsigned OrigSize = FrameworkName.size();
692
693 FrameworkName += "Headers/";
694
695 if (SearchPath) {
696 SearchPath->clear();
697 // Without trailing '/'.
698 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
699 }
700
701 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
702
703 auto File =
704 FileMgr.getOptionalFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
705 if (!File) {
706 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
707 const char *Private = "Private";
708 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
709 Private+strlen(Private));
710 if (SearchPath)
711 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
712 Private+strlen(Private));
713
714 File = FileMgr.getOptionalFileRef(FrameworkName,
715 /*OpenFile=*/!SuggestedModule);
716 }
717
718 // If we found the header and are allowed to suggest a module, do so now.
719 if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
720 // Find the framework in which this header occurs.
721 StringRef FrameworkPath = File->getDir().getName();
722 bool FoundFramework = false;
723 do {
724 // Determine whether this directory exists.
725 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkPath);
726 if (!Dir)
727 break;
728
729 // If this is a framework directory, then we're a subframework of this
730 // framework.
731 if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
732 FoundFramework = true;
733 break;
734 }
735
736 // Get the parent directory name.
737 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
738 if (FrameworkPath.empty())
739 break;
740 } while (true);
741
742 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
743 if (FoundFramework) {
744 if (!HS.findUsableModuleForFrameworkHeader(*File, FrameworkPath,
745 RequestingModule,
746 SuggestedModule, IsSystem))
747 return std::nullopt;
748 } else {
749 if (!HS.findUsableModuleForHeader(*File, getDir(), RequestingModule,
750 SuggestedModule, IsSystem))
751 return std::nullopt;
752 }
753 }
754 if (File)
755 return *File;
756 return std::nullopt;
757}
758
759void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
762 CacheLookup.HitIt = HitIt;
763 noteLookupUsage(HitIt.Idx, Loc);
764}
765
766void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
767 SearchDirsUsage[HitIdx] = true;
768
769 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
770 if (UserEntryIdxIt != SearchDirToHSEntry.end())
771 Diags.Report(Loc, diag::remark_pp_search_path_usage)
772 << HSOpts.UserEntries[UserEntryIdxIt->second].Path;
773}
774
776 ModMap.setTarget(Target);
777}
778
779//===----------------------------------------------------------------------===//
780// Header File Location.
781//===----------------------------------------------------------------------===//
782
783/// Return true with a diagnostic if the file that MSVC would have found
784/// fails to match the one that Clang would have found with MSVC header search
785/// disabled.
788 const FileEntry *FE,
789 SourceLocation IncludeLoc) {
790 if (MSFE && FE != *MSFE) {
791 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
792 return true;
793 }
794 return false;
795}
796
797static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
798 assert(!Str.empty());
799 char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
800 std::copy(Str.begin(), Str.end(), CopyStr);
801 CopyStr[Str.size()] = '\0';
802 return CopyStr;
803}
804
805static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader,
806 SmallVectorImpl<char> &FrameworkName,
807 SmallVectorImpl<char> &IncludeSpelling) {
808 using namespace llvm::sys;
809 path::const_iterator I = path::begin(Path);
810 path::const_iterator E = path::end(Path);
811 IsPrivateHeader = false;
812
813 // Detect different types of framework style paths:
814 //
815 // ...Foo.framework/{Headers,PrivateHeaders}
816 // ...Foo.framework/Versions/{A,Current}/{Headers,PrivateHeaders}
817 // ...Foo.framework/Frameworks/Nested.framework/{Headers,PrivateHeaders}
818 // ...<other variations with 'Versions' like in the above path>
819 //
820 // and some other variations among these lines.
821 int FoundComp = 0;
822 while (I != E) {
823 if (*I == "Headers") {
824 ++FoundComp;
825 } else if (*I == "PrivateHeaders") {
826 ++FoundComp;
827 IsPrivateHeader = true;
828 } else if (I->ends_with(".framework")) {
829 StringRef Name = I->drop_back(10); // Drop .framework
830 // Need to reset the strings and counter to support nested frameworks.
831 FrameworkName.clear();
832 FrameworkName.append(Name.begin(), Name.end());
833 IncludeSpelling.clear();
834 IncludeSpelling.append(Name.begin(), Name.end());
835 FoundComp = 1;
836 } else if (FoundComp >= 2) {
837 IncludeSpelling.push_back('/');
838 IncludeSpelling.append(I->begin(), I->end());
839 }
840 ++I;
841 }
842
843 return !FrameworkName.empty() && FoundComp >= 2;
844}
845
846static void
848 StringRef Includer, StringRef IncludeFilename,
849 FileEntryRef IncludeFE, bool isAngled = false,
850 bool FoundByHeaderMap = false) {
851 bool IsIncluderPrivateHeader = false;
852 SmallString<128> FromFramework, ToFramework;
853 SmallString<128> FromIncludeSpelling, ToIncludeSpelling;
854 if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework,
855 FromIncludeSpelling))
856 return;
857 bool IsIncludeePrivateHeader = false;
858 bool IsIncludeeInFramework =
859 isFrameworkStylePath(IncludeFE.getName(), IsIncludeePrivateHeader,
860 ToFramework, ToIncludeSpelling);
861
862 if (!isAngled && !FoundByHeaderMap) {
863 SmallString<128> NewInclude("<");
864 if (IsIncludeeInFramework) {
865 NewInclude += ToIncludeSpelling;
866 NewInclude += ">";
867 } else {
868 NewInclude += IncludeFilename;
869 NewInclude += ">";
870 }
871 Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
872 << IncludeFilename
873 << FixItHint::CreateReplacement(IncludeLoc, NewInclude);
874 }
875
876 // Headers in Foo.framework/Headers should not include headers
877 // from Foo.framework/PrivateHeaders, since this violates public/private
878 // API boundaries and can cause modular dependency cycles.
879 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
880 IsIncludeePrivateHeader && FromFramework == ToFramework)
881 Diags.Report(IncludeLoc, diag::warn_framework_include_private_from_public)
882 << IncludeFilename;
883}
884
885/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
886/// return null on failure. isAngled indicates whether the file reference is
887/// for system \#include's or not (i.e. using <> instead of ""). Includers, if
888/// non-empty, indicates where the \#including file(s) are, in case a relative
889/// search is needed. Microsoft mode will pass all \#including files.
891 StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
893 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
894 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
895 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
896 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
897 bool BuildSystemModule, bool OpenFile, bool CacheFailures) {
898 ConstSearchDirIterator CurDirLocal = nullptr;
899 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
900
901 if (IsMapped)
902 *IsMapped = false;
903
904 if (IsFrameworkFound)
905 *IsFrameworkFound = false;
906
907 if (SuggestedModule)
908 *SuggestedModule = ModuleMap::KnownHeader();
909
910 // If 'Filename' is absolute, check to see if it exists and no searching.
911 if (llvm::sys::path::is_absolute(Filename)) {
912 CurDir = nullptr;
913
914 // If this was an #include_next "/absolute/file", fail.
915 if (FromDir)
916 return std::nullopt;
917
918 if (SearchPath)
919 SearchPath->clear();
920 if (RelativePath) {
921 RelativePath->clear();
922 RelativePath->append(Filename.begin(), Filename.end());
923 }
924 // Otherwise, just return the file.
925 return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
926 /*IsSystemHeaderDir*/ false,
927 RequestingModule, SuggestedModule, OpenFile,
928 CacheFailures);
929 }
930
931 // This is the header that MSVC's header search would have found.
932 ModuleMap::KnownHeader MSSuggestedModule;
934
935 // Check to see if the file is in the #includer's directory. This cannot be
936 // based on CurDir, because each includer could be a #include of a
937 // subdirectory (#include "foo/bar.h") and a subsequent include of "baz.h"
938 // should resolve to "whatever/foo/baz.h". This search is not done for <>
939 // headers.
940 if (!Includers.empty() && !isAngled) {
941 SmallString<1024> TmpDir;
942 bool First = true;
943 for (const auto &IncluderAndDir : Includers) {
944 OptionalFileEntryRef Includer = IncluderAndDir.first;
945
946 // Concatenate the requested file onto the directory.
947 TmpDir = IncluderAndDir.second.getName();
948 llvm::sys::path::append(TmpDir, Filename);
949
950 // FIXME: We don't cache the result of getFileInfo across the call to
951 // getFileAndSuggestModule, because it's a reference to an element of
952 // a container that could be reallocated across this call.
953 //
954 // If we have no includer, that means we're processing a #include
955 // from a module build. We should treat this as a system header if we're
956 // building a [system] module.
957 bool IncluderIsSystemHeader = [&]() {
958 if (!Includer)
959 return BuildSystemModule;
960 const HeaderFileInfo *HFI = getExistingFileInfo(*Includer);
961 assert(HFI && "includer without file info");
962 return HFI->DirInfo != SrcMgr::C_User;
963 }();
964 if (OptionalFileEntryRef FE = getFileAndSuggestModule(
965 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
966 RequestingModule, SuggestedModule)) {
967 if (!Includer) {
968 assert(First && "only first includer can have no file");
969 return FE;
970 }
971
972 // Leave CurDir unset.
973 // This file is a system header or C++ unfriendly if the old file is.
974 //
975 // Note that we only use one of FromHFI/ToHFI at once, due to potential
976 // reallocation of the underlying vector potentially making the first
977 // reference binding dangling.
978 const HeaderFileInfo *FromHFI = getExistingFileInfo(*Includer);
979 assert(FromHFI && "includer without file info");
980 unsigned DirInfo = FromHFI->DirInfo;
981
982 HeaderFileInfo &ToHFI = getFileInfo(*FE);
983 ToHFI.DirInfo = DirInfo;
984
985 if (SearchPath) {
986 StringRef SearchPathRef(IncluderAndDir.second.getName());
987 SearchPath->clear();
988 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
989 }
990 if (RelativePath) {
991 RelativePath->clear();
992 RelativePath->append(Filename.begin(), Filename.end());
993 }
994 if (First) {
995 diagnoseFrameworkInclude(Diags, IncludeLoc,
996 IncluderAndDir.second.getName(), Filename,
997 *FE);
998 return FE;
999 }
1000
1001 // Otherwise, we found the path via MSVC header search rules. If
1002 // -Wmsvc-include is enabled, we have to keep searching to see if we
1003 // would've found this header in -I or -isystem directories.
1004 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1005 return FE;
1006 } else {
1007 MSFE = FE;
1008 if (SuggestedModule) {
1009 MSSuggestedModule = *SuggestedModule;
1010 *SuggestedModule = ModuleMap::KnownHeader();
1011 }
1012 break;
1013 }
1014 }
1015 First = false;
1016 }
1017 }
1018
1019 CurDir = nullptr;
1020
1021 // If this is a system #include, ignore the user #include locs.
1023 isAngled ? angled_dir_begin() : search_dir_begin();
1024
1025 // If this is a #include_next request, start searching after the directory the
1026 // file was found in.
1027 if (FromDir)
1028 It = FromDir;
1029
1030 // Cache all of the lookups performed by this method. Many headers are
1031 // multiply included, and the "pragma once" optimization prevents them from
1032 // being relex/pp'd, but they would still have to search through a
1033 // (potentially huge) series of SearchDirs to find it.
1034 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1035
1036 ConstSearchDirIterator NextIt = std::next(It);
1037
1038 if (!SkipCache) {
1039 if (CacheLookup.StartIt == NextIt &&
1040 CacheLookup.RequestingModule == RequestingModule) {
1041 // HIT: Skip querying potentially lots of directories for this lookup.
1042 if (CacheLookup.HitIt)
1043 It = CacheLookup.HitIt;
1044 if (CacheLookup.MappedName) {
1045 Filename = CacheLookup.MappedName;
1046 if (IsMapped)
1047 *IsMapped = true;
1048 }
1049 } else {
1050 // MISS: This is the first query, or the previous query didn't match
1051 // our search start. We will fill in our found location below, so prime
1052 // the start point value.
1053 CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1054
1055 if (It == search_dir_begin() && FirstNonHeaderMapSearchDirIdx > 0) {
1056 // Handle cold misses of user includes in the presence of many header
1057 // maps. We avoid searching perhaps thousands of header maps by
1058 // jumping directly to the correct one or jumping beyond all of them.
1059 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1060 if (Iter == SearchDirHeaderMapIndex.end())
1061 // Not in index => Skip to first SearchDir after initial header maps
1062 It = search_dir_nth(FirstNonHeaderMapSearchDirIdx);
1063 else
1064 // In index => Start with a specific header map
1065 It = search_dir_nth(Iter->second);
1066 }
1067 }
1068 } else {
1069 CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1070 }
1071
1072 SmallString<64> MappedName;
1073
1074 // Check each directory in sequence to see if it contains this file.
1075 for (; It != search_dir_end(); ++It) {
1076 bool InUserSpecifiedSystemFramework = false;
1077 bool IsInHeaderMap = false;
1078 bool IsFrameworkFoundInDir = false;
1079 OptionalFileEntryRef File = It->LookupFile(
1080 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1081 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1082 IsInHeaderMap, MappedName, OpenFile);
1083 if (!MappedName.empty()) {
1084 assert(IsInHeaderMap && "MappedName should come from a header map");
1085 CacheLookup.MappedName =
1086 copyString(MappedName, LookupFileCache.getAllocator());
1087 }
1088 if (IsMapped)
1089 // A filename is mapped when a header map remapped it to a relative path
1090 // used in subsequent header search or to an absolute path pointing to an
1091 // existing file.
1092 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap && File));
1093 if (IsFrameworkFound)
1094 // Because we keep a filename remapped for subsequent search directory
1095 // lookups, ignore IsFrameworkFoundInDir after the first remapping and not
1096 // just for remapping in a current search directory.
1097 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1098 if (!File)
1099 continue;
1100
1101 CurDir = It;
1102
1103 IncludeNames[*File] = Filename;
1104
1105 // This file is a system header or C++ unfriendly if the dir is.
1107 HFI.DirInfo = CurDir->getDirCharacteristic();
1108
1109 // If the directory characteristic is User but this framework was
1110 // user-specified to be treated as a system framework, promote the
1111 // characteristic.
1112 if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
1114
1115 // If the filename matches a known system header prefix, override
1116 // whether the file is a system header.
1117 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1118 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1119 HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
1121 break;
1122 }
1123 }
1124
1125 if (checkMSVCHeaderSearch(Diags, MSFE, &File->getFileEntry(), IncludeLoc)) {
1126 if (SuggestedModule)
1127 *SuggestedModule = MSSuggestedModule;
1128 return MSFE;
1129 }
1130
1131 bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
1132 if (!Includers.empty())
1133 diagnoseFrameworkInclude(Diags, IncludeLoc,
1134 Includers.front().second.getName(), Filename,
1135 *File, isAngled, FoundByHeaderMap);
1136
1137 // Remember this location for the next lookup we do.
1138 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1139 return File;
1140 }
1141
1142 if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
1143 if (SuggestedModule)
1144 *SuggestedModule = MSSuggestedModule;
1145 return MSFE;
1146 }
1147
1148 // Otherwise, didn't find it. Remember we didn't find this.
1149 CacheLookup.HitIt = search_dir_end();
1150 return std::nullopt;
1151}
1152
1153/// LookupSubframeworkHeader - Look up a subframework for the specified
1154/// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
1155/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
1156/// is a subframework within Carbon.framework. If so, return the FileEntry
1157/// for the designated file, otherwise return null.
1159 StringRef Filename, FileEntryRef ContextFileEnt,
1160 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
1161 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {
1162 // Framework names must have a '/' in the filename. Find it.
1163 // FIXME: Should we permit '\' on Windows?
1164 size_t SlashPos = Filename.find('/');
1165 if (SlashPos == StringRef::npos)
1166 return std::nullopt;
1167
1168 // Look up the base framework name of the ContextFileEnt.
1169 StringRef ContextName = ContextFileEnt.getName();
1170
1171 // If the context info wasn't a framework, couldn't be a subframework.
1172 const unsigned DotFrameworkLen = 10;
1173 auto FrameworkPos = ContextName.find(".framework");
1174 if (FrameworkPos == StringRef::npos ||
1175 (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1176 ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1177 return std::nullopt;
1178
1179 SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1180 FrameworkPos +
1181 DotFrameworkLen + 1);
1182
1183 // Append Frameworks/HIToolbox.framework/
1184 FrameworkName += "Frameworks/";
1185 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1186 FrameworkName += ".framework/";
1187
1188 auto &CacheLookup =
1189 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1190 FrameworkCacheEntry())).first;
1191
1192 // Some other location?
1193 if (CacheLookup.second.Directory &&
1194 CacheLookup.first().size() == FrameworkName.size() &&
1195 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1196 CacheLookup.first().size()) != 0)
1197 return std::nullopt;
1198
1199 // Cache subframework.
1200 if (!CacheLookup.second.Directory) {
1201 ++NumSubFrameworkLookups;
1202
1203 // If the framework dir doesn't exist, we fail.
1204 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1205 if (!Dir)
1206 return std::nullopt;
1207
1208 // Otherwise, if it does, remember that this is the right direntry for this
1209 // framework.
1210 CacheLookup.second.Directory = Dir;
1211 }
1212
1213
1214 if (RelativePath) {
1215 RelativePath->clear();
1216 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1217 }
1218
1219 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
1220 SmallString<1024> HeadersFilename(FrameworkName);
1221 HeadersFilename += "Headers/";
1222 if (SearchPath) {
1223 SearchPath->clear();
1224 // Without trailing '/'.
1225 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1226 }
1227
1228 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1229 auto File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1230 if (!File) {
1231 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
1232 HeadersFilename = FrameworkName;
1233 HeadersFilename += "PrivateHeaders/";
1234 if (SearchPath) {
1235 SearchPath->clear();
1236 // Without trailing '/'.
1237 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1238 }
1239
1240 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1241 File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1242
1243 if (!File)
1244 return std::nullopt;
1245 }
1246
1247 // This file is a system header or C++ unfriendly if the old file is.
1248 const HeaderFileInfo *ContextHFI = getExistingFileInfo(ContextFileEnt);
1249 assert(ContextHFI && "context file without file info");
1250 // Note that the temporary 'DirInfo' is required here, as the call to
1251 // getFileInfo could resize the vector and might invalidate 'ContextHFI'.
1252 unsigned DirInfo = ContextHFI->DirInfo;
1253 getFileInfo(*File).DirInfo = DirInfo;
1254
1255 FrameworkName.pop_back(); // remove the trailing '/'
1256 if (!findUsableModuleForFrameworkHeader(*File, FrameworkName,
1257 RequestingModule, SuggestedModule,
1258 /*IsSystem*/ false))
1259 return std::nullopt;
1260
1261 return *File;
1262}
1263
1264//===----------------------------------------------------------------------===//
1265// File Info Management.
1266//===----------------------------------------------------------------------===//
1267
1270 if (ModuleMap::isModular(Role))
1271 return !HFI->isModuleHeader || HFI->isTextualModuleHeader;
1272 if (!HFI->isModuleHeader && (Role & ModuleMap::TextualHeader))
1273 return !HFI->isTextualModuleHeader;
1274 return false;
1275}
1276
1278 bool isModuleHeader,
1279 bool isTextualModuleHeader) {
1280 HFI.isModuleHeader |= isModuleHeader;
1281 if (HFI.isModuleHeader)
1282 HFI.isTextualModuleHeader = false;
1283 else
1284 HFI.isTextualModuleHeader |= isTextualModuleHeader;
1285}
1286
1289 (Role & ModuleMap::TextualHeader));
1290}
1291
1292/// Merge the header file info provided by \p OtherHFI into the current
1293/// header file info (\p HFI)
1295 const HeaderFileInfo &OtherHFI) {
1296 assert(OtherHFI.External && "expected to merge external HFI");
1297
1298 HFI.isImport |= OtherHFI.isImport;
1299 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
1301 OtherHFI.isTextualModuleHeader);
1302
1303 if (!HFI.LazyControllingMacro.isValid())
1305
1306 HFI.DirInfo = OtherHFI.DirInfo;
1307 HFI.External = (!HFI.IsValid || HFI.External);
1308 HFI.IsValid = true;
1309}
1310
1312 if (FE.getUID() >= FileInfo.size())
1313 FileInfo.resize(FE.getUID() + 1);
1314
1315 HeaderFileInfo *HFI = &FileInfo[FE.getUID()];
1316 // FIXME: Use a generation count to check whether this is really up to date.
1317 if (ExternalSource && !HFI->Resolved) {
1318 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1319 if (ExternalHFI.IsValid) {
1320 HFI->Resolved = true;
1321 if (ExternalHFI.External)
1322 mergeHeaderFileInfo(*HFI, ExternalHFI);
1323 }
1324 }
1325
1326 HFI->IsValid = true;
1327 // We assume the caller has local information about this header file, so it's
1328 // no longer strictly external.
1329 HFI->External = false;
1330 return *HFI;
1331}
1332
1334 HeaderFileInfo *HFI;
1335 if (ExternalSource) {
1336 if (FE.getUID() >= FileInfo.size())
1337 FileInfo.resize(FE.getUID() + 1);
1338
1339 HFI = &FileInfo[FE.getUID()];
1340 // FIXME: Use a generation count to check whether this is really up to date.
1341 if (!HFI->Resolved) {
1342 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1343 if (ExternalHFI.IsValid) {
1344 HFI->Resolved = true;
1345 if (ExternalHFI.External)
1346 mergeHeaderFileInfo(*HFI, ExternalHFI);
1347 }
1348 }
1349 } else if (FE.getUID() < FileInfo.size()) {
1350 HFI = &FileInfo[FE.getUID()];
1351 } else {
1352 HFI = nullptr;
1353 }
1354
1355 return (HFI && HFI->IsValid) ? HFI : nullptr;
1356}
1357
1358const HeaderFileInfo *
1360 HeaderFileInfo *HFI;
1361 if (FE.getUID() < FileInfo.size()) {
1362 HFI = &FileInfo[FE.getUID()];
1363 } else {
1364 HFI = nullptr;
1365 }
1366
1367 return (HFI && HFI->IsValid && !HFI->External) ? HFI : nullptr;
1368}
1369
1371 // Check if we've entered this file and found an include guard or #pragma
1372 // once. Note that we dor't check for #import, because that's not a property
1373 // of the file itself.
1374 if (auto *HFI = getExistingFileInfo(File))
1375 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1376 return false;
1377}
1378
1381 bool isCompilingModuleHeader) {
1382 // Don't mark the file info as non-external if there's nothing to change.
1383 if (!isCompilingModuleHeader) {
1384 if ((Role & ModuleMap::ExcludedHeader))
1385 return;
1386 auto *HFI = getExistingFileInfo(FE);
1387 if (HFI && !moduleMembershipNeedsMerge(HFI, Role))
1388 return;
1389 }
1390
1391 auto &HFI = getFileInfo(FE);
1392 HFI.mergeModuleMembership(Role);
1393 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1394}
1395
1397 FileEntryRef File, bool isImport,
1398 bool ModulesEnabled, Module *M,
1399 bool &IsFirstIncludeOfFile) {
1400 // An include file should be entered if either:
1401 // 1. This is the first include of the file.
1402 // 2. This file can be included multiple times, that is it's not an
1403 // "include-once" file.
1404 //
1405 // Include-once is controlled by these preprocessor directives.
1406 //
1407 // #pragma once
1408 // This directive is in the include file, and marks it as an include-once
1409 // file.
1410 //
1411 // #import <file>
1412 // This directive is in the includer, and indicates that the include file
1413 // should only be entered if this is the first include.
1414 ++NumIncluded;
1415 IsFirstIncludeOfFile = false;
1416 HeaderFileInfo &FileInfo = getFileInfo(File);
1417
1418 auto MaybeReenterImportedFile = [&]() -> bool {
1419 // Modules add a wrinkle though: what's included isn't necessarily visible.
1420 // Consider this module.
1421 // module Example {
1422 // module A { header "a.h" export * }
1423 // module B { header "b.h" export * }
1424 // }
1425 // b.h includes c.h. The main file includes a.h, which will trigger a module
1426 // build of Example, and c.h will be included. However, c.h isn't visible to
1427 // the main file. Normally this is fine, the main file can just include c.h
1428 // if it needs it. If c.h is in a module, the include will translate into a
1429 // module import, this function will be skipped, and everything will work as
1430 // expected. However, if c.h is not in a module (or is `textual`), then this
1431 // function will run. If c.h is include-once, it will not be entered from
1432 // the main file and it will still not be visible.
1433
1434 // If modules aren't enabled then there's no visibility issue. Always
1435 // respect `#pragma once`.
1436 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1437 return false;
1438
1439 // Ensure FileInfo bits are up to date.
1441
1442 // This brings up a subtlety of #import - it's not a very good indicator of
1443 // include-once. Developers are often unaware of the difference between
1444 // #include and #import, and tend to use one or the other indiscrimiately.
1445 // In order to support #include on include-once headers that lack macro
1446 // guards and `#pragma once` (which is the vast majority of Objective-C
1447 // headers), if a file is ever included with #import, it's marked as
1448 // isImport in the HeaderFileInfo and treated as include-once. This allows
1449 // #include to work in Objective-C.
1450 // #include <Foundation/Foundation.h>
1451 // #include <Foundation/NSString.h>
1452 // Foundation.h has an #import of NSString.h, and so the second #include is
1453 // skipped even though NSString.h has no `#pragma once` and no macro guard.
1454 //
1455 // However, this helpfulness causes problems with modules. If c.h is not an
1456 // include-once file, but something included it with #import anyway (as is
1457 // typical in Objective-C code), this include will be skipped and c.h will
1458 // not be visible. Consider it not include-once if it is a `textual` header
1459 // in a module.
1460 if (FileInfo.isTextualModuleHeader)
1461 return true;
1462
1463 if (FileInfo.isCompilingModuleHeader) {
1464 // It's safer to re-enter a file whose module is being built because its
1465 // declarations will still be scoped to a single module.
1466 if (FileInfo.isModuleHeader) {
1467 // Headers marked as "builtin" are covered by the system module maps
1468 // rather than the builtin ones. Some versions of the Darwin module fail
1469 // to mark stdarg.h and stddef.h as textual. Attempt to re-enter these
1470 // files while building their module to allow them to function properly.
1471 if (ModMap.isBuiltinHeader(File))
1472 return true;
1473 } else {
1474 // Files that are excluded from their module can potentially be
1475 // re-entered from their own module. This might cause redeclaration
1476 // errors if another module saw this file first, but there's a
1477 // reasonable chance that its module will build first. However if
1478 // there's no controlling macro, then trust the #import and assume this
1479 // really is an include-once file.
1480 if (FileInfo.getControllingMacro(ExternalLookup))
1481 return true;
1482 }
1483 }
1484 // If the include file has a macro guard, then it might still not be
1485 // re-entered if the controlling macro is visibly defined. e.g. another
1486 // header in the module being built included this file and local submodule
1487 // visibility is not enabled.
1488
1489 // It might be tempting to re-enter the include-once file if it's not
1490 // visible in an attempt to make it visible. However this will still cause
1491 // redeclaration errors against the known-but-not-visible declarations. The
1492 // include file not being visible will most likely cause "undefined x"
1493 // errors, but at least there's a slim chance of compilation succeeding.
1494 return false;
1495 };
1496
1497 if (isImport) {
1498 // As discussed above, record that this file was ever `#import`ed, and treat
1499 // it as an include-once file from here out.
1500 FileInfo.isImport = true;
1501 if (PP.alreadyIncluded(File) && !MaybeReenterImportedFile())
1502 return false;
1503 } else {
1504 // isPragmaOnce and isImport are only set after the file has been included
1505 // at least once. If either are set then this is a repeat #include of an
1506 // include-once file.
1507 if (FileInfo.isPragmaOnce ||
1508 (FileInfo.isImport && !MaybeReenterImportedFile()))
1509 return false;
1510 }
1511
1512 // As a final optimization, check for a macro guard and skip entering the file
1513 // if the controlling macro is defined. The macro guard will effectively erase
1514 // the file's contents, and the include would have no effect other than to
1515 // waste time opening and reading a file.
1516 if (const IdentifierInfo *ControllingMacro =
1517 FileInfo.getControllingMacro(ExternalLookup)) {
1518 // If the header corresponds to a module, check whether the macro is already
1519 // defined in that module rather than checking all visible modules. This is
1520 // mainly to cover corner cases where the same controlling macro is used in
1521 // different files in multiple modules.
1522 if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1523 : PP.isMacroDefined(ControllingMacro)) {
1524 ++NumMultiIncludeFileOptzn;
1525 return false;
1526 }
1527 }
1528
1529 IsFirstIncludeOfFile = PP.markIncluded(File);
1530 return true;
1531}
1532
1534 return SearchDirs.capacity()
1535 + llvm::capacity_in_bytes(FileInfo)
1536 + llvm::capacity_in_bytes(HeaderMaps)
1537 + LookupFileCache.getAllocator().getTotalMemory()
1538 + FrameworkMap.getAllocator().getTotalMemory();
1539}
1540
1542 return &DL - &*SearchDirs.begin();
1543}
1544
1545StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1546 return FrameworkNames.insert(Framework).first->first();
1547}
1548
1550 auto It = IncludeNames.find(File);
1551 if (It == IncludeNames.end())
1552 return {};
1553 return It->second;
1554}
1555
1557 const DirectoryEntry *Root,
1558 bool IsSystem) {
1559 if (!HSOpts.ImplicitModuleMaps)
1560 return false;
1561
1562 SmallVector<DirectoryEntryRef, 2> FixUpDirectories;
1563
1564 StringRef DirName = FileName;
1565 do {
1566 // Get the parent directory name.
1567 DirName = llvm::sys::path::parent_path(DirName);
1568 if (DirName.empty())
1569 return false;
1570
1571 // Determine whether this directory exists.
1572 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1573 if (!Dir)
1574 return false;
1575
1576 // Try to load the module map file in this directory.
1578 *Dir, IsSystem,
1579 llvm::sys::path::extension(Dir->getName()) == ".framework")) {
1580 case MMR_NewlyProcessed:
1581 case MMR_AlreadyProcessed: {
1582 // Success. All of the directories we stepped through inherit this module
1583 // map file.
1584 const ModuleMapDirectoryState &MMDS = DirectoryModuleMap[*Dir];
1585 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1586 DirectoryModuleMap[FixUpDirectories[I]] = MMDS;
1587 return true;
1588 }
1589 case MMR_NoDirectory:
1590 case MMR_InvalidModuleMap:
1591 break;
1592 }
1593
1594 // If we hit the top of our search, we're done.
1595 if (*Dir == Root)
1596 return false;
1597
1598 // Keep track of all of the directories we checked, so we can mark them as
1599 // having module maps if we eventually do find a module map.
1600 FixUpDirectories.push_back(*Dir);
1601 } while (true);
1602}
1603
1606 bool AllowExcluded) const {
1607 if (ExternalSource) {
1608 // Make sure the external source has handled header info about this file,
1609 // which includes whether the file is part of a module.
1611 }
1612 return ModMap.findModuleForHeader(File, AllowTextual, AllowExcluded);
1613}
1614
1617 if (ExternalSource) {
1618 // Make sure the external source has handled header info about this file,
1619 // which includes whether the file is part of a module.
1621 }
1622 return ModMap.findAllModulesForHeader(File);
1623}
1624
1627 if (ExternalSource) {
1628 // Make sure the external source has handled header info about this file,
1629 // which includes whether the file is part of a module.
1631 }
1632 return ModMap.findResolvedModulesForHeader(File);
1633}
1634
1636 Module *RequestingModule,
1637 ModuleMap::KnownHeader *SuggestedModule) {
1639 HS.findModuleForHeader(File, /*AllowTextual*/true);
1640
1641 // If this module specifies [no_undeclared_includes], we cannot find any
1642 // file that's in a non-dependency module.
1643 if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
1644 HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false);
1645 if (!RequestingModule->directlyUses(Module.getModule())) {
1646 // Builtin headers are a special case. Multiple modules can use the same
1647 // builtin as a modular header (see also comment in
1648 // ShouldEnterIncludeFile()), so the builtin header may have been
1649 // "claimed" by an unrelated module. This shouldn't prevent us from
1650 // including the builtin header textually in this module.
1651 if (HS.getModuleMap().isBuiltinHeader(File)) {
1652 if (SuggestedModule)
1653 *SuggestedModule = ModuleMap::KnownHeader();
1654 return true;
1655 }
1656 // TODO: Add this module (or just its module map file) into something like
1657 // `RequestingModule->AffectingClangModules`.
1658 return false;
1659 }
1660 }
1661
1662 if (SuggestedModule)
1663 *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
1665 : Module;
1666
1667 return true;
1668}
1669
1670bool HeaderSearch::findUsableModuleForHeader(
1671 FileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule,
1672 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1673 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1674 // If there is a module that corresponds to this header, suggest it.
1675 hasModuleMap(File.getNameAsRequested(), Root, IsSystemHeaderDir);
1676 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1677 }
1678 return true;
1679}
1680
1681bool HeaderSearch::findUsableModuleForFrameworkHeader(
1682 FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
1683 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1684 // If we're supposed to suggest a module, look for one now.
1685 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1686 // Find the top-level framework based on this framework.
1687 SmallVector<std::string, 4> SubmodulePath;
1688 OptionalDirectoryEntryRef TopFrameworkDir =
1689 ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1690 assert(TopFrameworkDir && "Could not find the top-most framework dir");
1691
1692 // Determine the name of the top-level framework.
1693 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1694
1695 // Load this framework module. If that succeeds, find the suggested module
1696 // for this header, if any.
1697 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1698
1699 // FIXME: This can find a module not part of ModuleName, which is
1700 // important so that we're consistent about whether this header
1701 // corresponds to a module. Possibly we should lock down framework modules
1702 // so that this is not possible.
1703 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1704 }
1705 return true;
1706}
1707
1709 FileManager &FileMgr,
1710 DiagnosticsEngine &Diags,
1711 bool Diagnose = true) {
1712 StringRef Filename = llvm::sys::path::filename(File.getName());
1713 SmallString<128> PrivateFilename(File.getDir().getName());
1714 if (Filename == "module.map")
1715 llvm::sys::path::append(PrivateFilename, "module_private.map");
1716 else if (Filename == "module.modulemap")
1717 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1718 else
1719 return std::nullopt;
1720 auto PMMFile = FileMgr.getOptionalFileRef(PrivateFilename);
1721 if (PMMFile) {
1722 if (Diagnose && Filename == "module.map")
1723 Diags.Report(diag::warn_deprecated_module_dot_map)
1724 << PrivateFilename << 1
1725 << File.getDir().getName().ends_with(".framework");
1726 }
1727 return PMMFile;
1728}
1729
1731 FileID ID, unsigned *Offset,
1732 StringRef OriginalModuleMapFile) {
1733 // Find the directory for the module. For frameworks, that may require going
1734 // up from the 'Modules' directory.
1736 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
1737 Dir = FileMgr.getOptionalDirectoryRef(".");
1738 } else {
1739 if (!OriginalModuleMapFile.empty()) {
1740 // We're building a preprocessed module map. Find or invent the directory
1741 // that it originally occupied.
1742 Dir = FileMgr.getOptionalDirectoryRef(
1743 llvm::sys::path::parent_path(OriginalModuleMapFile));
1744 if (!Dir) {
1745 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1746 Dir = FakeFile.getDir();
1747 }
1748 } else {
1749 Dir = File.getDir();
1750 }
1751
1752 assert(Dir && "parent must exist");
1753 StringRef DirName(Dir->getName());
1754 if (llvm::sys::path::filename(DirName) == "Modules") {
1755 DirName = llvm::sys::path::parent_path(DirName);
1756 if (DirName.ends_with(".framework"))
1757 if (auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
1758 Dir = *MaybeDir;
1759 // FIXME: This assert can fail if there's a race between the above check
1760 // and the removal of the directory.
1761 assert(Dir && "parent must exist");
1762 }
1763 }
1764
1765 assert(Dir && "module map home directory must exist");
1766 switch (parseAndLoadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) {
1767 case MMR_AlreadyProcessed:
1768 case MMR_NewlyProcessed:
1769 return false;
1770 case MMR_NoDirectory:
1771 case MMR_InvalidModuleMap:
1772 return true;
1773 }
1774 llvm_unreachable("Unknown load module map result");
1775}
1776
1777HeaderSearch::ModuleMapResult
1778HeaderSearch::parseAndLoadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
1779 DirectoryEntryRef Dir, FileID ID,
1780 unsigned *Offset) {
1781 // Check whether we've already loaded this module map, and mark it as being
1782 // loaded in case we recursively try to load it from itself.
1783 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1784 if (!AddResult.second)
1785 return AddResult.first->second ? MMR_AlreadyProcessed
1786 : MMR_InvalidModuleMap;
1787
1788 if (ModMap.parseAndLoadModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1789 LoadedModuleMaps[File] = false;
1790 return MMR_InvalidModuleMap;
1791 }
1792
1793 // Try to load a corresponding private module map.
1794 if (OptionalFileEntryRef PMMFile =
1795 getPrivateModuleMap(File, FileMgr, Diags, !ParsedModuleMaps[File])) {
1796 if (ModMap.parseAndLoadModuleMapFile(*PMMFile, IsSystem, Dir)) {
1797 LoadedModuleMaps[File] = false;
1798 return MMR_InvalidModuleMap;
1799 }
1800 }
1801
1802 // This directory has a module map.
1803 return MMR_NewlyProcessed;
1804}
1805
1806HeaderSearch::ModuleMapResult
1807HeaderSearch::parseModuleMapFileImpl(FileEntryRef File, bool IsSystem,
1808 DirectoryEntryRef Dir, FileID ID) {
1809 // Check whether we've already parsed this module map, and mark it as being
1810 // parsed in case we recursively try to parse it from itself.
1811 auto AddResult = ParsedModuleMaps.insert(std::make_pair(File, true));
1812 if (!AddResult.second)
1813 return AddResult.first->second ? MMR_AlreadyProcessed
1814 : MMR_InvalidModuleMap;
1815
1816 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID)) {
1817 ParsedModuleMaps[File] = false;
1818 return MMR_InvalidModuleMap;
1819 }
1820
1821 // Try to parse a corresponding private module map.
1822 if (OptionalFileEntryRef PMMFile =
1823 getPrivateModuleMap(File, FileMgr, Diags)) {
1824 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, Dir)) {
1825 ParsedModuleMaps[File] = false;
1826 return MMR_InvalidModuleMap;
1827 }
1828 }
1829
1830 // This directory has a module map.
1831 return MMR_NewlyProcessed;
1832}
1833
1836 if (!HSOpts.ImplicitModuleMaps)
1837 return std::nullopt;
1838 // For frameworks, the preferred spelling is Modules/module.modulemap, but
1839 // module.map at the framework root is also accepted.
1840 SmallString<128> ModuleMapFileName(Dir.getName());
1841 if (IsFramework)
1842 llvm::sys::path::append(ModuleMapFileName, "Modules");
1843 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1844 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1845 return *F;
1846
1847 // Continue to allow module.map, but warn it's deprecated.
1848 ModuleMapFileName = Dir.getName();
1849 llvm::sys::path::append(ModuleMapFileName, "module.map");
1850 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
1851 Diags.Report(diag::warn_deprecated_module_dot_map)
1852 << ModuleMapFileName << 0 << IsFramework;
1853 return *F;
1854 }
1855
1856 // For frameworks, allow to have a private module map with a preferred
1857 // spelling when a public module map is absent.
1858 if (IsFramework) {
1859 ModuleMapFileName = Dir.getName();
1860 llvm::sys::path::append(ModuleMapFileName, "Modules",
1861 "module.private.modulemap");
1862 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1863 return *F;
1864 }
1865 return std::nullopt;
1866}
1867
1868Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
1869 bool IsSystem) {
1870 // Try to load a module map file.
1871 switch (parseAndLoadModuleMapFile(Dir, IsSystem, /*IsFramework*/ true)) {
1872 case MMR_InvalidModuleMap:
1873 // Try to infer a module map from the framework directory.
1874 if (HSOpts.ImplicitModuleMaps)
1875 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1876 break;
1877
1878 case MMR_NoDirectory:
1879 return nullptr;
1880
1881 case MMR_AlreadyProcessed:
1882 case MMR_NewlyProcessed:
1883 break;
1884 }
1885
1886 return ModMap.findOrLoadModule(Name);
1887}
1888
1889HeaderSearch::ModuleMapResult
1890HeaderSearch::parseAndLoadModuleMapFile(StringRef DirName, bool IsSystem,
1891 bool IsFramework) {
1892 if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
1893 return parseAndLoadModuleMapFile(*Dir, IsSystem, IsFramework);
1894
1895 return MMR_NoDirectory;
1896}
1897
1898HeaderSearch::ModuleMapResult
1900 bool IsFramework) {
1901 auto InsertRes = DirectoryModuleMap.insert(std::pair{
1902 Dir, ModuleMapDirectoryState{{}, ModuleMapDirectoryState::Invalid}});
1903 ModuleMapDirectoryState &MMState = InsertRes.first->second;
1904 if (!InsertRes.second) {
1905 switch (MMState.Status) {
1906 case ModuleMapDirectoryState::Parsed:
1907 break;
1908 case ModuleMapDirectoryState::Loaded:
1909 return MMR_AlreadyProcessed;
1910 case ModuleMapDirectoryState::Invalid:
1911 return MMR_InvalidModuleMap;
1912 };
1913 }
1914
1915 if (!MMState.ModuleMapFile)
1916 MMState.ModuleMapFile = lookupModuleMapFile(Dir, IsFramework);
1917
1918 if (MMState.ModuleMapFile) {
1919 ModuleMapResult Result =
1920 parseAndLoadModuleMapFileImpl(*MMState.ModuleMapFile, IsSystem, Dir);
1921 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1922 // E.g. Foo.framework/Modules/module.modulemap
1923 // ^Dir ^ModuleMapFile
1924 if (Result == MMR_NewlyProcessed)
1925 MMState.Status = ModuleMapDirectoryState::Loaded;
1926 else if (Result == MMR_InvalidModuleMap)
1927 MMState.Status = ModuleMapDirectoryState::Invalid;
1928 return Result;
1929 }
1930 return MMR_InvalidModuleMap;
1931}
1932
1933HeaderSearch::ModuleMapResult
1934HeaderSearch::parseModuleMapFile(StringRef DirName, bool IsSystem,
1935 bool IsFramework) {
1936 if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
1937 return parseModuleMapFile(*Dir, IsSystem, IsFramework);
1938
1939 return MMR_NoDirectory;
1940}
1941
1942HeaderSearch::ModuleMapResult
1943HeaderSearch::parseModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
1944 bool IsFramework) {
1945 auto InsertRes = DirectoryModuleMap.insert(std::pair{
1946 Dir, ModuleMapDirectoryState{{}, ModuleMapDirectoryState::Invalid}});
1947 ModuleMapDirectoryState &MMState = InsertRes.first->second;
1948 if (!InsertRes.second) {
1949 switch (MMState.Status) {
1950 case ModuleMapDirectoryState::Parsed:
1951 case ModuleMapDirectoryState::Loaded:
1952 return MMR_AlreadyProcessed;
1953 case ModuleMapDirectoryState::Invalid:
1954 return MMR_InvalidModuleMap;
1955 };
1956 }
1957
1958 if (!MMState.ModuleMapFile)
1959 MMState.ModuleMapFile = lookupModuleMapFile(Dir, IsFramework);
1960
1961 if (MMState.ModuleMapFile) {
1962 ModuleMapResult Result =
1963 parseModuleMapFileImpl(*MMState.ModuleMapFile, IsSystem, Dir);
1964 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1965 // E.g. Foo.framework/Modules/module.modulemap
1966 // ^Dir ^ModuleMapFile
1967 if (Result == MMR_NewlyProcessed)
1968 MMState.Status = ModuleMapDirectoryState::Parsed;
1969 else if (Result == MMR_InvalidModuleMap)
1970 MMState.Status = ModuleMapDirectoryState::Invalid;
1971 return Result;
1972 }
1973 return MMR_InvalidModuleMap;
1974}
1975
1977 Modules.clear();
1978
1979 if (HSOpts.ImplicitModuleMaps) {
1980 // Load module maps for each of the header search directories.
1981 for (DirectoryLookup &DL : search_dir_range()) {
1982 bool IsSystem = DL.isSystemHeaderDirectory();
1983 if (DL.isFramework()) {
1984 std::error_code EC;
1985 SmallString<128> DirNative;
1986 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
1987
1988 // Search each of the ".framework" directories to load them as modules.
1989 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1990 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1991 DirEnd;
1992 Dir != DirEnd && !EC; Dir.increment(EC)) {
1993 if (llvm::sys::path::extension(Dir->path()) != ".framework")
1994 continue;
1995
1996 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
1997 if (!FrameworkDir)
1998 continue;
1999
2000 // Load this framework module.
2001 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2002 IsSystem);
2003 }
2004 continue;
2005 }
2006
2007 // FIXME: Deal with header maps.
2008 if (DL.isHeaderMap())
2009 continue;
2010
2011 // Try to load a module map file for the search directory.
2012 parseAndLoadModuleMapFile(*DL.getDirRef(), IsSystem,
2013 /*IsFramework*/ false);
2014
2015 // Try to load module map files for immediate subdirectories of this
2016 // search directory.
2017 loadSubdirectoryModuleMaps(DL);
2018 }
2019 }
2020
2021 // Populate the list of modules.
2022 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2023}
2024
2026 if (!HSOpts.ImplicitModuleMaps)
2027 return;
2028
2029 // Load module maps for each of the header search directories.
2030 for (const DirectoryLookup &DL : search_dir_range()) {
2031 // We only care about normal header directories.
2032 if (!DL.isNormalDir())
2033 continue;
2034
2035 // Try to load a module map file for the search directory.
2036 parseAndLoadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(),
2037 DL.isFramework());
2038 }
2039}
2040
2041void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
2042 assert(HSOpts.ImplicitModuleMaps &&
2043 "Should not be loading subdirectory module maps");
2044
2045 if (SearchDir.haveSearchedAllModuleMaps())
2046 return;
2047
2048 std::error_code EC;
2049 SmallString<128> Dir = SearchDir.getDirRef()->getName();
2050 FileMgr.makeAbsolutePath(Dir);
2051 SmallString<128> DirNative;
2052 llvm::sys::path::native(Dir, DirNative);
2053 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2054 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2055 Dir != DirEnd && !EC; Dir.increment(EC)) {
2056 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2057 continue;
2058 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
2059 if (IsFramework == SearchDir.isFramework())
2060 parseAndLoadModuleMapFile(Dir->path(),
2061 SearchDir.isSystemHeaderDirectory(),
2062 SearchDir.isFramework());
2063 }
2064
2065 SearchDir.setSearchedAllModuleMaps(true);
2066}
2067
2069 FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled) const {
2070 return suggestPathToFileForDiagnostics(File.getName(), /*WorkingDir=*/"",
2071 MainFile, IsAngled);
2072}
2073
2075 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2076 bool *IsAngled) const {
2077 using namespace llvm::sys;
2078
2079 llvm::SmallString<32> FilePath = File;
2080 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2081 fs::make_absolute(WorkingDir, FilePath);
2082 // remove_dots switches to backslashes on windows as a side-effect!
2083 // We always want to suggest forward slashes for includes.
2084 // (not remove_dots(..., posix) as that misparses windows paths).
2085 path::remove_dots(FilePath, /*remove_dot_dot=*/true);
2086 path::native(FilePath, path::Style::posix);
2087 File = FilePath;
2088
2089 unsigned BestPrefixLength = 0;
2090 // Checks whether `Dir` is a strict path prefix of `File`. If so and that's
2091 // the longest prefix we've seen so for it, returns true and updates the
2092 // `BestPrefixLength` accordingly.
2093 auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
2094 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2095 fs::make_absolute(WorkingDir, Dir);
2096 path::remove_dots(Dir, /*remove_dot_dot=*/true);
2097 for (auto NI = path::begin(File), NE = path::end(File),
2098 DI = path::begin(Dir), DE = path::end(Dir);
2099 NI != NE; ++NI, ++DI) {
2100 if (DI == DE) {
2101 // Dir is a prefix of File, up to choice of path separators.
2102 unsigned PrefixLength = NI - path::begin(File);
2103 if (PrefixLength > BestPrefixLength) {
2104 BestPrefixLength = PrefixLength;
2105 return true;
2106 }
2107 break;
2108 }
2109
2110 // Consider all path separators equal.
2111 if (NI->size() == 1 && DI->size() == 1 &&
2112 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2113 continue;
2114
2115 // Special case Apple .sdk folders since the search path is typically a
2116 // symlink like `iPhoneSimulator14.5.sdk` while the file is instead
2117 // located in `iPhoneSimulator.sdk` (the real folder).
2118 if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) {
2119 StringRef NBasename = path::stem(*NI);
2120 StringRef DBasename = path::stem(*DI);
2121 if (DBasename.starts_with(NBasename))
2122 continue;
2123 }
2124
2125 if (*NI != *DI)
2126 break;
2127 }
2128 return false;
2129 };
2130
2131 bool BestPrefixIsFramework = false;
2132 for (const DirectoryLookup &DL : search_dir_range()) {
2133 if (DL.isNormalDir()) {
2134 StringRef Dir = DL.getDirRef()->getName();
2135 if (CheckDir(Dir)) {
2136 if (IsAngled)
2137 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2138 BestPrefixIsFramework = false;
2139 }
2140 } else if (DL.isFramework()) {
2141 StringRef Dir = DL.getFrameworkDirRef()->getName();
2142 if (CheckDir(Dir)) {
2143 // Framework includes by convention use <>.
2144 if (IsAngled)
2145 *IsAngled = BestPrefixLength;
2146 BestPrefixIsFramework = true;
2147 }
2148 }
2149 }
2150
2151 // Try to shorten include path using TUs directory, if we couldn't find any
2152 // suitable prefix in include search paths.
2153 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2154 if (IsAngled)
2155 *IsAngled = false;
2156 BestPrefixIsFramework = false;
2157 }
2158
2159 // Try resolving resulting filename via reverse search in header maps,
2160 // key from header name is user preferred name for the include file.
2161 StringRef Filename = File.drop_front(BestPrefixLength);
2162 for (const DirectoryLookup &DL : search_dir_range()) {
2163 if (!DL.isHeaderMap())
2164 continue;
2165
2166 StringRef SpelledFilename =
2167 DL.getHeaderMap()->reverseLookupFilename(Filename);
2168 if (!SpelledFilename.empty()) {
2169 Filename = SpelledFilename;
2170 BestPrefixIsFramework = false;
2171 break;
2172 }
2173 }
2174
2175 // If the best prefix is a framework path, we need to compute the proper
2176 // include spelling for the framework header.
2177 bool IsPrivateHeader;
2178 SmallString<128> FrameworkName, IncludeSpelling;
2179 if (BestPrefixIsFramework &&
2180 isFrameworkStylePath(Filename, IsPrivateHeader, FrameworkName,
2181 IncludeSpelling)) {
2182 Filename = IncludeSpelling;
2183 }
2184 return path::convert_to_slash(Filename);
2185}
Defines the Diagnostic-related interfaces.
IndirectLocalPath & Path
Expr * E
Defines the clang::FileManager interface and associated types.
StringRef Filename
Definition: Format.cpp:3177
unsigned Iter
Definition: HTMLLogger.cpp:153
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.
llvm::MachO::Target Target
Definition: MachO.h:51
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::Preprocessor interface.
SourceLocation Loc
Definition: SemaObjC.cpp:754
Defines the SourceManager interface.
constexpr bool has_value() const
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:231
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1529
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:950
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:352
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:306
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
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:219
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:208
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:175
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:139
This class represents an Apple concept known as a 'header map'.
Definition: HeaderMap.h:84
StringRef getFileName() const
Return the filename of the headermap.
Definition: HeaderMap.cpp:108
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,...
Definition: HeaderMap.cpp:200
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...
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
std::vector< std::string > PrebuiltModulePaths
The directories used to load prebuilt module files.
unsigned ImplicitModuleMaps
Implicit module maps.
std::vector< Entry > UserEntries
User specified include entries.
unsigned AllowModuleMapSubdirectorySearch
Whether we should look for a module in module maps only in provided header search paths or if we are ...
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,...
Definition: HeaderSearch.h:237
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
Definition: HeaderSearch.h:386
void AddSearchPath(const DirectoryLookup &dir, bool isAngled)
Add an additional search path.
Module * lookupModule(StringRef ModuleName, SourceLocation ImportLoc=SourceLocation(), bool AllowSearch=true, bool AllowExtraModuleMapSearch=false)
Lookup a module Search for a module with the given name.
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 #inclu...
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.
Definition: HeaderSearch.h:448
ConstSearchDirIterator angled_dir_begin() const
Definition: HeaderSearch.h:871
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
Definition: HeaderSearch.h:857
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()
Definition: HeaderSearch.h:851
FrameworkCacheEntry & LookupFrameworkCache(StringRef FWName)
Look up the specified framework name in our framework cache.
Definition: HeaderSearch.h:530
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.
Definition: HeaderSearch.h:384
SearchDirRange search_dir_range()
Definition: HeaderSearch.h:852
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.
Definition: HeaderSearch.h:831
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.
Definition: HeaderSearch.h:445
SearchDirIterator search_dir_begin()
Definition: HeaderSearch.h:850
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...
Definition: LangOptions.h:434
bool isValid() const
Whether this pointer is non-NULL.
bool isID() const
Whether this pointer is currently stored as ID.
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.
Definition: ModuleMap.cpp:2237
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Definition: ModuleMap.cpp:594
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
Definition: ModuleMap.cpp:102
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Definition: ModuleMap.cpp:1261
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
Definition: ModuleMap.cpp:705
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Definition: ModuleMap.cpp:1422
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Definition: ModuleMap.cpp:403
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef Dir, FileID ID=FileID(), SourceLocation ExternModuleLoc=SourceLocation())
Parse a module map without creating clang::Module instances.
Definition: ModuleMap.cpp:1324
void setTarget(const TargetInfo &Target)
Set the target information.
Definition: ModuleMap.cpp:360
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
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Definition: ModuleMap.cpp:693
Module * findOrLoadModule(StringRef Name)
Definition: ModuleMap.cpp:2215
llvm::iterator_range< module_iterator > modules() const
Definition: ModuleMap.h:749
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Definition: ModuleMap.cpp:1504
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.
Definition: Preprocessor.h:145
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.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Result
The result type of a method or function.
#define false
Definition: stdbool.h:26
This structure is used to record entries in our framework cache.
Definition: HeaderSearch.h:160
bool IsUserSpecifiedSystemFramework
Whether this framework has been "user-specified" to be treated as if it were a system framework (even...
Definition: HeaderSearch.h:167
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
Definition: HeaderSearch.h:162
The preprocessor keeps track of this information for each file that is #included.
Definition: HeaderSearch.h:59
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,...
Definition: HeaderSearch.h:123
unsigned DirInfo
Keep track of whether this is a system header, and if so, whether it is C++ clean or not.
Definition: HeaderSearch.h:81
unsigned isModuleHeader
Whether this header is part of and built with a module.
Definition: HeaderSearch.h:92
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.
Definition: HeaderSearch.h:98
unsigned isPragmaOnce
True if this is a #pragma once file.
Definition: HeaderSearch.h:74
unsigned Resolved
Whether this structure is considered to already have been "resolved", meaning that it was loaded from...
Definition: HeaderSearch.h:109
unsigned isCompilingModuleHeader
Whether this header is part of the module that we are building, even if it doesn't build with the mod...
Definition: HeaderSearch.h:104
unsigned IsValid
Whether this file has been looked up as a header.
Definition: HeaderSearch.h:113
unsigned isImport
True if this is a #import'd file.
Definition: HeaderSearch.h:70
unsigned External
Whether this header file info was supplied by an external source, and has not changed since.
Definition: HeaderSearch.h:86