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