;
51#define DEBUG_TYPE "file-search" 55NumMultiIncludeFileOptzn,
56 "Number of #includes skipped due to the multi-include optimization.");
59 "Number of subframework lookups.");
73 if(ControllingMacro && ControllingMacro->
isOutOfDate()) {
74assert(
External&&
"We must have an external source if we have a " 75 "controlling macro that is out of date.");
76 External->updateOutOfDateIdentifier(*ControllingMacro);
78 returnControllingMacro;
87: HSOpts(
std::move(HSOpts)), Diags(Diags),
88FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
89ModMap(SourceMgr, Diags, LangOpts,
Target, *this) {}
92llvm::errs() <<
"\n*** HeaderSearch Stats:\n" 93<< FileInfo.size() <<
" files tracked.\n";
94 unsignedNumOnceOnlyFiles = 0;
95 for(
unsignedi = 0, e = FileInfo.size(); i != e; ++i)
96NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
97llvm::errs() <<
" "<< NumOnceOnlyFiles <<
" #import/#pragma once files.\n";
99llvm::errs() <<
" "<< NumIncluded <<
" #include/#include_next/#import.\n" 100<<
" "<< NumMultiIncludeFileOptzn
101<<
" #includes skipped due to the multi-include optimization.\n";
103llvm::errs() << NumFrameworkLookups <<
" framework lookups.\n" 104<< NumSubFrameworkLookups <<
" subframework lookups.\n";
108std::vector<DirectoryLookup> dirs,
unsigned intangledDirIdx,
109 unsigned intsystemDirIdx,
110llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
111assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
112 "Directory indices are unordered");
113SearchDirs = std::move(dirs);
114SearchDirsUsage.assign(SearchDirs.size(),
false);
115AngledDirIdx = angledDirIdx;
116SystemDirIdx = systemDirIdx;
117SearchDirToHSEntry = std::move(searchDirToHSEntry);
119indexInitialHeaderMaps();
123 unsignedidx = isAngled ? SystemDirIdx : AngledDirIdx;
124SearchDirs.insert(SearchDirs.begin() + idx, dir);
125SearchDirsUsage.insert(SearchDirsUsage.begin() + idx,
false);
132std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size());
133 for(
unsignedI = 0,
E= SearchDirsUsage.size(); I <
E; ++I) {
135 if(SearchDirsUsage[I]) {
136 autoUserEntryIdxIt = SearchDirToHSEntry.find(I);
138 if(UserEntryIdxIt != SearchDirToHSEntry.end())
139UserEntryUsage[UserEntryIdxIt->second] =
true;
142 returnUserEntryUsage;
146std::vector<bool> VFSUsage;
153RootFS.visit([&](llvm::vfs::FileSystem &FS) {
154 if(
auto*RFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&FS)) {
155VFSUsage.push_back(RFS->hasBeenUsed());
156RFS->clearHasBeenUsed();
160 "A different number of RedirectingFileSystem's were present than " 161 "-ivfsoverlay options passed to Clang!");
163std::reverse(VFSUsage.begin(), VFSUsage.end());
172 if(!HeaderMaps.empty()) {
173 for(
unsignedi = 0, e = HeaderMaps.size(); i != e; ++i)
176 if(HeaderMaps[i].first == FE)
177 returnHeaderMaps[i].second.get();
181HeaderMaps.emplace_back(FE, std::move(HM));
182 returnHeaderMaps.back().second.get();
191 for(
auto&HM : HeaderMaps)
192Names.push_back(std::string(HM.first.getName()));
208 autoi(HSOpts->PrebuiltModuleFiles.find(ModuleName));
209 if(i != HSOpts->PrebuiltModuleFiles.end())
212 if(FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
217 for(
conststd::string &Dir : HSOpts->PrebuiltModulePaths) {
219llvm::sys::fs::make_absolute(
Result);
220 if(ModuleName.contains(
':'))
224llvm::sys::path::append(
Result, ModuleName.split(
':').first +
"-"+
225ModuleName.split(
':').second +
228llvm::sys::path::append(
Result, ModuleName +
".pcm");
230 returnstd::string(
Result);
240StringRef ModuleMapPath =
ModuleMap->getName();
241StringRef ModuleCacheHash = HSOpts->DisableModuleHash ?
"":
getModuleHash();
242 for(
conststd::string &Dir : HSOpts->PrebuiltModulePaths) {
244llvm::sys::fs::make_absolute(CachePath);
245llvm::sys::path::append(CachePath, ModuleCacheHash);
247getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
255StringRef ModuleMapPath) {
256 returngetCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
260std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
261StringRef ModuleMapPath,
262StringRef CachePath) {
265 if(CachePath.empty())
270 if(HSOpts->DisableModuleHash) {
271llvm::sys::path::append(
Result, ModuleName +
".pcm");
281 if(
getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
284 autoHash = llvm::xxh3_64bits(CanonicalPath.str().lower());
287llvm::APInt(64, Hash).toStringUnsigned(HashStr,
36);
288llvm::sys::path::append(
Result, ModuleName +
"-"+ HashStr +
".pcm");
290 return Result.str().str();
295 boolAllowExtraModuleMapSearch) {
298 if(
Module|| !AllowSearch || !HSOpts->ImplicitModuleMaps)
301StringRef SearchName = ModuleName;
303AllowExtraModuleMapSearch);
313 if(!
Module&& SearchName.consume_back(
"_Private"))
315AllowExtraModuleMapSearch);
316 if(!
Module&& SearchName.consume_back(
"Private"))
318AllowExtraModuleMapSearch);
324 boolAllowExtraModuleMapSearch) {
330 if(Dir.isFramework()) {
335FrameworkDirName += Dir.getFrameworkDirRef()->getName();
336llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
337 if(
autoFrameworkDir =
340 Module= loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
349 if(!Dir.isNormalDir())
352 boolIsSystem = Dir.isSystemHeaderDirectory();
358 false) == LMM_NewlyLoaded) {
369NestedModuleMapDirName = Dir.getDirRef()->getName();
370llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
372 false) == LMM_NewlyLoaded){
379 if(HSOpts->AllowModuleMapSubdirectorySearch) {
382 if(Dir.haveSearchedAllModuleMaps())
387 if(AllowExtraModuleMapSearch)
388loadSubdirectoryModuleMaps(Dir);
400voidHeaderSearch::indexInitialHeaderMaps() {
401llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
404 for(
unsignedi = 0; i != SearchDirs.size(); ++i) {
405 auto&Dir = SearchDirs[i];
410 if(!Dir.isHeaderMap()) {
411SearchDirHeaderMapIndex = std::move(Index);
412FirstNonHeaderMapSearchDirIdx = i;
417 autoCallback = [&](StringRef
Filename) {
418Index.try_emplace(
Filename.lower(), i);
420Dir.getHeaderMap()->forEachKey(Callback);
435assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
441 boolIsSystemHeaderDir,
Module*RequestingModule,
443 boolCacheFailures
) {
450std::error_code EC = llvm::errorToErrorCode(
File.takeError());
451 if(EC != llvm::errc::no_such_file_or_directory &&
452EC != llvm::errc::invalid_argument &&
453EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
454Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
461 if(!findUsableModuleForHeader(
462*
File, Dir ? Dir :
File->getFileEntry().getDir(), RequestingModule,
463SuggestedModule, IsSystemHeaderDir))
475 bool&InUserSpecifiedSystemFramework,
bool&IsFrameworkFound,
477 boolOpenFile)
const{
478InUserSpecifiedSystemFramework =
false;
479IsInHeaderMap =
false;
486llvm::sys::path::append(TmpDir,
Filename);
490SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
493RelativePath->clear();
497 returnHS.getFileAndSuggestModule(
499RequestingModule, SuggestedModule, OpenFile);
503 returnDoFrameworkLookup(
Filename, HS, SearchPath, RelativePath,
504RequestingModule, SuggestedModule,
505InUserSpecifiedSystemFramework, IsFrameworkFound);
507assert(
isHeaderMap() &&
"Unknown directory lookup");
514IsInHeaderMap =
true;
516 autoFixupSearchPathAndFindUsableModule =
519StringRef SearchPathRef(
getName());
521SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
524RelativePath->clear();
527 if(!HS.findUsableModuleForHeader(
File,
File.getFileEntry().getDir(),
528RequestingModule, SuggestedModule,
538 if(llvm::sys::path::is_relative(Dest)) {
539MappedName.append(Dest.begin(), Dest.end());
540 Filename= StringRef(MappedName.begin(), MappedName.size());
545 returnFixupSearchPathAndFindUsableModule(*Res);
552HS.noteLookupUsage(HS.
searchDirIdx(*
this), IncludeLoc);
565assert(llvm::sys::path::extension(DirName) ==
".framework"&&
566 "Not a framework directory");
588DirName = llvm::sys::path::parent_path(DirName);
599 if(llvm::sys::path::extension(DirName) ==
".framework") {
600SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
601TopFrameworkDir = *Dir;
605 returnTopFrameworkDir;
609 boolHasSuggestedModule) {
610 returnHasSuggestedModule ||
620 bool&InUserSpecifiedSystemFramework,
bool&IsFrameworkFound)
const{
624 size_tSlashPos =
Filename.find(
'/');
625 if(SlashPos == StringRef::npos)
642 if(FrameworkName.empty() || FrameworkName.back() !=
'/')
643FrameworkName.push_back(
'/');
646StringRef ModuleName(
Filename.begin(), SlashPos);
647FrameworkName += ModuleName;
650FrameworkName +=
".framework/";
654++NumFrameworkLookups;
669SystemFrameworkMarker +=
".system_framework";
670 if(llvm::sys::fs::exists(SystemFrameworkMarker)) {
681RelativePath->clear();
686 unsignedOrigSize = FrameworkName.size();
688FrameworkName +=
"Headers/";
693SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
702 const char*
Private=
"Private";
703FrameworkName.insert(FrameworkName.begin()+OrigSize,
Private,
706SearchPath->insert(SearchPath->begin()+OrigSize,
Private,
716StringRef FrameworkPath =
File->getDir().getName();
717 boolFoundFramework =
false;
726 if(llvm::sys::path::extension(FrameworkPath) ==
".framework") {
727FoundFramework =
true;
732FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
733 if(FrameworkPath.empty())
738 if(FoundFramework) {
739 if(!HS.findUsableModuleForFrameworkHeader(*
File, FrameworkPath,
741SuggestedModule, IsSystem))
744 if(!HS.findUsableModuleForHeader(*
File,
getDir(), RequestingModule,
745SuggestedModule, IsSystem))
754voidHeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
757CacheLookup.HitIt = HitIt;
758noteLookupUsage(HitIt.Idx,
Loc);
762SearchDirsUsage[HitIdx] =
true;
764 autoUserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
765 if(UserEntryIdxIt != SearchDirToHSEntry.end())
766Diags.
Report(
Loc, diag::remark_pp_search_path_usage)
767<< HSOpts->UserEntries[UserEntryIdxIt->second].Path;
785 if(MSFE && FE != *MSFE) {
786Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
792static const char*
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
793assert(!Str.empty());
794 char*CopyStr = Alloc.Allocate<
char>(Str.size()+1);
795std::copy(Str.begin(), Str.end(), CopyStr);
796CopyStr[Str.size()] =
'\0';
803 using namespacellvm::sys;
804path::const_iterator I = path::begin(
Path);
805path::const_iterator
E= path::end(
Path);
806IsPrivateHeader =
false;
818 if(*I ==
"Headers") {
820}
else if(*I ==
"PrivateHeaders") {
822IsPrivateHeader =
true;
823}
else if(I->ends_with(
".framework")) {
824StringRef Name = I->drop_back(10);
826FrameworkName.clear();
827FrameworkName.append(Name.begin(), Name.end());
828IncludeSpelling.clear();
829IncludeSpelling.append(Name.begin(), Name.end());
831}
else if(FoundComp >= 2) {
832IncludeSpelling.push_back(
'/');
833IncludeSpelling.append(I->begin(), I->end());
838 return!FrameworkName.empty() && FoundComp >= 2;
843StringRef Includer, StringRef IncludeFilename,
845 boolFoundByHeaderMap =
false) {
846 boolIsIncluderPrivateHeader =
false;
850FromIncludeSpelling))
852 boolIsIncludeePrivateHeader =
false;
853 boolIsIncludeeInFramework =
855ToFramework, ToIncludeSpelling);
857 if(!isAngled && !FoundByHeaderMap) {
859 if(IsIncludeeInFramework) {
860NewInclude += ToIncludeSpelling;
863NewInclude += IncludeFilename;
866Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
874 if(!IsIncluderPrivateHeader && IsIncludeeInFramework &&
875IsIncludeePrivateHeader && FromFramework == ToFramework)
876Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
888 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
891 bool*IsMapped,
bool*IsFrameworkFound,
boolSkipCache,
892 boolBuildSystemModule,
boolOpenFile,
boolCacheFailures) {
899 if(IsFrameworkFound)
900*IsFrameworkFound =
false;
906 if(llvm::sys::path::is_absolute(
Filename)) {
916RelativePath->clear();
920 returngetFileAndSuggestModule(
Filename, IncludeLoc,
nullptr,
922RequestingModule, SuggestedModule, OpenFile,
935 if(!Includers.empty() && !isAngled) {
938 for(
const auto&IncluderAndDir : Includers) {
942TmpDir = IncluderAndDir.second.getName();
943llvm::sys::path::append(TmpDir,
Filename);
952 boolIncluderIsSystemHeader = [&]() {
954 returnBuildSystemModule;
956assert(HFI &&
"includer without file info");
960TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
961RequestingModule, SuggestedModule)) {
963assert(
First&&
"only first includer can have no file");
974assert(FromHFI &&
"includer without file info");
975 unsignedDirInfo = FromHFI->
DirInfo;
981StringRef SearchPathRef(IncluderAndDir.second.getName());
983SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
986RelativePath->clear();
991IncluderAndDir.second.getName(),
Filename,
999 if(Diags.
isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1003 if(SuggestedModule) {
1004MSSuggestedModule = *SuggestedModule;
1029LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
1034 if(CacheLookup.StartIt == NextIt &&
1035CacheLookup.RequestingModule == RequestingModule) {
1037 if(CacheLookup.HitIt)
1038It = CacheLookup.HitIt;
1039 if(CacheLookup.MappedName) {
1048CacheLookup.reset(RequestingModule,
NextIt);
1054 auto Iter= SearchDirHeaderMapIndex.find(
Filename.lower());
1055 if(
Iter== SearchDirHeaderMapIndex.end())
1064CacheLookup.reset(RequestingModule,
NextIt);
1071 boolInUserSpecifiedSystemFramework =
false;
1072 boolIsInHeaderMap =
false;
1073 boolIsFrameworkFoundInDir =
false;
1075 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1076SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1077IsInHeaderMap, MappedName, OpenFile);
1078 if(!MappedName.empty()) {
1079assert(IsInHeaderMap &&
"MappedName should come from a header map");
1080CacheLookup.MappedName =
1081 copyString(MappedName, LookupFileCache.getAllocator());
1087*IsMapped |= (!MappedName.empty() || (IsInHeaderMap &&
File));
1088 if(IsFrameworkFound)
1092*IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1102HFI.
DirInfo= CurDir->getDirCharacteristic();
1112 for(
unsignedj = SystemHeaderPrefixes.size(); j; --j) {
1113 if(
Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1121 if(SuggestedModule)
1122*SuggestedModule = MSSuggestedModule;
1126 boolFoundByHeaderMap = !IsMapped ?
false: *IsMapped;
1127 if(!Includers.empty())
1129Includers.front().second.getName(),
Filename,
1130*
File, isAngled, FoundByHeaderMap);
1133cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1138 if(SuggestedModule)
1139*SuggestedModule = MSSuggestedModule;
1145 returnstd::nullopt;
1159 size_tSlashPos =
Filename.find(
'/');
1160 if(SlashPos == StringRef::npos)
1161 returnstd::nullopt;
1164StringRef ContextName = ContextFileEnt.
getName();
1167 const unsignedDotFrameworkLen = 10;
1168 autoFrameworkPos = ContextName.find(
".framework");
1169 if(FrameworkPos == StringRef::npos ||
1170(ContextName[FrameworkPos + DotFrameworkLen] !=
'/'&&
1171ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1172 returnstd::nullopt;
1176DotFrameworkLen + 1);
1179FrameworkName +=
"Frameworks/";
1181FrameworkName +=
".framework/";
1184*FrameworkMap.insert(std::make_pair(
Filename.substr(0, SlashPos),
1188 if(CacheLookup.second.Directory &&
1189CacheLookup.first().size() == FrameworkName.size() &&
1190memcmp(CacheLookup.first().data(), &FrameworkName[0],
1191CacheLookup.first().size()) != 0)
1192 returnstd::nullopt;
1195 if(!CacheLookup.second.Directory) {
1196++NumSubFrameworkLookups;
1201 returnstd::nullopt;
1205CacheLookup.second.Directory = Dir;
1210RelativePath->clear();
1216HeadersFilename +=
"Headers/";
1218SearchPath->clear();
1220SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1227HeadersFilename = FrameworkName;
1228HeadersFilename +=
"PrivateHeaders/";
1230SearchPath->clear();
1232SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1239 returnstd::nullopt;
1244assert(ContextHFI &&
"context file without file info");
1247 unsignedDirInfo = ContextHFI->
DirInfo;
1250FrameworkName.pop_back();
1251 if(!findUsableModuleForFrameworkHeader(*
File, FrameworkName,
1252RequestingModule, SuggestedModule,
1254 returnstd::nullopt;
1273 boolisModuleHeader,
1274 boolisTextualModuleHeader) {
1291assert(OtherHFI.
External&&
"expected to merge external HFI");
1307 if(FE.
getUID() >= FileInfo.size())
1308FileInfo.resize(FE.
getUID() + 1);
1314 if(ExternalHFI.IsValid) {
1316 if(ExternalHFI.External)
1331 if(FE.
getUID() >= FileInfo.size())
1332FileInfo.resize(FE.
getUID() + 1);
1334HFI = &FileInfo[FE.
getUID()];
1338 if(ExternalHFI.IsValid) {
1340 if(ExternalHFI.External)
1344}
else if(FE.
getUID() < FileInfo.size()) {
1345HFI = &FileInfo[FE.
getUID()];
1350 return(HFI && HFI->
IsValid) ? HFI :
nullptr;
1356 if(FE.
getUID() < FileInfo.size()) {
1357HFI = &FileInfo[FE.
getUID()];
1370 returnHFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1376 boolisCompilingModuleHeader) {
1378 if(!isCompilingModuleHeader) {
1387HFI.mergeModuleMembership(Role);
1388HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1393 boolModulesEnabled,
Module*M,
1394 bool&IsFirstIncludeOfFile) {
1410IsFirstIncludeOfFile =
false;
1413 autoMaybeReenterImportedFile = [&]() ->
bool{
1503(FileInfo.
isImport&& !MaybeReenterImportedFile()))
1519++NumMultiIncludeFileOptzn;
1529 returnSearchDirs.capacity()
1530+ llvm::capacity_in_bytes(FileInfo)
1531+ llvm::capacity_in_bytes(HeaderMaps)
1532+ LookupFileCache.getAllocator().getTotalMemory()
1533+ FrameworkMap.getAllocator().getTotalMemory();
1537 return&DL - &*SearchDirs.begin();
1541 returnFrameworkNames.insert(Framework).first->first();
1545 autoIt = IncludeNames.find(
File);
1546 if(It == IncludeNames.end())
1554 if(!HSOpts->ImplicitModuleMaps)
1562DirName = llvm::sys::path::parent_path(DirName);
1563 if(DirName.empty())
1573llvm::sys::path::extension(Dir->getName()) ==
1575 caseLMM_NewlyLoaded:
1576 caseLMM_AlreadyLoaded:
1579 for(
unsignedI = 0, N = FixUpDirectories.size(); I != N; ++I)
1580DirectoryHasModuleMap[FixUpDirectories[I]] =
true;
1583 caseLMM_NoDirectory:
1584 caseLMM_InvalidModuleMap:
1594FixUpDirectories.push_back(*Dir);
1600 boolAllowExcluded)
const{
1630 Module*RequestingModule,
1646 if(SuggestedModule)
1656 if(SuggestedModule)
1664boolHeaderSearch::findUsableModuleForHeader(
1675boolHeaderSearch::findUsableModuleForFrameworkHeader(
1684assert(TopFrameworkDir &&
"Could not find the top-most framework dir");
1687StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1691loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1705StringRef
Filename= llvm::sys::path::filename(
File.getName());
1708llvm::sys::path::append(PrivateFilename,
"module_private.map");
1709 else if(
Filename==
"module.modulemap")
1710llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1712 returnstd::nullopt;
1716Diags.
Report(diag::warn_deprecated_module_dot_map)
1717<< PrivateFilename << 1
1718<<
File.getDir().getName().ends_with(
".framework");
1724 FileIDID,
unsigned*Offset,
1725StringRef OriginalModuleMapFile) {
1732 if(!OriginalModuleMapFile.empty()) {
1736llvm::sys::path::parent_path(OriginalModuleMapFile));
1739Dir = FakeFile.getDir();
1742Dir =
File.getDir();
1745assert(Dir &&
"parent must exist");
1746StringRef DirName(Dir->
getName());
1747 if(llvm::sys::path::filename(DirName) ==
"Modules") {
1748DirName = llvm::sys::path::parent_path(DirName);
1749 if(DirName.ends_with(
".framework"))
1754assert(Dir &&
"parent must exist");
1758assert(Dir &&
"module map home directory must exist");
1759 switch(loadModuleMapFileImpl(
File, IsSystem, *Dir, ID, Offset)) {
1760 caseLMM_AlreadyLoaded:
1761 caseLMM_NewlyLoaded:
1763 caseLMM_NoDirectory:
1764 caseLMM_InvalidModuleMap:
1767llvm_unreachable(
"Unknown load module map result");
1770HeaderSearch::LoadModuleMapResult
1776 autoAddResult = LoadedModuleMaps.insert(std::make_pair(
File,
true));
1777 if(!AddResult.second)
1778 returnAddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1781LoadedModuleMaps[
File] =
false;
1782 returnLMM_InvalidModuleMap;
1789LoadedModuleMaps[
File] =
false;
1790 returnLMM_InvalidModuleMap;
1795 returnLMM_NewlyLoaded;
1800 if(!HSOpts->ImplicitModuleMaps)
1801 returnstd::nullopt;
1806llvm::sys::path::append(ModuleMapFileName,
"Modules");
1807llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1812ModuleMapFileName = Dir.
getName();
1813llvm::sys::path::append(ModuleMapFileName,
"module.map");
1815Diags.
Report(diag::warn_deprecated_module_dot_map)
1816<< ModuleMapFileName << 0 << IsFramework;
1823ModuleMapFileName = Dir.
getName();
1824llvm::sys::path::append(ModuleMapFileName,
"Modules",
1825 "module.private.modulemap");
1829 returnstd::nullopt;
1836 caseLMM_InvalidModuleMap:
1838 if(HSOpts->ImplicitModuleMaps)
1839ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1842 caseLMM_NoDirectory:
1845 caseLMM_AlreadyLoaded:
1846 caseLMM_NewlyLoaded:
1853HeaderSearch::LoadModuleMapResult
1859 returnLMM_NoDirectory;
1862HeaderSearch::LoadModuleMapResult
1865 autoKnownDir = DirectoryHasModuleMap.find(Dir);
1866 if(KnownDir != DirectoryHasModuleMap.end())
1867 returnKnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1871LoadModuleMapResult
Result=
1872loadModuleMapFileImpl(*ModuleMapFile, IsSystem, Dir);
1876 if(
Result== LMM_NewlyLoaded)
1877DirectoryHasModuleMap[Dir] =
true;
1878 else if(
Result== LMM_InvalidModuleMap)
1879DirectoryHasModuleMap[Dir] =
false;
1882 returnLMM_InvalidModuleMap;
1888 if(HSOpts->ImplicitModuleMaps) {
1891 boolIsSystem = DL.isSystemHeaderDirectory();
1892 if(DL.isFramework()) {
1895llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
1899 for(llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1901Dir != DirEnd && !EC; Dir.increment(EC)) {
1902 if(llvm::sys::path::extension(Dir->path()) !=
".framework")
1910loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1917 if(DL.isHeaderMap())
1925loadSubdirectoryModuleMaps(DL);
1930llvm::transform(ModMap.
modules(), std::back_inserter(Modules),
1931[](
const auto&NameAndMod) { return NameAndMod.second; });
1935 if(!HSOpts->ImplicitModuleMaps)
1941 if(!DL.isNormalDir())
1950voidHeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup&SearchDir) {
1951assert(HSOpts->ImplicitModuleMaps &&
1952 "Should not be loading subdirectory module maps");
1961llvm::sys::path::native(Dir, DirNative);
1963 for(llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1964Dir != DirEnd && !EC; Dir.increment(EC)) {
1965 if(Dir->type() == llvm::sys::fs::file_type::regular_file)
1967 boolIsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
1979MainFile, IsAngled);
1983llvm::StringRef
File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1984 bool*IsAngled)
const{
1985 using namespacellvm::sys;
1988 if(!WorkingDir.empty() && !path::is_absolute(FilePath))
1989fs::make_absolute(WorkingDir, FilePath);
1993path::remove_dots(FilePath,
true);
1994path::native(FilePath, path::Style::posix);
1997 unsignedBestPrefixLength = 0;
2002 if(!WorkingDir.empty() && !path::is_absolute(Dir))
2003fs::make_absolute(WorkingDir, Dir);
2004path::remove_dots(Dir,
true);
2005 for(
autoNI = path::begin(
File), NE = path::end(
File),
2006DI = path::begin(Dir), DE = path::end(Dir);
2007NI != NE; ++NI, ++DI) {
2010 unsignedPrefixLength = NI - path::begin(
File);
2011 if(PrefixLength > BestPrefixLength) {
2012BestPrefixLength = PrefixLength;
2019 if(NI->size() == 1 && DI->size() == 1 &&
2020path::is_separator(NI->front()) && path::is_separator(DI->front()))
2026 if(NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
2027StringRef NBasename = path::stem(*NI);
2028StringRef DBasename = path::stem(*DI);
2029 if(DBasename.starts_with(NBasename))
2039 boolBestPrefixIsFramework =
false;
2041 if(DL.isNormalDir()) {
2042StringRef Dir = DL.getDirRef()->getName();
2043 if(CheckDir(Dir)) {
2045*IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2046BestPrefixIsFramework =
false;
2048}
else if(DL.isFramework()) {
2049StringRef Dir = DL.getFrameworkDirRef()->getName();
2050 if(CheckDir(Dir)) {
2053*IsAngled = BestPrefixLength;
2054BestPrefixIsFramework =
true;
2061 if(!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2064BestPrefixIsFramework =
false;
2069StringRef
Filename=
File.drop_front(BestPrefixLength);
2071 if(!DL.isHeaderMap())
2074StringRef SpelledFilename =
2075DL.getHeaderMap()->reverseLookupFilename(
Filename);
2076 if(!SpelledFilename.empty()) {
2078BestPrefixIsFramework =
false;
2085 boolIsPrivateHeader;
2087 if(BestPrefixIsFramework &&
2092 returnpath::convert_to_slash(
Filename);
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
llvm::MachO::Target Target
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.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
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.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified directory (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.
IdentifierInfo * getPtr() const
bool isID() const
Whether this pointer is currently stored as ID.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
void setTarget(const TargetInfo &Target)
Set the target information.
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.
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
llvm::iterator_range< module_iterator > modules() const
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.
The JSON file list parser is used to communicate input to InstallAPI.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Result
The result type of a method or function.
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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4