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");
235 return std::string(
Result);
245 StringRef ModuleMapPath =
ModuleMap->getName();
246 StringRef ContextHash = HSOpts.DisableModuleHash ?
"" :
getContextHash();
247 for (
const std::string &Dir : HSOpts.PrebuiltModulePaths) {
249 FileMgr.makeAbsolutePath(CachePath);
250 llvm::sys::path::append(CachePath, ContextHash);
252 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
260 StringRef ModuleMapPath) {
261 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
265std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
266 StringRef ModuleMapPath,
267 StringRef CachePath) {
270 if (CachePath.empty())
276 llvm::sys::path::append(Result, ModuleName +
".pcm");
285 SmallString<128> CanonicalPath(ModuleMapPath);
286 if (
getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
289 auto Hash = llvm::xxh3_64bits(CanonicalPath.str().lower());
291 SmallString<128> HashStr;
292 llvm::APInt(64, Hash).toStringUnsigned(HashStr, 36);
293 llvm::sys::path::append(
Result, ModuleName +
"-" + HashStr +
".pcm");
295 return Result.str().str();
300 bool AllowExtraModuleMapSearch) {
303 if (
Module || !AllowSearch || !HSOpts.ImplicitModuleMaps)
306 StringRef SearchName = ModuleName;
308 AllowExtraModuleMapSearch);
318 if (!
Module && SearchName.consume_back(
"_Private"))
320 AllowExtraModuleMapSearch);
321 if (!
Module && SearchName.consume_back(
"Private"))
323 AllowExtraModuleMapSearch);
329 bool AllowExtraModuleMapSearch) {
335 if (Dir.isFramework()) {
340 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
341 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
342 if (
auto FrameworkDir =
343 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
345 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
354 if (!Dir.isNormalDir())
357 bool IsSystem = Dir.isSystemHeaderDirectory();
360 DirectoryEntryRef NormalDir = *Dir.getDirRef();
362 if (parseModuleMapFile(NormalDir, IsSystem,
363 false) == MMR_NewlyProcessed) {
366 Module = ModMap.findOrLoadModule(ModuleName);
373 SmallString<128> NestedModuleMapDirName;
374 NestedModuleMapDirName = Dir.getDirRef()->getName();
375 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
376 if (parseModuleMapFile(NestedModuleMapDirName, IsSystem,
377 false) == MMR_NewlyProcessed) {
379 Module = ModMap.findOrLoadModule(ModuleName);
384 if (HSOpts.AllowModuleMapSubdirectorySearch) {
387 if (Dir.haveSearchedAllModuleMaps())
392 if (AllowExtraModuleMapSearch)
393 loadSubdirectoryModuleMaps(Dir);
396 Module = ModMap.findOrLoadModule(ModuleName);
405void HeaderSearch::indexInitialHeaderMaps() {
406 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
409 for (
unsigned i = 0; i != SearchDirs.size(); ++i) {
410 auto &Dir = SearchDirs[i];
415 if (!Dir.isHeaderMap()) {
416 SearchDirHeaderMapIndex = std::move(Index);
417 FirstNonHeaderMapSearchDirIdx = i;
422 auto Callback = [&](StringRef Filename) {
423 Index.try_emplace(Filename.lower(), i);
425 Dir.getHeaderMap()->forEachKey(Callback);
440 assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
446 bool IsSystemHeaderDir,
Module *RequestingModule,
448 bool CacheFailures ) {
455 std::error_code EC = llvm::errorToErrorCode(
File.takeError());
456 if (EC != llvm::errc::no_such_file_or_directory &&
457 EC != llvm::errc::invalid_argument &&
458 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
459 Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
466 if (!findUsableModuleForHeader(
467 *
File, Dir ? Dir :
File->getFileEntry().getDir(), RequestingModule,
468 SuggestedModule, IsSystemHeaderDir))
480 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound,
482 bool OpenFile)
const {
483 InUserSpecifiedSystemFramework =
false;
484 IsInHeaderMap =
false;
491 llvm::sys::path::append(TmpDir, Filename);
495 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
498 RelativePath->clear();
499 RelativePath->append(Filename.begin(), Filename.end());
502 return HS.getFileAndSuggestModule(
504 RequestingModule, SuggestedModule, OpenFile);
508 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
509 RequestingModule, SuggestedModule,
510 InUserSpecifiedSystemFramework, IsFrameworkFound);
512 assert(
isHeaderMap() &&
"Unknown directory lookup");
519 IsInHeaderMap =
true;
521 auto FixupSearchPathAndFindUsableModule =
524 StringRef SearchPathRef(
getName());
526 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
529 RelativePath->clear();
530 RelativePath->append(Filename.begin(), Filename.end());
532 if (!HS.findUsableModuleForHeader(
File,
File.getFileEntry().getDir(),
533 RequestingModule, SuggestedModule,
543 if (llvm::sys::path::is_relative(Dest)) {
544 MappedName.append(Dest.begin(), Dest.end());
545 Filename = StringRef(MappedName.begin(), MappedName.size());
550 return FixupSearchPathAndFindUsableModule(*Res);
570 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
571 "Not a framework directory");
587 auto TopFrameworkDir =
FileMgr.getOptionalDirectoryRef(DirName);
590 DirName =
FileMgr.getCanonicalName(*TopFrameworkDir);
593 DirName = llvm::sys::path::parent_path(DirName);
598 auto Dir =
FileMgr.getOptionalDirectoryRef(DirName);
604 if (llvm::sys::path::extension(DirName) ==
".framework") {
605 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
606 TopFrameworkDir = *Dir;
610 return TopFrameworkDir;
614 bool HasSuggestedModule) {
615 return HasSuggestedModule ||
625 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
629 size_t SlashPos = Filename.find(
'/');
630 if (SlashPos == StringRef::npos)
635 FrameworkCacheEntry &CacheEntry =
645 SmallString<1024> FrameworkName;
647 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
648 FrameworkName.push_back(
'/');
651 StringRef ModuleName(Filename.begin(), SlashPos);
652 FrameworkName += ModuleName;
655 FrameworkName +=
".framework/";
659 ++NumFrameworkLookups;
673 SmallString<1024> SystemFrameworkMarker(FrameworkName);
674 SystemFrameworkMarker +=
".system_framework";
685 RelativePath->clear();
686 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
690 unsigned OrigSize = FrameworkName.size();
692 FrameworkName +=
"Headers/";
697 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
700 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
706 const char *
Private =
"Private";
707 FrameworkName.insert(FrameworkName.begin()+OrigSize,
Private,
710 SearchPath->insert(SearchPath->begin()+OrigSize,
Private,
720 StringRef FrameworkPath =
File->getDir().getName();
721 bool FoundFramework =
false;
730 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
731 FoundFramework =
true;
736 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
737 if (FrameworkPath.empty())
742 if (FoundFramework) {
743 if (!HS.findUsableModuleForFrameworkHeader(*
File, FrameworkPath,
745 SuggestedModule, IsSystem))
748 if (!HS.findUsableModuleForHeader(*
File,
getDir(), RequestingModule,
749 SuggestedModule, IsSystem))
758void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
761 CacheLookup.HitIt = HitIt;
762 noteLookupUsage(HitIt.Idx, Loc);
765void HeaderSearch::noteLookupUsage(
unsigned HitIdx,
SourceLocation Loc) {
766 SearchDirsUsage[HitIdx] =
true;
768 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
769 if (UserEntryIdxIt != SearchDirToHSEntry.end())
770 Diags.Report(Loc, diag::remark_pp_search_path_usage)
771 << HSOpts.UserEntries[UserEntryIdxIt->second].Path;
789 if (MSFE && FE != *MSFE) {
790 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
796static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
797 assert(!Str.empty());
798 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
799 std::copy(Str.begin(), Str.end(), CopyStr);
800 CopyStr[Str.size()] =
'\0';
807 using namespace llvm::sys;
808 path::const_iterator I = path::begin(Path);
809 path::const_iterator E = path::end(Path);
810 IsPrivateHeader =
false;
822 if (*I ==
"Headers") {
824 }
else if (*I ==
"PrivateHeaders") {
826 IsPrivateHeader =
true;
827 }
else if (I->ends_with(
".framework")) {
828 StringRef Name = I->drop_back(10);
830 FrameworkName.clear();
831 FrameworkName.append(Name.begin(), Name.end());
832 IncludeSpelling.clear();
833 IncludeSpelling.append(Name.begin(), Name.end());
835 }
else if (FoundComp >= 2) {
836 IncludeSpelling.push_back(
'/');
837 IncludeSpelling.append(I->begin(), I->end());
842 return !FrameworkName.empty() && FoundComp >= 2;
847 StringRef Includer, StringRef IncludeFilename,
849 bool FoundByHeaderMap =
false) {
850 bool IsIncluderPrivateHeader =
false;
854 FromIncludeSpelling))
856 bool IsIncludeePrivateHeader =
false;
857 bool IsIncludeeInFramework =
859 ToFramework, ToIncludeSpelling);
861 if (!isAngled && !FoundByHeaderMap) {
863 if (IsIncludeeInFramework) {
864 NewInclude += ToIncludeSpelling;
867 NewInclude += IncludeFilename;
870 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
878 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
879 IsIncludeePrivateHeader && FromFramework == ToFramework)
880 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
887 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
888 bool isAngled,
int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt) {
890 if (Diags.isIgnored(diag::warn_header_shadowing, IncludeLoc) ||
894 if (MainLoopIt && MainLoopIt->isSystemHeaderDirectory())
897 DiagnosedShadowing =
true;
901 for (
size_t i = IncluderLoopIndex + 1; i < Includers.size(); ++i) {
902 const auto &IncluderAndDir = Includers[i];
904 llvm::sys::path::append(TmpDir, Filename);
906 if (&
File->getFileEntry() == *FE)
908 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
909 << Filename << (*FE).getDir().getName()
910 << IncluderAndDir.second.getName();
913 llvm::errorToErrorCode(
File.takeError());
919 ConstSearchDirIterator It =
922 It = std::next(MainLoopIt);
923 }
else if (FromDir) {
931 llvm::sys::path::append(TmpPath, Filename);
933 if (&
File->getFileEntry() == *FE)
935 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
936 << Filename << (*FE).getDir().getName() << It->getName();
939 llvm::errorToErrorCode(
File.takeError());
951 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
952 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
955 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
956 bool BuildSystemModule,
bool OpenFile,
bool CacheFailures) {
957 ConstSearchDirIterator CurDirLocal =
nullptr;
958 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
963 if (IsFrameworkFound)
964 *IsFrameworkFound =
false;
970 if (llvm::sys::path::is_absolute(Filename)) {
980 RelativePath->clear();
981 RelativePath->append(Filename.begin(), Filename.end());
984 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
986 RequestingModule, SuggestedModule, OpenFile,
993 bool DiagnosedShadowing =
false;
1000 if (!Includers.empty() && !isAngled) {
1003 for (
const auto &IncluderAndDir : Includers) {
1007 TmpDir = IncluderAndDir.second.getName();
1008 llvm::sys::path::append(TmpDir, Filename);
1017 bool IncluderIsSystemHeader = [&]() {
1019 return BuildSystemModule;
1021 assert(HFI &&
"includer without file info");
1025 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
1026 RequestingModule, SuggestedModule)) {
1028 FromDir, Includers, isAngled,
1029 &IncluderAndDir - Includers.begin(),
nullptr);
1031 assert(
First &&
"only first includer can have no file");
1042 assert(FromHFI &&
"includer without file info");
1043 unsigned DirInfo = FromHFI->
DirInfo;
1049 StringRef SearchPathRef(IncluderAndDir.second.getName());
1050 SearchPath->clear();
1051 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
1054 RelativePath->clear();
1055 RelativePath->append(Filename.begin(), Filename.end());
1059 IncluderAndDir.second.getName(), Filename,
1067 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1071 if (SuggestedModule) {
1072 MSSuggestedModule = *SuggestedModule;
1085 ConstSearchDirIterator It =
1097 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1099 ConstSearchDirIterator NextIt = std::next(It);
1102 if (CacheLookup.StartIt == NextIt &&
1103 CacheLookup.RequestingModule == RequestingModule) {
1105 if (CacheLookup.HitIt)
1106 It = CacheLookup.HitIt;
1107 if (CacheLookup.MappedName) {
1108 Filename = CacheLookup.MappedName;
1116 CacheLookup.reset(RequestingModule, NextIt);
1122 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1123 if (Iter == SearchDirHeaderMapIndex.end())
1132 CacheLookup.reset(RequestingModule, NextIt);
1139 bool InUserSpecifiedSystemFramework =
false;
1140 bool IsInHeaderMap =
false;
1141 bool IsFrameworkFoundInDir =
false;
1143 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1144 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1145 IsInHeaderMap, MappedName, OpenFile);
1146 if (!MappedName.empty()) {
1147 assert(IsInHeaderMap &&
"MappedName should come from a header map");
1148 CacheLookup.MappedName =
1149 copyString(MappedName, LookupFileCache.getAllocator());
1155 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap &&
File));
1156 if (IsFrameworkFound)
1160 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1165 FromDir, Includers, isAngled, -1, It);
1169 IncludeNames[*
File] = Filename;
1173 HFI.
DirInfo = CurDir->getDirCharacteristic();
1183 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1184 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1192 if (SuggestedModule)
1193 *SuggestedModule = MSSuggestedModule;
1197 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
1198 if (!Includers.empty())
1200 Includers.front().second.getName(), Filename,
1201 *
File, isAngled, FoundByHeaderMap);
1204 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1209 if (SuggestedModule)
1210 *SuggestedModule = MSSuggestedModule;
1216 return std::nullopt;
1230 size_t SlashPos = Filename.find(
'/');
1231 if (SlashPos == StringRef::npos)
1232 return std::nullopt;
1235 StringRef ContextName = ContextFileEnt.
getName();
1238 const unsigned DotFrameworkLen = 10;
1239 auto FrameworkPos = ContextName.find(
".framework");
1240 if (FrameworkPos == StringRef::npos ||
1241 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
1242 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1243 return std::nullopt;
1247 DotFrameworkLen + 1);
1250 FrameworkName +=
"Frameworks/";
1251 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1252 FrameworkName +=
".framework/";
1255 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1259 if (CacheLookup.second.Directory &&
1260 CacheLookup.first().size() == FrameworkName.size() &&
1261 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1262 CacheLookup.first().size()) != 0)
1263 return std::nullopt;
1266 if (!CacheLookup.second.Directory) {
1267 ++NumSubFrameworkLookups;
1270 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1272 return std::nullopt;
1276 CacheLookup.second.Directory = Dir;
1281 RelativePath->clear();
1282 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1287 HeadersFilename +=
"Headers/";
1289 SearchPath->clear();
1291 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1294 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1295 auto File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1298 HeadersFilename = FrameworkName;
1299 HeadersFilename +=
"PrivateHeaders/";
1301 SearchPath->clear();
1303 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1306 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1307 File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1310 return std::nullopt;
1315 assert(ContextHFI &&
"context file without file info");
1318 unsigned DirInfo = ContextHFI->
DirInfo;
1321 FrameworkName.pop_back();
1322 if (!findUsableModuleForFrameworkHeader(*
File, FrameworkName,
1323 RequestingModule, SuggestedModule,
1325 return std::nullopt;
1344 bool isModuleHeader,
1345 bool isTextualModuleHeader) {
1362 assert(OtherHFI.
External &&
"expected to merge external HFI");
1378 if (FE.
getUID() >= FileInfo.size())
1379 FileInfo.resize(FE.
getUID() + 1);
1383 if (ExternalSource && !HFI->
Resolved) {
1384 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1385 if (ExternalHFI.IsValid) {
1387 if (ExternalHFI.External)
1401 if (ExternalSource) {
1402 if (FE.
getUID() >= FileInfo.size())
1403 FileInfo.resize(FE.
getUID() + 1);
1405 HFI = &FileInfo[FE.
getUID()];
1408 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1409 if (ExternalHFI.IsValid) {
1411 if (ExternalHFI.External)
1415 }
else if (FE.
getUID() < FileInfo.size()) {
1416 HFI = &FileInfo[FE.
getUID()];
1421 return (HFI && HFI->
IsValid) ? HFI :
nullptr;
1427 if (FE.
getUID() < FileInfo.size()) {
1428 HFI = &FileInfo[FE.
getUID()];
1441 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1447 bool isCompilingModuleHeader) {
1449 if (!isCompilingModuleHeader) {
1458 HFI.mergeModuleMembership(
Role);
1459 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1464 bool ModulesEnabled,
Module *M,
1465 bool &IsFirstIncludeOfFile) {
1481 IsFirstIncludeOfFile =
false;
1484 auto MaybeReenterImportedFile = [&]() ->
bool {
1502 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1506 ModMap.resolveHeaderDirectives(
File);
1526 if (FileInfo.isTextualModuleHeader)
1529 if (FileInfo.isCompilingModuleHeader) {
1532 if (FileInfo.isModuleHeader) {
1537 if (ModMap.isBuiltinHeader(
File))
1546 if (FileInfo.getControllingMacro(ExternalLookup))
1566 FileInfo.isImport =
true;
1573 if (FileInfo.isPragmaOnce ||
1574 (FileInfo.isImport && !MaybeReenterImportedFile()))
1583 FileInfo.getControllingMacro(ExternalLookup)) {
1590 ++NumMultiIncludeFileOptzn;
1600 return SearchDirs.capacity()
1601 + llvm::capacity_in_bytes(FileInfo)
1602 + llvm::capacity_in_bytes(HeaderMaps)
1603 + LookupFileCache.getAllocator().getTotalMemory()
1604 + FrameworkMap.getAllocator().getTotalMemory();
1608 return &DL - &*SearchDirs.begin();
1612 return FrameworkNames.insert(Framework).first->first();
1616 auto It = IncludeNames.find(
File);
1617 if (It == IncludeNames.end())
1623 ModuleMapDirectoryState &MMState) {
1624 if (!MMState.ModuleMapFile)
1631 if (MMState.PrivateModuleMapFile)
1634 processModuleMapForIndex(*ParsedMM, Dir,
"", MMState);
1635 if (ParsedPrivateMM)
1636 processModuleMapForIndex(*ParsedPrivateMM, Dir,
"", MMState);
1639void HeaderSearch::addToModuleMapIndex(StringRef RelPath, StringRef ModuleName,
1640 StringRef PathPrefix,
1641 ModuleMapDirectoryState &MMState) {
1643 llvm::sys::path::append(RelFromRootPath, RelPath);
1644 llvm::sys::path::native(RelFromRootPath);
1645 MMState.HeaderToModules[RelFromRootPath].push_back(ModuleName);
1648void HeaderSearch::processExternModuleDeclForIndex(
1650 StringRef PathPrefix, ModuleMapDirectoryState &MMState) {
1651 StringRef FileNameRef = EMD.
Path;
1652 SmallString<128> ModuleMapFileName;
1653 if (llvm::sys::path::is_relative(FileNameRef)) {
1654 ModuleMapFileName = MMDir.
getName();
1655 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1656 FileNameRef = ModuleMapFileName;
1658 if (
auto EFile = FileMgr.getOptionalFileRef(FileNameRef)) {
1659 if (
auto *ExtMMF = ModMap.getParsedModuleMap(*EFile)) {
1662 SmallString<128> NewPrefix(PathPrefix);
1663 StringRef ExternDir = llvm::sys::path::parent_path(EMD.
Path);
1664 if (!ExternDir.empty()) {
1665 llvm::sys::path::append(NewPrefix, ExternDir);
1666 llvm::sys::path::native(NewPrefix);
1668 processModuleMapForIndex(*ExtMMF, EFile->getDir(), NewPrefix, MMState);
1674 StringRef ModuleName,
1676 StringRef PathPrefix,
1677 ModuleMapDirectoryState &MMState) {
1679 if (MD.
Id.front().first ==
"*")
1682 auto ProcessDecl = llvm::makeVisitor(
1683 [&](
const modulemap::HeaderDecl &HD) {
1685 MMState.UmbrellaHeaderModules.push_back(ModuleName);
1687 addToModuleMapIndex(HD.
Path, ModuleName, PathPrefix, MMState);
1690 [&](
const modulemap::UmbrellaDirDecl &UDD) {
1691 SmallString<128> FullPath(PathPrefix);
1692 llvm::sys::path::append(FullPath, UDD.Path);
1693 llvm::sys::path::native(FullPath);
1694 MMState.UmbrellaDirModules.push_back(
1695 std::make_pair(std::string(FullPath), ModuleName));
1697 [&](
const modulemap::ModuleDecl &SubMD) {
1698 processModuleDeclForIndex(SubMD, ModuleName, MMDir, PathPrefix,
1701 [&](
const modulemap::ExternModuleDecl &EMD) {
1702 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix, MMState);
1708 for (
const auto &Decl : MD.
Decls) {
1709 std::visit(ProcessDecl, Decl);
1715 StringRef PathPrefix,
1716 ModuleMapDirectoryState &MMState) {
1717 for (
const auto &Decl : MMF.
Decls) {
1718 std::visit(llvm::makeVisitor(
1719 [&](
const modulemap::ModuleDecl &MD) {
1720 processModuleDeclForIndex(MD, MD.
Id.front().first, MMDir,
1721 PathPrefix, MMState);
1723 [&](
const modulemap::ExternModuleDecl &EMD) {
1724 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix,
1734 if (!HSOpts.ImplicitModuleMaps)
1741 DirName = llvm::sys::path::parent_path(DirName);
1742 if (DirName.empty())
1746 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1752 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1756 parseModuleMapFile(*Dir, IsSystem, IsFramework);
1757 auto DirState = DirectoryModuleMap.find(*Dir);
1758 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1761 if (!HSOpts.LazyLoadModuleMaps)
1764 auto &MMState = DirState->second;
1767 if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() &&
1768 MMState.UmbrellaHeaderModules.empty()) {
1769 buildModuleMapIndex(*Dir, MMState);
1775 StringRef RelativePath =
FileName.substr(DirName.size());
1777 while (!RelativePath.empty() &&
1778 llvm::sys::path::is_separator(RelativePath.front()))
1779 RelativePath = RelativePath.substr(1);
1781 llvm::sys::path::native(RelativePathNative);
1782 RelativePath = RelativePathNative;
1786 auto CachedMods = MMState.HeaderToModules.find(RelativePath);
1787 if (CachedMods != MMState.HeaderToModules.end()) {
1788 ModulesToLoad.append(CachedMods->second.begin(),
1789 CachedMods->second.end());
1793 for (
const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
1794 if (RelativePath.starts_with(UmbrellaDir.first) ||
1795 UmbrellaDir.first ==
".") {
1796 ModulesToLoad.push_back(UmbrellaDir.second);
1811 ModulesToLoad.append(MMState.UmbrellaHeaderModules.begin(),
1812 MMState.UmbrellaHeaderModules.end());
1815 bool LoadedAny =
false;
1816 for (StringRef ModName : ModulesToLoad) {
1817 if (ModMap.findOrLoadModule(ModName)) {
1826 }
while (CurDir != Root);
1832 bool AllowExcluded)
const {
1833 if (ExternalSource) {
1838 return ModMap.findModuleForHeader(
File, AllowTextual, AllowExcluded);
1843 if (ExternalSource) {
1848 return ModMap.findAllModulesForHeader(
File);
1853 if (ExternalSource) {
1858 return ModMap.findResolvedModulesForHeader(
File);
1875 if (SuggestedModule)
1885 if (SuggestedModule)
1893bool HeaderSearch::findUsableModuleForHeader(
1897 if (!HSOpts.LazyLoadModuleMaps) {
1903 ModuleMap::KnownHeader
Module =
1910 ModuleMap::KnownHeader
Module =
1918 Module = ModMap.findModuleForHeader(
File,
true);
1927bool HeaderSearch::findUsableModuleForFrameworkHeader(
1933 SmallVector<std::string, 4> SubmodulePath;
1936 assert(TopFrameworkDir &&
"Could not find the top-most framework dir");
1939 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1943 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1949 ModuleMap::KnownHeader
Module =
1960 bool Diagnose =
true) {
1961 StringRef Filename = llvm::sys::path::filename(
File.getName());
1963 if (Filename ==
"module.map")
1964 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1965 else if (Filename ==
"module.modulemap")
1966 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1968 return std::nullopt;
1969 auto PMMFile =
FileMgr.getOptionalFileRef(PrivateFilename);
1971 if (Diagnose && Filename ==
"module.map")
1972 Diags.
Report(diag::warn_deprecated_module_dot_map)
1973 << PrivateFilename << 1
1974 <<
File.getDir().getName().ends_with(
".framework");
1980 FileID ID,
unsigned *Offset,
1981 StringRef OriginalModuleMapFile) {
1986 Dir = FileMgr.getOptionalDirectoryRef(
".");
1988 if (!OriginalModuleMapFile.empty()) {
1991 Dir = FileMgr.getOptionalDirectoryRef(
1992 llvm::sys::path::parent_path(OriginalModuleMapFile));
1994 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1995 Dir = FakeFile.getDir();
1998 Dir =
File.getDir();
2001 assert(Dir &&
"parent must exist");
2002 StringRef DirName(Dir->
getName());
2003 if (llvm::sys::path::filename(DirName) ==
"Modules") {
2004 DirName = llvm::sys::path::parent_path(DirName);
2005 if (DirName.ends_with(
".framework"))
2006 if (
auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
2010 assert(Dir &&
"parent must exist");
2014 assert(Dir &&
"module map home directory must exist");
2015 switch (parseAndLoadModuleMapFileImpl(
File, IsSystem, *Dir, ID, Offset,
2017 case MMR_AlreadyProcessed:
2018 case MMR_NewlyProcessed:
2020 case MMR_NoDirectory:
2021 case MMR_InvalidModuleMap:
2024 llvm_unreachable(
"Unknown load module map result");
2027HeaderSearch::ModuleMapResult HeaderSearch::parseAndLoadModuleMapFileImpl(
2029 unsigned *Offset,
bool DiagnosePrivMMap) {
2032 auto AddResult = LoadedModuleMaps.insert(std::make_pair(
File,
true));
2033 if (!AddResult.second)
2034 return AddResult.first->second ? MMR_AlreadyProcessed
2035 : MMR_InvalidModuleMap;
2038 LoadedModuleMaps[
File] =
false;
2039 return MMR_InvalidModuleMap;
2046 LoadedModuleMaps[
File] =
false;
2047 return MMR_InvalidModuleMap;
2052 return MMR_NewlyProcessed;
2055HeaderSearch::ModuleMapResult
2060 auto AddResult = ParsedModuleMaps.insert(std::make_pair(
File,
true));
2061 if (!AddResult.second)
2062 return AddResult.first->second ? MMR_AlreadyProcessed
2063 : MMR_InvalidModuleMap;
2065 if (ModMap.parseModuleMapFile(
File, IsSystem, Dir, ID)) {
2066 ParsedModuleMaps[
File] =
false;
2067 return MMR_InvalidModuleMap;
2073 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, Dir)) {
2074 ParsedModuleMaps[
File] =
false;
2075 return MMR_InvalidModuleMap;
2080 return MMR_NewlyProcessed;
2085 if (!HSOpts.ImplicitModuleMaps)
2086 return std::nullopt;
2091 llvm::sys::path::append(ModuleMapFileName,
"Modules");
2092 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
2093 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2097 ModuleMapFileName = Dir.
getName();
2098 llvm::sys::path::append(ModuleMapFileName,
"module.map");
2099 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
2100 Diags.Report(diag::warn_deprecated_module_dot_map)
2101 << ModuleMapFileName << 0 << IsFramework;
2108 ModuleMapFileName = Dir.
getName();
2109 llvm::sys::path::append(ModuleMapFileName,
"Modules",
2110 "module.private.modulemap");
2111 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2114 return std::nullopt;
2121 case MMR_InvalidModuleMap:
2124 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
2127 case MMR_NoDirectory:
2130 case MMR_AlreadyProcessed:
2131 case MMR_NewlyProcessed:
2138HeaderSearch::ModuleMapResult
2141 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2144 return MMR_NoDirectory;
2147HeaderSearch::ModuleMapResult
2150 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2151 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2152 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2153 if (!InsertRes.second) {
2154 switch (MMState.Status) {
2155 case ModuleMapDirectoryState::Parsed:
2157 case ModuleMapDirectoryState::Loaded:
2158 return MMR_AlreadyProcessed;
2159 case ModuleMapDirectoryState::Invalid:
2160 return MMR_InvalidModuleMap;
2164 if (!MMState.ModuleMapFile) {
2166 if (MMState.ModuleMapFile)
2167 MMState.PrivateModuleMapFile =
2171 if (MMState.ModuleMapFile) {
2173 parseAndLoadModuleMapFileImpl(*MMState.ModuleMapFile, IsSystem, Dir);
2177 if (
Result == MMR_NewlyProcessed)
2178 MMState.Status = ModuleMapDirectoryState::Loaded;
2179 else if (
Result == MMR_InvalidModuleMap)
2180 MMState.Status = ModuleMapDirectoryState::Invalid;
2183 return MMR_InvalidModuleMap;
2186HeaderSearch::ModuleMapResult
2187HeaderSearch::parseModuleMapFile(StringRef DirName,
bool IsSystem,
2189 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2190 return parseModuleMapFile(*Dir, IsSystem, IsFramework);
2192 return MMR_NoDirectory;
2195HeaderSearch::ModuleMapResult
2198 if (!HSOpts.LazyLoadModuleMaps)
2201 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2202 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2203 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2204 if (!InsertRes.second) {
2205 switch (MMState.Status) {
2206 case ModuleMapDirectoryState::Parsed:
2207 case ModuleMapDirectoryState::Loaded:
2208 return MMR_AlreadyProcessed;
2209 case ModuleMapDirectoryState::Invalid:
2210 return MMR_InvalidModuleMap;
2214 if (!MMState.ModuleMapFile) {
2216 if (MMState.ModuleMapFile)
2217 MMState.PrivateModuleMapFile =
2221 if (MMState.ModuleMapFile) {
2223 parseModuleMapFileImpl(*MMState.ModuleMapFile, IsSystem, Dir);
2227 if (
Result == MMR_NewlyProcessed)
2228 MMState.Status = ModuleMapDirectoryState::Parsed;
2229 else if (
Result == MMR_InvalidModuleMap)
2230 MMState.Status = ModuleMapDirectoryState::Invalid;
2233 return MMR_InvalidModuleMap;
2239 if (HSOpts.ImplicitModuleMaps) {
2242 bool IsSystem = DL.isSystemHeaderDirectory();
2243 if (DL.isFramework()) {
2246 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
2249 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2250 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
2252 Dir != DirEnd && !EC; Dir.increment(EC)) {
2253 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
2256 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
2261 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2268 if (DL.isHeaderMap())
2277 loadSubdirectoryModuleMaps(DL);
2282 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2286 if (!HSOpts.ImplicitModuleMaps)
2292 if (!DL.isNormalDir())
2301void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
2303 "Should not be loading subdirectory module maps");
2310 FileMgr.makeAbsolutePath(Dir);
2312 llvm::sys::path::native(Dir, DirNative);
2313 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
2314 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2315 Dir != DirEnd && !EC; Dir.increment(EC)) {
2316 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2318 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
2331 MainFile, IsAngled);
2335 llvm::StringRef
File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2336 bool *IsAngled)
const {
2337 using namespace llvm::sys;
2340 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2341 path::make_absolute(WorkingDir, FilePath);
2345 path::remove_dots(FilePath,
true);
2346 path::native(FilePath, path::Style::posix);
2349 unsigned BestPrefixLength = 0;
2354 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2355 path::make_absolute(WorkingDir, Dir);
2356 path::remove_dots(Dir,
true);
2357 for (
auto NI = path::begin(
File), NE = path::end(
File),
2358 DI = path::begin(Dir), DE = path::end(Dir);
2359 NI != NE; ++NI, ++DI) {
2362 unsigned PrefixLength = NI - path::begin(
File);
2363 if (PrefixLength > BestPrefixLength) {
2364 BestPrefixLength = PrefixLength;
2371 if (NI->size() == 1 && DI->size() == 1 &&
2372 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2378 if (NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
2379 StringRef NBasename = path::stem(*NI);
2380 StringRef DBasename = path::stem(*DI);
2381 if (DBasename.starts_with(NBasename))
2391 bool BestPrefixIsFramework =
false;
2393 if (DL.isNormalDir()) {
2394 StringRef Dir = DL.getDirRef()->getName();
2395 if (CheckDir(Dir)) {
2397 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2398 BestPrefixIsFramework =
false;
2400 }
else if (DL.isFramework()) {
2401 StringRef Dir = DL.getFrameworkDirRef()->getName();
2402 if (CheckDir(Dir)) {
2405 *IsAngled = BestPrefixLength;
2406 BestPrefixIsFramework =
true;
2413 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2416 BestPrefixIsFramework =
false;
2421 StringRef Filename =
File.drop_front(BestPrefixLength);
2423 if (!DL.isHeaderMap())
2426 StringRef SpelledFilename =
2427 DL.getHeaderMap()->reverseLookupFilename(Filename);
2428 if (!SpelledFilename.empty()) {
2429 Filename = SpelledFilename;
2430 BestPrefixIsFramework =
false;
2437 bool IsPrivateHeader;
2439 if (BestPrefixIsFramework &&
2442 Filename = IncludeSpelling;
2444 return path::convert_to_slash(Filename);
2449 NormalizedPath.assign(Path.begin(), Path.end());
2450 if (!NormalizedPath.empty()) {
2451 FileMgr.makeAbsolutePath(NormalizedPath);
2452 llvm::sys::path::remove_dots(NormalizedPath);
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)
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.
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
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.
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