clang: lib/Lex/ModuleMap.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
28#include "llvm/ADT/DenseMap.h"
29#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/SmallPtrSet.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/StringSwitch.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/Path.h"
38#include "llvm/Support/VirtualFileSystem.h"
39#include "llvm/Support/raw_ostream.h"
40#include
41#include
42#include
43#include
44#include <system_error>
45#include
46
47using namespace clang;
48
49void ModuleMapCallbacks::anchor() {}
50
52 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
53 if (PendingLinkAs != PendingLinkAsModule.end()) {
54 for (auto &Name : PendingLinkAs->second) {
56 if (M)
57 M->UseExportAsModuleLinkName = true;
58 }
59 }
60}
61
68
70 switch ((int)Role) {
81 }
82 llvm_unreachable("unknown header role");
83}
84
87 switch ((int)Kind) {
98 }
99 llvm_unreachable("unknown header kind");
100}
101
105
107ModuleMap::resolveExport(Module *Mod,
109 bool Complain) const {
110
112 assert(Unresolved.Wildcard && "Invalid unresolved export");
114 }
115
116
117 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
118 if (!Context)
119 return {};
120
122}
123
125 bool Complain) const {
126
128 if (!Context) {
129 if (Complain)
130 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
132
133 return nullptr;
134 }
135
136
137 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
139 if (!Sub) {
140 if (Complain)
141 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
142 << Id[I].first << Context->getFullModuleName()
143 << SourceRange(Id[0].second, Id[I-1].second);
144
145 return nullptr;
146 }
147
148 Context = Sub;
149 }
150
151 return Context;
152}
153
154
155
158
160 for (; Mod; Mod = Mod->Parent) {
162 Paths.push_back(Mod->Name);
163 }
164
165 if (Paths.empty())
166 return;
167
168
169 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
170 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");
171}
172
176
178 SmallString<128> FullPathName(Directory->getName());
179
182 expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
183 if ( || (Header.Size && File->getSize() != *Header.Size) ||
185 return std::nullopt;
186 return *File;
187 };
188
190 unsigned FullPathLength = FullPathName.size();
192 unsigned RelativePathLength = RelativePathName.size();
193
194
195 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
196 llvm::sys::path::append(FullPathName, RelativePathName);
197 if (auto File = GetFile(FullPathName))
199
200
201
202
203
204
205
207 RelativePathName.clear();
208 else
209 RelativePathName.resize(RelativePathLength);
210 FullPathName.resize(FullPathLength);
211 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
213 llvm::sys::path::append(FullPathName, RelativePathName);
214 return GetFile(FullPathName);
215 };
216
217 if (llvm::sys::path::is_absolute(Header.FileName)) {
218 RelativePathName.clear();
219 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
220 return GetFile(Header.FileName);
221 }
222
224 return GetFrameworkFile();
225
226
227 llvm::sys::path::append(RelativePathName, Header.FileName);
228 llvm::sys::path::append(FullPathName, RelativePathName);
229 auto NormalHdrFile = GetFile(FullPathName);
230
231 if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
232
233
234
235 FullPathName.assign(Directory->getName());
236 RelativePathName.clear();
237 if (GetFrameworkFile()) {
239 diag::warn_mmap_incomplete_framework_module_declaration)
241 NeedsFramework = true;
242 }
243 return std::nullopt;
244 }
245
246 return NormalHdrFile;
247}
248
249
250
251
253 return llvm::StringSwitch(FileName)
254 .Case("float.h", true)
255 .Case("iso646.h", true)
256 .Case("limits.h", true)
257 .Case("stdalign.h", true)
258 .Case("stdarg.h", true)
259 .Case("stdatomic.h", true)
260 .Case("stdbool.h", true)
261 .Case("stdckdint.h", true)
262 .Case("stdcountof.h", true)
263 .Case("stddef.h", true)
264 .Case("stdint.h", true)
265 .Case("tgmath.h", true)
266 .Case("unwind.h", true)
267 .Default(false);
268}
269
270
271
273 return llvm::StringSwitch(ModuleName)
274 .Case("_Builtin_float", true)
275 .Case("_Builtin_inttypes", true)
276 .Case("_Builtin_iso646", true)
277 .Case("_Builtin_limits", true)
278 .Case("_Builtin_stdalign", true)
279 .Case("_Builtin_stdarg", true)
280 .Case("_Builtin_stdatomic", true)
281 .Case("_Builtin_stdbool", true)
282 .Case("_Builtin_stddef", true)
283 .Case("_Builtin_stdint", true)
284 .Case("_Builtin_stdnoreturn", true)
285 .Case("_Builtin_tgmath", true)
286 .Case("_Builtin_unwind", true)
287 .Default(false);
288}
289
290void ModuleMap::resolveHeader(Module *Mod,
292 bool &NeedsFramework) {
293 SmallString<128> RelativePathName;
295 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
297 const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
298 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
299 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
300 << UmbrellaMod->getFullModuleName();
301 else
302
304 RelativePathName.str());
305 } else {
306 Module::Header H = {Header.FileName, std::string(RelativePathName),
309 }
311
312
314
315 } else {
316
317
319
320
321
322
325 }
326}
327
328bool ModuleMap::resolveAsBuiltinHeader(
331 llvm::sys::path::is_absolute(Header.FileName) ||
333 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
335 return false;
336
337
338
339
340 SmallString<128> Path;
341 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
342 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
344 return false;
345
349 return true;
350}
351
355 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
356 HeaderInfo(HeaderInfo) {
357}
358
360
362 assert((!this->Target || this->Target == &Target) &&
363 "Improper target override");
364 this->Target = &Target;
365}
366
367
370 if (Name.empty())
371 return Name;
372
374
375
376 Buffer.clear();
378 Buffer.push_back('_');
379 Buffer.reserve(Buffer.size() + Name.size());
380 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
382 Buffer.push_back(Name[I]);
383 else
384 Buffer.push_back('_');
385 }
386
387 Name = StringRef(Buffer.data(), Buffer.size());
388 }
389
390 while (llvm::StringSwitch(Name)
393#include "clang/Basic/TokenKinds.def"
395 if (Name.data() != Buffer.data())
396 Buffer.append(Name.begin(), Name.end());
397 Buffer.push_back('_');
398 Name = StringRef(Buffer.data(), Buffer.size());
399 }
400
401 return Name;
402}
403
405 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
407}
408
411 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
414}
415
416ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
418 HeadersMap::iterator Known = Headers.find(File);
422 return Headers.find(File);
423 }
424 return Known;
425}
426
429 if (UmbrellaDirs.empty())
430 return {};
431
433
434
435
436
437
438 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
439
440
441
442 do {
443 auto KnownDir = UmbrellaDirs.find(*Dir);
444 if (KnownDir != UmbrellaDirs.end())
446
447 IntermediateDirs.push_back(*Dir);
448
449
450 DirName = llvm::sys::path::parent_path(DirName);
451 if (DirName.empty())
452 break;
453
454
455 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
456 } while (Dir);
457 return {};
458}
459
463#ifndef NDEBUG
465
466
467
468 bool IsPrivate = false;
472 for (auto Hs : HeaderList)
473 IsPrivate |= llvm::any_of(
475 assert(IsPrivate && "inconsistent headers and roles");
476 }
477#endif
479}
480
484
486 bool RequestingModuleIsModuleInterface,
489
490
492 return;
493
494 if (RequestingModule) {
495 resolveUses(RequestingModule, false);
497 }
498
499 bool Excluded = false;
501 Module *NotUsed = nullptr;
502
503 HeadersMap::iterator Known = findKnownHeader(File);
504 if (Known != Headers.end()) {
505 for (const KnownHeader &Header : Known->second) {
506
508 Excluded = true;
509 continue;
510 }
511
512
515 continue;
516 }
517
518
519
520 if (RequestingModule && LangOpts.ModulesDeclUse &&
523 continue;
524 }
525
526
527 return;
528 }
529
530 Excluded = true;
531 }
532
533
535 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
536 << Filename;
537 return;
538 }
539
540
541 if (NotUsed) {
542 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
544 << NotUsed->Name;
545 return;
546 }
547
548 if (Excluded || isHeaderInUmbrellaDirs(File))
549 return;
550
551
552
553 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
554 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
556 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
557 LangOpts.isCompilingModule()) {
558
560 diag::warn_non_modular_include_in_framework_module :
561 diag::warn_non_modular_include_in_module;
562 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
563 << File.getName();
564 }
565}
566
569
570
571
572
574 return true;
575
576
580
581
585
586
590
591
592 return false;
593}
594
596 bool AllowTextual,
597 bool AllowExcluded) {
600 return {};
601 return R;
602 };
603
604 HeadersMap::iterator Known = findKnownHeader(File);
605 if (Known != Headers.end()) {
607
609
611 continue;
612
614 return MakeResult(H);
617 }
618 return MakeResult(Result);
619 }
620
621 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
622}
623
625ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
626 assert(!Headers.count(File) && "already have a module for this header");
627
629 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
630 if (H) {
632
633
634
637 UmbrellaModule = UmbrellaModule->Parent;
638
641
642
643
644
646
647 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
648
651 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
655
656
657 UmbrellaDirs[SkippedDir] = Result;
658
659
660
663 }
664
665
668 llvm::sys::path::stem(File.getName()), NameBuf);
672 Result->addTopHeader(File);
673
674
675
678 } else {
679
680
681 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
682 UmbrellaDirs[SkippedDirs[I]] = Result;
683 }
684
686 Headers[File].push_back(Header);
687 return Header;
688 }
689
690 return {};
691}
692
695 HeadersMap::iterator Known = findKnownHeader(File);
696 if (Known != Headers.end())
697 return Known->second;
698
699 if (findOrCreateModuleForHeaderInUmbrellaDir(File))
700 return Headers.find(File)->second;
701
702 return {};
703}
704
707
709 auto It = Headers.find(File);
710 if (It == Headers.end())
711 return {};
712 return It->second;
713}
714
718
722 HeadersMap::const_iterator Known = Headers.find(Header);
723 if (Known != Headers.end()) {
725 I = Known->second.begin(),
726 E = Known->second.end();
727 I != E; ++I) {
728
730 continue;
731
732 if (I->isAvailable() &&
733 (!RequestingModule ||
734 I->getModule()->isSubModuleOf(RequestingModule))) {
735
736
737
738
739
741 continue;
742 return false;
743 }
744 }
745 return true;
746 }
747
750 StringRef DirName = Dir->getName();
751
752 auto IsUnavailable = [&](const Module *M) {
753 return !M->isAvailable() && (!RequestingModule ||
755 };
756
757
758
759 do {
760 auto KnownDir = UmbrellaDirs.find(*Dir);
761 if (KnownDir != UmbrellaDirs.end()) {
763 if (IsUnavailable(Found))
764 return true;
765
766
767
770 UmbrellaModule->Parent)
771 UmbrellaModule = UmbrellaModule->Parent;
772
774 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
775
778 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
781 return false;
782 if (IsUnavailable(Found))
783 return true;
784 }
785
786
789 llvm::sys::path::stem(Header.getName()),
790 NameBuf);
793 return false;
794 }
795
796 return IsUnavailable(Found);
797 }
798
799 SkippedDirs.push_back(*Dir);
800
801
802 DirName = llvm::sys::path::parent_path(DirName);
803 if (DirName.empty())
804 break;
805
806
807 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
808 } while (Dir);
809
810 return false;
811}
812
814 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
815 if (Known != Modules.end())
816 return Known->getValue();
817
818 return nullptr;
819}
820
823 return SubM;
825 return nullptr;
826 Module *Result = new (ModulesAlloc.Allocate())
832 if (Result->InferExportWildcard)
835}
836
838 Module *Context) const {
839 for(; Context; Context = Context->Parent) {
841 return Sub;
842 }
843
845}
846
848 if (!Context)
850
851 return Context->findSubmodule(Name);
852}
853
856 bool IsFramework,
857 bool IsExplicit) {
858
860 return std::make_pair(Sub, false);
861
862
864 return std::make_pair(M, true);
865}
866
868 bool IsFramework, bool IsExplicit) {
870 "Creating duplicate submodule");
871
872 Module *Result = new (ModulesAlloc.Allocate())
874 IsFramework, IsExplicit, NumCreatedModules++);
875 if (!Parent) {
876 if (LangOpts.CurrentModule == Name)
877 SourceModule = Result;
878 Modules[Name] = Result;
879 ModuleScopeIDs[Result] = CurrentModuleScopeID;
880 }
882}
883
886 auto *Result = new (ModulesAlloc.Allocate()) Module(
888 true, NumCreatedModules++);
890
891
893 PendingSubmodules.emplace_back(Result);
895}
896
900 assert(Parent && "We should only create an implicit global module fragment "
901 "in a module purview");
902
903
904
905 auto *Result = new (ModulesAlloc.Allocate())
907 false, false, NumCreatedModules++);
910}
911
915 auto *Result = new (ModulesAlloc.Allocate()) Module(
917 true, NumCreatedModules++);
920}
921
924 auto *Result = new (ModulesAlloc.Allocate())
926 false, NumCreatedModules++);
928
929
930 for (auto &Submodule : PendingSubmodules)
931 Submodule->setParent(Result);
932 PendingSubmodules.clear();
934}
935
937 StringRef Name) {
938 assert(LangOpts.CurrentModule == Name && "module name mismatch");
939 assert(!Modules[Name] && "redefining existing module");
940
943 Modules[Name] = SourceModule = Result;
944
945
946
947 auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
948 assert(MainFile && "no input file for module interface");
950
952}
953
955 StringRef Name) {
956 assert(LangOpts.CurrentModule == Name && "module name mismatch");
957
959 "creating implementation module without an interface");
960
961
962
963
964 StringRef IName = ".ImplementationUnit";
965 assert(!Modules[IName] && "multiple implementation units?");
966
969 Modules[IName] = SourceModule = Result;
970
971
972 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
973 "no input file for module implementation");
974
976}
977
980 assert(LangOpts.CurrentModule == Name && "module name mismatch");
981 assert(!Modules[Name] && "redefining existing module");
982
983 auto *Result = new (ModulesAlloc.Allocate())
985 false, NumCreatedModules++);
987 Modules[Name] = SourceModule = Result;
990}
991
992
993
995 assert(Mod->IsFramework && "Can only infer linking for framework modules");
997 "Can only infer linking for top-level frameworks");
998
999 StringRef FrameworkName(Mod->Name);
1000 FrameworkName.consume_back("_Private");
1002 true));
1003}
1004
1006 bool IsSystem, Module *Parent) {
1007 Attributes Attrs;
1009 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
1010}
1011
1013 Attributes Attrs, Module *Parent) {
1014
1015
1016
1017
1018 StringRef FrameworkDirName =
1019 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
1020
1021
1022
1023
1026 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1027
1028
1030 return Mod;
1031
1033
1034
1035
1036 FileID ModuleMapFID;
1037 if (!Parent) {
1038
1039 bool canInfer = false;
1040 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1041
1042 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1043 if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {
1044
1045
1046 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1047 inferred = InferredDirectories.find(*ParentDir);
1048 if (inferred == InferredDirectories.end()) {
1049
1050
1051 bool IsFrameworkDir = Parent.ends_with(".framework");
1054
1055
1057 inferred = InferredDirectories.find(*ParentDir);
1058 }
1059
1060 if (inferred == InferredDirectories.end())
1061 inferred = InferredDirectories.insert(
1062 std::make_pair(*ParentDir, InferredDirectory())).first;
1063 }
1064
1065 if (inferred->second.InferModules) {
1066
1067
1068 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1069 canInfer =
1070 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1071
1072 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1073 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1074 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1075 Attrs.NoUndeclaredIncludes |=
1076 inferred->second.Attrs.NoUndeclaredIncludes;
1077 ModuleMapFID = inferred->second.ModuleMapFID;
1078 }
1079 }
1080 }
1081
1082
1083 if (!canInfer)
1084 return nullptr;
1085 } else {
1087 }
1088
1089
1090 SmallString<128> UmbrellaName = FrameworkDir.getName();
1091 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1093
1094
1095
1096
1097 if (!UmbrellaHeader)
1098 return nullptr;
1099
1100 Module *Result = new (ModulesAlloc.Allocate())
1101 Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,
1102 true, false, NumCreatedModules++);
1104 if (!Parent) {
1105 if (LangOpts.CurrentModule == ModuleName)
1106 SourceModule = Result;
1107 Modules[ModuleName] = Result;
1108 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1109 }
1110
1111 Result->IsSystem |= Attrs.IsSystem;
1112 Result->IsExternC |= Attrs.IsExternC;
1113 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1114 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1115 Result->Directory = FrameworkDir;
1116
1117
1118 StringRef RelativePath = UmbrellaName.str().substr(
1119 Result->getTopLevelModule()->Directory->getName().size());
1120 RelativePath = llvm::sys::path::relative_path(RelativePath);
1121
1122
1124 RelativePath);
1125
1126
1128
1129
1130 Result->InferSubmodules = true;
1131 Result->InferExportWildcard = true;
1132
1133
1134 std::error_code EC;
1135 SmallString<128> SubframeworksDirName = FrameworkDir.getName();
1136 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1137 llvm::sys::path::native(SubframeworksDirName);
1139 for (llvm::vfs::directory_iterator
1140 Dir = FS.dir_begin(SubframeworksDirName, EC),
1141 DirEnd;
1142 Dir != DirEnd && !EC; Dir.increment(EC)) {
1143 if (!StringRef(Dir->path()).ends_with(".framework"))
1144 continue;
1145
1147
1148
1149
1150
1151 StringRef SubframeworkDirName =
1153 bool FoundParent = false;
1154 do {
1155
1156 SubframeworkDirName
1157 = llvm::sys::path::parent_path(SubframeworkDirName);
1158 if (SubframeworkDirName.empty())
1159 break;
1160
1161 if (auto SubDir =
1163 if (*SubDir == FrameworkDir) {
1164 FoundParent = true;
1165 break;
1166 }
1167 }
1168 } while (true);
1169
1170 if (!FoundParent)
1171 continue;
1172
1173
1174 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1175 }
1176 }
1177
1178
1179
1180 if (->isSubFramework())
1182
1184}
1185
1187 Module *ShadowingModule) {
1188
1189
1190 Module *Result = new (ModulesAlloc.Allocate())
1192 IsFramework, false, NumCreatedModules++);
1193 Result->ShadowingModule = ShadowingModule;
1194 Result->markUnavailable(true);
1195 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1196 ShadowModules.push_back(Result);
1197
1199}
1200
1202 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1203 const Twine &PathRelativeToRootModuleDirectory) {
1205 Mod->Umbrella = UmbrellaHeader;
1208 PathRelativeToRootModuleDirectory.str();
1209 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1210
1211
1212 for (const auto &Cb : Callbacks)
1213 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1214}
1215
1218 const Twine &PathRelativeToRootModuleDirectory) {
1219 Mod->Umbrella = UmbrellaDir;
1222 PathRelativeToRootModuleDirectory.str();
1223 UmbrellaDirs[UmbrellaDir] = Mod;
1224}
1225
1226void ModuleMap::addUnresolvedHeader(Module *Mod,
1228 bool &NeedsFramework) {
1229
1230
1231 if (resolveAsBuiltinHeader(Mod, Header)) {
1232
1233
1234
1235
1239 }
1240
1241
1242
1243
1244
1247
1248
1250 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1251 else
1252 LazyHeadersBySize[*Header.Size].push_back(Mod);
1254 return;
1255 }
1256
1257
1258
1259 resolveHeader(Mod, Header, NeedsFramework);
1260}
1261
1263 auto BySize = LazyHeadersBySize.find(File->getSize());
1264 if (BySize != LazyHeadersBySize.end()) {
1265 for (auto *M : BySize->second)
1267 LazyHeadersBySize.erase(BySize);
1268 }
1269
1270 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1271 if (ByModTime != LazyHeadersByModTime.end()) {
1272 for (auto *M : ByModTime->second)
1274 LazyHeadersByModTime.erase(ByModTime);
1275 }
1276}
1277
1279 Module *Mod, std::optional<const FileEntry *> File) const {
1280 bool NeedsFramework = false;
1282 const auto Size = File ? (*File)->getSize() : 0;
1283 const auto ModTime = File ? (*File)->getModificationTime() : 0;
1284
1287 (Header.Size && Header.Size != Size)))
1288 NewHeaders.push_back(Header);
1289 else
1290
1291
1292 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1293 }
1295}
1296
1300
1302
1303
1304
1305
1306 auto &HeaderList = Headers[HeaderEntry];
1307 if (llvm::is_contained(HeaderList, KH))
1308 return;
1309
1310 HeaderList.push_back(KH);
1312
1313 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
1314 if (!Imported || isCompilingModuleHeader) {
1315
1316
1317 HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role, isCompilingModuleHeader);
1318 }
1319
1320
1321 for (const auto &Cb : Callbacks)
1322 Cb->moduleMapAddHeader(HeaderEntry.getName());
1323}
1324
1328 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator
1329 Known = ParsedModuleMap.find(File);
1330 if (Known != ParsedModuleMap.end())
1331 return Known->second == nullptr;
1332
1333
1334 if (ID.isInvalid()) {
1335 ID = SourceMgr.translateFile(File);
1336 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {
1337 auto FileCharacter =
1339 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
1340 }
1341 }
1342
1343 std::optionalllvm::MemoryBufferRef Buffer = SourceMgr.getBufferOrNone(ID);
1344 if (!Buffer) {
1345 ParsedModuleMap[File] = nullptr;
1346 return true;
1347 }
1348
1349 Diags.Report(diag::remark_mmap_parse) << File.getName();
1350 std::optionalmodulemap::ModuleMapFile MaybeMMF =
1352
1353 if (!MaybeMMF) {
1354 ParsedModuleMap[File] = nullptr;
1355 return true;
1356 }
1357
1358 ParsedModuleMaps.push_back(
1359 std::make_uniquemodulemap::ModuleMapFile(std::move(*MaybeMMF)));
1361 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;
1362 for (const auto &Decl : MMF.Decls) {
1363 std::visit(llvm::makeVisitor(
1365
1366
1367
1368 auto &ModuleDecls =
1369 ParsedModules[StringRef(MD.Id.front().first)];
1370 ModuleDecls.push_back(std::pair(&MMF, &MD));
1371 },
1373 PendingExternalModuleMaps.push_back(&EMD);
1374 }),
1376 }
1377
1379 StringRef FileNameRef = EMD->Path;
1381 if (llvm::sys::path::is_relative(FileNameRef)) {
1382 ModuleMapFileName += Dir.getName();
1383 llvm::sys::path::append(ModuleMapFileName, EMD->Path);
1384 FileNameRef = ModuleMapFileName;
1385 }
1386
1387 if (auto EFile =
1388 SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {
1390 ExternModuleLoc);
1391 }
1392 }
1393
1394 ParsedModuleMap[File] = &MMF;
1395
1396 for (const auto &Cb : Callbacks)
1398
1399 return false;
1400}
1401
1404 return {};
1405
1407}
1408
1413
1416 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1417 return InferredModuleAllowedBy.find(M)->second;
1418 }
1420}
1421
1426
1429 InferredModuleAllowedBy[M] = ModMapFID;
1430}
1431
1432std::error_code
1434 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1435
1436
1437
1438 if (llvm::sys::path::filename(Dir) == "Modules") {
1439 StringRef Parent = llvm::sys::path::parent_path(Dir);
1440 if (Parent.ends_with(".framework"))
1441 Dir = Parent;
1442 }
1443
1444 FileManager &FM = SourceMgr.getFileManager();
1445 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1446 if (!DirEntry)
1447 return llvm::errorToErrorCode(DirEntry.takeError());
1448
1449
1451 if (CanonicalDir != Dir)
1452 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1453
1454
1455
1456
1457
1458
1459
1460 llvm::sys::path::remove_dots(Path);
1461
1462 return std::error_code();
1463}
1464
1467 AdditionalModMaps[M].insert(ModuleMap);
1468}
1469
1471 llvm::errs() << "Modules:";
1472 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1473 MEnd = Modules.end();
1474 M != MEnd; ++M)
1475 M->getValue()->print(llvm::errs(), 2);
1476
1477 llvm::errs() << "Headers:";
1478 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1479 H != HEnd; ++H) {
1480 llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1482 E = H->second.end();
1483 I != E; ++I) {
1484 if (I != H->second.begin())
1485 llvm::errs() << ",";
1486 llvm::errs() << I->getModule()->getFullModuleName();
1487 }
1488 llvm::errs() << "\n";
1489 }
1490}
1491
1497 if (Export.getPointer() || Export.getInt())
1498 Mod->Exports.push_back(Export);
1499 else
1501 }
1503}
1504
1507 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1508 Top->UnresolvedDirectUses.clear();
1510 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1511 if (DirectUse)
1512 Top->DirectUses.push_back(DirectUse);
1513 else
1514 Top->UnresolvedDirectUses.push_back(UDU);
1515 }
1516 return !Top->UnresolvedDirectUses.empty();
1517}
1518
1523 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1525 Conflict.Other = OtherMod;
1526 Conflict.Message = UC.Message;
1527 Mod->Conflicts.push_back(Conflict);
1528 } else
1530 }
1532}
1533
1534
1535
1536
1537
1538namespace clang {
1541
1544
1545
1546 FileID ModuleMapFID;
1547
1548
1550
1551
1552
1554
1555
1556 bool IsSystem;
1557
1558
1559 bool HadError = false;
1560
1561
1562 Module *ActiveModule = nullptr;
1563
1564
1565
1566
1567
1568
1569
1570
1571
1573
1586
1587
1588
1589
1590
1591 void diagnosePrivateModules(SourceLocation StartLoc);
1592
1593 using Attributes = ModuleMap::Attributes;
1594
1595public:
1599 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),
1600 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
1601
1605};
1606
1607}
1608
1609
1610
1611
1612
1613void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {
1614 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1615 const Module *M, SourceRange ReplLoc) {
1616 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1617 diag::note_mmap_rename_top_level_private_module);
1618 D << BadName << M->Name;
1620 };
1621
1622 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1623 auto const *M = E->getValue();
1624 if (M->Directory != ActiveModule->Directory)
1625 continue;
1626
1627 SmallString<128> FullName(ActiveModule->getFullModuleName());
1628 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
1629 continue;
1630 SmallString<128> FixedPrivModDecl;
1631 SmallString<128> Canonical(M->Name);
1632 Canonical.append("_Private");
1633
1634
1635 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1636 M->Name == ActiveModule->Parent->Name) {
1637 Diags.Report(ActiveModule->DefinitionLoc,
1638 diag::warn_mmap_mismatched_private_submodule)
1639 << FullName;
1640
1641 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1643 FixItInitBegin = StartLoc;
1644
1645 if (ActiveModule->Parent->IsFramework)
1646 FixedPrivModDecl.append("framework ");
1647 FixedPrivModDecl.append("module ");
1648 FixedPrivModDecl.append(Canonical);
1649
1650 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1651 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1652 continue;
1653 }
1654
1655
1656 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1657 ActiveModule->Name != Canonical) {
1658 Diags.Report(ActiveModule->DefinitionLoc,
1659 diag::warn_mmap_mismatched_private_module_name)
1660 << ActiveModule->Name;
1661 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1662 SourceRange(ActiveModule->DefinitionLoc));
1663 }
1664 }
1665}
1666
1668 if (MD.Id.front().first == "*")
1669 return handleInferredModuleDecl(MD);
1670
1671 CurrModuleDeclLoc = MD.Location;
1672
1673 Module *PreviousActiveModule = ActiveModule;
1674 if (MD.Id.size() > 1) {
1675
1676
1677 ActiveModule = nullptr;
1678 const Module *TopLevelModule = nullptr;
1679 for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {
1681 Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {
1682 if (I == 0)
1683 TopLevelModule = Next;
1684 ActiveModule = Next;
1685 continue;
1686 }
1687
1688 Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)
1689 << MD.Id[I].first << (ActiveModule != nullptr)
1690 << (ActiveModule
1691 ? ActiveModule->getTopLevelModule()->getFullModuleName()
1692 : "");
1693 HadError = true;
1694 }
1695
1696 if (TopLevelModule &&
1697 ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
1698 assert(ModuleMapFID !=
1699 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
1700 "submodule defined in same file as 'module *' that allowed its "
1701 "top-level module");
1702 Map.addAdditionalModuleMapFile(
1703 TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
1704 }
1705 }
1706
1707 StringRef ModuleName = MD.Id.back().first;
1708 SourceLocation ModuleNameLoc = MD.Id.back().second;
1709
1710
1711 Module *ShadowingModule = nullptr;
1712 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1713
1714
1715
1716
1717 bool LoadedFromASTFile = Existing->IsFromModuleFile;
1718
1719 bool Inferred = Existing->IsInferred;
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735 bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
1736
1737
1738 bool ParsedAsMainInput =
1740 Map.LangOpts.CurrentModule == ModuleName &&
1741 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1742 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1743
1744
1745 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;
1746 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||
1747 SameModuleDecl) {
1748 ActiveModule = PreviousActiveModule;
1749
1750 return;
1751 }
1752
1753 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1754 ShadowingModule = Existing;
1755 } else {
1756
1757 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1758 << ModuleName;
1759 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1760 HadError = true;
1761 return;
1762 }
1763 }
1764
1765
1766 if (ShadowingModule) {
1767 ActiveModule =
1768 Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
1769 } else {
1770 ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
1772 }
1773
1774 ActiveModule->DefinitionLoc = ModuleNameLoc;
1776 ActiveModule->IsSystem = true;
1778 ActiveModule->IsExternC = true;
1780 ActiveModule->NoUndeclaredIncludes = true;
1781 ActiveModule->Directory = Directory;
1782
1783 StringRef MapFileName(
1784 SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
1785 if (MapFileName.ends_with("module.private.modulemap") ||
1786 MapFileName.ends_with("module_private.map")) {
1787 ActiveModule->ModuleMapIsPrivate = true;
1788 }
1789
1790
1791
1792
1793 SourceLocation StartLoc =
1794 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1795 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1796 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1797 StartLoc) &&
1798 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1799 StartLoc) &&
1800 ActiveModule->ModuleMapIsPrivate)
1801 diagnosePrivateModules(MD.Location);
1802
1804 std::visit(
1805 llvm::makeVisitor(
1806 [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },
1807 [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
1808 [&](const modulemap::UmbrellaDirDecl &UDD) {
1809 handleUmbrellaDirDecl(UDD);
1810 },
1811 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
1812 [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
1813 [&](const modulemap::ExportAsDecl &EAD) {
1814 handleExportAsDecl(EAD);
1815 },
1816 [&](const modulemap::ExternModuleDecl &EMD) {
1817 handleExternModuleDecl(EMD);
1818 },
1819 [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },
1820 [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
1821 [&](const modulemap::ConfigMacrosDecl &CMD) {
1822 handleConfigMacros(CMD);
1823 },
1824 [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },
1825 [&](const modulemap::ExcludeDecl &ED) {
1826 Diags.Report(ED.Location, diag::err_mmap_expected_member);
1827 }),
1829 }
1830
1831
1832
1833 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1834 ActiveModule->LinkLibraries.empty())
1836
1837
1838
1839 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
1840 ActiveModule->Parent) {
1841 ActiveModule->getTopLevelModule()->markUnavailable(false);
1842 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1843 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1844 }
1845
1846
1847 ActiveModule = PreviousActiveModule;
1848}
1849
1850void ModuleMapLoader::handleExternModuleDecl(
1852 StringRef FileNameRef = EMD.Path;
1853 SmallString<128> ModuleMapFileName;
1854 if (llvm::sys::path::is_relative(FileNameRef)) {
1855 ModuleMapFileName += Directory.getName();
1856 llvm::sys::path::append(ModuleMapFileName, EMD.Path);
1857 FileNameRef = ModuleMapFileName;
1858 }
1859 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
1860 Map.parseAndLoadModuleMapFile(
1861 *File, IsSystem,
1862 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1863 ? Directory
1864 : File->getDir(),
1865 FileID(), nullptr, EMD.Location);
1866}
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1884 bool &IsRequiresExcludedHack) {
1885 if (Feature == "excluded" &&
1888 IsRequiresExcludedHack = true;
1889 return false;
1891 return false;
1892 }
1893
1894 return true;
1895}
1896
1898
1899 for (const modulemap::RequiresFeature &RF : RD.Features) {
1900 bool IsRequiresExcludedHack = false;
1901 bool ShouldAddRequirement =
1903
1904 if (IsRequiresExcludedHack)
1905 UsesRequiresExcludedHack.insert(ActiveModule);
1906
1907 if (ShouldAddRequirement) {
1908
1910 *Map.Target);
1911 }
1912 }
1913}
1914
1916
1918
1923 }
1924
1927
1928 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1929
1930
1932 }
1933
1934 Module::UnresolvedHeaderDirective Header;
1938 Header.Kind = Map.headerRoleToKind(Role);
1939
1940
1942 !std::holds_alternativestd::monostate(ActiveModule->Umbrella)) {
1943 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1944 << ActiveModule->getFullModuleName();
1945 HadError = true;
1946 return;
1947 }
1948
1949 if (HD.Size)
1953
1954 bool NeedsFramework = false;
1955
1956
1957
1958 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
1960 ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
1961 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
1962
1963 if (NeedsFramework)
1964 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
1965 << ActiveModule->getFullModuleName()
1967}
1968
1973
1974void ModuleMapLoader::handleUmbrellaDirDecl(
1976 std::string DirName = std::string(UDD.Path);
1977 std::string DirNameAsWritten = DirName;
1978
1979
1980 if (!std::holds_alternativestd::monostate(ActiveModule->Umbrella)) {
1981 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
1982 << ActiveModule->getFullModuleName();
1983 HadError = true;
1984 return;
1985 }
1986
1987
1989 if (llvm::sys::path::is_absolute(DirName)) {
1990 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
1991 } else {
1992 SmallString<128> PathName;
1993 PathName = Directory.getName();
1994 llvm::sys::path::append(PathName, DirName);
1995 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
1996 }
1997
1998 if (!Dir) {
1999 Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)
2000 << DirName;
2001 return;
2002 }
2003
2004 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2005
2006
2007
2008
2009 std::error_code EC;
2010 SmallVector<Module::Header, 6> Headers;
2011 llvm::vfs::FileSystem &FS =
2012 SourceMgr.getFileManager().getVirtualFileSystem();
2013 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2014 I != E && !EC; I.increment(EC)) {
2015 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2016 Module::Header Header = {"", std::string(I->path()), *FE};
2017 Headers.push_back(std::move(Header));
2018 }
2019 }
2020
2021
2023
2024 for (auto &Header : Headers)
2026 return;
2027 }
2028
2029 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2030 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
2031 << OwningModule->getFullModuleName();
2032 HadError = true;
2033 return;
2034 }
2035
2036
2037 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
2038}
2039
2042 ActiveModule->UnresolvedExports.push_back(Unresolved);
2043}
2044
2046 const auto &ModName = EAD.Id.front();
2047
2048 if (!ActiveModule->ExportAsModule.empty()) {
2049 if (ActiveModule->ExportAsModule == ModName.first) {
2050 Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)
2051 << ActiveModule->Name << ModName.first;
2052 } else {
2053 Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)
2054 << ActiveModule->Name << ActiveModule->ExportAsModule
2055 << ModName.first;
2056 }
2057 }
2058
2059 ActiveModule->ExportAsModule = ModName.first;
2060 Map.addLinkAsDependency(ActiveModule);
2061}
2062
2064 if (ActiveModule->Parent)
2065 Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);
2066 else
2067 ActiveModule->UnresolvedDirectUses.push_back(UD.Id);
2068}
2069
2071 ActiveModule->LinkLibraries.push_back(
2072 Module::LinkLibrary(std::string{LD.Library}, LD.Framework));
2073}
2074
2075void ModuleMapLoader::handleConfigMacros(
2077 if (ActiveModule->Parent) {
2078 Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);
2079 return;
2080 }
2081
2082
2083
2085 ActiveModule->ConfigMacrosExhaustive = true;
2086 }
2087 ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),
2089}
2090
2092 Module::UnresolvedConflict Conflict;
2093
2096
2097
2098 ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));
2099}
2100
2101void ModuleMapLoader::handleInferredModuleDecl(
2103 SourceLocation StarLoc = MD.Id.front().second;
2104
2105
2106 if (!ActiveModule && !MD.Framework) {
2107 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2108 return;
2109 }
2110
2111 if (ActiveModule) {
2112
2113 if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
2114 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2115 return;
2116 }
2117
2118
2119 if (ActiveModule->InferSubmodules) {
2120 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2121 if (ActiveModule->InferredSubmoduleLoc.isValid())
2122 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2123 diag::note_mmap_prev_definition);
2124 return;
2125 }
2126
2127
2129 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2130 return;
2131 }
2133 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2134 return;
2135 }
2136
2137 if (ActiveModule) {
2138
2139 ActiveModule->InferSubmodules = true;
2140 ActiveModule->InferredSubmoduleLoc = StarLoc;
2141 ActiveModule->InferExplicitSubmodules = MD.Explicit;
2142 } else {
2143
2144 auto &InfDir = Map.InferredDirectories[Directory];
2145 InfDir.InferModules = true;
2146 InfDir.Attrs = MD.Attrs;
2147 InfDir.ModuleMapFID = ModuleMapFID;
2148
2149 }
2150
2152 std::visit(
2153 llvm::makeVisitor(
2154 [&](const auto &Other) {
2155 Diags.Report(Other.Location,
2156 diag::err_mmap_expected_inferred_member)
2157 << (ActiveModule != nullptr);
2158 },
2159 [&](const modulemap::ExcludeDecl &ED) {
2160
2161 if (ActiveModule) {
2163 diag::err_mmap_expected_inferred_member)
2164 << (ActiveModule != nullptr);
2165 HadError = true;
2166 return;
2167 }
2168 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(
2169 ED.Module);
2170 },
2171 [&](const modulemap::ExportDecl &ED) {
2172
2173 if (!ActiveModule) {
2175 diag::err_mmap_expected_inferred_member)
2176 << (ActiveModule != nullptr);
2177 HadError = true;
2178 return;
2179 }
2180
2181 if (ED.Wildcard && ED.Id.size() == 0)
2182 ActiveModule->InferExportWildcard = true;
2183 else
2184 Diags.Report(ED.Id.front().second,
2185 diag::err_mmap_expected_export_wildcard);
2186 }),
2188 }
2189}
2190
2192 handleModuleDecl(MD);
2193 return HadError;
2194}
2195
2198 handleExternModuleDecl(EMD);
2199 return HadError;
2200}
2201
2204 for (const auto &Decl : MMF.Decls) {
2205 std::visit(
2206 llvm::makeVisitor(
2209 handleExternModuleDecl(EMD);
2210 }),
2212 }
2213 return HadError;
2214}
2215
2217 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
2218 if (Known != Modules.end())
2219 return Known->getValue();
2220
2221 auto ParsedMod = ParsedModules.find(Name);
2222 if (ParsedMod == ParsedModules.end())
2223 return nullptr;
2224
2225 Diags.Report(diag::remark_mmap_load_module) << Name;
2226
2227 for (const auto &ModuleDecl : ParsedMod->second) {
2232 return nullptr;
2233 }
2234
2236}
2237
2240 unsigned *Offset,
2242 assert(Target && "Missing target information");
2243 llvm::DenseMap<const FileEntry *, bool>::iterator Known =
2244 LoadedModuleMap.find(File);
2245 if (Known != LoadedModuleMap.end())
2246 return Known->second;
2247
2248
2249 if (ID.isInvalid()) {
2250 ID = SourceMgr.translateFile(File);
2251
2252
2253
2254
2255 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {
2256 auto FileCharacter =
2258 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2259 }
2260 }
2261
2262 assert(Target && "Missing target information");
2263 std::optionalllvm::MemoryBufferRef Buffer = SourceMgr.getBufferOrNone(ID);
2264 if (!Buffer)
2265 return LoadedModuleMap[File] = true;
2266 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2267 "invalid buffer offset");
2268
2269 std::optionalmodulemap::ModuleMapFile MMF =
2271 bool Result = false;
2272 if (MMF) {
2273 Diags.Report(diag::remark_mmap_load) << File.getName();
2274 ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem);
2276 }
2278
2279
2280
2281 for (const auto &Cb : Callbacks)
2282 Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);
2283
2285}
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
std::shared_ptr< TokenRole > Role
A token can have a special role that can carry extra information about the token's formatting.
FormatToken * Next
The next token in the unwrapped line.
#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.
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
Definition ModuleMap.cpp:252
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
Definition ModuleMap.cpp:272
static Module * getTopLevelOrNull(Module *M)
Definition ModuleMap.cpp:481
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
Definition ModuleMap.cpp:460
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
Definition ModuleMap.cpp:994
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
Definition ModuleMap.cpp:368
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.
Definition ModuleMap.cpp:156
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
Definition ModuleMap.cpp:1883
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
Definition ModuleMap.cpp:567
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Definition ModuleMap.cpp:1969
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.
Decl - This represents one declaration (or definition), e.g.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
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.
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...
Required to construct a Module.
bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD)
Definition ModuleMap.cpp:2196
ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)
Definition ModuleMap.cpp:1596
bool parseAndLoadModuleMapFile(const modulemap::ModuleMapFile &MMF)
Definition ModuleMap.cpp:2202
bool loadModuleDecl(const modulemap::ModuleDecl &MD)
Definition ModuleMap.cpp:2191
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
Definition ModuleMap.cpp:1186
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
Definition ModuleMap.cpp:1492
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
Definition ModuleMap.cpp:62
friend class ModuleMapLoader
void dump()
Dump the contents of the module map, for debugging purposes.
Definition ModuleMap.cpp:1470
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.
Definition ModuleMap.cpp:854
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
Definition ModuleMap.cpp:1216
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
Definition ModuleMap.cpp:485
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
Definition ModuleMap.cpp:1465
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
Definition ModuleMap.cpp:1410
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Definition ModuleMap.cpp:69
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
Definition ModuleMap.cpp:813
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
Definition ModuleMap.cpp:2238
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Definition ModuleMap.cpp:595
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
Definition ModuleMap.cpp:978
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
Definition ModuleMap.cpp:102
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
Definition ModuleMap.cpp:1519
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Definition ModuleMap.cpp:719
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Definition ModuleMap.cpp:1262
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
Definition ModuleMap.cpp:706
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Definition ModuleMap.cpp:1423
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
Definition ModuleMap.cpp:409
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
Definition ModuleMap.cpp:954
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
Definition ModuleMap.cpp:352
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
Definition ModuleMap.cpp:1433
FileID getModuleMapFileIDForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
Definition ModuleMap.cpp:1414
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
Definition ModuleMap.cpp:1427
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
Definition ModuleMap.cpp:1201
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.
Definition ModuleMap.cpp:837
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Definition ModuleMap.cpp:404
Module * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Create new submodule, assuming it does not exist.
Definition ModuleMap.cpp:867
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
Definition ModuleMap.cpp:715
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
Definition ModuleMap.cpp:1402
~ModuleMap()
Destroy the module map.
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef Dir, FileID ID=FileID(), SourceLocation ExternModuleLoc=SourceLocation())
Parse a module map without creating clang::Module instances.
Definition ModuleMap.cpp:1325
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
Definition ModuleMap.cpp:884
void setTarget(const TargetInfo &Target)
Set the target information.
Definition ModuleMap.cpp:361
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
Definition ModuleMap.cpp:847
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
Definition ModuleMap.cpp:51
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.
Definition ModuleMap.cpp:936
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
Definition ModuleMap.cpp:1297
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
Definition ModuleMap.cpp:913
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
Definition ModuleMap.cpp:821
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Definition ModuleMap.cpp:694
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
Definition ModuleMap.cpp:898
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...
Definition ModuleMap.cpp:922
Module * findOrLoadModule(StringRef Name)
Definition ModuleMap.cpp:2216
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
Definition ModuleMap.cpp:86
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Definition ModuleMap.cpp:1505
Describes a module or submodule.
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.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
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.
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.
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.
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 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.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
Defines the clang::TargetInfo interface.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
bool Sub(InterpState &S, CodePtr OpPC)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
std::optional< ModuleMapFile > parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset)
Parse a module map file into an in memory representation.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
@ 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.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ Keyword
The name has been typo-corrected to a keyword.
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
@ Other
Other implicit parameter.
unsigned IsExternC
Whether this is an extern "C" module.
unsigned IsSystem
Whether this is a system module.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
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.
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 ...
std::vector< StringRef > Macros
ModuleAttributes Attrs
Points to the first keyword in the decl.
std::vector< Decl > Decls
Represents the parsed form of a module map file.
std::vector< TopLevelDecl > Decls
FileID ID
The FileID used to parse this module map. This is always a local ID.
OptionalDirectoryEntryRef Dir
The directory in which the module map was discovered.
std::vector< RequiresFeature > Features