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