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 (
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";
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);
288 SmallString<128> CanonicalPath(ModuleMapPath);
289 if (
getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
292 auto Hash = llvm::xxh3_64bits(CanonicalPath.str().lower());
294 SmallString<128> HashStr;
295 llvm::APInt(64, Hash).toStringUnsigned(HashStr, 36);
296 llvm::sys::path::append(
Result, ModuleName +
"-" + HashStr +
".pcm");
303 bool AllowExtraModuleMapSearch) {
306 if (
Module || !AllowSearch || !HSOpts.ImplicitModuleMaps)
309 StringRef SearchName = ModuleName;
311 AllowExtraModuleMapSearch);
321 if (!
Module && SearchName.consume_back(
"_Private"))
323 AllowExtraModuleMapSearch);
324 if (!
Module && SearchName.consume_back(
"Private"))
326 AllowExtraModuleMapSearch);
332 bool AllowExtraModuleMapSearch) {
338 if (Dir.isFramework()) {
343 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
344 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
345 if (
auto FrameworkDir =
346 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
348 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem,
358 if (!Dir.isNormalDir())
361 bool IsSystem = Dir.isSystemHeaderDirectory();
364 DirectoryEntryRef NormalDir = *Dir.getDirRef();
366 if (parseModuleMapFile(NormalDir, IsSystem,
true,
367 false) == MMR_NewlyProcessed) {
370 Module = ModMap.findOrLoadModule(ModuleName);
377 SmallString<128> NestedModuleMapDirName;
378 NestedModuleMapDirName = Dir.getDirRef()->getName();
379 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
380 if (parseModuleMapFile(NestedModuleMapDirName, IsSystem,
382 false) == MMR_NewlyProcessed) {
384 Module = ModMap.findOrLoadModule(ModuleName);
389 if (HSOpts.AllowModuleMapSubdirectorySearch) {
392 if (Dir.haveSearchedAllModuleMaps())
397 if (AllowExtraModuleMapSearch)
398 loadSubdirectoryModuleMaps(Dir);
401 Module = ModMap.findOrLoadModule(ModuleName);
410void HeaderSearch::indexInitialHeaderMaps() {
411 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
414 for (
unsigned i = 0; i != SearchDirs.size(); ++i) {
415 auto &Dir = SearchDirs[i];
420 if (!Dir.isHeaderMap()) {
421 SearchDirHeaderMapIndex = std::move(Index);
422 FirstNonHeaderMapSearchDirIdx = i;
427 auto Callback = [&](StringRef Filename) {
428 Index.try_emplace(Filename.lower(), i);
430 Dir.getHeaderMap()->forEachKey(Callback);
445 assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
451 bool IsSystemHeaderDir,
Module *RequestingModule,
453 bool CacheFailures ) {
460 std::error_code EC = llvm::errorToErrorCode(
File.takeError());
461 if (EC != llvm::errc::no_such_file_or_directory &&
462 EC != llvm::errc::invalid_argument &&
463 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
464 Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
471 if (!findUsableModuleForHeader(
472 *
File, Dir ? Dir :
File->getFileEntry().getDir(), RequestingModule,
473 SuggestedModule, IsSystemHeaderDir))
485 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound,
487 bool OpenFile)
const {
488 InUserSpecifiedSystemFramework =
false;
489 IsInHeaderMap =
false;
496 llvm::sys::path::append(TmpDir, Filename);
500 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
503 RelativePath->clear();
504 RelativePath->append(Filename.begin(), Filename.end());
507 return HS.getFileAndSuggestModule(
509 RequestingModule, SuggestedModule, OpenFile);
513 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
514 RequestingModule, SuggestedModule,
515 InUserSpecifiedSystemFramework, IsFrameworkFound);
517 assert(
isHeaderMap() &&
"Unknown directory lookup");
524 IsInHeaderMap =
true;
526 auto FixupSearchPathAndFindUsableModule =
529 StringRef SearchPathRef(
getName());
531 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
534 RelativePath->clear();
535 RelativePath->append(Filename.begin(), Filename.end());
537 if (!HS.findUsableModuleForHeader(
File,
File.getFileEntry().getDir(),
538 RequestingModule, SuggestedModule,
548 if (llvm::sys::path::is_relative(Dest)) {
549 MappedName.append(Dest.begin(), Dest.end());
550 Filename = StringRef(MappedName.begin(), MappedName.size());
555 return FixupSearchPathAndFindUsableModule(*Res);
575 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
576 "Not a framework directory");
592 auto TopFrameworkDir =
FileMgr.getOptionalDirectoryRef(DirName);
595 DirName =
FileMgr.getCanonicalName(*TopFrameworkDir);
598 DirName = llvm::sys::path::parent_path(DirName);
603 auto Dir =
FileMgr.getOptionalDirectoryRef(DirName);
609 if (llvm::sys::path::extension(DirName) ==
".framework") {
610 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
611 TopFrameworkDir = *Dir;
615 return TopFrameworkDir;
619 bool HasSuggestedModule) {
620 return HasSuggestedModule ||
630 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
634 size_t SlashPos = Filename.find(
'/');
635 if (SlashPos == StringRef::npos)
640 FrameworkCacheEntry &CacheEntry =
650 SmallString<1024> FrameworkName;
652 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
653 FrameworkName.push_back(
'/');
656 StringRef ModuleName(Filename.begin(), SlashPos);
657 FrameworkName += ModuleName;
660 FrameworkName +=
".framework/";
664 ++NumFrameworkLookups;
678 SmallString<1024> SystemFrameworkMarker(FrameworkName);
679 SystemFrameworkMarker +=
".system_framework";
690 RelativePath->clear();
691 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
695 unsigned OrigSize = FrameworkName.size();
697 FrameworkName +=
"Headers/";
702 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
705 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
711 const char *
Private =
"Private";
712 FrameworkName.insert(FrameworkName.begin()+OrigSize,
Private,
715 SearchPath->insert(SearchPath->begin()+OrigSize,
Private,
725 StringRef FrameworkPath =
File->getDir().getName();
726 bool FoundFramework =
false;
735 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
736 FoundFramework =
true;
741 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
742 if (FrameworkPath.empty())
747 if (FoundFramework) {
748 if (!HS.findUsableModuleForFrameworkHeader(*
File, FrameworkPath,
750 SuggestedModule, IsSystem))
753 if (!HS.findUsableModuleForHeader(*
File,
getDir(), RequestingModule,
754 SuggestedModule, IsSystem))
763void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
766 CacheLookup.HitIt = HitIt;
767 noteLookupUsage(HitIt.Idx, Loc);
770void HeaderSearch::noteLookupUsage(
unsigned HitIdx,
SourceLocation Loc) {
771 SearchDirsUsage[HitIdx] =
true;
773 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
774 if (UserEntryIdxIt != SearchDirToHSEntry.end())
775 Diags.Report(Loc, diag::remark_pp_search_path_usage)
776 << HSOpts.UserEntries[UserEntryIdxIt->second].Path;
794 if (MSFE && FE != *MSFE) {
795 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
801static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
802 assert(!Str.empty());
803 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
804 std::copy(Str.begin(), Str.end(), CopyStr);
805 CopyStr[Str.size()] =
'\0';
812 using namespace llvm::sys;
813 path::const_iterator I = path::begin(Path);
814 path::const_iterator E = path::end(Path);
815 IsPrivateHeader =
false;
827 if (*I ==
"Headers") {
829 }
else if (*I ==
"PrivateHeaders") {
831 IsPrivateHeader =
true;
832 }
else if (I->ends_with(
".framework")) {
833 StringRef Name = I->drop_back(10);
835 FrameworkName.clear();
836 FrameworkName.append(Name.begin(), Name.end());
837 IncludeSpelling.clear();
838 IncludeSpelling.append(Name.begin(), Name.end());
840 }
else if (FoundComp >= 2) {
841 IncludeSpelling.push_back(
'/');
842 IncludeSpelling.append(I->begin(), I->end());
847 return !FrameworkName.empty() && FoundComp >= 2;
852 StringRef Includer, StringRef IncludeFilename,
854 bool FoundByHeaderMap =
false) {
855 bool IsIncluderPrivateHeader =
false;
859 FromIncludeSpelling))
861 bool IsIncludeePrivateHeader =
false;
862 bool IsIncludeeInFramework =
864 ToFramework, ToIncludeSpelling);
866 if (!isAngled && !FoundByHeaderMap) {
868 if (IsIncludeeInFramework) {
869 NewInclude += ToIncludeSpelling;
872 NewInclude += IncludeFilename;
875 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
883 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
884 IsIncludeePrivateHeader && FromFramework == ToFramework)
885 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
892 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
893 bool isAngled,
int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt) {
895 if (Diags.isIgnored(diag::warn_header_shadowing, IncludeLoc) ||
899 if (MainLoopIt && MainLoopIt->isSystemHeaderDirectory())
902 DiagnosedShadowing =
true;
906 for (
size_t i = IncluderLoopIndex + 1; i < Includers.size(); ++i) {
907 const auto &IncluderAndDir = Includers[i];
909 llvm::sys::path::append(TmpDir, Filename);
911 if (&
File->getFileEntry() == *FE)
913 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
914 << Filename << (*FE).getDir().getName()
915 << IncluderAndDir.second.getName();
918 llvm::errorToErrorCode(
File.takeError());
924 ConstSearchDirIterator It =
927 It = std::next(MainLoopIt);
928 }
else if (FromDir) {
936 llvm::sys::path::append(TmpPath, Filename);
938 if (&
File->getFileEntry() == *FE)
940 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
941 << Filename << (*FE).getDir().getName() << It->getName();
944 llvm::errorToErrorCode(
File.takeError());
956 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
957 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
960 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
961 bool BuildSystemModule,
bool OpenFile,
bool CacheFailures) {
962 ConstSearchDirIterator CurDirLocal =
nullptr;
963 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
968 if (IsFrameworkFound)
969 *IsFrameworkFound =
false;
975 if (llvm::sys::path::is_absolute(Filename)) {
985 RelativePath->clear();
986 RelativePath->append(Filename.begin(), Filename.end());
989 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
991 RequestingModule, SuggestedModule, OpenFile,
998 bool DiagnosedShadowing =
false;
1005 if (!Includers.empty() && !isAngled) {
1008 for (
const auto &IncluderAndDir : Includers) {
1012 TmpDir = IncluderAndDir.second.getName();
1013 llvm::sys::path::append(TmpDir, Filename);
1022 bool IncluderIsSystemHeader = [&]() {
1024 return BuildSystemModule;
1026 assert(HFI &&
"includer without file info");
1030 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
1031 RequestingModule, SuggestedModule)) {
1033 FromDir, Includers, isAngled,
1034 &IncluderAndDir - Includers.begin(),
nullptr);
1036 assert(
First &&
"only first includer can have no file");
1047 assert(FromHFI &&
"includer without file info");
1048 unsigned DirInfo = FromHFI->
DirInfo;
1054 StringRef SearchPathRef(IncluderAndDir.second.getName());
1055 SearchPath->clear();
1056 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
1059 RelativePath->clear();
1060 RelativePath->append(Filename.begin(), Filename.end());
1064 IncluderAndDir.second.getName(), Filename,
1072 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1076 if (SuggestedModule) {
1077 MSSuggestedModule = *SuggestedModule;
1090 ConstSearchDirIterator It =
1102 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1104 ConstSearchDirIterator NextIt = std::next(It);
1107 if (CacheLookup.StartIt == NextIt &&
1108 CacheLookup.RequestingModule == RequestingModule) {
1110 if (CacheLookup.HitIt)
1111 It = CacheLookup.HitIt;
1112 if (CacheLookup.MappedName) {
1113 Filename = CacheLookup.MappedName;
1121 CacheLookup.reset(RequestingModule, NextIt);
1127 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1128 if (Iter == SearchDirHeaderMapIndex.end())
1137 CacheLookup.reset(RequestingModule, NextIt);
1144 bool InUserSpecifiedSystemFramework =
false;
1145 bool IsInHeaderMap =
false;
1146 bool IsFrameworkFoundInDir =
false;
1148 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1149 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1150 IsInHeaderMap, MappedName, OpenFile);
1151 if (!MappedName.empty()) {
1152 assert(IsInHeaderMap &&
"MappedName should come from a header map");
1153 CacheLookup.MappedName =
1154 copyString(MappedName, LookupFileCache.getAllocator());
1160 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap &&
File));
1161 if (IsFrameworkFound)
1165 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1170 FromDir, Includers, isAngled, -1, It);
1174 IncludeNames[*
File] = Filename;
1178 HFI.
DirInfo = CurDir->getDirCharacteristic();
1188 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1189 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1197 if (SuggestedModule)
1198 *SuggestedModule = MSSuggestedModule;
1202 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
1203 if (!Includers.empty())
1205 Includers.front().second.getName(), Filename,
1206 *
File, isAngled, FoundByHeaderMap);
1209 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1214 if (SuggestedModule)
1215 *SuggestedModule = MSSuggestedModule;
1221 return std::nullopt;
1235 size_t SlashPos = Filename.find(
'/');
1236 if (SlashPos == StringRef::npos)
1237 return std::nullopt;
1240 StringRef ContextName = ContextFileEnt.
getName();
1243 const unsigned DotFrameworkLen = 10;
1244 auto FrameworkPos = ContextName.find(
".framework");
1245 if (FrameworkPos == StringRef::npos ||
1246 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
1247 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1248 return std::nullopt;
1252 DotFrameworkLen + 1);
1255 FrameworkName +=
"Frameworks/";
1256 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1257 FrameworkName +=
".framework/";
1260 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1264 if (CacheLookup.second.Directory &&
1265 CacheLookup.first().size() == FrameworkName.size() &&
1266 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1267 CacheLookup.first().size()) != 0)
1268 return std::nullopt;
1271 if (!CacheLookup.second.Directory) {
1272 ++NumSubFrameworkLookups;
1275 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1277 return std::nullopt;
1281 CacheLookup.second.Directory = Dir;
1286 RelativePath->clear();
1287 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1292 HeadersFilename +=
"Headers/";
1294 SearchPath->clear();
1296 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1299 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1300 auto File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1303 HeadersFilename = FrameworkName;
1304 HeadersFilename +=
"PrivateHeaders/";
1306 SearchPath->clear();
1308 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1311 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1312 File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1315 return std::nullopt;
1320 assert(ContextHFI &&
"context file without file info");
1323 unsigned DirInfo = ContextHFI->
DirInfo;
1326 FrameworkName.pop_back();
1327 if (!findUsableModuleForFrameworkHeader(*
File, FrameworkName,
1328 RequestingModule, SuggestedModule,
1330 return std::nullopt;
1349 bool isModuleHeader,
1350 bool isTextualModuleHeader) {
1367 assert(OtherHFI.
External &&
"expected to merge external HFI");
1383 if (FE.
getUID() >= FileInfo.size())
1384 FileInfo.resize(FE.
getUID() + 1);
1388 if (ExternalSource && !HFI->
Resolved) {
1389 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1390 if (ExternalHFI.IsValid) {
1392 if (ExternalHFI.External)
1406 if (ExternalSource) {
1407 if (FE.
getUID() >= FileInfo.size())
1408 FileInfo.resize(FE.
getUID() + 1);
1410 HFI = &FileInfo[FE.
getUID()];
1413 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1414 if (ExternalHFI.IsValid) {
1416 if (ExternalHFI.External)
1420 }
else if (FE.
getUID() < FileInfo.size()) {
1421 HFI = &FileInfo[FE.
getUID()];
1426 return (HFI && HFI->
IsValid) ? HFI :
nullptr;
1432 if (FE.
getUID() < FileInfo.size()) {
1433 HFI = &FileInfo[FE.
getUID()];
1446 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1452 bool isCompilingModuleHeader) {
1454 if (!isCompilingModuleHeader) {
1463 HFI.mergeModuleMembership(
Role);
1464 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1469 bool ModulesEnabled,
Module *M,
1470 bool &IsFirstIncludeOfFile) {
1486 IsFirstIncludeOfFile =
false;
1489 auto MaybeReenterImportedFile = [&]() ->
bool {
1507 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1511 ModMap.resolveHeaderDirectives(
File);
1531 if (FileInfo.isTextualModuleHeader)
1534 if (FileInfo.isCompilingModuleHeader) {
1537 if (FileInfo.isModuleHeader) {
1542 if (ModMap.isBuiltinHeader(
File))
1551 if (FileInfo.getControllingMacro(ExternalLookup))
1571 FileInfo.isImport =
true;
1578 if (FileInfo.isPragmaOnce ||
1579 (FileInfo.isImport && !MaybeReenterImportedFile()))
1588 FileInfo.getControllingMacro(ExternalLookup)) {
1595 ++NumMultiIncludeFileOptzn;
1605 return SearchDirs.capacity()
1606 + llvm::capacity_in_bytes(FileInfo)
1607 + llvm::capacity_in_bytes(HeaderMaps)
1608 + LookupFileCache.getAllocator().getTotalMemory()
1609 + FrameworkMap.getAllocator().getTotalMemory();
1613 return &DL - &*SearchDirs.begin();
1617 return FrameworkNames.insert(Framework).first->first();
1621 auto It = IncludeNames.find(
File);
1622 if (It == IncludeNames.end())
1628 ModuleMapDirectoryState &MMState) {
1629 if (!MMState.ModuleMapFile)
1636 if (MMState.PrivateModuleMapFile)
1639 processModuleMapForIndex(*ParsedMM, Dir,
"", MMState);
1640 if (ParsedPrivateMM)
1641 processModuleMapForIndex(*ParsedPrivateMM, Dir,
"", MMState);
1644void HeaderSearch::addToModuleMapIndex(StringRef RelPath, StringRef ModuleName,
1645 StringRef PathPrefix,
1646 ModuleMapDirectoryState &MMState) {
1648 llvm::sys::path::append(RelFromRootPath, RelPath);
1649 llvm::sys::path::native(RelFromRootPath);
1650 MMState.HeaderToModules[RelFromRootPath].push_back(ModuleName);
1653void HeaderSearch::processExternModuleDeclForIndex(
1655 StringRef PathPrefix, ModuleMapDirectoryState &MMState) {
1656 StringRef FileNameRef = EMD.
Path;
1657 SmallString<128> ModuleMapFileName;
1658 if (llvm::sys::path::is_relative(FileNameRef)) {
1659 ModuleMapFileName = MMDir.
getName();
1660 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1661 FileNameRef = ModuleMapFileName;
1663 if (
auto EFile = FileMgr.getOptionalFileRef(FileNameRef)) {
1664 if (
auto *ExtMMF = ModMap.getParsedModuleMap(*EFile)) {
1667 SmallString<128> NewPrefix(PathPrefix);
1668 StringRef ExternDir = llvm::sys::path::parent_path(EMD.
Path);
1669 if (!ExternDir.empty()) {
1670 llvm::sys::path::append(NewPrefix, ExternDir);
1671 llvm::sys::path::native(NewPrefix);
1673 processModuleMapForIndex(*ExtMMF, EFile->getDir(), NewPrefix, MMState);
1679 StringRef ModuleName,
1681 StringRef PathPrefix,
1682 ModuleMapDirectoryState &MMState) {
1684 if (MD.
Id.front().first ==
"*")
1687 auto ProcessDecl = llvm::makeVisitor(
1688 [&](
const modulemap::HeaderDecl &HD) {
1690 MMState.UmbrellaHeaderModules.push_back(ModuleName);
1692 addToModuleMapIndex(HD.
Path, ModuleName, PathPrefix, MMState);
1695 [&](
const modulemap::UmbrellaDirDecl &UDD) {
1696 SmallString<128> FullPath(PathPrefix);
1697 llvm::sys::path::append(FullPath, UDD.Path);
1698 llvm::sys::path::native(FullPath);
1699 MMState.UmbrellaDirModules.push_back(
1700 std::make_pair(std::string(FullPath), ModuleName));
1702 [&](
const modulemap::ModuleDecl &SubMD) {
1703 processModuleDeclForIndex(SubMD, ModuleName, MMDir, PathPrefix,
1706 [&](
const modulemap::ExternModuleDecl &EMD) {
1707 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix, MMState);
1713 for (
const auto &Decl : MD.
Decls) {
1714 std::visit(ProcessDecl, Decl);
1720 StringRef PathPrefix,
1721 ModuleMapDirectoryState &MMState) {
1722 for (
const auto &Decl : MMF.
Decls) {
1723 std::visit(llvm::makeVisitor(
1724 [&](
const modulemap::ModuleDecl &MD) {
1725 processModuleDeclForIndex(MD, MD.
Id.front().first, MMDir,
1726 PathPrefix, MMState);
1728 [&](
const modulemap::ExternModuleDecl &EMD) {
1729 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix,
1741 if (!
FileName.starts_with(DirPath))
1743 StringRef RelativePath =
FileName.substr(DirPath.size());
1744 while (!RelativePath.empty() &&
1745 llvm::sys::path::is_separator(RelativePath.front()))
1746 RelativePath = RelativePath.substr(1);
1747 return RelativePath;
1751 StringRef RelativePath,
const ModuleMapDirectoryState &MMState)
const {
1752 SmallVector<StringRef, 1> Modules;
1755 auto CachedMods = MMState.HeaderToModules.find(RelativePath);
1756 if (CachedMods != MMState.HeaderToModules.end())
1757 Modules.append(CachedMods->second.begin(), CachedMods->second.end());
1760 for (
const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
1761 if (RelativePath.starts_with(UmbrellaDir.first) || UmbrellaDir.first ==
".")
1762 Modules.push_back(UmbrellaDir.second);
1776 Modules.append(MMState.UmbrellaHeaderModules.begin(),
1777 MMState.UmbrellaHeaderModules.end());
1785 if (!HSOpts.ImplicitModuleMaps)
1792 DirName = llvm::sys::path::parent_path(DirName);
1793 if (DirName.empty())
1797 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1803 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1807 parseModuleMapFile(*Dir, IsSystem,
true,
1809 auto DirState = DirectoryModuleMap.find(*Dir);
1810 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1813 if (!HSOpts.LazyLoadModuleMaps &&
1814 Diags.isIgnored(diag::warn_mmap_deprecated_symlink_to_modular_header,
1818 auto &MMState = DirState->second;
1821 if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() &&
1822 MMState.UmbrellaHeaderModules.empty()) {
1823 buildModuleMapIndex(*Dir, MMState);
1827 if (!HSOpts.LazyLoadModuleMaps)
1835 llvm::sys::path::native(RelativePathNative);
1837 auto ModulesToLoad =
1838 findMatchingModulesInIndex(RelativePathNative, MMState);
1841 bool LoadedAny =
false;
1842 for (StringRef ModName : ModulesToLoad) {
1843 if (ModMap.findOrLoadModule(ModName)) {
1852 }
while (CurDir != Root);
1858 bool AllowExcluded)
const {
1859 if (ExternalSource) {
1864 return ModMap.findModuleForHeader(
File, AllowTextual, AllowExcluded);
1869 if (ExternalSource) {
1874 return ModMap.findAllModulesForHeader(
File);
1879 if (ExternalSource) {
1884 return ModMap.findResolvedModulesForHeader(
File);
1901 if (SuggestedModule)
1911 if (SuggestedModule)
1925 if (!HSOpts.ImplicitModuleMaps ||
Module.getModule()->isPartOfFramework() ||
1926 !
Module.getModule()->isModuleMapModule())
1929 if (Diags.isIgnored(diag::warn_mmap_deprecated_symlink_to_modular_header,
1930 Module.getModule()->DefinitionLoc))
1933 if (
File.isDeviceFile() ||
File.isNamedPipe())
1936 llvm::SmallString<128> AbsPath(
File.getName());
1937 FileMgr.makeAbsolutePath(AbsPath);
1938 llvm::sys::path::remove_dots(AbsPath,
true);
1942 llvm::SmallString<128> LinkTarget;
1943 if (llvm::sys::fs::readlink(AbsPath, LinkTarget))
1951 const DirectoryEntry *CurDir =
nullptr;
1955 DirName = llvm::sys::path::parent_path(DirName);
1956 if (DirName.empty())
1959 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1964 auto DirState = DirectoryModuleMap.find(*Dir);
1965 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1971 if (RelativePath.empty())
1973 SmallString<128> RelativePathNative(RelativePath);
1974 llvm::sys::path::native(RelativePathNative);
1976 auto MatchingModules =
1977 findMatchingModulesInIndex(RelativePathNative, DirState->second);
1978 if (!MatchingModules.empty())
1980 }
while (CurDir != Root);
1983 Diags.Report(diag::warn_mmap_deprecated_symlink_to_modular_header)
1984 <<
File.getName() << LinkTarget
1985 <<
Module.getModule()->getFullModuleName();
1986 Diags.Report(
Module.getModule()->DefinitionLoc,
1987 diag::note_mmap_module_defined_here);
1990bool HeaderSearch::findUsableModuleForHeader(
1994 if (!HSOpts.LazyLoadModuleMaps) {
2000 ModuleMap::KnownHeader
Module =
2002 diagnoseUncoveredSymlink(
File,
Module, Root);
2008 ModuleMap::KnownHeader
Module =
2016 Module = ModMap.findModuleForHeader(
File,
true);
2018 diagnoseUncoveredSymlink(
File,
Module, Root);
2025bool HeaderSearch::findUsableModuleForFrameworkHeader(
2031 SmallVector<std::string, 4> SubmodulePath;
2034 assert(TopFrameworkDir &&
"Could not find the top-most framework dir");
2037 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
2041 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework,
2048 ModuleMap::KnownHeader
Module =
2059 bool Diagnose =
true) {
2060 StringRef Filename = llvm::sys::path::filename(
File.getName());
2062 if (Filename ==
"module.map")
2063 llvm::sys::path::append(PrivateFilename,
"module_private.map");
2064 else if (Filename ==
"module.modulemap")
2065 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
2067 return std::nullopt;
2068 auto PMMFile =
FileMgr.getOptionalFileRef(PrivateFilename);
2070 if (Diagnose && Filename ==
"module.map")
2071 Diags.
Report(diag::warn_deprecated_module_dot_map)
2072 << PrivateFilename << 1
2073 <<
File.getDir().getName().ends_with(
".framework");
2079 bool ImplicitlyDiscovered,
2080 FileID ID,
unsigned *Offset,
2081 StringRef OriginalModuleMapFile) {
2086 Dir = FileMgr.getOptionalDirectoryRef(
".");
2088 if (!OriginalModuleMapFile.empty()) {
2091 Dir = FileMgr.getOptionalDirectoryRef(
2092 llvm::sys::path::parent_path(OriginalModuleMapFile));
2094 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
2095 Dir = FakeFile.getDir();
2098 Dir =
File.getDir();
2101 assert(Dir &&
"parent must exist");
2102 StringRef DirName(Dir->
getName());
2103 if (llvm::sys::path::filename(DirName) ==
"Modules") {
2104 DirName = llvm::sys::path::parent_path(DirName);
2105 if (DirName.ends_with(
".framework"))
2106 if (
auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
2110 assert(Dir &&
"parent must exist");
2114 assert(Dir &&
"module map home directory must exist");
2115 switch (parseAndLoadModuleMapFileImpl(
File, IsSystem, ImplicitlyDiscovered,
2118 case MMR_AlreadyProcessed:
2119 case MMR_NewlyProcessed:
2121 case MMR_NoDirectory:
2122 case MMR_InvalidModuleMap:
2125 llvm_unreachable(
"Unknown load module map result");
2128HeaderSearch::ModuleMapResult HeaderSearch::parseAndLoadModuleMapFileImpl(
2133 auto AddResult = LoadedModuleMaps.insert(std::make_pair(
File,
true));
2134 if (!AddResult.second)
2135 return AddResult.first->second ? MMR_AlreadyProcessed
2136 : MMR_InvalidModuleMap;
2140 LoadedModuleMaps[
File] =
false;
2141 return MMR_InvalidModuleMap;
2148 ImplicitlyDiscovered, Dir)) {
2149 LoadedModuleMaps[
File] =
false;
2150 return MMR_InvalidModuleMap;
2155 return MMR_NewlyProcessed;
2158HeaderSearch::ModuleMapResult
2160 bool ImplicitlyDiscovered,
2164 auto AddResult = ParsedModuleMaps.insert(std::make_pair(
File,
true));
2165 if (!AddResult.second)
2166 return AddResult.first->second ? MMR_AlreadyProcessed
2167 : MMR_InvalidModuleMap;
2169 if (ModMap.parseModuleMapFile(
File, IsSystem, ImplicitlyDiscovered, Dir,
2171 ParsedModuleMaps[
File] =
false;
2172 return MMR_InvalidModuleMap;
2178 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, ImplicitlyDiscovered,
2180 ParsedModuleMaps[
File] =
false;
2181 return MMR_InvalidModuleMap;
2186 return MMR_NewlyProcessed;
2191 if (!HSOpts.ImplicitModuleMaps)
2192 return std::nullopt;
2197 llvm::sys::path::append(ModuleMapFileName,
"Modules");
2198 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
2199 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2203 ModuleMapFileName = Dir.
getName();
2204 llvm::sys::path::append(ModuleMapFileName,
"module.map");
2205 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
2206 Diags.Report(diag::warn_deprecated_module_dot_map)
2207 << ModuleMapFileName << 0 << IsFramework;
2214 ModuleMapFileName = Dir.
getName();
2215 llvm::sys::path::append(ModuleMapFileName,
"Modules",
2216 "module.private.modulemap");
2217 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2220 return std::nullopt;
2225 bool ImplicitlyDiscovered) {
2229 case MMR_InvalidModuleMap:
2232 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
2235 case MMR_NoDirectory:
2238 case MMR_AlreadyProcessed:
2239 case MMR_NewlyProcessed:
2246HeaderSearch::ModuleMapResult
2248 bool ImplicitlyDiscovered,
2250 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2254 return MMR_NoDirectory;
2257HeaderSearch::ModuleMapResult
2259 bool ImplicitlyDiscovered,
2261 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2262 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2263 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2264 if (!InsertRes.second) {
2265 switch (MMState.Status) {
2266 case ModuleMapDirectoryState::Parsed:
2268 case ModuleMapDirectoryState::Loaded:
2269 return MMR_AlreadyProcessed;
2270 case ModuleMapDirectoryState::Invalid:
2271 return MMR_InvalidModuleMap;
2275 if (!MMState.ModuleMapFile) {
2277 if (MMState.ModuleMapFile)
2278 MMState.PrivateModuleMapFile =
2282 if (MMState.ModuleMapFile) {
2283 ModuleMapResult
Result = parseAndLoadModuleMapFileImpl(
2284 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2288 if (
Result == MMR_NewlyProcessed)
2289 MMState.Status = ModuleMapDirectoryState::Loaded;
2290 else if (
Result == MMR_InvalidModuleMap)
2291 MMState.Status = ModuleMapDirectoryState::Invalid;
2294 return MMR_InvalidModuleMap;
2297HeaderSearch::ModuleMapResult
2298HeaderSearch::parseModuleMapFile(StringRef DirName,
bool IsSystem,
2299 bool ImplicitlyDiscovered,
bool IsFramework) {
2300 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2301 return parseModuleMapFile(*Dir, IsSystem, ImplicitlyDiscovered,
2304 return MMR_NoDirectory;
2307HeaderSearch::ModuleMapResult
2309 bool ImplicitlyDiscovered,
bool IsFramework) {
2310 if (!HSOpts.LazyLoadModuleMaps)
2314 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2315 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2316 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2317 if (!InsertRes.second) {
2318 switch (MMState.Status) {
2319 case ModuleMapDirectoryState::Parsed:
2320 case ModuleMapDirectoryState::Loaded:
2321 return MMR_AlreadyProcessed;
2322 case ModuleMapDirectoryState::Invalid:
2323 return MMR_InvalidModuleMap;
2327 if (!MMState.ModuleMapFile) {
2329 if (MMState.ModuleMapFile)
2330 MMState.PrivateModuleMapFile =
2334 if (MMState.ModuleMapFile) {
2335 ModuleMapResult
Result = parseModuleMapFileImpl(
2336 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2340 if (
Result == MMR_NewlyProcessed)
2341 MMState.Status = ModuleMapDirectoryState::Parsed;
2342 else if (
Result == MMR_InvalidModuleMap)
2343 MMState.Status = ModuleMapDirectoryState::Invalid;
2346 return MMR_InvalidModuleMap;
2352 if (HSOpts.ImplicitModuleMaps) {
2355 bool IsSystem = DL.isSystemHeaderDirectory();
2356 if (DL.isFramework()) {
2359 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
2362 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2363 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
2365 Dir != DirEnd && !EC; Dir.increment(EC)) {
2366 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
2369 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
2374 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2381 if (DL.isHeaderMap())
2391 loadSubdirectoryModuleMaps(DL);
2396 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2400 if (!HSOpts.ImplicitModuleMaps)
2406 if (!DL.isNormalDir())
2411 true, DL.isFramework());
2415void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
2417 "Should not be loading subdirectory module maps");
2424 FileMgr.makeAbsolutePath(Dir);
2426 llvm::sys::path::native(Dir, DirNative);
2427 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
2428 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2429 Dir != DirEnd && !EC; Dir.increment(EC)) {
2430 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2432 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
2445 MainFile, IsAngled);
2449 llvm::StringRef
File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2450 bool *IsAngled)
const {
2451 using namespace llvm::sys;
2454 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2455 path::make_absolute(WorkingDir, FilePath);
2459 path::remove_dots(FilePath,
true);
2460 path::native(FilePath, path::Style::posix);
2463 unsigned BestPrefixLength = 0;
2468 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2469 path::make_absolute(WorkingDir, Dir);
2470 path::remove_dots(Dir,
true);
2471 for (
auto NI = path::begin(
File), NE = path::end(
File),
2472 DI = path::begin(Dir), DE = path::end(Dir);
2473 NI != NE; ++NI, ++DI) {
2476 unsigned PrefixLength = NI - path::begin(
File);
2477 if (PrefixLength > BestPrefixLength) {
2478 BestPrefixLength = PrefixLength;
2485 if (NI->size() == 1 && DI->size() == 1 &&
2486 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2492 if (NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
2493 StringRef NBasename = path::stem(*NI);
2494 StringRef DBasename = path::stem(*DI);
2495 if (DBasename.starts_with(NBasename))
2505 bool BestPrefixIsFramework =
false;
2507 if (DL.isNormalDir()) {
2508 StringRef Dir = DL.getDirRef()->getName();
2509 if (CheckDir(Dir)) {
2511 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2512 BestPrefixIsFramework =
false;
2514 }
else if (DL.isFramework()) {
2515 StringRef Dir = DL.getFrameworkDirRef()->getName();
2516 if (CheckDir(Dir)) {
2519 *IsAngled = BestPrefixLength;
2520 BestPrefixIsFramework =
true;
2527 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2530 BestPrefixIsFramework =
false;
2535 StringRef Filename =
File.drop_front(BestPrefixLength);
2537 if (!DL.isHeaderMap())
2540 StringRef SpelledFilename =
2541 DL.getHeaderMap()->reverseLookupFilename(Filename);
2542 if (!SpelledFilename.empty()) {
2543 Filename = SpelledFilename;
2544 BestPrefixIsFramework =
false;
2551 bool IsPrivateHeader;
2553 if (BestPrefixIsFramework &&
2556 Filename = IncludeSpelling;
2558 return path::convert_to_slash(Filename);
2563 NormalizedPath.assign(Path.begin(), Path.end());
2564 if (!NormalizedPath.empty()) {
2565 FileMgr.makeAbsolutePath(NormalizedPath);
2566 llvm::sys::path::remove_dots(NormalizedPath);
2572 std::string ContextHash,
size_t &NormalizedModuleCachePathLen) {
2575 NormalizedModuleCachePathLen = SpecificModuleCachePath.size();
2576 if (!SpecificModuleCachePath.empty() && !DisableModuleHash)
2577 llvm::sys::path::append(SpecificModuleCachePath, ContextHash);
2578 return std::string(SpecificModuleCachePath);
2582 ContextHash = std::move(NewContextHash);
2584 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash, ContextHash,
2585 NormalizedModuleCachePathLen);
2589 StringRef ModuleCachePath,
2590 bool DisableModuleHash,
2591 std::string ContextHash) {
2592 size_t NormalizedModuleCachePathLen;
2594 FileMgr, ModuleCachePath, DisableModuleHash, std::move(ContextHash),
2595 NormalizedModuleCachePathLen);
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
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.
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.
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.
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.
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).
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.
The JSON file list parser is used to communicate input to InstallAPI.
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