clang: lib/Lex/ModuleMap.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/StringMap.h"
35#include "llvm/ADT/StringRef.h"
36#include "llvm/ADT/StringSwitch.h"
37#include "llvm/Support/Allocator.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/ErrorHandling.h"
40#include "llvm/Support/Path.h"
41#include "llvm/Support/VirtualFileSystem.h"
42#include "llvm/Support/raw_ostream.h"
43#include
44#include
45#include
46#include
47#include
48#include
49#include <system_error>
50#include
51
52using namespace clang;
53
54void ModuleMapCallbacks::anchor() {}
55
57 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
58 if (PendingLinkAs != PendingLinkAsModule.end()) {
59 for (auto &Name : PendingLinkAs->second) {
61 if (M)
62 M->UseExportAsModuleLinkName = true;
63 }
64 }
65}
66
70 else
72}
73
75 switch ((int)Role) {
86 }
87 llvm_unreachable("unknown header role");
88}
89
92 switch ((int)Kind) {
103 }
104 llvm_unreachable("unknown header kind");
105}
106
109}
110
112ModuleMap::resolveExport(Module *Mod,
114 bool Complain) const {
115
117 assert(Unresolved.Wildcard && "Invalid unresolved export");
119 }
120
121
122 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
123 if (!Context)
124 return {};
125
127}
128
130 bool Complain) const {
131
133 if (!Context) {
134 if (Complain)
135 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
137
138 return nullptr;
139 }
140
141
142 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
144 if (!Sub) {
145 if (Complain)
146 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
147 << Id[I].first << Context->getFullModuleName()
149
150 return nullptr;
151 }
152
153 Context = Sub;
154 }
155
156 return Context;
157}
158
159
160
163
165 for (; Mod; Mod = Mod->Parent) {
167 Paths.push_back(Mod->Name);
168 }
169
170 if (Paths.empty())
171 return;
172
173
174 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
175 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");
176}
177
181
184
188 if ( || (Header.Size && File->getSize() != *Header.Size) ||
190 return std::nullopt;
191 return *File;
192 };
193
195 unsigned FullPathLength = FullPathName.size();
197 unsigned RelativePathLength = RelativePathName.size();
198
199
200 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
201 llvm::sys::path::append(FullPathName, RelativePathName);
202 if (auto File = GetFile(FullPathName))
204
205
206
207
208
209
210
212 RelativePathName.clear();
213 else
214 RelativePathName.resize(RelativePathLength);
215 FullPathName.resize(FullPathLength);
216 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
218 llvm::sys::path::append(FullPathName, RelativePathName);
219 return GetFile(FullPathName);
220 };
221
222 if (llvm::sys::path::is_absolute(Header.FileName)) {
223 RelativePathName.clear();
224 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
225 return GetFile(Header.FileName);
226 }
227
229 return GetFrameworkFile();
230
231
232 llvm::sys::path::append(RelativePathName, Header.FileName);
233 llvm::sys::path::append(FullPathName, RelativePathName);
234 auto NormalHdrFile = GetFile(FullPathName);
235
236 if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
237
238
239
240 FullPathName.assign(Directory->getName());
241 RelativePathName.clear();
242 if (GetFrameworkFile()) {
244 diag::warn_mmap_incomplete_framework_module_declaration)
246 NeedsFramework = true;
247 }
248 return std::nullopt;
249 }
250
251 return NormalHdrFile;
252}
253
254
255
256
258 return llvm::StringSwitch(FileName)
259 .Case("float.h", true)
260 .Case("iso646.h", true)
261 .Case("limits.h", true)
262 .Case("stdalign.h", true)
263 .Case("stdarg.h", true)
264 .Case("stdatomic.h", true)
265 .Case("stdbool.h", true)
266 .Case("stddef.h", true)
267 .Case("stdint.h", true)
268 .Case("tgmath.h", true)
269 .Case("unwind.h", true)
270 .Default(false);
271}
272
273
274
276 return llvm::StringSwitch(ModuleName)
277 .Case("_Builtin_float", true)
278 .Case("_Builtin_inttypes", true)
279 .Case("_Builtin_iso646", true)
280 .Case("_Builtin_limits", true)
281 .Case("_Builtin_stdalign", true)
282 .Case("_Builtin_stdarg", true)
283 .Case("_Builtin_stdatomic", true)
284 .Case("_Builtin_stdbool", true)
285 .Case("_Builtin_stddef", true)
286 .Case("_Builtin_stdint", true)
287 .Case("_Builtin_stdnoreturn", true)
288 .Case("_Builtin_tgmath", true)
289 .Case("_Builtin_unwind", true)
290 .Default(false);
291}
292
293void ModuleMap::resolveHeader(Module *Mod,
295 bool &NeedsFramework) {
298 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
301 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
303 << UmbrellaMod->getFullModuleName();
304 else
305
307 RelativePathName.str());
308 } else {
312 }
314
315
317
318 } else {
319
320
322
323
324
325
328 }
329}
330
331bool ModuleMap::resolveAsBuiltinHeader(
334 llvm::sys::path::is_absolute(Header.FileName) ||
336 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
338 return false;
339
340
341
342
344 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
347 return false;
348
352 return true;
353}
354
358 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
359 HeaderInfo(HeaderInfo) {
360 MMapLangOpts.LineComment = true;
361}
362
364
366 assert((!this->Target || this->Target == &Target) &&
367 "Improper target override");
368 this->Target = &Target;
369}
370
371
374 if (Name.empty())
375 return Name;
376
378
379
380 Buffer.clear();
382 Buffer.push_back('_');
383 Buffer.reserve(Buffer.size() + Name.size());
384 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
386 Buffer.push_back(Name[I]);
387 else
388 Buffer.push_back('_');
389 }
390
391 Name = StringRef(Buffer.data(), Buffer.size());
392 }
393
394 while (llvm::StringSwitch(Name)
395#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
396#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
397#include "clang/Basic/TokenKinds.def"
399 if (Name.data() != Buffer.data())
400 Buffer.append(Name.begin(), Name.end());
401 Buffer.push_back('_');
402 Name = StringRef(Buffer.data(), Buffer.size());
403 }
404
405 return Name;
406}
407
409 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
411}
412
415 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
418}
419
420ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
422 HeadersMap::iterator Known = Headers.find(File);
426 return Headers.find(File);
427 }
428 return Known;
429}
430
433 if (UmbrellaDirs.empty())
434 return {};
435
437
438
439
440
441
443
444
445
446 do {
447 auto KnownDir = UmbrellaDirs.find(*Dir);
448 if (KnownDir != UmbrellaDirs.end())
449 return KnownHeader(KnownDir->second, NormalHeader);
450
451 IntermediateDirs.push_back(*Dir);
452
453
454 DirName = llvm::sys::path::parent_path(DirName);
455 if (DirName.empty())
456 break;
457
458
460 } while (Dir);
461 return {};
462}
463
467#ifndef NDEBUG
469
470
471
472 bool IsPrivate = false;
476 for (auto Hs : HeaderList)
477 IsPrivate |= llvm::any_of(
479 assert(IsPrivate && "inconsistent headers and roles");
480 }
481#endif
483}
484
487}
488
490 bool RequestingModuleIsModuleInterface,
493
494
496 return;
497
498 if (RequestingModule) {
499 resolveUses(RequestingModule, false);
501 }
502
503 bool Excluded = false;
505 Module *NotUsed = nullptr;
506
507 HeadersMap::iterator Known = findKnownHeader(File);
508 if (Known != Headers.end()) {
509 for (const KnownHeader &Header : Known->second) {
510
512 Excluded = true;
513 continue;
514 }
515
516
519 continue;
520 }
521
522
523
524 if (RequestingModule && LangOpts.ModulesDeclUse &&
527 continue;
528 }
529
530
531 return;
532 }
533
534 Excluded = true;
535 }
536
537
539 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
541 return;
542 }
543
544
545 if (NotUsed) {
546 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
548 << NotUsed->Name;
549 return;
550 }
551
552 if (Excluded || isHeaderInUmbrellaDirs(File))
553 return;
554
555
556
557 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
558 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
560 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
562
564 diag::warn_non_modular_include_in_framework_module :
565 diag::warn_non_modular_include_in_module;
567 << File.getName();
568 }
569}
570
573
574
575
576
578 return true;
579
580
584
585
589
590
594
595
596 return false;
597}
598
600 bool AllowTextual,
601 bool AllowExcluded) {
604 return {};
605 return R;
606 };
607
608 HeadersMap::iterator Known = findKnownHeader(File);
609 if (Known != Headers.end()) {
611
613
615 continue;
616
618 return MakeResult(H);
621 }
622 return MakeResult(Result);
623 }
624
625 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
626}
627
629ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
630 assert(!Headers.count(File) && "already have a module for this header");
631
633 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
634 if (H) {
636
637
638
641 UmbrellaModule = UmbrellaModule->Parent;
642
645
646
647
648
650
651 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
652
655 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
659
660
661 UmbrellaDirs[SkippedDir] = Result;
662
663
664
667 }
668
669
672 llvm::sys::path::stem(File.getName()), NameBuf);
677
678
679
682 } else {
683
684
685 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
686 UmbrellaDirs[SkippedDirs[I]] = Result;
687 }
688
690 Headers[File].push_back(Header);
691 return Header;
692 }
693
694 return {};
695}
696
699 HeadersMap::iterator Known = findKnownHeader(File);
700 if (Known != Headers.end())
701 return Known->second;
702
703 if (findOrCreateModuleForHeaderInUmbrellaDir(File))
704 return Headers.find(File)->second;
705
706 return {};
707}
708
711
713 auto It = Headers.find(File);
714 if (It == Headers.end())
715 return {};
716 return It->second;
717}
718
721}
722
726 HeadersMap::const_iterator Known = Headers.find(Header);
727 if (Known != Headers.end()) {
729 I = Known->second.begin(),
730 E = Known->second.end();
731 I != E; ++I) {
732
734 continue;
735
736 if (I->isAvailable() &&
737 (!RequestingModule ||
738 I->getModule()->isSubModuleOf(RequestingModule))) {
739
740
741
742
743
745 continue;
746 return false;
747 }
748 }
749 return true;
750 }
751
754 StringRef DirName = Dir->getName();
755
756 auto IsUnavailable = [&](const Module *M) {
757 return !M->isAvailable() && (!RequestingModule ||
759 };
760
761
762
763 do {
764 auto KnownDir = UmbrellaDirs.find(*Dir);
765 if (KnownDir != UmbrellaDirs.end()) {
767 if (IsUnavailable(Found))
768 return true;
769
770
771
774 UmbrellaModule->Parent)
775 UmbrellaModule = UmbrellaModule->Parent;
776
778 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
779
782 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
785 return false;
786 if (IsUnavailable(Found))
787 return true;
788 }
789
790
793 llvm::sys::path::stem(Header.getName()),
794 NameBuf);
797 return false;
798 }
799
800 return IsUnavailable(Found);
801 }
802
803 SkippedDirs.push_back(*Dir);
804
805
806 DirName = llvm::sys::path::parent_path(DirName);
807 if (DirName.empty())
808 break;
809
810
812 } while (Dir);
813
814 return false;
815}
816
818 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
819 if (Known != Modules.end())
820 return Known->getValue();
821
822 return nullptr;
823}
824
826 if (Module *SubM = Parent->findSubmodule(Name))
827 return SubM;
828 if (->InferSubmodules)
829 return nullptr;
830 Module *Result = new (ModulesAlloc.Allocate())
832 Parent->InferExplicitSubmodules, 0);
833 Result->InferExplicitSubmodules = Parent->InferExplicitSubmodules;
834 Result->InferSubmodules = Parent->InferSubmodules;
835 Result->InferExportWildcard = Parent->InferExportWildcard;
836 if (Result->InferExportWildcard)
839}
840
842 Module *Context) const {
843 for(; Context; Context = Context->Parent) {
845 return Sub;
846 }
847
849}
850
852 if (!Context)
854
855 return Context->findSubmodule(Name);
856}
857
860 bool IsFramework,
861 bool IsExplicit) {
862
864 return std::make_pair(Sub, false);
865
866
868 return std::make_pair(M, true);
869}
870
872 bool IsFramework, bool IsExplicit) {
874 "Creating duplicate submodule");
875
876 Module *Result = new (ModulesAlloc.Allocate())
878 IsFramework, IsExplicit, NumCreatedModules++);
881 SourceModule = Result;
882 Modules[Name] = Result;
883 ModuleScopeIDs[Result] = CurrentModuleScopeID;
884 }
886}
887
890 auto *Result = new (ModulesAlloc.Allocate()) Module(
892 true, NumCreatedModules++);
894
895
897 PendingSubmodules.emplace_back(Result);
899}
900
904 assert(Parent && "We should only create an implicit global module fragment "
905 "in a module purview");
906
907
908
909 auto *Result = new (ModulesAlloc.Allocate())
911 false, false, NumCreatedModules++);
914}
915
919 auto *Result = new (ModulesAlloc.Allocate()) Module(
921 true, NumCreatedModules++);
924}
925
928 auto *Result = new (ModulesAlloc.Allocate())
930 false, NumCreatedModules++);
932
933
934 for (auto &Submodule : PendingSubmodules)
935 Submodule->setParent(Result);
936 PendingSubmodules.clear();
938}
939
941 StringRef Name) {
942 assert(LangOpts.CurrentModule == Name && "module name mismatch");
943 assert(!Modules[Name] && "redefining existing module");
944
947 Modules[Name] = SourceModule = Result;
948
949
950
952 assert(MainFile && "no input file for module interface");
954
956}
957
959 StringRef Name) {
960 assert(LangOpts.CurrentModule == Name && "module name mismatch");
961
963 "creating implementation module without an interface");
964
965
966
967
968 StringRef IName = ".ImplementationUnit";
969 assert(!Modules[IName] && "multiple implementation units?");
970
973 Modules[IName] = SourceModule = Result;
974
975
977 "no input file for module implementation");
978
980}
981
984 assert(LangOpts.CurrentModule == Name && "module name mismatch");
985 assert(!Modules[Name] && "redefining existing module");
986
987 auto *Result = new (ModulesAlloc.Allocate())
989 false, NumCreatedModules++);
991 Modules[Name] = SourceModule = Result;
994}
995
996
997
999 assert(Mod->IsFramework && "Can only infer linking for framework modules");
1001 "Can only infer linking for top-level frameworks");
1002
1003 StringRef FrameworkName(Mod->Name);
1004 FrameworkName.consume_back("_Private");
1006 true));
1007}
1008
1011 Attributes Attrs;
1013 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
1014}
1015
1018
1019
1020
1021
1022 StringRef FrameworkDirName =
1024
1025
1026
1027
1030 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1031
1032
1034 return Mod;
1035
1037
1038
1039
1040 FileID ModuleMapFID;
1042
1043 bool canInfer = false;
1044 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1045
1046 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1048
1049
1050 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1051 inferred = InferredDirectories.find(*ParentDir);
1052 if (inferred == InferredDirectories.end()) {
1053
1054
1055 bool IsFrameworkDir = Parent.ends_with(".framework");
1059 inferred = InferredDirectories.find(*ParentDir);
1060 }
1061
1062 if (inferred == InferredDirectories.end())
1063 inferred = InferredDirectories.insert(
1064 std::make_pair(*ParentDir, InferredDirectory())).first;
1065 }
1066
1067 if (inferred->second.InferModules) {
1068
1069
1070 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1071 canInfer =
1072 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1073
1074 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1075 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1076 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1077 Attrs.NoUndeclaredIncludes |=
1078 inferred->second.Attrs.NoUndeclaredIncludes;
1079 ModuleMapFID = inferred->second.ModuleMapFID;
1080 }
1081 }
1082 }
1083
1084
1085 if (!canInfer)
1086 return nullptr;
1087 } else {
1089 }
1090
1091
1093 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1095
1096
1097
1098
1099 if (!UmbrellaHeader)
1100 return nullptr;
1101
1102 Module *Result = new (ModulesAlloc.Allocate())
1104 true, false, NumCreatedModules++);
1108 SourceModule = Result;
1109 Modules[ModuleName] = Result;
1110 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1111 }
1112
1113 Result->IsSystem |= Attrs.IsSystem;
1114 Result->IsExternC |= Attrs.IsExternC;
1115 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1116 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1117 Result->Directory = FrameworkDir;
1118
1119
1120 StringRef RelativePath = UmbrellaName.str().substr(
1121 Result->getTopLevelModule()->Directory->getName().size());
1122 RelativePath = llvm::sys::path::relative_path(RelativePath);
1123
1124
1126 RelativePath);
1127
1128
1130
1131
1132 Result->InferSubmodules = true;
1133 Result->InferExportWildcard = true;
1134
1135
1136 std::error_code EC;
1138 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1139 llvm::sys::path::native(SubframeworksDirName);
1141 for (llvm::vfs::directory_iterator
1142 Dir = FS.dir_begin(SubframeworksDirName, EC),
1143 DirEnd;
1144 Dir != DirEnd && !EC; Dir.increment(EC)) {
1145 if (!StringRef(Dir->path()).ends_with(".framework"))
1146 continue;
1147
1149
1150
1151
1152
1153 StringRef SubframeworkDirName =
1155 bool FoundParent = false;
1156 do {
1157
1158 SubframeworkDirName
1159 = llvm::sys::path::parent_path(SubframeworkDirName);
1160 if (SubframeworkDirName.empty())
1161 break;
1162
1163 if (auto SubDir =
1165 if (*SubDir == FrameworkDir) {
1166 FoundParent = true;
1167 break;
1168 }
1169 }
1170 } while (true);
1171
1172 if (!FoundParent)
1173 continue;
1174
1175
1176 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1177 }
1178 }
1179
1180
1181
1182 if (->isSubFramework())
1184
1186}
1187
1189 Module *ShadowingModule) {
1190
1191
1192 Module *Result = new (ModulesAlloc.Allocate())
1194 IsFramework, false, NumCreatedModules++);
1195 Result->ShadowingModule = ShadowingModule;
1196 Result->markUnavailable(true);
1197 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1198 ShadowModules.push_back(Result);
1199
1201}
1202
1204 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1205 const Twine &PathRelativeToRootModuleDirectory) {
1207 Mod->Umbrella = UmbrellaHeader;
1210 PathRelativeToRootModuleDirectory.str();
1211 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1212
1213
1214 for (const auto &Cb : Callbacks)
1215 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1216}
1217
1220 const Twine &PathRelativeToRootModuleDirectory) {
1221 Mod->Umbrella = UmbrellaDir;
1224 PathRelativeToRootModuleDirectory.str();
1225 UmbrellaDirs[UmbrellaDir] = Mod;
1226}
1227
1228void ModuleMap::addUnresolvedHeader(Module *Mod,
1230 bool &NeedsFramework) {
1231
1232
1233 if (resolveAsBuiltinHeader(Mod, Header)) {
1234
1235
1236
1237
1241 }
1242
1243
1244
1245
1246
1249
1250
1252 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1253 else
1254 LazyHeadersBySize[*Header.Size].push_back(Mod);
1256 return;
1257 }
1258
1259
1260
1261 resolveHeader(Mod, Header, NeedsFramework);
1262}
1263
1265 auto BySize = LazyHeadersBySize.find(File->getSize());
1266 if (BySize != LazyHeadersBySize.end()) {
1267 for (auto *M : BySize->second)
1269 LazyHeadersBySize.erase(BySize);
1270 }
1271
1272 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1273 if (ByModTime != LazyHeadersByModTime.end()) {
1274 for (auto *M : ByModTime->second)
1276 LazyHeadersByModTime.erase(ByModTime);
1277 }
1278}
1279
1281 Module *Mod, std::optional<const FileEntry *> File) const {
1282 bool NeedsFramework = false;
1284 const auto Size = File ? (*File)->getSize() : 0;
1285 const auto ModTime = File ? (*File)->getModificationTime() : 0;
1286
1289 (Header.Size && Header.Size != Size)))
1290 NewHeaders.push_back(Header);
1291 else
1292
1293
1294 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1295 }
1297}
1298
1302
1304
1305
1306
1307
1308 auto &HeaderList = Headers[HeaderEntry];
1309 if (llvm::is_contained(HeaderList, KH))
1310 return;
1311
1312 HeaderList.push_back(KH);
1314
1315 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
1316 if (!Imported || isCompilingModuleHeader) {
1317
1318
1319 HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role, isCompilingModuleHeader);
1320 }
1321
1322
1323 for (const auto &Cb : Callbacks)
1324 Cb->moduleMapAddHeader(HeaderEntry.getName());
1325}
1326
1329 return {};
1330
1332}
1333
1337}
1338
1341 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1342 return InferredModuleAllowedBy.find(M)->second;
1343 }
1345}
1346
1350}
1351
1354 InferredModuleAllowedBy[M] = ModMapFID;
1355}
1356
1357std::error_code
1359 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1360
1361
1362
1363 if (llvm::sys::path::filename(Dir) == "Modules") {
1364 StringRef Parent = llvm::sys::path::parent_path(Dir);
1365 if (Parent.ends_with(".framework"))
1367 }
1368
1370 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1371 if (!DirEntry)
1372 return llvm::errorToErrorCode(DirEntry.takeError());
1373
1374
1376 if (CanonicalDir != Dir)
1377 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1378
1379
1380
1381
1382
1383
1384
1385 llvm::sys::path::remove_dots(Path);
1386
1387 return std::error_code();
1388}
1389
1392 AdditionalModMaps[M].insert(ModuleMap);
1393}
1394
1396 llvm::errs() << "Modules:";
1397 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1398 MEnd = Modules.end();
1399 M != MEnd; ++M)
1400 M->getValue()->print(llvm::errs(), 2);
1401
1402 llvm::errs() << "Headers:";
1403 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1404 H != HEnd; ++H) {
1405 llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1407 E = H->second.end();
1408 I != E; ++I) {
1409 if (I != H->second.begin())
1410 llvm::errs() << ",";
1411 llvm::errs() << I->getModule()->getFullModuleName();
1412 }
1413 llvm::errs() << "\n";
1414 }
1415}
1416
1422 if (Export.getPointer() || Export.getInt())
1423 Mod->Exports.push_back(Export);
1424 else
1426 }
1428}
1429
1432 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1433 Top->UnresolvedDirectUses.clear();
1435 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1436 if (DirectUse)
1437 Top->DirectUses.push_back(DirectUse);
1438 else
1439 Top->UnresolvedDirectUses.push_back(UDU);
1440 }
1441 return !Top->UnresolvedDirectUses.empty();
1442}
1443
1448 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1450 Conflict.Other = OtherMod;
1451 Conflict.Message = UC.Message;
1452 Mod->Conflicts.push_back(Conflict);
1453 } else
1455 }
1457}
1458
1459
1460
1461
1462
1463namespace clang {
1464
1465
1497
1500 union {
1501
1503
1504
1506 };
1507
1513 }
1514
1516
1519 }
1520
1523 }
1524
1528 }
1529 };
1530
1534
1535
1536
1538
1541
1542
1543 FileID ModuleMapFID;
1544
1545
1547
1548
1549
1551
1552
1553 bool IsSystem;
1554
1555
1556 bool HadError = false;
1557
1558
1559
1560 llvm::BumpPtrAllocator StringData;
1561
1562
1564
1565
1566 Module *ActiveModule = nullptr;
1567
1568
1569
1570
1571
1572
1573
1574
1575
1577
1578
1580
1581
1582
1584
1586 void parseModuleDecl();
1587 void parseExternModuleDecl();
1588 void parseRequiresDecl();
1590 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1591 void parseExportDecl();
1592 void parseExportAsDecl();
1593 void parseUseDecl();
1594 void parseLinkDecl();
1595 void parseConfigMacros();
1596 void parseConflict();
1597 void parseInferredModuleDecl(bool Framework, bool Explicit);
1598
1599
1600
1601
1602
1603 void diagnosePrivateModules(SourceLocation ExplicitLoc,
1605
1606 using Attributes = ModuleMap::Attributes;
1607
1608 bool parseOptionalAttributes(Attributes &Attrs);
1609
1610 public:
1615 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1616 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {
1618 consumeToken();
1619 }
1620
1622
1625 };
1626
1627}
1628
1631
1632retry:
1637 switch (LToken.getKind()) {
1638 case tok::raw_identifier: {
1642 Tok.Kind = llvm::StringSwitchMMToken::TokenKind(RI)
1660 break;
1661 }
1662
1663 case tok::comma:
1665 break;
1666
1667 case tok::eof:
1669 break;
1670
1671 case tok::l_brace:
1673 break;
1674
1675 case tok::l_square:
1677 break;
1678
1679 case tok::period:
1681 break;
1682
1683 case tok::r_brace:
1685 break;
1686
1687 case tok::r_square:
1689 break;
1690
1691 case tok:⭐
1693 break;
1694
1695 case tok::exclaim:
1697 break;
1698
1699 case tok::string_literal: {
1701 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1702 HadError = true;
1703 goto retry;
1704 }
1705
1706
1710 goto retry;
1711
1712
1713 unsigned Length = StringLiteral.GetStringLength();
1714 char *Saved = StringData.Allocate<char>(Length + 1);
1716 Saved[Length] = 0;
1717
1718
1722 break;
1723 }
1724
1725 case tok::numeric_constant: {
1726
1728 SpellingBuffer.resize(LToken.getLength() + 1);
1729 const char *Start = SpellingBuffer.data();
1730 unsigned Length =
1733 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1735 HadError = true;
1736 goto retry;
1737 }
1738
1741 break;
1742 }
1743
1744 case tok::comment:
1745 goto retry;
1746
1747 case tok::hash:
1748
1749
1750
1751
1752 {
1753 auto NextIsIdent = [&](StringRef Str) -> bool {
1755 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1757 };
1758 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1759 NextIsIdent("module") && NextIsIdent("contents")) {
1761 break;
1762 }
1763 }
1764 [[fallthrough]];
1765
1766 default:
1768 HadError = true;
1769 goto retry;
1770 }
1771
1773}
1774
1776 unsigned braceDepth = 0;
1777 unsigned squareDepth = 0;
1778 do {
1779 switch (Tok.Kind) {
1781 return;
1782
1784 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1785 return;
1786
1787 ++braceDepth;
1788 break;
1789
1791 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1792 return;
1793
1794 ++squareDepth;
1795 break;
1796
1798 if (braceDepth > 0)
1799 --braceDepth;
1800 else if (Tok.is(K))
1801 return;
1802 break;
1803
1805 if (squareDepth > 0)
1806 --squareDepth;
1807 else if (Tok.is(K))
1808 return;
1809 break;
1810
1811 default:
1812 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1813 return;
1814 break;
1815 }
1816
1817 consumeToken();
1818 } while (true);
1819}
1820
1821
1822
1823
1824
1825
1826
1827
1828bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1829 Id.clear();
1830 do {
1832 Id.push_back(
1834 consumeToken();
1835 } else {
1836 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1837 return true;
1838 }
1839
1841 break;
1842
1843 consumeToken();
1844 } while (true);
1845
1846 return false;
1847}
1848
1849namespace {
1850
1851
1852 enum AttributeKind {
1853
1854 AT_unknown,
1855
1856
1857 AT_system,
1858
1859
1860 AT_extern_c,
1861
1862
1863 AT_exhaustive,
1864
1865
1866 AT_no_undeclared_includes
1867 };
1868
1869}
1870
1871
1872
1873
1874
1875void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
1877 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1880 diag::note_mmap_rename_top_level_private_module);
1881 D << BadName << M->Name;
1883 };
1884
1886 auto const *M = E->getValue();
1887 if (M->Directory != ActiveModule->Directory)
1888 continue;
1889
1891 if (.starts_with(M->Name) &&
.ends_with("Private"))
1892 continue;
1895 Canonical.append("_Private");
1896
1897
1898 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1899 M->Name == ActiveModule->Parent->Name) {
1901 diag::warn_mmap_mismatched_private_submodule)
1903
1905 if (FrameworkLoc.isValid())
1906 FixItInitBegin = FrameworkLoc;
1907 if (ExplicitLoc.isValid())
1908 FixItInitBegin = ExplicitLoc;
1909
1911 FixedPrivModDecl.append("framework ");
1912 FixedPrivModDecl.append("module ");
1913 FixedPrivModDecl.append(Canonical);
1914
1915 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1917 continue;
1918 }
1919
1920
1922 ActiveModule->Name != Canonical) {
1924 diag::warn_mmap_mismatched_private_module_name)
1925 << ActiveModule->Name;
1926 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1928 }
1929 }
1930}
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950void ModuleMapParser::parseModuleDecl() {
1954 parseExternModuleDecl();
1955 return;
1956 }
1957
1958
1962 bool Framework = false;
1963
1964
1966 ExplicitLoc = consumeToken();
1968 }
1969
1970
1972 FrameworkLoc = consumeToken();
1973 Framework = true;
1974 }
1975
1976
1978 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1979 consumeToken();
1980 HadError = true;
1981 return;
1982 }
1983 CurrModuleDeclLoc = consumeToken();
1984
1985
1986
1988 return parseInferredModuleDecl(Framework, Explicit);
1989
1990
1992 if (parseModuleId(Id)) {
1993 HadError = true;
1994 return;
1995 }
1996
1997 if (ActiveModule) {
1998 if (Id.size() > 1) {
1999 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
2001
2002 HadError = true;
2003 return;
2004 }
2005 } else if (Id.size() == 1 && Explicit) {
2006
2007 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
2010 HadError = true;
2011 }
2012
2013 Module *PreviousActiveModule = ActiveModule;
2014 if (Id.size() > 1) {
2015
2016
2017 ActiveModule = nullptr;
2018 const Module *TopLevelModule = nullptr;
2019 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
2021 if (I == 0)
2022 TopLevelModule = Next;
2023 ActiveModule = Next;
2024 continue;
2025 }
2026
2027 Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module)
2028 << Id[I].first << (ActiveModule != nullptr)
2029 << (ActiveModule
2031 : "");
2032 HadError = true;
2033 }
2034
2035 if (TopLevelModule &&
2037 assert(ModuleMapFID !=
2039 "submodule defined in same file as 'module *' that allowed its "
2040 "top-level module");
2043 }
2044 }
2045
2046 StringRef ModuleName = Id.back().first;
2048
2049
2050 Attributes Attrs;
2051 if (parseOptionalAttributes(Attrs))
2052 return;
2053
2054
2057 << ModuleName;
2058 HadError = true;
2059 return;
2060 }
2062
2063
2064 Module *ShadowingModule = nullptr;
2066
2067
2068
2069
2071
2072 bool Inferred = Existing->IsInferred;
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088 bool PartOfFramework = Framework || Existing->isPartOfFramework();
2089
2090
2091 bool ParsedAsMainInput =
2096 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
2097 ActiveModule = PreviousActiveModule;
2098
2101 consumeToken();
2102 else {
2103 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2104 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2105 HadError = true;
2106 }
2107 return;
2108 }
2109
2111 ShadowingModule = Existing;
2112 } else {
2113
2114 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2115 << ModuleName;
2116 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2117
2118
2121 consumeToken();
2122
2123 HadError = true;
2124 return;
2125 }
2126 }
2127
2128
2129 if (ShadowingModule) {
2130 ActiveModule =
2132 } else {
2135 }
2136
2138 if (Attrs.IsSystem || IsSystem)
2139 ActiveModule->IsSystem = true;
2140 if (Attrs.IsExternC)
2142 if (Attrs.NoUndeclaredIncludes)
2144 ActiveModule->Directory = Directory;
2145
2146 StringRef MapFileName(
2148 if (MapFileName.ends_with("module.private.modulemap") ||
2149 MapFileName.ends_with("module_private.map")) {
2151 }
2152
2153
2154
2155
2159 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
2160 StartLoc) &&
2161 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
2162 StartLoc) &&
2164 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2165
2166 bool Done = false;
2167 do {
2168 switch (Tok.Kind) {
2171 Done = true;
2172 break;
2173
2175 parseConfigMacros();
2176 break;
2177
2179 parseConflict();
2180 break;
2181
2186 parseModuleDecl();
2187 break;
2188
2190 parseExportDecl();
2191 break;
2192
2194 parseExportAsDecl();
2195 break;
2196
2198 parseUseDecl();
2199 break;
2200
2202 parseRequiresDecl();
2203 break;
2204
2207 break;
2208
2213 else
2214 parseUmbrellaDirDecl(UmbrellaLoc);
2215 break;
2216 }
2217
2220 break;
2221
2224 break;
2225
2228 break;
2229
2231 parseLinkDecl();
2232 break;
2233
2234 default:
2235 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
2236 consumeToken();
2237 break;
2238 }
2239 } while (!Done);
2240
2242 consumeToken();
2243 else {
2244 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2245 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2246 HadError = true;
2247 }
2248
2249
2250
2254
2255
2256
2258 ActiveModule->Parent) {
2262 }
2263
2264
2265 ActiveModule = PreviousActiveModule;
2266}
2267
2268
2269
2270
2271
2272void ModuleMapParser::parseExternModuleDecl() {
2274 SourceLocation ExternLoc = consumeToken();
2275
2276
2278 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2279 consumeToken();
2280 HadError = true;
2281 return;
2282 }
2283 consumeToken();
2284
2285
2287 if (parseModuleId(Id)) {
2288 HadError = true;
2289 return;
2290 }
2291
2292
2294 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2295 HadError = true;
2296 return;
2297 }
2299 consumeToken();
2300
2301 StringRef FileNameRef = FileName;
2303 if (llvm::sys::path::is_relative(FileNameRef)) {
2304 ModuleMapFileName += Directory.getName();
2305 llvm::sys::path::append(ModuleMapFileName, FileName);
2306 FileNameRef = ModuleMapFileName;
2307 }
2310 *File, IsSystem,
2312 ? Directory
2313 : File->getDir(),
2314 FileID(), nullptr, ExternLoc);
2315}
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2333 bool &IsRequiresExcludedHack) {
2334 if (Feature == "excluded" &&
2337 IsRequiresExcludedHack = true;
2338 return false;
2339 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
2340 return false;
2341 }
2342
2343 return true;
2344}
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357void ModuleMapParser::parseRequiresDecl() {
2359
2360
2361 consumeToken();
2362
2363
2364 do {
2365 bool RequiredState = true;
2367 RequiredState = false;
2368 consumeToken();
2369 }
2370
2372 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
2373 HadError = true;
2374 return;
2375 }
2376
2377
2378 std::string Feature = std::string(Tok.getString());
2379 consumeToken();
2380
2381 bool IsRequiresExcludedHack = false;
2382 bool ShouldAddRequirement =
2384
2385 if (IsRequiresExcludedHack)
2386 UsesRequiresExcludedHack.insert(ActiveModule);
2387
2388 if (ShouldAddRequirement) {
2389
2390 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2391 *Map.Target);
2392 }
2393
2395 break;
2396
2397
2398 consumeToken();
2399 } while (true);
2400}
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
2413
2415
2418
2420 LeadingToken = Tok.Kind;
2421 consumeToken();
2422 }
2425 }
2426
2429
2430 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2431
2432
2434 }
2435
2442 return;
2443 }
2444 consumeToken();
2445 }
2446
2447
2450 << "header";
2451 HadError = true;
2452 return;
2453 }
2459
2460
2462 !std::holds_alternativestd::monostate(ActiveModule->Umbrella)) {
2465 HadError = true;
2466 return;
2467 }
2468
2469
2470
2473
2475 enum Attribute { Size, ModTime, Unknown };
2476 StringRef Str = Tok.getString();
2478 switch (llvm::StringSwitch(Str)
2479 .Case("size", Size)
2480 .Case("mtime", ModTime)
2483 if (Header.Size)
2484 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2487 diag::err_mmap_invalid_header_attribute_value) << Str;
2489 break;
2490 }
2492 consumeToken();
2493 break;
2494
2495 case ModTime:
2497 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2500 diag::err_mmap_invalid_header_attribute_value) << Str;
2502 break;
2503 }
2505 consumeToken();
2506 break;
2507
2509 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2511 break;
2512 }
2513 }
2514
2516 consumeToken();
2517 else {
2518 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2519 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2520 HadError = true;
2521 }
2522 }
2523
2524 bool NeedsFramework = false;
2525
2526
2527
2528 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
2530 ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
2531 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2532
2533 if (NeedsFramework)
2534 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2537}
2538
2542}
2543
2544
2545
2546
2547
2548void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
2549
2552 << "umbrella";
2553 HadError = true;
2554 return;
2555 }
2556
2557 std::string DirName = std::string(Tok.getString());
2558 std::string DirNameAsWritten = DirName;
2560
2561
2562 if (!std::holds_alternativestd::monostate(ActiveModule->Umbrella)) {
2563 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2565 HadError = true;
2566 return;
2567 }
2568
2569
2571 if (llvm::sys::path::is_absolute(DirName)) {
2573 } else {
2575 PathName = Directory.getName();
2576 llvm::sys::path::append(PathName, DirName);
2578 }
2579
2580 if (!Dir) {
2581 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2582 << DirName;
2583 return;
2584 }
2585
2586 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2587
2588
2589
2590
2591 std::error_code EC;
2593 llvm::vfs::FileSystem &FS =
2595 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2596 I != E && !EC; I.increment(EC)) {
2598 Module::Header Header = {"", std::string(I->path()), *FE};
2599 Headers.push_back(std::move(Header));
2600 }
2601 }
2602
2603
2605
2606 for (auto &Header : Headers)
2608 return;
2609 }
2610
2611 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2612 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2613 << OwningModule->getFullModuleName();
2614 HadError = true;
2615 return;
2616 }
2617
2618
2620}
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631void ModuleMapParser::parseExportDecl() {
2634
2635
2637 bool Wildcard = false;
2638 do {
2639
2641 ParsedModuleId.push_back(
2643 consumeToken();
2644
2646 consumeToken();
2647 continue;
2648 }
2649
2650 break;
2651 }
2652
2654 Wildcard = true;
2655 consumeToken();
2656 break;
2657 }
2658
2660 HadError = true;
2661 return;
2662 } while (true);
2663
2665 ExportLoc, ParsedModuleId, Wildcard
2666 };
2668}
2669
2670
2671
2672
2673
2674void ModuleMapParser::parseExportAsDecl() {
2676 consumeToken();
2677
2680 HadError = true;
2681 return;
2682 }
2683
2684 if (ActiveModule->Parent) {
2685 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
2686 consumeToken();
2687 return;
2688 }
2689
2692 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2694 } else {
2695 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2698 }
2699 }
2700
2703
2704 consumeToken();
2705}
2706
2707
2708
2709
2710
2711void ModuleMapParser::parseUseDecl() {
2713 auto KWLoc = consumeToken();
2714
2716 parseModuleId(ParsedModuleId);
2717
2718 if (ActiveModule->Parent)
2719 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2720 else
2722}
2723
2724
2725
2726
2727
2728void ModuleMapParser::parseLinkDecl() {
2731
2732
2733 bool IsFramework = false;
2735 consumeToken();
2736 IsFramework = true;
2737 }
2738
2739
2741 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2743 HadError = true;
2744 return;
2745 }
2746
2747 std::string LibraryName = std::string(Tok.getString());
2748 consumeToken();
2750 IsFramework));
2751}
2752
2753
2754
2755
2756
2757
2758
2759
2760void ModuleMapParser::parseConfigMacros() {
2763
2764
2765 if (ActiveModule->Parent) {
2766 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2767 }
2768
2769
2770 Attributes Attrs;
2771 if (parseOptionalAttributes(Attrs))
2772 return;
2773
2774 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2776 }
2777
2778
2779
2781 return;
2782
2783
2784 if (!ActiveModule->Parent) {
2786 }
2787 consumeToken();
2788
2789 do {
2790
2792 break;
2793 consumeToken();
2794
2795
2796
2798 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2799 break;
2800 }
2801
2802
2803 if (!ActiveModule->Parent) {
2805 }
2806 consumeToken();
2807 } while (true);
2808}
2809
2810
2812 std::string result;
2813 {
2814 llvm::raw_string_ostream OS(result);
2815
2816 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2817 if (I)
2818 OS << ".";
2819 OS << Id[I].first;
2820 }
2821 }
2822
2823 return result;
2824}
2825
2826
2827
2828
2829
2830void ModuleMapParser::parseConflict() {
2834
2835
2836 if (parseModuleId(Conflict.Id))
2837 return;
2838
2839
2841 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2843 return;
2844 }
2845 consumeToken();
2846
2847
2849 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2851 return;
2852 }
2854 consumeToken();
2855
2856
2858}
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2872 bool Failed = false;
2873
2874
2875 if (!ActiveModule && !Framework) {
2876 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2877 Failed = true;
2878 }
2879
2880 if (ActiveModule) {
2881
2882 if (!Failed && ActiveModule->IsAvailable &&
2884 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2885 Failed = true;
2886 }
2887
2888
2890 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2893 diag::note_mmap_prev_definition);
2894 Failed = true;
2895 }
2896
2897
2898 if (Framework) {
2899 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2900 Framework = false;
2901 }
2903 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2905 }
2906
2907
2908 if (Failed) {
2910 consumeToken();
2913 consumeToken();
2914 }
2915 HadError = true;
2916 return;
2917 }
2918
2919
2920 Attributes Attrs;
2921 if (parseOptionalAttributes(Attrs))
2922 return;
2923
2924 if (ActiveModule) {
2925
2929 } else {
2930
2931 Map.InferredDirectories[Directory].InferModules = true;
2932 Map.InferredDirectories[Directory].Attrs = Attrs;
2933 Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID;
2934
2935 }
2936
2937
2939 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2940 HadError = true;
2941 return;
2942 }
2944
2945
2946 bool Done = false;
2947 do {
2948 switch (Tok.Kind) {
2951 Done = true;
2952 break;
2953
2955 if (ActiveModule) {
2956 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2957 << (ActiveModule != nullptr);
2958 consumeToken();
2959 break;
2960 }
2961
2962 consumeToken();
2963
2965 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2966 break;
2967 }
2968
2969 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2971 consumeToken();
2972 break;
2973
2975 if (!ActiveModule) {
2976 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2977 << (ActiveModule != nullptr);
2978 consumeToken();
2979 break;
2980 }
2981
2982 consumeToken();
2985 else
2987 diag::err_mmap_expected_export_wildcard);
2988 consumeToken();
2989 break;
2990
2996 default:
2997 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2998 << (ActiveModule != nullptr);
2999 consumeToken();
3000 break;
3001 }
3002 } while (!Done);
3003
3005 consumeToken();
3006 else {
3007 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
3008 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
3009 HadError = true;
3010 }
3011}
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
3026 bool HadError = false;
3027
3029
3031
3032
3034 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
3037 consumeToken();
3038 HadError = true;
3039 }
3040
3041
3042 AttributeKind Attribute
3043 = llvm::StringSwitch(Tok.getString())
3044 .Case("exhaustive", AT_exhaustive)
3045 .Case("extern_c", AT_extern_c)
3046 .Case("no_undeclared_includes", AT_no_undeclared_includes)
3047 .Case("system", AT_system)
3048 .Default(AT_unknown);
3049 switch (Attribute) {
3050 case AT_unknown:
3051 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
3053 break;
3054
3055 case AT_system:
3056 Attrs.IsSystem = true;
3057 break;
3058
3059 case AT_extern_c:
3060 Attrs.IsExternC = true;
3061 break;
3062
3063 case AT_exhaustive:
3064 Attrs.IsExhaustive = true;
3065 break;
3066
3067 case AT_no_undeclared_includes:
3068 Attrs.NoUndeclaredIncludes = true;
3069 break;
3070 }
3071 consumeToken();
3072
3073
3075 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
3076 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
3078 HadError = true;
3079 }
3080
3082 consumeToken();
3083 }
3084
3085 return HadError;
3086}
3087
3088
3089
3090
3091
3093 do {
3094 switch (Tok.Kind) {
3096 return HadError;
3097
3102 parseModuleDecl();
3103 break;
3104
3128 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
3129 HadError = true;
3130 consumeToken();
3131 break;
3132 }
3133 } while (true);
3134}
3135
3138 unsigned *Offset,
3140 assert(Target && "Missing target information");
3141 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3142 = ParsedModuleMap.find(File);
3143 if (Known != ParsedModuleMap.end())
3144 return Known->second;
3145
3146
3147 if (ID.isInvalid()) {
3148 auto FileCharacter =
3150 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
3151 }
3152
3153 assert(Target && "Missing target information");
3154 std::optionalllvm::MemoryBufferRef Buffer = SourceMgr.getBufferOrNone(ID);
3155 if (!Buffer)
3156 return ParsedModuleMap[File] = true;
3157 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
3158 "invalid buffer offset");
3159
3160
3162 Buffer->getBufferStart(),
3163 Buffer->getBufferStart() + (Offset ? *Offset : 0),
3164 Buffer->getBufferEnd());
3169
3170 if (Offset) {
3172 assert(Loc.first == ID && "stopped in a different file?");
3173 *Offset = Loc.second;
3174 }
3175
3176
3177 for (const auto &Cb : Callbacks)
3178 Cb->moduleMapFileRead(Start, File, IsSystem);
3179
3181}
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
#define ALIAS(NAME, TOK, FLAGS)
#define KEYWORD(NAME, FLAGS)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
static Module * getTopLevelOrNull(Module *M)
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives.
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
static std::string formatModuleId(const ModuleId &Id)
Format a module-id into a string.
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
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).
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.
DirectoryEntryRef getDir() const
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.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
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.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompilingModule() const
Are we compiling a module?
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
SourceLocation getSourceLocation(const char *Loc, unsigned TokLen=1) const
getSourceLocation - Return a source location identifier for the specified offset in the current file.
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...
Required to construct a Module.
SourceLocation getLocation()
bool terminatedByDirective()
bool parseModuleMapFile()
Parse a module map file.
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
void dump()
Dump the contents of the module map, for debugging purposes.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
bool mayShadowNewModule(Module *ExistingModule)
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
module_iterator module_begin() const
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 shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
FileID getModuleMapFileIDForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
Module * findOrCreateModuleFirst(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Call ModuleMap::findOrCreateModule and throw away the information whether the module was found or cre...
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Module * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Create new submodule, assuming it does not exist.
module_iterator module_end() const
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
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.
~ModuleMap()
Destroy the module map.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
void setTarget(const TargetInfo &Target)
Set the target information.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
ModuleHeaderRole
Flags describing the role of a module header.
@ PrivateHeader
This header is included but private.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ NormalHeader
This header is normally included in the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module interface unit.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)
Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
SourceLocation InferredSubmoduleLoc
The location of the inferred submodule.
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
SourceLocation DefinitionLoc
The location of the module definition.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Module * Parent
The parent of this module.
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
void addHeader(HeaderKind HK, Header H)
std::string UmbrellaRelativeToRootModuleDirectory
OptionalDirectoryEntryRef Directory
The build directory of this module.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
ArrayRef< Header > getHeaders(HeaderKind HK) const
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
@ ModuleHeaderUnit
This is a C++20 header unit.
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
unsigned IsFramework
Whether this is a framework module.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned IsAvailable
Whether this module is available in the current translation unit.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
std::vector< Conflict > Conflicts
The list of conflicts.
Parser - This implements a parser for the C family of languages.
Encodes a location in the source.
static SourceLocation getFromRawEncoding(UIntTy Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
StringLiteral - This represents a string literal expression, e.g.
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
Defines the clang::TargetInfo interface.
bool Sub(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
A token in a module map file.
SourceLocation getLocation() const
bool is(TokenKind K) const
SourceLocation::UIntTy Location
StringRef getString() const
enum clang::MMToken::TokenKind Kind
uint64_t getInteger() const
A conflict between two modules.
Module * Other
The module that this module conflicts with.
std::string Message
The message provided to the user when there is a conflict.
A library or framework to link against when an entity from this module is used.
An unresolved conflict with another module.
std::string Message
The message provided to the user when there is a conflict.
ModuleId Id
The (unresolved) module id.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...