30 #include "llvm/ADT/DenseMap.h"
31 #include "llvm/ADT/None.h"
32 #include "llvm/ADT/STLExtras.h"
33 #include "llvm/ADT/SmallPtrSet.h"
34 #include "llvm/ADT/SmallString.h"
35 #include "llvm/ADT/SmallVector.h"
36 #include "llvm/ADT/StringMap.h"
37 #include "llvm/ADT/StringRef.h"
38 #include "llvm/ADT/StringSwitch.h"
39 #include "llvm/Support/Allocator.h"
40 #include "llvm/Support/Compiler.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include "llvm/Support/MemoryBuffer.h"
43 #include "llvm/Support/Path.h"
44 #include "llvm/Support/VirtualFileSystem.h"
45 #include "llvm/Support/raw_ostream.h"
51 #include <system_error>
54 using namespace clang;
56 void ModuleMapCallbacks::anchor() {}
59 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
60 if (PendingLinkAs != PendingLinkAsModule.end()) {
61 for (
auto &Name : PendingLinkAs->second) {
64 M->UseExportAsModuleLinkName =
true;
78 default: llvm_unreachable(
"unknown header role");
102 llvm_unreachable(
"unexpected header kind");
104 llvm_unreachable(
"unknown header kind");
108 ModuleMap::resolveExport(
Module *Mod,
110 bool Complain)
const {
113 assert(
Unresolved.Wildcard &&
"Invalid unresolved export");
126 bool Complain)
const {
131 Diags.
Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
138 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
142 Diags.
Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
143 <<
Id[I].first << Context->getFullModuleName()
161 for (; Mod; Mod = Mod->
Parent) {
163 Paths.push_back(Mod->
Name);
170 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
171 llvm::sys::path::append(Path,
"Frameworks", Framework +
".framework");
175 Module *M,
const Module::UnresolvedHeaderDirective &Header,
184 if (!File || (Header.Size &&
File->getSize() != *Header.Size) ||
185 (Header.ModTime &&
File->getModificationTime() != *Header.ModTime))
191 unsigned FullPathLength = FullPathName.size();
193 unsigned RelativePathLength = RelativePathName.size();
196 llvm::sys::path::append(RelativePathName,
"Headers", Header.FileName);
197 llvm::sys::path::append(FullPathName, RelativePathName);
198 if (
auto File = GetFile(FullPathName))
208 RelativePathName.clear();
210 RelativePathName.resize(RelativePathLength);
211 FullPathName.resize(FullPathLength);
212 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
214 llvm::sys::path::append(FullPathName, RelativePathName);
215 return GetFile(FullPathName);
218 if (llvm::sys::path::is_absolute(Header.FileName)) {
219 RelativePathName.clear();
220 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
221 return GetFile(Header.FileName);
225 return GetFrameworkFile();
228 llvm::sys::path::append(RelativePathName, Header.FileName);
229 llvm::sys::path::append(FullPathName, RelativePathName);
230 auto NormalHdrFile = GetFile(FullPathName);
232 if (!NormalHdrFile && Directory->getName().endswith(
".framework")) {
236 FullPathName.assign(Directory->getName());
237 RelativePathName.clear();
238 if (GetFrameworkFile()) {
239 Diags.
Report(Header.FileNameLoc,
240 diag::warn_mmap_incomplete_framework_module_declaration)
242 NeedsFramework =
true;
247 return NormalHdrFile;
250 void ModuleMap::resolveHeader(
Module *Mod,
251 const Module::UnresolvedHeaderDirective &Header,
252 bool &NeedsFramework) {
255 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
256 if (Header.IsUmbrella) {
258 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
259 Diags.
Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
260 << UmbrellaMod->getFullModuleName();
265 Module::Header H = {Header.FileName,
std::string(RelativePathName.str()),
272 }
else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
285 if (!Header.Size && !Header.ModTime)
290 bool ModuleMap::resolveAsBuiltinHeader(
291 Module *Mod,
const Module::UnresolvedHeaderDirective &Header) {
293 llvm::sys::path::is_absolute(Header.FileName) ||
295 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
303 llvm::sys::path::append(Path, BuiltinIncludeDir->
getName(), Header.FileName);
317 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts),
Target(
Target),
318 HeaderInfo(HeaderInfo) {
319 MMapLangOpts.LineComment =
true;
323 for (
auto &M : Modules)
325 for (
auto *M : ShadowModules)
330 assert((!this->Target || this->Target == &
Target) &&
331 "Improper target override");
346 Buffer.push_back(
'_');
347 Buffer.reserve(Buffer.size() + Name.size());
348 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
350 Buffer.push_back(Name[I]);
352 Buffer.push_back(
'_');
355 Name = StringRef(Buffer.data(), Buffer.size());
358 while (llvm::StringSwitch<bool>(Name)
359 #define
KEYWORD(Keyword,Conditions) .Case(#Keyword,
true)
360 #define
ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword,
true)
361 #
include "clang/Basic/TokenKinds.def"
363 if (Name.data() != Buffer.data())
364 Buffer.append(Name.begin(), Name.end());
365 Buffer.push_back(
'_');
366 Name = StringRef(Buffer.data(), Buffer.size());
376 return llvm::StringSwitch<bool>(FileName)
377 .Case(
"float.h",
true)
378 .Case(
"iso646.h",
true)
379 .Case(
"limits.h",
true)
380 .Case(
"stdalign.h",
true)
381 .Case(
"stdarg.h",
true)
382 .Case(
"stdatomic.h",
true)
383 .Case(
"stdbool.h",
true)
384 .Case(
"stddef.h",
true)
385 .Case(
"stdint.h",
true)
386 .Case(
"tgmath.h",
true)
387 .Case(
"unwind.h",
true)
392 return File->getDir() == BuiltinIncludeDir &&
396 ModuleMap::HeadersMap::iterator
397 ModuleMap::findKnownHeader(
const FileEntry *File) {
399 HeadersMap::iterator Known = Headers.find(File);
403 return Headers.find(File);
409 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
411 if (UmbrellaDirs.empty())
415 assert(Dir &&
"file in no directory");
426 auto KnownDir = UmbrellaDirs.find(Dir);
427 if (KnownDir != UmbrellaDirs.end())
430 IntermediateDirs.push_back(Dir);
433 DirName = llvm::sys::path::parent_path(DirName);
454 bool IsPrivate =
false;
458 for (
auto *Hs : HeaderList)
460 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
461 return H.Entry == IncFileEnt;
463 assert(IsPrivate &&
"inconsistent headers and roles");
474 bool RequestingModuleIsModuleInterface,
482 if (RequestingModule) {
487 bool Excluded =
false;
488 Module *Private =
nullptr;
489 Module *NotUsed =
nullptr;
491 HeadersMap::iterator Known = findKnownHeader(
File);
492 if (Known != Headers.end()) {
502 if (RequestingModule && LangOpts.ModulesDeclUse &&
517 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
524 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
529 if (Excluded || isHeaderInUmbrellaDirs(
File))
534 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
535 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
537 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
541 diag::warn_non_modular_include_in_framework_module :
542 diag::warn_non_modular_include_in_module;
579 HeadersMap::iterator Known = findKnownHeader(
File);
580 if (Known != Headers.end()) {
586 return MakeResult(H);
590 return MakeResult(Result);
593 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(
File));
597 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
598 assert(!Headers.count(File) &&
"already have a module for this header");
601 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
603 Module *Result = H.getModule();
607 Module *UmbrellaModule = Result;
609 UmbrellaModule = UmbrellaModule->
Parent;
620 for (
const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) {
624 llvm::sys::path::stem(SkippedDir->getName()), NameBuf);
627 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
628 Result->IsInferred =
true;
631 UmbrellaDirs[SkippedDir] = Result;
642 llvm::sys::path::stem(
File->getName()), NameBuf);
645 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
646 Result->IsInferred =
true;
647 Result->addTopHeader(File);
656 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
657 UmbrellaDirs[SkippedDirs[I]] = Result;
661 Headers[
File].push_back(Header);
670 HeadersMap::iterator Known = findKnownHeader(
File);
671 if (Known != Headers.end())
672 return Known->second;
674 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
675 return Headers.find(
File)->second;
684 auto It = Headers.find(
File);
685 if (It == Headers.end())
696 const Module *RequestingModule)
const {
698 HeadersMap::const_iterator Known = Headers.find(Header);
699 if (Known != Headers.end()) {
701 I = Known->second.begin(),
702 E = Known->second.end();
705 if (I->isAvailable() &&
706 (!RequestingModule ||
723 StringRef DirName = Dir->
getName();
725 auto IsUnavailable = [&](
const Module *M) {
733 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
734 = UmbrellaDirs.find(Dir);
735 if (KnownDir != UmbrellaDirs.end()) {
736 Module *Found = KnownDir->second;
737 if (IsUnavailable(Found))
742 Module *UmbrellaModule = Found;
744 UmbrellaModule = UmbrellaModule->
Parent;
747 for (
const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) {
751 llvm::sys::path::stem(SkippedDir->getName()), NameBuf);
755 if (IsUnavailable(Found))
762 llvm::sys::path::stem(Header->
getName()),
769 return IsUnavailable(Found);
772 SkippedDirs.push_back(Dir);
775 DirName = llvm::sys::path::parent_path(DirName);
790 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
791 if (Known != Modules.end())
792 return Known->getValue();
799 for(; Context; Context = Context->Parent) {
811 return Context->findSubmodule(Name);
820 return std::make_pair(
Sub,
false);
824 IsExplicit, NumCreatedModules++);
827 SourceModule = Result;
828 Modules[Name] = Result;
829 ModuleScopeIDs[Result] = CurrentModuleScopeID;
831 return std::make_pair(Result,
true);
836 auto *Result =
new Module(
"<global>", Loc,
Parent,
false,
837 true, NumCreatedModules++);
842 PendingSubmodules.emplace_back(Result);
851 true, NumCreatedModules++);
859 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
860 assert(!Modules[Name] &&
"redefining existing module");
863 new Module(Name, Loc,
nullptr,
false,
864 false, NumCreatedModules++);
866 Modules[Name] = SourceModule = Result;
869 for (
auto &Submodule : PendingSubmodules) {
870 Submodule->setParent(Result);
873 PendingSubmodules.clear();
878 assert(MainFile &&
"no input file for module interface");
886 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
887 assert(!Modules[Name] &&
"redefining existing module");
891 false, NumCreatedModules++);
893 Modules[Name] = SourceModule = Result;
898 true, NumCreatedModules++);
909 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
910 assert(!Modules[Name] &&
"redefining existing module");
912 auto *Result =
new Module(Name, Loc,
nullptr,
false,
913 false, NumCreatedModules++);
915 Modules[Name] = SourceModule = Result;
924 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
926 "Can only infer linking for top-level frameworks");
929 LibName += FrameworkDir->
getName();
930 llvm::sys::path::append(LibName, Mod->
Name);
935 for (
const char *extension : {
"",
".tbd"}) {
936 llvm::sys::path::replace_extension(LibName, extension);
937 if (FileMgr.
getFile(LibName)) {
949 return inferFrameworkModule(FrameworkDir, Attrs,
Parent);
958 StringRef FrameworkDirName =
966 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
976 const FileEntry *ModuleMapFile =
nullptr;
979 bool canInfer =
false;
980 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
982 StringRef
Parent = llvm::sys::path::parent_path(FrameworkDirName);
986 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
987 inferred = InferredDirectories.find(*ParentDir);
988 if (inferred == InferredDirectories.end()) {
991 bool IsFrameworkDir =
Parent.endswith(
".framework");
995 inferred = InferredDirectories.find(*ParentDir);
998 if (inferred == InferredDirectories.end())
999 inferred = InferredDirectories.insert(
1000 std::make_pair(*ParentDir, InferredDirectory())).first;
1003 if (inferred->second.InferModules) {
1006 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1008 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1010 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1011 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1012 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1013 Attrs.NoUndeclaredIncludes |=
1014 inferred->second.Attrs.NoUndeclaredIncludes;
1015 ModuleMapFile = inferred->second.ModuleMapFile;
1029 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1030 auto UmbrellaHeader = FileMgr.
getFile(UmbrellaName);
1035 if (!UmbrellaHeader)
1040 NumCreatedModules++);
1041 InferredModuleAllowedBy[Result] = ModuleMapFile;
1042 Result->IsInferred =
true;
1045 SourceModule = Result;
1046 Modules[ModuleName] = Result;
1047 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1050 Result->IsSystem |= Attrs.IsSystem;
1051 Result->IsExternC |= Attrs.IsExternC;
1052 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1053 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1054 Result->Directory = FrameworkDir;
1057 StringRef RelativePath = UmbrellaName.str().substr(
1058 Result->getTopLevelModule()->Directory->
getName().size());
1059 RelativePath = llvm::sys::path::relative_path(RelativePath);
1068 Result->InferSubmodules =
true;
1069 Result->InferExportWildcard =
true;
1074 = StringRef(FrameworkDir->
getName());
1075 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1076 llvm::sys::path::native(SubframeworksDirName);
1078 for (llvm::vfs::directory_iterator
1079 Dir = FS.dir_begin(SubframeworksDirName, EC),
1081 Dir != DirEnd && !EC; Dir.increment(EC)) {
1082 if (!StringRef(Dir->path()).endswith(
".framework"))
1085 if (
auto SubframeworkDir =
1091 StringRef SubframeworkDirName =
1093 bool FoundParent =
false;
1097 = llvm::sys::path::parent_path(SubframeworkDirName);
1098 if (SubframeworkDirName.empty())
1101 if (
auto SubDir = FileMgr.
getDirectory(SubframeworkDirName)) {
1102 if (*SubDir == FrameworkDir) {
1113 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1119 if (!Result->isSubFramework()) {
1127 Module *ShadowingModule) {
1132 false, NumCreatedModules++);
1133 Result->ShadowingModule = ShadowingModule;
1134 Result->markUnavailable(
true);
1135 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1136 ShadowModules.push_back(Result);
1142 Module *Mod,
const FileEntry *UmbrellaHeader,
const Twine &NameAsWritten,
1143 const Twine &PathRelativeToRootModuleDirectory) {
1148 PathRelativeToRootModuleDirectory.str();
1149 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
1152 for (
const auto &Cb : Callbacks)
1153 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1157 const Twine &NameAsWritten,
1158 const Twine &PathRelativeToRootModuleDirectory) {
1162 PathRelativeToRootModuleDirectory.str();
1163 UmbrellaDirs[UmbrellaDir] = Mod;
1166 void ModuleMap::addUnresolvedHeader(
Module *Mod,
1168 bool &NeedsFramework) {
1171 if (resolveAsBuiltinHeader(Mod, Header)) {
1190 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1192 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1199 resolveHeader(Mod, Header, NeedsFramework);
1203 auto BySize = LazyHeadersBySize.find(
File->getSize());
1204 if (BySize != LazyHeadersBySize.end()) {
1205 for (
auto *M : BySize->second)
1207 LazyHeadersBySize.erase(BySize);
1210 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1211 if (ByModTime != LazyHeadersByModTime.end()) {
1212 for (
auto *M : ByModTime->second)
1214 LazyHeadersByModTime.erase(ByModTime);
1220 bool NeedsFramework =
false;
1222 const auto Size =
File ?
File.getValue()->getSize() : 0;
1223 const auto ModTime =
File ?
File.getValue()->getModificationTime() : 0;
1227 (Header.
Size && Header.
Size != Size)))
1228 NewHeaders.push_back(Header);
1232 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1244 auto &HeaderList = Headers[Header.
Entry];
1245 if (llvm::is_contained(HeaderList, KH))
1248 HeaderList.push_back(KH);
1251 bool isCompilingModuleHeader =
1253 if (!Imported || isCompilingModuleHeader) {
1257 isCompilingModuleHeader);
1261 for (
const auto &Cb : Callbacks)
1270 (void) Headers[Header.
Entry];
1286 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1287 return InferredModuleAllowedBy.find(M)->second;
1293 assert(M->
IsInferred &&
"module not inferred");
1294 InferredModuleAllowedBy[M] = ModMap;
1303 llvm::errs() <<
"Modules:";
1304 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1305 MEnd = Modules.end();
1307 M->getValue()->
print(llvm::errs(), 2);
1309 llvm::errs() <<
"Headers:";
1310 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1312 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1314 E = H->second.end();
1316 if (I != H->second.begin())
1317 llvm::errs() <<
",";
1318 llvm::errs() << I->getModule()->getFullModuleName();
1320 llvm::errs() <<
"\n";
1329 if (Export.getPointer() || Export.getInt())
1330 Mod->
Exports.push_back(Export);
1341 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1354 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1356 Conflict.
Other = OtherMod;
1357 Conflict.
Message = UC.Message;
1462 bool HadError =
false;
1466 llvm::BumpPtrAllocator StringData;
1472 Module *ActiveModule =
nullptr;
1494 void parseModuleDecl();
1495 void parseExternModuleDecl();
1496 void parseRequiresDecl();
1499 void parseExportDecl();
1500 void parseExportAsDecl();
1501 void parseUseDecl();
1502 void parseLinkDecl();
1503 void parseConfigMacros();
1504 void parseConflict();
1505 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1514 using Attributes = ModuleMap::Attributes;
1516 bool parseOptionalAttributes(Attributes &Attrs);
1523 : L(L), SourceMgr(SourceMgr),
Target(
Target), Diags(Diags), Map(Map),
1524 ModuleMapFile(ModuleMapFile), Directory(Directory),
1525 IsSystem(IsSystem) {
1547 case tok::raw_identifier: {
1551 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1608 case tok::string_literal: {
1623 char *Saved = StringData.Allocate<
char>(Length + 1);
1634 case tok::numeric_constant: {
1637 SpellingBuffer.resize(LToken.
getLength() + 1);
1638 const char *Start = SpellingBuffer.data();
1642 if (StringRef(Start, Length).getAsInteger(0,
Value)) {
1662 auto NextIsIdent = [&](StringRef Str) ->
bool {
1667 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1668 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1685 unsigned braceDepth = 0;
1686 unsigned squareDepth = 0;
1693 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1700 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1714 if (squareDepth > 0)
1721 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1737 bool ModuleMapParser::parseModuleId(
ModuleId &
Id) {
1761 enum AttributeKind {
1775 AT_no_undeclared_includes
1784 void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1786 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1789 diag::note_mmap_rename_top_level_private_module);
1790 D << BadName << M->Name;
1795 auto const *M = E->getValue();
1796 if (M->Directory != ActiveModule->
Directory)
1800 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1804 Canonical.append(
"_Private");
1807 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->Parent &&
1810 diag::warn_mmap_mismatched_private_submodule)
1815 FixItInitBegin = FrameworkLoc;
1817 FixItInitBegin = ExplicitLoc;
1820 FixedPrivModDecl.append(
"framework ");
1821 FixedPrivModDecl.append(
"module ");
1822 FixedPrivModDecl.append(Canonical);
1824 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1831 ActiveModule->
Name != Canonical) {
1833 diag::warn_mmap_mismatched_private_module_name)
1834 << ActiveModule->
Name;
1835 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M,
1859 void ModuleMapParser::parseModuleDecl() {
1863 parseExternModuleDecl();
1870 bool Explicit =
false;
1871 bool Framework =
false;
1875 ExplicitLoc = consumeToken();
1881 FrameworkLoc = consumeToken();
1892 CurrModuleDeclLoc = consumeToken();
1897 return parseInferredModuleDecl(Framework, Explicit);
1901 if (parseModuleId(
Id)) {
1907 if (
Id.size() > 1) {
1908 Diags.
Report(
Id.front().second, diag::err_mmap_nested_submodule_id)
1914 }
else if (
Id.size() == 1 && Explicit) {
1916 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1922 Module *PreviousActiveModule = ActiveModule;
1923 if (
Id.size() > 1) {
1926 ActiveModule =
nullptr;
1927 const Module *TopLevelModule =
nullptr;
1928 for (
unsigned I = 0, N =
Id.size() - 1; I != N; ++I) {
1931 TopLevelModule = Next;
1932 ActiveModule = Next;
1936 Diags.
Report(
Id[I].second, diag::err_mmap_missing_parent_module)
1937 <<
Id[I].first << (ActiveModule !=
nullptr)
1944 if (TopLevelModule &&
1947 "submodule defined in same file as 'module *' that allowed its "
1948 "top-level module");
1953 StringRef ModuleName =
Id.back().first;
1958 if (parseOptionalAttributes(Attrs))
1971 Module *ShadowingModule =
nullptr;
1980 bool ParsedAsMainInput =
1985 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
1992 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
1999 ShadowingModule = Existing;
2002 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2004 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2017 if (ShadowingModule) {
2027 if (Attrs.IsSystem || IsSystem)
2029 if (Attrs.IsExternC)
2031 if (Attrs.NoUndeclaredIncludes ||
2032 (!ActiveModule->
Parent && ModuleName ==
"Darwin"))
2036 StringRef MapFileName(ModuleMapFile->
getName());
2037 if (MapFileName.endswith(
"module.private.modulemap") ||
2038 MapFileName.endswith(
"module_private.map")) {
2048 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_submodule,
2050 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_module_name,
2053 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2064 parseConfigMacros();
2083 parseExportAsDecl();
2091 parseRequiresDecl();
2103 parseUmbrellaDirDecl(UmbrellaLoc);
2134 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2155 ActiveModule = PreviousActiveModule;
2162 void ModuleMapParser::parseExternModuleDecl() {
2177 if (parseModuleId(
Id)) {
2191 StringRef FileNameRef = FileName;
2193 if (llvm::sys::path::is_relative(FileNameRef)) {
2194 ModuleMapFileName += Directory->
getName();
2195 llvm::sys::path::append(ModuleMapFileName, FileName);
2196 FileNameRef = ModuleMapFileName;
2203 : (*File)->getDir(),
2204 FileID(),
nullptr, ExternLoc);
2223 bool &IsRequiresExcludedHack) {
2224 if (Feature ==
"excluded" &&
2227 IsRequiresExcludedHack =
true;
2229 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2247 void ModuleMapParser::parseRequiresDecl() {
2255 bool RequiredState =
true;
2257 RequiredState =
false;
2271 bool IsRequiresExcludedHack =
false;
2272 bool ShouldAddRequirement =
2275 if (IsRequiresExcludedHack)
2276 UsesRequiresExcludedHack.insert(ActiveModule);
2278 if (ShouldAddRequirement) {
2280 ActiveModule->
addRequirement(Feature, RequiredState, Map.LangOpts,
2309 LeadingToken = Tok.
Kind;
2317 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2341 Module::UnresolvedHeaderDirective Header;
2343 Header.FileNameLoc = consumeToken();
2350 if (Header.IsUmbrella && ActiveModule->
Umbrella) {
2351 Diags.
Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
2366 switch (llvm::StringSwitch<Attribute>(Str)
2368 .Case(
"mtime", ModTime)
2372 Diags.
Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2375 diag::err_mmap_invalid_header_attribute_value) << Str;
2385 Diags.
Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2388 diag::err_mmap_invalid_header_attribute_value) << Str;
2397 Diags.
Report(Loc, diag::err_mmap_expected_header_attribute);
2407 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2412 bool NeedsFramework =
false;
2413 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2415 if (NeedsFramework && ActiveModule)
2416 Diags.
Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2422 const Module::Header *B) {
2423 return A->NameAsWritten.compare(B->NameAsWritten);
2430 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2445 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2453 if (llvm::sys::path::is_absolute(DirName)) {
2458 PathName = Directory->
getName();
2459 llvm::sys::path::append(PathName, DirName);
2465 Diags.
Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2470 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2477 llvm::vfs::FileSystem &FS =
2479 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2480 I != E && !EC; I.increment(EC)) {
2482 Module::Header Header = {
"",
std::string(I->path()), *FE};
2483 Headers.push_back(std::move(Header));
2490 for (
auto &Header : Headers)
2495 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2496 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2497 << OwningModule->getFullModuleName();
2503 Map.
setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
2515 void ModuleMapParser::parseExportDecl() {
2521 bool Wildcard =
false;
2525 ParsedModuleId.push_back(
2549 ExportLoc, ParsedModuleId, Wildcard
2558 void ModuleMapParser::parseExportAsDecl() {
2568 if (ActiveModule->
Parent) {
2595 void ModuleMapParser::parseUseDecl() {
2597 auto KWLoc = consumeToken();
2600 parseModuleId(ParsedModuleId);
2602 if (ActiveModule->
Parent)
2603 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
2612 void ModuleMapParser::parseLinkDecl() {
2617 bool IsFramework =
false;
2633 ActiveModule->
LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2644 void ModuleMapParser::parseConfigMacros() {
2649 if (ActiveModule->
Parent) {
2650 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2655 if (parseOptionalAttributes(Attrs))
2658 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
2668 if (!ActiveModule->
Parent) {
2687 if (!ActiveModule->
Parent) {
2698 llvm::raw_string_ostream OS(result);
2700 for (
unsigned I = 0, N =
Id.size(); I != N; ++I) {
2714 void ModuleMapParser::parseConflict() {
2717 Module::UnresolvedConflict Conflict;
2720 if (parseModuleId(Conflict.Id))
2737 Conflict.Message = Tok.
getString().str();
2753 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2756 bool Failed =
false;
2759 if (!ActiveModule && !Framework) {
2760 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2768 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2774 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2777 diag::note_mmap_prev_definition);
2783 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2786 }
else if (Explicit) {
2787 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2805 if (parseOptionalAttributes(Attrs))
2815 Map.InferredDirectories[Directory].InferModules =
true;
2816 Map.InferredDirectories[Directory].Attrs = Attrs;
2817 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2841 << (ActiveModule !=
nullptr);
2853 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2859 if (!ActiveModule) {
2861 << (ActiveModule !=
nullptr);
2871 diag::err_mmap_expected_export_wildcard);
2882 << (ActiveModule !=
nullptr);
2892 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2909 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2910 bool HadError =
false;
2926 AttributeKind Attribute
2927 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
2928 .Case(
"exhaustive", AT_exhaustive)
2929 .Case(
"extern_c", AT_extern_c)
2930 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2931 .Case(
"system", AT_system)
2932 .Default(AT_unknown);
2933 switch (Attribute) {
2940 Attrs.IsSystem =
true;
2944 Attrs.IsExternC =
true;
2948 Attrs.IsExhaustive =
true;
2951 case AT_no_undeclared_includes:
2952 Attrs.NoUndeclaredIncludes =
true;
2960 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
3024 assert(Target &&
"Missing target information");
3025 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3026 = ParsedModuleMap.find(
File);
3027 if (Known != ParsedModuleMap.end())
3028 return Known->second;
3031 if (
ID.isInvalid()) {
3032 auto FileCharacter =
3037 assert(Target &&
"Missing target information");
3040 return ParsedModuleMap[
File] =
true;
3041 assert((!
Offset || *Offset <= Buffer->getBufferSize()) &&
3042 "invalid buffer offset");
3046 Buffer->getBufferStart(),
3048 Buffer->getBufferEnd());
3052 bool Result =
Parser.parseModuleMapFile();
3053 ParsedModuleMap[
File] = Result;
3057 assert(Loc.first ==
ID &&
"stopped in a different file?");
3062 for (
const auto &Cb : Callbacks)
3063 Cb->moduleMapFileRead(Start, *
File, IsSystem);