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