Thanks to visit codestin.com
Credit goes to clang.llvm.org

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