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) {
62 auto *M = findModule(Name.getKey());
64 M->UseExportAsModuleLinkName =
true;
78 default: llvm_unreachable(
"unknown header role");
85 case PrivateHeader | TextualHeader:
102 llvm_unreachable(
"unexpected header kind");
104 llvm_unreachable(
"unknown header kind");
108 ModuleMap::resolveExport(
Module *Mod,
110 bool Complain)
const {
112 if (Unresolved.
Id.empty()) {
113 assert(Unresolved.
Wildcard &&
"Invalid unresolved export");
118 Module *Context = resolveModuleId(Unresolved.
Id, Mod, Complain);
126 bool Complain)
const {
128 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
131 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
138 for (
unsigned I = 1, N = Id.size(); I != N; ++I) {
139 Module *
Sub = lookupModuleQualified(Id[I].first, Context);
142 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
161 for (; Mod; Mod = Mod->
Parent) {
163 Paths.push_back(Mod->
Name);
170 for (
unsigned I = Paths.size() - 1; I != 0; --I)
171 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
182 auto File = SourceMgr.getFileManager().getFile(
Filename);
184 (Header.
Size && (*File)->getSize() != *Header.
Size) ||
185 (Header.
ModTime && (*File)->getModificationTime() != *Header.
ModTime))
190 auto GetFrameworkFile = [&]() ->
const FileEntry * {
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();
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()) {
240 diag::warn_mmap_incomplete_framework_module_declaration)
242 NeedsFramework =
true;
247 return NormalHdrFile;
250 void ModuleMap::resolveHeader(
Module *Mod,
252 bool &NeedsFramework) {
255 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
258 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
259 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
260 << UmbrellaMod->getFullModuleName();
263 setUmbrellaHeader(Mod, File, RelativePathName.str());
267 excludeHeader(Mod, H);
269 addHeader(Mod, H, headerKindToRole(Header.
Kind));
289 bool ModuleMap::resolveAsBuiltinHeader(
292 llvm::sys::path::is_absolute(Header.
FileName) ||
294 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
302 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.
FileName);
303 auto File = SourceMgr.getFileManager().getFile(Path);
307 auto Role = headerKindToRole(Header.
Kind);
309 addHeader(Mod, H, Role);
316 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
317 HeaderInfo(HeaderInfo) {
318 MMapLangOpts.LineComment =
true;
322 for (
auto &M : Modules)
324 for (
auto *M : ShadowModules)
329 assert((!this->Target || this->Target == &Target) &&
330 "Improper target override");
331 this->Target = &Target;
345 Buffer.push_back(
'_');
346 Buffer.reserve(Buffer.size() + Name.size());
347 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
349 Buffer.push_back(Name[I]);
351 Buffer.push_back(
'_');
354 Name = StringRef(Buffer.data(), Buffer.size());
357 while (llvm::StringSwitch<bool>(Name)
358 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 359 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 360 #include "clang/Basic/TokenKinds.def" 362 if (Name.data() != Buffer.data())
363 Buffer.append(Name.begin(), Name.end());
364 Buffer.push_back(
'_');
365 Name = StringRef(Buffer.data(), Buffer.size());
375 return llvm::StringSwitch<bool>(FileName)
376 .Case(
"float.h",
true)
377 .Case(
"iso646.h",
true)
378 .Case(
"limits.h",
true)
379 .Case(
"stdalign.h",
true)
380 .Case(
"stdarg.h",
true)
381 .Case(
"stdatomic.h",
true)
382 .Case(
"stdbool.h",
true)
383 .Case(
"stddef.h",
true)
384 .Case(
"stdint.h",
true)
385 .Case(
"tgmath.h",
true)
386 .Case(
"unwind.h",
true)
390 ModuleMap::HeadersMap::iterator
391 ModuleMap::findKnownHeader(
const FileEntry *File) {
393 HeadersMap::iterator Known = Headers.find(File);
395 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
398 return Headers.find(File);
404 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
406 if (UmbrellaDirs.empty())
410 assert(Dir &&
"file in no directory");
421 auto KnownDir = UmbrellaDirs.find(Dir);
422 if (KnownDir != UmbrellaDirs.end())
425 IntermediateDirs.push_back(Dir);
428 DirName = llvm::sys::path::parent_path(DirName);
449 bool IsPrivate =
false;
453 for (
auto *Hs : HeaderList)
455 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
456 return H.Entry == IncFileEnt;
458 assert(IsPrivate &&
"inconsistent headers and roles");
469 bool RequestingModuleIsModuleInterface,
478 if (RequestingModule) {
483 bool Excluded =
false;
484 Module *Private =
nullptr;
485 Module *NotUsed =
nullptr;
487 HeadersMap::iterator Known = findKnownHeader(File);
488 if (Known != Headers.end()) {
498 if (RequestingModule && LangOpts.ModulesDeclUse &&
513 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
520 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
525 if (Excluded || isHeaderInUmbrellaDirs(File))
530 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
531 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
533 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
537 diag::warn_non_modular_include_in_framework_module :
538 diag::warn_non_modular_include_in_module;
572 HeadersMap::iterator Known = findKnownHeader(File);
573 if (Known != Headers.end()) {
579 return MakeResult(H);
583 return MakeResult(Result);
586 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
590 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
591 assert(!Headers.count(File) &&
"already have a module for this header");
594 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
602 UmbrellaModule = UmbrellaModule->
Parent;
613 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
617 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()), NameBuf);
620 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
624 UmbrellaDirs[SkippedDirs[I-1]] =
Result;
635 llvm::sys::path::stem(File->
getName()), NameBuf);
638 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
649 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
650 UmbrellaDirs[SkippedDirs[I]] = Result;
654 Headers[File].push_back(Header);
664 auto It = Headers.find(File);
665 if (It == Headers.end())
676 const Module *RequestingModule)
const {
678 HeadersMap::const_iterator Known = Headers.find(Header);
679 if (Known != Headers.end()) {
681 I = Known->second.begin(),
682 E = Known->second.end();
685 if (I->isAvailable() &&
686 (!RequestingModule ||
703 StringRef DirName = Dir->
getName();
705 auto IsUnavailable = [&](
const Module *M) {
713 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
714 = UmbrellaDirs.find(Dir);
715 if (KnownDir != UmbrellaDirs.end()) {
716 Module *Found = KnownDir->second;
717 if (IsUnavailable(Found))
722 Module *UmbrellaModule = Found;
724 UmbrellaModule = UmbrellaModule->
Parent;
727 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
731 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()),
736 if (IsUnavailable(Found))
743 llvm::sys::path::stem(Header->
getName()),
750 return IsUnavailable(Found);
753 SkippedDirs.push_back(Dir);
756 DirName = llvm::sys::path::parent_path(DirName);
771 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
772 if (Known != Modules.end())
773 return Known->getValue();
780 for(; Context; Context = Context->
Parent) {
801 return std::make_pair(
Sub,
false);
805 IsExplicit, NumCreatedModules++);
810 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
812 return std::make_pair(Result,
true);
816 PendingSubmodules.emplace_back(
817 new Module(
"<global>", Loc,
nullptr,
false,
818 true, NumCreatedModules++));
820 return PendingSubmodules.back().get();
827 new Module(
"<private>", Loc, Parent,
false,
828 true, NumCreatedModules++);
836 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
837 assert(!Modules[Name] &&
"redefining existing module");
840 new Module(Name, Loc,
nullptr,
false,
841 false, NumCreatedModules++);
843 Modules[Name] = SourceModule =
Result;
846 for (
auto &Submodule : PendingSubmodules) {
847 Submodule->setParent(
Result);
850 PendingSubmodules.clear();
855 assert(MainFile &&
"no input file for module interface");
863 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
864 assert(!Modules[Name] &&
"redefining existing module");
868 false, NumCreatedModules++);
870 Modules[Name] = SourceModule =
Result;
875 true, NumCreatedModules++);
888 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
890 "Can only infer linking for top-level frameworks");
893 LibName += FrameworkDir->
getName();
894 llvm::sys::path::append(LibName, Mod->
Name);
899 for (
const char *extension : {
"",
".tbd"}) {
900 llvm::sys::path::replace_extension(LibName, extension);
901 if (FileMgr.
getFile(LibName)) {
913 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
922 StringRef FrameworkDirName =
930 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
940 const FileEntry *ModuleMapFile =
nullptr;
943 bool canInfer =
false;
944 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
946 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
950 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
951 inferred = InferredDirectories.find(*ParentDir);
952 if (inferred == InferredDirectories.end()) {
955 bool IsFrameworkDir = Parent.endswith(
".framework");
959 inferred = InferredDirectories.find(*ParentDir);
962 if (inferred == InferredDirectories.end())
963 inferred = InferredDirectories.insert(
964 std::make_pair(*ParentDir, InferredDirectory())).first;
967 if (inferred->second.InferModules) {
970 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
971 canInfer = std::find(inferred->second.ExcludedModules.begin(),
972 inferred->second.ExcludedModules.end(),
973 Name) == inferred->second.ExcludedModules.end();
975 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
976 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
977 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
978 Attrs.NoUndeclaredIncludes |=
979 inferred->second.Attrs.NoUndeclaredIncludes;
980 ModuleMapFile = inferred->second.ModuleMapFile;
994 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
995 auto UmbrellaHeader = FileMgr.
getFile(UmbrellaName);
1000 if (!UmbrellaHeader)
1005 NumCreatedModules++);
1006 InferredModuleAllowedBy[
Result] = ModuleMapFile;
1011 Modules[ModuleName] =
Result;
1012 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1015 Result->
IsSystem |= Attrs.IsSystem;
1037 = StringRef(FrameworkDir->
getName());
1038 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1039 llvm::sys::path::native(SubframeworksDirName);
1041 for (llvm::vfs::directory_iterator
1042 Dir = FS.dir_begin(SubframeworksDirName, EC),
1044 Dir != DirEnd && !EC; Dir.increment(EC)) {
1045 if (!StringRef(Dir->path()).endswith(
".framework"))
1048 if (
auto SubframeworkDir =
1054 StringRef SubframeworkDirName =
1056 bool FoundParent =
false;
1060 = llvm::sys::path::parent_path(SubframeworkDirName);
1061 if (SubframeworkDirName.empty())
1064 if (
auto SubDir = FileMgr.
getDirectory(SubframeworkDirName)) {
1065 if (*SubDir == FrameworkDir) {
1076 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1090 Module *ShadowingModule) {
1095 false, NumCreatedModules++);
1098 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1099 ShadowModules.push_back(Result);
1105 Twine NameAsWritten) {
1109 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
1112 for (
const auto &Cb : Callbacks)
1113 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1117 Twine NameAsWritten) {
1120 UmbrellaDirs[UmbrellaDir] = Mod;
1123 void ModuleMap::addUnresolvedHeader(
Module *Mod,
1125 bool &NeedsFramework) {
1128 if (resolveAsBuiltinHeader(Mod, Header)) {
1147 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1149 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1156 resolveHeader(Mod, Header, NeedsFramework);
1160 auto BySize = LazyHeadersBySize.find(File->
getSize());
1161 if (BySize != LazyHeadersBySize.end()) {
1162 for (
auto *M : BySize->second)
1164 LazyHeadersBySize.erase(BySize);
1168 if (ByModTime != LazyHeadersByModTime.end()) {
1169 for (
auto *M : ByModTime->second)
1171 LazyHeadersByModTime.erase(ByModTime);
1176 bool NeedsFramework =
false;
1180 const_cast<ModuleMap*
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1191 auto &HeaderList = Headers[Header.
Entry];
1192 for (
auto H : HeaderList)
1196 HeaderList.push_back(KH);
1199 bool isCompilingModuleHeader =
1201 if (!Imported || isCompilingModuleHeader) {
1205 isCompilingModuleHeader);
1209 for (
const auto &Cb : Callbacks)
1218 (void) Headers[Header.
Entry];
1234 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1235 return InferredModuleAllowedBy.find(M)->second;
1241 assert(M->
IsInferred &&
"module not inferred");
1242 InferredModuleAllowedBy[M] = ModMap;
1246 llvm::errs() <<
"Modules:";
1247 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1248 MEnd = Modules.end();
1250 M->getValue()->
print(llvm::errs(), 2);
1252 llvm::errs() <<
"Headers:";
1253 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1255 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1257 E = H->second.end();
1259 if (I != H->second.begin())
1260 llvm::errs() <<
",";
1261 llvm::errs() << I->getModule()->getFullModuleName();
1263 llvm::errs() <<
"\n";
1270 for (
auto &UE : Unresolved) {
1272 if (Export.getPointer() || Export.getInt())
1273 Mod->
Exports.push_back(Export);
1283 for (
auto &UDU : Unresolved) {
1284 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1296 for (
auto &UC : Unresolved) {
1297 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1299 Conflict.
Other = OtherMod;
1300 Conflict.
Message = UC.Message;
1361 StringData =
nullptr;
1376 : StringRef(StringData, StringLength);
1405 bool HadError =
false;
1409 llvm::BumpPtrAllocator StringData;
1415 Module *ActiveModule =
nullptr;
1425 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1437 void parseModuleDecl();
1438 void parseExternModuleDecl();
1439 void parseRequiresDecl();
1442 void parseExportDecl();
1443 void parseExportAsDecl();
1444 void parseUseDecl();
1445 void parseLinkDecl();
1446 void parseConfigMacros();
1447 void parseConflict();
1448 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1457 using Attributes = ModuleMap::Attributes;
1459 bool parseOptionalAttributes(Attributes &Attrs);
1466 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1467 ModuleMapFile(ModuleMapFile), Directory(Directory),
1468 IsSystem(IsSystem) {
1487 L.LexFromRawLexer(LToken);
1490 case tok::raw_identifier: {
1492 Tok.StringData = RI.data();
1493 Tok.StringLength = RI.size();
1494 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1551 case tok::string_literal: {
1553 Diags.Report(LToken.
getLocation(), diag::err_invalid_string_udl);
1566 char *Saved = StringData.Allocate<
char>(Length + 1);
1572 Tok.StringData = Saved;
1573 Tok.StringLength = Length;
1577 case tok::numeric_constant: {
1580 SpellingBuffer.resize(LToken.
getLength() + 1);
1581 const char *Start = SpellingBuffer.data();
1585 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1586 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1605 auto NextIsIdent = [&](StringRef Str) ->
bool {
1606 L.LexFromRawLexer(LToken);
1610 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1611 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1619 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1628 unsigned braceDepth = 0;
1629 unsigned squareDepth = 0;
1636 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1643 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1657 if (squareDepth > 0)
1664 if (braceDepth == 0 && squareDepth == 0 &&
Tok.
is(K))
1680 bool ModuleMapParser::parseModuleId(
ModuleId &Id) {
1684 Id.push_back(std::make_pair(
Tok.getString(),
Tok.getLocation()));
1687 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module_name);
1717 AT_no_undeclared_includes
1726 void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1728 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1730 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1731 diag::note_mmap_rename_top_level_private_module);
1732 D << BadName << M->Name;
1736 for (
auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1737 auto const *M = E->getValue();
1738 if (M->Directory != ActiveModule->Directory)
1742 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1746 Canonical.append(
"_Private");
1749 if (ActiveModule->Parent && ActiveModule->Name ==
"Private" && !M->Parent &&
1750 M->Name == ActiveModule->Parent->Name) {
1751 Diags.Report(ActiveModule->DefinitionLoc,
1752 diag::warn_mmap_mismatched_private_submodule)
1757 FixItInitBegin = FrameworkLoc;
1759 FixItInitBegin = ExplicitLoc;
1761 if (FrameworkLoc.
isValid() || ActiveModule->Parent->IsFramework)
1762 FixedPrivModDecl.append(
"framework ");
1763 FixedPrivModDecl.append(
"module ");
1764 FixedPrivModDecl.append(Canonical);
1766 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1767 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1772 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1773 ActiveModule->Name != Canonical) {
1774 Diags.Report(ActiveModule->DefinitionLoc,
1775 diag::warn_mmap_mismatched_private_module_name)
1776 << ActiveModule->Name;
1777 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1801 void ModuleMapParser::parseModuleDecl() {
1805 parseExternModuleDecl();
1812 bool Explicit =
false;
1813 bool Framework =
false;
1817 ExplicitLoc = consumeToken();
1823 FrameworkLoc = consumeToken();
1829 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
1834 CurrModuleDeclLoc = consumeToken();
1839 return parseInferredModuleDecl(Framework, Explicit);
1843 if (parseModuleId(Id)) {
1849 if (Id.size() > 1) {
1850 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1851 <<
SourceRange(Id.front().second, Id.back().second);
1856 }
else if (Id.size() == 1 && Explicit) {
1858 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1864 Module *PreviousActiveModule = ActiveModule;
1865 if (Id.size() > 1) {
1868 ActiveModule =
nullptr;
1869 const Module *TopLevelModule =
nullptr;
1870 for (
unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1871 if (
Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1873 TopLevelModule = Next;
1874 ActiveModule = Next;
1879 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1881 << ActiveModule->getTopLevelModule()->getFullModuleName();
1883 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1889 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1890 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1891 "submodule defined in same file as 'module *' that allowed its " 1892 "top-level module");
1893 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1897 StringRef ModuleName = Id.back().first;
1902 if (parseOptionalAttributes(Attrs))
1907 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace)
1915 Module *ShadowingModule =
nullptr;
1916 if (
Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1924 bool ParsedAsMainInput =
1926 Map.LangOpts.CurrentModule == ModuleName &&
1927 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1928 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1929 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
1935 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
1936 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1942 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1943 ShadowingModule = Existing;
1946 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1948 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1961 if (ShadowingModule) {
1963 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
1966 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
1970 ActiveModule->DefinitionLoc = ModuleNameLoc;
1971 if (Attrs.IsSystem || IsSystem)
1972 ActiveModule->IsSystem =
true;
1973 if (Attrs.IsExternC)
1974 ActiveModule->IsExternC =
true;
1975 if (Attrs.NoUndeclaredIncludes ||
1976 (!ActiveModule->Parent && ModuleName ==
"Darwin"))
1977 ActiveModule->NoUndeclaredIncludes =
true;
1978 ActiveModule->Directory = Directory;
1980 StringRef MapFileName(ModuleMapFile->getName());
1981 if (MapFileName.endswith(
"module.private.modulemap") ||
1982 MapFileName.endswith(
"module_private.map")) {
1983 ActiveModule->ModuleMapIsPrivate =
true;
1990 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1991 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1992 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1994 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1996 ActiveModule->ModuleMapIsPrivate)
1997 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2008 parseConfigMacros();
2027 parseExportAsDecl();
2035 parseRequiresDecl();
2047 parseUmbrellaDirDecl(UmbrellaLoc);
2068 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_member);
2077 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2078 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2084 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2085 ActiveModule->LinkLibraries.empty()) {
2091 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
2092 ActiveModule->Parent) {
2093 ActiveModule->getTopLevelModule()->markUnavailable();
2094 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2095 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2099 ActiveModule = PreviousActiveModule;
2106 void ModuleMapParser::parseExternModuleDecl() {
2112 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2121 if (parseModuleId(Id)) {
2128 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2132 std::string FileName =
Tok.getString();
2135 StringRef FileNameRef = FileName;
2137 if (llvm::sys::path::is_relative(FileNameRef)) {
2138 ModuleMapFileName += Directory->getName();
2139 llvm::sys::path::append(ModuleMapFileName, FileName);
2140 FileNameRef = ModuleMapFileName;
2142 if (
auto File = SourceMgr.getFileManager().getFile(FileNameRef))
2143 Map.parseModuleMapFile(
2145 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2148 FileID(),
nullptr, ExternLoc);
2167 bool &IsRequiresExcludedHack) {
2168 if (Feature ==
"excluded" &&
2171 IsRequiresExcludedHack =
true;
2173 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2191 void ModuleMapParser::parseRequiresDecl() {
2199 bool RequiredState =
true;
2201 RequiredState =
false;
2206 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_feature);
2212 std::string Feature =
Tok.getString();
2215 bool IsRequiresExcludedHack =
false;
2216 bool ShouldAddRequirement =
2219 if (IsRequiresExcludedHack)
2220 UsesRequiresExcludedHack.insert(ActiveModule);
2222 if (ShouldAddRequirement) {
2224 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2253 LeadingToken =
Tok.Kind;
2261 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2269 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2280 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2291 : Map.headerRoleToKind(Role));
2294 if (Header.
IsUmbrella && ActiveModule->Umbrella) {
2295 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
2296 << ActiveModule->getFullModuleName();
2307 enum Attribute { Size, ModTime,
Unknown };
2308 StringRef Str =
Tok.getString();
2310 switch (llvm::StringSwitch<Attribute>(Str)
2312 .Case(
"mtime", ModTime)
2316 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2318 Diags.Report(
Tok.getLocation(),
2319 diag::err_mmap_invalid_header_attribute_value) << Str;
2323 Header.
Size =
Tok.getInteger();
2329 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2331 Diags.Report(
Tok.getLocation(),
2332 diag::err_mmap_invalid_header_attribute_value) << Str;
2341 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2350 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2351 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2356 bool NeedsFramework =
false;
2357 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2359 if (NeedsFramework && ActiveModule)
2360 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2361 << ActiveModule->getFullModuleName()
2374 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2377 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2383 std::string DirName =
Tok.getString();
2387 if (ActiveModule->Umbrella) {
2388 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2389 << ActiveModule->getFullModuleName();
2396 if (llvm::sys::path::is_absolute(DirName)) {
2397 if (
auto D = SourceMgr.getFileManager().getDirectory(DirName))
2401 PathName = Directory->getName();
2402 llvm::sys::path::append(PathName, DirName);
2403 if (
auto D = SourceMgr.getFileManager().getDirectory(PathName))
2408 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2413 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2420 llvm::vfs::FileSystem &FS =
2421 SourceMgr.getFileManager().getVirtualFileSystem();
2422 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2423 I != E && !EC; I.increment(EC)) {
2424 if (
auto FE = SourceMgr.getFileManager().getFile(I->path())) {
2427 Headers.push_back(std::move(Header));
2434 for (
auto &Header : Headers)
2439 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2440 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2441 << OwningModule->getFullModuleName();
2447 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2459 void ModuleMapParser::parseExportDecl() {
2465 bool Wildcard =
false;
2469 ParsedModuleId.push_back(std::make_pair(
Tok.getString(),
2470 Tok.getLocation()));
2487 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2493 ExportLoc, ParsedModuleId, Wildcard
2495 ActiveModule->UnresolvedExports.push_back(Unresolved);
2502 void ModuleMapParser::parseExportAsDecl() {
2507 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2512 if (ActiveModule->Parent) {
2513 Diags.Report(
Tok.getLocation(), diag::err_mmap_submodule_export_as);
2518 if (!ActiveModule->ExportAsModule.empty()) {
2519 if (ActiveModule->ExportAsModule ==
Tok.getString()) {
2520 Diags.Report(
Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2521 << ActiveModule->Name <<
Tok.getString();
2523 Diags.Report(
Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2524 << ActiveModule->Name << ActiveModule->ExportAsModule
2529 ActiveModule->ExportAsModule =
Tok.getString();
2530 Map.addLinkAsDependency(ActiveModule);
2539 void ModuleMapParser::parseUseDecl() {
2541 auto KWLoc = consumeToken();
2544 parseModuleId(ParsedModuleId);
2546 if (ActiveModule->Parent)
2547 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2549 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2556 void ModuleMapParser::parseLinkDecl() {
2561 bool IsFramework =
false;
2569 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_library_name)
2575 std::string LibraryName =
Tok.getString();
2588 void ModuleMapParser::parseConfigMacros() {
2593 if (ActiveModule->Parent) {
2594 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2599 if (parseOptionalAttributes(Attrs))
2602 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2603 ActiveModule->ConfigMacrosExhaustive =
true;
2612 if (!ActiveModule->Parent) {
2613 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2626 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_config_macro);
2631 if (!ActiveModule->Parent) {
2632 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2642 llvm::raw_string_ostream OS(result);
2644 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
2658 void ModuleMapParser::parseConflict() {
2664 if (parseModuleId(Conflict.
Id))
2669 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2677 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2685 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2697 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2700 bool Failed =
false;
2703 if (!ActiveModule && !Framework) {
2704 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2710 if (!Failed && ActiveModule->IsAvailable &&
2711 !ActiveModule->getUmbrellaDir()) {
2712 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2717 if (!Failed && ActiveModule->InferSubmodules) {
2718 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2719 if (ActiveModule->InferredSubmoduleLoc.isValid())
2720 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2721 diag::note_mmap_prev_definition);
2727 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2730 }
else if (Explicit) {
2731 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2749 if (parseOptionalAttributes(Attrs))
2754 ActiveModule->InferSubmodules =
true;
2755 ActiveModule->InferredSubmoduleLoc = StarLoc;
2756 ActiveModule->InferExplicitSubmodules = Explicit;
2759 Map.InferredDirectories[Directory].InferModules =
true;
2760 Map.InferredDirectories[Directory].Attrs = Attrs;
2761 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2767 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2784 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2785 << (ActiveModule !=
nullptr);
2793 Diags.Report(
Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2797 Map.InferredDirectories[Directory].ExcludedModules
2798 .push_back(
Tok.getString());
2803 if (!ActiveModule) {
2804 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2805 << (ActiveModule !=
nullptr);
2812 ActiveModule->InferExportWildcard =
true;
2814 Diags.Report(
Tok.getLocation(),
2815 diag::err_mmap_expected_export_wildcard);
2825 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2826 << (ActiveModule !=
nullptr);
2835 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2836 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2853 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2854 bool HadError =
false;
2862 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_attribute);
2871 = llvm::StringSwitch<AttributeKind>(
Tok.getString())
2872 .Case(
"exhaustive", AT_exhaustive)
2873 .Case(
"extern_c", AT_extern_c)
2874 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2875 .Case(
"system", AT_system)
2876 .Default(AT_unknown);
2877 switch (Attribute) {
2879 Diags.Report(
Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2884 Attrs.IsSystem =
true;
2888 Attrs.IsExternC =
true;
2892 Attrs.IsExhaustive =
true;
2895 case AT_no_undeclared_includes:
2896 Attrs.NoUndeclaredIncludes =
true;
2903 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rsquare);
2904 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2956 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2968 assert(
Target &&
"Missing target information");
2969 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2970 = ParsedModuleMap.find(File);
2971 if (Known != ParsedModuleMap.end())
2972 return Known->second;
2976 auto FileCharacter =
2978 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2981 assert(
Target &&
"Missing target information");
2982 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2984 return ParsedModuleMap[File] =
true;
2985 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2986 "invalid buffer offset");
2989 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2990 Buffer->getBufferStart(),
2991 Buffer->getBufferStart() + (Offset ? *
Offset : 0),
2992 Buffer->getBufferEnd());
2997 ParsedModuleMap[File] =
Result;
3000 auto Loc = SourceMgr.getDecomposedLoc(Parser.
getLocation());
3001 assert(Loc.first == ID &&
"stopped in a different file?");
3002 *Offset = Loc.second;
3006 for (
const auto &Cb : Callbacks)
3007 Cb->moduleMapFileRead(Start, *File, IsSystem);
unsigned IsAvailable
Whether this module is available in the current translation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer...
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap)
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
SourceLocation getLocation() const
std::string Name
The name of this module.
static Module * getTopLevelOrNull(Module *M)
This header is included but private.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system...
std::string Message
The message provided to the user when there is a conflict.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Implements support for file system lookup, file system caching, and directory search management...
void dump()
Dump the contents of the module map, for debugging purposes.
Defines the clang::FileManager interface and associated types.
An unresolved conflict with another module.
time_t getModificationTime() const
This header is part of the module (for layering purposes) but should be textually included...
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Defines the SourceManager interface.
void excludeHeader(Module *Mod, Module::Header Header)
Marks this header as being excluded from the given module.
unsigned IsFramework
Whether this is a framework module.
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, const FileEntry *ModuleMapFile, const DirectoryEntry *Directory, bool IsSystem)
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isCompilingModule() const
Are we compiling a module interface (.cppm or module map)?
Parser - This implements a parser for the C family of languages.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Module * createHeaderModule(StringRef Name, ArrayRef< Module::Header > Headers)
Create a header module from the specified list of headers.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup...
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
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...
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
tok::TokenKind getKind() const
void markUnavailable(bool MissingRequirement=false)
Mark this module and all of its submodules as unavailable.
This is the private module fragment within some C++ module.
unsigned GetStringLength() const
FileManager & getFileManager() const
A library or framework to link against when an entity from this module is used.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Token - This structure provides full information about a lexed token.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, Twine NameAsWritten)
Sets the umbrella directory of the given module to the given directory.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Compiling a module from a module map.
Describes a module or submodule.
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
std::string Message
The message provided to the user when there is a conflict.
ModuleId Id
The (unresolved) module id.
Concrete class used by the front-end to report problems and issues.
bool isSubModuleOf(const Module *Other) const
Determine whether this module is a submodule of the given other module.
Module * Parent
The parent of this module.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Defines the Diagnostic-related interfaces.
void setTarget(const TargetInfo &Target)
Set the target information.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules...
StringRef getString() const
const FileEntry * getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name, Module *GlobalModule)
Create a new module for a C++ module interface unit.
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
std::string CurrentModule
The name of the current module, of which the main source file is a part.
bool parseModuleMapFile(const FileEntry *File, bool IsSystem, const DirectoryEntry *HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
ModuleHeaderRole
Flags describing the role of a module header.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc)
Create a global module fragment for a C++ module unit.
Exposes information about the current target.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
Defines the clang::LangOptions interface.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
ModuleId Id
The name of the module.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used...
static int compareModuleHeaders(const Module::Header *A, const Module::Header *B)
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false)
Retrieve the module that owns the given header file, if any.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, Twine NameAsWritten)
Sets the umbrella header of the given module to the given header.
static std::string formatModuleId(const ModuleId &Id)
Format a module-id into a string.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
The result type of a method or function.
StringRef GetString() const
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
const DirectoryEntry * Directory
The build directory of this module.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
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.
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, FileManager &FileMgr)
For a framework module, infer the framework against which we should link.
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
SourceLocation getLocation()
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
LLVM_READONLY bool isValidIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
Encodes a location in the source.
StringRef getName() const
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed, for use in "private" modules.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
bool is(TokenKind K) const
Cached information about one file (either on disk or in the virtual file system). ...
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
This is a fragment of the global module within some C++ module.
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context...
Defines the clang::Module class, which describes a module in the source code.
bool Wildcard
Whether this export declaration ends in a wildcard, indicating that all of its submodules should be e...
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
This header is normally included in the module.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
bool parseModuleMapFile()
Parse a module map file.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
A conflict between two modules.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
static std::string getName(const CallEvent &Call)
Module * ShadowingModule
A module with the same name that shadows this module.
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File) const
Retrieve all the modules that contain the given header file.
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
LLVM_READONLY bool isIdentifierBody(unsigned char c, bool AllowDollar=false)
Returns true if this is a body character of a C identifier, which is [a-zA-Z0-9_].
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
unsigned getLength() const
bool terminatedByDirective()
SourceLocation DefinitionLoc
The location of the module definition.
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
uint64_t getInteger() const
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
A token in a module map file.
std::vector< Conflict > Conflicts
The list of conflicts.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Cached information about one directory (either on disk or in the virtual file system).
Defines the clang::SourceLocation class and associated facilities.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
~ModuleMap()
Destroy the module map.
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
AttributeKind
Enumerates the known attributes.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Module * Other
The module that this module conflicts with.
A trivial tuple used to represent a source range.
llvm::vfs::FileSystem & getVirtualFileSystem() const
This class handles loading and caching of source files into memory.
bool Sub(InterpState &S, CodePtr OpPC)
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
This is a C++ Modules TS module interface unit.
StringRef getName() const