27 #include "llvm/ADT/APInt.h" 28 #include "llvm/ADT/Hashing.h" 29 #include "llvm/ADT/SmallString.h" 30 #include "llvm/ADT/SmallVector.h" 31 #include "llvm/ADT/StringRef.h" 32 #include "llvm/Support/Allocator.h" 33 #include "llvm/Support/Capacity.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/FileSystem.h" 36 #include "llvm/Support/Path.h" 37 #include "llvm/Support/VirtualFileSystem.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) {}
79 fprintf(stderr,
"\n*** HeaderSearch Stats:\n");
80 fprintf(stderr,
"%d files tracked.\n", (
int)FileInfo.size());
81 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
82 for (
unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
83 NumOnceOnlyFiles += FileInfo[i].isImport;
84 if (MaxNumIncludes < FileInfo[i].NumIncludes)
85 MaxNumIncludes = FileInfo[i].NumIncludes;
86 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
88 fprintf(stderr,
" %d #import/#pragma once files.\n", NumOnceOnlyFiles);
89 fprintf(stderr,
" %d included exactly once.\n", NumSingleIncludedFiles);
90 fprintf(stderr,
" %d max times a file is included.\n", MaxNumIncludes);
92 fprintf(stderr,
" %d #include/#include_next/#import.\n", NumIncluded);
93 fprintf(stderr,
" %d #includes skipped due to" 94 " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
96 fprintf(stderr,
"%d framework lookups.\n", NumFrameworkLookups);
97 fprintf(stderr,
"%d subframework lookups.\n", NumSubFrameworkLookups);
105 if (!HeaderMaps.empty()) {
106 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
109 if (HeaderMaps[i].first == FE)
110 return HeaderMaps[i].second.get();
114 HeaderMaps.emplace_back(FE, std::move(HM));
115 return HeaderMaps.back().second.get();
124 for (
auto &HM : HeaderMaps)
125 Names.push_back(HM.first->getName());
137 auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
138 if (i != HSOpts->PrebuiltModuleFiles.end())
141 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
146 for (
const std::string &Dir : HSOpts->PrebuiltModulePaths) {
148 llvm::sys::fs::make_absolute(Result);
149 llvm::sys::path::append(Result, ModuleName +
".pcm");
151 return Result.str().str();
157 StringRef ModuleMapPath) {
164 llvm::sys::fs::make_absolute(Result);
166 if (HSOpts->DisableModuleHash) {
167 llvm::sys::path::append(Result, ModuleName +
".pcm");
176 std::string
Parent = llvm::sys::path::parent_path(ModuleMapPath);
183 auto FileName = llvm::sys::path::filename(ModuleMapPath);
185 llvm::hash_code Hash =
189 llvm::APInt(64,
size_t(Hash)).toStringUnsigned(HashStr, 36);
190 llvm::sys::path::append(Result, ModuleName +
"-" + HashStr +
".pcm");
192 return Result.str().str();
196 bool AllowExtraModuleMapSearch) {
199 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
202 StringRef SearchName = ModuleName;
203 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
213 if (!Module && SearchName.consume_back(
"_Private"))
214 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
215 if (!Module && SearchName.consume_back(
"Private"))
216 Module =
lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
221 bool AllowExtraModuleMapSearch) {
226 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
227 if (SearchDirs[Idx].isFramework()) {
232 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
233 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
238 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
247 if (!SearchDirs[Idx].isNormalDir())
250 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
253 false) == LMM_NewlyLoaded) {
264 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
265 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
267 false) == LMM_NewlyLoaded){
276 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
281 if (AllowExtraModuleMapSearch)
282 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
301 return getDir()->getName();
303 return getFrameworkDir()->getName();
304 assert(isHeaderMap() &&
"Unknown DirectoryLookup");
305 return getHeaderMap()->getFileName();
308 const FileEntry *HeaderSearch::getFileAndSuggestModule(
310 bool IsSystemHeaderDir,
Module *RequestingModule,
319 if (!findUsableModuleForHeader(File, Dir ? Dir : File->
getDir(),
320 RequestingModule, SuggestedModule,
337 bool &InUserSpecifiedSystemFramework,
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);
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)
const {
470 size_t SlashPos =
Filename.find(
'/');
471 if (SlashPos == StringRef::npos)
return nullptr;
475 HeaderSearch::FrameworkCacheEntry &CacheEntry =
479 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
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/";
498 if (!CacheEntry.Directory) {
503 if (!Dir)
return nullptr;
507 CacheEntry.Directory = getFrameworkDir();
513 SystemFrameworkMarker +=
".system_framework";
514 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
515 CacheEntry.IsUserSpecifiedSystemFramework =
true;
521 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
524 RelativePath->clear();
529 unsigned OrigSize = FrameworkName.size();
531 FrameworkName +=
"Headers/";
536 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
544 const char *Private =
"Private";
545 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
546 Private+strlen(Private));
548 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
549 Private+strlen(Private));
551 FE = FileMgr.
getFile(FrameworkName, !SuggestedModule);
558 bool FoundFramework =
false;
567 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
568 FoundFramework =
true;
573 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
574 if (FrameworkPath.empty())
579 if (FoundFramework) {
580 if (!HS.findUsableModuleForFrameworkHeader(
581 FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
584 if (!HS.findUsableModuleForHeader(FE, getDir(), RequestingModule,
585 SuggestedModule, IsSystem))
606 if (MSFE && FE != MSFE) {
607 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
613 static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
614 assert(!Str.empty());
615 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
616 std::copy(Str.begin(), Str.end(), CopyStr);
617 CopyStr[Str.size()] =
'\0';
624 path::const_iterator I = path::begin(Path);
625 path::const_iterator E = path::end(Path);
626 IsPrivateHeader =
false;
640 if (I->endswith(
".framework")) {
641 FrameworkName.append(I->begin(), I->end());
644 if (*I ==
"PrivateHeaders") {
646 IsPrivateHeader =
true;
651 return !FrameworkName.empty() && FoundComp >= 2;
656 StringRef Includer, StringRef IncludeFilename,
657 const FileEntry *IncludeFE,
bool isAngled =
false,
658 bool FoundByHeaderMap =
false) {
659 bool IsIncluderPrivateHeader =
false;
663 bool IsIncludeePrivateHeader =
false;
665 IncludeFE->
getName(), IsIncludeePrivateHeader, ToFramework);
667 if (!isAngled && !FoundByHeaderMap) {
669 if (IsIncludeeInFramework) {
670 NewInclude += StringRef(ToFramework).drop_back(10);
673 NewInclude += IncludeFilename;
675 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
683 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
684 IsIncludeePrivateHeader && FromFramework == ToFramework)
685 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
697 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
700 bool *IsMapped,
bool SkipCache,
bool BuildSystemModule) {
708 if (llvm::sys::path::is_absolute(Filename)) {
712 if (FromDir)
return nullptr;
717 RelativePath->clear();
718 RelativePath->append(Filename.begin(), Filename.end());
721 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
723 RequestingModule, SuggestedModule);
735 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
738 for (
const auto &IncluderAndDir : Includers) {
739 const FileEntry *Includer = IncluderAndDir.first;
743 TmpDir = IncluderAndDir.second->getName();
744 TmpDir.push_back(
'/');
745 TmpDir.append(Filename.begin(), Filename.end());
754 bool IncluderIsSystemHeader =
757 if (
const FileEntry *FE = getFileAndSuggestModule(
758 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
759 RequestingModule, SuggestedModule)) {
761 assert(First &&
"only first includer can have no file");
772 unsigned DirInfo = FromHFI.
DirInfo;
782 StringRef SearchPathRef(IncluderAndDir.second->getName());
784 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
787 RelativePath->clear();
788 RelativePath->append(Filename.begin(), Filename.end());
792 IncluderAndDir.second->getName(),
Filename,
800 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
804 if (SuggestedModule) {
805 MSSuggestedModule = *SuggestedModule;
818 unsigned i = isAngled ? AngledDirIdx : 0;
823 i = FromDir-&SearchDirs[0];
829 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
834 if (!SkipCache && CacheLookup.StartIdx == i+1) {
836 i = CacheLookup.HitIdx;
837 if (CacheLookup.MappedName) {
838 Filename = CacheLookup.MappedName;
846 CacheLookup.reset(i+1);
852 for (; i != SearchDirs.size(); ++i) {
853 bool InUserSpecifiedSystemFramework =
false;
854 bool HasBeenMapped =
false;
855 const FileEntry *FE = SearchDirs[i].LookupFile(
856 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
857 SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
860 CacheLookup.MappedName =
861 copyString(Filename, LookupFileCache.getAllocator());
867 CurDir = &SearchDirs[i];
881 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
882 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
892 size_t SlashPos = Filename.find(
'/');
893 if (SlashPos != StringRef::npos) {
902 *SuggestedModule = MSSuggestedModule;
906 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
907 if (!Includers.empty())
909 Includers.front().second->getName(),
Filename,
910 FE, isAngled, FoundByHeaderMap);
913 CacheLookup.HitIdx = i;
921 if (!Includers.empty() && Includers.front().first && !isAngled &&
922 Filename.find(
'/') == StringRef::npos) {
926 ScratchFilename += IncludingHFI.
Framework;
927 ScratchFilename +=
'/';
931 LookupFile(ScratchFilename, IncludeLoc,
true, FromDir,
932 CurDir, Includers.front(), SearchPath, RelativePath,
933 RequestingModule, SuggestedModule, IsMapped);
937 *SuggestedModule = MSSuggestedModule;
941 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
942 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
950 *SuggestedModule = MSSuggestedModule;
955 CacheLookup.HitIdx = SearchDirs.size();
971 assert(ContextFileEnt &&
"No context file?");
975 size_t SlashPos = Filename.find(
'/');
976 if (SlashPos == StringRef::npos)
return nullptr;
979 StringRef ContextName = ContextFileEnt->
getName();
982 const unsigned DotFrameworkLen = 10;
983 auto FrameworkPos = ContextName.find(
".framework");
984 if (FrameworkPos == StringRef::npos ||
985 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
986 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
991 DotFrameworkLen + 1);
994 FrameworkName +=
"Frameworks/";
995 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
996 FrameworkName +=
".framework/";
999 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1000 FrameworkCacheEntry())).first;
1003 if (CacheLookup.second.Directory &&
1004 CacheLookup.first().size() == FrameworkName.size() &&
1005 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1006 CacheLookup.first().size()) != 0)
1010 if (!CacheLookup.second.Directory) {
1011 ++NumSubFrameworkLookups;
1015 if (!Dir)
return nullptr;
1019 CacheLookup.second.Directory = Dir;
1025 RelativePath->clear();
1026 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1031 HeadersFilename +=
"Headers/";
1033 SearchPath->clear();
1035 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1038 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1039 if (!(FE = FileMgr.getFile(HeadersFilename,
true))) {
1041 HeadersFilename = FrameworkName;
1042 HeadersFilename +=
"PrivateHeaders/";
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)))
1062 FrameworkName.pop_back();
1063 if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
1064 SuggestedModule,
false))
1078 assert(OtherHFI.
External &&
"expected to merge external HFI");
1102 if (FE->
getUID() >= FileInfo.size())
1103 FileInfo.resize(FE->
getUID() + 1);
1107 if (ExternalSource && !HFI->
Resolved) {
1109 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1111 HFI = &FileInfo[FE->
getUID()];
1112 if (ExternalHFI.External)
1125 bool WantExternal)
const {
1129 if (ExternalSource) {
1130 if (FE->
getUID() >= FileInfo.size()) {
1133 FileInfo.resize(FE->
getUID() + 1);
1136 HFI = &FileInfo[FE->
getUID()];
1141 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1143 HFI = &FileInfo[FE->
getUID()];
1144 if (ExternalHFI.External)
1147 }
else if (FE->
getUID() >= FileInfo.size()) {
1150 HFI = &FileInfo[FE->
getUID()];
1162 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1163 HFI->ControllingMacroID;
1169 bool isCompilingModuleHeader) {
1173 if (!isCompilingModuleHeader) {
1174 if (!isModularHeader)
1177 if (HFI && HFI->isModuleHeader)
1182 HFI.isModuleHeader |= isModularHeader;
1183 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1188 bool ModulesEnabled,
Module *M) {
1196 auto TryEnterImported = [&]() ->
bool {
1197 if (!ModulesEnabled)
1200 ModMap.resolveHeaderDirectives(File);
1218 bool TryEnterHdr =
false;
1220 TryEnterHdr = File->
getDir() == ModMap.getBuiltinDir() &&
1222 llvm::sys::path::filename(File->
getName()));
1246 if (FileInfo.
isImport && !TryEnterImported())
1259 ++NumMultiIncludeFileOptzn;
1271 return SearchDirs.capacity()
1272 + llvm::capacity_in_bytes(FileInfo)
1273 + llvm::capacity_in_bytes(HeaderMaps)
1274 + LookupFileCache.getAllocator().getTotalMemory()
1275 + FrameworkMap.getAllocator().getTotalMemory();
1279 return FrameworkNames.insert(Framework).first->first();
1285 if (!HSOpts->ImplicitModuleMaps)
1290 StringRef DirName = FileName;
1293 DirName = llvm::sys::path::parent_path(DirName);
1294 if (DirName.empty())
1304 llvm::sys::path::extension(Dir->
getName()) ==
1306 case LMM_NewlyLoaded:
1307 case LMM_AlreadyLoaded:
1310 for (
unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1311 DirectoryHasModuleMap[FixUpDirectories[I]] =
true;
1314 case LMM_NoDirectory:
1315 case LMM_InvalidModuleMap:
1325 FixUpDirectories.push_back(Dir);
1331 bool AllowTextual)
const {
1332 if (ExternalSource) {
1337 return ModMap.findModuleForHeader(File, AllowTextual);
1341 Module *RequestingModule,
1345 if (SuggestedModule)
1362 bool HeaderSearch::findUsableModuleForHeader(
1368 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1373 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1374 const FileEntry *File, StringRef FrameworkName,
Module *RequestingModule,
1384 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1388 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1394 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1403 if (Filename ==
"module.map")
1404 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1405 else if (Filename ==
"module.modulemap")
1406 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1409 return FileMgr.
getFile(PrivateFilename);
1414 StringRef OriginalModuleMapFile) {
1419 Dir = FileMgr.getDirectory(
".");
1421 if (!OriginalModuleMapFile.empty()) {
1424 Dir = FileMgr.getDirectory(
1425 llvm::sys::path::parent_path(OriginalModuleMapFile));
1427 auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
1428 Dir = FakeFile->getDir();
1434 StringRef DirName(Dir->
getName());
1435 if (llvm::sys::path::filename(DirName) ==
"Modules") {
1436 DirName = llvm::sys::path::parent_path(DirName);
1437 if (DirName.endswith(
".framework"))
1438 Dir = FileMgr.getDirectory(DirName);
1441 assert(Dir &&
"parent must exist");
1445 switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1446 case LMM_AlreadyLoaded:
1447 case LMM_NewlyLoaded:
1449 case LMM_NoDirectory:
1450 case LMM_InvalidModuleMap:
1453 llvm_unreachable(
"Unknown load module map result");
1456 HeaderSearch::LoadModuleMapResult
1457 HeaderSearch::loadModuleMapFileImpl(
const FileEntry *File,
bool IsSystem,
1460 assert(File &&
"expected FileEntry");
1464 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File,
true));
1465 if (!AddResult.second)
1466 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1468 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1469 LoadedModuleMaps[File] =
false;
1470 return LMM_InvalidModuleMap;
1475 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1476 LoadedModuleMaps[File] =
false;
1477 return LMM_InvalidModuleMap;
1482 return LMM_NewlyLoaded;
1487 if (!HSOpts->ImplicitModuleMaps)
1493 llvm::sys::path::append(ModuleMapFileName,
"Modules");
1494 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1495 if (
const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
1499 ModuleMapFileName = Dir->
getName();
1500 llvm::sys::path::append(ModuleMapFileName,
"module.map");
1501 return FileMgr.getFile(ModuleMapFileName);
1504 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1512 case LMM_InvalidModuleMap:
1514 if (HSOpts->ImplicitModuleMaps)
1515 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1518 case LMM_AlreadyLoaded:
1519 case LMM_NoDirectory:
1522 case LMM_NewlyLoaded:
1526 return ModMap.findModule(Name);
1529 HeaderSearch::LoadModuleMapResult
1535 return LMM_NoDirectory;
1538 HeaderSearch::LoadModuleMapResult
1541 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1542 if (KnownDir != DirectoryHasModuleMap.end())
1543 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1546 LoadModuleMapResult
Result =
1547 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1551 if (Result == LMM_NewlyLoaded)
1552 DirectoryHasModuleMap[Dir] =
true;
1553 else if (Result == LMM_InvalidModuleMap)
1554 DirectoryHasModuleMap[Dir] =
false;
1557 return LMM_InvalidModuleMap;
1563 if (HSOpts->ImplicitModuleMaps) {
1565 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1566 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1567 if (SearchDirs[Idx].isFramework()) {
1570 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->
getName(),
1574 llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
1575 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1577 Dir != DirEnd && !EC; Dir.increment(EC)) {
1578 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
1582 FileMgr.getDirectory(Dir->path());
1587 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir,
1594 if (SearchDirs[Idx].isHeaderMap())
1603 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1609 MEnd = ModMap.module_end();
1611 Modules.push_back(M->getValue());
1616 if (!HSOpts->ImplicitModuleMaps)
1620 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1622 if (!SearchDirs[Idx].isNormalDir()) {
1628 SearchDirs[Idx].isSystemHeaderDirectory(),
1629 SearchDirs[Idx].isFramework());
1633 void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
1634 assert(HSOpts->ImplicitModuleMaps &&
1635 "Should not be loading subdirectory module maps");
1642 FileMgr.makeAbsolutePath(Dir);
1644 llvm::sys::path::native(Dir, DirNative);
1645 llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
1646 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1647 Dir != DirEnd && !EC; Dir.increment(EC)) {
1648 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
1667 llvm::StringRef File, llvm::StringRef WorkingDir,
bool *IsSystem) {
1670 unsigned BestPrefixLength = 0;
1671 unsigned BestSearchDir;
1673 for (
unsigned I = 0; I != SearchDirs.size(); ++I) {
1675 if (!SearchDirs[I].isNormalDir())
1678 StringRef Dir = SearchDirs[I].getDir()->
getName();
1680 if (!WorkingDir.empty() && !path::is_absolute(Dir)) {
1681 fs::make_absolute(WorkingDir, DirPath);
1682 path::remove_dots(DirPath,
true);
1685 for (
auto NI = path::begin(File), NE = path::end(File),
1686 DI = path::begin(Dir), DE = path::end(Dir);
1689 while (NI != NE && *NI ==
".")
1695 while (DI != DE && *DI ==
".")
1700 unsigned PrefixLength = NI - path::begin(File);
1701 if (PrefixLength > BestPrefixLength) {
1702 BestPrefixLength = PrefixLength;
1714 *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx :
false;
1715 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.
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
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.
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.
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