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