28 #include "llvm/ADT/APInt.h" 29 #include "llvm/ADT/Hashing.h" 30 #include "llvm/ADT/SmallString.h" 31 #include "llvm/ADT/SmallVector.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/Support/Allocator.h" 34 #include "llvm/Support/Capacity.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include "llvm/Support/FileSystem.h" 37 #include "llvm/Support/Path.h" 44 #include <system_error> 47 using namespace clang;
53 assert(External &&
"We must have an external source if we have a " 54 "controlling macro that is out of date.");
74 : HSOpts(
std::move(HSOpts)), Diags(Diags),
75 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
76 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
80 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
81 delete HeaderMaps[i].second;
85 fprintf(stderr,
"\n*** HeaderSearch Stats:\n");
86 fprintf(stderr,
"%d files tracked.\n", (
int)FileInfo.size());
87 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
88 for (
unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
89 NumOnceOnlyFiles += FileInfo[i].isImport;
90 if (MaxNumIncludes < FileInfo[i].NumIncludes)
91 MaxNumIncludes = FileInfo[i].NumIncludes;
92 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
94 fprintf(stderr,
" %d #import/#pragma once files.\n", NumOnceOnlyFiles);
95 fprintf(stderr,
" %d included exactly once.\n", NumSingleIncludedFiles);
96 fprintf(stderr,
" %d max times a file is included.\n", MaxNumIncludes);
98 fprintf(stderr,
" %d #include/#include_next/#import.\n", NumIncluded);
99 fprintf(stderr,
" %d #includes skipped due to" 100 " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
102 fprintf(stderr,
"%d framework lookups.\n", NumFrameworkLookups);
103 fprintf(stderr,
"%d subframework lookups.\n", NumSubFrameworkLookups);
111 if (!HeaderMaps.empty()) {
112 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
115 if (HeaderMaps[i].first == FE)
116 return HeaderMaps[i].second;
120 HeaderMaps.push_back(std::make_pair(FE, HM));
130 for (
auto &HM : HeaderMaps)
131 Names.push_back(HM.first->getName());
143 auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
144 if (i != HSOpts->PrebuiltModuleFiles.end())
147 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
152 for (
const std::string &Dir : HSOpts->PrebuiltModulePaths) {
154 llvm::sys::fs::make_absolute(Result);
155 llvm::sys::path::append(Result, ModuleName +
".pcm");
157 return Result.str().str();
163 StringRef ModuleMapPath) {
170 llvm::sys::fs::make_absolute(Result);
172 if (HSOpts->DisableModuleHash) {
173 llvm::sys::path::append(Result, ModuleName +
".pcm");
182 std::string
Parent = llvm::sys::path::parent_path(ModuleMapPath);
189 auto FileName = llvm::sys::path::filename(ModuleMapPath);
191 llvm::hash_code Hash =
195 llvm::APInt(64,
size_t(Hash)).toStringUnsigned(HashStr, 36);
196 llvm::sys::path::append(Result, ModuleName +
"-" + HashStr +
".pcm");
198 return Result.str().str();
202 bool AllowExtraModuleMapSearch) {
205 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
208 StringRef SearchName = ModuleName;
209 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
219 if (!Module && SearchName.consume_back(
"_Private"))
220 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
221 if (!Module && SearchName.consume_back(
"Private"))
222 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
227 bool AllowExtraModuleMapSearch) {
232 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
233 if (SearchDirs[Idx].isFramework()) {
238 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
239 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
244 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
253 if (!SearchDirs[Idx].isNormalDir())
256 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
259 false) == LMM_NewlyLoaded) {
270 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
271 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
273 false) == LMM_NewlyLoaded){
282 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
287 if (AllowExtraModuleMapSearch)
288 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
307 return getDir()->getName();
309 return getFrameworkDir()->getName();
310 assert(isHeaderMap() &&
"Unknown DirectoryLookup");
311 return getHeaderMap()->getFileName();
314 const FileEntry *HeaderSearch::getFileAndSuggestModule(
316 bool IsSystemHeaderDir,
Module *RequestingModule,
325 if (!findUsableModuleForHeader(File, Dir ? Dir : File->
getDir(),
326 RequestingModule, SuggestedModule,
343 bool &InUserSpecifiedSystemFramework,
346 InUserSpecifiedSystemFramework =
false;
347 HasBeenMapped =
false;
352 TmpDir = getDir()->getName();
353 llvm::sys::path::append(TmpDir, Filename);
355 StringRef SearchPathRef(getDir()->
getName());
357 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
360 RelativePath->clear();
361 RelativePath->append(Filename.begin(), Filename.end());
364 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
365 isSystemHeaderDirectory(),
366 RequestingModule, SuggestedModule);
370 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
371 RequestingModule, SuggestedModule,
372 InUserSpecifiedSystemFramework);
374 assert(isHeaderMap() &&
"Unknown directory lookup");
386 if (llvm::sys::path::is_relative(Dest)) {
388 MappedName.append(Dest.begin(), Dest.end());
389 Filename = StringRef(MappedName.begin(), MappedName.size());
390 HasBeenMapped =
true;
398 StringRef SearchPathRef(
getName());
400 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
403 RelativePath->clear();
404 RelativePath->append(Filename.begin(), Filename.end());
419 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
420 "Not a framework directory");
440 DirName = llvm::sys::path::parent_path(DirName);
451 if (llvm::sys::path::extension(DirName) ==
".framework") {
452 SubmodulePath.push_back(llvm::sys::path::stem(DirName));
453 TopFrameworkDir = Dir;
457 return TopFrameworkDir;
461 bool HasSuggestedModule) {
462 return HasSuggestedModule ||
468 const FileEntry *DirectoryLookup::DoFrameworkLookup(
472 bool &InUserSpecifiedSystemFramework)
const {
476 size_t SlashPos =
Filename.find(
'/');
477 if (SlashPos == StringRef::npos)
return nullptr;
481 HeaderSearch::FrameworkCacheEntry &CacheEntry =
485 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
492 FrameworkName += getFrameworkDir()->getName();
493 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
494 FrameworkName.push_back(
'/');
497 StringRef ModuleName(
Filename.begin(), SlashPos);
498 FrameworkName += ModuleName;
501 FrameworkName +=
".framework/";
504 if (!CacheEntry.Directory) {
509 if (!Dir)
return nullptr;
513 CacheEntry.Directory = getFrameworkDir();
519 SystemFrameworkMarker +=
".system_framework";
520 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
521 CacheEntry.IsUserSpecifiedSystemFramework =
true;
527 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
530 RelativePath->clear();
535 unsigned OrigSize = FrameworkName.size();
537 FrameworkName +=
"Headers/";
542 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
550 const char *Private =
"Private";
551 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
552 Private+strlen(Private));
554 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
555 Private+strlen(Private));
557 FE = FileMgr.
getFile(FrameworkName, !SuggestedModule);
564 bool FoundFramework =
false;
573 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
574 FoundFramework =
true;
579 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
580 if (FrameworkPath.empty())
585 if (FoundFramework) {
586 if (!HS.findUsableModuleForFrameworkHeader(
587 FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
590 if (!HS.findUsableModuleForHeader(FE, getDir(), RequestingModule,
591 SuggestedModule, IsSystem))
612 if (MSFE && FE != MSFE) {
613 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
619 static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
620 assert(!Str.empty());
621 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
622 std::copy(Str.begin(), Str.end(), CopyStr);
623 CopyStr[Str.size()] =
'\0';
630 path::const_iterator I = path::begin(Path);
631 path::const_iterator E = path::end(Path);
632 IsPrivateHeader =
false;
646 if (I->endswith(
".framework")) {
647 FrameworkName.append(I->begin(), I->end());
650 if (*I ==
"PrivateHeaders") {
652 IsPrivateHeader =
true;
657 return FoundComp >= 2;
662 StringRef Includer, StringRef IncludeFilename,
663 const FileEntry *IncludeFE,
bool isAngled =
false,
664 bool FoundByHeaderMap =
false) {
665 bool IsIncluderPrivateHeader =
false;
669 bool IsIncludeePrivateHeader =
false;
671 IncludeFE->
getName(), IsIncludeePrivateHeader, ToFramework);
673 if (!isAngled && !FoundByHeaderMap) {
675 if (IsIncludeeInFramework) {
676 NewInclude += StringRef(ToFramework).drop_back(10);
679 NewInclude += IncludeFilename;
681 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
689 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
690 IsIncludeePrivateHeader && FromFramework == ToFramework)
691 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
703 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
706 bool *IsMapped,
bool SkipCache,
bool BuildSystemModule) {
714 if (llvm::sys::path::is_absolute(Filename)) {
718 if (FromDir)
return nullptr;
723 RelativePath->clear();
724 RelativePath->append(Filename.begin(), Filename.end());
727 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
729 RequestingModule, SuggestedModule);
741 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
744 for (
const auto &IncluderAndDir : Includers) {
745 const FileEntry *Includer = IncluderAndDir.first;
749 TmpDir = IncluderAndDir.second->getName();
750 TmpDir.push_back(
'/');
751 TmpDir.append(Filename.begin(), Filename.end());
760 bool IncluderIsSystemHeader =
763 if (
const FileEntry *FE = getFileAndSuggestModule(
764 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
765 RequestingModule, SuggestedModule)) {
767 assert(First &&
"only first includer can have no file");
778 unsigned DirInfo = FromHFI.
DirInfo;
788 StringRef SearchPathRef(IncluderAndDir.second->getName());
790 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
793 RelativePath->clear();
794 RelativePath->append(Filename.begin(), Filename.end());
798 IncluderAndDir.second->getName(),
Filename,
806 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
810 if (SuggestedModule) {
811 MSSuggestedModule = *SuggestedModule;
824 unsigned i = isAngled ? AngledDirIdx : 0;
829 i = FromDir-&SearchDirs[0];
835 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
840 if (!SkipCache && CacheLookup.StartIdx == i+1) {
842 i = CacheLookup.HitIdx;
843 if (CacheLookup.MappedName) {
844 Filename = CacheLookup.MappedName;
852 CacheLookup.reset(i+1);
858 for (; i != SearchDirs.size(); ++i) {
859 bool InUserSpecifiedSystemFramework =
false;
860 bool HasBeenMapped =
false;
861 const FileEntry *FE = SearchDirs[i].LookupFile(
862 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
863 SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
866 CacheLookup.MappedName =
867 copyString(Filename, LookupFileCache.getAllocator());
873 CurDir = &SearchDirs[i];
887 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
888 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
898 size_t SlashPos = Filename.find(
'/');
899 if (SlashPos != StringRef::npos) {
908 *SuggestedModule = MSSuggestedModule;
912 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
913 if (!Includers.empty())
915 Includers.front().second->getName(),
Filename,
916 FE, isAngled, FoundByHeaderMap);
919 CacheLookup.HitIdx = i;
927 if (!Includers.empty() && Includers.front().first && !isAngled &&
928 Filename.find(
'/') == StringRef::npos) {
932 ScratchFilename += IncludingHFI.
Framework;
933 ScratchFilename +=
'/';
937 LookupFile(ScratchFilename, IncludeLoc,
true, FromDir,
938 CurDir, Includers.front(), SearchPath, RelativePath,
939 RequestingModule, SuggestedModule, IsMapped);
943 *SuggestedModule = MSSuggestedModule;
947 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
948 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
956 *SuggestedModule = MSSuggestedModule;
961 CacheLookup.HitIdx = SearchDirs.size();
977 assert(ContextFileEnt &&
"No context file?");
981 size_t SlashPos = Filename.find(
'/');
982 if (SlashPos == StringRef::npos)
return nullptr;
985 StringRef ContextName = ContextFileEnt->
getName();
988 const unsigned DotFrameworkLen = 10;
989 auto FrameworkPos = ContextName.find(
".framework");
990 if (FrameworkPos == StringRef::npos ||
991 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
992 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
997 DotFrameworkLen + 1);
1000 FrameworkName +=
"Frameworks/";
1001 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1002 FrameworkName +=
".framework/";
1005 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1006 FrameworkCacheEntry())).first;
1009 if (CacheLookup.second.Directory &&
1010 CacheLookup.first().size() == FrameworkName.size() &&
1011 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1012 CacheLookup.first().size()) != 0)
1016 if (!CacheLookup.second.Directory) {
1017 ++NumSubFrameworkLookups;
1021 if (!Dir)
return nullptr;
1025 CacheLookup.second.Directory = Dir;
1031 RelativePath->clear();
1032 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1037 HeadersFilename +=
"Headers/";
1039 SearchPath->clear();
1041 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1044 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1045 if (!(FE = FileMgr.getFile(HeadersFilename,
true))) {
1047 HeadersFilename = FrameworkName;
1048 HeadersFilename +=
"PrivateHeaders/";
1050 SearchPath->clear();
1052 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1055 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1056 if (!(FE = FileMgr.getFile(HeadersFilename,
true)))
1068 FrameworkName.pop_back();
1069 if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
1070 SuggestedModule,
false))
1084 assert(OtherHFI.
External &&
"expected to merge external HFI");
1108 if (FE->
getUID() >= FileInfo.size())
1109 FileInfo.resize(FE->
getUID() + 1);
1113 if (ExternalSource && !HFI->
Resolved) {
1115 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1117 HFI = &FileInfo[FE->
getUID()];
1118 if (ExternalHFI.External)
1131 bool WantExternal)
const {
1135 if (ExternalSource) {
1136 if (FE->
getUID() >= FileInfo.size()) {
1139 FileInfo.resize(FE->
getUID() + 1);
1142 HFI = &FileInfo[FE->
getUID()];
1147 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1149 HFI = &FileInfo[FE->
getUID()];
1150 if (ExternalHFI.External)
1153 }
else if (FE->
getUID() >= FileInfo.size()) {
1156 HFI = &FileInfo[FE->
getUID()];
1168 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1169 HFI->ControllingMacroID;
1175 bool isCompilingModuleHeader) {
1179 if (!isCompilingModuleHeader) {
1180 if (!isModularHeader)
1183 if (HFI && HFI->isModuleHeader)
1188 HFI.isModuleHeader |= isModularHeader;
1189 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1194 bool ModulesEnabled,
Module *M) {
1202 auto TryEnterImported = [&]() ->
bool {
1203 if (!ModulesEnabled)
1206 ModMap.resolveHeaderDirectives(File);
1224 bool TryEnterHdr =
false;
1226 TryEnterHdr = File->
getDir() == ModMap.getBuiltinDir() &&
1228 llvm::sys::path::filename(File->
getName()));
1252 if (FileInfo.
isImport && !TryEnterImported())
1265 ++NumMultiIncludeFileOptzn;
1277 return SearchDirs.capacity()
1278 + llvm::capacity_in_bytes(FileInfo)
1279 + llvm::capacity_in_bytes(HeaderMaps)
1280 + LookupFileCache.getAllocator().getTotalMemory()
1281 + FrameworkMap.getAllocator().getTotalMemory();
1285 return FrameworkNames.insert(Framework).first->first();
1291 if (!HSOpts->ImplicitModuleMaps)
1296 StringRef DirName = FileName;
1299 DirName = llvm::sys::path::parent_path(DirName);
1300 if (DirName.empty())
1310 llvm::sys::path::extension(Dir->
getName()) ==
1312 case LMM_NewlyLoaded:
1313 case LMM_AlreadyLoaded:
1316 for (
unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1317 DirectoryHasModuleMap[FixUpDirectories[I]] =
true;
1320 case LMM_NoDirectory:
1321 case LMM_InvalidModuleMap:
1331 FixUpDirectories.push_back(Dir);
1337 bool AllowTextual)
const {
1338 if (ExternalSource) {
1343 return ModMap.findModuleForHeader(File, AllowTextual);
1347 Module *RequestingModule,
1351 if (SuggestedModule)
1368 bool HeaderSearch::findUsableModuleForHeader(
1374 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1379 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1380 const FileEntry *File, StringRef FrameworkName,
Module *RequestingModule,
1390 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1394 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1400 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1409 if (Filename ==
"module.map")
1410 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1411 else if (Filename ==
"module.modulemap")
1412 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1415 return FileMgr.
getFile(PrivateFilename);
1420 StringRef OriginalModuleMapFile) {
1425 Dir = FileMgr.getDirectory(
".");
1427 if (!OriginalModuleMapFile.empty()) {
1430 Dir = FileMgr.getDirectory(
1431 llvm::sys::path::parent_path(OriginalModuleMapFile));
1433 auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
1434 Dir = FakeFile->getDir();
1440 StringRef DirName(Dir->
getName());
1441 if (llvm::sys::path::filename(DirName) ==
"Modules") {
1442 DirName = llvm::sys::path::parent_path(DirName);
1443 if (DirName.endswith(
".framework"))
1444 Dir = FileMgr.getDirectory(DirName);
1447 assert(Dir &&
"parent must exist");
1451 switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1452 case LMM_AlreadyLoaded:
1453 case LMM_NewlyLoaded:
1455 case LMM_NoDirectory:
1456 case LMM_InvalidModuleMap:
1459 llvm_unreachable(
"Unknown load module map result");
1462 HeaderSearch::LoadModuleMapResult
1463 HeaderSearch::loadModuleMapFileImpl(
const FileEntry *File,
bool IsSystem,
1466 assert(File &&
"expected FileEntry");
1470 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File,
true));
1471 if (!AddResult.second)
1472 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1474 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1475 LoadedModuleMaps[File] =
false;
1476 return LMM_InvalidModuleMap;
1481 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1482 LoadedModuleMaps[File] =
false;
1483 return LMM_InvalidModuleMap;
1488 return LMM_NewlyLoaded;
1493 if (!HSOpts->ImplicitModuleMaps)
1499 llvm::sys::path::append(ModuleMapFileName,
"Modules");
1500 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1501 if (
const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
1505 ModuleMapFileName = Dir->
getName();
1506 llvm::sys::path::append(ModuleMapFileName,
"module.map");
1507 return FileMgr.getFile(ModuleMapFileName);
1510 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1518 case LMM_InvalidModuleMap:
1520 if (HSOpts->ImplicitModuleMaps)
1521 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1524 case LMM_AlreadyLoaded:
1525 case LMM_NoDirectory:
1528 case LMM_NewlyLoaded:
1532 return ModMap.findModule(Name);
1535 HeaderSearch::LoadModuleMapResult
1541 return LMM_NoDirectory;
1544 HeaderSearch::LoadModuleMapResult
1547 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1548 if (KnownDir != DirectoryHasModuleMap.end())
1549 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1552 LoadModuleMapResult
Result =
1553 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1557 if (Result == LMM_NewlyLoaded)
1558 DirectoryHasModuleMap[Dir] =
true;
1559 else if (Result == LMM_InvalidModuleMap)
1560 DirectoryHasModuleMap[Dir] =
false;
1563 return LMM_InvalidModuleMap;
1569 if (HSOpts->ImplicitModuleMaps) {
1571 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1572 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1573 if (SearchDirs[Idx].isFramework()) {
1576 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->
getName(),
1582 Dir != DirEnd && !EC; Dir.increment(EC)) {
1583 if (llvm::sys::path::extension(Dir->
getName()) !=
".framework")
1587 FileMgr.getDirectory(Dir->
getName());
1592 loadFrameworkModule(llvm::sys::path::stem(Dir->
getName()),
1593 FrameworkDir, IsSystem);
1599 if (SearchDirs[Idx].isHeaderMap())
1608 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1614 MEnd = ModMap.module_end();
1616 Modules.push_back(M->getValue());
1621 if (!HSOpts->ImplicitModuleMaps)
1625 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1627 if (!SearchDirs[Idx].isNormalDir()) {
1633 SearchDirs[Idx].isSystemHeaderDirectory(),
1634 SearchDirs[Idx].isFramework());
1638 void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
1639 assert(HSOpts->ImplicitModuleMaps &&
1640 "Should not be loading subdirectory module maps");
1647 llvm::sys::path::native(SearchDir.
getDir()->
getName(), DirNative);
1650 Dir != DirEnd && !EC; Dir.increment(EC)) {
1652 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1671 llvm::StringRef File, llvm::StringRef WorkingDir,
bool *IsSystem) {
1674 unsigned BestPrefixLength = 0;
1675 unsigned BestSearchDir;
1677 for (
unsigned I = 0; I != SearchDirs.size(); ++I) {
1679 if (!SearchDirs[I].isNormalDir())
1682 StringRef Dir = SearchDirs[I].getDir()->
getName();
1684 if (!WorkingDir.empty() && !path::is_absolute(Dir)) {
1685 auto err = fs::make_absolute(WorkingDir, DirPath);
1687 path::remove_dots(DirPath,
true);
1690 for (
auto NI = path::begin(File), NE = path::end(File),
1691 DI = path::begin(Dir), DE = path::end(Dir);
1694 while (NI != NE && *NI ==
".")
1700 while (DI != DE && *DI ==
".")
1705 unsigned PrefixLength = NI - path::begin(File);
1706 if (PrefixLength > BestPrefixLength) {
1707 BestPrefixLength = PrefixLength;
1719 *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx :
false;
1720 return 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
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
The virtual file system interface.
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.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
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...
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
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.
const FileEntry * LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &HasBeenMapped, SmallVectorImpl< char > &MappedName) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
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 * 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.
Defines the virtual file system interface vfs::FileSystem.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
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).
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
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.
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