[mlir][LLVM] `LLVMTypeConverter`: Tighten materialization checks (#116532)
[llvm-project.git] / clang / lib / Lex / HeaderSearch.cpp
blobbf8fe44e4ca9ca45cee72caf6e9237be1dfc30cd
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.
11 //===----------------------------------------------------------------------===//
13 #include "clang/Lex/HeaderSearch.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/IdentifierTable.h"
17 #include "clang/Basic/Module.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "clang/Lex/DirectoryLookup.h"
20 #include "clang/Lex/ExternalPreprocessorSource.h"
21 #include "clang/Lex/HeaderMap.h"
22 #include "clang/Lex/HeaderSearchOptions.h"
23 #include "clang/Lex/LexDiagnostic.h"
24 #include "clang/Lex/ModuleMap.h"
25 #include "clang/Lex/Preprocessor.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>
49 using namespace clang;
51 #define DEBUG_TYPE "file-search"
53 ALWAYS_ENABLED_STATISTIC(NumIncluded, "Number of attempted #includes.");
54 ALWAYS_ENABLED_STATISTIC(
55 NumMultiIncludeFileOptzn,
56 "Number of #includes skipped due to the multi-include optimization.");
57 ALWAYS_ENABLED_STATISTIC(NumFrameworkLookups, "Number of framework lookups.");
58 ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
59 "Number of subframework lookups.");
61 const IdentifierInfo *
62 HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
63 if (LazyControllingMacro.isID()) {
64 if (!External)
65 return nullptr;
67 LazyControllingMacro =
68 External->GetIdentifier(LazyControllingMacro.getID());
69 return LazyControllingMacro.getPtr();
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);
78 return ControllingMacro;
81 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() = default;
83 HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
84 SourceManager &SourceMgr, DiagnosticsEngine &Diags,
85 const LangOptions &LangOpts,
86 const TargetInfo *Target)
87 : HSOpts(std::move(HSOpts)), Diags(Diags),
88 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
89 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
91 void HeaderSearch::PrintStats() {
92 llvm::errs() << "\n*** HeaderSearch Stats:\n"
93 << FileInfo.size() << " files tracked.\n";
94 unsigned NumOnceOnlyFiles = 0;
95 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i)
96 NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
97 llvm::errs() << " " << NumOnceOnlyFiles << " #import/#pragma once files.\n";
99 llvm::errs() << " " << NumIncluded << " #include/#include_next/#import.\n"
100 << " " << NumMultiIncludeFileOptzn
101 << " #includes skipped due to the multi-include optimization.\n";
103 llvm::errs() << NumFrameworkLookups << " framework lookups.\n"
104 << NumSubFrameworkLookups << " subframework lookups.\n";
107 void HeaderSearch::SetSearchPaths(
108 std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx,
109 unsigned int systemDirIdx,
110 llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
111 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
112 "Directory indices are unordered");
113 SearchDirs = std::move(dirs);
114 SearchDirsUsage.assign(SearchDirs.size(), false);
115 AngledDirIdx = angledDirIdx;
116 SystemDirIdx = systemDirIdx;
117 SearchDirToHSEntry = std::move(searchDirToHSEntry);
118 //LookupFileCache.clear();
119 indexInitialHeaderMaps();
122 void HeaderSearch::AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
123 unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
124 SearchDirs.insert(SearchDirs.begin() + idx, dir);
125 SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false);
126 if (!isAngled)
127 AngledDirIdx++;
128 SystemDirIdx++;
131 std::vector<bool> HeaderSearch::computeUserEntryUsage() const {
132 std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size());
133 for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
134 // Check whether this DirectoryLookup has been successfully used.
135 if (SearchDirsUsage[I]) {
136 auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
137 // Check whether this DirectoryLookup maps to a HeaderSearch::UserEntry.
138 if (UserEntryIdxIt != SearchDirToHSEntry.end())
139 UserEntryUsage[UserEntryIdxIt->second] = true;
142 return UserEntryUsage;
145 std::vector<bool> HeaderSearch::collectVFSUsageAndClear() const {
146 std::vector<bool> VFSUsage;
147 if (!getHeaderSearchOpts().ModulesIncludeVFSUsage)
148 return VFSUsage;
150 llvm::vfs::FileSystem &RootFS = FileMgr.getVirtualFileSystem();
151 // TODO: This only works if the `RedirectingFileSystem`s were all created by
152 // `createVFSFromOverlayFiles`.
153 RootFS.visit([&](llvm::vfs::FileSystem &FS) {
154 if (auto *RFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&FS)) {
155 VFSUsage.push_back(RFS->hasBeenUsed());
156 RFS->clearHasBeenUsed();
159 assert(VFSUsage.size() == getHeaderSearchOpts().VFSOverlayFiles.size() &&
160 "A different number of RedirectingFileSystem's were present than "
161 "-ivfsoverlay options passed to Clang!");
162 // VFS visit order is the opposite of VFSOverlayFiles order.
163 std::reverse(VFSUsage.begin(), VFSUsage.end());
164 return VFSUsage;
167 /// CreateHeaderMap - This method returns a HeaderMap for the specified
168 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
169 const HeaderMap *HeaderSearch::CreateHeaderMap(FileEntryRef FE) {
170 // We expect the number of headermaps to be small, and almost always empty.
171 // If it ever grows, use of a linear search should be re-evaluated.
172 if (!HeaderMaps.empty()) {
173 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
174 // Pointer equality comparison of FileEntries works because they are
175 // already uniqued by inode.
176 if (HeaderMaps[i].first == FE)
177 return HeaderMaps[i].second.get();
180 if (std::unique_ptr<HeaderMap> HM = HeaderMap::Create(FE, FileMgr)) {
181 HeaderMaps.emplace_back(FE, std::move(HM));
182 return HeaderMaps.back().second.get();
185 return nullptr;
188 /// Get filenames for all registered header maps.
189 void HeaderSearch::getHeaderMapFileNames(
190 SmallVectorImpl<std::string> &Names) const {
191 for (auto &HM : HeaderMaps)
192 Names.push_back(std::string(HM.first.getName()));
195 std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
196 OptionalFileEntryRef ModuleMap =
197 getModuleMap().getModuleMapFileForUniquing(Module);
198 // The ModuleMap maybe a nullptr, when we load a cached C++ module without
199 // *.modulemap file. In this case, just return an empty string.
200 if (!ModuleMap)
201 return {};
202 return getCachedModuleFileName(Module->Name, ModuleMap->getNameAsRequested());
205 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
206 bool FileMapOnly) {
207 // First check the module name to pcm file map.
208 auto i(HSOpts->PrebuiltModuleFiles.find(ModuleName));
209 if (i != HSOpts->PrebuiltModuleFiles.end())
210 return i->second;
212 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
213 return {};
215 // Then go through each prebuilt module directory and try to find the pcm
216 // file.
217 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
218 SmallString<256> Result(Dir);
219 llvm::sys::fs::make_absolute(Result);
220 if (ModuleName.contains(':'))
221 // The separator of C++20 modules partitions (':') is not good for file
222 // systems, here clang and gcc choose '-' by default since it is not a
223 // valid character of C++ indentifiers. So we could avoid conflicts.
224 llvm::sys::path::append(Result, ModuleName.split(':').first + "-" +
225 ModuleName.split(':').second +
226 ".pcm");
227 else
228 llvm::sys::path::append(Result, ModuleName + ".pcm");
229 if (getFileMgr().getOptionalFileRef(Result))
230 return std::string(Result);
233 return {};
236 std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
237 OptionalFileEntryRef ModuleMap =
238 getModuleMap().getModuleMapFileForUniquing(Module);
239 StringRef ModuleName = Module->Name;
240 StringRef ModuleMapPath = ModuleMap->getName();
241 StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash();
242 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
243 SmallString<256> CachePath(Dir);
244 llvm::sys::fs::make_absolute(CachePath);
245 llvm::sys::path::append(CachePath, ModuleCacheHash);
246 std::string FileName =
247 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
248 if (!FileName.empty() && getFileMgr().getOptionalFileRef(FileName))
249 return FileName;
251 return {};
254 std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
255 StringRef ModuleMapPath) {
256 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
257 getModuleCachePath());
260 std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
261 StringRef ModuleMapPath,
262 StringRef CachePath) {
263 // If we don't have a module cache path or aren't supposed to use one, we
264 // can't do anything.
265 if (CachePath.empty())
266 return {};
268 SmallString<256> Result(CachePath);
270 if (HSOpts->DisableModuleHash) {
271 llvm::sys::path::append(Result, ModuleName + ".pcm");
272 } else {
273 // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
274 // ideally be globally unique to this particular module. Name collisions
275 // in the hash are safe (because any translation unit can only import one
276 // module with each name), but result in a loss of caching.
278 // To avoid false-negatives, we form as canonical a path as we can, and map
279 // to lower-case in case we're on a case-insensitive file system.
280 SmallString<128> CanonicalPath(ModuleMapPath);
281 if (getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
282 return {};
284 auto Hash = llvm::xxh3_64bits(CanonicalPath.str().lower());
286 SmallString<128> HashStr;
287 llvm::APInt(64, Hash).toStringUnsigned(HashStr, /*Radix*/36);
288 llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
290 return Result.str().str();
293 Module *HeaderSearch::lookupModule(StringRef ModuleName,
294 SourceLocation ImportLoc, bool AllowSearch,
295 bool AllowExtraModuleMapSearch) {
296 // Look in the module map to determine if there is a module by this name.
297 Module *Module = ModMap.findModule(ModuleName);
298 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
299 return Module;
301 StringRef SearchName = ModuleName;
302 Module = lookupModule(ModuleName, SearchName, ImportLoc,
303 AllowExtraModuleMapSearch);
305 // The facility for "private modules" -- adjacent, optional module maps named
306 // module.private.modulemap that are supposed to define private submodules --
307 // may have different flavors of names: FooPrivate, Foo_Private and Foo.Private.
309 // Foo.Private is now deprecated in favor of Foo_Private. Users of FooPrivate
310 // should also rename to Foo_Private. Representing private as submodules
311 // could force building unwanted dependencies into the parent module and cause
312 // dependency cycles.
313 if (!Module && SearchName.consume_back("_Private"))
314 Module = lookupModule(ModuleName, SearchName, ImportLoc,
315 AllowExtraModuleMapSearch);
316 if (!Module && SearchName.consume_back("Private"))
317 Module = lookupModule(ModuleName, SearchName, ImportLoc,
318 AllowExtraModuleMapSearch);
319 return Module;
322 Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
323 SourceLocation ImportLoc,
324 bool AllowExtraModuleMapSearch) {
325 Module *Module = nullptr;
327 // Look through the various header search paths to load any available module
328 // maps, searching for a module map that describes this module.
329 for (DirectoryLookup &Dir : search_dir_range()) {
330 if (Dir.isFramework()) {
331 // Search for or infer a module map for a framework. Here we use
332 // SearchName rather than ModuleName, to permit finding private modules
333 // named FooPrivate in buggy frameworks named Foo.
334 SmallString<128> FrameworkDirName;
335 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
336 llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
337 if (auto FrameworkDir =
338 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
339 bool IsSystem = Dir.getDirCharacteristic() != SrcMgr::C_User;
340 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
341 if (Module)
342 break;
346 // FIXME: Figure out how header maps and module maps will work together.
348 // Only deal with normal search directories.
349 if (!Dir.isNormalDir())
350 continue;
352 bool IsSystem = Dir.isSystemHeaderDirectory();
353 // Only returns std::nullopt if not a normal directory, which we just
354 // checked
355 DirectoryEntryRef NormalDir = *Dir.getDirRef();
356 // Search for a module map file in this directory.
357 if (loadModuleMapFile(NormalDir, IsSystem,
358 /*IsFramework*/false) == LMM_NewlyLoaded) {
359 // We just loaded a module map file; check whether the module is
360 // available now.
361 Module = ModMap.findModule(ModuleName);
362 if (Module)
363 break;
366 // Search for a module map in a subdirectory with the same name as the
367 // module.
368 SmallString<128> NestedModuleMapDirName;
369 NestedModuleMapDirName = Dir.getDirRef()->getName();
370 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
371 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
372 /*IsFramework*/false) == LMM_NewlyLoaded){
373 // If we just loaded a module map file, look for the module again.
374 Module = ModMap.findModule(ModuleName);
375 if (Module)
376 break;
379 if (HSOpts->AllowModuleMapSubdirectorySearch) {
380 // If we've already performed the exhaustive search for module maps in
381 // this search directory, don't do it again.
382 if (Dir.haveSearchedAllModuleMaps())
383 continue;
385 // Load all module maps in the immediate subdirectories of this search
386 // directory if ModuleName was from @import.
387 if (AllowExtraModuleMapSearch)
388 loadSubdirectoryModuleMaps(Dir);
390 // Look again for the module.
391 Module = ModMap.findModule(ModuleName);
392 if (Module)
393 break;
397 return Module;
400 void HeaderSearch::indexInitialHeaderMaps() {
401 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
403 // Iterate over all filename keys and associate them with the index i.
404 for (unsigned i = 0; i != SearchDirs.size(); ++i) {
405 auto &Dir = SearchDirs[i];
407 // We're concerned with only the initial contiguous run of header
408 // maps within SearchDirs, which can be 99% of SearchDirs when
409 // SearchDirs.size() is ~10000.
410 if (!Dir.isHeaderMap()) {
411 SearchDirHeaderMapIndex = std::move(Index);
412 FirstNonHeaderMapSearchDirIdx = i;
413 break;
416 // Give earlier keys precedence over identical later keys.
417 auto Callback = [&](StringRef Filename) {
418 Index.try_emplace(Filename.lower(), i);
420 Dir.getHeaderMap()->forEachKey(Callback);
424 //===----------------------------------------------------------------------===//
425 // File lookup within a DirectoryLookup scope
426 //===----------------------------------------------------------------------===//
428 /// getName - Return the directory or filename corresponding to this lookup
429 /// object.
430 StringRef DirectoryLookup::getName() const {
431 if (isNormalDir())
432 return getDirRef()->getName();
433 if (isFramework())
434 return getFrameworkDirRef()->getName();
435 assert(isHeaderMap() && "Unknown DirectoryLookup");
436 return getHeaderMap()->getFileName();
439 OptionalFileEntryRef HeaderSearch::getFileAndSuggestModule(
440 StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
441 bool IsSystemHeaderDir, Module *RequestingModule,
442 ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/,
443 bool CacheFailures /*=true*/) {
444 // If we have a module map that might map this header, load it and
445 // check whether we'll have a suggestion for a module.
446 auto File = getFileMgr().getFileRef(FileName, OpenFile, CacheFailures);
447 if (!File) {
448 // For rare, surprising errors (e.g. "out of file handles"), diag the EC
449 // message.
450 std::error_code EC = llvm::errorToErrorCode(File.takeError());
451 if (EC != llvm::errc::no_such_file_or_directory &&
452 EC != llvm::errc::invalid_argument &&
453 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
454 Diags.Report(IncludeLoc, diag::err_cannot_open_file)
455 << FileName << EC.message();
457 return std::nullopt;
460 // If there is a module that corresponds to this header, suggest it.
461 if (!findUsableModuleForHeader(
462 *File, Dir ? Dir : File->getFileEntry().getDir(), RequestingModule,
463 SuggestedModule, IsSystemHeaderDir))
464 return std::nullopt;
466 return *File;
469 /// LookupFile - Lookup the specified file in this search path, returning it
470 /// if it exists or returning null if not.
471 OptionalFileEntryRef DirectoryLookup::LookupFile(
472 StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
473 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
474 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
475 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
476 bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName,
477 bool OpenFile) const {
478 InUserSpecifiedSystemFramework = false;
479 IsInHeaderMap = false;
480 MappedName.clear();
482 SmallString<1024> TmpDir;
483 if (isNormalDir()) {
484 // Concatenate the requested file onto the directory.
485 TmpDir = getDirRef()->getName();
486 llvm::sys::path::append(TmpDir, Filename);
487 if (SearchPath) {
488 StringRef SearchPathRef(getDirRef()->getName());
489 SearchPath->clear();
490 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
492 if (RelativePath) {
493 RelativePath->clear();
494 RelativePath->append(Filename.begin(), Filename.end());
497 return HS.getFileAndSuggestModule(
498 TmpDir, IncludeLoc, getDir(), isSystemHeaderDirectory(),
499 RequestingModule, SuggestedModule, OpenFile);
502 if (isFramework())
503 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
504 RequestingModule, SuggestedModule,
505 InUserSpecifiedSystemFramework, IsFrameworkFound);
507 assert(isHeaderMap() && "Unknown directory lookup");
508 const HeaderMap *HM = getHeaderMap();
509 SmallString<1024> Path;
510 StringRef Dest = HM->lookupFilename(Filename, Path);
511 if (Dest.empty())
512 return std::nullopt;
514 IsInHeaderMap = true;
516 auto FixupSearchPathAndFindUsableModule =
517 [&](FileEntryRef File) -> OptionalFileEntryRef {
518 if (SearchPath) {
519 StringRef SearchPathRef(getName());
520 SearchPath->clear();
521 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
523 if (RelativePath) {
524 RelativePath->clear();
525 RelativePath->append(Filename.begin(), Filename.end());
527 if (!HS.findUsableModuleForHeader(File, File.getFileEntry().getDir(),
528 RequestingModule, SuggestedModule,
529 isSystemHeaderDirectory())) {
530 return std::nullopt;
532 return File;
535 // Check if the headermap maps the filename to a framework include
536 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
537 // framework include.
538 if (llvm::sys::path::is_relative(Dest)) {
539 MappedName.append(Dest.begin(), Dest.end());
540 Filename = StringRef(MappedName.begin(), MappedName.size());
541 Dest = HM->lookupFilename(Filename, Path);
544 if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest, OpenFile)) {
545 return FixupSearchPathAndFindUsableModule(*Res);
548 // Header maps need to be marked as used whenever the filename matches.
549 // The case where the target file **exists** is handled by callee of this
550 // function as part of the regular logic that applies to include search paths.
551 // The case where the target file **does not exist** is handled here:
552 HS.noteLookupUsage(HS.searchDirIdx(*this), IncludeLoc);
553 return std::nullopt;
556 /// Given a framework directory, find the top-most framework directory.
558 /// \param FileMgr The file manager to use for directory lookups.
559 /// \param DirName The name of the framework directory.
560 /// \param SubmodulePath Will be populated with the submodule path from the
561 /// returned top-level module to the originally named framework.
562 static OptionalDirectoryEntryRef
563 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
564 SmallVectorImpl<std::string> &SubmodulePath) {
565 assert(llvm::sys::path::extension(DirName) == ".framework" &&
566 "Not a framework directory");
568 // Note: as an egregious but useful hack we use the real path here, because
569 // frameworks moving between top-level frameworks to embedded frameworks tend
570 // to be symlinked, and we base the logical structure of modules on the
571 // physical layout. In particular, we need to deal with crazy includes like
573 // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
575 // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
576 // which one should access with, e.g.,
578 // #include <Bar/Wibble.h>
580 // Similar issues occur when a top-level framework has moved into an
581 // embedded framework.
582 auto TopFrameworkDir = FileMgr.getOptionalDirectoryRef(DirName);
584 if (TopFrameworkDir)
585 DirName = FileMgr.getCanonicalName(*TopFrameworkDir);
586 do {
587 // Get the parent directory name.
588 DirName = llvm::sys::path::parent_path(DirName);
589 if (DirName.empty())
590 break;
592 // Determine whether this directory exists.
593 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
594 if (!Dir)
595 break;
597 // If this is a framework directory, then we're a subframework of this
598 // framework.
599 if (llvm::sys::path::extension(DirName) == ".framework") {
600 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
601 TopFrameworkDir = *Dir;
603 } while (true);
605 return TopFrameworkDir;
608 static bool needModuleLookup(Module *RequestingModule,
609 bool HasSuggestedModule) {
610 return HasSuggestedModule ||
611 (RequestingModule && RequestingModule->NoUndeclaredIncludes);
614 /// DoFrameworkLookup - Do a lookup of the specified file in the current
615 /// DirectoryLookup, which is a framework directory.
616 OptionalFileEntryRef DirectoryLookup::DoFrameworkLookup(
617 StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
618 SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
619 ModuleMap::KnownHeader *SuggestedModule,
620 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
621 FileManager &FileMgr = HS.getFileMgr();
623 // Framework names must have a '/' in the filename.
624 size_t SlashPos = Filename.find('/');
625 if (SlashPos == StringRef::npos)
626 return std::nullopt;
628 // Find out if this is the home for the specified framework, by checking
629 // HeaderSearch. Possible answers are yes/no and unknown.
630 FrameworkCacheEntry &CacheEntry =
631 HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
633 // If it is known and in some other directory, fail.
634 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDirRef())
635 return std::nullopt;
637 // Otherwise, construct the path to this framework dir.
639 // FrameworkName = "/System/Library/Frameworks/"
640 SmallString<1024> FrameworkName;
641 FrameworkName += getFrameworkDirRef()->getName();
642 if (FrameworkName.empty() || FrameworkName.back() != '/')
643 FrameworkName.push_back('/');
645 // FrameworkName = "/System/Library/Frameworks/Cocoa"
646 StringRef ModuleName(Filename.begin(), SlashPos);
647 FrameworkName += ModuleName;
649 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
650 FrameworkName += ".framework/";
652 // If the cache entry was unresolved, populate it now.
653 if (!CacheEntry.Directory) {
654 ++NumFrameworkLookups;
656 // If the framework dir doesn't exist, we fail.
657 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
658 if (!Dir)
659 return std::nullopt;
661 // Otherwise, if it does, remember that this is the right direntry for this
662 // framework.
663 CacheEntry.Directory = getFrameworkDirRef();
665 // If this is a user search directory, check if the framework has been
666 // user-specified as a system framework.
667 if (getDirCharacteristic() == SrcMgr::C_User) {
668 SmallString<1024> SystemFrameworkMarker(FrameworkName);
669 SystemFrameworkMarker += ".system_framework";
670 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
671 CacheEntry.IsUserSpecifiedSystemFramework = true;
676 // Set out flags.
677 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
678 IsFrameworkFound = CacheEntry.Directory.has_value();
680 if (RelativePath) {
681 RelativePath->clear();
682 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
685 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
686 unsigned OrigSize = FrameworkName.size();
688 FrameworkName += "Headers/";
690 if (SearchPath) {
691 SearchPath->clear();
692 // Without trailing '/'.
693 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
696 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
698 auto File =
699 FileMgr.getOptionalFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
700 if (!File) {
701 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
702 const char *Private = "Private";
703 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
704 Private+strlen(Private));
705 if (SearchPath)
706 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
707 Private+strlen(Private));
709 File = FileMgr.getOptionalFileRef(FrameworkName,
710 /*OpenFile=*/!SuggestedModule);
713 // If we found the header and are allowed to suggest a module, do so now.
714 if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
715 // Find the framework in which this header occurs.
716 StringRef FrameworkPath = File->getDir().getName();
717 bool FoundFramework = false;
718 do {
719 // Determine whether this directory exists.
720 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkPath);
721 if (!Dir)
722 break;
724 // If this is a framework directory, then we're a subframework of this
725 // framework.
726 if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
727 FoundFramework = true;
728 break;
731 // Get the parent directory name.
732 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
733 if (FrameworkPath.empty())
734 break;
735 } while (true);
737 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
738 if (FoundFramework) {
739 if (!HS.findUsableModuleForFrameworkHeader(*File, FrameworkPath,
740 RequestingModule,
741 SuggestedModule, IsSystem))
742 return std::nullopt;
743 } else {
744 if (!HS.findUsableModuleForHeader(*File, getDir(), RequestingModule,
745 SuggestedModule, IsSystem))
746 return std::nullopt;
749 if (File)
750 return *File;
751 return std::nullopt;
754 void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
755 ConstSearchDirIterator HitIt,
756 SourceLocation Loc) {
757 CacheLookup.HitIt = HitIt;
758 noteLookupUsage(HitIt.Idx, Loc);
761 void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
762 SearchDirsUsage[HitIdx] = true;
764 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
765 if (UserEntryIdxIt != SearchDirToHSEntry.end())
766 Diags.Report(Loc, diag::remark_pp_search_path_usage)
767 << HSOpts->UserEntries[UserEntryIdxIt->second].Path;
770 void HeaderSearch::setTarget(const TargetInfo &Target) {
771 ModMap.setTarget(Target);
774 //===----------------------------------------------------------------------===//
775 // Header File Location.
776 //===----------------------------------------------------------------------===//
778 /// Return true with a diagnostic if the file that MSVC would have found
779 /// fails to match the one that Clang would have found with MSVC header search
780 /// disabled.
781 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
782 OptionalFileEntryRef MSFE,
783 const FileEntry *FE,
784 SourceLocation IncludeLoc) {
785 if (MSFE && FE != *MSFE) {
786 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
787 return true;
789 return false;
792 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
793 assert(!Str.empty());
794 char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
795 std::copy(Str.begin(), Str.end(), CopyStr);
796 CopyStr[Str.size()] = '\0';
797 return CopyStr;
800 static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader,
801 SmallVectorImpl<char> &FrameworkName,
802 SmallVectorImpl<char> &IncludeSpelling) {
803 using namespace llvm::sys;
804 path::const_iterator I = path::begin(Path);
805 path::const_iterator E = path::end(Path);
806 IsPrivateHeader = false;
808 // Detect different types of framework style paths:
810 // ...Foo.framework/{Headers,PrivateHeaders}
811 // ...Foo.framework/Versions/{A,Current}/{Headers,PrivateHeaders}
812 // ...Foo.framework/Frameworks/Nested.framework/{Headers,PrivateHeaders}
813 // ...<other variations with 'Versions' like in the above path>
815 // and some other variations among these lines.
816 int FoundComp = 0;
817 while (I != E) {
818 if (*I == "Headers") {
819 ++FoundComp;
820 } else if (*I == "PrivateHeaders") {
821 ++FoundComp;
822 IsPrivateHeader = true;
823 } else if (I->ends_with(".framework")) {
824 StringRef Name = I->drop_back(10); // Drop .framework
825 // Need to reset the strings and counter to support nested frameworks.
826 FrameworkName.clear();
827 FrameworkName.append(Name.begin(), Name.end());
828 IncludeSpelling.clear();
829 IncludeSpelling.append(Name.begin(), Name.end());
830 FoundComp = 1;
831 } else if (FoundComp >= 2) {
832 IncludeSpelling.push_back('/');
833 IncludeSpelling.append(I->begin(), I->end());
835 ++I;
838 return !FrameworkName.empty() && FoundComp >= 2;
841 static void
842 diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc,
843 StringRef Includer, StringRef IncludeFilename,
844 FileEntryRef IncludeFE, bool isAngled = false,
845 bool FoundByHeaderMap = false) {
846 bool IsIncluderPrivateHeader = false;
847 SmallString<128> FromFramework, ToFramework;
848 SmallString<128> FromIncludeSpelling, ToIncludeSpelling;
849 if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework,
850 FromIncludeSpelling))
851 return;
852 bool IsIncludeePrivateHeader = false;
853 bool IsIncludeeInFramework =
854 isFrameworkStylePath(IncludeFE.getName(), IsIncludeePrivateHeader,
855 ToFramework, ToIncludeSpelling);
857 if (!isAngled && !FoundByHeaderMap) {
858 SmallString<128> NewInclude("<");
859 if (IsIncludeeInFramework) {
860 NewInclude += ToIncludeSpelling;
861 NewInclude += ">";
862 } else {
863 NewInclude += IncludeFilename;
864 NewInclude += ">";
866 Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
867 << IncludeFilename
868 << FixItHint::CreateReplacement(IncludeLoc, NewInclude);
871 // Headers in Foo.framework/Headers should not include headers
872 // from Foo.framework/PrivateHeaders, since this violates public/private
873 // API boundaries and can cause modular dependency cycles.
874 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
875 IsIncludeePrivateHeader && FromFramework == ToFramework)
876 Diags.Report(IncludeLoc, diag::warn_framework_include_private_from_public)
877 << IncludeFilename;
880 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
881 /// return null on failure. isAngled indicates whether the file reference is
882 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
883 /// non-empty, indicates where the \#including file(s) are, in case a relative
884 /// search is needed. Microsoft mode will pass all \#including files.
885 OptionalFileEntryRef HeaderSearch::LookupFile(
886 StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
887 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
888 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
889 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
890 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
891 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
892 bool BuildSystemModule, bool OpenFile, bool CacheFailures) {
893 ConstSearchDirIterator CurDirLocal = nullptr;
894 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
896 if (IsMapped)
897 *IsMapped = false;
899 if (IsFrameworkFound)
900 *IsFrameworkFound = false;
902 if (SuggestedModule)
903 *SuggestedModule = ModuleMap::KnownHeader();
905 // If 'Filename' is absolute, check to see if it exists and no searching.
906 if (llvm::sys::path::is_absolute(Filename)) {
907 CurDir = nullptr;
909 // If this was an #include_next "/absolute/file", fail.
910 if (FromDir)
911 return std::nullopt;
913 if (SearchPath)
914 SearchPath->clear();
915 if (RelativePath) {
916 RelativePath->clear();
917 RelativePath->append(Filename.begin(), Filename.end());
919 // Otherwise, just return the file.
920 return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
921 /*IsSystemHeaderDir*/ false,
922 RequestingModule, SuggestedModule, OpenFile,
923 CacheFailures);
926 // This is the header that MSVC's header search would have found.
927 ModuleMap::KnownHeader MSSuggestedModule;
928 OptionalFileEntryRef MSFE;
930 // Check to see if the file is in the #includer's directory. This cannot be
931 // based on CurDir, because each includer could be a #include of a
932 // subdirectory (#include "foo/bar.h") and a subsequent include of "baz.h"
933 // should resolve to "whatever/foo/baz.h". This search is not done for <>
934 // headers.
935 if (!Includers.empty() && !isAngled) {
936 SmallString<1024> TmpDir;
937 bool First = true;
938 for (const auto &IncluderAndDir : Includers) {
939 OptionalFileEntryRef Includer = IncluderAndDir.first;
941 // Concatenate the requested file onto the directory.
942 TmpDir = IncluderAndDir.second.getName();
943 llvm::sys::path::append(TmpDir, Filename);
945 // FIXME: We don't cache the result of getFileInfo across the call to
946 // getFileAndSuggestModule, because it's a reference to an element of
947 // a container that could be reallocated across this call.
949 // If we have no includer, that means we're processing a #include
950 // from a module build. We should treat this as a system header if we're
951 // building a [system] module.
952 bool IncluderIsSystemHeader = [&]() {
953 if (!Includer)
954 return BuildSystemModule;
955 const HeaderFileInfo *HFI = getExistingFileInfo(*Includer);
956 assert(HFI && "includer without file info");
957 return HFI->DirInfo != SrcMgr::C_User;
958 }();
959 if (OptionalFileEntryRef FE = getFileAndSuggestModule(
960 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
961 RequestingModule, SuggestedModule)) {
962 if (!Includer) {
963 assert(First && "only first includer can have no file");
964 return FE;
967 // Leave CurDir unset.
968 // This file is a system header or C++ unfriendly if the old file is.
970 // Note that we only use one of FromHFI/ToHFI at once, due to potential
971 // reallocation of the underlying vector potentially making the first
972 // reference binding dangling.
973 const HeaderFileInfo *FromHFI = getExistingFileInfo(*Includer);
974 assert(FromHFI && "includer without file info");
975 unsigned DirInfo = FromHFI->DirInfo;
977 HeaderFileInfo &ToHFI = getFileInfo(*FE);
978 ToHFI.DirInfo = DirInfo;
980 if (SearchPath) {
981 StringRef SearchPathRef(IncluderAndDir.second.getName());
982 SearchPath->clear();
983 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
985 if (RelativePath) {
986 RelativePath->clear();
987 RelativePath->append(Filename.begin(), Filename.end());
989 if (First) {
990 diagnoseFrameworkInclude(Diags, IncludeLoc,
991 IncluderAndDir.second.getName(), Filename,
992 *FE);
993 return FE;
996 // Otherwise, we found the path via MSVC header search rules. If
997 // -Wmsvc-include is enabled, we have to keep searching to see if we
998 // would've found this header in -I or -isystem directories.
999 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1000 return FE;
1001 } else {
1002 MSFE = FE;
1003 if (SuggestedModule) {
1004 MSSuggestedModule = *SuggestedModule;
1005 *SuggestedModule = ModuleMap::KnownHeader();
1007 break;
1010 First = false;
1014 CurDir = nullptr;
1016 // If this is a system #include, ignore the user #include locs.
1017 ConstSearchDirIterator It =
1018 isAngled ? angled_dir_begin() : search_dir_begin();
1020 // If this is a #include_next request, start searching after the directory the
1021 // file was found in.
1022 if (FromDir)
1023 It = FromDir;
1025 // Cache all of the lookups performed by this method. Many headers are
1026 // multiply included, and the "pragma once" optimization prevents them from
1027 // being relex/pp'd, but they would still have to search through a
1028 // (potentially huge) series of SearchDirs to find it.
1029 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1031 ConstSearchDirIterator NextIt = std::next(It);
1033 if (!SkipCache) {
1034 if (CacheLookup.StartIt == NextIt &&
1035 CacheLookup.RequestingModule == RequestingModule) {
1036 // HIT: Skip querying potentially lots of directories for this lookup.
1037 if (CacheLookup.HitIt)
1038 It = CacheLookup.HitIt;
1039 if (CacheLookup.MappedName) {
1040 Filename = CacheLookup.MappedName;
1041 if (IsMapped)
1042 *IsMapped = true;
1044 } else {
1045 // MISS: This is the first query, or the previous query didn't match
1046 // our search start. We will fill in our found location below, so prime
1047 // the start point value.
1048 CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1050 if (It == search_dir_begin() && FirstNonHeaderMapSearchDirIdx > 0) {
1051 // Handle cold misses of user includes in the presence of many header
1052 // maps. We avoid searching perhaps thousands of header maps by
1053 // jumping directly to the correct one or jumping beyond all of them.
1054 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1055 if (Iter == SearchDirHeaderMapIndex.end())
1056 // Not in index => Skip to first SearchDir after initial header maps
1057 It = search_dir_nth(FirstNonHeaderMapSearchDirIdx);
1058 else
1059 // In index => Start with a specific header map
1060 It = search_dir_nth(Iter->second);
1063 } else {
1064 CacheLookup.reset(RequestingModule, /*NewStartIt=*/NextIt);
1067 SmallString<64> MappedName;
1069 // Check each directory in sequence to see if it contains this file.
1070 for (; It != search_dir_end(); ++It) {
1071 bool InUserSpecifiedSystemFramework = false;
1072 bool IsInHeaderMap = false;
1073 bool IsFrameworkFoundInDir = false;
1074 OptionalFileEntryRef File = It->LookupFile(
1075 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1076 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1077 IsInHeaderMap, MappedName, OpenFile);
1078 if (!MappedName.empty()) {
1079 assert(IsInHeaderMap && "MappedName should come from a header map");
1080 CacheLookup.MappedName =
1081 copyString(MappedName, LookupFileCache.getAllocator());
1083 if (IsMapped)
1084 // A filename is mapped when a header map remapped it to a relative path
1085 // used in subsequent header search or to an absolute path pointing to an
1086 // existing file.
1087 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap && File));
1088 if (IsFrameworkFound)
1089 // Because we keep a filename remapped for subsequent search directory
1090 // lookups, ignore IsFrameworkFoundInDir after the first remapping and not
1091 // just for remapping in a current search directory.
1092 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1093 if (!File)
1094 continue;
1096 CurDir = It;
1098 IncludeNames[*File] = Filename;
1100 // This file is a system header or C++ unfriendly if the dir is.
1101 HeaderFileInfo &HFI = getFileInfo(*File);
1102 HFI.DirInfo = CurDir->getDirCharacteristic();
1104 // If the directory characteristic is User but this framework was
1105 // user-specified to be treated as a system framework, promote the
1106 // characteristic.
1107 if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
1108 HFI.DirInfo = SrcMgr::C_System;
1110 // If the filename matches a known system header prefix, override
1111 // whether the file is a system header.
1112 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1113 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1114 HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
1115 : SrcMgr::C_User;
1116 break;
1120 if (checkMSVCHeaderSearch(Diags, MSFE, &File->getFileEntry(), IncludeLoc)) {
1121 if (SuggestedModule)
1122 *SuggestedModule = MSSuggestedModule;
1123 return MSFE;
1126 bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
1127 if (!Includers.empty())
1128 diagnoseFrameworkInclude(Diags, IncludeLoc,
1129 Includers.front().second.getName(), Filename,
1130 *File, isAngled, FoundByHeaderMap);
1132 // Remember this location for the next lookup we do.
1133 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1134 return File;
1137 if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
1138 if (SuggestedModule)
1139 *SuggestedModule = MSSuggestedModule;
1140 return MSFE;
1143 // Otherwise, didn't find it. Remember we didn't find this.
1144 CacheLookup.HitIt = search_dir_end();
1145 return std::nullopt;
1148 /// LookupSubframeworkHeader - Look up a subframework for the specified
1149 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
1150 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
1151 /// is a subframework within Carbon.framework. If so, return the FileEntry
1152 /// for the designated file, otherwise return null.
1153 OptionalFileEntryRef HeaderSearch::LookupSubframeworkHeader(
1154 StringRef Filename, FileEntryRef ContextFileEnt,
1155 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
1156 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {
1157 // Framework names must have a '/' in the filename. Find it.
1158 // FIXME: Should we permit '\' on Windows?
1159 size_t SlashPos = Filename.find('/');
1160 if (SlashPos == StringRef::npos)
1161 return std::nullopt;
1163 // Look up the base framework name of the ContextFileEnt.
1164 StringRef ContextName = ContextFileEnt.getName();
1166 // If the context info wasn't a framework, couldn't be a subframework.
1167 const unsigned DotFrameworkLen = 10;
1168 auto FrameworkPos = ContextName.find(".framework");
1169 if (FrameworkPos == StringRef::npos ||
1170 (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1171 ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1172 return std::nullopt;
1174 SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1175 FrameworkPos +
1176 DotFrameworkLen + 1);
1178 // Append Frameworks/HIToolbox.framework/
1179 FrameworkName += "Frameworks/";
1180 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1181 FrameworkName += ".framework/";
1183 auto &CacheLookup =
1184 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1185 FrameworkCacheEntry())).first;
1187 // Some other location?
1188 if (CacheLookup.second.Directory &&
1189 CacheLookup.first().size() == FrameworkName.size() &&
1190 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1191 CacheLookup.first().size()) != 0)
1192 return std::nullopt;
1194 // Cache subframework.
1195 if (!CacheLookup.second.Directory) {
1196 ++NumSubFrameworkLookups;
1198 // If the framework dir doesn't exist, we fail.
1199 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1200 if (!Dir)
1201 return std::nullopt;
1203 // Otherwise, if it does, remember that this is the right direntry for this
1204 // framework.
1205 CacheLookup.second.Directory = Dir;
1209 if (RelativePath) {
1210 RelativePath->clear();
1211 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1214 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
1215 SmallString<1024> HeadersFilename(FrameworkName);
1216 HeadersFilename += "Headers/";
1217 if (SearchPath) {
1218 SearchPath->clear();
1219 // Without trailing '/'.
1220 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1223 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1224 auto File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1225 if (!File) {
1226 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
1227 HeadersFilename = FrameworkName;
1228 HeadersFilename += "PrivateHeaders/";
1229 if (SearchPath) {
1230 SearchPath->clear();
1231 // Without trailing '/'.
1232 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1235 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1236 File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1238 if (!File)
1239 return std::nullopt;
1242 // This file is a system header or C++ unfriendly if the old file is.
1243 const HeaderFileInfo *ContextHFI = getExistingFileInfo(ContextFileEnt);
1244 assert(ContextHFI && "context file without file info");
1245 // Note that the temporary 'DirInfo' is required here, as the call to
1246 // getFileInfo could resize the vector and might invalidate 'ContextHFI'.
1247 unsigned DirInfo = ContextHFI->DirInfo;
1248 getFileInfo(*File).DirInfo = DirInfo;
1250 FrameworkName.pop_back(); // remove the trailing '/'
1251 if (!findUsableModuleForFrameworkHeader(*File, FrameworkName,
1252 RequestingModule, SuggestedModule,
1253 /*IsSystem*/ false))
1254 return std::nullopt;
1256 return *File;
1259 //===----------------------------------------------------------------------===//
1260 // File Info Management.
1261 //===----------------------------------------------------------------------===//
1263 static bool moduleMembershipNeedsMerge(const HeaderFileInfo *HFI,
1264 ModuleMap::ModuleHeaderRole Role) {
1265 if (ModuleMap::isModular(Role))
1266 return !HFI->isModuleHeader || HFI->isTextualModuleHeader;
1267 if (!HFI->isModuleHeader && (Role & ModuleMap::TextualHeader))
1268 return !HFI->isTextualModuleHeader;
1269 return false;
1272 static void mergeHeaderFileInfoModuleBits(HeaderFileInfo &HFI,
1273 bool isModuleHeader,
1274 bool isTextualModuleHeader) {
1275 HFI.isModuleHeader |= isModuleHeader;
1276 if (HFI.isModuleHeader)
1277 HFI.isTextualModuleHeader = false;
1278 else
1279 HFI.isTextualModuleHeader |= isTextualModuleHeader;
1282 void HeaderFileInfo::mergeModuleMembership(ModuleMap::ModuleHeaderRole Role) {
1283 mergeHeaderFileInfoModuleBits(*this, ModuleMap::isModular(Role),
1284 (Role & ModuleMap::TextualHeader));
1287 /// Merge the header file info provided by \p OtherHFI into the current
1288 /// header file info (\p HFI)
1289 static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
1290 const HeaderFileInfo &OtherHFI) {
1291 assert(OtherHFI.External && "expected to merge external HFI");
1293 HFI.isImport |= OtherHFI.isImport;
1294 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
1295 mergeHeaderFileInfoModuleBits(HFI, OtherHFI.isModuleHeader,
1296 OtherHFI.isTextualModuleHeader);
1298 if (!HFI.LazyControllingMacro.isValid())
1299 HFI.LazyControllingMacro = OtherHFI.LazyControllingMacro;
1301 HFI.DirInfo = OtherHFI.DirInfo;
1302 HFI.External = (!HFI.IsValid || HFI.External);
1303 HFI.IsValid = true;
1306 HeaderFileInfo &HeaderSearch::getFileInfo(FileEntryRef FE) {
1307 if (FE.getUID() >= FileInfo.size())
1308 FileInfo.resize(FE.getUID() + 1);
1310 HeaderFileInfo *HFI = &FileInfo[FE.getUID()];
1311 // FIXME: Use a generation count to check whether this is really up to date.
1312 if (ExternalSource && !HFI->Resolved) {
1313 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1314 if (ExternalHFI.IsValid) {
1315 HFI->Resolved = true;
1316 if (ExternalHFI.External)
1317 mergeHeaderFileInfo(*HFI, ExternalHFI);
1321 HFI->IsValid = true;
1322 // We assume the caller has local information about this header file, so it's
1323 // no longer strictly external.
1324 HFI->External = false;
1325 return *HFI;
1328 const HeaderFileInfo *HeaderSearch::getExistingFileInfo(FileEntryRef FE) const {
1329 HeaderFileInfo *HFI;
1330 if (ExternalSource) {
1331 if (FE.getUID() >= FileInfo.size())
1332 FileInfo.resize(FE.getUID() + 1);
1334 HFI = &FileInfo[FE.getUID()];
1335 // FIXME: Use a generation count to check whether this is really up to date.
1336 if (!HFI->Resolved) {
1337 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1338 if (ExternalHFI.IsValid) {
1339 HFI->Resolved = true;
1340 if (ExternalHFI.External)
1341 mergeHeaderFileInfo(*HFI, ExternalHFI);
1344 } else if (FE.getUID() < FileInfo.size()) {
1345 HFI = &FileInfo[FE.getUID()];
1346 } else {
1347 HFI = nullptr;
1350 return (HFI && HFI->IsValid) ? HFI : nullptr;
1353 const HeaderFileInfo *
1354 HeaderSearch::getExistingLocalFileInfo(FileEntryRef FE) const {
1355 HeaderFileInfo *HFI;
1356 if (FE.getUID() < FileInfo.size()) {
1357 HFI = &FileInfo[FE.getUID()];
1358 } else {
1359 HFI = nullptr;
1362 return (HFI && HFI->IsValid && !HFI->External) ? HFI : nullptr;
1365 bool HeaderSearch::isFileMultipleIncludeGuarded(FileEntryRef File) const {
1366 // Check if we've entered this file and found an include guard or #pragma
1367 // once. Note that we dor't check for #import, because that's not a property
1368 // of the file itself.
1369 if (auto *HFI = getExistingFileInfo(File))
1370 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1371 return false;
1374 void HeaderSearch::MarkFileModuleHeader(FileEntryRef FE,
1375 ModuleMap::ModuleHeaderRole Role,
1376 bool isCompilingModuleHeader) {
1377 // Don't mark the file info as non-external if there's nothing to change.
1378 if (!isCompilingModuleHeader) {
1379 if ((Role & ModuleMap::ExcludedHeader))
1380 return;
1381 auto *HFI = getExistingFileInfo(FE);
1382 if (HFI && !moduleMembershipNeedsMerge(HFI, Role))
1383 return;
1386 auto &HFI = getFileInfo(FE);
1387 HFI.mergeModuleMembership(Role);
1388 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1391 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
1392 FileEntryRef File, bool isImport,
1393 bool ModulesEnabled, Module *M,
1394 bool &IsFirstIncludeOfFile) {
1395 // An include file should be entered if either:
1396 // 1. This is the first include of the file.
1397 // 2. This file can be included multiple times, that is it's not an
1398 // "include-once" file.
1400 // Include-once is controlled by these preprocessor directives.
1402 // #pragma once
1403 // This directive is in the include file, and marks it as an include-once
1404 // file.
1406 // #import <file>
1407 // This directive is in the includer, and indicates that the include file
1408 // should only be entered if this is the first include.
1409 ++NumIncluded;
1410 IsFirstIncludeOfFile = false;
1411 HeaderFileInfo &FileInfo = getFileInfo(File);
1413 auto MaybeReenterImportedFile = [&]() -> bool {
1414 // Modules add a wrinkle though: what's included isn't necessarily visible.
1415 // Consider this module.
1416 // module Example {
1417 // module A { header "a.h" export * }
1418 // module B { header "b.h" export * }
1419 // }
1420 // b.h includes c.h. The main file includes a.h, which will trigger a module
1421 // build of Example, and c.h will be included. However, c.h isn't visible to
1422 // the main file. Normally this is fine, the main file can just include c.h
1423 // if it needs it. If c.h is in a module, the include will translate into a
1424 // module import, this function will be skipped, and everything will work as
1425 // expected. However, if c.h is not in a module (or is `textual`), then this
1426 // function will run. If c.h is include-once, it will not be entered from
1427 // the main file and it will still not be visible.
1429 // If modules aren't enabled then there's no visibility issue. Always
1430 // respect `#pragma once`.
1431 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1432 return false;
1434 // Ensure FileInfo bits are up to date.
1435 ModMap.resolveHeaderDirectives(File);
1437 // This brings up a subtlety of #import - it's not a very good indicator of
1438 // include-once. Developers are often unaware of the difference between
1439 // #include and #import, and tend to use one or the other indiscrimiately.
1440 // In order to support #include on include-once headers that lack macro
1441 // guards and `#pragma once` (which is the vast majority of Objective-C
1442 // headers), if a file is ever included with #import, it's marked as
1443 // isImport in the HeaderFileInfo and treated as include-once. This allows
1444 // #include to work in Objective-C.
1445 // #include <Foundation/Foundation.h>
1446 // #include <Foundation/NSString.h>
1447 // Foundation.h has an #import of NSString.h, and so the second #include is
1448 // skipped even though NSString.h has no `#pragma once` and no macro guard.
1450 // However, this helpfulness causes problems with modules. If c.h is not an
1451 // include-once file, but something included it with #import anyway (as is
1452 // typical in Objective-C code), this include will be skipped and c.h will
1453 // not be visible. Consider it not include-once if it is a `textual` header
1454 // in a module.
1455 if (FileInfo.isTextualModuleHeader)
1456 return true;
1458 if (FileInfo.isCompilingModuleHeader) {
1459 // It's safer to re-enter a file whose module is being built because its
1460 // declarations will still be scoped to a single module.
1461 if (FileInfo.isModuleHeader) {
1462 // Headers marked as "builtin" are covered by the system module maps
1463 // rather than the builtin ones. Some versions of the Darwin module fail
1464 // to mark stdarg.h and stddef.h as textual. Attempt to re-enter these
1465 // files while building their module to allow them to function properly.
1466 if (ModMap.isBuiltinHeader(File))
1467 return true;
1468 } else {
1469 // Files that are excluded from their module can potentially be
1470 // re-entered from their own module. This might cause redeclaration
1471 // errors if another module saw this file first, but there's a
1472 // reasonable chance that its module will build first. However if
1473 // there's no controlling macro, then trust the #import and assume this
1474 // really is an include-once file.
1475 if (FileInfo.getControllingMacro(ExternalLookup))
1476 return true;
1479 // If the include file has a macro guard, then it might still not be
1480 // re-entered if the controlling macro is visibly defined. e.g. another
1481 // header in the module being built included this file and local submodule
1482 // visibility is not enabled.
1484 // It might be tempting to re-enter the include-once file if it's not
1485 // visible in an attempt to make it visible. However this will still cause
1486 // redeclaration errors against the known-but-not-visible declarations. The
1487 // include file not being visible will most likely cause "undefined x"
1488 // errors, but at least there's a slim chance of compilation succeeding.
1489 return false;
1492 if (isImport) {
1493 // As discussed above, record that this file was ever `#import`ed, and treat
1494 // it as an include-once file from here out.
1495 FileInfo.isImport = true;
1496 if (PP.alreadyIncluded(File) && !MaybeReenterImportedFile())
1497 return false;
1498 } else {
1499 // isPragmaOnce and isImport are only set after the file has been included
1500 // at least once. If either are set then this is a repeat #include of an
1501 // include-once file.
1502 if (FileInfo.isPragmaOnce ||
1503 (FileInfo.isImport && !MaybeReenterImportedFile()))
1504 return false;
1507 // As a final optimization, check for a macro guard and skip entering the file
1508 // if the controlling macro is defined. The macro guard will effectively erase
1509 // the file's contents, and the include would have no effect other than to
1510 // waste time opening and reading a file.
1511 if (const IdentifierInfo *ControllingMacro =
1512 FileInfo.getControllingMacro(ExternalLookup)) {
1513 // If the header corresponds to a module, check whether the macro is already
1514 // defined in that module rather than checking all visible modules. This is
1515 // mainly to cover corner cases where the same controlling macro is used in
1516 // different files in multiple modules.
1517 if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1518 : PP.isMacroDefined(ControllingMacro)) {
1519 ++NumMultiIncludeFileOptzn;
1520 return false;
1524 IsFirstIncludeOfFile = PP.markIncluded(File);
1525 return true;
1528 size_t HeaderSearch::getTotalMemory() const {
1529 return SearchDirs.capacity()
1530 + llvm::capacity_in_bytes(FileInfo)
1531 + llvm::capacity_in_bytes(HeaderMaps)
1532 + LookupFileCache.getAllocator().getTotalMemory()
1533 + FrameworkMap.getAllocator().getTotalMemory();
1536 unsigned HeaderSearch::searchDirIdx(const DirectoryLookup &DL) const {
1537 return &DL - &*SearchDirs.begin();
1540 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1541 return FrameworkNames.insert(Framework).first->first();
1544 StringRef HeaderSearch::getIncludeNameForHeader(const FileEntry *File) const {
1545 auto It = IncludeNames.find(File);
1546 if (It == IncludeNames.end())
1547 return {};
1548 return It->second;
1551 bool HeaderSearch::hasModuleMap(StringRef FileName,
1552 const DirectoryEntry *Root,
1553 bool IsSystem) {
1554 if (!HSOpts->ImplicitModuleMaps)
1555 return false;
1557 SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
1559 StringRef DirName = FileName;
1560 do {
1561 // Get the parent directory name.
1562 DirName = llvm::sys::path::parent_path(DirName);
1563 if (DirName.empty())
1564 return false;
1566 // Determine whether this directory exists.
1567 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1568 if (!Dir)
1569 return false;
1571 // Try to load the module map file in this directory.
1572 switch (loadModuleMapFile(*Dir, IsSystem,
1573 llvm::sys::path::extension(Dir->getName()) ==
1574 ".framework")) {
1575 case LMM_NewlyLoaded:
1576 case LMM_AlreadyLoaded:
1577 // Success. All of the directories we stepped through inherit this module
1578 // map file.
1579 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1580 DirectoryHasModuleMap[FixUpDirectories[I]] = true;
1581 return true;
1583 case LMM_NoDirectory:
1584 case LMM_InvalidModuleMap:
1585 break;
1588 // If we hit the top of our search, we're done.
1589 if (*Dir == Root)
1590 return false;
1592 // Keep track of all of the directories we checked, so we can mark them as
1593 // having module maps if we eventually do find a module map.
1594 FixUpDirectories.push_back(*Dir);
1595 } while (true);
1598 ModuleMap::KnownHeader
1599 HeaderSearch::findModuleForHeader(FileEntryRef File, bool AllowTextual,
1600 bool AllowExcluded) const {
1601 if (ExternalSource) {
1602 // Make sure the external source has handled header info about this file,
1603 // which includes whether the file is part of a module.
1604 (void)getExistingFileInfo(File);
1606 return ModMap.findModuleForHeader(File, AllowTextual, AllowExcluded);
1609 ArrayRef<ModuleMap::KnownHeader>
1610 HeaderSearch::findAllModulesForHeader(FileEntryRef File) const {
1611 if (ExternalSource) {
1612 // Make sure the external source has handled header info about this file,
1613 // which includes whether the file is part of a module.
1614 (void)getExistingFileInfo(File);
1616 return ModMap.findAllModulesForHeader(File);
1619 ArrayRef<ModuleMap::KnownHeader>
1620 HeaderSearch::findResolvedModulesForHeader(FileEntryRef File) const {
1621 if (ExternalSource) {
1622 // Make sure the external source has handled header info about this file,
1623 // which includes whether the file is part of a module.
1624 (void)getExistingFileInfo(File);
1626 return ModMap.findResolvedModulesForHeader(File);
1629 static bool suggestModule(HeaderSearch &HS, FileEntryRef File,
1630 Module *RequestingModule,
1631 ModuleMap::KnownHeader *SuggestedModule) {
1632 ModuleMap::KnownHeader Module =
1633 HS.findModuleForHeader(File, /*AllowTextual*/true);
1635 // If this module specifies [no_undeclared_includes], we cannot find any
1636 // file that's in a non-dependency module.
1637 if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
1638 HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false);
1639 if (!RequestingModule->directlyUses(Module.getModule())) {
1640 // Builtin headers are a special case. Multiple modules can use the same
1641 // builtin as a modular header (see also comment in
1642 // ShouldEnterIncludeFile()), so the builtin header may have been
1643 // "claimed" by an unrelated module. This shouldn't prevent us from
1644 // including the builtin header textually in this module.
1645 if (HS.getModuleMap().isBuiltinHeader(File)) {
1646 if (SuggestedModule)
1647 *SuggestedModule = ModuleMap::KnownHeader();
1648 return true;
1650 // TODO: Add this module (or just its module map file) into something like
1651 // `RequestingModule->AffectingClangModules`.
1652 return false;
1656 if (SuggestedModule)
1657 *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
1658 ? ModuleMap::KnownHeader()
1659 : Module;
1661 return true;
1664 bool HeaderSearch::findUsableModuleForHeader(
1665 FileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule,
1666 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1667 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1668 // If there is a module that corresponds to this header, suggest it.
1669 hasModuleMap(File.getNameAsRequested(), Root, IsSystemHeaderDir);
1670 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1672 return true;
1675 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1676 FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
1677 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1678 // If we're supposed to suggest a module, look for one now.
1679 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1680 // Find the top-level framework based on this framework.
1681 SmallVector<std::string, 4> SubmodulePath;
1682 OptionalDirectoryEntryRef TopFrameworkDir =
1683 ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1684 assert(TopFrameworkDir && "Could not find the top-most framework dir");
1686 // Determine the name of the top-level framework.
1687 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1689 // Load this framework module. If that succeeds, find the suggested module
1690 // for this header, if any.
1691 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1693 // FIXME: This can find a module not part of ModuleName, which is
1694 // important so that we're consistent about whether this header
1695 // corresponds to a module. Possibly we should lock down framework modules
1696 // so that this is not possible.
1697 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1699 return true;
1702 static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File,
1703 FileManager &FileMgr,
1704 DiagnosticsEngine &Diags) {
1705 StringRef Filename = llvm::sys::path::filename(File.getName());
1706 SmallString<128> PrivateFilename(File.getDir().getName());
1707 if (Filename == "module.map")
1708 llvm::sys::path::append(PrivateFilename, "module_private.map");
1709 else if (Filename == "module.modulemap")
1710 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1711 else
1712 return std::nullopt;
1713 auto PMMFile = FileMgr.getOptionalFileRef(PrivateFilename);
1714 if (PMMFile) {
1715 if (Filename == "module.map")
1716 Diags.Report(diag::warn_deprecated_module_dot_map)
1717 << PrivateFilename << 1
1718 << File.getDir().getName().ends_with(".framework");
1720 return PMMFile;
1723 bool HeaderSearch::loadModuleMapFile(FileEntryRef File, bool IsSystem,
1724 FileID ID, unsigned *Offset,
1725 StringRef OriginalModuleMapFile) {
1726 // Find the directory for the module. For frameworks, that may require going
1727 // up from the 'Modules' directory.
1728 OptionalDirectoryEntryRef Dir;
1729 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
1730 Dir = FileMgr.getOptionalDirectoryRef(".");
1731 } else {
1732 if (!OriginalModuleMapFile.empty()) {
1733 // We're building a preprocessed module map. Find or invent the directory
1734 // that it originally occupied.
1735 Dir = FileMgr.getOptionalDirectoryRef(
1736 llvm::sys::path::parent_path(OriginalModuleMapFile));
1737 if (!Dir) {
1738 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1739 Dir = FakeFile.getDir();
1741 } else {
1742 Dir = File.getDir();
1745 assert(Dir && "parent must exist");
1746 StringRef DirName(Dir->getName());
1747 if (llvm::sys::path::filename(DirName) == "Modules") {
1748 DirName = llvm::sys::path::parent_path(DirName);
1749 if (DirName.ends_with(".framework"))
1750 if (auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
1751 Dir = *MaybeDir;
1752 // FIXME: This assert can fail if there's a race between the above check
1753 // and the removal of the directory.
1754 assert(Dir && "parent must exist");
1758 assert(Dir && "module map home directory must exist");
1759 switch (loadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) {
1760 case LMM_AlreadyLoaded:
1761 case LMM_NewlyLoaded:
1762 return false;
1763 case LMM_NoDirectory:
1764 case LMM_InvalidModuleMap:
1765 return true;
1767 llvm_unreachable("Unknown load module map result");
1770 HeaderSearch::LoadModuleMapResult
1771 HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
1772 DirectoryEntryRef Dir, FileID ID,
1773 unsigned *Offset) {
1774 // Check whether we've already loaded this module map, and mark it as being
1775 // loaded in case we recursively try to load it from itself.
1776 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1777 if (!AddResult.second)
1778 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1780 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1781 LoadedModuleMaps[File] = false;
1782 return LMM_InvalidModuleMap;
1785 // Try to load a corresponding private module map.
1786 if (OptionalFileEntryRef PMMFile =
1787 getPrivateModuleMap(File, FileMgr, Diags)) {
1788 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, Dir)) {
1789 LoadedModuleMaps[File] = false;
1790 return LMM_InvalidModuleMap;
1794 // This directory has a module map.
1795 return LMM_NewlyLoaded;
1798 OptionalFileEntryRef
1799 HeaderSearch::lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework) {
1800 if (!HSOpts->ImplicitModuleMaps)
1801 return std::nullopt;
1802 // For frameworks, the preferred spelling is Modules/module.modulemap, but
1803 // module.map at the framework root is also accepted.
1804 SmallString<128> ModuleMapFileName(Dir.getName());
1805 if (IsFramework)
1806 llvm::sys::path::append(ModuleMapFileName, "Modules");
1807 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1808 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1809 return *F;
1811 // Continue to allow module.map, but warn it's deprecated.
1812 ModuleMapFileName = Dir.getName();
1813 llvm::sys::path::append(ModuleMapFileName, "module.map");
1814 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
1815 Diags.Report(diag::warn_deprecated_module_dot_map)
1816 << ModuleMapFileName << 0 << IsFramework;
1817 return *F;
1820 // For frameworks, allow to have a private module map with a preferred
1821 // spelling when a public module map is absent.
1822 if (IsFramework) {
1823 ModuleMapFileName = Dir.getName();
1824 llvm::sys::path::append(ModuleMapFileName, "Modules",
1825 "module.private.modulemap");
1826 if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
1827 return *F;
1829 return std::nullopt;
1832 Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
1833 bool IsSystem) {
1834 // Try to load a module map file.
1835 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
1836 case LMM_InvalidModuleMap:
1837 // Try to infer a module map from the framework directory.
1838 if (HSOpts->ImplicitModuleMaps)
1839 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1840 break;
1842 case LMM_NoDirectory:
1843 return nullptr;
1845 case LMM_AlreadyLoaded:
1846 case LMM_NewlyLoaded:
1847 break;
1850 return ModMap.findModule(Name);
1853 HeaderSearch::LoadModuleMapResult
1854 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
1855 bool IsFramework) {
1856 if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
1857 return loadModuleMapFile(*Dir, IsSystem, IsFramework);
1859 return LMM_NoDirectory;
1862 HeaderSearch::LoadModuleMapResult
1863 HeaderSearch::loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
1864 bool IsFramework) {
1865 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1866 if (KnownDir != DirectoryHasModuleMap.end())
1867 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1869 if (OptionalFileEntryRef ModuleMapFile =
1870 lookupModuleMapFile(Dir, IsFramework)) {
1871 LoadModuleMapResult Result =
1872 loadModuleMapFileImpl(*ModuleMapFile, IsSystem, Dir);
1873 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1874 // E.g. Foo.framework/Modules/module.modulemap
1875 // ^Dir ^ModuleMapFile
1876 if (Result == LMM_NewlyLoaded)
1877 DirectoryHasModuleMap[Dir] = true;
1878 else if (Result == LMM_InvalidModuleMap)
1879 DirectoryHasModuleMap[Dir] = false;
1880 return Result;
1882 return LMM_InvalidModuleMap;
1885 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
1886 Modules.clear();
1888 if (HSOpts->ImplicitModuleMaps) {
1889 // Load module maps for each of the header search directories.
1890 for (DirectoryLookup &DL : search_dir_range()) {
1891 bool IsSystem = DL.isSystemHeaderDirectory();
1892 if (DL.isFramework()) {
1893 std::error_code EC;
1894 SmallString<128> DirNative;
1895 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
1897 // Search each of the ".framework" directories to load them as modules.
1898 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1899 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1900 DirEnd;
1901 Dir != DirEnd && !EC; Dir.increment(EC)) {
1902 if (llvm::sys::path::extension(Dir->path()) != ".framework")
1903 continue;
1905 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
1906 if (!FrameworkDir)
1907 continue;
1909 // Load this framework module.
1910 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1911 IsSystem);
1913 continue;
1916 // FIXME: Deal with header maps.
1917 if (DL.isHeaderMap())
1918 continue;
1920 // Try to load a module map file for the search directory.
1921 loadModuleMapFile(*DL.getDirRef(), IsSystem, /*IsFramework*/ false);
1923 // Try to load module map files for immediate subdirectories of this
1924 // search directory.
1925 loadSubdirectoryModuleMaps(DL);
1929 // Populate the list of modules.
1930 llvm::transform(ModMap.modules(), std::back_inserter(Modules),
1931 [](const auto &NameAndMod) { return NameAndMod.second; });
1934 void HeaderSearch::loadTopLevelSystemModules() {
1935 if (!HSOpts->ImplicitModuleMaps)
1936 return;
1938 // Load module maps for each of the header search directories.
1939 for (const DirectoryLookup &DL : search_dir_range()) {
1940 // We only care about normal header directories.
1941 if (!DL.isNormalDir())
1942 continue;
1944 // Try to load a module map file for the search directory.
1945 loadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(),
1946 DL.isFramework());
1950 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
1951 assert(HSOpts->ImplicitModuleMaps &&
1952 "Should not be loading subdirectory module maps");
1954 if (SearchDir.haveSearchedAllModuleMaps())
1955 return;
1957 std::error_code EC;
1958 SmallString<128> Dir = SearchDir.getDirRef()->getName();
1959 FileMgr.makeAbsolutePath(Dir);
1960 SmallString<128> DirNative;
1961 llvm::sys::path::native(Dir, DirNative);
1962 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1963 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1964 Dir != DirEnd && !EC; Dir.increment(EC)) {
1965 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
1966 continue;
1967 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
1968 if (IsFramework == SearchDir.isFramework())
1969 loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
1970 SearchDir.isFramework());
1973 SearchDir.setSearchedAllModuleMaps(true);
1976 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1977 FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled) const {
1978 return suggestPathToFileForDiagnostics(File.getName(), /*WorkingDir=*/"",
1979 MainFile, IsAngled);
1982 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1983 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1984 bool *IsAngled) const {
1985 using namespace llvm::sys;
1987 llvm::SmallString<32> FilePath = File;
1988 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
1989 fs::make_absolute(WorkingDir, FilePath);
1990 // remove_dots switches to backslashes on windows as a side-effect!
1991 // We always want to suggest forward slashes for includes.
1992 // (not remove_dots(..., posix) as that misparses windows paths).
1993 path::remove_dots(FilePath, /*remove_dot_dot=*/true);
1994 path::native(FilePath, path::Style::posix);
1995 File = FilePath;
1997 unsigned BestPrefixLength = 0;
1998 // Checks whether `Dir` is a strict path prefix of `File`. If so and that's
1999 // the longest prefix we've seen so for it, returns true and updates the
2000 // `BestPrefixLength` accordingly.
2001 auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
2002 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2003 fs::make_absolute(WorkingDir, Dir);
2004 path::remove_dots(Dir, /*remove_dot_dot=*/true);
2005 for (auto NI = path::begin(File), NE = path::end(File),
2006 DI = path::begin(Dir), DE = path::end(Dir);
2007 NI != NE; ++NI, ++DI) {
2008 if (DI == DE) {
2009 // Dir is a prefix of File, up to choice of path separators.
2010 unsigned PrefixLength = NI - path::begin(File);
2011 if (PrefixLength > BestPrefixLength) {
2012 BestPrefixLength = PrefixLength;
2013 return true;
2015 break;
2018 // Consider all path separators equal.
2019 if (NI->size() == 1 && DI->size() == 1 &&
2020 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2021 continue;
2023 // Special case Apple .sdk folders since the search path is typically a
2024 // symlink like `iPhoneSimulator14.5.sdk` while the file is instead
2025 // located in `iPhoneSimulator.sdk` (the real folder).
2026 if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) {
2027 StringRef NBasename = path::stem(*NI);
2028 StringRef DBasename = path::stem(*DI);
2029 if (DBasename.starts_with(NBasename))
2030 continue;
2033 if (*NI != *DI)
2034 break;
2036 return false;
2039 bool BestPrefixIsFramework = false;
2040 for (const DirectoryLookup &DL : search_dir_range()) {
2041 if (DL.isNormalDir()) {
2042 StringRef Dir = DL.getDirRef()->getName();
2043 if (CheckDir(Dir)) {
2044 if (IsAngled)
2045 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2046 BestPrefixIsFramework = false;
2048 } else if (DL.isFramework()) {
2049 StringRef Dir = DL.getFrameworkDirRef()->getName();
2050 if (CheckDir(Dir)) {
2051 // Framework includes by convention use <>.
2052 if (IsAngled)
2053 *IsAngled = BestPrefixLength;
2054 BestPrefixIsFramework = true;
2059 // Try to shorten include path using TUs directory, if we couldn't find any
2060 // suitable prefix in include search paths.
2061 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2062 if (IsAngled)
2063 *IsAngled = false;
2064 BestPrefixIsFramework = false;
2067 // Try resolving resulting filename via reverse search in header maps,
2068 // key from header name is user preferred name for the include file.
2069 StringRef Filename = File.drop_front(BestPrefixLength);
2070 for (const DirectoryLookup &DL : search_dir_range()) {
2071 if (!DL.isHeaderMap())
2072 continue;
2074 StringRef SpelledFilename =
2075 DL.getHeaderMap()->reverseLookupFilename(Filename);
2076 if (!SpelledFilename.empty()) {
2077 Filename = SpelledFilename;
2078 BestPrefixIsFramework = false;
2079 break;
2083 // If the best prefix is a framework path, we need to compute the proper
2084 // include spelling for the framework header.
2085 bool IsPrivateHeader;
2086 SmallString<128> FrameworkName, IncludeSpelling;
2087 if (BestPrefixIsFramework &&
2088 isFrameworkStylePath(Filename, IsPrivateHeader, FrameworkName,
2089 IncludeSpelling)) {
2090 Filename = IncludeSpelling;
2092 return path::convert_to_slash(Filename);