clang: lib/Lex/HeaderSearch.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
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"
40#include
41#include
42#include
43#include
44#include
45#include
46#include <system_error>
47#include
48
49using namespace clang;
50
51#define DEBUG_TYPE "file-search"
52
55 NumMultiIncludeFileOptzn,
56 "Number of #includes skipped due to the multi-include optimization.");
59 "Number of subframework lookups.");
60
65 return nullptr;
66
70 }
71
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);
77 }
78 return ControllingMacro;
79}
80
82
87 : HSOpts(std::move(HSOpts)), Diags(Diags),
88 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
89 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
90
92 llvm::errs() << "\n*** HeaderSearch Stats:\n"
93 << FileInfo.size() << " files tracked.\n";
94 unsigned NumOnceOnlyFiles = 0;
95 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i)
96 NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
97 llvm::errs() << " " << NumOnceOnlyFiles << " #import/#pragma once files.\n";
98
99 llvm::errs() << " " << NumIncluded << " #include/#include_next/#import.\n"
100 << " " << NumMultiIncludeFileOptzn
101 << " #includes skipped due to the multi-include optimization.\n";
102
103 llvm::errs() << NumFrameworkLookups << " framework lookups.\n"
104 << NumSubFrameworkLookups << " subframework lookups.\n";
105}
106
108 std::vector dirs, unsigned int angledDirIdx,
109 unsigned int systemDirIdx,
110 llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
111 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
112 "Directory indices are unordered");
113 SearchDirs = std::move(dirs);
114 SearchDirsUsage.assign(SearchDirs.size(), false);
115 AngledDirIdx = angledDirIdx;
116 SystemDirIdx = systemDirIdx;
117 SearchDirToHSEntry = std::move(searchDirToHSEntry);
118
119 indexInitialHeaderMaps();
120}
121
123 unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
124 SearchDirs.insert(SearchDirs.begin() + idx, dir);
125 SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false);
126 if (!isAngled)
127 AngledDirIdx++;
128 SystemDirIdx++;
129}
130
132 std::vector UserEntryUsage(HSOpts->UserEntries.size());
133 for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
134
135 if (SearchDirsUsage[I]) {
136 auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
137
138 if (UserEntryIdxIt != SearchDirToHSEntry.end())
139 UserEntryUsage[UserEntryIdxIt->second] = true;
140 }
141 }
142 return UserEntryUsage;
143}
144
146 std::vector VFSUsage;
148 return VFSUsage;
149
151
152
153 RootFS.visit([&](llvm::vfs::FileSystem &FS) {
154 if (auto *RFS = dyn_castllvm::vfs::RedirectingFileSystem(&FS)) {
155 VFSUsage.push_back(RFS->hasBeenUsed());
156 RFS->clearHasBeenUsed();
157 }
158 });
159 assert(VFSUsage.size() == getHeaderSearchOpts().VFSOverlayFiles.size() &&
160 "A different number of RedirectingFileSystem's were present than "
161 "-ivfsoverlay options passed to Clang!");
162
163 std::reverse(VFSUsage.begin(), VFSUsage.end());
164 return VFSUsage;
165}
166
167
168
170
171
172 if (!HeaderMaps.empty()) {
173 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
174
175
176 if (HeaderMaps[i].first == FE)
177 return HeaderMaps[i].second.get();
178 }
179
180 if (std::unique_ptr HM = HeaderMap::Create(FE, FileMgr)) {
181 HeaderMaps.emplace_back(FE, std::move(HM));
182 return HeaderMaps.back().second.get();
183 }
184
185 return nullptr;
186}
187
188
191 for (auto &HM : HeaderMaps)
192 Names.push_back(std::string(HM.first.getName()));
193}
194
198
199
201 return {};
203}
204
206 bool FileMapOnly) {
207
208 auto i(HSOpts->PrebuiltModuleFiles.find(ModuleName));
209 if (i != HSOpts->PrebuiltModuleFiles.end())
210 return i->second;
211
212 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
213 return {};
214
215
216
217 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
219 llvm::sys::fs::make_absolute(Result);
220 if (ModuleName.contains(':'))
221
222
223
224 llvm::sys::path::append(Result, ModuleName.split(':').first + "-" +
225 ModuleName.split(':').second +
226 ".pcm");
227 else
228 llvm::sys::path::append(Result, ModuleName + ".pcm");
230 return std::string(Result);
231 }
232
233 return {};
234}
235
240 StringRef ModuleMapPath = ModuleMap->getName();
241 StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash();
242 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
244 llvm::sys::fs::make_absolute(CachePath);
245 llvm::sys::path::append(CachePath, ModuleCacheHash);
247 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
250 }
251 return {};
252}
253
255 StringRef ModuleMapPath) {
256 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
258}
259
260std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
261 StringRef ModuleMapPath,
262 StringRef CachePath) {
263
264
265 if (CachePath.empty())
266 return {};
267
269
270 if (HSOpts->DisableModuleHash) {
271 llvm::sys::path::append(Result, ModuleName + ".pcm");
272 } else {
273
274
275
276
277
278
279
281 if (getModuleMap().canonicalizeModuleMapPath(CanonicalPath))
282 return {};
283
284 auto Hash = llvm::xxh3_64bits(CanonicalPath.str().lower());
285
287 llvm::APInt(64, Hash).toStringUnsigned(HashStr, 36);
288 llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
289 }
290 return Result.str().str();
291}
292
295 bool AllowExtraModuleMapSearch) {
296
298 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
300
301 StringRef SearchName = ModuleName;
303 AllowExtraModuleMapSearch);
304
305
306
307
308
309
310
311
312
313 if ( && SearchName.consume_back("_Private"))
315 AllowExtraModuleMapSearch);
316 if ( && SearchName.consume_back("Private"))
318 AllowExtraModuleMapSearch);
320}
321
324 bool AllowExtraModuleMapSearch) {
326
327
328
330 if (Dir.isFramework()) {
331
332
333
335 FrameworkDirName += Dir.getFrameworkDirRef()->getName();
336 llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
337 if (auto FrameworkDir =
339 bool IsSystem = Dir.getDirCharacteristic() != SrcMgr::C_User;
340 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
342 break;
343 }
344 }
345
346
347
348
349 if (!Dir.isNormalDir())
350 continue;
351
352 bool IsSystem = Dir.isSystemHeaderDirectory();
353
354
356
358 false) == LMM_NewlyLoaded) {
359
360
363 break;
364 }
365
366
367
369 NestedModuleMapDirName = Dir.getDirRef()->getName();
370 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
372 false) == LMM_NewlyLoaded){
373
376 break;
377 }
378
379 if (HSOpts->AllowModuleMapSubdirectorySearch) {
380
381
382 if (Dir.haveSearchedAllModuleMaps())
383 continue;
384
385
386
387 if (AllowExtraModuleMapSearch)
388 loadSubdirectoryModuleMaps(Dir);
389
390
393 break;
394 }
395 }
396
398}
399
400void HeaderSearch::indexInitialHeaderMaps() {
401 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> Index(SearchDirs.size());
402
403
404 for (unsigned i = 0; i != SearchDirs.size(); ++i) {
405 auto &Dir = SearchDirs[i];
406
407
408
409
410 if (!Dir.isHeaderMap()) {
411 SearchDirHeaderMapIndex = std::move(Index);
412 FirstNonHeaderMapSearchDirIdx = i;
413 break;
414 }
415
416
417 auto Callback = [&](StringRef Filename) {
418 Index.try_emplace(Filename.lower(), i);
419 };
420 Dir.getHeaderMap()->forEachKey(Callback);
421 }
422}
423
424
425
426
427
428
429
435 assert(isHeaderMap() && "Unknown DirectoryLookup");
437}
438
441 bool IsSystemHeaderDir, Module *RequestingModule,
443 bool CacheFailures ) {
444
445
448
449
450 std::error_code EC = llvm::errorToErrorCode(File.takeError());
451 if (EC != llvm::errc::no_such_file_or_directory &&
452 EC != llvm::errc::invalid_argument &&
453 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
454 Diags.Report(IncludeLoc, diag::err_cannot_open_file)
456 }
457 return std::nullopt;
458 }
459
460
461 if (!findUsableModuleForHeader(
462 *File, Dir ? Dir : File->getFileEntry().getDir(), RequestingModule,
463 SuggestedModule, IsSystemHeaderDir))
464 return std::nullopt;
465
466 return *File;
467}
468
469
470
475 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
477 bool OpenFile) const {
478 InUserSpecifiedSystemFramework = false;
479 IsInHeaderMap = false;
480 MappedName.clear();
481
484
486 llvm::sys::path::append(TmpDir, Filename);
487 if (SearchPath) {
489 SearchPath->clear();
490 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
491 }
492 if (RelativePath) {
493 RelativePath->clear();
495 }
496
497 return HS.getFileAndSuggestModule(
499 RequestingModule, SuggestedModule, OpenFile);
500 }
501
503 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
504 RequestingModule, SuggestedModule,
505 InUserSpecifiedSystemFramework, IsFrameworkFound);
506
507 assert(isHeaderMap() && "Unknown directory lookup");
511 if (Dest.empty())
512 return std::nullopt;
513
514 IsInHeaderMap = true;
515
516 auto FixupSearchPathAndFindUsableModule =
518 if (SearchPath) {
519 StringRef SearchPathRef(getName());
520 SearchPath->clear();
521 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
522 }
523 if (RelativePath) {
524 RelativePath->clear();
526 }
527 if (!HS.findUsableModuleForHeader(File, File.getFileEntry().getDir(),
528 RequestingModule, SuggestedModule,
530 return std::nullopt;
531 }
533 };
534
535
536
537
538 if (llvm::sys::path::is_relative(Dest)) {
539 MappedName.append(Dest.begin(), Dest.end());
540 Filename = StringRef(MappedName.begin(), MappedName.size());
542 }
543
545 return FixupSearchPathAndFindUsableModule(*Res);
546 }
547
548
549
550
551
552 HS.noteLookupUsage(HS.searchDirIdx(*this), IncludeLoc);
553 return std::nullopt;
554}
555
556
557
558
559
560
561
565 assert(llvm::sys::path::extension(DirName) == ".framework" &&
566 "Not a framework directory");
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
583
584 if (TopFrameworkDir)
586 do {
587
588 DirName = llvm::sys::path::parent_path(DirName);
589 if (DirName.empty())
590 break;
591
592
594 if (!Dir)
595 break;
596
597
598
599 if (llvm::sys::path::extension(DirName) == ".framework") {
600 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
601 TopFrameworkDir = *Dir;
602 }
603 } while (true);
604
605 return TopFrameworkDir;
606}
607
609 bool HasSuggestedModule) {
610 return HasSuggestedModule ||
612}
613
614
615
620 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
622
623
624 size_t SlashPos = Filename.find('/');
625 if (SlashPos == StringRef::npos)
626 return std::nullopt;
627
628
629
632
633
635 return std::nullopt;
636
637
638
639
642 if (FrameworkName.empty() || FrameworkName.back() != '/')
643 FrameworkName.push_back('/');
644
645
646 StringRef ModuleName(Filename.begin(), SlashPos);
647 FrameworkName += ModuleName;
648
649
650 FrameworkName += ".framework/";
651
652
654 ++NumFrameworkLookups;
655
656
658 if (!Dir)
659 return std::nullopt;
660
661
662
664
665
666
669 SystemFrameworkMarker += ".system_framework";
670 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
672 }
673 }
674 }
675
676
679
680 if (RelativePath) {
681 RelativePath->clear();
682 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
683 }
684
685
686 unsigned OrigSize = FrameworkName.size();
687
688 FrameworkName += "Headers/";
689
690 if (SearchPath) {
691 SearchPath->clear();
692
693 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
694 }
695
696 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
697
699 FileMgr.getOptionalFileRef(FrameworkName, !SuggestedModule);
701
702 const char *Private = "Private";
703 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
705 if (SearchPath)
706 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
708
710 !SuggestedModule);
711 }
712
713
715
716 StringRef FrameworkPath = File->getDir().getName();
717 bool FoundFramework = false;
718 do {
719
721 if (!Dir)
722 break;
723
724
725
726 if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
727 FoundFramework = true;
728 break;
729 }
730
731
732 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
733 if (FrameworkPath.empty())
734 break;
735 } while (true);
736
738 if (FoundFramework) {
739 if (!HS.findUsableModuleForFrameworkHeader(*File, FrameworkPath,
740 RequestingModule,
741 SuggestedModule, IsSystem))
742 return std::nullopt;
743 } else {
744 if (!HS.findUsableModuleForHeader(*File, getDir(), RequestingModule,
745 SuggestedModule, IsSystem))
746 return std::nullopt;
747 }
748 }
750 return *File;
751 return std::nullopt;
752}
753
754void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
757 CacheLookup.HitIt = HitIt;
758 noteLookupUsage(HitIt.Idx, Loc);
759}
760
761void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
762 SearchDirsUsage[HitIdx] = true;
763
764 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
765 if (UserEntryIdxIt != SearchDirToHSEntry.end())
766 Diags.Report(Loc, diag::remark_pp_search_path_usage)
767 << HSOpts->UserEntries[UserEntryIdxIt->second].Path;
768}
769
772}
773
774
775
776
777
778
779
780
785 if (MSFE && FE != *MSFE) {
786 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
787 return true;
788 }
789 return false;
790}
791
792static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
793 assert(!Str.empty());
794 char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
795 std::copy(Str.begin(), Str.end(), CopyStr);
796 CopyStr[Str.size()] = '\0';
797 return CopyStr;
798}
799
803 using namespace llvm::sys;
804 path::const_iterator I = path::begin(Path);
805 path::const_iterator E = path::end(Path);
806 IsPrivateHeader = false;
807
808
809
810
811
812
813
814
815
816 int FoundComp = 0;
817 while (I != E) {
818 if (*I == "Headers") {
819 ++FoundComp;
820 } else if (*I == "PrivateHeaders") {
821 ++FoundComp;
822 IsPrivateHeader = true;
823 } else if (I->ends_with(".framework")) {
824 StringRef Name = I->drop_back(10);
825
826 FrameworkName.clear();
827 FrameworkName.append(Name.begin(), Name.end());
828 IncludeSpelling.clear();
829 IncludeSpelling.append(Name.begin(), Name.end());
830 FoundComp = 1;
831 } else if (FoundComp >= 2) {
832 IncludeSpelling.push_back('/');
833 IncludeSpelling.append(I->begin(), I->end());
834 }
835 ++I;
836 }
837
838 return !FrameworkName.empty() && FoundComp >= 2;
839}
840
841static void
843 StringRef Includer, StringRef IncludeFilename,
844 FileEntryRef IncludeFE, bool isAngled = false,
845 bool FoundByHeaderMap = false) {
846 bool IsIncluderPrivateHeader = false;
850 FromIncludeSpelling))
851 return;
852 bool IsIncludeePrivateHeader = false;
853 bool IsIncludeeInFramework =
855 ToFramework, ToIncludeSpelling);
856
857 if (!isAngled && !FoundByHeaderMap) {
859 if (IsIncludeeInFramework) {
860 NewInclude += ToIncludeSpelling;
861 NewInclude += ">";
862 } else {
863 NewInclude += IncludeFilename;
864 NewInclude += ">";
865 }
866 Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
867 << IncludeFilename
869 }
870
871
872
873
874 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
875 IsIncludeePrivateHeader && FromFramework == ToFramework)
876 Diags.Report(IncludeLoc, diag::warn_framework_include_private_from_public)
877 << IncludeFilename;
878}
879
880
881
882
883
884
888 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
891 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
892 bool BuildSystemModule, bool OpenFile, bool CacheFailures) {
895
896 if (IsMapped)
897 *IsMapped = false;
898
899 if (IsFrameworkFound)
900 *IsFrameworkFound = false;
901
902 if (SuggestedModule)
904
905
906 if (llvm::sys::path::is_absolute(Filename)) {
907 CurDir = nullptr;
908
909
910 if (FromDir)
911 return std::nullopt;
912
913 if (SearchPath)
914 SearchPath->clear();
915 if (RelativePath) {
916 RelativePath->clear();
918 }
919
920 return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
921 false,
922 RequestingModule, SuggestedModule, OpenFile,
923 CacheFailures);
924 }
925
926
929
930
931
932
933
934
935 if (!Includers.empty() && !isAngled) {
937 bool First = true;
938 for (const auto &IncluderAndDir : Includers) {
940
941
942 TmpDir = IncluderAndDir.second.getName();
943 llvm::sys::path::append(TmpDir, Filename);
944
945
946
947
948
949
950
951
952 bool IncluderIsSystemHeader = [&]() {
953 if (!Includer)
954 return BuildSystemModule;
956 assert(HFI && "includer without file info");
958 }();
960 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
961 RequestingModule, SuggestedModule)) {
962 if (!Includer) {
963 assert(First && "only first includer can have no file");
964 return FE;
965 }
966
967
968
969
970
971
972
974 assert(FromHFI && "includer without file info");
975 unsigned DirInfo = FromHFI->DirInfo;
976
979
980 if (SearchPath) {
981 StringRef SearchPathRef(IncluderAndDir.second.getName());
982 SearchPath->clear();
983 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
984 }
985 if (RelativePath) {
986 RelativePath->clear();
988 }
991 IncluderAndDir.second.getName(), Filename,
992 *FE);
993 return FE;
994 }
995
996
997
998
999 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
1000 return FE;
1001 } else {
1002 MSFE = FE;
1003 if (SuggestedModule) {
1004 MSSuggestedModule = *SuggestedModule;
1006 }
1007 break;
1008 }
1009 }
1011 }
1012 }
1013
1014 CurDir = nullptr;
1015
1016
1019
1020
1021
1022 if (FromDir)
1023 It = FromDir;
1024
1025
1026
1027
1028
1029 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
1030
1032
1033 if (!SkipCache) {
1034 if (CacheLookup.StartIt == NextIt &&
1035 CacheLookup.RequestingModule == RequestingModule) {
1036
1037 if (CacheLookup.HitIt)
1038 It = CacheLookup.HitIt;
1039 if (CacheLookup.MappedName) {
1040 Filename = CacheLookup.MappedName;
1041 if (IsMapped)
1042 *IsMapped = true;
1043 }
1044 } else {
1045
1046
1047
1048 CacheLookup.reset(RequestingModule, NextIt);
1049
1050 if (It == search_dir_begin() && FirstNonHeaderMapSearchDirIdx > 0) {
1051
1052
1053
1054 auto Iter = SearchDirHeaderMapIndex.find(Filename.lower());
1055 if (Iter == SearchDirHeaderMapIndex.end())
1056
1058 else
1059
1061 }
1062 }
1063 } else {
1064 CacheLookup.reset(RequestingModule, NextIt);
1065 }
1066
1068
1069
1071 bool InUserSpecifiedSystemFramework = false;
1072 bool IsInHeaderMap = false;
1073 bool IsFrameworkFoundInDir = false;
1075 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1076 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1077 IsInHeaderMap, MappedName, OpenFile);
1078 if (!MappedName.empty()) {
1079 assert(IsInHeaderMap && "MappedName should come from a header map");
1080 CacheLookup.MappedName =
1081 copyString(MappedName, LookupFileCache.getAllocator());
1082 }
1083 if (IsMapped)
1084
1085
1086
1087 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap && File));
1088 if (IsFrameworkFound)
1089
1090
1091
1092 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1094 continue;
1095
1096 CurDir = It;
1097
1099
1100
1102 HFI.DirInfo = CurDir->getDirCharacteristic();
1103
1104
1105
1106
1109
1110
1111
1112 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1113 if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) {
1116 break;
1117 }
1118 }
1119
1121 if (SuggestedModule)
1122 *SuggestedModule = MSSuggestedModule;
1123 return MSFE;
1124 }
1125
1126 bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
1127 if (!Includers.empty())
1129 Includers.front().second.getName(), Filename,
1130 *File, isAngled, FoundByHeaderMap);
1131
1132
1133 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1134 return File;
1135 }
1136
1138 if (SuggestedModule)
1139 *SuggestedModule = MSSuggestedModule;
1140 return MSFE;
1141 }
1142
1143
1145 return std::nullopt;
1146}
1147
1148
1149
1150
1151
1152
1157
1158
1159 size_t SlashPos = Filename.find('/');
1160 if (SlashPos == StringRef::npos)
1161 return std::nullopt;
1162
1163
1164 StringRef ContextName = ContextFileEnt.getName();
1165
1166
1167 const unsigned DotFrameworkLen = 10;
1168 auto FrameworkPos = ContextName.find(".framework");
1169 if (FrameworkPos == StringRef::npos ||
1170 (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1171 ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1172 return std::nullopt;
1173
1174 SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1175 FrameworkPos +
1176 DotFrameworkLen + 1);
1177
1178
1179 FrameworkName += "Frameworks/";
1180 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1181 FrameworkName += ".framework/";
1182
1183 auto &CacheLookup =
1184 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1186
1187
1188 if (CacheLookup.second.Directory &&
1189 CacheLookup.first().size() == FrameworkName.size() &&
1190 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1191 CacheLookup.first().size()) != 0)
1192 return std::nullopt;
1193
1194
1195 if (!CacheLookup.second.Directory) {
1196 ++NumSubFrameworkLookups;
1197
1198
1200 if (!Dir)
1201 return std::nullopt;
1202
1203
1204
1205 CacheLookup.second.Directory = Dir;
1206 }
1207
1208
1209 if (RelativePath) {
1210 RelativePath->clear();
1211 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1212 }
1213
1214
1216 HeadersFilename += "Headers/";
1217 if (SearchPath) {
1218 SearchPath->clear();
1219
1220 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1221 }
1222
1223 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1225 if () {
1226
1227 HeadersFilename = FrameworkName;
1228 HeadersFilename += "PrivateHeaders/";
1229 if (SearchPath) {
1230 SearchPath->clear();
1231
1232 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1233 }
1234
1235 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1237
1239 return std::nullopt;
1240 }
1241
1242
1244 assert(ContextHFI && "context file without file info");
1245
1246
1247 unsigned DirInfo = ContextHFI->DirInfo;
1249
1250 FrameworkName.pop_back();
1251 if (!findUsableModuleForFrameworkHeader(*File, FrameworkName,
1252 RequestingModule, SuggestedModule,
1253 false))
1254 return std::nullopt;
1255
1256 return *File;
1257}
1258
1259
1260
1261
1262
1269 return false;
1270}
1271
1273 bool isModuleHeader,
1274 bool isTextualModuleHeader) {
1278 else
1280}
1281
1285}
1286
1287
1288
1291 assert(OtherHFI.External && "expected to merge external HFI");
1292
1297
1300
1304}
1305
1307 if (FE.getUID() >= FileInfo.size())
1308 FileInfo.resize(FE.getUID() + 1);
1309
1311
1313 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1314 if (ExternalHFI.IsValid) {
1316 if (ExternalHFI.External)
1318 }
1319 }
1320
1322
1323
1325 return *HFI;
1326}
1327
1331 if (FE.getUID() >= FileInfo.size())
1332 FileInfo.resize(FE.getUID() + 1);
1333
1334 HFI = &FileInfo[FE.getUID()];
1335
1337 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1338 if (ExternalHFI.IsValid) {
1340 if (ExternalHFI.External)
1342 }
1343 }
1344 } else if (FE.getUID() < FileInfo.size()) {
1345 HFI = &FileInfo[FE.getUID()];
1346 } else {
1347 HFI = nullptr;
1348 }
1349
1350 return (HFI && HFI->IsValid) ? HFI : nullptr;
1351}
1352
1356 if (FE.getUID() < FileInfo.size()) {
1357 HFI = &FileInfo[FE.getUID()];
1358 } else {
1359 HFI = nullptr;
1360 }
1361
1362 return (HFI && HFI->IsValid && !HFI->External) ? HFI : nullptr;
1363}
1364
1366
1367
1368
1370 return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
1371 return false;
1372}
1373
1376 bool isCompilingModuleHeader) {
1377
1378 if (!isCompilingModuleHeader) {
1380 return;
1383 return;
1384 }
1385
1387 HFI.mergeModuleMembership(Role);
1388 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1389}
1390
1393 bool ModulesEnabled, Module *M,
1394 bool &IsFirstIncludeOfFile) {
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409 ++NumIncluded;
1410 IsFirstIncludeOfFile = false;
1412
1413 auto MaybeReenterImportedFile = [&]() -> bool {
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431 if (!ModulesEnabled || FileInfo.isPragmaOnce)
1432 return false;
1433
1434
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1456 return true;
1457
1459
1460
1462
1463
1464
1465
1467 return true;
1468 } else {
1469
1470
1471
1472
1473
1474
1476 return true;
1477 }
1478 }
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489 return false;
1490 };
1491
1492 if (isImport) {
1493
1494
1497 return false;
1498 } else {
1499
1500
1501
1503 (FileInfo.isImport && !MaybeReenterImportedFile()))
1504 return false;
1505 }
1506
1507
1508
1509
1510
1513
1514
1515
1516
1519 ++NumMultiIncludeFileOptzn;
1520 return false;
1521 }
1522 }
1523
1525 return true;
1526}
1527
1529 return SearchDirs.capacity()
1530 + llvm::capacity_in_bytes(FileInfo)
1531 + llvm::capacity_in_bytes(HeaderMaps)
1532 + LookupFileCache.getAllocator().getTotalMemory()
1533 + FrameworkMap.getAllocator().getTotalMemory();
1534}
1535
1537 return &DL - &*SearchDirs.begin();
1538}
1539
1541 return FrameworkNames.insert(Framework).first->first();
1542}
1543
1545 auto It = IncludeNames.find(File);
1546 if (It == IncludeNames.end())
1547 return {};
1548 return It->second;
1549}
1550
1553 bool IsSystem) {
1554 if (!HSOpts->ImplicitModuleMaps)
1555 return false;
1556
1558
1559 StringRef DirName = FileName;
1560 do {
1561
1562 DirName = llvm::sys::path::parent_path(DirName);
1563 if (DirName.empty())
1564 return false;
1565
1566
1568 if (!Dir)
1569 return false;
1570
1571
1573 llvm::sys::path::extension(Dir->getName()) ==
1574 ".framework")) {
1575 case LMM_NewlyLoaded:
1576 case LMM_AlreadyLoaded:
1577
1578
1579 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1580 DirectoryHasModuleMap[FixUpDirectories[I]] = true;
1581 return true;
1582
1583 case LMM_NoDirectory:
1584 case LMM_InvalidModuleMap:
1585 break;
1586 }
1587
1588
1589 if (*Dir == Root)
1590 return false;
1591
1592
1593
1594 FixUpDirectories.push_back(*Dir);
1595 } while (true);
1596}
1597
1600 bool AllowExcluded) const {
1602
1603
1605 }
1607}
1608
1612
1613
1615 }
1617}
1618
1622
1623
1625 }
1627}
1628
1630 Module *RequestingModule,
1634
1635
1636
1640
1641
1642
1643
1644
1646 if (SuggestedModule)
1648 return true;
1649 }
1650
1651
1652 return false;
1653 }
1654 }
1655
1656 if (SuggestedModule)
1660
1661 return true;
1662}
1663
1664bool HeaderSearch::findUsableModuleForHeader(
1668
1669 hasModuleMap(File.getNameAsRequested(), Root, IsSystemHeaderDir);
1670 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1671 }
1672 return true;
1673}
1674
1675bool HeaderSearch::findUsableModuleForFrameworkHeader(
1678
1680
1684 assert(TopFrameworkDir && "Could not find the top-most framework dir");
1685
1686
1687 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1688
1689
1690
1691 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1692
1693
1694
1695
1696
1697 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1698 }
1699 return true;
1700}
1701
1705 StringRef Filename = llvm::sys::path::filename(File.getName());
1707 if (Filename == "module.map")
1708 llvm::sys::path::append(PrivateFilename, "module_private.map");
1709 else if (Filename == "module.modulemap")
1710 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1711 else
1712 return std::nullopt;
1714 if (PMMFile) {
1715 if (Filename == "module.map")
1716 Diags.Report(diag::warn_deprecated_module_dot_map)
1717 << PrivateFilename << 1
1718 << File.getDir().getName().ends_with(".framework");
1719 }
1720 return PMMFile;
1721}
1722
1724 FileID ID, unsigned *Offset,
1725 StringRef OriginalModuleMapFile) {
1726
1727
1731 } else {
1732 if (!OriginalModuleMapFile.empty()) {
1733
1734
1736 llvm::sys::path::parent_path(OriginalModuleMapFile));
1737 if (!Dir) {
1738 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1739 Dir = FakeFile.getDir();
1740 }
1741 } else {
1742 Dir = File.getDir();
1743 }
1744
1745 assert(Dir && "parent must exist");
1746 StringRef DirName(Dir->getName());
1747 if (llvm::sys::path::filename(DirName) == "Modules") {
1748 DirName = llvm::sys::path::parent_path(DirName);
1749 if (DirName.ends_with(".framework"))
1751 Dir = *MaybeDir;
1752
1753
1754 assert(Dir && "parent must exist");
1755 }
1756 }
1757
1758 assert(Dir && "module map home directory must exist");
1759 switch (loadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) {
1760 case LMM_AlreadyLoaded:
1761 case LMM_NewlyLoaded:
1762 return false;
1763 case LMM_NoDirectory:
1764 case LMM_InvalidModuleMap:
1765 return true;
1766 }
1767 llvm_unreachable("Unknown load module map result");
1768}
1769
1770HeaderSearch::LoadModuleMapResult
1771HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
1773 unsigned *Offset) {
1774
1775
1776 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1777 if (!AddResult.second)
1778 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1779
1781 LoadedModuleMaps[File] = false;
1782 return LMM_InvalidModuleMap;
1783 }
1784
1785
1789 LoadedModuleMaps[File] = false;
1790 return LMM_InvalidModuleMap;
1791 }
1792 }
1793
1794
1795 return LMM_NewlyLoaded;
1796}
1797
1800 if (!HSOpts->ImplicitModuleMaps)
1801 return std::nullopt;
1802
1803
1805 if (IsFramework)
1806 llvm::sys::path::append(ModuleMapFileName, "Modules");
1807 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1809 return *F;
1810
1811
1812 ModuleMapFileName = Dir.getName();
1813 llvm::sys::path::append(ModuleMapFileName, "module.map");
1815 Diags.Report(diag::warn_deprecated_module_dot_map)
1816 << ModuleMapFileName << 0 << IsFramework;
1817 return *F;
1818 }
1819
1820
1821
1822 if (IsFramework) {
1823 ModuleMapFileName = Dir.getName();
1824 llvm::sys::path::append(ModuleMapFileName, "Modules",
1825 "module.private.modulemap");
1827 return *F;
1828 }
1829 return std::nullopt;
1830}
1831
1833 bool IsSystem) {
1834
1835 switch (loadModuleMapFile(Dir, IsSystem, true)) {
1836 case LMM_InvalidModuleMap:
1837
1838 if (HSOpts->ImplicitModuleMaps)
1839 ModMap.inferFrameworkModule(Dir, IsSystem, nullptr);
1840 break;
1841
1842 case LMM_NoDirectory:
1843 return nullptr;
1844
1845 case LMM_AlreadyLoaded:
1846 case LMM_NewlyLoaded:
1847 break;
1848 }
1849
1851}
1852
1853HeaderSearch::LoadModuleMapResult
1855 bool IsFramework) {
1858
1859 return LMM_NoDirectory;
1860}
1861
1862HeaderSearch::LoadModuleMapResult
1864 bool IsFramework) {
1865 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1866 if (KnownDir != DirectoryHasModuleMap.end())
1867 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1868
1871 LoadModuleMapResult Result =
1872 loadModuleMapFileImpl(*ModuleMapFile, IsSystem, Dir);
1873
1874
1875
1876 if (Result == LMM_NewlyLoaded)
1877 DirectoryHasModuleMap[Dir] = true;
1878 else if (Result == LMM_InvalidModuleMap)
1879 DirectoryHasModuleMap[Dir] = false;
1881 }
1882 return LMM_InvalidModuleMap;
1883}
1884
1886 Modules.clear();
1887
1888 if (HSOpts->ImplicitModuleMaps) {
1889
1891 bool IsSystem = DL.isSystemHeaderDirectory();
1892 if (DL.isFramework()) {
1893 std::error_code EC;
1895 llvm::sys::path::native(DL.getFrameworkDirRef()->getName(), DirNative);
1896
1897
1899 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1900 DirEnd;
1901 Dir != DirEnd && !EC; Dir.increment(EC)) {
1902 if (llvm::sys::path::extension(Dir->path()) != ".framework")
1903 continue;
1904
1906 if (!FrameworkDir)
1907 continue;
1908
1909
1910 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1911 IsSystem);
1912 }
1913 continue;
1914 }
1915
1916
1917 if (DL.isHeaderMap())
1918 continue;
1919
1920
1921 loadModuleMapFile(*DL.getDirRef(), IsSystem, false);
1922
1923
1924
1925 loadSubdirectoryModuleMaps(DL);
1926 }
1927 }
1928
1929
1930 llvm::transform(ModMap.modules(), std::back_inserter(Modules),
1931 [](const auto &NameAndMod) { return NameAndMod.second; });
1932}
1933
1935 if (!HSOpts->ImplicitModuleMaps)
1936 return;
1937
1938
1940
1941 if (!DL.isNormalDir())
1942 continue;
1943
1944
1945 loadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(),
1946 DL.isFramework());
1947 }
1948}
1949
1950void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
1951 assert(HSOpts->ImplicitModuleMaps &&
1952 "Should not be loading subdirectory module maps");
1953
1955 return;
1956
1957 std::error_code EC;
1961 llvm::sys::path::native(Dir, DirNative);
1963 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1964 Dir != DirEnd && !EC; Dir.increment(EC)) {
1965 if (Dir->type() == llvm::sys::fs::file_type::regular_file)
1966 continue;
1967 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
1968 if (IsFramework == SearchDir.isFramework())
1971 }
1972
1974}
1975
1977 FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled) const {
1979 MainFile, IsAngled);
1980}
1981
1983 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1984 bool *IsAngled) const {
1985 using namespace llvm::sys;
1986
1988 if (!WorkingDir.empty() && !path::is_absolute(FilePath))
1989 fs::make_absolute(WorkingDir, FilePath);
1990
1991
1992
1993 path::remove_dots(FilePath, true);
1994 path::native(FilePath, path::Style::posix);
1995 File = FilePath;
1996
1997 unsigned BestPrefixLength = 0;
1998
1999
2000
2002 if (!WorkingDir.empty() && !path::is_absolute(Dir))
2003 fs::make_absolute(WorkingDir, Dir);
2004 path::remove_dots(Dir, true);
2005 for (auto NI = path::begin(File), NE = path::end(File),
2006 DI = path::begin(Dir), DE = path::end(Dir);
2007 NI != NE; ++NI, ++DI) {
2008 if (DI == DE) {
2009
2010 unsigned PrefixLength = NI - path::begin(File);
2011 if (PrefixLength > BestPrefixLength) {
2012 BestPrefixLength = PrefixLength;
2013 return true;
2014 }
2015 break;
2016 }
2017
2018
2019 if (NI->size() == 1 && DI->size() == 1 &&
2020 path::is_separator(NI->front()) && path::is_separator(DI->front()))
2021 continue;
2022
2023
2024
2025
2026 if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) {
2027 StringRef NBasename = path::stem(*NI);
2028 StringRef DBasename = path::stem(*DI);
2029 if (DBasename.starts_with(NBasename))
2030 continue;
2031 }
2032
2033 if (*NI != *DI)
2034 break;
2035 }
2036 return false;
2037 };
2038
2039 bool BestPrefixIsFramework = false;
2041 if (DL.isNormalDir()) {
2042 StringRef Dir = DL.getDirRef()->getName();
2043 if (CheckDir(Dir)) {
2044 if (IsAngled)
2045 *IsAngled = BestPrefixLength && isSystem(DL.getDirCharacteristic());
2046 BestPrefixIsFramework = false;
2047 }
2048 } else if (DL.isFramework()) {
2049 StringRef Dir = DL.getFrameworkDirRef()->getName();
2050 if (CheckDir(Dir)) {
2051
2052 if (IsAngled)
2053 *IsAngled = BestPrefixLength;
2054 BestPrefixIsFramework = true;
2055 }
2056 }
2057 }
2058
2059
2060
2061 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
2062 if (IsAngled)
2063 *IsAngled = false;
2064 BestPrefixIsFramework = false;
2065 }
2066
2067
2068
2069 StringRef Filename = File.drop_front(BestPrefixLength);
2071 if (!DL.isHeaderMap())
2072 continue;
2073
2074 StringRef SpelledFilename =
2075 DL.getHeaderMap()->reverseLookupFilename(Filename);
2076 if (!SpelledFilename.empty()) {
2078 BestPrefixIsFramework = false;
2079 break;
2080 }
2081 }
2082
2083
2084
2085 bool IsPrivateHeader;
2087 if (BestPrefixIsFramework &&
2089 IncludeSpelling)) {
2091 }
2092 return path::convert_to_slash(Filename);
2093}
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
llvm::MachO::Target Target
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.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
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.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
FileEntryRef getVirtualFileRef(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...
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified directory (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.
IdentifierInfo * getPtr() const
bool isID() const
Whether this pointer is currently stored as ID.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
void setTarget(const TargetInfo &Target)
Set the target information.
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.
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
llvm::iterator_range< module_iterator > modules() const
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.
The JSON file list parser is used to communicate input to InstallAPI.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Result
The result type of a method or function.
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.