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