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/StringRef.h" 31 #include "llvm/Support/Allocator.h" 32 #include "llvm/Support/Capacity.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/FileSystem.h" 35 #include "llvm/Support/Path.h" 36 #include "llvm/Support/VirtualFileSystem.h" 43 #include <system_error> 46 using namespace clang;
52 assert(External &&
"We must have an external source if we have a " 53 "controlling macro that is out of date.");
73 : HSOpts(
std::move(HSOpts)), Diags(Diags),
74 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
75 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
78 fprintf(stderr,
"\n*** HeaderSearch Stats:\n");
79 fprintf(stderr,
"%d files tracked.\n", (
int)FileInfo.size());
80 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
81 for (
unsigned i = 0, e = FileInfo.size();
i != e; ++
i) {
82 NumOnceOnlyFiles += FileInfo[
i].isImport;
83 if (MaxNumIncludes < FileInfo[
i].NumIncludes)
84 MaxNumIncludes = FileInfo[
i].NumIncludes;
85 NumSingleIncludedFiles += FileInfo[
i].NumIncludes == 1;
87 fprintf(stderr,
" %d #import/#pragma once files.\n", NumOnceOnlyFiles);
88 fprintf(stderr,
" %d included exactly once.\n", NumSingleIncludedFiles);
89 fprintf(stderr,
" %d max times a file is included.\n", MaxNumIncludes);
91 fprintf(stderr,
" %d #include/#include_next/#import.\n", NumIncluded);
92 fprintf(stderr,
" %d #includes skipped due to" 93 " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
95 fprintf(stderr,
"%d framework lookups.\n", NumFrameworkLookups);
96 fprintf(stderr,
"%d subframework lookups.\n", NumSubFrameworkLookups);
104 if (!HeaderMaps.empty()) {
105 for (
unsigned i = 0, e = HeaderMaps.size();
i != e; ++
i)
108 if (HeaderMaps[
i].first == FE)
109 return HeaderMaps[
i].second.get();
113 HeaderMaps.emplace_back(FE, std::move(HM));
114 return HeaderMaps.back().second.get();
123 for (
auto &HM : HeaderMaps)
124 Names.push_back(HM.first->getName());
136 auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
137 if (
i != HSOpts->PrebuiltModuleFiles.end())
140 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
145 for (
const std::string &Dir : HSOpts->PrebuiltModulePaths) {
147 llvm::sys::fs::make_absolute(Result);
148 llvm::sys::path::append(Result, ModuleName +
".pcm");
150 return Result.str().str();
156 StringRef ModuleMapPath) {
163 llvm::sys::fs::make_absolute(Result);
165 if (HSOpts->DisableModuleHash) {
166 llvm::sys::path::append(Result, ModuleName +
".pcm");
175 std::string
Parent = llvm::sys::path::parent_path(ModuleMapPath);
182 auto FileName = llvm::sys::path::filename(ModuleMapPath);
184 llvm::hash_code Hash =
188 llvm::APInt(64,
size_t(Hash)).toStringUnsigned(HashStr, 36);
189 llvm::sys::path::append(Result, ModuleName +
"-" + HashStr +
".pcm");
191 return Result.str().str();
195 bool AllowExtraModuleMapSearch) {
198 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
201 StringRef SearchName = ModuleName;
202 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
212 if (!Module && SearchName.consume_back(
"_Private"))
213 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
214 if (!Module && SearchName.consume_back(
"Private"))
215 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
220 bool AllowExtraModuleMapSearch) {
225 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
226 if (SearchDirs[Idx].isFramework()) {
231 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
232 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
237 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
246 if (!SearchDirs[Idx].isNormalDir())
249 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
252 false) == LMM_NewlyLoaded) {
263 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
264 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
266 false) == LMM_NewlyLoaded){
275 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
280 if (AllowExtraModuleMapSearch)
281 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
300 return getDir()->getName();
302 return getFrameworkDir()->getName();
303 assert(isHeaderMap() &&
"Unknown DirectoryLookup");
304 return getHeaderMap()->getFileName();
307 const FileEntry *HeaderSearch::getFileAndSuggestModule(
309 bool IsSystemHeaderDir,
Module *RequestingModule,
318 if (!findUsableModuleForHeader(File, Dir ? Dir : File->
getDir(),
319 RequestingModule, SuggestedModule,
336 bool &InUserSpecifiedSystemFramework,
337 bool &IsFrameworkFound,
340 InUserSpecifiedSystemFramework =
false;
341 HasBeenMapped =
false;
346 TmpDir = getDir()->getName();
347 llvm::sys::path::append(TmpDir, Filename);
349 StringRef SearchPathRef(getDir()->
getName());
351 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
354 RelativePath->clear();
355 RelativePath->append(Filename.begin(), Filename.end());
358 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
359 isSystemHeaderDirectory(),
360 RequestingModule, SuggestedModule);
364 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
365 RequestingModule, SuggestedModule,
366 InUserSpecifiedSystemFramework, IsFrameworkFound);
368 assert(isHeaderMap() &&
"Unknown directory lookup");
380 if (llvm::sys::path::is_relative(Dest)) {
382 MappedName.append(Dest.begin(), Dest.end());
383 Filename = StringRef(MappedName.begin(), MappedName.size());
384 HasBeenMapped =
true;
392 StringRef SearchPathRef(
getName());
394 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
397 RelativePath->clear();
398 RelativePath->append(Filename.begin(), Filename.end());
413 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
414 "Not a framework directory");
434 DirName = llvm::sys::path::parent_path(DirName);
445 if (llvm::sys::path::extension(DirName) ==
".framework") {
446 SubmodulePath.push_back(llvm::sys::path::stem(DirName));
447 TopFrameworkDir = Dir;
451 return TopFrameworkDir;
455 bool HasSuggestedModule) {
456 return HasSuggestedModule ||
462 const FileEntry *DirectoryLookup::DoFrameworkLookup(
466 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
470 size_t SlashPos =
Filename.find(
'/');
471 if (SlashPos == StringRef::npos)
return nullptr;
486 FrameworkName += getFrameworkDir()->getName();
487 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
488 FrameworkName.push_back(
'/');
491 StringRef ModuleName(
Filename.begin(), SlashPos);
492 FrameworkName += ModuleName;
495 FrameworkName +=
".framework/";
503 if (!Dir)
return nullptr;
507 CacheEntry.
Directory = getFrameworkDir();
513 SystemFrameworkMarker +=
".system_framework";
514 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
525 RelativePath->clear();
530 unsigned OrigSize = FrameworkName.size();
532 FrameworkName +=
"Headers/";
537 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
545 const char *Private =
"Private";
546 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
547 Private+strlen(Private));
549 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
550 Private+strlen(Private));
552 FE = FileMgr.
getFile(FrameworkName, !SuggestedModule);
559 bool FoundFramework =
false;
568 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
569 FoundFramework =
true;
574 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
575 if (FrameworkPath.empty())
580 if (FoundFramework) {
581 if (!HS.findUsableModuleForFrameworkHeader(
582 FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
585 if (!HS.findUsableModuleForHeader(FE, getDir(), RequestingModule,
586 SuggestedModule, IsSystem))
607 if (MSFE && FE != MSFE) {
608 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
614 static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
615 assert(!Str.empty());
616 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
617 std::copy(Str.begin(), Str.end(), CopyStr);
618 CopyStr[Str.size()] =
'\0';
625 path::const_iterator I = path::begin(Path);
626 path::const_iterator E = path::end(Path);
627 IsPrivateHeader =
false;
641 if (I->endswith(
".framework")) {
642 FrameworkName.append(I->begin(), I->end());
645 if (*I ==
"PrivateHeaders") {
647 IsPrivateHeader =
true;
652 return !FrameworkName.empty() && FoundComp >= 2;
657 StringRef Includer, StringRef IncludeFilename,
658 const FileEntry *IncludeFE,
bool isAngled =
false,
659 bool FoundByHeaderMap =
false) {
660 bool IsIncluderPrivateHeader =
false;
664 bool IsIncludeePrivateHeader =
false;
666 IncludeFE->
getName(), IsIncludeePrivateHeader, ToFramework);
668 if (!isAngled && !FoundByHeaderMap) {
670 if (IsIncludeeInFramework) {
671 NewInclude += StringRef(ToFramework).drop_back(10);
674 NewInclude += IncludeFilename;
676 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
684 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
685 IsIncludeePrivateHeader && FromFramework == ToFramework)
686 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
698 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
701 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
702 bool BuildSystemModule) {
706 if (IsFrameworkFound)
707 *IsFrameworkFound =
false;
713 if (llvm::sys::path::is_absolute(Filename)) {
717 if (FromDir)
return nullptr;
722 RelativePath->clear();
723 RelativePath->append(Filename.begin(), Filename.end());
726 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
728 RequestingModule, SuggestedModule);
740 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
743 for (
const auto &IncluderAndDir : Includers) {
744 const FileEntry *Includer = IncluderAndDir.first;
748 TmpDir = IncluderAndDir.second->getName();
749 TmpDir.push_back(
'/');
750 TmpDir.append(Filename.begin(), Filename.end());
759 bool IncluderIsSystemHeader =
762 if (
const FileEntry *FE = getFileAndSuggestModule(
763 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
764 RequestingModule, SuggestedModule)) {
766 assert(First &&
"only first includer can have no file");
777 unsigned DirInfo = FromHFI.
DirInfo;
787 StringRef SearchPathRef(IncluderAndDir.second->getName());
789 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
792 RelativePath->clear();
793 RelativePath->append(Filename.begin(), Filename.end());
797 IncluderAndDir.second->getName(),
Filename,
805 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
809 if (SuggestedModule) {
810 MSSuggestedModule = *SuggestedModule;
823 unsigned i = isAngled ? AngledDirIdx : 0;
828 i = FromDir-&SearchDirs[0];
834 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
839 if (!SkipCache && CacheLookup.StartIdx == i+1) {
841 i = CacheLookup.HitIdx;
842 if (CacheLookup.MappedName) {
843 Filename = CacheLookup.MappedName;
851 CacheLookup.reset(i+1);
857 for (; i != SearchDirs.size(); ++
i) {
858 bool InUserSpecifiedSystemFramework =
false;
859 bool HasBeenMapped =
false;
860 bool IsFrameworkFoundInDir =
false;
861 const FileEntry *FE = SearchDirs[
i].LookupFile(
862 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
863 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
864 HasBeenMapped, MappedName);
866 CacheLookup.MappedName =
867 copyString(Filename, LookupFileCache.getAllocator());
871 if (IsFrameworkFound)
875 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
878 CurDir = &SearchDirs[
i];
892 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
893 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
903 size_t SlashPos = Filename.find(
'/');
904 if (SlashPos != StringRef::npos) {
913 *SuggestedModule = MSSuggestedModule;
917 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
918 if (!Includers.empty())
920 Includers.front().second->getName(),
Filename,
921 FE, isAngled, FoundByHeaderMap);
924 CacheLookup.HitIdx =
i;
932 if (!Includers.empty() && Includers.front().first && !isAngled &&
933 Filename.find(
'/') == StringRef::npos) {
937 ScratchFilename += IncludingHFI.
Framework;
938 ScratchFilename +=
'/';
942 ScratchFilename, IncludeLoc,
true, FromDir, CurDir,
943 Includers.front(), SearchPath, RelativePath, RequestingModule,
944 SuggestedModule, IsMapped,
nullptr);
948 *SuggestedModule = MSSuggestedModule;
952 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
953 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
961 *SuggestedModule = MSSuggestedModule;
966 CacheLookup.HitIdx = SearchDirs.size();
982 assert(ContextFileEnt &&
"No context file?");
986 size_t SlashPos = Filename.find(
'/');
987 if (SlashPos == StringRef::npos)
return nullptr;
990 StringRef ContextName = ContextFileEnt->
getName();
993 const unsigned DotFrameworkLen = 10;
994 auto FrameworkPos = ContextName.find(
".framework");
995 if (FrameworkPos == StringRef::npos ||
996 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
997 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1002 DotFrameworkLen + 1);
1005 FrameworkName +=
"Frameworks/";
1006 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1007 FrameworkName +=
".framework/";
1010 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1014 if (CacheLookup.second.Directory &&
1015 CacheLookup.first().size() == FrameworkName.size() &&
1016 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1017 CacheLookup.first().size()) != 0)
1021 if (!CacheLookup.second.Directory) {
1022 ++NumSubFrameworkLookups;
1026 if (!Dir)
return nullptr;
1030 CacheLookup.second.Directory = Dir;
1036 RelativePath->clear();
1037 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1042 HeadersFilename +=
"Headers/";
1044 SearchPath->clear();
1046 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1049 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1050 if (!(FE = FileMgr.getFile(HeadersFilename,
true))) {
1052 HeadersFilename = FrameworkName;
1053 HeadersFilename +=
"PrivateHeaders/";
1055 SearchPath->clear();
1057 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1060 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1061 if (!(FE = FileMgr.getFile(HeadersFilename,
true)))
1073 FrameworkName.pop_back();
1074 if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
1075 SuggestedModule,
false))
1089 assert(OtherHFI.
External &&
"expected to merge external HFI");
1113 if (FE->
getUID() >= FileInfo.size())
1114 FileInfo.resize(FE->
getUID() + 1);
1118 if (ExternalSource && !HFI->
Resolved) {
1120 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1122 HFI = &FileInfo[FE->
getUID()];
1123 if (ExternalHFI.External)
1136 bool WantExternal)
const {
1140 if (ExternalSource) {
1141 if (FE->
getUID() >= FileInfo.size()) {
1144 FileInfo.resize(FE->
getUID() + 1);
1147 HFI = &FileInfo[FE->
getUID()];
1152 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1154 HFI = &FileInfo[FE->
getUID()];
1155 if (ExternalHFI.External)
1158 }
else if (FE->
getUID() >= FileInfo.size()) {
1161 HFI = &FileInfo[FE->
getUID()];
1173 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1174 HFI->ControllingMacroID;
1180 bool isCompilingModuleHeader) {
1184 if (!isCompilingModuleHeader) {
1185 if (!isModularHeader)
1188 if (HFI && HFI->isModuleHeader)
1193 HFI.isModuleHeader |= isModularHeader;
1194 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1199 bool ModulesEnabled,
Module *M) {
1207 auto TryEnterImported = [&]() ->
bool {
1208 if (!ModulesEnabled)
1211 ModMap.resolveHeaderDirectives(File);
1229 bool TryEnterHdr =
false;
1231 TryEnterHdr = File->
getDir() == ModMap.getBuiltinDir() &&
1233 llvm::sys::path::filename(File->
getName()));
1257 if (FileInfo.
isImport && !TryEnterImported())
1270 ++NumMultiIncludeFileOptzn;
1282 return SearchDirs.capacity()
1283 + llvm::capacity_in_bytes(FileInfo)
1284 + llvm::capacity_in_bytes(HeaderMaps)
1285 + LookupFileCache.getAllocator().getTotalMemory()
1286 + FrameworkMap.getAllocator().getTotalMemory();
1290 return FrameworkNames.insert(Framework).first->first();
1296 if (!HSOpts->ImplicitModuleMaps)
1301 StringRef DirName = FileName;
1304 DirName = llvm::sys::path::parent_path(DirName);
1305 if (DirName.empty())
1315 llvm::sys::path::extension(Dir->
getName()) ==
1317 case LMM_NewlyLoaded:
1318 case LMM_AlreadyLoaded:
1321 for (
unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1322 DirectoryHasModuleMap[FixUpDirectories[I]] =
true;
1325 case LMM_NoDirectory:
1326 case LMM_InvalidModuleMap:
1336 FixUpDirectories.push_back(Dir);
1342 bool AllowTextual)
const {
1343 if (ExternalSource) {
1348 return ModMap.findModuleForHeader(File, AllowTextual);
1352 Module *RequestingModule,
1356 if (SuggestedModule)
1373 bool HeaderSearch::findUsableModuleForHeader(
1379 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1384 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1385 const FileEntry *File, StringRef FrameworkName,
Module *RequestingModule,
1395 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1399 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1405 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1414 if (Filename ==
"module.map")
1415 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1416 else if (Filename ==
"module.modulemap")
1417 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1420 return FileMgr.
getFile(PrivateFilename);
1425 StringRef OriginalModuleMapFile) {
1430 Dir = FileMgr.getDirectory(
".");
1432 if (!OriginalModuleMapFile.empty()) {
1435 Dir = FileMgr.getDirectory(
1436 llvm::sys::path::parent_path(OriginalModuleMapFile));
1438 auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
1439 Dir = FakeFile->getDir();
1445 StringRef DirName(Dir->
getName());
1446 if (llvm::sys::path::filename(DirName) ==
"Modules") {
1447 DirName = llvm::sys::path::parent_path(DirName);
1448 if (DirName.endswith(
".framework"))
1449 Dir = FileMgr.getDirectory(DirName);
1452 assert(Dir &&
"parent must exist");
1456 switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1457 case LMM_AlreadyLoaded:
1458 case LMM_NewlyLoaded:
1460 case LMM_NoDirectory:
1461 case LMM_InvalidModuleMap:
1464 llvm_unreachable(
"Unknown load module map result");
1467 HeaderSearch::LoadModuleMapResult
1468 HeaderSearch::loadModuleMapFileImpl(
const FileEntry *File,
bool IsSystem,
1471 assert(File &&
"expected FileEntry");
1475 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File,
true));
1476 if (!AddResult.second)
1477 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1479 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1480 LoadedModuleMaps[File] =
false;
1481 return LMM_InvalidModuleMap;
1486 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1487 LoadedModuleMaps[File] =
false;
1488 return LMM_InvalidModuleMap;
1493 return LMM_NewlyLoaded;
1498 if (!HSOpts->ImplicitModuleMaps)
1504 llvm::sys::path::append(ModuleMapFileName,
"Modules");
1505 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1506 if (
const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
1510 ModuleMapFileName = Dir->
getName();
1511 llvm::sys::path::append(ModuleMapFileName,
"module.map");
1512 return FileMgr.getFile(ModuleMapFileName);
1515 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1523 case LMM_InvalidModuleMap:
1525 if (HSOpts->ImplicitModuleMaps)
1526 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1529 case LMM_AlreadyLoaded:
1530 case LMM_NoDirectory:
1533 case LMM_NewlyLoaded:
1537 return ModMap.findModule(Name);
1540 HeaderSearch::LoadModuleMapResult
1546 return LMM_NoDirectory;
1549 HeaderSearch::LoadModuleMapResult
1552 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1553 if (KnownDir != DirectoryHasModuleMap.end())
1554 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1557 LoadModuleMapResult
Result =
1558 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1562 if (Result == LMM_NewlyLoaded)
1563 DirectoryHasModuleMap[Dir] =
true;
1564 else if (Result == LMM_InvalidModuleMap)
1565 DirectoryHasModuleMap[Dir] =
false;
1568 return LMM_InvalidModuleMap;
1574 if (HSOpts->ImplicitModuleMaps) {
1576 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1577 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1578 if (SearchDirs[Idx].isFramework()) {
1581 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->
getName(),
1585 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1586 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1588 Dir != DirEnd && !EC; Dir.increment(EC)) {
1589 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
1593 FileMgr.getDirectory(Dir->path());
1598 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir,
1605 if (SearchDirs[Idx].isHeaderMap())
1614 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1620 MEnd = ModMap.module_end();
1622 Modules.push_back(M->getValue());
1627 if (!HSOpts->ImplicitModuleMaps)
1631 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1633 if (!SearchDirs[Idx].isNormalDir()) {
1639 SearchDirs[Idx].isSystemHeaderDirectory(),
1640 SearchDirs[Idx].isFramework());
1644 void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
1645 assert(HSOpts->ImplicitModuleMaps &&
1646 "Should not be loading subdirectory module maps");
1653 FileMgr.makeAbsolutePath(Dir);
1655 llvm::sys::path::native(Dir, DirNative);
1656 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1657 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1658 Dir != DirEnd && !EC; Dir.increment(EC)) {
1659 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
1669 const FileEntry *File, llvm::StringRef MainFile,
bool *IsSystem) {
1674 MainFile, IsSystem);
1678 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1682 unsigned BestPrefixLength = 0;
1686 auto CheckDir = [&](llvm::StringRef Dir) ->
bool {
1688 if (!WorkingDir.empty() && !path::is_absolute(Dir))
1689 fs::make_absolute(WorkingDir, DirPath);
1690 path::remove_dots(DirPath,
true);
1692 for (
auto NI = path::begin(File), NE = path::end(File),
1693 DI = path::begin(Dir), DE = path::end(Dir);
1696 while (NI != NE && *NI ==
".")
1702 while (DI != DE && *DI ==
".")
1707 unsigned PrefixLength = NI - path::begin(File);
1708 if (PrefixLength > BestPrefixLength) {
1709 BestPrefixLength = PrefixLength;
1716 if (NI->size() == 1 && DI->size() == 1 &&
1717 path::is_separator(NI->front()) && path::is_separator(DI->front()))
1726 for (
unsigned I = 0; I != SearchDirs.size(); ++I) {
1728 if (!SearchDirs[I].isNormalDir())
1731 StringRef Dir = SearchDirs[I].getDir()->
getName();
1732 if (CheckDir(Dir) && IsSystem)
1733 *IsSystem = BestPrefixLength ? I >= SystemDirIdx :
false;
1738 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile)) && IsSystem)
1742 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
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.
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...
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.
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. ...
const FileEntry * LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, bool &HasBeenMapped, SmallVectorImpl< char > &MappedName) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
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)
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).
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.
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