26#include "llvm/ADT/APInt.h"
27#include "llvm/ADT/STLExtras.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"
39#include "llvm/Support/xxhash.h"
46#include <system_error>
51#define DEBUG_TYPE "file-search"
55 NumMultiIncludeFileOptzn,
56 "Number of #includes skipped due to the multi-include optimization.");
59 "Number of subframework lookups.");
73 if (ControllingMacro && ControllingMacro->
isOutOfDate()) {
74 assert(
External &&
"We must have an external source if we have a "
75 "controlling macro that is out of date.");
76 External->updateOutOfDateIdentifier(*ControllingMacro);
78 return ControllingMacro;
87 : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()),
88 FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts,
Target, *this) {}
91 llvm::errs() <<
"\n*** HeaderSearch Stats:\n"
92 << FileInfo.size() <<
" files tracked.\n";
93 unsigned NumOnceOnlyFiles = 0;
94 for (
unsigned i = 0, e = FileInfo.size(); i != e; ++i)
95 NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
96 llvm::errs() <<
" " << NumOnceOnlyFiles <<
" #import/#pragma once files.\n";
98 llvm::errs() <<
" " << NumIncluded <<
" #include/#include_next/#import.\n"
99 <<
" " << NumMultiIncludeFileOptzn
100 <<
" #includes skipped due to the multi-include optimization.\n";
102 llvm::errs() << NumFrameworkLookups <<
" framework lookups.\n"
103 << NumSubFrameworkLookups <<
" subframework lookups.\n";
107 std::vector<DirectoryLookup> dirs,
unsigned int angledDirIdx,
108 unsigned int systemDirIdx,
109 llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
110 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
111 "Directory indices are unordered");
112 SearchDirs = std::move(dirs);
113 SearchDirsUsage.assign(SearchDirs.size(),
false);
114 AngledDirIdx = angledDirIdx;
115 SystemDirIdx = systemDirIdx;
116 SearchDirToHSEntry = std::move(searchDirToHSEntry);
118 indexInitialHeaderMaps();
122 unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
123 SearchDirs.insert(SearchDirs.begin() + idx, dir);
124 SearchDirsUsage.insert(SearchDirsUsage.begin() + idx,
false);
131 std::vector<bool> UserEntryUsage(HSOpts.UserEntries.size());
132 for (
unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
134 if (SearchDirsUsage[I]) {
135 auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
137 if (UserEntryIdxIt != SearchDirToHSEntry.end())
138 UserEntryUsage[UserEntryIdxIt->second] =
true;
141 return UserEntryUsage;
145 std::vector<bool> VFSUsage;
149 llvm::vfs::FileSystem &RootFS = FileMgr.getVirtualFileSystem();
153 RootFS.visit([&](llvm::vfs::FileSystem &FS) {
154 if (
auto *RFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&FS)) {
158 if (!RFS->getOverlayFileDir().empty()) {
159 VFSUsage.push_back(RFS->hasBeenUsed());
160 RFS->clearHasBeenUsed();
165 "A different number of RedirectingFileSystem's were present than "
166 "-ivfsoverlay options passed to Clang!");
168 std::reverse(VFSUsage.begin(), VFSUsage.end());
177 if (!HeaderMaps.empty()) {
178 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
181 if (HeaderMaps[i].first == FE)
182 return HeaderMaps[i].second.get();
186 HeaderMaps.emplace_back(FE, std::move(HM));
187 return HeaderMaps.back().second.get();
196 for (
auto &HM : HeaderMaps)
197 Names.push_back(std::string(HM.first.getName()));
213 auto i(HSOpts.PrebuiltModuleFiles.find(ModuleName));
214 if (i != HSOpts.PrebuiltModuleFiles.end())
217 if (FileMapOnly || HSOpts.PrebuiltModulePaths.empty())
222 for (
const std::string &Dir : HSOpts.PrebuiltModulePaths) {
224 FileMgr.makeAbsolutePath(
Result);
225 if (ModuleName.contains(
':'))
229 llvm::sys::path::append(
Result, ModuleName.split(
':').first +
"-" +
230 ModuleName.split(
':').second +
233 llvm::sys::path::append(
Result, ModuleName +
".pcm");
235 return std::string(
Result);
245 StringRef ModuleMapPath =
ModuleMap->getName();
246 StringRef ContextHash = HSOpts.DisableModuleHash ?
"" :
getContextHash();
247 for (
const std::string &Dir : HSOpts.PrebuiltModulePaths) {
249 FileMgr.makeAbsolutePath(CachePath);
250 llvm::sys::path::append(CachePath, ContextHash);
252 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
260 StringRef ModuleMapPath) {
261 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
265std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
266 StringRef ModuleMapPath,
267 StringRef CachePath) {
270 if (CachePath.empty())
276 llvm::sys::path::append(Result, ModuleName +
".pcm");
285 SmallString<128> CanonicalPath(ModuleMapPath);
286 if (
getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
289 auto Hash = llvm::xxh3_64bits(CanonicalPath.str().lower());
291 SmallString<128> HashStr;
292 llvm::APInt(64, Hash).toStringUnsigned(HashStr, 36);
293 llvm::sys::path::append(
Result, ModuleName +
"-" + HashStr +
".pcm");
295 return Result.str().str();
300 bool AllowExtraModuleMapSearch) {
303 if (
Module || !AllowSearch || !HSOpts.ImplicitModuleMaps)
306 StringRef SearchName = ModuleName;
308 AllowExtraModuleMapSearch);
318 if (!
Module && SearchName.consume_back(
"_Private"))
320 AllowExtraModuleMapSearch);
321 if (!
Module && SearchName.consume_back(
"Private"))
323 AllowExtraModuleMapSearch);
329 bool AllowExtraModuleMapSearch) {
335 if (Dir.isFramework()) {
340 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
341 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
342 if (
auto FrameworkDir =
343 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
345 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem,
355 if (!Dir.isNormalDir())
358 bool IsSystem = Dir.isSystemHeaderDirectory();
361 DirectoryEntryRef NormalDir = *Dir.getDirRef();
363 if (parseModuleMapFile(NormalDir, IsSystem,
true,
364 false) == MMR_NewlyProcessed) {
367 Module = ModMap.findOrLoadModule(ModuleName);
374 SmallString<128> NestedModuleMapDirName;
375 NestedModuleMapDirName = Dir.getDirRef()->getName();
376 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
377 if (parseModuleMapFile(NestedModuleMapDirName, IsSystem,
379 false) == MMR_NewlyProcessed) {
381 Module = ModMap.findOrLoadModule(ModuleName);
386 if (HSOpts.AllowModuleMapSubdirectorySearch) {
389 if (Dir.haveSearchedAllModuleMaps())
394 if (AllowExtraModuleMapSearch)
395 loadSubdirectoryModuleMaps(Dir);
398 Module = ModMap.findOrLoadModule(ModuleName);
407void HeaderSearch::indexInitialHeaderMaps() {
408 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
411 for (
unsigned i = 0; i != SearchDirs.size(); ++i) {
412 auto &Dir = SearchDirs[i];
417 if (!Dir.isHeaderMap()) {
418 SearchDirHeaderMapIndex = std::move(Index);
419 FirstNonHeaderMapSearchDirIdx = i;
424 auto Callback = [&](StringRef Filename) {
425 Index.try_emplace(Filename.lower(), i);
427 Dir.getHeaderMap()->forEachKey(Callback);
442 assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
448 bool IsSystemHeaderDir,
Module *RequestingModule,
450 bool CacheFailures ) {
457 std::error_code EC = llvm::errorToErrorCode(
File.takeError());
458 if (EC != llvm::errc::no_such_file_or_directory &&
459 EC != llvm::errc::invalid_argument &&
460 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
461 Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
468 if (!findUsableModuleForHeader(
469 *
File, Dir ? Dir :
File->getFileEntry().getDir(), RequestingModule,
470 SuggestedModule, IsSystemHeaderDir))
482 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound,
484 bool OpenFile)
const {
485 InUserSpecifiedSystemFramework =
false;
486 IsInHeaderMap =
false;
493 llvm::sys::path::append(TmpDir, Filename);
497 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
500 RelativePath->clear();
501 RelativePath->append(Filename.begin(), Filename.end());
504 return HS.getFileAndSuggestModule(
506 RequestingModule, SuggestedModule, OpenFile);
510 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
511 RequestingModule, SuggestedModule,
512 InUserSpecifiedSystemFramework, IsFrameworkFound);
514 assert(
isHeaderMap() &&
"Unknown directory lookup");
521 IsInHeaderMap =
true;
523 auto FixupSearchPathAndFindUsableModule =
526 StringRef SearchPathRef(
getName());
528 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
531 RelativePath->clear();
532 RelativePath->append(Filename.begin(), Filename.end());
534 if (!HS.findUsableModuleForHeader(
File,
File.getFileEntry().getDir(),
535 RequestingModule, SuggestedModule,
545 if (llvm::sys::path::is_relative(Dest)) {
546 MappedName.append(Dest.begin(), Dest.end());
547 Filename = StringRef(MappedName.begin(), MappedName.size());
552 return FixupSearchPathAndFindUsableModule(*Res);
572 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
573 "Not a framework directory");
589 auto TopFrameworkDir =
FileMgr.getOptionalDirectoryRef(DirName);
592 DirName =
FileMgr.getCanonicalName(*TopFrameworkDir);
595 DirName = llvm::sys::path::parent_path(DirName);
600 auto Dir =
FileMgr.getOptionalDirectoryRef(DirName);
606 if (llvm::sys::path::extension(DirName) ==
".framework") {
607 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
608 TopFrameworkDir = *Dir;
612 return TopFrameworkDir;
616 bool HasSuggestedModule) {
617 return HasSuggestedModule ||
627 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
631 size_t SlashPos = Filename.find(
'/');
632 if (SlashPos == StringRef::npos)
637 FrameworkCacheEntry &CacheEntry =
647 SmallString<1024> FrameworkName;
649 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
650 FrameworkName.push_back(
'/');
653 StringRef ModuleName(Filename.begin(), SlashPos);
654 FrameworkName += ModuleName;
657 FrameworkName +=
".framework/";
661 ++NumFrameworkLookups;
675 SmallString<1024> SystemFrameworkMarker(FrameworkName);
676 SystemFrameworkMarker +=
".system_framework";
687 RelativePath->clear();
688 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
692 unsigned OrigSize = FrameworkName.size();
694 FrameworkName +=
"Headers/";
699 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
702 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
708 const char *
Private =
"Private";
709 FrameworkName.insert(FrameworkName.begin()+OrigSize,
Private,
712 SearchPath->insert(SearchPath->begin()+OrigSize,
Private,
722 StringRef FrameworkPath =
File->getDir().getName();
723 bool FoundFramework =
false;
732 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
733 FoundFramework =
true;
738 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
739 if (FrameworkPath.empty())
744 if (FoundFramework) {
745 if (!HS.findUsableModuleForFrameworkHeader(*
File, FrameworkPath,
747 SuggestedModule, IsSystem))
750 if (!HS.findUsableModuleForHeader(*
File,
getDir(), RequestingModule,
751 SuggestedModule, IsSystem))
760void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
763 CacheLookup.HitIt = HitIt;
764 noteLookupUsage(HitIt.Idx, Loc);
767void HeaderSearch::noteLookupUsage(
unsigned HitIdx,
SourceLocation Loc) {
768 SearchDirsUsage[HitIdx] =
true;
770 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
771 if (UserEntryIdxIt != SearchDirToHSEntry.end())
772 Diags.Report(Loc, diag::remark_pp_search_path_usage)
773 << HSOpts.UserEntries[UserEntryIdxIt->second].Path;
791 if (MSFE && FE != *MSFE) {
792 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
798static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
799 assert(!Str.empty());
800 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
801 std::copy(Str.begin(), Str.end(), CopyStr);
802 CopyStr[Str.size()] =
'\0';
809 using namespace llvm::sys;
810 path::const_iterator I = path::begin(Path);
811 path::const_iterator E = path::end(Path);
812 IsPrivateHeader =
false;
824 if (*I ==
"Headers") {
826 }
else if (*I ==
"PrivateHeaders") {
828 IsPrivateHeader =
true;
829 }
else if (I->ends_with(
".framework")) {
830 StringRef Name = I->drop_back(10);
832 FrameworkName.clear();
833 FrameworkName.append(Name.begin(), Name.end());
834 IncludeSpelling.clear();
835 IncludeSpelling.append(Name.begin(), Name.end());
837 }
else if (FoundComp >= 2) {
838 IncludeSpelling.push_back(
'/');
839 IncludeSpelling.append(I->begin(), I->end());
844 return !FrameworkName.empty() && FoundComp >= 2;
849 StringRef Includer, StringRef IncludeFilename,
851 bool FoundByHeaderMap =
false) {
852 bool IsIncluderPrivateHeader =
false;
856 FromIncludeSpelling))
858 bool IsIncludeePrivateHeader =
false;
859 bool IsIncludeeInFramework =
861 ToFramework, ToIncludeSpelling);
863 if (!isAngled && !FoundByHeaderMap) {
865 if (IsIncludeeInFramework) {
866 NewInclude += ToIncludeSpelling;
869 NewInclude += IncludeFilename;
872 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
880 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
881 IsIncludeePrivateHeader && FromFramework == ToFramework)
882 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
889 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
890 bool isAngled,
int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt) {
892 if (Diags.isIgnored(diag::warn_header_shadowing, IncludeLoc) ||
896 if (MainLoopIt && MainLoopIt->isSystemHeaderDirectory())
899 DiagnosedShadowing =
true;
903 for (
size_t i = IncluderLoopIndex + 1; i < Includers.size(); ++i) {
904 const auto &IncluderAndDir = Includers[i];
906 llvm::sys::path::append(TmpDir, Filename);
908 if (&
File->getFileEntry() == *FE)
910 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
911 << Filename << (*FE).getDir().getName()
912 << IncluderAndDir.second.getName();
915 llvm::errorToErrorCode(
File.takeError());
921 ConstSearchDirIterator It =
924 It = std::next(MainLoopIt);
925 }
else if (FromDir) {
933 llvm::sys::path::append(TmpPath, Filename);
935 if (&
File->getFileEntry() == *FE)
937 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
938 << Filename << (*FE).getDir().getName() << It->getName();
941 llvm::errorToErrorCode(
File.takeError());
953 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
954 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
957 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
958 bool BuildSystemModule,
bool OpenFile,
bool CacheFailures) {
959 ConstSearchDirIterator CurDirLocal =
nullptr;
960 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
965 if (IsFrameworkFound)
966 *IsFrameworkFound =
false;
972 if (llvm::sys::path::is_absolute(Filename)) {
982 RelativePath->clear();
983 RelativePath->append(Filename.begin(), Filename.end());
986 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
988 RequestingModule, SuggestedModule, OpenFile,
995 bool DiagnosedShadowing =
false;
1002 if (!Includers.empty() && !isAngled) {
1005 for (
const auto &IncluderAndDir : Includers) {
1009 TmpDir = IncluderAndDir.second.getName();
1010 llvm::sys::path::append(TmpDir, Filename);
1019 bool IncluderIsSystemHeader = [&]() {
1021 return BuildSystemModule;
1023 assert(HFI &&
"includer without file info");
1027 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
1028 RequestingModule, SuggestedModule)) {
1030 FromDir, Includers, isAngled,
1031 &IncluderAndDir - Includers.begin(),
nullptr);
1033 assert(
First &&
"only first includer can have no file");
1044 assert(FromHFI &&
"includer without file info");
1045 unsigned DirInfo = FromHFI->
DirInfo;
1051 StringRef SearchPathRef(IncluderAndDir.second.getName());
1052 SearchPath->clear();
1053 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
1056 RelativePath->clear();
1057 RelativePath->append(Filename.begin(), Filename.end());
1061 IncluderAndDir.second.getName(), Filename,
1069 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1073 if (SuggestedModule) {
1074 MSSuggestedModule = *SuggestedModule;
1087 ConstSearchDirIterator It =
1099 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1101 ConstSearchDirIterator NextIt = std::next(It);
1104 if (CacheLookup.StartIt == NextIt &&
1105 CacheLookup.RequestingModule == RequestingModule) {
1107 if (CacheLookup.HitIt)
1108 It = CacheLookup.HitIt;
1109 if (CacheLookup.MappedName) {
1110 Filename = CacheLookup.MappedName;
1118 CacheLookup.reset(RequestingModule, NextIt);
1124 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1125 if (Iter == SearchDirHeaderMapIndex.end())
1134 CacheLookup.reset(RequestingModule, NextIt);
1141 bool InUserSpecifiedSystemFramework =
false;
1142 bool IsInHeaderMap =
false;
1143 bool IsFrameworkFoundInDir =
false;
1145 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1146 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1147 IsInHeaderMap, MappedName, OpenFile);
1148 if (!MappedName.empty()) {
1149 assert(IsInHeaderMap &&
"MappedName should come from a header map");
1150 CacheLookup.MappedName =
1151 copyString(MappedName, LookupFileCache.getAllocator());
1157 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap &&
File));
1158 if (IsFrameworkFound)
1162 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1167 FromDir, Includers, isAngled, -1, It);
1171 IncludeNames[*
File] = Filename;
1175 HFI.
DirInfo = CurDir->getDirCharacteristic();
1185 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1186 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1194 if (SuggestedModule)
1195 *SuggestedModule = MSSuggestedModule;
1199 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
1200 if (!Includers.empty())
1202 Includers.front().second.getName(), Filename,
1203 *
File, isAngled, FoundByHeaderMap);
1206 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1211 if (SuggestedModule)
1212 *SuggestedModule = MSSuggestedModule;
1218 return std::nullopt;
1232 size_t SlashPos = Filename.find(
'/');
1233 if (SlashPos == StringRef::npos)
1234 return std::nullopt;
1237 StringRef ContextName = ContextFileEnt.
getName();
1240 const unsigned DotFrameworkLen = 10;
1241 auto FrameworkPos = ContextName.find(
".framework");
1242 if (FrameworkPos == StringRef::npos ||
1243 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
1244 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1245 return std::nullopt;
1249 DotFrameworkLen + 1);
1252 FrameworkName +=
"Frameworks/";
1253 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1254 FrameworkName +=
".framework/";
1257 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1261 if (CacheLookup.second.Directory &&
1262 CacheLookup.first().size() == FrameworkName.size() &&
1263 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1264 CacheLookup.first().size()) != 0)
1265 return std::nullopt;
1268 if (!CacheLookup.second.Directory) {
1269 ++NumSubFrameworkLookups;
1272 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1274 return std::nullopt;
1278 CacheLookup.second.Directory = Dir;
1283 RelativePath->clear();
1284 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1289 HeadersFilename +=
"Headers/";
1291 SearchPath->clear();
1293 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1296 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1297 auto File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1300 HeadersFilename = FrameworkName;
1301 HeadersFilename +=
"PrivateHeaders/";
1303 SearchPath->clear();
1305 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1308 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1309 File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1312 return std::nullopt;
1317 assert(ContextHFI &&
"context file without file info");
1320 unsigned DirInfo = ContextHFI->
DirInfo;
1323 FrameworkName.pop_back();
1324 if (!findUsableModuleForFrameworkHeader(*
File, FrameworkName,
1325 RequestingModule, SuggestedModule,
1327 return std::nullopt;
1346 bool isModuleHeader,
1347 bool isTextualModuleHeader) {
1364 assert(OtherHFI.
External &&
"expected to merge external HFI");
1380 if (FE.
getUID() >= FileInfo.size())
1381 FileInfo.resize(FE.
getUID() + 1);
1385 if (ExternalSource && !HFI->
Resolved) {
1386 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1387 if (ExternalHFI.IsValid) {
1389 if (ExternalHFI.External)
1403 if (ExternalSource) {
1404 if (FE.
getUID() >= FileInfo.size())
1405 FileInfo.resize(FE.
getUID() + 1);
1407 HFI = &FileInfo[FE.
getUID()];
1410 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1411 if (ExternalHFI.IsValid) {
1413 if (ExternalHFI.External)
1417 }
else if (FE.
getUID() < FileInfo.size()) {
1418 HFI = &FileInfo[FE.
getUID()];
1423 return (HFI && HFI->
IsValid) ? HFI :
nullptr;
1429 if (FE.
getUID() < FileInfo.size()) {
1430 HFI = &FileInfo[FE.
getUID()];
1443 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1449 bool isCompilingModuleHeader) {
1451 if (!isCompilingModuleHeader) {
1460 HFI.mergeModuleMembership(
Role);
1461 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1466 bool ModulesEnabled,
Module *M,
1467 bool &IsFirstIncludeOfFile) {
1483 IsFirstIncludeOfFile =
false;
1486 auto MaybeReenterImportedFile = [&]() ->
bool {
1504 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1508 ModMap.resolveHeaderDirectives(
File);
1528 if (FileInfo.isTextualModuleHeader)
1531 if (FileInfo.isCompilingModuleHeader) {
1534 if (FileInfo.isModuleHeader) {
1539 if (ModMap.isBuiltinHeader(
File))
1548 if (FileInfo.getControllingMacro(ExternalLookup))
1568 FileInfo.isImport =
true;
1575 if (FileInfo.isPragmaOnce ||
1576 (FileInfo.isImport && !MaybeReenterImportedFile()))
1585 FileInfo.getControllingMacro(ExternalLookup)) {
1592 ++NumMultiIncludeFileOptzn;
1602 return SearchDirs.capacity()
1603 + llvm::capacity_in_bytes(FileInfo)
1604 + llvm::capacity_in_bytes(HeaderMaps)
1605 + LookupFileCache.getAllocator().getTotalMemory()
1606 + FrameworkMap.getAllocator().getTotalMemory();
1610 return &DL - &*SearchDirs.begin();
1614 return FrameworkNames.insert(Framework).first->first();
1618 auto It = IncludeNames.find(
File);
1619 if (It == IncludeNames.end())
1625 ModuleMapDirectoryState &MMState) {
1626 if (!MMState.ModuleMapFile)
1633 if (MMState.PrivateModuleMapFile)
1636 processModuleMapForIndex(*ParsedMM, Dir,
"", MMState);
1637 if (ParsedPrivateMM)
1638 processModuleMapForIndex(*ParsedPrivateMM, Dir,
"", MMState);
1641void HeaderSearch::addToModuleMapIndex(StringRef RelPath, StringRef ModuleName,
1642 StringRef PathPrefix,
1643 ModuleMapDirectoryState &MMState) {
1645 llvm::sys::path::append(RelFromRootPath, RelPath);
1646 llvm::sys::path::native(RelFromRootPath);
1647 MMState.HeaderToModules[RelFromRootPath].push_back(ModuleName);
1650void HeaderSearch::processExternModuleDeclForIndex(
1652 StringRef PathPrefix, ModuleMapDirectoryState &MMState) {
1653 StringRef FileNameRef = EMD.
Path;
1654 SmallString<128> ModuleMapFileName;
1655 if (llvm::sys::path::is_relative(FileNameRef)) {
1656 ModuleMapFileName = MMDir.
getName();
1657 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1658 FileNameRef = ModuleMapFileName;
1660 if (
auto EFile = FileMgr.getOptionalFileRef(FileNameRef)) {
1661 if (
auto *ExtMMF = ModMap.getParsedModuleMap(*EFile)) {
1664 SmallString<128> NewPrefix(PathPrefix);
1665 StringRef ExternDir = llvm::sys::path::parent_path(EMD.
Path);
1666 if (!ExternDir.empty()) {
1667 llvm::sys::path::append(NewPrefix, ExternDir);
1668 llvm::sys::path::native(NewPrefix);
1670 processModuleMapForIndex(*ExtMMF, EFile->getDir(), NewPrefix, MMState);
1676 StringRef ModuleName,
1678 StringRef PathPrefix,
1679 ModuleMapDirectoryState &MMState) {
1681 if (MD.
Id.front().first ==
"*")
1684 auto ProcessDecl = llvm::makeVisitor(
1685 [&](
const modulemap::HeaderDecl &HD) {
1687 MMState.UmbrellaHeaderModules.push_back(ModuleName);
1689 addToModuleMapIndex(HD.
Path, ModuleName, PathPrefix, MMState);
1692 [&](
const modulemap::UmbrellaDirDecl &UDD) {
1693 SmallString<128> FullPath(PathPrefix);
1694 llvm::sys::path::append(FullPath, UDD.Path);
1695 llvm::sys::path::native(FullPath);
1696 MMState.UmbrellaDirModules.push_back(
1697 std::make_pair(std::string(FullPath), ModuleName));
1699 [&](
const modulemap::ModuleDecl &SubMD) {
1700 processModuleDeclForIndex(SubMD, ModuleName, MMDir, PathPrefix,
1703 [&](
const modulemap::ExternModuleDecl &EMD) {
1704 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix, MMState);
1710 for (
const auto &Decl : MD.
Decls) {
1711 std::visit(ProcessDecl, Decl);
1717 StringRef PathPrefix,
1718 ModuleMapDirectoryState &MMState) {
1719 for (
const auto &Decl : MMF.
Decls) {
1720 std::visit(llvm::makeVisitor(
1721 [&](
const modulemap::ModuleDecl &MD) {
1722 processModuleDeclForIndex(MD, MD.
Id.front().first, MMDir,
1723 PathPrefix, MMState);
1725 [&](
const modulemap::ExternModuleDecl &EMD) {
1726 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix,
1736 if (!HSOpts.ImplicitModuleMaps)
1743 DirName = llvm::sys::path::parent_path(DirName);
1744 if (DirName.empty())
1748 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1754 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1758 parseModuleMapFile(*Dir, IsSystem,
true,
1760 auto DirState = DirectoryModuleMap.find(*Dir);
1761 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1764 if (!HSOpts.LazyLoadModuleMaps)
1767 auto &MMState = DirState->second;
1770 if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() &&
1771 MMState.UmbrellaHeaderModules.empty()) {
1772 buildModuleMapIndex(*Dir, MMState);
1778 StringRef RelativePath =
FileName.substr(DirName.size());
1780 while (!RelativePath.empty() &&
1781 llvm::sys::path::is_separator(RelativePath.front()))
1782 RelativePath = RelativePath.substr(1);
1784 llvm::sys::path::native(RelativePathNative);
1785 RelativePath = RelativePathNative;
1789 auto CachedMods = MMState.HeaderToModules.find(RelativePath);
1790 if (CachedMods != MMState.HeaderToModules.end()) {
1791 ModulesToLoad.append(CachedMods->second.begin(),
1792 CachedMods->second.end());
1796 for (
const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
1797 if (RelativePath.starts_with(UmbrellaDir.first) ||
1798 UmbrellaDir.first ==
".") {
1799 ModulesToLoad.push_back(UmbrellaDir.second);
1814 ModulesToLoad.append(MMState.UmbrellaHeaderModules.begin(),
1815 MMState.UmbrellaHeaderModules.end());
1818 bool LoadedAny =
false;
1819 for (StringRef ModName : ModulesToLoad) {
1820 if (ModMap.findOrLoadModule(ModName)) {
1829 }
while (CurDir != Root);
1835 bool AllowExcluded)
const {
1836 if (ExternalSource) {
1841 return ModMap.findModuleForHeader(
File, AllowTextual, AllowExcluded);
1846 if (ExternalSource) {
1851 return ModMap.findAllModulesForHeader(
File);
1856 if (ExternalSource) {
1861 return ModMap.findResolvedModulesForHeader(
File);
1878 if (SuggestedModule)
1888 if (SuggestedModule)
1896bool HeaderSearch::findUsableModuleForHeader(
1900 if (!HSOpts.LazyLoadModuleMaps) {
1906 ModuleMap::KnownHeader
Module =
1913 ModuleMap::KnownHeader
Module =
1921 Module = ModMap.findModuleForHeader(
File,
true);
1930bool HeaderSearch::findUsableModuleForFrameworkHeader(
1936 SmallVector<std::string, 4> SubmodulePath;
1939 assert(TopFrameworkDir &&
"Could not find the top-most framework dir");
1942 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1946 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework,
1953 ModuleMap::KnownHeader
Module =
1964 bool Diagnose =
true) {
1965 StringRef Filename = llvm::sys::path::filename(
File.getName());
1967 if (Filename ==
"module.map")
1968 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1969 else if (Filename ==
"module.modulemap")
1970 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1972 return std::nullopt;
1973 auto PMMFile =
FileMgr.getOptionalFileRef(PrivateFilename);
1975 if (Diagnose && Filename ==
"module.map")
1976 Diags.
Report(diag::warn_deprecated_module_dot_map)
1977 << PrivateFilename << 1
1978 <<
File.getDir().getName().ends_with(
".framework");
1984 bool ImplicitlyDiscovered,
1985 FileID ID,
unsigned *Offset,
1986 StringRef OriginalModuleMapFile) {
1991 Dir = FileMgr.getOptionalDirectoryRef(
".");
1993 if (!OriginalModuleMapFile.empty()) {
1996 Dir = FileMgr.getOptionalDirectoryRef(
1997 llvm::sys::path::parent_path(OriginalModuleMapFile));
1999 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
2000 Dir = FakeFile.getDir();
2003 Dir =
File.getDir();
2006 assert(Dir &&
"parent must exist");
2007 StringRef DirName(Dir->
getName());
2008 if (llvm::sys::path::filename(DirName) ==
"Modules") {
2009 DirName = llvm::sys::path::parent_path(DirName);
2010 if (DirName.ends_with(
".framework"))
2011 if (
auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
2015 assert(Dir &&
"parent must exist");
2019 assert(Dir &&
"module map home directory must exist");
2020 switch (parseAndLoadModuleMapFileImpl(
File, IsSystem, ImplicitlyDiscovered,
2023 case MMR_AlreadyProcessed:
2024 case MMR_NewlyProcessed:
2026 case MMR_NoDirectory:
2027 case MMR_InvalidModuleMap:
2030 llvm_unreachable(
"Unknown load module map result");
2033HeaderSearch::ModuleMapResult HeaderSearch::parseAndLoadModuleMapFileImpl(
2038 auto AddResult = LoadedModuleMaps.insert(std::make_pair(
File,
true));
2039 if (!AddResult.second)
2040 return AddResult.first->second ? MMR_AlreadyProcessed
2041 : MMR_InvalidModuleMap;
2045 LoadedModuleMaps[
File] =
false;
2046 return MMR_InvalidModuleMap;
2053 ImplicitlyDiscovered, Dir)) {
2054 LoadedModuleMaps[
File] =
false;
2055 return MMR_InvalidModuleMap;
2060 return MMR_NewlyProcessed;
2063HeaderSearch::ModuleMapResult
2065 bool ImplicitlyDiscovered,
2069 auto AddResult = ParsedModuleMaps.insert(std::make_pair(
File,
true));
2070 if (!AddResult.second)
2071 return AddResult.first->second ? MMR_AlreadyProcessed
2072 : MMR_InvalidModuleMap;
2074 if (ModMap.parseModuleMapFile(
File, IsSystem, ImplicitlyDiscovered, Dir,
2076 ParsedModuleMaps[
File] =
false;
2077 return MMR_InvalidModuleMap;
2083 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, ImplicitlyDiscovered,
2085 ParsedModuleMaps[
File] =
false;
2086 return MMR_InvalidModuleMap;
2091 return MMR_NewlyProcessed;
2096 if (!HSOpts.ImplicitModuleMaps)
2097 return std::nullopt;
2102 llvm::sys::path::append(ModuleMapFileName,
"Modules");
2103 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
2104 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2108 ModuleMapFileName = Dir.
getName();
2109 llvm::sys::path::append(ModuleMapFileName,
"module.map");
2110 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
2111 Diags.Report(diag::warn_deprecated_module_dot_map)
2112 << ModuleMapFileName << 0 << IsFramework;
2119 ModuleMapFileName = Dir.
getName();
2120 llvm::sys::path::append(ModuleMapFileName,
"Modules",
2121 "module.private.modulemap");
2122 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2125 return std::nullopt;
2130 bool ImplicitlyDiscovered) {
2134 case MMR_InvalidModuleMap:
2137 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
2140 case MMR_NoDirectory:
2143 case MMR_AlreadyProcessed:
2144 case MMR_NewlyProcessed:
2151HeaderSearch::ModuleMapResult
2153 bool ImplicitlyDiscovered,
2155 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2159 return MMR_NoDirectory;
2162HeaderSearch::ModuleMapResult
2164 bool ImplicitlyDiscovered,
2166 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2167 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2168 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2169 if (!InsertRes.second) {
2170 switch (MMState.Status) {
2171 case ModuleMapDirectoryState::Parsed:
2173 case ModuleMapDirectoryState::Loaded:
2174 return MMR_AlreadyProcessed;
2175 case ModuleMapDirectoryState::Invalid:
2176 return MMR_InvalidModuleMap;
2180 if (!MMState.ModuleMapFile) {
2182 if (MMState.ModuleMapFile)
2183 MMState.PrivateModuleMapFile =
2187 if (MMState.ModuleMapFile) {
2188 ModuleMapResult
Result = parseAndLoadModuleMapFileImpl(
2189 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2193 if (
Result == MMR_NewlyProcessed)
2194 MMState.Status = ModuleMapDirectoryState::Loaded;
2195 else if (
Result == MMR_InvalidModuleMap)
2196 MMState.Status = ModuleMapDirectoryState::Invalid;
2199 return MMR_InvalidModuleMap;
2202HeaderSearch::ModuleMapResult
2203HeaderSearch::parseModuleMapFile(StringRef DirName,
bool IsSystem,
2204 bool ImplicitlyDiscovered,
bool IsFramework) {
2205 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2206 return parseModuleMapFile(*Dir, IsSystem, ImplicitlyDiscovered,
2209 return MMR_NoDirectory;
2212HeaderSearch::ModuleMapResult
2214 bool ImplicitlyDiscovered,
bool IsFramework) {
2215 if (!HSOpts.LazyLoadModuleMaps)
2219 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2220 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2221 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2222 if (!InsertRes.second) {
2223 switch (MMState.Status) {
2224 case ModuleMapDirectoryState::Parsed:
2225 case ModuleMapDirectoryState::Loaded:
2226 return MMR_AlreadyProcessed;
2227 case ModuleMapDirectoryState::Invalid:
2228 return MMR_InvalidModuleMap;
2232 if (!MMState.ModuleMapFile) {
2234 if (MMState.ModuleMapFile)
2235 MMState.PrivateModuleMapFile =
2239 if (MMState.ModuleMapFile) {
2240 ModuleMapResult
Result = parseModuleMapFileImpl(
2241 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2245 if (
Result == MMR_NewlyProcessed)
2246 MMState.Status = ModuleMapDirectoryState::Parsed;
2247 else if (
Result == MMR_InvalidModuleMap)
2248 MMState.Status = ModuleMapDirectoryState::Invalid;
2251 return MMR_InvalidModuleMap;
2257 if (HSOpts.ImplicitModuleMaps) {
2260 bool IsSystem = DL.isSystemHeaderDirectory();
2261 if (DL.isFramework()) {
2264 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
2267 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2268 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
2270 Dir != DirEnd && !EC; Dir.increment(EC)) {
2271 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
2274 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
2279 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2286 if (DL.isHeaderMap())
2296 loadSubdirectoryModuleMaps(DL);
2301 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2305 if (!HSOpts.ImplicitModuleMaps)
2311 if (!DL.isNormalDir())
2316 true, DL.isFramework());
2320void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
2322 "Should not be loading subdirectory module maps");
2329 FileMgr.makeAbsolutePath(Dir);
2331 llvm::sys::path::native(Dir, DirNative);
2332 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
2333 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2334 Dir != DirEnd && !EC; Dir.increment(EC)) {
2335 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2337 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
2350 MainFile, IsAngled);
2354 llvm::StringRef
File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2355 bool *IsAngled)
const {
2356 using namespace llvm::sys;
2359 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2360 path::make_absolute(WorkingDir, FilePath);
2364 path::remove_dots(FilePath,
true);
2365 path::native(FilePath, path::Style::posix);
2368 unsigned BestPrefixLength = 0;
2373 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2374 path::make_absolute(WorkingDir, Dir);
2375 path::remove_dots(Dir,
true);
2376 for (
auto NI = path::begin(
File), NE = path::end(
File),
2377 DI = path::begin(Dir), DE = path::end(Dir);
2378 NI != NE; ++NI, ++DI) {
2381 unsigned PrefixLength = NI - path::begin(
File);
2382 if (PrefixLength > BestPrefixLength) {
2383 BestPrefixLength = PrefixLength;
2390 if (NI->size() == 1 && DI->size() == 1 &&
2391 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2397 if (NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
2398 StringRef NBasename = path::stem(*NI);
2399 StringRef DBasename = path::stem(*DI);
2400 if (DBasename.starts_with(NBasename))
2410 bool BestPrefixIsFramework =
false;
2412 if (DL.isNormalDir()) {
2413 StringRef Dir = DL.getDirRef()->getName();
2414 if (CheckDir(Dir)) {
2416 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2417 BestPrefixIsFramework =
false;
2419 }
else if (DL.isFramework()) {
2420 StringRef Dir = DL.getFrameworkDirRef()->getName();
2421 if (CheckDir(Dir)) {
2424 *IsAngled = BestPrefixLength;
2425 BestPrefixIsFramework =
true;
2432 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2435 BestPrefixIsFramework =
false;
2440 StringRef Filename =
File.drop_front(BestPrefixLength);
2442 if (!DL.isHeaderMap())
2445 StringRef SpelledFilename =
2446 DL.getHeaderMap()->reverseLookupFilename(Filename);
2447 if (!SpelledFilename.empty()) {
2448 Filename = SpelledFilename;
2449 BestPrefixIsFramework =
false;
2456 bool IsPrivateHeader;
2458 if (BestPrefixIsFramework &&
2461 Filename = IncludeSpelling;
2463 return path::convert_to_slash(Filename);
2468 NormalizedPath.assign(Path.begin(), Path.end());
2469 if (!NormalizedPath.empty()) {
2470 FileMgr.makeAbsolutePath(NormalizedPath);
2471 llvm::sys::path::remove_dots(NormalizedPath);
2477 std::string ContextHash,
size_t &NormalizedModuleCachePathLen) {
2480 NormalizedModuleCachePathLen = SpecificModuleCachePath.size();
2481 if (!SpecificModuleCachePath.empty() && !DisableModuleHash)
2482 llvm::sys::path::append(SpecificModuleCachePath, ContextHash);
2483 return std::string(SpecificModuleCachePath);
2487 ContextHash = std::move(NewContextHash);
2489 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash, ContextHash,
2490 NormalizedModuleCachePathLen);
2494 StringRef ModuleCachePath,
2495 bool DisableModuleHash,
2496 std::string ContextHash) {
2497 size_t NormalizedModuleCachePathLen;
2499 FileMgr, ModuleCachePath, DisableModuleHash, std::move(ContextHash),
2500 NormalizedModuleCachePathLen);
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
constexpr bool has_value() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
OptionalFileEntryRef LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, bool &IsInHeaderMap, SmallVectorImpl< char > &MappedName, bool OpenFile=true) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
bool isFramework() const
isFramework - True if this is a framework directory.
bool isSystemHeaderDirectory() const
Whether this describes a system header directory.
OptionalDirectoryEntryRef getFrameworkDirRef() const
void setSearchedAllModuleMaps(bool SAMM)
Specify whether we have already searched all of the subdirectories for module maps.
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
OptionalDirectoryEntryRef getDirRef() const
bool haveSearchedAllModuleMaps() const
Determine whether we have already searched this entire directory for module maps.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
bool isNormalDir() const
isNormalDir - Return true if this is a normal directory, not a header map.
const HeaderMap * getHeaderMap() const
getHeaderMap - Return the directory that this entry refers to.
Abstract interface for external sources of preprocessor information.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
One of these records is kept for each identifier that is lexed.
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isValid() const
Whether this pointer is non-NULL.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
const modulemap::ModuleMapFile * getParsedModuleMap(FileEntryRef File) const
Get the ModuleMapFile for a FileEntry previously parsed with parseModuleMapFile.
ModuleHeaderRole
Flags describing the role of a module header.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Module * findOrLoadModule(StringRef Name)
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
std::string Name
The name of this module.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool markIncluded(FileEntryRef File)
Mark the file as included.
bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M)
Determine whether II is defined as a macro within the module M, if that is a module that we've alread...
bool isMacroDefined(StringRef Id)
bool alreadyIncluded(FileEntryRef File) const
Return true if this header has already been included.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
std::string createSpecificModuleCachePath(FileManager &FileMgr, StringRef ModuleCachePath, bool DisableModuleHash, std::string ContextHash)
void normalizeModuleCachePath(FileManager &FileMgr, StringRef Path, SmallVectorImpl< char > &NormalizedPath)
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
This structure is used to record entries in our framework cache.
bool IsUserSpecifiedSystemFramework
Whether this framework has been "user-specified" to be treated as if it were a system framework (even...
OptionalDirectoryEntryRef Directory
The directory entry which should be used for the cached framework.
std::vector< Decl > Decls
Represents the parsed form of a module map file.
std::vector< TopLevelDecl > Decls