23 #include "llvm/ADT/APInt.h"
24 #include "llvm/ADT/Hashing.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/Support/Capacity.h"
27 #include "llvm/Support/FileSystem.h"
28 #include "llvm/Support/Path.h"
31 #if defined(LLVM_ON_UNIX)
34 using namespace clang;
40 assert(External &&
"We must have an external source if we have a "
41 "controlling macro that is out of date.");
57 HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
61 : HSOpts(std::move(HSOpts)), Diags(Diags),
62 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
63 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {
66 NoCurDirSearch =
false;
68 ExternalLookup =
nullptr;
69 ExternalSource =
nullptr;
71 NumMultiIncludeFileOptzn = 0;
72 NumFrameworkLookups = NumSubFrameworkLookups = 0;
77 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
78 delete HeaderMaps[i].second;
82 fprintf(stderr,
"\n*** HeaderSearch Stats:\n");
83 fprintf(stderr,
"%d files tracked.\n", (
int)FileInfo.size());
84 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
85 for (
unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
86 NumOnceOnlyFiles += FileInfo[i].isImport;
87 if (MaxNumIncludes < FileInfo[i].NumIncludes)
88 MaxNumIncludes = FileInfo[i].NumIncludes;
89 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
91 fprintf(stderr,
" %d #import/#pragma once files.\n", NumOnceOnlyFiles);
92 fprintf(stderr,
" %d included exactly once.\n", NumSingleIncludedFiles);
93 fprintf(stderr,
" %d max times a file is included.\n", MaxNumIncludes);
95 fprintf(stderr,
" %d #include/#include_next/#import.\n", NumIncluded);
96 fprintf(stderr,
" %d #includes skipped due to"
97 " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
99 fprintf(stderr,
"%d framework lookups.\n", NumFrameworkLookups);
100 fprintf(stderr,
"%d subframework lookups.\n", NumSubFrameworkLookups);
108 if (!HeaderMaps.empty()) {
109 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
112 if (HeaderMaps[i].first == FE)
113 return HeaderMaps[i].second;
117 HeaderMaps.push_back(std::make_pair(FE, HM));
127 for (
auto &HM : HeaderMaps)
128 Names.push_back(HM.first->getName());
139 StringRef ModuleMapPath,
140 bool UsePrebuiltPath) {
141 if (UsePrebuiltPath) {
142 if (HSOpts->PrebuiltModulePaths.empty())
143 return std::string();
146 for (
const std::string &Dir : HSOpts->PrebuiltModulePaths) {
148 llvm::sys::fs::make_absolute(Result);
150 llvm::sys::path::append(Result, ModuleName +
".pcm");
152 return Result.str().str();
154 return std::string();
160 return std::string();
163 llvm::sys::fs::make_absolute(Result);
165 if (HSOpts->DisableModuleHash) {
166 llvm::sys::path::append(Result, ModuleName +
".pcm");
175 std::string Parent = llvm::sys::path::parent_path(ModuleMapPath);
180 return std::string();
182 auto FileName = llvm::sys::path::filename(ModuleMapPath);
184 llvm::hash_code Hash =
185 llvm::hash_combine(DirName.lower(),
FileName.lower());
188 llvm::APInt(64,
size_t(Hash)).toStringUnsigned(HashStr, 36);
189 llvm::sys::path::append(Result, ModuleName +
"-" + HashStr +
".pcm");
191 return Result.str().str();
197 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
200 StringRef SearchName = ModuleName;
210 if (!Module && SearchName.consume_back(
"Private"))
220 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
221 if (SearchDirs[Idx].isFramework()) {
226 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
227 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
232 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
241 if (!SearchDirs[Idx].isNormalDir())
244 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
247 false) == LMM_NewlyLoaded) {
258 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
259 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
261 false) == LMM_NewlyLoaded){
270 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
275 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
297 assert(
isHeaderMap() &&
"Unknown DirectoryLookup");
301 const FileEntry *HeaderSearch::getFileAndSuggestModule(
303 bool IsSystemHeaderDir, Module *RequestingModule,
312 if (!findUsableModuleForHeader(File, Dir ? Dir : File->
getDir(),
313 RequestingModule, SuggestedModule,
328 Module *RequestingModule,
330 bool &InUserSpecifiedSystemFramework,
333 InUserSpecifiedSystemFramework =
false;
334 HasBeenMapped =
false;
340 llvm::sys::path::append(TmpDir, Filename);
344 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
347 RelativePath->clear();
348 RelativePath->append(Filename.begin(), Filename.end());
351 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc,
getDir(),
353 RequestingModule, SuggestedModule);
357 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
358 RequestingModule, SuggestedModule,
359 InUserSpecifiedSystemFramework);
361 assert(
isHeaderMap() &&
"Unknown directory lookup");
373 if (llvm::sys::path::is_relative(Dest)) {
375 MappedName.append(Dest.begin(), Dest.end());
376 Filename = StringRef(MappedName.begin(), MappedName.size());
377 HasBeenMapped =
true;
386 StringRef SearchPathRef(
getName());
388 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
391 RelativePath->clear();
392 RelativePath->append(Filename.begin(), Filename.end());
407 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
408 "Not a framework directory");
428 DirName = llvm::sys::path::parent_path(DirName);
439 if (llvm::sys::path::extension(DirName) ==
".framework") {
440 SubmodulePath.push_back(llvm::sys::path::stem(DirName));
441 TopFrameworkDir = Dir;
445 return TopFrameworkDir;
449 bool HasSuggestedModule) {
450 return HasSuggestedModule ||
456 const FileEntry *DirectoryLookup::DoFrameworkLookup(
460 bool &InUserSpecifiedSystemFramework)
const {
464 size_t SlashPos = Filename.find(
'/');
465 if (SlashPos == StringRef::npos)
return nullptr;
469 HeaderSearch::FrameworkCacheEntry &CacheEntry =
481 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
482 FrameworkName.push_back(
'/');
485 StringRef ModuleName(Filename.begin(), SlashPos);
486 FrameworkName += ModuleName;
489 FrameworkName +=
".framework/";
492 if (!CacheEntry.Directory) {
497 if (!Dir)
return nullptr;
507 SystemFrameworkMarker +=
".system_framework";
508 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
509 CacheEntry.IsUserSpecifiedSystemFramework =
true;
515 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
518 RelativePath->clear();
519 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
523 unsigned OrigSize = FrameworkName.size();
525 FrameworkName +=
"Headers/";
530 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
533 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
538 const char *Private =
"Private";
539 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
540 Private+strlen(Private));
542 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
543 Private+strlen(Private));
545 FE = FileMgr.
getFile(FrameworkName, !SuggestedModule);
552 bool FoundFramework =
false;
561 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
562 FoundFramework =
true;
567 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
568 if (FrameworkPath.empty())
573 if (FoundFramework) {
574 if (!HS.findUsableModuleForFrameworkHeader(
575 FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
578 if (!HS.findUsableModuleForHeader(FE,
getDir(), RequestingModule,
579 SuggestedModule, IsSystem))
601 if (MSFE && FE != MSFE) {
602 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
608 static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
609 assert(!Str.empty());
610 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
611 std::copy(Str.begin(), Str.end(), CopyStr);
612 CopyStr[Str.size()] =
'\0';
624 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
627 bool *IsMapped,
bool SkipCache,
bool BuildSystemModule) {
635 if (llvm::sys::path::is_absolute(Filename)) {
639 if (FromDir)
return nullptr;
644 RelativePath->clear();
645 RelativePath->append(Filename.begin(), Filename.end());
648 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
650 RequestingModule, SuggestedModule);
662 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
665 for (
const auto &IncluderAndDir : Includers) {
666 const FileEntry *Includer = IncluderAndDir.first;
670 TmpDir = IncluderAndDir.second->getName();
671 TmpDir.push_back(
'/');
672 TmpDir.append(Filename.begin(), Filename.end());
681 bool IncluderIsSystemHeader =
684 if (
const FileEntry *FE = getFileAndSuggestModule(
685 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
686 RequestingModule, SuggestedModule)) {
688 assert(First &&
"only first includer can have no file");
699 unsigned DirInfo = FromHFI.
DirInfo;
709 StringRef SearchPathRef(IncluderAndDir.second->getName());
711 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
714 RelativePath->clear();
715 RelativePath->append(Filename.begin(), Filename.end());
723 if (Diags.
isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
727 if (SuggestedModule) {
728 MSSuggestedModule = *SuggestedModule;
741 unsigned i = isAngled ? AngledDirIdx : 0;
746 i = FromDir-&SearchDirs[0];
752 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
757 if (!SkipCache && CacheLookup.StartIdx == i+1) {
759 i = CacheLookup.HitIdx;
760 if (CacheLookup.MappedName) {
761 Filename = CacheLookup.MappedName;
769 CacheLookup.reset(i+1);
775 for (; i != SearchDirs.size(); ++i) {
776 bool InUserSpecifiedSystemFramework =
false;
777 bool HasBeenMapped =
false;
778 const FileEntry *FE = SearchDirs[i].LookupFile(
779 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
780 SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
783 CacheLookup.MappedName =
784 copyString(Filename, LookupFileCache.getAllocator());
790 CurDir = &SearchDirs[i];
804 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
805 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
815 size_t SlashPos = Filename.find(
'/');
816 if (SlashPos != StringRef::npos) {
825 *SuggestedModule = MSSuggestedModule;
830 CacheLookup.HitIdx = i;
838 if (!Includers.empty() && Includers.front().first && !isAngled &&
839 Filename.find(
'/') == StringRef::npos) {
843 ScratchFilename += IncludingHFI.
Framework;
844 ScratchFilename +=
'/';
848 LookupFile(ScratchFilename, IncludeLoc,
true, FromDir,
849 CurDir, Includers.front(), SearchPath, RelativePath,
850 RequestingModule, SuggestedModule, IsMapped);
854 *SuggestedModule = MSSuggestedModule;
858 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
859 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
867 *SuggestedModule = MSSuggestedModule;
872 CacheLookup.HitIdx = SearchDirs.size();
886 Module *RequestingModule,
888 assert(ContextFileEnt &&
"No context file?");
892 size_t SlashPos = Filename.find(
'/');
893 if (SlashPos == StringRef::npos)
return nullptr;
896 StringRef ContextName = ContextFileEnt->
getName();
899 const unsigned DotFrameworkLen = 10;
900 auto FrameworkPos = ContextName.find(
".framework");
901 if (FrameworkPos == StringRef::npos ||
902 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
903 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
908 DotFrameworkLen + 1);
911 FrameworkName +=
"Frameworks/";
912 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
913 FrameworkName +=
".framework/";
916 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
917 FrameworkCacheEntry())).first;
920 if (CacheLookup.second.Directory &&
921 CacheLookup.first().size() == FrameworkName.size() &&
922 memcmp(CacheLookup.first().data(), &FrameworkName[0],
923 CacheLookup.first().size()) != 0)
927 if (!CacheLookup.second.Directory) {
928 ++NumSubFrameworkLookups;
932 if (!Dir)
return nullptr;
936 CacheLookup.second.Directory = Dir;
942 RelativePath->clear();
943 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
948 HeadersFilename +=
"Headers/";
952 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
955 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
956 if (!(FE = FileMgr.
getFile(HeadersFilename,
true))) {
959 HeadersFilename = FrameworkName;
960 HeadersFilename +=
"PrivateHeaders/";
964 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
967 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
968 if (!(FE = FileMgr.
getFile(HeadersFilename,
true)))
980 FrameworkName.pop_back();
981 if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
982 SuggestedModule,
false))
996 assert(OtherHFI.
External &&
"expected to merge external HFI");
1020 if (FE->
getUID() >= FileInfo.size())
1021 FileInfo.resize(FE->
getUID() + 1);
1025 if (ExternalSource && !HFI->
Resolved) {
1029 HFI = &FileInfo[FE->
getUID()];
1030 if (ExternalHFI.External)
1043 bool WantExternal)
const {
1047 if (ExternalSource) {
1048 if (FE->
getUID() >= FileInfo.size()) {
1051 FileInfo.resize(FE->
getUID() + 1);
1054 HFI = &FileInfo[FE->
getUID()];
1061 HFI = &FileInfo[FE->
getUID()];
1062 if (ExternalHFI.External)
1065 }
else if (FE->
getUID() >= FileInfo.size()) {
1068 HFI = &FileInfo[FE->
getUID()];
1080 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1081 HFI->ControllingMacroID;
1087 bool isCompilingModuleHeader) {
1091 if (!isCompilingModuleHeader) {
1092 if (!isModularHeader)
1095 if (HFI && HFI->isModuleHeader)
1100 HFI.isModuleHeader |= isModularHeader;
1101 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1106 bool ModulesEnabled, Module *M) {
1114 auto TryEnterImported = [&](void) ->
bool {
1115 if (!ModulesEnabled)
1136 bool TryEnterHdr =
false;
1140 llvm::sys::path::filename(File->
getName()));
1164 if (FileInfo.
isImport && !TryEnterImported())
1177 ++NumMultiIncludeFileOptzn;
1189 return SearchDirs.capacity()
1190 + llvm::capacity_in_bytes(FileInfo)
1191 + llvm::capacity_in_bytes(HeaderMaps)
1192 + LookupFileCache.getAllocator().getTotalMemory()
1193 + FrameworkMap.getAllocator().getTotalMemory();
1197 return FrameworkNames.insert(Framework).first->first();
1203 if (!HSOpts->ImplicitModuleMaps)
1211 DirName = llvm::sys::path::parent_path(DirName);
1212 if (DirName.empty())
1222 llvm::sys::path::extension(Dir->
getName()) ==
1224 case LMM_NewlyLoaded:
1225 case LMM_AlreadyLoaded:
1228 for (
unsigned I = 0, N = FixUpDirectories.size();
I != N; ++
I)
1229 DirectoryHasModuleMap[FixUpDirectories[
I]] =
true;
1232 case LMM_NoDirectory:
1233 case LMM_InvalidModuleMap:
1243 FixUpDirectories.push_back(Dir);
1249 bool AllowTextual)
const {
1250 if (ExternalSource) {
1259 Module *RequestingModule,
1263 if (SuggestedModule)
1280 bool HeaderSearch::findUsableModuleForHeader(
1286 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1291 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1292 const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
1302 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1306 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1312 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1319 StringRef Filename = llvm::sys::path::filename(File->
getName());
1321 if (Filename ==
"module.map")
1322 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1323 else if (Filename ==
"module.modulemap")
1324 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1327 return FileMgr.
getFile(PrivateFilename);
1332 StringRef OriginalModuleMapFile) {
1339 if (!OriginalModuleMapFile.empty()) {
1343 llvm::sys::path::parent_path(OriginalModuleMapFile));
1345 auto *FakeFile = FileMgr.
getVirtualFile(OriginalModuleMapFile, 0, 0);
1346 Dir = FakeFile->getDir();
1352 StringRef DirName(Dir->
getName());
1353 if (llvm::sys::path::filename(DirName) ==
"Modules") {
1354 DirName = llvm::sys::path::parent_path(DirName);
1355 if (DirName.endswith(
".framework"))
1359 assert(Dir &&
"parent must exist");
1363 switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1364 case LMM_AlreadyLoaded:
1365 case LMM_NewlyLoaded:
1367 case LMM_NoDirectory:
1368 case LMM_InvalidModuleMap:
1371 llvm_unreachable(
"Unknown load module map result");
1374 HeaderSearch::LoadModuleMapResult
1375 HeaderSearch::loadModuleMapFileImpl(
const FileEntry *File,
bool IsSystem,
1378 assert(File &&
"expected FileEntry");
1382 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File,
true));
1383 if (!AddResult.second)
1384 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1387 LoadedModuleMaps[File] =
false;
1388 return LMM_InvalidModuleMap;
1394 LoadedModuleMaps[File] =
false;
1395 return LMM_InvalidModuleMap;
1400 return LMM_NewlyLoaded;
1405 if (!HSOpts->ImplicitModuleMaps)
1411 llvm::sys::path::append(ModuleMapFileName,
"Modules");
1412 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1417 ModuleMapFileName = Dir->
getName();
1418 llvm::sys::path::append(ModuleMapFileName,
"module.map");
1419 return FileMgr.
getFile(ModuleMapFileName);
1422 Module *HeaderSearch::loadFrameworkModule(StringRef
Name,
1425 if (Module *Module = ModMap.
findModule(Name))
1430 case LMM_InvalidModuleMap:
1432 if (HSOpts->ImplicitModuleMaps)
1433 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1436 case LMM_AlreadyLoaded:
1437 case LMM_NoDirectory:
1440 case LMM_NewlyLoaded:
1448 HeaderSearch::LoadModuleMapResult
1454 return LMM_NoDirectory;
1457 HeaderSearch::LoadModuleMapResult
1460 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1461 if (KnownDir != DirectoryHasModuleMap.end())
1462 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1465 LoadModuleMapResult
Result =
1466 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1470 if (Result == LMM_NewlyLoaded)
1471 DirectoryHasModuleMap[Dir] =
true;
1472 else if (Result == LMM_InvalidModuleMap)
1473 DirectoryHasModuleMap[Dir] =
false;
1476 return LMM_InvalidModuleMap;
1482 if (HSOpts->ImplicitModuleMaps) {
1484 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1485 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1486 if (SearchDirs[Idx].isFramework()) {
1489 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
1495 Dir != DirEnd && !EC; Dir.increment(EC)) {
1496 if (llvm::sys::path::extension(Dir->
getName()) !=
".framework")
1505 loadFrameworkModule(llvm::sys::path::stem(Dir->
getName()),
1506 FrameworkDir, IsSystem);
1512 if (SearchDirs[Idx].isHeaderMap())
1521 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1529 Modules.push_back(M->getValue());
1534 if (!HSOpts->ImplicitModuleMaps)
1538 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1540 if (!SearchDirs[Idx].isNormalDir()) {
1546 SearchDirs[Idx].isSystemHeaderDirectory(),
1547 SearchDirs[Idx].isFramework());
1551 void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
1552 assert(HSOpts->ImplicitModuleMaps &&
1553 "Should not be loading subdirectory module maps");
1560 llvm::sys::path::native(SearchDir.
getDir()->
getName(), DirNative);
1563 Dir != DirEnd && !EC; Dir.increment(EC)) {
1565 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1579 StringRef Name = File->
getName();
1581 unsigned BestPrefixLength = 0;
1582 unsigned BestSearchDir;
1584 for (
unsigned I = 0;
I != SearchDirs.size(); ++
I) {
1586 if (!SearchDirs[
I].isNormalDir())
1589 StringRef Dir = SearchDirs[
I].getDir()->getName();
1590 for (
auto NI = llvm::sys::path::begin(Name),
1591 NE = llvm::sys::path::end(Name),
1592 DI = llvm::sys::path::begin(Dir),
1593 DE = llvm::sys::path::end(Dir);
1596 while (NI != NE && *NI ==
".")
1602 while (DI != DE && *DI ==
".")
1607 unsigned PrefixLength = NI - llvm::sys::path::begin(Name);
1608 if (PrefixLength > BestPrefixLength) {
1609 BestPrefixLength = PrefixLength;
1621 *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx :
false;
1622 return Name.drop_front(BestPrefixLength);
std::string Name
The name of this module.
module_iterator module_begin() const
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
This header is part of the module (for layering purposes) but should be textually included...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
virtual IdentifierInfo * GetIdentifier(unsigned ID)=0
Return the identifier associated with the given ID number.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
The virtual file system interface.
One of these records is kept for each identifier that is lexed.
bool isFramework() const
isFramework - True if this is a framework directory.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
Concrete class used by the front-end to report problems and issues.
bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M)
Determine whether II is defined as a macro within the module M, if that is a module that we've alread...
module_iterator module_end() const
StringRef getName() const
detail::InMemoryDirectory::const_iterator I
void setTarget(const TargetInfo &Target)
Set the target information.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules...
llvm::StringMap< Module * >::const_iterator module_iterator
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
bool parseModuleMapFile(const FileEntry *File, bool IsSystem, const DirectoryEntry *HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
const HeaderMap * getHeaderMap() const
getHeaderMap - Return the directory that this entry refers to.
ModuleHeaderRole
Flags describing the role of a module header.
Exposes information about the current target.
Abstract interface for external sources of preprocessor information.
bool isSystemHeaderDirectory() const
Whether this describes a system header directory.
Defines the clang::Preprocessor interface.
bool isNormalDir() const
isNormalDir - Return true if this is a normal directory, not a header map.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false)
Retrieve the module that owns the given header file, if any.
const FileEntry * LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &HasBeenMapped, SmallVectorImpl< char > &MappedName) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
The result type of a method or function.
const DirectoryEntry * getBuiltinDir() const
Get the directory that contains Clang-supplied include files.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
bool haveSearchedAllModuleMaps() const
Determine whether we have already searched this entire directory for module maps. ...
const DirectoryEntry * getFrameworkDir() const
getFrameworkDir - Return the directory that this framework refers to.
Encodes a location in the source.
Cached information about one file (either on disk or in the virtual file system). ...
const FileEntry * getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
bool isMacroDefined(StringRef Id)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
StringRef getName() const
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)=0
Update an out-of-date identifier.
Cached information about one directory (either on disk or in the virtual file system).
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
bool isIndexHeaderMap() const
Whether this header map is building a framework or not.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
void setSearchedAllModuleMaps(bool SAMM)
Specify whether we have already searched all of the subdirectories for module maps.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.