28 #include "llvm/ADT/APInt.h" 29 #include "llvm/ADT/Hashing.h" 30 #include "llvm/ADT/SmallString.h" 31 #include "llvm/ADT/SmallVector.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/Support/Allocator.h" 34 #include "llvm/Support/Capacity.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include "llvm/Support/FileSystem.h" 37 #include "llvm/Support/Path.h" 44 #include <system_error> 47 using namespace clang;
53 assert(External &&
"We must have an external source if we have a " 54 "controlling macro that is out of date.");
74 : HSOpts(
std::move(HSOpts)), Diags(Diags),
75 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
76 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
80 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
81 delete HeaderMaps[i].second;
85 fprintf(stderr,
"\n*** HeaderSearch Stats:\n");
86 fprintf(stderr,
"%d files tracked.\n", (
int)FileInfo.size());
87 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
88 for (
unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
89 NumOnceOnlyFiles += FileInfo[i].isImport;
90 if (MaxNumIncludes < FileInfo[i].NumIncludes)
91 MaxNumIncludes = FileInfo[i].NumIncludes;
92 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
94 fprintf(stderr,
" %d #import/#pragma once files.\n", NumOnceOnlyFiles);
95 fprintf(stderr,
" %d included exactly once.\n", NumSingleIncludedFiles);
96 fprintf(stderr,
" %d max times a file is included.\n", MaxNumIncludes);
98 fprintf(stderr,
" %d #include/#include_next/#import.\n", NumIncluded);
99 fprintf(stderr,
" %d #includes skipped due to" 100 " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
102 fprintf(stderr,
"%d framework lookups.\n", NumFrameworkLookups);
103 fprintf(stderr,
"%d subframework lookups.\n", NumSubFrameworkLookups);
111 if (!HeaderMaps.empty()) {
112 for (
unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
115 if (HeaderMaps[i].first == FE)
116 return HeaderMaps[i].second;
120 HeaderMaps.push_back(std::make_pair(FE, HM));
130 for (
auto &HM : HeaderMaps)
131 Names.push_back(HM.first->getName());
143 auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
144 if (i != HSOpts->PrebuiltModuleFiles.end())
147 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
152 for (
const std::string &Dir : HSOpts->PrebuiltModulePaths) {
154 llvm::sys::fs::make_absolute(Result);
155 llvm::sys::path::append(Result, ModuleName +
".pcm");
157 return Result.str().str();
163 StringRef ModuleMapPath) {
170 llvm::sys::fs::make_absolute(Result);
172 if (HSOpts->DisableModuleHash) {
173 llvm::sys::path::append(Result, ModuleName +
".pcm");
182 std::string
Parent = llvm::sys::path::parent_path(ModuleMapPath);
189 auto FileName = llvm::sys::path::filename(ModuleMapPath);
191 llvm::hash_code Hash =
195 llvm::APInt(64,
size_t(Hash)).toStringUnsigned(HashStr, 36);
196 llvm::sys::path::append(Result, ModuleName +
"-" + HashStr +
".pcm");
198 return Result.str().str();
204 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
207 StringRef SearchName = ModuleName;
218 if (!Module && SearchName.consume_back(
"_Private"))
220 if (!Module && SearchName.consume_back(
"Private"))
230 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
231 if (SearchDirs[Idx].isFramework()) {
236 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
237 llvm::sys::path::append(FrameworkDirName, SearchName +
".framework");
242 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
251 if (!SearchDirs[Idx].isNormalDir())
254 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
257 false) == LMM_NewlyLoaded) {
268 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
269 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
271 false) == LMM_NewlyLoaded){
280 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
285 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
304 return getDir()->getName();
306 return getFrameworkDir()->getName();
307 assert(isHeaderMap() &&
"Unknown DirectoryLookup");
308 return getHeaderMap()->getFileName();
311 const FileEntry *HeaderSearch::getFileAndSuggestModule(
313 bool IsSystemHeaderDir,
Module *RequestingModule,
322 if (!findUsableModuleForHeader(File, Dir ? Dir : File->
getDir(),
323 RequestingModule, SuggestedModule,
340 bool &InUserSpecifiedSystemFramework,
343 InUserSpecifiedSystemFramework =
false;
344 HasBeenMapped =
false;
349 TmpDir = getDir()->getName();
350 llvm::sys::path::append(TmpDir, Filename);
352 StringRef SearchPathRef(getDir()->getName());
354 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
357 RelativePath->clear();
358 RelativePath->append(Filename.begin(), Filename.end());
361 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
362 isSystemHeaderDirectory(),
363 RequestingModule, SuggestedModule);
367 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
368 RequestingModule, SuggestedModule,
369 InUserSpecifiedSystemFramework);
371 assert(isHeaderMap() &&
"Unknown directory lookup");
383 if (llvm::sys::path::is_relative(Dest)) {
385 MappedName.append(Dest.begin(), Dest.end());
386 Filename = StringRef(MappedName.begin(), MappedName.size());
387 HasBeenMapped =
true;
395 StringRef SearchPathRef(getName());
397 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
400 RelativePath->clear();
401 RelativePath->append(Filename.begin(), Filename.end());
416 assert(llvm::sys::path::extension(DirName) ==
".framework" &&
417 "Not a framework directory");
437 DirName = llvm::sys::path::parent_path(DirName);
448 if (llvm::sys::path::extension(DirName) ==
".framework") {
449 SubmodulePath.push_back(llvm::sys::path::stem(DirName));
450 TopFrameworkDir = Dir;
454 return TopFrameworkDir;
458 bool HasSuggestedModule) {
459 return HasSuggestedModule ||
465 const FileEntry *DirectoryLookup::DoFrameworkLookup(
469 bool &InUserSpecifiedSystemFramework)
const {
473 size_t SlashPos =
Filename.find(
'/');
474 if (SlashPos == StringRef::npos)
return nullptr;
478 HeaderSearch::FrameworkCacheEntry &CacheEntry =
482 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
489 FrameworkName += getFrameworkDir()->getName();
490 if (FrameworkName.empty() || FrameworkName.back() !=
'/')
491 FrameworkName.push_back(
'/');
494 StringRef ModuleName(
Filename.begin(), SlashPos);
495 FrameworkName += ModuleName;
498 FrameworkName +=
".framework/";
501 if (!CacheEntry.Directory) {
506 if (!Dir)
return nullptr;
510 CacheEntry.Directory = getFrameworkDir();
516 SystemFrameworkMarker +=
".system_framework";
517 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
518 CacheEntry.IsUserSpecifiedSystemFramework =
true;
524 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
527 RelativePath->clear();
532 unsigned OrigSize = FrameworkName.size();
534 FrameworkName +=
"Headers/";
539 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
547 const char *Private =
"Private";
548 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
549 Private+strlen(Private));
551 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
552 Private+strlen(Private));
554 FE = FileMgr.
getFile(FrameworkName, !SuggestedModule);
561 bool FoundFramework =
false;
570 if (llvm::sys::path::extension(FrameworkPath) ==
".framework") {
571 FoundFramework =
true;
576 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
577 if (FrameworkPath.empty())
582 if (FoundFramework) {
583 if (!HS.findUsableModuleForFrameworkHeader(
584 FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
587 if (!HS.findUsableModuleForHeader(FE, getDir(), RequestingModule,
588 SuggestedModule, IsSystem))
609 if (MSFE && FE != MSFE) {
610 Diags.
Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->
getName();
616 static const char *
copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
617 assert(!Str.empty());
618 char *CopyStr = Alloc.Allocate<
char>(Str.size()+1);
619 std::copy(Str.begin(), Str.end(), CopyStr);
620 CopyStr[Str.size()] =
'\0';
632 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
635 bool *IsMapped,
bool SkipCache,
bool BuildSystemModule) {
643 if (llvm::sys::path::is_absolute(Filename)) {
647 if (FromDir)
return nullptr;
652 RelativePath->clear();
653 RelativePath->append(Filename.begin(), Filename.end());
656 return getFileAndSuggestModule(Filename, IncludeLoc,
nullptr,
658 RequestingModule, SuggestedModule);
670 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
673 for (
const auto &IncluderAndDir : Includers) {
674 const FileEntry *Includer = IncluderAndDir.first;
678 TmpDir = IncluderAndDir.second->getName();
679 TmpDir.push_back(
'/');
680 TmpDir.append(Filename.begin(), Filename.end());
689 bool IncluderIsSystemHeader =
692 if (
const FileEntry *FE = getFileAndSuggestModule(
693 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
694 RequestingModule, SuggestedModule)) {
696 assert(First &&
"only first includer can have no file");
707 unsigned DirInfo = FromHFI.
DirInfo;
717 StringRef SearchPathRef(IncluderAndDir.second->getName());
719 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
722 RelativePath->clear();
723 RelativePath->append(Filename.begin(), Filename.end());
731 if (Diags.
isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
735 if (SuggestedModule) {
736 MSSuggestedModule = *SuggestedModule;
749 unsigned i = isAngled ? AngledDirIdx : 0;
754 i = FromDir-&SearchDirs[0];
760 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
765 if (!SkipCache && CacheLookup.StartIdx == i+1) {
767 i = CacheLookup.HitIdx;
768 if (CacheLookup.MappedName) {
769 Filename = CacheLookup.MappedName;
777 CacheLookup.reset(i+1);
783 for (; i != SearchDirs.size(); ++i) {
784 bool InUserSpecifiedSystemFramework =
false;
785 bool HasBeenMapped =
false;
786 const FileEntry *FE = SearchDirs[i].LookupFile(
787 Filename, *
this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
788 SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
791 CacheLookup.MappedName =
792 copyString(Filename, LookupFileCache.getAllocator());
798 CurDir = &SearchDirs[i];
812 for (
unsigned j = SystemHeaderPrefixes.size(); j; --j) {
813 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
823 size_t SlashPos = Filename.find(
'/');
824 if (SlashPos != StringRef::npos) {
833 *SuggestedModule = MSSuggestedModule;
838 CacheLookup.HitIdx = i;
846 if (!Includers.empty() && Includers.front().first && !isAngled &&
847 Filename.find(
'/') == StringRef::npos) {
851 ScratchFilename += IncludingHFI.
Framework;
852 ScratchFilename +=
'/';
856 LookupFile(ScratchFilename, IncludeLoc,
true, FromDir,
857 CurDir, Includers.front(), SearchPath, RelativePath,
858 RequestingModule, SuggestedModule, IsMapped);
862 *SuggestedModule = MSSuggestedModule;
866 LookupFileCacheInfo &CacheLookup = LookupFileCache[
Filename];
867 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
875 *SuggestedModule = MSSuggestedModule;
880 CacheLookup.HitIdx = SearchDirs.size();
896 assert(ContextFileEnt &&
"No context file?");
900 size_t SlashPos = Filename.find(
'/');
901 if (SlashPos == StringRef::npos)
return nullptr;
904 StringRef ContextName = ContextFileEnt->
getName();
907 const unsigned DotFrameworkLen = 10;
908 auto FrameworkPos = ContextName.find(
".framework");
909 if (FrameworkPos == StringRef::npos ||
910 (ContextName[FrameworkPos + DotFrameworkLen] !=
'/' &&
911 ContextName[FrameworkPos + DotFrameworkLen] !=
'\\'))
916 DotFrameworkLen + 1);
919 FrameworkName +=
"Frameworks/";
920 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
921 FrameworkName +=
".framework/";
924 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
925 FrameworkCacheEntry())).first;
928 if (CacheLookup.second.Directory &&
929 CacheLookup.first().size() == FrameworkName.size() &&
930 memcmp(CacheLookup.first().data(), &FrameworkName[0],
931 CacheLookup.first().size()) != 0)
935 if (!CacheLookup.second.Directory) {
936 ++NumSubFrameworkLookups;
940 if (!Dir)
return nullptr;
944 CacheLookup.second.Directory = Dir;
950 RelativePath->clear();
951 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
956 HeadersFilename +=
"Headers/";
960 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
963 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
964 if (!(FE = FileMgr.
getFile(HeadersFilename,
true))) {
966 HeadersFilename = FrameworkName;
967 HeadersFilename +=
"PrivateHeaders/";
971 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
974 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
975 if (!(FE = FileMgr.
getFile(HeadersFilename,
true)))
987 FrameworkName.pop_back();
988 if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
989 SuggestedModule,
false))
1003 assert(OtherHFI.
External &&
"expected to merge external HFI");
1027 if (FE->
getUID() >= FileInfo.size())
1028 FileInfo.resize(FE->
getUID() + 1);
1032 if (ExternalSource && !HFI->
Resolved) {
1036 HFI = &FileInfo[FE->
getUID()];
1037 if (ExternalHFI.External)
1050 bool WantExternal)
const {
1054 if (ExternalSource) {
1055 if (FE->
getUID() >= FileInfo.size()) {
1058 FileInfo.resize(FE->
getUID() + 1);
1061 HFI = &FileInfo[FE->
getUID()];
1068 HFI = &FileInfo[FE->
getUID()];
1069 if (ExternalHFI.External)
1072 }
else if (FE->
getUID() >= FileInfo.size()) {
1075 HFI = &FileInfo[FE->
getUID()];
1087 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1088 HFI->ControllingMacroID;
1094 bool isCompilingModuleHeader) {
1098 if (!isCompilingModuleHeader) {
1099 if (!isModularHeader)
1102 if (HFI && HFI->isModuleHeader)
1107 HFI.isModuleHeader |= isModularHeader;
1108 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1113 bool ModulesEnabled,
Module *M) {
1121 auto TryEnterImported = [&]() ->
bool {
1122 if (!ModulesEnabled)
1143 bool TryEnterHdr =
false;
1147 llvm::sys::path::filename(File->
getName()));
1171 if (FileInfo.
isImport && !TryEnterImported())
1184 ++NumMultiIncludeFileOptzn;
1196 return SearchDirs.capacity()
1197 + llvm::capacity_in_bytes(FileInfo)
1198 + llvm::capacity_in_bytes(HeaderMaps)
1199 + LookupFileCache.getAllocator().getTotalMemory()
1200 + FrameworkMap.getAllocator().getTotalMemory();
1204 return FrameworkNames.insert(Framework).first->first();
1210 if (!HSOpts->ImplicitModuleMaps)
1215 StringRef DirName = FileName;
1218 DirName = llvm::sys::path::parent_path(DirName);
1219 if (DirName.empty())
1229 llvm::sys::path::extension(Dir->
getName()) ==
1231 case LMM_NewlyLoaded:
1232 case LMM_AlreadyLoaded:
1235 for (
unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1236 DirectoryHasModuleMap[FixUpDirectories[I]] =
true;
1239 case LMM_NoDirectory:
1240 case LMM_InvalidModuleMap:
1250 FixUpDirectories.push_back(Dir);
1256 bool AllowTextual)
const {
1257 if (ExternalSource) {
1266 Module *RequestingModule,
1270 if (SuggestedModule)
1287 bool HeaderSearch::findUsableModuleForHeader(
1293 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1298 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1299 const FileEntry *File, StringRef FrameworkName,
Module *RequestingModule,
1309 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->
getName());
1313 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1319 return suggestModule(*
this, File, RequestingModule, SuggestedModule);
1328 if (Filename ==
"module.map")
1329 llvm::sys::path::append(PrivateFilename,
"module_private.map");
1330 else if (Filename ==
"module.modulemap")
1331 llvm::sys::path::append(PrivateFilename,
"module.private.modulemap");
1334 return FileMgr.
getFile(PrivateFilename);
1339 StringRef OriginalModuleMapFile) {
1346 if (!OriginalModuleMapFile.empty()) {
1350 llvm::sys::path::parent_path(OriginalModuleMapFile));
1352 auto *FakeFile = FileMgr.
getVirtualFile(OriginalModuleMapFile, 0, 0);
1353 Dir = FakeFile->getDir();
1359 StringRef DirName(Dir->
getName());
1360 if (llvm::sys::path::filename(DirName) ==
"Modules") {
1361 DirName = llvm::sys::path::parent_path(DirName);
1362 if (DirName.endswith(
".framework"))
1366 assert(Dir &&
"parent must exist");
1370 switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
1371 case LMM_AlreadyLoaded:
1372 case LMM_NewlyLoaded:
1374 case LMM_NoDirectory:
1375 case LMM_InvalidModuleMap:
1378 llvm_unreachable(
"Unknown load module map result");
1381 HeaderSearch::LoadModuleMapResult
1382 HeaderSearch::loadModuleMapFileImpl(
const FileEntry *File,
bool IsSystem,
1385 assert(File &&
"expected FileEntry");
1389 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File,
true));
1390 if (!AddResult.second)
1391 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1394 LoadedModuleMaps[File] =
false;
1395 return LMM_InvalidModuleMap;
1401 LoadedModuleMaps[File] =
false;
1402 return LMM_InvalidModuleMap;
1407 return LMM_NewlyLoaded;
1412 if (!HSOpts->ImplicitModuleMaps)
1418 llvm::sys::path::append(ModuleMapFileName,
"Modules");
1419 llvm::sys::path::append(ModuleMapFileName,
"module.modulemap");
1424 ModuleMapFileName = Dir->
getName();
1425 llvm::sys::path::append(ModuleMapFileName,
"module.map");
1426 return FileMgr.
getFile(ModuleMapFileName);
1429 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1437 case LMM_InvalidModuleMap:
1439 if (HSOpts->ImplicitModuleMaps)
1440 ModMap.inferFrameworkModule(Dir, IsSystem,
nullptr);
1443 case LMM_AlreadyLoaded:
1444 case LMM_NoDirectory:
1447 case LMM_NewlyLoaded:
1454 HeaderSearch::LoadModuleMapResult
1460 return LMM_NoDirectory;
1463 HeaderSearch::LoadModuleMapResult
1466 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1467 if (KnownDir != DirectoryHasModuleMap.end())
1468 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1471 LoadModuleMapResult
Result =
1472 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1476 if (Result == LMM_NewlyLoaded)
1477 DirectoryHasModuleMap[Dir] =
true;
1478 else if (Result == LMM_InvalidModuleMap)
1479 DirectoryHasModuleMap[Dir] =
false;
1482 return LMM_InvalidModuleMap;
1488 if (HSOpts->ImplicitModuleMaps) {
1490 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1491 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1492 if (SearchDirs[Idx].isFramework()) {
1495 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
1501 Dir != DirEnd && !EC; Dir.increment(EC)) {
1502 if (llvm::sys::path::extension(Dir->
getName()) !=
".framework")
1511 loadFrameworkModule(llvm::sys::path::stem(Dir->
getName()),
1512 FrameworkDir, IsSystem);
1518 if (SearchDirs[Idx].isHeaderMap())
1527 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1535 Modules.push_back(M->getValue());
1540 if (!HSOpts->ImplicitModuleMaps)
1544 for (
unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1546 if (!SearchDirs[Idx].isNormalDir()) {
1552 SearchDirs[Idx].isSystemHeaderDirectory(),
1553 SearchDirs[Idx].isFramework());
1557 void HeaderSearch::loadSubdirectoryModuleMaps(
DirectoryLookup &SearchDir) {
1558 assert(HSOpts->ImplicitModuleMaps &&
1559 "Should not be loading subdirectory module maps");
1566 llvm::sys::path::native(SearchDir.
getDir()->
getName(), DirNative);
1569 Dir != DirEnd && !EC; Dir.increment(EC)) {
1571 llvm::sys::path::extension(Dir->
getName()) ==
".framework";
1585 StringRef Name = File->
getName();
1587 unsigned BestPrefixLength = 0;
1588 unsigned BestSearchDir;
1590 for (
unsigned I = 0; I != SearchDirs.size(); ++I) {
1592 if (!SearchDirs[I].isNormalDir())
1595 StringRef Dir = SearchDirs[I].getDir()->getName();
1596 for (
auto NI = llvm::sys::path::begin(Name),
1597 NE = llvm::sys::path::end(Name),
1598 DI = llvm::sys::path::begin(Dir),
1599 DE = llvm::sys::path::end(Dir);
1602 while (NI != NE && *NI ==
".")
1608 while (DI != DE && *DI ==
".")
1613 unsigned PrefixLength = NI - llvm::sys::path::begin(Name);
1614 if (PrefixLength > BestPrefixLength) {
1615 BestPrefixLength = PrefixLength;
1627 *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx :
false;
1628 return Name.drop_front(BestPrefixLength);
std::string Name
The name of this module.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool isIndexHeaderMap() const
Whether this header map is building a framework or not.
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
This header is part of the module (for layering purposes) but should be textually included...
Defines the SourceManager interface.
Defines the clang::Module class, which describes a module in the source code.
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
virtual IdentifierInfo * GetIdentifier(unsigned ID)=0
Return the identifier associated with the given ID number.
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
llvm::StringMap< Module * >::const_iterator module_iterator
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
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.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
Concrete class used by the front-end to report problems and issues.
bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M)
Determine whether II is defined as a macro within the module M, if that is a module that we've alread...
Defines the Diagnostic-related interfaces.
void setTarget(const TargetInfo &Target)
Set the target information.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules...
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
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.
ModuleHeaderRole
Flags describing the role of a module header.
Exposes information about the current target.
Abstract interface for external sources of preprocessor information.
Defines the clang::Preprocessor interface.
bool isFramework() const
isFramework - True if this is a framework directory.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false)
Retrieve the module that owns the given header file, if any.
module_iterator module_begin() const
const FileEntry * LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &HasBeenMapped, SmallVectorImpl< char > &MappedName) const
LookupFile - Lookup the specified file in this search path, returning it if it exists or returning nu...
The result type of a method or function.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
const DirectoryEntry * getDir() const
Return the directory the file lives in.
const DirectoryEntry * getBuiltinDir() const
Get the directory that contains Clang-supplied include files.
Encodes a location in the source.
bool isSystemHeaderDirectory() const
Whether this describes a system header directory.
StringRef getName() const
Cached information about one file (either on disk or in the virtual file system). ...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
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 haveSearchedAllModuleMaps() const
Determine whether we have already searched this entire directory for module maps. ...
module_iterator module_end() const
bool isMacroDefined(StringRef Id)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
Dataflow Directional Tag Classes.
Defines the virtual file system interface vfs::FileSystem.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)=0
Update an out-of-date identifier.
Cached information about one directory (either on disk or in the virtual file system).
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
void setSearchedAllModuleMaps(bool SAMM)
Specify whether we have already searched all of the subdirectories for module maps.
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
StringRef getName() const