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