26#include "llvm/ADT/APInt.h"
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/ADT/SmallString.h"
29#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/Statistic.h"
31#include "llvm/ADT/StringRef.h"
32#include "llvm/Support/Allocator.h"
33#include "llvm/Support/Capacity.h"
34#include "llvm/Support/Errc.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/FileSystem.h"
37#include "llvm/Support/Path.h"
38#include "llvm/Support/VirtualFileSystem.h"
39#include "llvm/Support/xxhash.h"
46#include <system_error>
51#define DEBUG_TYPE "file-search"
55 NumMultiIncludeFileOptzn,
56 "Number of #includes skipped due to the multi-include optimization.");
59 "Number of subframework lookups.");
73 if (ControllingMacro && ControllingMacro->
isOutOfDate()) {
74 assert(
External &&
"We must have an external source if we have a "
75 "controlling macro that is out of date.");
76 External->updateOutOfDateIdentifier(*ControllingMacro);
78 return ControllingMacro;
87 : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()),
88 FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts,
Target, *this) {}
91 llvm::errs() <<
"\n*** HeaderSearch Stats:\n"
92 << FileInfo.size() <<
" files tracked.\n";
93 unsigned NumOnceOnlyFiles = 0;
94 for (
const auto &[FE, HFI] : FileInfo)
95 NumOnceOnlyFiles += (HFI.isPragmaOnce || HFI.isImport);
96 llvm::errs() <<
" " << NumOnceOnlyFiles <<
" #import/#pragma once files.\n";
98 llvm::errs() <<
" " << NumIncluded <<
" #include/#include_next/#import.\n"
99 <<
" " << NumMultiIncludeFileOptzn
100 <<
" #includes skipped due to the multi-include optimization.\n";
102 llvm::errs() << NumFrameworkLookups <<
" framework lookups.\n"
103 << NumSubFrameworkLookups <<
" subframework lookups.\n";
107 std::vector<DirectoryLookup> dirs,
unsigned int angledDirIdx,
108 unsigned int systemDirIdx,
109 llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
110 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
111 "Directory indices are unordered");
112 SearchDirs = std::move(dirs);
113 SearchDirsUsage.assign(SearchDirs.size(),
false);
114 AngledDirIdx = angledDirIdx;
115 SystemDirIdx = systemDirIdx;
116 SearchDirToHSEntry = std::move(searchDirToHSEntry);
118 indexInitialHeaderMaps();
122 unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
123 SearchDirs.insert(SearchDirs.begin() + idx, dir);
124 SearchDirsUsage.insert(SearchDirsUsage.begin() + idx,
false);
131 std::vector<bool> UserEntryUsage(HSOpts.UserEntries.size());
132 for (
unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
134 if (SearchDirsUsage[I]) {
135 auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
137 if (UserEntryIdxIt != SearchDirToHSEntry.end())
138 UserEntryUsage[UserEntryIdxIt->second] =
true;
141 return UserEntryUsage;
145 std::vector<bool> VFSUsage;
149 llvm::vfs::FileSystem &RootFS = FileMgr.getVirtualFileSystem();
153 RootFS.visit([&](llvm::vfs::FileSystem &FS) {
154 if (
auto *RFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&FS)) {
158 if (!RFS->getOverlayFileDir().empty()) {
159 VFSUsage.push_back(RFS->hasBeenUsed());
160 RFS->clearHasBeenUsed();
165 "A different number of RedirectingFileSystem's were present than "
166 "-ivfsoverlay options passed to Clang!");
168 std::reverse(VFSUsage.begin(), VFSUsage.end());
177 if (!HeaderMaps.empty()) {
178 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
181 if (HeaderMaps[i].first == FE)
182 return HeaderMaps[i].second.get();
186 HeaderMaps.emplace_back(FE, std::move(HM));
187 return HeaderMaps.back().second.get();
196 for (
auto &HM : HeaderMaps)
197 Names.push_back(std::string(HM.first.getName()));
213 auto i(HSOpts.PrebuiltModuleFiles.find(ModuleName));
214 if (i != HSOpts.PrebuiltModuleFiles.end())
217 if (FileMapOnly || HSOpts.PrebuiltModulePaths.empty())
222 for (
const std::string &Dir : HSOpts.PrebuiltModulePaths) {
224 FileMgr.makeAbsolutePath(
Result);
225 if (ModuleName.contains(
':'))
229 llvm::sys::path::append(
Result, ModuleName.split(
':').first +
"-" +
230 ModuleName.split(
':').second +
233 llvm::sys::path::append(
Result, ModuleName +
".pcm");
245 StringRef ModuleMapPath =
ModuleMap->getName();
246 for (
const std::string &Dir : HSOpts.PrebuiltModulePaths) {
248 FileMgr.makeAbsolutePath(CachePath);
250 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
258 StringRef ModuleMapPath) {
259 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
264 StringRef ModuleName, StringRef ModuleMapPath, StringRef CachePath) {
267 if (CachePath.empty())
274 unsigned SuffixBegin =
Result.size();
277 llvm::sys::path::append(
Result, ModuleName +
".pcm");
279 llvm::sys::path::append(
Result, ContextHash);
287 SmallString<128> CanonicalPath(ModuleMapPath);
288 if (
getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
291 auto Hash = llvm::xxh3_64bits(CanonicalPath);
293 SmallString<128> HashStr;
294 llvm::APInt(64, Hash).toStringUnsigned(HashStr, 36);
295 llvm::sys::path::append(
Result, ModuleName +
"-" + HashStr +
".pcm");
302 bool AllowExtraModuleMapSearch) {
305 if (
Module || !AllowSearch || !HSOpts.ImplicitModuleMaps)
308 StringRef SearchName = ModuleName;
310 AllowExtraModuleMapSearch);
320 if (!
Module && SearchName.consume_back(
"_Private"))
322 AllowExtraModuleMapSearch);
323 if (!
Module && SearchName.consume_back(
"Private"))
325 AllowExtraModuleMapSearch);
331 bool AllowExtraModuleMapSearch) {
337 if (Dir.isFramework()) {
342 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
343 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
344 if (
auto FrameworkDir =
345 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
347 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem,
357 if (!Dir.isNormalDir())
360 bool IsSystem = Dir.isSystemHeaderDirectory();
363 DirectoryEntryRef NormalDir = *Dir.getDirRef();
365 if (parseModuleMapFile(NormalDir, IsSystem,
true,
366 false) == MMR_NewlyProcessed) {
369 Module = ModMap.findOrLoadModule(ModuleName);
376 SmallString<128> NestedModuleMapDirName;
377 NestedModuleMapDirName = Dir.getDirRef()->getName();
378 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
379 if (parseModuleMapFile(NestedModuleMapDirName, IsSystem,
381 false) == MMR_NewlyProcessed) {
383 Module = ModMap.findOrLoadModule(ModuleName);
388 if (HSOpts.AllowModuleMapSubdirectorySearch) {
391 if (Dir.haveSearchedAllModuleMaps())
396 if (AllowExtraModuleMapSearch)
397 loadSubdirectoryModuleMaps(Dir);
400 Module = ModMap.findOrLoadModule(ModuleName);
409void HeaderSearch::indexInitialHeaderMaps() {
410 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
413 for (
unsigned i = 0; i != SearchDirs.size(); ++i) {
414 auto &Dir = SearchDirs[i];
419 if (!Dir.isHeaderMap()) {
420 SearchDirHeaderMapIndex = std::move(Index);
421 FirstNonHeaderMapSearchDirIdx = i;
426 auto Callback = [&](StringRef Filename) {
427 Index.try_emplace(Filename.lower(), i);
429 Dir.getHeaderMap()->forEachKey(
Callback);
444 assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
450 bool IsSystemHeaderDir,
Module *RequestingModule,
452 bool CacheFailures ) {
459 std::error_code EC = llvm::errorToErrorCode(
File.takeError());
460 if (EC != llvm::errc::no_such_file_or_directory &&
461 EC != llvm::errc::invalid_argument &&
462 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
463 Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
470 if (!findUsableModuleForHeader(
471 *
File, Dir ? Dir :
File->getFileEntry().getDir(), RequestingModule,
472 SuggestedModule, IsSystemHeaderDir))
484 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound,
486 bool OpenFile)
const {
487 InUserSpecifiedSystemFramework =
false;
488 IsInHeaderMap =
false;
495 llvm::sys::path::append(TmpDir, Filename);
499 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
502 RelativePath->clear();
503 RelativePath->append(Filename.begin(), Filename.end());
506 return HS.getFileAndSuggestModule(
508 RequestingModule, SuggestedModule, OpenFile);
512 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
513 RequestingModule, SuggestedModule,
514 InUserSpecifiedSystemFramework, IsFrameworkFound);
516 assert(
isHeaderMap() &&
"Unknown directory lookup");
523 IsInHeaderMap =
true;
525 auto FixupSearchPathAndFindUsableModule =
528 StringRef SearchPathRef(
getName());
530 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
533 RelativePath->clear();
534 RelativePath->append(Filename.begin(), Filename.end());
536 if (!HS.findUsableModuleForHeader(
File,
File.getFileEntry().getDir(),
537 RequestingModule, SuggestedModule,
547 if (llvm::sys::path::is_relative(Dest)) {
548 MappedName.append(Dest.begin(), Dest.end());
549 Filename = StringRef(MappedName.begin(), MappedName.size());
554 return FixupSearchPathAndFindUsableModule(*Res);
574 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
575 "Not a framework directory");
591 auto TopFrameworkDir =
FileMgr.getOptionalDirectoryRef(DirName);
594 DirName =
FileMgr.getCanonicalName(*TopFrameworkDir);
597 DirName = llvm::sys::path::parent_path(DirName);
602 auto Dir =
FileMgr.getOptionalDirectoryRef(DirName);
608 if (llvm::sys::path::extension(DirName) ==
".framework") {
609 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
610 TopFrameworkDir = *Dir;
614 return TopFrameworkDir;
618 bool HasSuggestedModule) {
619 return HasSuggestedModule ||
629 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
633 size_t SlashPos = Filename.find(
'/');
634 if (SlashPos == StringRef::npos)
639 FrameworkCacheEntry &CacheEntry =
649 SmallString<1024> FrameworkName;
651 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
652 FrameworkName.push_back(
'/');
655 StringRef ModuleName(Filename.begin(), SlashPos);
656 FrameworkName += ModuleName;
659 FrameworkName +=
".framework/";
663 ++NumFrameworkLookups;
677 SmallString<1024> SystemFrameworkMarker(FrameworkName);
678 SystemFrameworkMarker +=
".system_framework";
689 RelativePath->clear();
690 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
694 unsigned OrigSize = FrameworkName.size();
696 FrameworkName +=
"Headers/";
701 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
704 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
710 const char *
Private =
"Private";
711 FrameworkName.insert(FrameworkName.begin()+OrigSize,
Private,
714 SearchPath->insert(SearchPath->begin()+OrigSize,
Private,
724 StringRef FrameworkPath =
File->getDir().getName();
725 bool FoundFramework =
false;
734 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
735 FoundFramework =
true;
740 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
741 if (FrameworkPath.empty())
746 if (FoundFramework) {
747 if (!HS.findUsableModuleForFrameworkHeader(*
File, FrameworkPath,
749 SuggestedModule, IsSystem))
752 if (!HS.findUsableModuleForHeader(*
File,
getDir(), RequestingModule,
753 SuggestedModule, IsSystem))
762void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
765 CacheLookup.HitIt = HitIt;
766 noteLookupUsage(HitIt.Idx, Loc);
769void HeaderSearch::noteLookupUsage(
unsigned HitIdx,
SourceLocation Loc) {
770 SearchDirsUsage[HitIdx] =
true;
772 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
773 if (UserEntryIdxIt != SearchDirToHSEntry.end())
774 Diags.Report(Loc, diag::remark_pp_search_path_usage)
775 << HSOpts.UserEntries[UserEntryIdxIt->second].Path;
793 if (MSFE && FE != *MSFE) {
794 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
800static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
801 assert(!Str.empty());
802 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
803 std::copy(Str.begin(), Str.end(), CopyStr);
804 CopyStr[Str.size()] =
'\0';
811 using namespace llvm::sys;
812 path::const_iterator I = path::begin(Path);
813 path::const_iterator E = path::end(Path);
814 IsPrivateHeader =
false;
826 if (*I ==
"Headers") {
828 }
else if (*I ==
"PrivateHeaders") {
830 IsPrivateHeader =
true;
831 }
else if (I->ends_with(
".framework")) {
832 StringRef Name = I->drop_back(10);
834 FrameworkName.clear();
835 FrameworkName.append(Name.begin(), Name.end());
836 IncludeSpelling.clear();
837 IncludeSpelling.append(Name.begin(), Name.end());
839 }
else if (FoundComp >= 2) {
840 IncludeSpelling.push_back(
'/');
841 IncludeSpelling.append(I->begin(), I->end());
846 return !FrameworkName.empty() && FoundComp >= 2;
851 StringRef Includer, StringRef IncludeFilename,
853 bool FoundByHeaderMap =
false) {
854 bool IsIncluderPrivateHeader =
false;
858 FromIncludeSpelling))
860 bool IsIncludeePrivateHeader =
false;
861 bool IsIncludeeInFramework =
863 ToFramework, ToIncludeSpelling);
865 if (!isAngled && !FoundByHeaderMap) {
867 if (IsIncludeeInFramework) {
868 NewInclude += ToIncludeSpelling;
871 NewInclude += IncludeFilename;
874 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
882 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
883 IsIncludeePrivateHeader && FromFramework == ToFramework)
884 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
890 ConstSearchDirIterator FromDir,
891 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
892 bool isAngled,
int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt) {
894 if (Diags.isIgnored(diag::warn_header_shadowing, IncludeLoc))
897 if (MainLoopIt && MainLoopIt->isSystemHeaderDirectory())
903 if (!ShadowCheckedHeaders[Filename].insert(FE).second)
908 for (
size_t i = IncluderLoopIndex + 1; i < Includers.size(); ++i) {
909 const auto &IncluderAndDir = Includers[i];
911 llvm::sys::path::append(TmpDir, Filename);
915 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
917 << IncluderAndDir.second.getName();
924 ConstSearchDirIterator It =
927 It = std::next(MainLoopIt);
928 }
else if (FromDir) {
936 llvm::sys::path::append(TmpPath, Filename);
940 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
954 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
955 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
958 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
959 bool BuildSystemModule,
bool OpenFile,
bool CacheFailures) {
960 ConstSearchDirIterator CurDirLocal =
nullptr;
961 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
966 if (IsFrameworkFound)
967 *IsFrameworkFound =
false;
973 if (llvm::sys::path::is_absolute(Filename)) {
983 RelativePath->clear();
984 RelativePath->append(Filename.begin(), Filename.end());
987 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
989 RequestingModule, SuggestedModule, OpenFile,
1002 if (!Includers.empty() && !isAngled) {
1005 for (
const auto &IncluderAndDir : Includers) {
1009 TmpDir = IncluderAndDir.second.getName();
1010 llvm::sys::path::append(TmpDir, Filename);
1019 bool IncluderIsSystemHeader = [&]() {
1021 return BuildSystemModule;
1023 assert(HFI &&
"includer without file info");
1027 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
1028 RequestingModule, SuggestedModule)) {
1030 isAngled, &IncluderAndDir - Includers.begin(),
1033 assert(
First &&
"only first includer can have no file");
1044 assert(FromHFI &&
"includer without file info");
1045 unsigned DirInfo = FromHFI->
DirInfo;
1051 StringRef SearchPathRef(IncluderAndDir.second.getName());
1052 SearchPath->clear();
1053 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
1056 RelativePath->clear();
1057 RelativePath->append(Filename.begin(), Filename.end());
1061 IncluderAndDir.second.getName(), Filename,
1069 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1073 if (SuggestedModule) {
1074 MSSuggestedModule = *SuggestedModule;
1087 ConstSearchDirIterator It =
1099 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1101 ConstSearchDirIterator NextIt = std::next(It);
1104 if (CacheLookup.StartIt == NextIt &&
1105 CacheLookup.RequestingModule == RequestingModule) {
1107 if (CacheLookup.HitIt)
1108 It = CacheLookup.HitIt;
1109 if (CacheLookup.MappedName) {
1110 Filename = CacheLookup.MappedName;
1118 CacheLookup.reset(RequestingModule, NextIt);
1124 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1125 if (Iter == SearchDirHeaderMapIndex.end())
1134 CacheLookup.reset(RequestingModule, NextIt);
1141 bool InUserSpecifiedSystemFramework =
false;
1142 bool IsInHeaderMap =
false;
1143 bool IsFrameworkFoundInDir =
false;
1145 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1146 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1147 IsInHeaderMap, MappedName, OpenFile);
1148 if (!MappedName.empty()) {
1149 assert(IsInHeaderMap &&
"MappedName should come from a header map");
1150 CacheLookup.MappedName =
1151 copyString(MappedName, LookupFileCache.getAllocator());
1157 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap &&
File));
1158 if (IsFrameworkFound)
1162 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1176 IncludeNames[*
File] = Filename;
1180 HFI.
DirInfo = CurDir->getDirCharacteristic();
1190 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1191 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1199 if (SuggestedModule)
1200 *SuggestedModule = MSSuggestedModule;
1204 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
1205 if (!Includers.empty())
1207 Includers.front().second.getName(), Filename,
1208 *
File, isAngled, FoundByHeaderMap);
1211 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1216 if (SuggestedModule)
1217 *SuggestedModule = MSSuggestedModule;
1223 return std::nullopt;
1237 size_t SlashPos = Filename.find(
'/');
1238 if (SlashPos == StringRef::npos)
1239 return std::nullopt;
1242 StringRef ContextName = ContextFileEnt.
getName();
1245 const unsigned DotFrameworkLen = 10;
1246 auto FrameworkPos = ContextName.find(
".framework");
1247 if (FrameworkPos == StringRef::npos ||
1248 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
1249 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1250 return std::nullopt;
1254 DotFrameworkLen + 1);
1257 FrameworkName +=
"Frameworks/";
1258 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1259 FrameworkName +=
".framework/";
1262 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1266 if (CacheLookup.second.Directory &&
1267 CacheLookup.first().size() == FrameworkName.size() &&
1268 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1269 CacheLookup.first().size()) != 0)
1270 return std::nullopt;
1273 if (!CacheLookup.second.Directory) {
1274 ++NumSubFrameworkLookups;
1277 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1279 return std::nullopt;
1283 CacheLookup.second.Directory = Dir;
1288 RelativePath->clear();
1289 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1294 HeadersFilename +=
"Headers/";
1296 SearchPath->clear();
1298 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1301 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1302 auto File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1305 HeadersFilename = FrameworkName;
1306 HeadersFilename +=
"PrivateHeaders/";
1308 SearchPath->clear();
1310 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1313 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1314 File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1317 return std::nullopt;
1322 assert(ContextHFI &&
"context file without file info");
1325 unsigned DirInfo = ContextHFI->
DirInfo;
1328 FrameworkName.pop_back();
1329 if (!findUsableModuleForFrameworkHeader(*
File, FrameworkName,
1330 RequestingModule, SuggestedModule,
1332 return std::nullopt;
1351 bool isModuleHeader,
1352 bool isTextualModuleHeader) {
1369 assert(OtherHFI.
External &&
"expected to merge external HFI");
1387 if (ExternalSource && !HFI->
Resolved) {
1388 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1389 if (ExternalHFI.IsValid) {
1391 if (ExternalHFI.External)
1405 if (ExternalSource) {
1406 HFI = &FileInfo[FE];
1409 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1410 if (ExternalHFI.IsValid) {
1412 if (ExternalHFI.External)
1416 }
else if (
auto It = FileInfo.find(FE); It != FileInfo.end()) {
1422 return (HFI && HFI->
IsValid) ? HFI :
nullptr;
1427 for (
const auto &[FE, HFI] : FileInfo)
1428 if (HFI.IsValid && !HFI.External)
1437 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1443 bool isCompilingModuleHeader) {
1445 if (!isCompilingModuleHeader) {
1454 HFI.mergeModuleMembership(
Role);
1455 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1460 bool ModulesEnabled,
Module *M,
1461 bool &IsFirstIncludeOfFile) {
1477 IsFirstIncludeOfFile =
false;
1480 auto MaybeReenterImportedFile = [&]() ->
bool {
1498 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1502 ModMap.resolveHeaderDirectives(
File);
1522 if (FileInfo.isTextualModuleHeader)
1525 if (FileInfo.isCompilingModuleHeader) {
1528 if (FileInfo.isModuleHeader) {
1533 if (ModMap.isBuiltinHeader(
File))
1542 if (FileInfo.getControllingMacro(ExternalLookup))
1562 FileInfo.isImport =
true;
1569 if (FileInfo.isPragmaOnce ||
1570 (FileInfo.isImport && !MaybeReenterImportedFile()))
1579 FileInfo.getControllingMacro(ExternalLookup)) {
1586 ++NumMultiIncludeFileOptzn;
1596 return SearchDirs.capacity()
1597 + llvm::capacity_in_bytes(FileInfo)
1598 + llvm::capacity_in_bytes(HeaderMaps)
1599 + LookupFileCache.getAllocator().getTotalMemory()
1600 + FrameworkMap.getAllocator().getTotalMemory();
1604 return &DL - &*SearchDirs.begin();
1608 return FrameworkNames.insert(Framework).first->first();
1612 auto It = IncludeNames.find(
File);
1613 if (It == IncludeNames.end())
1619 ModuleMapDirectoryState &MMState) {
1620 if (!MMState.ModuleMapFile)
1627 if (MMState.PrivateModuleMapFile)
1630 processModuleMapForIndex(*ParsedMM, Dir,
"", MMState);
1631 if (ParsedPrivateMM)
1632 processModuleMapForIndex(*ParsedPrivateMM, Dir,
"", MMState);
1635void HeaderSearch::addToModuleMapIndex(StringRef RelPath, StringRef ModuleName,
1636 StringRef PathPrefix,
1637 ModuleMapDirectoryState &MMState) {
1639 llvm::sys::path::append(RelFromRootPath, RelPath);
1640 llvm::sys::path::native(RelFromRootPath);
1641 MMState.HeaderToModules[RelFromRootPath].push_back(ModuleName);
1644void HeaderSearch::processExternModuleDeclForIndex(
1646 StringRef PathPrefix, ModuleMapDirectoryState &MMState) {
1647 StringRef FileNameRef = EMD.
Path;
1648 SmallString<128> ModuleMapFileName;
1649 if (llvm::sys::path::is_relative(FileNameRef)) {
1650 ModuleMapFileName = MMDir.
getName();
1651 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1652 FileNameRef = ModuleMapFileName;
1654 if (
auto EFile = FileMgr.getOptionalFileRef(FileNameRef)) {
1655 if (
auto *ExtMMF = ModMap.getParsedModuleMap(*EFile)) {
1658 SmallString<128> NewPrefix(PathPrefix);
1659 StringRef ExternDir = llvm::sys::path::parent_path(EMD.
Path);
1660 if (!ExternDir.empty()) {
1661 llvm::sys::path::append(NewPrefix, ExternDir);
1662 llvm::sys::path::native(NewPrefix);
1664 processModuleMapForIndex(*ExtMMF, EFile->getDir(), NewPrefix, MMState);
1670 StringRef ModuleName,
1672 StringRef PathPrefix,
1673 ModuleMapDirectoryState &MMState) {
1675 if (MD.
Id.front().first ==
"*")
1678 auto ProcessDecl = llvm::makeVisitor(
1679 [&](
const modulemap::HeaderDecl &HD) {
1681 MMState.UmbrellaHeaderModules.push_back(ModuleName);
1683 addToModuleMapIndex(HD.
Path, ModuleName, PathPrefix, MMState);
1686 [&](
const modulemap::UmbrellaDirDecl &UDD) {
1687 SmallString<128> FullPath(PathPrefix);
1688 llvm::sys::path::append(FullPath, UDD.Path);
1689 llvm::sys::path::native(FullPath);
1690 MMState.UmbrellaDirModules.push_back(
1691 std::make_pair(std::string(FullPath), ModuleName));
1693 [&](
const modulemap::ModuleDecl &SubMD) {
1694 processModuleDeclForIndex(SubMD, ModuleName, MMDir, PathPrefix,
1697 [&](
const modulemap::ExternModuleDecl &EMD) {
1698 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix, MMState);
1704 for (
const auto &Decl : MD.
Decls) {
1705 std::visit(ProcessDecl, Decl);
1711 StringRef PathPrefix,
1712 ModuleMapDirectoryState &MMState) {
1713 for (
const auto &Decl : MMF.
Decls) {
1714 std::visit(llvm::makeVisitor(
1715 [&](
const modulemap::ModuleDecl &MD) {
1716 processModuleDeclForIndex(MD, MD.
Id.front().first, MMDir,
1717 PathPrefix, MMState);
1719 [&](
const modulemap::ExternModuleDecl &EMD) {
1720 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix,
1732 if (!
FileName.starts_with(DirPath))
1734 StringRef RelativePath =
FileName.substr(DirPath.size());
1735 while (!RelativePath.empty() &&
1736 llvm::sys::path::is_separator(RelativePath.front()))
1737 RelativePath = RelativePath.substr(1);
1738 return RelativePath;
1742 StringRef RelativePath,
const ModuleMapDirectoryState &MMState)
const {
1743 SmallVector<StringRef, 1> Modules;
1746 auto CachedMods = MMState.HeaderToModules.find(RelativePath);
1747 if (CachedMods != MMState.HeaderToModules.end())
1748 Modules.append(CachedMods->second.begin(), CachedMods->second.end());
1751 for (
const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
1752 if (RelativePath.starts_with(UmbrellaDir.first) || UmbrellaDir.first ==
".")
1753 Modules.push_back(UmbrellaDir.second);
1767 Modules.append(MMState.UmbrellaHeaderModules.begin(),
1768 MMState.UmbrellaHeaderModules.end());
1776 if (!HSOpts.ImplicitModuleMaps)
1783 DirName = llvm::sys::path::parent_path(DirName);
1784 if (DirName.empty())
1788 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1794 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1798 parseModuleMapFile(*Dir, IsSystem,
true,
1800 auto DirState = DirectoryModuleMap.find(*Dir);
1801 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1804 if (!HSOpts.LazyLoadModuleMaps &&
1805 Diags.isIgnored(diag::warn_mmap_deprecated_symlink_to_modular_header,
1809 auto &MMState = DirState->second;
1812 if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() &&
1813 MMState.UmbrellaHeaderModules.empty()) {
1814 buildModuleMapIndex(*Dir, MMState);
1818 if (!HSOpts.LazyLoadModuleMaps)
1826 llvm::sys::path::native(RelativePathNative);
1828 auto ModulesToLoad =
1829 findMatchingModulesInIndex(RelativePathNative, MMState);
1832 bool LoadedAny =
false;
1833 for (StringRef ModName : ModulesToLoad) {
1834 if (ModMap.findOrLoadModule(ModName)) {
1843 }
while (CurDir != Root);
1849 bool AllowExcluded)
const {
1850 if (ExternalSource) {
1855 return ModMap.findModuleForHeader(
File, AllowTextual, AllowExcluded);
1860 if (ExternalSource) {
1865 return ModMap.findAllModulesForHeader(
File);
1870 if (ExternalSource) {
1875 return ModMap.findResolvedModulesForHeader(
File);
1892 if (SuggestedModule)
1902 if (SuggestedModule)
1916 if (!HSOpts.ImplicitModuleMaps ||
Module.getModule()->isPartOfFramework() ||
1917 !
Module.getModule()->isModuleMapModule())
1920 if (Diags.isIgnored(diag::warn_mmap_deprecated_symlink_to_modular_header,
1921 Module.getModule()->DefinitionLoc))
1924 if (
File.isDeviceFile() ||
File.isNamedPipe())
1927 llvm::SmallString<128> AbsPath(
File.getName());
1928 FileMgr.makeAbsolutePath(AbsPath);
1929 llvm::sys::path::remove_dots(AbsPath,
true);
1933 llvm::SmallString<128> LinkTarget;
1934 if (llvm::sys::fs::readlink(AbsPath, LinkTarget))
1942 const DirectoryEntry *CurDir =
nullptr;
1946 DirName = llvm::sys::path::parent_path(DirName);
1947 if (DirName.empty())
1950 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1955 auto DirState = DirectoryModuleMap.find(*Dir);
1956 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1962 if (RelativePath.empty())
1964 SmallString<128> RelativePathNative(RelativePath);
1965 llvm::sys::path::native(RelativePathNative);
1967 auto MatchingModules =
1968 findMatchingModulesInIndex(RelativePathNative, DirState->second);
1969 if (!MatchingModules.empty())
1971 }
while (CurDir != Root);
1974 Diags.Report(diag::warn_mmap_deprecated_symlink_to_modular_header)
1975 <<
File.getName() << LinkTarget
1976 <<
Module.getModule()->getFullModuleName();
1977 Diags.Report(
Module.getModule()->DefinitionLoc,
1978 diag::note_mmap_module_defined_here);
1981bool HeaderSearch::findUsableModuleForHeader(
1985 if (!HSOpts.LazyLoadModuleMaps) {
1991 ModuleMap::KnownHeader
Module =
1993 diagnoseUncoveredSymlink(
File,
Module, Root);
1999 ModuleMap::KnownHeader
Module =
2007 Module = ModMap.findModuleForHeader(
File,
true);
2009 diagnoseUncoveredSymlink(
File,
Module, Root);
2016bool HeaderSearch::findUsableModuleForFrameworkHeader(
2022 SmallVector<std::string, 4> SubmodulePath;
2025 assert(TopFrameworkDir &&
"Could not find the top-most framework dir");
2028 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
2032 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework,
2039 ModuleMap::KnownHeader
Module =
2050 bool Diagnose =
true) {
2051 StringRef Filename = llvm::sys::path::filename(
File.getName());
2053 if (Filename ==
"module.map")
2054 llvm::sys::path::append(PrivateFilename,
"module_private.map");
2055 else if (Filename ==
"module.modulemap")
2056 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
2058 return std::nullopt;
2059 auto PMMFile =
FileMgr.getOptionalFileRef(PrivateFilename);
2061 if (Diagnose && Filename ==
"module.map")
2062 Diags.
Report(diag::warn_deprecated_module_dot_map)
2063 << PrivateFilename << 1
2064 <<
File.getDir().getName().ends_with(
".framework");
2070 bool ImplicitlyDiscovered,
2071 FileID ID,
unsigned *Offset,
2072 StringRef OriginalModuleMapFile) {
2077 Dir = FileMgr.getOptionalDirectoryRef(
".");
2079 if (!OriginalModuleMapFile.empty()) {
2082 Dir = FileMgr.getOptionalDirectoryRef(
2083 llvm::sys::path::parent_path(OriginalModuleMapFile));
2085 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
2086 Dir = FakeFile.getDir();
2089 Dir =
File.getDir();
2092 assert(Dir &&
"parent must exist");
2093 StringRef DirName(Dir->
getName());
2094 if (llvm::sys::path::filename(DirName) ==
"Modules") {
2095 DirName = llvm::sys::path::parent_path(DirName);
2096 if (DirName.ends_with(
".framework"))
2097 if (
auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
2101 assert(Dir &&
"parent must exist");
2105 assert(Dir &&
"module map home directory must exist");
2106 switch (parseAndLoadModuleMapFileImpl(
File, IsSystem, ImplicitlyDiscovered,
2109 case MMR_AlreadyProcessed:
2110 case MMR_NewlyProcessed:
2112 case MMR_NoDirectory:
2113 case MMR_InvalidModuleMap:
2116 llvm_unreachable(
"Unknown load module map result");
2119HeaderSearch::ModuleMapResult HeaderSearch::parseAndLoadModuleMapFileImpl(
2124 auto AddResult = LoadedModuleMaps.insert(std::make_pair(
File,
true));
2125 if (!AddResult.second)
2126 return AddResult.first->second ? MMR_AlreadyProcessed
2127 : MMR_InvalidModuleMap;
2131 LoadedModuleMaps[
File] =
false;
2132 return MMR_InvalidModuleMap;
2139 ImplicitlyDiscovered, Dir)) {
2140 LoadedModuleMaps[
File] =
false;
2141 return MMR_InvalidModuleMap;
2146 return MMR_NewlyProcessed;
2149HeaderSearch::ModuleMapResult
2151 bool ImplicitlyDiscovered,
2155 auto AddResult = ParsedModuleMaps.insert(std::make_pair(
File,
true));
2156 if (!AddResult.second)
2157 return AddResult.first->second ? MMR_AlreadyProcessed
2158 : MMR_InvalidModuleMap;
2160 if (ModMap.parseModuleMapFile(
File, IsSystem, ImplicitlyDiscovered, Dir,
2162 ParsedModuleMaps[
File] =
false;
2163 return MMR_InvalidModuleMap;
2169 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, ImplicitlyDiscovered,
2171 ParsedModuleMaps[
File] =
false;
2172 return MMR_InvalidModuleMap;
2177 return MMR_NewlyProcessed;
2182 if (!HSOpts.ImplicitModuleMaps)
2183 return std::nullopt;
2188 llvm::sys::path::append(ModuleMapFileName,
"Modules");
2189 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
2190 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2194 ModuleMapFileName = Dir.
getName();
2195 llvm::sys::path::append(ModuleMapFileName,
"module.map");
2196 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
2197 Diags.Report(diag::warn_deprecated_module_dot_map)
2198 << ModuleMapFileName << 0 << IsFramework;
2205 ModuleMapFileName = Dir.
getName();
2206 llvm::sys::path::append(ModuleMapFileName,
"Modules",
2207 "module.private.modulemap");
2208 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2211 return std::nullopt;
2216 bool ImplicitlyDiscovered) {
2220 case MMR_InvalidModuleMap:
2223 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
2226 case MMR_NoDirectory:
2229 case MMR_AlreadyProcessed:
2230 case MMR_NewlyProcessed:
2237HeaderSearch::ModuleMapResult
2239 bool ImplicitlyDiscovered,
2241 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2245 return MMR_NoDirectory;
2248HeaderSearch::ModuleMapResult
2250 bool ImplicitlyDiscovered,
2252 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2253 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2254 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2255 if (!InsertRes.second) {
2256 switch (MMState.Status) {
2257 case ModuleMapDirectoryState::Parsed:
2259 case ModuleMapDirectoryState::Loaded:
2260 return MMR_AlreadyProcessed;
2261 case ModuleMapDirectoryState::Invalid:
2262 return MMR_InvalidModuleMap;
2266 if (!MMState.ModuleMapFile) {
2268 if (MMState.ModuleMapFile)
2269 MMState.PrivateModuleMapFile =
2273 if (MMState.ModuleMapFile) {
2274 ModuleMapResult
Result = parseAndLoadModuleMapFileImpl(
2275 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2279 if (
Result == MMR_NewlyProcessed)
2280 MMState.Status = ModuleMapDirectoryState::Loaded;
2281 else if (
Result == MMR_InvalidModuleMap)
2282 MMState.Status = ModuleMapDirectoryState::Invalid;
2285 return MMR_InvalidModuleMap;
2288HeaderSearch::ModuleMapResult
2289HeaderSearch::parseModuleMapFile(StringRef DirName,
bool IsSystem,
2290 bool ImplicitlyDiscovered,
bool IsFramework) {
2291 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2292 return parseModuleMapFile(*Dir, IsSystem, ImplicitlyDiscovered,
2295 return MMR_NoDirectory;
2298HeaderSearch::ModuleMapResult
2300 bool ImplicitlyDiscovered,
bool IsFramework) {
2301 if (!HSOpts.LazyLoadModuleMaps)
2305 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2306 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2307 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2308 if (!InsertRes.second) {
2309 switch (MMState.Status) {
2310 case ModuleMapDirectoryState::Parsed:
2311 case ModuleMapDirectoryState::Loaded:
2312 return MMR_AlreadyProcessed;
2313 case ModuleMapDirectoryState::Invalid:
2314 return MMR_InvalidModuleMap;
2318 if (!MMState.ModuleMapFile) {
2320 if (MMState.ModuleMapFile)
2321 MMState.PrivateModuleMapFile =
2325 if (MMState.ModuleMapFile) {
2326 ModuleMapResult
Result = parseModuleMapFileImpl(
2327 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2331 if (
Result == MMR_NewlyProcessed)
2332 MMState.Status = ModuleMapDirectoryState::Parsed;
2333 else if (
Result == MMR_InvalidModuleMap)
2334 MMState.Status = ModuleMapDirectoryState::Invalid;
2337 return MMR_InvalidModuleMap;
2343 if (HSOpts.ImplicitModuleMaps) {
2346 bool IsSystem = DL.isSystemHeaderDirectory();
2347 if (DL.isFramework()) {
2350 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
2353 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2354 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
2356 Dir != DirEnd && !EC; Dir.increment(EC)) {
2357 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
2360 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
2365 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2372 if (DL.isHeaderMap())
2382 loadSubdirectoryModuleMaps(DL);
2387 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2391 if (!HSOpts.ImplicitModuleMaps)
2397 if (!DL.isNormalDir())
2402 true, DL.isFramework());
2406void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
2408 "Should not be loading subdirectory module maps");
2415 FileMgr.makeAbsolutePath(Dir);
2417 llvm::sys::path::native(Dir, DirNative);
2418 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
2419 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2420 Dir != DirEnd && !EC; Dir.increment(EC)) {
2421 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2423 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
2436 MainFile, IsAngled);
2440 llvm::StringRef
File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2441 bool *IsAngled)
const {
2442 using namespace llvm::sys;
2445 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2446 path::make_absolute(WorkingDir, FilePath);
2450 path::remove_dots(FilePath,
true);
2451 path::native(FilePath, path::Style::posix);
2454 unsigned BestPrefixLength = 0;
2459 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2460 path::make_absolute(WorkingDir, Dir);
2461 path::remove_dots(Dir,
true);
2462 for (
auto NI = path::begin(
File), NE = path::end(
File),
2463 DI = path::begin(Dir), DE = path::end(Dir);
2464 NI != NE; ++NI, ++DI) {
2467 unsigned PrefixLength = NI - path::begin(
File);
2468 if (PrefixLength > BestPrefixLength) {
2469 BestPrefixLength = PrefixLength;
2476 if (NI->size() == 1 && DI->size() == 1 &&
2477 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2483 if (NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
2484 StringRef NBasename = path::stem(*NI);
2485 StringRef DBasename = path::stem(*DI);
2486 if (DBasename.starts_with(NBasename))
2496 bool BestPrefixIsFramework =
false;
2498 if (DL.isNormalDir()) {
2499 StringRef Dir = DL.getDirRef()->getName();
2500 if (CheckDir(Dir)) {
2502 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2503 BestPrefixIsFramework =
false;
2505 }
else if (DL.isFramework()) {
2506 StringRef Dir = DL.getFrameworkDirRef()->getName();
2507 if (CheckDir(Dir)) {
2510 *IsAngled = BestPrefixLength;
2511 BestPrefixIsFramework =
true;
2518 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2521 BestPrefixIsFramework =
false;
2526 StringRef Filename =
File.drop_front(BestPrefixLength);
2528 if (!DL.isHeaderMap())
2531 StringRef SpelledFilename =
2532 DL.getHeaderMap()->reverseLookupFilename(Filename);
2533 if (!SpelledFilename.empty()) {
2534 Filename = SpelledFilename;
2535 BestPrefixIsFramework =
false;
2542 bool IsPrivateHeader;
2544 if (BestPrefixIsFramework &&
2547 Filename = IncludeSpelling;
2549 return path::convert_to_slash(Filename);
2554 NormalizedPath.assign(Path.begin(), Path.end());
2555 if (!NormalizedPath.empty()) {
2556 FileMgr.makeAbsolutePath(NormalizedPath);
2557 llvm::sys::path::remove_dots(NormalizedPath);
2563 std::string ContextHash,
size_t &NormalizedModuleCachePathLen) {
2566 NormalizedModuleCachePathLen = SpecificModuleCachePath.size();
2567 if (!SpecificModuleCachePath.empty() && !DisableModuleHash)
2568 llvm::sys::path::append(SpecificModuleCachePath, ContextHash);
2569 return std::string(SpecificModuleCachePath);
2573 ContextHash = std::move(NewContextHash);
2575 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash, ContextHash,
2576 NormalizedModuleCachePathLen);
2580 StringRef ModuleCachePath,
2581 bool DisableModuleHash,
2582 std::string ContextHash) {
2583 size_t NormalizedModuleCachePathLen;
2585 FileMgr, ModuleCachePath, DisableModuleHash, std::move(ContextHash),
2586 NormalizedModuleCachePathLen);
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Result
Implement __builtin_bit_cast and related operations.
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.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
OptionalFileEntryRef LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, bool &IsInHeaderMap, SmallVectorImpl< char > &MappedName, bool OpenFile=true) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
bool isFramework() const
isFramework - True if this is a framework directory.
bool isSystemHeaderDirectory() const
Whether this describes a system header directory.
OptionalDirectoryEntryRef getFrameworkDirRef() const
void setSearchedAllModuleMaps(bool SAMM)
Specify whether we have already searched all of the subdirectories for module maps.
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
OptionalDirectoryEntryRef getDirRef() const
bool haveSearchedAllModuleMaps() const
Determine whether we have already searched this entire directory for module maps.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
bool isNormalDir() const
isNormalDir - Return true if this is a normal directory, not a header map.
const HeaderMap * getHeaderMap() const
getHeaderMap - Return the directory that this entry refers to.
Abstract interface for external sources of preprocessor information.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
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.
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
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...
bool isValid() const
Whether this pointer is non-NULL.
Identifies a module file to be loaded.
static ModuleFileName makeImplicit(std::string Name, unsigned SuffixLength)
Creates a file name for an implicit module.
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
const modulemap::ModuleMapFile * getParsedModuleMap(FileEntryRef File) const
Get the ModuleMapFile for a FileEntry previously parsed with parseModuleMapFile.
ModuleHeaderRole
Flags describing the role of a module header.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Module * findOrLoadModule(StringRef Name)
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
std::string Name
The name of this module.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool markIncluded(FileEntryRef File)
Mark the file as included.
bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M)
Determine whether II is defined as a macro within the module M, if that is a module that we've alread...
bool isMacroDefined(StringRef Id)
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
std::string createSpecificModuleCachePath(FileManager &FileMgr, StringRef ModuleCachePath, bool DisableModuleHash, std::string ContextHash)
void normalizeModuleCachePath(FileManager &FileMgr, StringRef Path, SmallVectorImpl< char > &NormalizedPath)
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
This structure is used to record entries in our framework cache.
bool IsUserSpecifiedSystemFramework
Whether this framework has been "user-specified" to be treated as if it were a system framework (even...
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::vector< Decl > Decls
Represents the parsed form of a module map file.
std::vector< TopLevelDecl > Decls