26 #include "llvm/ADT/APInt.h" 27 #include "llvm/ADT/Hashing.h" 28 #include "llvm/ADT/SmallString.h" 29 #include "llvm/ADT/SmallVector.h" 30 #include "llvm/ADT/Statistic.h" 31 #include "llvm/ADT/StringRef.h" 32 #include "llvm/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" 45 #include <system_error> 48 using namespace clang;
50 #define DEBUG_TYPE "file-search" 54 NumMultiIncludeFileOptzn,
55 "Number of #includes skipped due to the multi-include optimization.");
58 "Number of subframework lookups.");
64 assert(External &&
"We must have an external source if we have a " 65 "controlling macro that is out of date.");
85 : HSOpts(
std::move(HSOpts)), Diags(Diags),
86 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
87 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
90 llvm::errs() <<
"\n*** HeaderSearch Stats:\n" 91 << FileInfo.size() <<
" files tracked.\n";
92 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
93 for (
unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
94 NumOnceOnlyFiles += FileInfo[i].isImport;
95 if (MaxNumIncludes < FileInfo[i].NumIncludes)
96 MaxNumIncludes = FileInfo[i].NumIncludes;
97 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
99 llvm::errs() <<
" " << NumOnceOnlyFiles <<
" #import/#pragma once files.\n" 100 <<
" " << NumSingleIncludedFiles <<
" included exactly once.\n" 101 <<
" " << MaxNumIncludes <<
" max times a file is included.\n";
103 llvm::errs() <<
" " << NumIncluded <<
" #include/#include_next/#import.\n" 104 <<
" " << NumMultiIncludeFileOptzn
105 <<
" #includes skipped due to the multi-include optimization.\n";
107 llvm::errs() << NumFrameworkLookups <<
" framework lookups.\n" 108 << NumSubFrameworkLookups <<
" subframework lookups.\n";
116 if (!HeaderMaps.empty()) {
117 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
120 if (HeaderMaps[i].first == FE)
121 return HeaderMaps[i].second.get();
125 HeaderMaps.emplace_back(FE, std::move(HM));
126 return HeaderMaps.back().second.get();
135 for (
auto &HM : HeaderMaps)
136 Names.push_back(HM.first->getName());
148 auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
149 if (i != HSOpts->PrebuiltModuleFiles.end())
152 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
157 for (
const std::string &Dir : HSOpts->PrebuiltModulePaths) {
159 llvm::sys::fs::make_absolute(Result);
160 llvm::sys::path::append(Result, ModuleName +
".pcm");
162 return Result.str().str();
168 StringRef ModuleMapPath) {
175 llvm::sys::fs::make_absolute(Result);
177 if (HSOpts->DisableModuleHash) {
178 llvm::sys::path::append(Result, ModuleName +
".pcm");
187 std::string
Parent = llvm::sys::path::parent_path(ModuleMapPath);
194 auto FileName = llvm::sys::path::filename(ModuleMapPath);
196 llvm::hash_code Hash =
200 llvm::APInt(64,
size_t(Hash)).toStringUnsigned(HashStr, 36);
201 llvm::sys::path::append(Result, ModuleName +
"-" + HashStr +
".pcm");
203 return Result.str().str();
207 bool AllowExtraModuleMapSearch) {
210 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
213 StringRef SearchName = ModuleName;
214 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
224 if (!Module && SearchName.consume_back(
"_Private"))
225 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
226 if (!Module && SearchName.consume_back(
"Private"))
227 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
232 bool AllowExtraModuleMapSearch) {
237 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
238 if (SearchDirs[Idx].isFramework()) {
243 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
244 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
245 if (
auto FrameworkDir = FileMgr.
getDirectory(FrameworkDirName)) {
248 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
257 if (!SearchDirs[Idx].isNormalDir())
260 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
263 false) == LMM_NewlyLoaded) {
274 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
275 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
277 false) == LMM_NewlyLoaded){
286 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
291 if (AllowExtraModuleMapSearch)
292 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
312 return getDir()->getName();
314 return getFrameworkDir()->getName();
315 assert(isHeaderMap() &&
"Unknown DirectoryLookup");
316 return getHeaderMap()->getFileName();
321 bool IsSystemHeaderDir,
Module *RequestingModule,
329 std::error_code EC = llvm::errorToErrorCode(File.takeError());
330 if (EC != llvm::errc::no_such_file_or_directory &&
331 EC != llvm::errc::invalid_argument &&
332 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
333 Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
334 << FileName << EC.message();
340 if (!findUsableModuleForHeader(
341 &File->getFileEntry(), Dir ? Dir : File->getFileEntry().getDir(),
342 RequestingModule, SuggestedModule, IsSystemHeaderDir))
354 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound,
356 InUserSpecifiedSystemFramework =
false;
357 IsInHeaderMap =
false;
363 TmpDir = getDir()->getName();
364 llvm::sys::path::append(TmpDir, Filename);
366 StringRef SearchPathRef(getDir()->
getName());
368 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
371 RelativePath->clear();
372 RelativePath->append(Filename.begin(), Filename.end());
375 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
376 isSystemHeaderDirectory(),
377 RequestingModule, SuggestedModule);
381 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
382 RequestingModule, SuggestedModule,
383 InUserSpecifiedSystemFramework, IsFrameworkFound);
385 assert(isHeaderMap() &&
"Unknown directory lookup");
392 IsInHeaderMap =
true;
394 auto FixupSearchPath = [&]() {
396 StringRef SearchPathRef(
getName());
398 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
401 RelativePath->clear();
402 RelativePath->append(Filename.begin(), Filename.end());
409 if (llvm::sys::path::is_relative(Dest)) {
410 MappedName.append(Dest.begin(), Dest.end());
411 Filename = StringRef(MappedName.begin(), MappedName.size());
434 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
435 "Not a framework directory");
452 if (
auto TopFrameworkDirOrErr = FileMgr.
getDirectory(DirName))
453 TopFrameworkDir = *TopFrameworkDirOrErr;
459 DirName = llvm::sys::path::parent_path(DirName);
470 if (llvm::sys::path::extension(DirName) ==
".framework") {
471 SubmodulePath.push_back(llvm::sys::path::stem(DirName));
472 TopFrameworkDir = *Dir;
476 return TopFrameworkDir;
480 bool HasSuggestedModule) {
481 return HasSuggestedModule ||
491 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
495 size_t SlashPos =
Filename.find(
'/');
496 if (SlashPos == StringRef::npos)
512 FrameworkName += getFrameworkDirRef()->getName();
513 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
514 FrameworkName.push_back(
'/');
517 StringRef ModuleName(
Filename.begin(), SlashPos);
518 FrameworkName += ModuleName;
521 FrameworkName +=
".framework/";
525 ++NumFrameworkLookups;
534 CacheEntry.
Directory = getFrameworkDir();
540 SystemFrameworkMarker +=
".system_framework";
541 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
552 RelativePath->clear();
557 unsigned OrigSize = FrameworkName.size();
559 FrameworkName +=
"Headers/";
564 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
573 const char *Private =
"Private";
574 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
575 Private+strlen(Private));
577 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
578 Private+strlen(Private));
587 StringRef FrameworkPath = File->getFileEntry().getDir()->getName();
588 bool FoundFramework =
false;
597 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
598 FoundFramework =
true;
603 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
604 if (FrameworkPath.empty())
609 if (FoundFramework) {
610 if (!HS.findUsableModuleForFrameworkHeader(
611 &File->getFileEntry(), FrameworkPath, RequestingModule,
612 SuggestedModule, IsSystem))
615 if (!HS.findUsableModuleForHeader(&File->getFileEntry(), getDir(),
616 RequestingModule, SuggestedModule,
640 if (MSFE && FE != MSFE) {
641 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
647 static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
648 assert(!Str.empty());
649 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
650 std::copy(Str.begin(), Str.end(), CopyStr);
651 CopyStr[Str.size()] =
'\0';
658 path::const_iterator I = path::begin(Path);
659 path::const_iterator E = path::end(Path);
660 IsPrivateHeader =
false;
674 if (I->endswith(
".framework")) {
675 FrameworkName.append(I->begin(), I->end());
678 if (*I ==
"PrivateHeaders") {
680 IsPrivateHeader =
true;
685 return !FrameworkName.empty() && FoundComp >= 2;
690 StringRef Includer, StringRef IncludeFilename,
691 const FileEntry *IncludeFE,
bool isAngled =
false,
692 bool FoundByHeaderMap =
false) {
693 bool IsIncluderPrivateHeader =
false;
697 bool IsIncludeePrivateHeader =
false;
699 IncludeFE->
getName(), IsIncludeePrivateHeader, ToFramework);
701 if (!isAngled && !FoundByHeaderMap) {
703 if (IsIncludeeInFramework) {
704 NewInclude += StringRef(ToFramework).drop_back(10);
707 NewInclude += IncludeFilename;
709 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
717 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
718 IsIncludeePrivateHeader && FromFramework == ToFramework)
719 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
731 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
734 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
735 bool BuildSystemModule) {
739 if (IsFrameworkFound)
740 *IsFrameworkFound =
false;
746 if (llvm::sys::path::is_absolute(Filename)) {
756 RelativePath->clear();
757 RelativePath->append(Filename.begin(), Filename.end());
760 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
762 RequestingModule, SuggestedModule);
775 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
778 for (
const auto &IncluderAndDir : Includers) {
779 const FileEntry *Includer = IncluderAndDir.first;
783 TmpDir = IncluderAndDir.second->getName();
784 TmpDir.push_back(
'/');
785 TmpDir.append(Filename.begin(), Filename.end());
794 bool IncluderIsSystemHeader =
798 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
799 RequestingModule, SuggestedModule)) {
801 assert(First &&
"only first includer can have no file");
812 unsigned DirInfo = FromHFI.
DirInfo;
822 StringRef SearchPathRef(IncluderAndDir.second->getName());
824 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
827 RelativePath->clear();
828 RelativePath->append(Filename.begin(), Filename.end());
832 IncluderAndDir.second->getName(),
Filename,
833 &FE->getFileEntry());
840 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
843 MSFE_FE = &FE->getFileEntry();
845 if (SuggestedModule) {
846 MSSuggestedModule = *SuggestedModule;
862 unsigned i = isAngled ? AngledDirIdx : 0;
867 i = FromDir-&SearchDirs[0];
873 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
878 if (!SkipCache && CacheLookup.StartIdx == i+1) {
880 i = CacheLookup.HitIdx;
881 if (CacheLookup.MappedName) {
882 Filename = CacheLookup.MappedName;
890 CacheLookup.reset(i+1);
896 for (; i != SearchDirs.size(); ++i) {
897 bool InUserSpecifiedSystemFramework =
false;
898 bool IsInHeaderMap =
false;
899 bool IsFrameworkFoundInDir =
false;
901 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
902 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
903 IsInHeaderMap, MappedName);
904 if (!MappedName.empty()) {
905 assert(IsInHeaderMap &&
"MappedName should come from a header map");
906 CacheLookup.MappedName =
907 copyString(MappedName, LookupFileCache.getAllocator());
913 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap && File));
914 if (IsFrameworkFound)
918 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
922 CurDir = &SearchDirs[i];
936 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
937 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
947 size_t SlashPos = Filename.find(
'/');
948 if (SlashPos != StringRef::npos) {
956 &File->getFileEntry(), IncludeLoc)) {
958 *SuggestedModule = MSSuggestedModule;
962 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
963 if (!Includers.empty())
965 Diags, IncludeLoc, Includers.front().second->getName(),
Filename,
966 &File->getFileEntry(), isAngled, FoundByHeaderMap);
969 CacheLookup.HitIdx = i;
977 if (!Includers.empty() && Includers.front().first && !isAngled &&
978 Filename.find(
'/') == StringRef::npos) {
982 ScratchFilename += IncludingHFI.
Framework;
983 ScratchFilename +=
'/';
987 ScratchFilename, IncludeLoc,
true, FromDir, CurDir,
988 Includers.front(), SearchPath, RelativePath, RequestingModule,
989 SuggestedModule, IsMapped,
nullptr);
992 File ? &File->getFileEntry() :
nullptr,
995 *SuggestedModule = MSSuggestedModule;
999 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
1000 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
1007 nullptr, IncludeLoc)) {
1008 if (SuggestedModule)
1009 *SuggestedModule = MSSuggestedModule;
1014 CacheLookup.HitIdx = SearchDirs.size();
1027 assert(ContextFileEnt &&
"No context file?");
1031 size_t SlashPos = Filename.find(
'/');
1032 if (SlashPos == StringRef::npos)
1036 StringRef ContextName = ContextFileEnt->
getName();
1039 const unsigned DotFrameworkLen = 10;
1040 auto FrameworkPos = ContextName.find(
".framework");
1041 if (FrameworkPos == StringRef::npos ||
1042 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
1043 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1048 DotFrameworkLen + 1);
1051 FrameworkName +=
"Frameworks/";
1052 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1053 FrameworkName +=
".framework/";
1056 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1060 if (CacheLookup.second.Directory &&
1061 CacheLookup.first().size() == FrameworkName.size() &&
1062 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1063 CacheLookup.first().size()) != 0)
1067 if (!CacheLookup.second.Directory) {
1068 ++NumSubFrameworkLookups;
1071 auto Dir = FileMgr.getDirectory(FrameworkName);
1077 CacheLookup.second.Directory = *Dir;
1082 RelativePath->clear();
1083 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1088 HeadersFilename +=
"Headers/";
1090 SearchPath->clear();
1092 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1095 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1096 auto File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1099 HeadersFilename = FrameworkName;
1100 HeadersFilename +=
"PrivateHeaders/";
1102 SearchPath->clear();
1104 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1107 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1108 File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1120 getFileInfo(&File->getFileEntry()).DirInfo = DirInfo;
1122 FrameworkName.pop_back();
1123 if (!findUsableModuleForFrameworkHeader(&File->getFileEntry(), FrameworkName,
1124 RequestingModule, SuggestedModule,
1139 assert(OtherHFI.
External &&
"expected to merge external HFI");
1163 if (FE->
getUID() >= FileInfo.size())
1164 FileInfo.resize(FE->
getUID() + 1);
1168 if (ExternalSource && !HFI->
Resolved) {
1170 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1172 HFI = &FileInfo[FE->
getUID()];
1173 if (ExternalHFI.External)
1186 bool WantExternal)
const {
1190 if (ExternalSource) {
1191 if (FE->
getUID() >= FileInfo.size()) {
1194 FileInfo.resize(FE->
getUID() + 1);
1197 HFI = &FileInfo[FE->
getUID()];
1202 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1204 HFI = &FileInfo[FE->
getUID()];
1205 if (ExternalHFI.External)
1208 }
else if (FE->
getUID() >= FileInfo.size()) {
1211 HFI = &FileInfo[FE->
getUID()];
1223 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1224 HFI->ControllingMacroID;
1230 bool isCompilingModuleHeader) {
1234 if (!isCompilingModuleHeader) {
1235 if (!isModularHeader)
1238 if (HFI && HFI->isModuleHeader)
1243 HFI.isModuleHeader |= isModularHeader;
1244 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1249 bool ModulesEnabled,
Module *M) {
1257 auto TryEnterImported = [&]() ->
bool {
1258 if (!ModulesEnabled)
1261 ModMap.resolveHeaderDirectives(File);
1279 bool TryEnterHdr =
false;
1281 TryEnterHdr = File->
getDir() == ModMap.getBuiltinDir() &&
1283 llvm::sys::path::filename(File->
getName()));
1307 if (FileInfo.
isImport && !TryEnterImported())
1320 ++NumMultiIncludeFileOptzn;
1332 return SearchDirs.capacity()
1333 + llvm::capacity_in_bytes(FileInfo)
1334 + llvm::capacity_in_bytes(HeaderMaps)
1335 + LookupFileCache.getAllocator().getTotalMemory()
1336 + FrameworkMap.getAllocator().getTotalMemory();
1340 return FrameworkNames.insert(Framework).first->first();
1346 if (!HSOpts->ImplicitModuleMaps)
1351 StringRef DirName = FileName;
1354 DirName = llvm::sys::path::parent_path(DirName);
1355 if (DirName.empty())
1359 auto Dir = FileMgr.getDirectory(DirName);
1365 llvm::sys::path::extension((*Dir)->getName()) ==
1367 case LMM_NewlyLoaded:
1368 case LMM_AlreadyLoaded:
1371 for (
unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1372 DirectoryHasModuleMap[FixUpDirectories[I]] =
true;
1375 case LMM_NoDirectory:
1376 case LMM_InvalidModuleMap:
1386 FixUpDirectories.push_back(*Dir);
1392 bool AllowTextual)
const {
1393 if (ExternalSource) {
1398 return ModMap.findModuleForHeader(File, AllowTextual);
1402 Module *RequestingModule,
1406 if (SuggestedModule)
1423 bool HeaderSearch::findUsableModuleForHeader(
1429 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1434 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1435 const FileEntry *File, StringRef FrameworkName,
Module *RequestingModule,
1445 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1449 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1455 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1464 if (Filename ==
"module.map")
1465 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1466 else if (Filename ==
"module.modulemap")
1467 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1470 if (
auto File = FileMgr.
getFile(PrivateFilename))
1477 StringRef OriginalModuleMapFile) {
1482 if (
auto DirOrErr = FileMgr.getDirectory(
"."))
1485 if (!OriginalModuleMapFile.empty()) {
1488 auto DirOrErr = FileMgr.getDirectory(
1489 llvm::sys::path::parent_path(OriginalModuleMapFile));
1493 auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
1494 Dir = FakeFile->getDir();
1500 StringRef DirName(Dir->
getName());
1501 if (llvm::sys::path::filename(DirName) ==
"Modules") {
1502 DirName = llvm::sys::path::parent_path(DirName);
1503 if (DirName.endswith(
".framework"))
1504 if (
auto DirOrErr = FileMgr.getDirectory(DirName))
1508 assert(Dir &&
"parent must exist");
1512 switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1513 case LMM_AlreadyLoaded:
1514 case LMM_NewlyLoaded:
1516 case LMM_NoDirectory:
1517 case LMM_InvalidModuleMap:
1520 llvm_unreachable(
"Unknown load module map result");
1523 HeaderSearch::LoadModuleMapResult
1524 HeaderSearch::loadModuleMapFileImpl(
const FileEntry *File,
bool IsSystem,
1527 assert(File &&
"expected FileEntry");
1531 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File,
true));
1532 if (!AddResult.second)
1533 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1535 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1536 LoadedModuleMaps[File] =
false;
1537 return LMM_InvalidModuleMap;
1542 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1543 LoadedModuleMaps[File] =
false;
1544 return LMM_InvalidModuleMap;
1549 return LMM_NewlyLoaded;
1554 if (!HSOpts->ImplicitModuleMaps)
1560 llvm::sys::path::append(ModuleMapFileName,
"Modules");
1561 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1562 if (
auto F = FileMgr.getFile(ModuleMapFileName))
1566 ModuleMapFileName = Dir->
getName();
1567 llvm::sys::path::append(ModuleMapFileName,
"module.map");
1568 if (
auto F = FileMgr.getFile(ModuleMapFileName))
1573 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1581 case LMM_InvalidModuleMap:
1583 if (HSOpts->ImplicitModuleMaps)
1584 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1587 case LMM_AlreadyLoaded:
1588 case LMM_NoDirectory:
1591 case LMM_NewlyLoaded:
1595 return ModMap.findModule(Name);
1598 HeaderSearch::LoadModuleMapResult
1601 if (
auto Dir = FileMgr.getDirectory(DirName))
1604 return LMM_NoDirectory;
1607 HeaderSearch::LoadModuleMapResult
1610 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1611 if (KnownDir != DirectoryHasModuleMap.end())
1612 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1615 LoadModuleMapResult
Result =
1616 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1620 if (Result == LMM_NewlyLoaded)
1621 DirectoryHasModuleMap[Dir] =
true;
1622 else if (Result == LMM_InvalidModuleMap)
1623 DirectoryHasModuleMap[Dir] =
false;
1626 return LMM_InvalidModuleMap;
1632 if (HSOpts->ImplicitModuleMaps) {
1634 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1635 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1636 if (SearchDirs[Idx].isFramework()) {
1639 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->
getName(),
1643 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1644 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1646 Dir != DirEnd && !EC; Dir.increment(EC)) {
1647 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
1651 FileMgr.getDirectory(Dir->path());
1656 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1663 if (SearchDirs[Idx].isHeaderMap())
1672 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1678 MEnd = ModMap.module_end();
1680 Modules.push_back(M->getValue());
1685 if (!HSOpts->ImplicitModuleMaps)
1689 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1691 if (!SearchDirs[Idx].isNormalDir()) {
1697 SearchDirs[Idx].isSystemHeaderDirectory(),
1698 SearchDirs[Idx].isFramework());
1702 void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
1703 assert(HSOpts->ImplicitModuleMaps &&
1704 "Should not be loading subdirectory module maps");
1711 FileMgr.makeAbsolutePath(Dir);
1713 llvm::sys::path::native(Dir, DirNative);
1714 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1715 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1716 Dir != DirEnd && !EC; Dir.increment(EC)) {
1717 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
1727 const FileEntry *File, llvm::StringRef MainFile,
bool *IsSystem) {
1732 MainFile, IsSystem);
1736 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1740 unsigned BestPrefixLength = 0;
1744 auto CheckDir = [&](llvm::StringRef Dir) ->
bool {
1746 if (!WorkingDir.empty() && !path::is_absolute(Dir))
1747 fs::make_absolute(WorkingDir, DirPath);
1748 path::remove_dots(DirPath,
true);
1750 for (
auto NI = path::begin(File),
NE = path::end(File),
1751 DI = path::begin(Dir), DE = path::end(Dir);
1754 while (NI !=
NE && *NI ==
".")
1760 while (DI != DE && *DI ==
".")
1765 unsigned PrefixLength = NI - path::begin(File);
1766 if (PrefixLength > BestPrefixLength) {
1767 BestPrefixLength = PrefixLength;
1774 if (NI->size() == 1 && DI->size() == 1 &&
1775 path::is_separator(NI->front()) && path::is_separator(DI->front()))
1784 for (
unsigned I = 0; I != SearchDirs.size(); ++I) {
1786 if (!SearchDirs[I].isNormalDir())
1789 StringRef Dir = SearchDirs[I].getDir()->
getName();
1790 if (CheckDir(Dir) && IsSystem)
1791 *IsSystem = BestPrefixLength ? I >= SystemDirIdx :
false;
1796 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile)) && IsSystem)
1800 return path::convert_to_slash(File.drop_front(BestPrefixLength));
std::string Name
The name of this module.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool isIndexHeaderMap() const
Whether this header map is building a framework or not.
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
This header is part of the module (for layering purposes) but should be textually included...
Defines the SourceManager interface.
Defines the clang::Module class, which describes a module in the source code.
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
virtual IdentifierInfo * GetIdentifier(unsigned ID)=0
Return the identifier associated with the given ID number.
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
llvm::StringMap< Module * >::const_iterator module_iterator
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
llvm::Optional< FileEntryRef > getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
bool IsUserSpecifiedSystemFramework
Whether this framework has been "user-specified" to be treated as if it were a system framework (even...
Concrete class used by the front-end to report problems and issues.
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...
Defines the Diagnostic-related interfaces.
void setTarget(const TargetInfo &Target)
Set the target information.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules...
ModuleHeaderRole
Flags describing the role of a module header.
Exposes information about the current target.
Abstract interface for external sources of preprocessor information.
Defines the clang::Preprocessor interface.
bool isFramework() const
isFramework - True if this is a framework directory.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
The result type of a method or function.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
const DirectoryEntry * Directory
The directory entry which should be used for the cached framework.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
Encodes a location in the source.
bool isSystemHeaderDirectory() const
Whether this describes a system header directory.
StringRef getName() const
Cached information about one file (either on disk or in the virtual file system). ...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
bool haveSearchedAllModuleMaps() const
Determine whether we have already searched this entire directory for module maps. ...
bool isMacroDefined(StringRef Id)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
Dataflow Directional Tag Classes.
static std::string getName(const CallEvent &Call)
bool NE(InterpState &S, CodePtr OpPC)
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)=0
Update an out-of-date identifier.
Cached information about one directory (either on disk or in the virtual file system).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
This structure is used to record entries in our framework cache.
Optional< FileEntryRef > 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) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
void setSearchedAllModuleMaps(bool SAMM)
Specify whether we have already searched all of the subdirectories for module maps.
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
StringRef getName() const
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).