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");
245 StringRef ModuleMapPath =
ModuleMap->getName();
246 for (
const std::string &Dir : HSOpts.PrebuiltModulePaths) {
248 FileMgr.makeAbsolutePath(CachePath);
250 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
258 StringRef ModuleMapPath) {
259 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
264 StringRef ModuleName, StringRef ModuleMapPath, StringRef CachePath) {
267 if (CachePath.empty())
274 unsigned SuffixBegin = Result.size();
277 llvm::sys::path::append(Result, ModuleName +
".pcm");
279 llvm::sys::path::append(
Result, ContextHash);
288 SmallString<128> CanonicalPath(ModuleMapPath);
289 if (
getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
292 auto Hash = llvm::xxh3_64bits(CanonicalPath.str().lower());
294 SmallString<128> HashStr;
295 llvm::APInt(64, Hash).toStringUnsigned(HashStr, 36);
296 llvm::sys::path::append(
Result, ModuleName +
"-" + HashStr +
".pcm");
303 bool AllowExtraModuleMapSearch) {
306 if (
Module || !AllowSearch || !HSOpts.ImplicitModuleMaps)
309 StringRef SearchName = ModuleName;
311 AllowExtraModuleMapSearch);
321 if (!
Module && SearchName.consume_back(
"_Private"))
323 AllowExtraModuleMapSearch);
324 if (!
Module && SearchName.consume_back(
"Private"))
326 AllowExtraModuleMapSearch);
332 bool AllowExtraModuleMapSearch) {
338 if (Dir.isFramework()) {
343 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
344 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
345 if (
auto FrameworkDir =
346 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
348 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem,
358 if (!Dir.isNormalDir())
361 bool IsSystem = Dir.isSystemHeaderDirectory();
364 DirectoryEntryRef NormalDir = *Dir.getDirRef();
366 if (parseModuleMapFile(NormalDir, IsSystem,
true,
367 false) == MMR_NewlyProcessed) {
370 Module = ModMap.findOrLoadModule(ModuleName);
377 SmallString<128> NestedModuleMapDirName;
378 NestedModuleMapDirName = Dir.getDirRef()->getName();
379 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
380 if (parseModuleMapFile(NestedModuleMapDirName, IsSystem,
382 false) == MMR_NewlyProcessed) {
384 Module = ModMap.findOrLoadModule(ModuleName);
389 if (HSOpts.AllowModuleMapSubdirectorySearch) {
392 if (Dir.haveSearchedAllModuleMaps())
397 if (AllowExtraModuleMapSearch)
398 loadSubdirectoryModuleMaps(Dir);
401 Module = ModMap.findOrLoadModule(ModuleName);
410void HeaderSearch::indexInitialHeaderMaps() {
411 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
414 for (
unsigned i = 0; i != SearchDirs.size(); ++i) {
415 auto &Dir = SearchDirs[i];
420 if (!Dir.isHeaderMap()) {
421 SearchDirHeaderMapIndex = std::move(Index);
422 FirstNonHeaderMapSearchDirIdx = i;
427 auto Callback = [&](StringRef Filename) {
428 Index.try_emplace(Filename.lower(), i);
430 Dir.getHeaderMap()->forEachKey(Callback);
445 assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
451 bool IsSystemHeaderDir,
Module *RequestingModule,
453 bool CacheFailures ) {
460 std::error_code EC = llvm::errorToErrorCode(
File.takeError());
461 if (EC != llvm::errc::no_such_file_or_directory &&
462 EC != llvm::errc::invalid_argument &&
463 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
464 Diags.
Report(IncludeLoc, diag::err_cannot_open_file)
471 if (!findUsableModuleForHeader(
472 *
File, Dir ? Dir :
File->getFileEntry().getDir(), RequestingModule,
473 SuggestedModule, IsSystemHeaderDir))
485 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound,
487 bool OpenFile)
const {
488 InUserSpecifiedSystemFramework =
false;
489 IsInHeaderMap =
false;
496 llvm::sys::path::append(TmpDir, Filename);
500 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
503 RelativePath->clear();
504 RelativePath->append(Filename.begin(), Filename.end());
507 return HS.getFileAndSuggestModule(
509 RequestingModule, SuggestedModule, OpenFile);
513 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
514 RequestingModule, SuggestedModule,
515 InUserSpecifiedSystemFramework, IsFrameworkFound);
517 assert(
isHeaderMap() &&
"Unknown directory lookup");
524 IsInHeaderMap =
true;
526 auto FixupSearchPathAndFindUsableModule =
529 StringRef SearchPathRef(
getName());
531 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
534 RelativePath->clear();
535 RelativePath->append(Filename.begin(), Filename.end());
537 if (!HS.findUsableModuleForHeader(
File,
File.getFileEntry().getDir(),
538 RequestingModule, SuggestedModule,
548 if (llvm::sys::path::is_relative(Dest)) {
549 MappedName.append(Dest.begin(), Dest.end());
550 Filename = StringRef(MappedName.begin(), MappedName.size());
555 return FixupSearchPathAndFindUsableModule(*Res);
575 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
576 "Not a framework directory");
592 auto TopFrameworkDir =
FileMgr.getOptionalDirectoryRef(DirName);
595 DirName =
FileMgr.getCanonicalName(*TopFrameworkDir);
598 DirName = llvm::sys::path::parent_path(DirName);
603 auto Dir =
FileMgr.getOptionalDirectoryRef(DirName);
609 if (llvm::sys::path::extension(DirName) ==
".framework") {
610 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
611 TopFrameworkDir = *Dir;
615 return TopFrameworkDir;
619 bool HasSuggestedModule) {
620 return HasSuggestedModule ||
630 bool &InUserSpecifiedSystemFramework,
bool &IsFrameworkFound)
const {
634 size_t SlashPos = Filename.find(
'/');
635 if (SlashPos == StringRef::npos)
640 FrameworkCacheEntry &CacheEntry =
650 SmallString<1024> FrameworkName;
652 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
653 FrameworkName.push_back(
'/');
656 StringRef ModuleName(Filename.begin(), SlashPos);
657 FrameworkName += ModuleName;
660 FrameworkName +=
".framework/";
664 ++NumFrameworkLookups;
678 SmallString<1024> SystemFrameworkMarker(FrameworkName);
679 SystemFrameworkMarker +=
".system_framework";
690 RelativePath->clear();
691 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
695 unsigned OrigSize = FrameworkName.size();
697 FrameworkName +=
"Headers/";
702 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
705 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
711 const char *
Private =
"Private";
712 FrameworkName.insert(FrameworkName.begin()+OrigSize,
Private,
715 SearchPath->insert(SearchPath->begin()+OrigSize,
Private,
725 StringRef FrameworkPath =
File->getDir().getName();
726 bool FoundFramework =
false;
735 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
736 FoundFramework =
true;
741 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
742 if (FrameworkPath.empty())
747 if (FoundFramework) {
748 if (!HS.findUsableModuleForFrameworkHeader(*
File, FrameworkPath,
750 SuggestedModule, IsSystem))
753 if (!HS.findUsableModuleForHeader(*
File,
getDir(), RequestingModule,
754 SuggestedModule, IsSystem))
763void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
766 CacheLookup.HitIt = HitIt;
767 noteLookupUsage(HitIt.Idx, Loc);
770void HeaderSearch::noteLookupUsage(
unsigned HitIdx,
SourceLocation Loc) {
771 SearchDirsUsage[HitIdx] =
true;
773 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
774 if (UserEntryIdxIt != SearchDirToHSEntry.end())
775 Diags.Report(Loc, diag::remark_pp_search_path_usage)
776 << HSOpts.UserEntries[UserEntryIdxIt->second].Path;
794 if (MSFE && FE != *MSFE) {
795 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
801static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
802 assert(!Str.empty());
803 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
804 std::copy(Str.begin(), Str.end(), CopyStr);
805 CopyStr[Str.size()] =
'\0';
812 using namespace llvm::sys;
813 path::const_iterator I = path::begin(Path);
814 path::const_iterator E = path::end(Path);
815 IsPrivateHeader =
false;
827 if (*I ==
"Headers") {
829 }
else if (*I ==
"PrivateHeaders") {
831 IsPrivateHeader =
true;
832 }
else if (I->ends_with(
".framework")) {
833 StringRef Name = I->drop_back(10);
835 FrameworkName.clear();
836 FrameworkName.append(Name.begin(), Name.end());
837 IncludeSpelling.clear();
838 IncludeSpelling.append(Name.begin(), Name.end());
840 }
else if (FoundComp >= 2) {
841 IncludeSpelling.push_back(
'/');
842 IncludeSpelling.append(I->begin(), I->end());
847 return !FrameworkName.empty() && FoundComp >= 2;
852 StringRef Includer, StringRef IncludeFilename,
854 bool FoundByHeaderMap =
false) {
855 bool IsIncluderPrivateHeader =
false;
859 FromIncludeSpelling))
861 bool IsIncludeePrivateHeader =
false;
862 bool IsIncludeeInFramework =
864 ToFramework, ToIncludeSpelling);
866 if (!isAngled && !FoundByHeaderMap) {
868 if (IsIncludeeInFramework) {
869 NewInclude += ToIncludeSpelling;
872 NewInclude += IncludeFilename;
875 Diags.
Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
883 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
884 IsIncludeePrivateHeader && FromFramework == ToFramework)
885 Diags.
Report(IncludeLoc, diag::warn_framework_include_private_from_public)
892 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
893 bool isAngled,
int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt) {
895 if (Diags.isIgnored(diag::warn_header_shadowing, IncludeLoc) ||
899 if (MainLoopIt && MainLoopIt->isSystemHeaderDirectory())
902 DiagnosedShadowing =
true;
906 for (
size_t i = IncluderLoopIndex + 1; i < Includers.size(); ++i) {
907 const auto &IncluderAndDir = Includers[i];
909 llvm::sys::path::append(TmpDir, Filename);
911 if (&
File->getFileEntry() == *FE)
913 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
914 << Filename << (*FE).getDir().getName()
915 << IncluderAndDir.second.getName();
918 llvm::errorToErrorCode(
File.takeError());
924 ConstSearchDirIterator It =
927 It = std::next(MainLoopIt);
928 }
else if (FromDir) {
936 llvm::sys::path::append(TmpPath, Filename);
938 if (&
File->getFileEntry() == *FE)
940 Diags.Report(IncludeLoc, diag::warn_header_shadowing)
941 << Filename << (*FE).getDir().getName() << It->getName();
944 llvm::errorToErrorCode(
File.takeError());
956 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
957 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
960 bool *IsMapped,
bool *IsFrameworkFound,
bool SkipCache,
961 bool BuildSystemModule,
bool OpenFile,
bool CacheFailures) {
962 ConstSearchDirIterator CurDirLocal =
nullptr;
963 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
968 if (IsFrameworkFound)
969 *IsFrameworkFound =
false;
975 if (llvm::sys::path::is_absolute(Filename)) {
985 RelativePath->clear();
986 RelativePath->append(Filename.begin(), Filename.end());
989 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
991 RequestingModule, SuggestedModule, OpenFile,
998 bool DiagnosedShadowing =
false;
1005 if (!Includers.empty() && !isAngled) {
1008 for (
const auto &IncluderAndDir : Includers) {
1012 TmpDir = IncluderAndDir.second.getName();
1013 llvm::sys::path::append(TmpDir, Filename);
1022 bool IncluderIsSystemHeader = [&]() {
1024 return BuildSystemModule;
1026 assert(HFI &&
"includer without file info");
1030 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
1031 RequestingModule, SuggestedModule)) {
1033 FromDir, Includers, isAngled,
1034 &IncluderAndDir - Includers.begin(),
nullptr);
1036 assert(
First &&
"only first includer can have no file");
1047 assert(FromHFI &&
"includer without file info");
1048 unsigned DirInfo = FromHFI->
DirInfo;
1054 StringRef SearchPathRef(IncluderAndDir.second.getName());
1055 SearchPath->clear();
1056 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
1059 RelativePath->clear();
1060 RelativePath->append(Filename.begin(), Filename.end());
1064 IncluderAndDir.second.getName(), Filename,
1072 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1076 if (SuggestedModule) {
1077 MSSuggestedModule = *SuggestedModule;
1090 ConstSearchDirIterator It =
1102 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1104 ConstSearchDirIterator NextIt = std::next(It);
1107 if (CacheLookup.StartIt == NextIt &&
1108 CacheLookup.RequestingModule == RequestingModule) {
1110 if (CacheLookup.HitIt)
1111 It = CacheLookup.HitIt;
1112 if (CacheLookup.MappedName) {
1113 Filename = CacheLookup.MappedName;
1121 CacheLookup.reset(RequestingModule, NextIt);
1127 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1128 if (Iter == SearchDirHeaderMapIndex.end())
1137 CacheLookup.reset(RequestingModule, NextIt);
1144 bool InUserSpecifiedSystemFramework =
false;
1145 bool IsInHeaderMap =
false;
1146 bool IsFrameworkFoundInDir =
false;
1148 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1149 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1150 IsInHeaderMap, MappedName, OpenFile);
1151 if (!MappedName.empty()) {
1152 assert(IsInHeaderMap &&
"MappedName should come from a header map");
1153 CacheLookup.MappedName =
1154 copyString(MappedName, LookupFileCache.getAllocator());
1160 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap &&
File));
1161 if (IsFrameworkFound)
1165 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1170 FromDir, Includers, isAngled, -1, It);
1174 IncludeNames[*
File] = Filename;
1178 HFI.
DirInfo = CurDir->getDirCharacteristic();
1188 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1189 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1197 if (SuggestedModule)
1198 *SuggestedModule = MSSuggestedModule;
1202 bool FoundByHeaderMap = !IsMapped ?
false : *IsMapped;
1203 if (!Includers.empty())
1205 Includers.front().second.getName(), Filename,
1206 *
File, isAngled, FoundByHeaderMap);
1209 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1214 if (SuggestedModule)
1215 *SuggestedModule = MSSuggestedModule;
1221 return std::nullopt;
1235 size_t SlashPos = Filename.find(
'/');
1236 if (SlashPos == StringRef::npos)
1237 return std::nullopt;
1240 StringRef ContextName = ContextFileEnt.
getName();
1243 const unsigned DotFrameworkLen = 10;
1244 auto FrameworkPos = ContextName.find(
".framework");
1245 if (FrameworkPos == StringRef::npos ||
1246 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
1247 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
1248 return std::nullopt;
1252 DotFrameworkLen + 1);
1255 FrameworkName +=
"Frameworks/";
1256 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1257 FrameworkName +=
".framework/";
1260 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1264 if (CacheLookup.second.Directory &&
1265 CacheLookup.first().size() == FrameworkName.size() &&
1266 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1267 CacheLookup.first().size()) != 0)
1268 return std::nullopt;
1271 if (!CacheLookup.second.Directory) {
1272 ++NumSubFrameworkLookups;
1275 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1277 return std::nullopt;
1281 CacheLookup.second.Directory = Dir;
1286 RelativePath->clear();
1287 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1292 HeadersFilename +=
"Headers/";
1294 SearchPath->clear();
1296 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1299 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1300 auto File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1303 HeadersFilename = FrameworkName;
1304 HeadersFilename +=
"PrivateHeaders/";
1306 SearchPath->clear();
1308 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1311 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1312 File = FileMgr.getOptionalFileRef(HeadersFilename,
true);
1315 return std::nullopt;
1320 assert(ContextHFI &&
"context file without file info");
1323 unsigned DirInfo = ContextHFI->
DirInfo;
1326 FrameworkName.pop_back();
1327 if (!findUsableModuleForFrameworkHeader(*
File, FrameworkName,
1328 RequestingModule, SuggestedModule,
1330 return std::nullopt;
1349 bool isModuleHeader,
1350 bool isTextualModuleHeader) {
1367 assert(OtherHFI.
External &&
"expected to merge external HFI");
1383 if (FE.
getUID() >= FileInfo.size())
1384 FileInfo.resize(FE.
getUID() + 1);
1388 if (ExternalSource && !HFI->
Resolved) {
1389 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1390 if (ExternalHFI.IsValid) {
1392 if (ExternalHFI.External)
1406 if (ExternalSource) {
1407 if (FE.
getUID() >= FileInfo.size())
1408 FileInfo.resize(FE.
getUID() + 1);
1410 HFI = &FileInfo[FE.
getUID()];
1413 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1414 if (ExternalHFI.IsValid) {
1416 if (ExternalHFI.External)
1420 }
else if (FE.
getUID() < FileInfo.size()) {
1421 HFI = &FileInfo[FE.
getUID()];
1426 return (HFI && HFI->
IsValid) ? HFI :
nullptr;
1432 if (FE.
getUID() < FileInfo.size()) {
1433 HFI = &FileInfo[FE.
getUID()];
1446 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1452 bool isCompilingModuleHeader) {
1454 if (!isCompilingModuleHeader) {
1463 HFI.mergeModuleMembership(
Role);
1464 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1469 bool ModulesEnabled,
Module *M,
1470 bool &IsFirstIncludeOfFile) {
1486 IsFirstIncludeOfFile =
false;
1489 auto MaybeReenterImportedFile = [&]() ->
bool {
1507 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1511 ModMap.resolveHeaderDirectives(
File);
1531 if (FileInfo.isTextualModuleHeader)
1534 if (FileInfo.isCompilingModuleHeader) {
1537 if (FileInfo.isModuleHeader) {
1542 if (ModMap.isBuiltinHeader(
File))
1551 if (FileInfo.getControllingMacro(ExternalLookup))
1571 FileInfo.isImport =
true;
1578 if (FileInfo.isPragmaOnce ||
1579 (FileInfo.isImport && !MaybeReenterImportedFile()))
1588 FileInfo.getControllingMacro(ExternalLookup)) {
1595 ++NumMultiIncludeFileOptzn;
1605 return SearchDirs.capacity()
1606 + llvm::capacity_in_bytes(FileInfo)
1607 + llvm::capacity_in_bytes(HeaderMaps)
1608 + LookupFileCache.getAllocator().getTotalMemory()
1609 + FrameworkMap.getAllocator().getTotalMemory();
1613 return &DL - &*SearchDirs.begin();
1617 return FrameworkNames.insert(Framework).first->first();
1621 auto It = IncludeNames.find(
File);
1622 if (It == IncludeNames.end())
1628 ModuleMapDirectoryState &MMState) {
1629 if (!MMState.ModuleMapFile)
1636 if (MMState.PrivateModuleMapFile)
1639 processModuleMapForIndex(*ParsedMM, Dir,
"", MMState);
1640 if (ParsedPrivateMM)
1641 processModuleMapForIndex(*ParsedPrivateMM, Dir,
"", MMState);
1644void HeaderSearch::addToModuleMapIndex(StringRef RelPath, StringRef ModuleName,
1645 StringRef PathPrefix,
1646 ModuleMapDirectoryState &MMState) {
1648 llvm::sys::path::append(RelFromRootPath, RelPath);
1649 llvm::sys::path::native(RelFromRootPath);
1650 MMState.HeaderToModules[RelFromRootPath].push_back(ModuleName);
1653void HeaderSearch::processExternModuleDeclForIndex(
1655 StringRef PathPrefix, ModuleMapDirectoryState &MMState) {
1656 StringRef FileNameRef = EMD.
Path;
1657 SmallString<128> ModuleMapFileName;
1658 if (llvm::sys::path::is_relative(FileNameRef)) {
1659 ModuleMapFileName = MMDir.
getName();
1660 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1661 FileNameRef = ModuleMapFileName;
1663 if (
auto EFile = FileMgr.getOptionalFileRef(FileNameRef)) {
1664 if (
auto *ExtMMF = ModMap.getParsedModuleMap(*EFile)) {
1667 SmallString<128> NewPrefix(PathPrefix);
1668 StringRef ExternDir = llvm::sys::path::parent_path(EMD.
Path);
1669 if (!ExternDir.empty()) {
1670 llvm::sys::path::append(NewPrefix, ExternDir);
1671 llvm::sys::path::native(NewPrefix);
1673 processModuleMapForIndex(*ExtMMF, EFile->getDir(), NewPrefix, MMState);
1679 StringRef ModuleName,
1681 StringRef PathPrefix,
1682 ModuleMapDirectoryState &MMState) {
1684 if (MD.
Id.front().first ==
"*")
1687 auto ProcessDecl = llvm::makeVisitor(
1688 [&](
const modulemap::HeaderDecl &HD) {
1690 MMState.UmbrellaHeaderModules.push_back(ModuleName);
1692 addToModuleMapIndex(HD.
Path, ModuleName, PathPrefix, MMState);
1695 [&](
const modulemap::UmbrellaDirDecl &UDD) {
1696 SmallString<128> FullPath(PathPrefix);
1697 llvm::sys::path::append(FullPath, UDD.Path);
1698 llvm::sys::path::native(FullPath);
1699 MMState.UmbrellaDirModules.push_back(
1700 std::make_pair(std::string(FullPath), ModuleName));
1702 [&](
const modulemap::ModuleDecl &SubMD) {
1703 processModuleDeclForIndex(SubMD, ModuleName, MMDir, PathPrefix,
1706 [&](
const modulemap::ExternModuleDecl &EMD) {
1707 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix, MMState);
1713 for (
const auto &Decl : MD.
Decls) {
1714 std::visit(ProcessDecl, Decl);
1720 StringRef PathPrefix,
1721 ModuleMapDirectoryState &MMState) {
1722 for (
const auto &Decl : MMF.
Decls) {
1723 std::visit(llvm::makeVisitor(
1724 [&](
const modulemap::ModuleDecl &MD) {
1725 processModuleDeclForIndex(MD, MD.
Id.front().first, MMDir,
1726 PathPrefix, MMState);
1728 [&](
const modulemap::ExternModuleDecl &EMD) {
1729 processExternModuleDeclForIndex(EMD, MMDir, PathPrefix,
1739 if (!HSOpts.ImplicitModuleMaps)
1746 DirName = llvm::sys::path::parent_path(DirName);
1747 if (DirName.empty())
1751 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1757 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1761 parseModuleMapFile(*Dir, IsSystem,
true,
1763 auto DirState = DirectoryModuleMap.find(*Dir);
1764 if (DirState == DirectoryModuleMap.end() || !DirState->second.ModuleMapFile)
1767 if (!HSOpts.LazyLoadModuleMaps)
1770 auto &MMState = DirState->second;
1773 if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() &&
1774 MMState.UmbrellaHeaderModules.empty()) {
1775 buildModuleMapIndex(*Dir, MMState);
1781 StringRef RelativePath =
FileName.substr(DirName.size());
1783 while (!RelativePath.empty() &&
1784 llvm::sys::path::is_separator(RelativePath.front()))
1785 RelativePath = RelativePath.substr(1);
1787 llvm::sys::path::native(RelativePathNative);
1788 RelativePath = RelativePathNative;
1792 auto CachedMods = MMState.HeaderToModules.find(RelativePath);
1793 if (CachedMods != MMState.HeaderToModules.end()) {
1794 ModulesToLoad.append(CachedMods->second.begin(),
1795 CachedMods->second.end());
1799 for (
const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
1800 if (RelativePath.starts_with(UmbrellaDir.first) ||
1801 UmbrellaDir.first ==
".") {
1802 ModulesToLoad.push_back(UmbrellaDir.second);
1817 ModulesToLoad.append(MMState.UmbrellaHeaderModules.begin(),
1818 MMState.UmbrellaHeaderModules.end());
1821 bool LoadedAny =
false;
1822 for (StringRef ModName : ModulesToLoad) {
1823 if (ModMap.findOrLoadModule(ModName)) {
1832 }
while (CurDir != Root);
1838 bool AllowExcluded)
const {
1839 if (ExternalSource) {
1844 return ModMap.findModuleForHeader(
File, AllowTextual, AllowExcluded);
1849 if (ExternalSource) {
1854 return ModMap.findAllModulesForHeader(
File);
1859 if (ExternalSource) {
1864 return ModMap.findResolvedModulesForHeader(
File);
1881 if (SuggestedModule)
1891 if (SuggestedModule)
1899bool HeaderSearch::findUsableModuleForHeader(
1903 if (!HSOpts.LazyLoadModuleMaps) {
1909 ModuleMap::KnownHeader
Module =
1916 ModuleMap::KnownHeader
Module =
1924 Module = ModMap.findModuleForHeader(
File,
true);
1933bool HeaderSearch::findUsableModuleForFrameworkHeader(
1939 SmallVector<std::string, 4> SubmodulePath;
1942 assert(TopFrameworkDir &&
"Could not find the top-most framework dir");
1945 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1949 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework,
1956 ModuleMap::KnownHeader
Module =
1967 bool Diagnose =
true) {
1968 StringRef Filename = llvm::sys::path::filename(
File.getName());
1970 if (Filename ==
"module.map")
1971 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1972 else if (Filename ==
"module.modulemap")
1973 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1975 return std::nullopt;
1976 auto PMMFile =
FileMgr.getOptionalFileRef(PrivateFilename);
1978 if (Diagnose && Filename ==
"module.map")
1979 Diags.
Report(diag::warn_deprecated_module_dot_map)
1980 << PrivateFilename << 1
1981 <<
File.getDir().getName().ends_with(
".framework");
1987 bool ImplicitlyDiscovered,
1988 FileID ID,
unsigned *Offset,
1989 StringRef OriginalModuleMapFile) {
1994 Dir = FileMgr.getOptionalDirectoryRef(
".");
1996 if (!OriginalModuleMapFile.empty()) {
1999 Dir = FileMgr.getOptionalDirectoryRef(
2000 llvm::sys::path::parent_path(OriginalModuleMapFile));
2002 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
2003 Dir = FakeFile.getDir();
2006 Dir =
File.getDir();
2009 assert(Dir &&
"parent must exist");
2010 StringRef DirName(Dir->
getName());
2011 if (llvm::sys::path::filename(DirName) ==
"Modules") {
2012 DirName = llvm::sys::path::parent_path(DirName);
2013 if (DirName.ends_with(
".framework"))
2014 if (
auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
2018 assert(Dir &&
"parent must exist");
2022 assert(Dir &&
"module map home directory must exist");
2023 switch (parseAndLoadModuleMapFileImpl(
File, IsSystem, ImplicitlyDiscovered,
2026 case MMR_AlreadyProcessed:
2027 case MMR_NewlyProcessed:
2029 case MMR_NoDirectory:
2030 case MMR_InvalidModuleMap:
2033 llvm_unreachable(
"Unknown load module map result");
2036HeaderSearch::ModuleMapResult HeaderSearch::parseAndLoadModuleMapFileImpl(
2041 auto AddResult = LoadedModuleMaps.insert(std::make_pair(
File,
true));
2042 if (!AddResult.second)
2043 return AddResult.first->second ? MMR_AlreadyProcessed
2044 : MMR_InvalidModuleMap;
2048 LoadedModuleMaps[
File] =
false;
2049 return MMR_InvalidModuleMap;
2056 ImplicitlyDiscovered, Dir)) {
2057 LoadedModuleMaps[
File] =
false;
2058 return MMR_InvalidModuleMap;
2063 return MMR_NewlyProcessed;
2066HeaderSearch::ModuleMapResult
2068 bool ImplicitlyDiscovered,
2072 auto AddResult = ParsedModuleMaps.insert(std::make_pair(
File,
true));
2073 if (!AddResult.second)
2074 return AddResult.first->second ? MMR_AlreadyProcessed
2075 : MMR_InvalidModuleMap;
2077 if (ModMap.parseModuleMapFile(
File, IsSystem, ImplicitlyDiscovered, Dir,
2079 ParsedModuleMaps[
File] =
false;
2080 return MMR_InvalidModuleMap;
2086 if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, ImplicitlyDiscovered,
2088 ParsedModuleMaps[
File] =
false;
2089 return MMR_InvalidModuleMap;
2094 return MMR_NewlyProcessed;
2099 if (!HSOpts.ImplicitModuleMaps)
2100 return std::nullopt;
2105 llvm::sys::path::append(ModuleMapFileName,
"Modules");
2106 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
2107 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2111 ModuleMapFileName = Dir.
getName();
2112 llvm::sys::path::append(ModuleMapFileName,
"module.map");
2113 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) {
2114 Diags.Report(diag::warn_deprecated_module_dot_map)
2115 << ModuleMapFileName << 0 << IsFramework;
2122 ModuleMapFileName = Dir.
getName();
2123 llvm::sys::path::append(ModuleMapFileName,
"Modules",
2124 "module.private.modulemap");
2125 if (
auto F = FileMgr.getOptionalFileRef(ModuleMapFileName))
2128 return std::nullopt;
2133 bool ImplicitlyDiscovered) {
2137 case MMR_InvalidModuleMap:
2140 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
2143 case MMR_NoDirectory:
2146 case MMR_AlreadyProcessed:
2147 case MMR_NewlyProcessed:
2154HeaderSearch::ModuleMapResult
2156 bool ImplicitlyDiscovered,
2158 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2162 return MMR_NoDirectory;
2165HeaderSearch::ModuleMapResult
2167 bool ImplicitlyDiscovered,
2169 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2170 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2171 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2172 if (!InsertRes.second) {
2173 switch (MMState.Status) {
2174 case ModuleMapDirectoryState::Parsed:
2176 case ModuleMapDirectoryState::Loaded:
2177 return MMR_AlreadyProcessed;
2178 case ModuleMapDirectoryState::Invalid:
2179 return MMR_InvalidModuleMap;
2183 if (!MMState.ModuleMapFile) {
2185 if (MMState.ModuleMapFile)
2186 MMState.PrivateModuleMapFile =
2190 if (MMState.ModuleMapFile) {
2191 ModuleMapResult
Result = parseAndLoadModuleMapFileImpl(
2192 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2196 if (
Result == MMR_NewlyProcessed)
2197 MMState.Status = ModuleMapDirectoryState::Loaded;
2198 else if (
Result == MMR_InvalidModuleMap)
2199 MMState.Status = ModuleMapDirectoryState::Invalid;
2202 return MMR_InvalidModuleMap;
2205HeaderSearch::ModuleMapResult
2206HeaderSearch::parseModuleMapFile(StringRef DirName,
bool IsSystem,
2207 bool ImplicitlyDiscovered,
bool IsFramework) {
2208 if (
auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
2209 return parseModuleMapFile(*Dir, IsSystem, ImplicitlyDiscovered,
2212 return MMR_NoDirectory;
2215HeaderSearch::ModuleMapResult
2217 bool ImplicitlyDiscovered,
bool IsFramework) {
2218 if (!HSOpts.LazyLoadModuleMaps)
2222 auto InsertRes = DirectoryModuleMap.insert(std::pair{
2223 Dir, ModuleMapDirectoryState{{}, {}, ModuleMapDirectoryState::Invalid}});
2224 ModuleMapDirectoryState &MMState = InsertRes.first->second;
2225 if (!InsertRes.second) {
2226 switch (MMState.Status) {
2227 case ModuleMapDirectoryState::Parsed:
2228 case ModuleMapDirectoryState::Loaded:
2229 return MMR_AlreadyProcessed;
2230 case ModuleMapDirectoryState::Invalid:
2231 return MMR_InvalidModuleMap;
2235 if (!MMState.ModuleMapFile) {
2237 if (MMState.ModuleMapFile)
2238 MMState.PrivateModuleMapFile =
2242 if (MMState.ModuleMapFile) {
2243 ModuleMapResult
Result = parseModuleMapFileImpl(
2244 *MMState.ModuleMapFile, IsSystem, ImplicitlyDiscovered, Dir);
2248 if (
Result == MMR_NewlyProcessed)
2249 MMState.Status = ModuleMapDirectoryState::Parsed;
2250 else if (
Result == MMR_InvalidModuleMap)
2251 MMState.Status = ModuleMapDirectoryState::Invalid;
2254 return MMR_InvalidModuleMap;
2260 if (HSOpts.ImplicitModuleMaps) {
2263 bool IsSystem = DL.isSystemHeaderDirectory();
2264 if (DL.isFramework()) {
2267 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
2270 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2271 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
2273 Dir != DirEnd && !EC; Dir.increment(EC)) {
2274 if (llvm::sys::path::extension(Dir->path()) !=
".framework")
2277 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
2282 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
2289 if (DL.isHeaderMap())
2299 loadSubdirectoryModuleMaps(DL);
2304 llvm::append_range(Modules, llvm::make_second_range(ModMap.modules()));
2308 if (!HSOpts.ImplicitModuleMaps)
2314 if (!DL.isNormalDir())
2319 true, DL.isFramework());
2323void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
2325 "Should not be loading subdirectory module maps");
2332 FileMgr.makeAbsolutePath(Dir);
2334 llvm::sys::path::native(Dir, DirNative);
2335 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
2336 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2337 Dir != DirEnd && !EC; Dir.increment(EC)) {
2338 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
2340 bool IsFramework = llvm::sys::path::extension(Dir->path()) ==
".framework";
2353 MainFile, IsAngled);
2357 llvm::StringRef
File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
2358 bool *IsAngled)
const {
2359 using namespace llvm::sys;
2362 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
2363 path::make_absolute(WorkingDir, FilePath);
2367 path::remove_dots(FilePath,
true);
2368 path::native(FilePath, path::Style::posix);
2371 unsigned BestPrefixLength = 0;
2376 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2377 path::make_absolute(WorkingDir, Dir);
2378 path::remove_dots(Dir,
true);
2379 for (
auto NI = path::begin(
File), NE = path::end(
File),
2380 DI = path::begin(Dir), DE = path::end(Dir);
2381 NI != NE; ++NI, ++DI) {
2384 unsigned PrefixLength = NI - path::begin(
File);
2385 if (PrefixLength > BestPrefixLength) {
2386 BestPrefixLength = PrefixLength;
2393 if (NI->size() == 1 && DI->size() == 1 &&
2394 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2400 if (NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
2401 StringRef NBasename = path::stem(*NI);
2402 StringRef DBasename = path::stem(*DI);
2403 if (DBasename.starts_with(NBasename))
2413 bool BestPrefixIsFramework =
false;
2415 if (DL.isNormalDir()) {
2416 StringRef Dir = DL.getDirRef()->getName();
2417 if (CheckDir(Dir)) {
2419 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2420 BestPrefixIsFramework =
false;
2422 }
else if (DL.isFramework()) {
2423 StringRef Dir = DL.getFrameworkDirRef()->getName();
2424 if (CheckDir(Dir)) {
2427 *IsAngled = BestPrefixLength;
2428 BestPrefixIsFramework =
true;
2435 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2438 BestPrefixIsFramework =
false;
2443 StringRef Filename =
File.drop_front(BestPrefixLength);
2445 if (!DL.isHeaderMap())
2448 StringRef SpelledFilename =
2449 DL.getHeaderMap()->reverseLookupFilename(Filename);
2450 if (!SpelledFilename.empty()) {
2451 Filename = SpelledFilename;
2452 BestPrefixIsFramework =
false;
2459 bool IsPrivateHeader;
2461 if (BestPrefixIsFramework &&
2464 Filename = IncludeSpelling;
2466 return path::convert_to_slash(Filename);
2471 NormalizedPath.assign(Path.begin(), Path.end());
2472 if (!NormalizedPath.empty()) {
2473 FileMgr.makeAbsolutePath(NormalizedPath);
2474 llvm::sys::path::remove_dots(NormalizedPath);
2480 std::string ContextHash,
size_t &NormalizedModuleCachePathLen) {
2483 NormalizedModuleCachePathLen = SpecificModuleCachePath.size();
2484 if (!SpecificModuleCachePath.empty() && !DisableModuleHash)
2485 llvm::sys::path::append(SpecificModuleCachePath, ContextHash);
2486 return std::string(SpecificModuleCachePath);
2490 ContextHash = std::move(NewContextHash);
2492 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash, ContextHash,
2493 NormalizedModuleCachePathLen);
2497 StringRef ModuleCachePath,
2498 bool DisableModuleHash,
2499 std::string ContextHash) {
2500 size_t NormalizedModuleCachePathLen;
2502 FileMgr, ModuleCachePath, DisableModuleHash, std::move(ContextHash),
2503 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.
Identifies a module file to be loaded.
static ModuleFileName makeImplicit(std::string Name, unsigned SuffixLength)
Creates a file name for an implicit module.
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
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