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"
44#include <system_error>
49void ModuleMapCallbacks::anchor() {}
52 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
53 if (PendingLinkAs != PendingLinkAsModule.end()) {
54 for (
auto &Name : PendingLinkAs->second) {
57 M->UseExportAsModuleLinkName =
true;
82 llvm_unreachable(
"unknown header role");
99 llvm_unreachable(
"unknown header kind");
107ModuleMap::resolveExport(
Module *Mod,
109 bool Complain)
const {
112 assert(
Unresolved.Wildcard &&
"Invalid unresolved export");
125 bool Complain)
const {
130 Diags.
Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
137 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
141 Diags.
Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
142 <<
Id[I].first << Context->getFullModuleName()
160 for (; Mod; Mod = Mod->
Parent) {
162 Paths.push_back(Mod->
Name);
169 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
170 llvm::sys::path::append(
Path,
"Frameworks", Framework +
".framework");
190 unsigned FullPathLength = FullPathName.size();
192 unsigned RelativePathLength = RelativePathName.size();
195 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
196 llvm::sys::path::append(FullPathName, RelativePathName);
197 if (
auto File = GetFile(FullPathName))
207 RelativePathName.clear();
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);
217 if (llvm::sys::path::is_absolute(Header.
FileName)) {
218 RelativePathName.clear();
224 return GetFrameworkFile();
227 llvm::sys::path::append(RelativePathName, Header.
FileName);
228 llvm::sys::path::append(FullPathName, RelativePathName);
229 auto NormalHdrFile = GetFile(FullPathName);
231 if (!NormalHdrFile && Directory->getName().ends_with(
".framework")) {
235 FullPathName.assign(Directory->getName());
236 RelativePathName.clear();
237 if (GetFrameworkFile()) {
239 diag::warn_mmap_incomplete_framework_module_declaration)
241 NeedsFramework =
true;
246 return NormalHdrFile;
253 return llvm::StringSwitch<bool>(
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(
"stdcountof.h",
true)
262 .Case(
"stddef.h",
true)
263 .Case(
"stdint.h",
true)
264 .Case(
"tgmath.h",
true)
265 .Case(
"unwind.h",
true)
272 return llvm::StringSwitch<bool>(ModuleName)
273 .Case(
"_Builtin_float",
true)
274 .Case(
"_Builtin_inttypes",
true)
275 .Case(
"_Builtin_iso646",
true)
276 .Case(
"_Builtin_limits",
true)
277 .Case(
"_Builtin_stdalign",
true)
278 .Case(
"_Builtin_stdarg",
true)
279 .Case(
"_Builtin_stdatomic",
true)
280 .Case(
"_Builtin_stdbool",
true)
281 .Case(
"_Builtin_stddef",
true)
282 .Case(
"_Builtin_stdint",
true)
283 .Case(
"_Builtin_stdnoreturn",
true)
284 .Case(
"_Builtin_tgmath",
true)
285 .Case(
"_Builtin_unwind",
true)
289void ModuleMap::resolveHeader(
Module *Mod,
291 bool &NeedsFramework) {
294 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
297 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
299 << UmbrellaMod->getFullModuleName();
303 RelativePathName.str());
327bool ModuleMap::resolveAsBuiltinHeader(
330 llvm::sys::path::is_absolute(Header.
FileName) ||
332 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
354 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts),
Target(
Target),
355 HeaderInfo(HeaderInfo) {
361 assert((!this->Target || this->Target == &
Target) &&
362 "Improper target override");
377 Buffer.push_back(
'_');
378 Buffer.reserve(Buffer.size() + Name.size());
379 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
381 Buffer.push_back(Name[I]);
383 Buffer.push_back(
'_');
386 Name = StringRef(Buffer.data(), Buffer.size());
389 while (llvm::StringSwitch<bool>(Name)
392#include
"clang/Basic/TokenKinds.def"
394 if (Name.data() != Buffer.data())
395 Buffer.append(Name.begin(), Name.end());
396 Buffer.push_back(
'_');
397 Name = StringRef(Buffer.data(), Buffer.size());
404 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
410 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
415ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(
FileEntryRef File) {
417 HeadersMap::iterator Known = Headers.find(
File);
421 return Headers.find(
File);
428 if (UmbrellaDirs.empty())
442 auto KnownDir = UmbrellaDirs.find(*Dir);
443 if (KnownDir != UmbrellaDirs.end())
446 IntermediateDirs.push_back(*Dir);
449 DirName = llvm::sys::path::parent_path(DirName);
467 bool IsPrivate =
false;
471 for (
auto Hs : HeaderList)
472 IsPrivate |= llvm::any_of(
474 assert(IsPrivate &&
"inconsistent headers and roles");
485 bool RequestingModuleIsModuleInterface,
493 if (RequestingModule) {
498 bool Excluded =
false;
500 Module *NotUsed =
nullptr;
502 HeadersMap::iterator Known = findKnownHeader(
File);
503 if (Known != Headers.end()) {
519 if (RequestingModule && LangOpts.ModulesDeclUse &&
534 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
541 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
547 if (Excluded || isHeaderInUmbrellaDirs(
File))
552 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
553 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
555 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
559 diag::warn_non_modular_include_in_framework_module :
560 diag::warn_non_modular_include_in_module;
596 bool AllowExcluded) {
603 HeadersMap::iterator Known = findKnownHeader(
File);
604 if (Known != Headers.end()) {
613 return MakeResult(H);
617 return MakeResult(
Result);
620 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(
File));
625 assert(!Headers.count(
File) &&
"already have a module for this header");
628 KnownHeader H = findHeaderInUmbrellaDirs(
File, SkippedDirs);
636 UmbrellaModule = UmbrellaModule->
Parent;
650 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
656 UmbrellaDirs[SkippedDir] =
Result;
667 llvm::sys::path::stem(
File.getName()), NameBuf);
680 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
681 UmbrellaDirs[SkippedDirs[I]] =
Result;
685 Headers[
File].push_back(Header);
694 HeadersMap::iterator Known = findKnownHeader(
File);
695 if (Known != Headers.end())
696 return Known->second;
698 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
699 return Headers.find(
File)->second;
708 auto It = Headers.find(
File);
709 if (It == Headers.end())
721 HeadersMap::const_iterator Known = Headers.find(Header);
722 if (Known != Headers.end()) {
724 I = Known->second.begin(),
725 E = Known->second.end();
731 if (I->isAvailable() &&
732 (!RequestingModule ||
749 StringRef DirName = Dir->
getName();
751 auto IsUnavailable = [&](
const Module *M) {
759 auto KnownDir = UmbrellaDirs.find(*Dir);
760 if (KnownDir != UmbrellaDirs.end()) {
762 if (IsUnavailable(
Found))
770 UmbrellaModule = UmbrellaModule->
Parent;
777 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
781 if (IsUnavailable(
Found))
788 llvm::sys::path::stem(Header.
getName()),
795 return IsUnavailable(
Found);
798 SkippedDirs.push_back(*Dir);
801 DirName = llvm::sys::path::parent_path(DirName);
813 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
814 if (Known != Modules.end())
815 return Known->getValue();
823 if (!
Parent->InferSubmodules)
827 Parent->InferExplicitSubmodules, 0);
828 Result->InferExplicitSubmodules =
Parent->InferExplicitSubmodules;
830 Result->InferExportWildcard =
Parent->InferExportWildcard;
831 if (
Result->InferExportWildcard)
838 for(; Context; Context = Context->Parent) {
850 return Context->findSubmodule(Name);
859 return std::make_pair(Sub,
false);
863 return std::make_pair(M,
true);
867 bool IsFramework,
bool IsExplicit) {
869 "Creating duplicate submodule");
873 IsFramework, IsExplicit, NumCreatedModules++);
878 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
887 true, NumCreatedModules++);
892 PendingSubmodules.emplace_back(
Result);
899 assert(
Parent &&
"We should only create an implicit global module fragment "
900 "in a module purview");
904 auto *
Result =
new (ModulesAlloc.Allocate())
906 false,
false, NumCreatedModules++);
916 true, NumCreatedModules++);
923 auto *
Result =
new (ModulesAlloc.Allocate())
925 false, NumCreatedModules++);
929 for (
auto &Submodule : PendingSubmodules)
930 Submodule->setParent(
Result);
931 PendingSubmodules.clear();
937 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
938 assert(!Modules[Name] &&
"redefining existing module");
942 Modules[Name] = SourceModule =
Result;
947 assert(MainFile &&
"no input file for module interface");
955 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
958 "creating implementation module without an interface");
963 StringRef IName =
".ImplementationUnit";
964 assert(!Modules[IName] &&
"multiple implementation units?");
968 Modules[IName] = SourceModule =
Result;
972 "no input file for module implementation");
979 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
980 assert(!Modules[Name] &&
"redefining existing module");
982 auto *
Result =
new (ModulesAlloc.Allocate())
984 false, NumCreatedModules++);
986 Modules[Name] = SourceModule =
Result;
994 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
996 "Can only infer linking for top-level frameworks");
998 StringRef FrameworkName(Mod->
Name);
999 FrameworkName.consume_back(
"_Private");
1008 return inferFrameworkModule(FrameworkDir, Attrs,
Parent);
1017 StringRef FrameworkDirName =
1025 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1038 bool canInfer =
false;
1039 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1041 StringRef
Parent = llvm::sys::path::parent_path(FrameworkDirName);
1045 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1046 inferred = InferredDirectories.find(*ParentDir);
1047 if (inferred == InferredDirectories.end()) {
1050 bool IsFrameworkDir =
Parent.ends_with(
".framework");
1056 inferred = InferredDirectories.find(*ParentDir);
1059 if (inferred == InferredDirectories.end())
1060 inferred = InferredDirectories.insert(
1061 std::make_pair(*ParentDir, InferredDirectory())).first;
1064 if (inferred->second.InferModules) {
1067 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1069 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1071 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1072 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1073 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1074 Attrs.NoUndeclaredIncludes |=
1075 inferred->second.Attrs.NoUndeclaredIncludes;
1076 ModuleMapFID = inferred->second.ModuleMapFID;
1090 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1096 if (!UmbrellaHeader)
1101 true,
false, NumCreatedModules++);
1106 Modules[ModuleName] =
Result;
1107 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1110 Result->IsSystem |= Attrs.IsSystem;
1111 Result->IsExternC |= Attrs.IsExternC;
1112 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1113 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1114 Result->Directory = FrameworkDir;
1117 StringRef RelativePath = UmbrellaName.str().substr(
1118 Result->getTopLevelModule()->Directory->getName().size());
1119 RelativePath = llvm::sys::path::relative_path(RelativePath);
1129 Result->InferSubmodules =
true;
1130 Result->InferExportWildcard =
true;
1135 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1136 llvm::sys::path::native(SubframeworksDirName);
1138 for (llvm::vfs::directory_iterator
1139 Dir = FS.dir_begin(SubframeworksDirName, EC),
1141 Dir != DirEnd && !EC; Dir.increment(EC)) {
1142 if (!StringRef(Dir->path()).ends_with(
".framework"))
1150 StringRef SubframeworkDirName =
1152 bool FoundParent =
false;
1156 = llvm::sys::path::parent_path(SubframeworkDirName);
1157 if (SubframeworkDirName.empty())
1162 if (*SubDir == FrameworkDir) {
1173 inferFrameworkModule(*SubframeworkDir, Attrs,
Result);
1179 if (!
Result->isSubFramework())
1186 Module *ShadowingModule) {
1191 IsFramework,
false, NumCreatedModules++);
1192 Result->ShadowingModule = ShadowingModule;
1193 Result->markUnavailable(
true);
1194 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1195 ShadowModules.push_back(
Result);
1202 const Twine &PathRelativeToRootModuleDirectory) {
1207 PathRelativeToRootModuleDirectory.str();
1208 UmbrellaDirs[UmbrellaHeader.
getDir()] = Mod;
1211 for (
const auto &Cb : Callbacks)
1212 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1217 const Twine &PathRelativeToRootModuleDirectory) {
1221 PathRelativeToRootModuleDirectory.str();
1222 UmbrellaDirs[UmbrellaDir] = Mod;
1225void ModuleMap::addUnresolvedHeader(
Module *Mod,
1227 bool &NeedsFramework) {
1230 if (resolveAsBuiltinHeader(Mod, Header)) {
1249 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1251 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1258 resolveHeader(Mod, Header, NeedsFramework);
1262 auto BySize = LazyHeadersBySize.find(
File->getSize());
1263 if (BySize != LazyHeadersBySize.end()) {
1264 for (
auto *M : BySize->second)
1266 LazyHeadersBySize.erase(BySize);
1269 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1270 if (ByModTime != LazyHeadersByModTime.end()) {
1271 for (
auto *M : ByModTime->second)
1273 LazyHeadersByModTime.erase(ByModTime);
1278 Module *Mod, std::optional<const FileEntry *>
File)
const {
1279 bool NeedsFramework =
false;
1281 const auto Size =
File ? (*File)->getSize() : 0;
1282 const auto ModTime =
File ? (*File)->getModificationTime() : 0;
1286 (Header.
Size && Header.
Size != Size)))
1287 NewHeaders.push_back(Header);
1291 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1305 auto &HeaderList = Headers[HeaderEntry];
1306 if (llvm::is_contained(HeaderList, KH))
1309 HeaderList.push_back(KH);
1312 bool isCompilingModuleHeader = Mod->
isForBuilding(LangOpts);
1313 if (!Imported || isCompilingModuleHeader) {
1320 for (
const auto &Cb : Callbacks)
1321 Cb->moduleMapAddHeader(HeaderEntry.
getName());
1327 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator
1328 Known = ParsedModuleMap.find(
File);
1329 if (Known != ParsedModuleMap.end())
1330 return Known->second ==
nullptr;
1333 if (ID.isInvalid()) {
1336 auto FileCharacter =
1342 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.
getBufferOrNone(ID);
1344 ParsedModuleMap[
File] =
nullptr;
1348 Diags.
Report(diag::remark_mmap_parse) <<
File.getName();
1349 std::optional<modulemap::ModuleMapFile> MaybeMMF =
1353 ParsedModuleMap[
File] =
nullptr;
1357 ParsedModuleMaps.push_back(
1358 std::make_unique<modulemap::ModuleMapFile>(std::move(*MaybeMMF)));
1360 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;
1362 std::visit(llvm::makeVisitor(
1368 ParsedModules[StringRef(MD.
Id.front().first)];
1369 ModuleDecls.push_back(std::pair(&MMF, &MD));
1372 PendingExternalModuleMaps.push_back(&EMD);
1378 StringRef FileNameRef = EMD->Path;
1380 if (llvm::sys::path::is_relative(FileNameRef)) {
1381 ModuleMapFileName += Dir.
getName();
1382 llvm::sys::path::append(ModuleMapFileName, EMD->Path);
1383 FileNameRef = ModuleMapFileName;
1393 ParsedModuleMap[
File] = &MMF;
1395 for (
const auto &Cb : Callbacks)
1415 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1416 return InferredModuleAllowedBy.find(M)->second;
1428 InferredModuleAllowedBy[M] = ModMapFID;
1433 StringRef Dir = llvm::sys::path::parent_path({
Path.data(),
Path.size()});
1437 if (llvm::sys::path::filename(Dir) ==
"Modules") {
1438 StringRef
Parent = llvm::sys::path::parent_path(Dir);
1439 if (
Parent.ends_with(
".framework"))
1446 return llvm::errorToErrorCode(DirEntry.takeError());
1450 if (CanonicalDir != Dir)
1451 llvm::sys::path::replace_path_prefix(
Path, Dir, CanonicalDir);
1459 llvm::sys::path::remove_dots(
Path);
1461 return std::error_code();
1470 llvm::errs() <<
"Modules:";
1471 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1472 MEnd = Modules.end();
1474 M->getValue()->
print(llvm::errs(), 2);
1476 llvm::errs() <<
"Headers:";
1477 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1479 llvm::errs() <<
" \"" << H->first.getName() <<
"\" -> ";
1481 E = H->second.end();
1483 if (I != H->second.begin())
1484 llvm::errs() <<
",";
1485 llvm::errs() << I->getModule()->getFullModuleName();
1487 llvm::errs() <<
"\n";
1496 if (Export.getPointer() || Export.getInt())
1497 Mod->
Exports.push_back(Export);
1506 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1507 Top->UnresolvedDirectUses.clear();
1509 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1511 Top->DirectUses.push_back(DirectUse);
1513 Top->UnresolvedDirectUses.push_back(UDU);
1515 return !Top->UnresolvedDirectUses.empty();
1522 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1524 Conflict.
Other = OtherMod;
1525 Conflict.
Message = UC.Message;
1558 bool HadError =
false;
1561 Module *ActiveModule =
nullptr;
1598 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),
1599 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
1612void ModuleMapLoader::diagnosePrivateModules(
SourceLocation StartLoc) {
1613 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1616 diag::note_mmap_rename_top_level_private_module);
1617 D << BadName << M->Name;
1622 auto const *M =
E->getValue();
1623 if (M->Directory != ActiveModule->
Directory)
1631 Canonical.append(
"_Private");
1634 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->Parent &&
1637 diag::warn_mmap_mismatched_private_submodule)
1642 FixItInitBegin = StartLoc;
1645 FixedPrivModDecl.append(
"framework ");
1646 FixedPrivModDecl.append(
"module ");
1647 FixedPrivModDecl.append(Canonical);
1649 GenNoteAndFixIt(
FullName, FixedPrivModDecl, M,
1656 ActiveModule->
Name != Canonical) {
1658 diag::warn_mmap_mismatched_private_module_name)
1659 << ActiveModule->
Name;
1660 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M,
1667 if (MD.
Id.front().first ==
"*")
1668 return handleInferredModuleDecl(MD);
1672 Module *PreviousActiveModule = ActiveModule;
1673 if (MD.
Id.size() > 1) {
1676 ActiveModule =
nullptr;
1677 const Module *TopLevelModule =
nullptr;
1678 for (
unsigned I = 0, N = MD.
Id.size() - 1; I != N; ++I) {
1682 TopLevelModule = Next;
1683 ActiveModule = Next;
1687 Diags.
Report(MD.
Id[I].second, diag::err_mmap_missing_parent_module)
1688 << MD.
Id[I].first << (ActiveModule !=
nullptr)
1695 if (TopLevelModule &&
1697 assert(ModuleMapFID !=
1699 "submodule defined in same file as 'module *' that allowed its "
1700 "top-level module");
1706 StringRef ModuleName = MD.
Id.back().first;
1710 Module *ShadowingModule =
nullptr;
1718 bool Inferred = Existing->IsInferred;
1734 bool PartOfFramework = MD.
Framework || Existing->isPartOfFramework();
1737 bool ParsedAsMainInput =
1744 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;
1745 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||
1747 ActiveModule = PreviousActiveModule;
1753 ShadowingModule = Existing;
1756 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1758 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1765 if (ShadowingModule) {
1782 StringRef MapFileName(
1784 if (MapFileName.ends_with(
"module.private.modulemap") ||
1785 MapFileName.ends_with(
"module_private.map")) {
1795 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_submodule,
1797 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_module_name,
1800 diagnosePrivateModules(MD.
Location);
1808 handleUmbrellaDirDecl(UDD);
1813 handleExportAsDecl(EAD);
1816 handleExternModuleDecl(EMD);
1821 handleConfigMacros(CMD);
1825 Diags.
Report(ED.Location, diag::err_mmap_expected_member);
1846 ActiveModule = PreviousActiveModule;
1849void ModuleMapLoader::handleExternModuleDecl(
1851 StringRef FileNameRef = EMD.
Path;
1853 if (llvm::sys::path::is_relative(FileNameRef)) {
1854 ModuleMapFileName += Directory.
getName();
1855 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1856 FileNameRef = ModuleMapFileName;
1883 bool &IsRequiresExcludedHack) {
1887 IsRequiresExcludedHack =
true;
1899 bool IsRequiresExcludedHack =
false;
1900 bool ShouldAddRequirement =
1903 if (IsRequiresExcludedHack)
1904 UsesRequiresExcludedHack.insert(ActiveModule);
1906 if (ShouldAddRequirement) {
1927 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1941 !std::holds_alternative<std::monostate>(ActiveModule->
Umbrella)) {
1953 bool NeedsFramework =
false;
1957 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
1960 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
1963 Diags.
Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
1973void ModuleMapLoader::handleUmbrellaDirDecl(
1975 std::string DirName = std::string(UDD.
Path);
1976 std::string DirNameAsWritten = DirName;
1979 if (!std::holds_alternative<std::monostate>(ActiveModule->
Umbrella)) {
1988 if (llvm::sys::path::is_absolute(DirName)) {
1992 PathName = Directory.
getName();
1993 llvm::sys::path::append(PathName, DirName);
1998 Diags.
Report(UDD.
Location, diag::warn_mmap_umbrella_dir_not_found)
2003 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2010 llvm::vfs::FileSystem &FS =
2012 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC),
E;
2013 I !=
E && !EC; I.increment(EC)) {
2016 Headers.push_back(std::move(Header));
2023 for (
auto &Header : Headers)
2028 if (
Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2030 << OwningModule->getFullModuleName();
2045 const auto &ModName = EAD.
Id.front();
2049 Diags.
Report(ModName.second, diag::warn_mmap_redundant_export_as)
2050 << ActiveModule->
Name << ModName.first;
2052 Diags.
Report(ModName.second, diag::err_mmap_conflicting_export_as)
2063 if (ActiveModule->
Parent)
2074void ModuleMapLoader::handleConfigMacros(
2076 if (ActiveModule->
Parent) {
2077 Diags.
Report(CMD.
Location, diag::err_mmap_config_macro_submodule);
2093 Conflict.
Id = CD.
Id;
2100void ModuleMapLoader::handleInferredModuleDecl(
2106 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2113 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2119 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2122 diag::note_mmap_prev_definition);
2128 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2132 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2143 auto &InfDir = Map.InferredDirectories[Directory];
2144 InfDir.InferModules =
true;
2145 InfDir.Attrs = MD.
Attrs;
2146 InfDir.ModuleMapFID = ModuleMapFID;
2153 [&](
const auto &
Other) {
2155 diag::err_mmap_expected_inferred_member)
2156 << (ActiveModule !=
nullptr);
2162 diag::err_mmap_expected_inferred_member)
2163 << (ActiveModule !=
nullptr);
2167 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(
2172 if (!ActiveModule) {
2174 diag::err_mmap_expected_inferred_member)
2175 << (ActiveModule !=
nullptr);
2184 diag::err_mmap_expected_export_wildcard);
2191 handleModuleDecl(MD);
2197 handleExternModuleDecl(EMD);
2208 handleExternModuleDecl(EMD);
2216 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
2217 if (Known != Modules.end())
2218 return Known->getValue();
2220 auto ParsedMod = ParsedModules.find(Name);
2221 if (ParsedMod == ParsedModules.end())
2224 Diags.
Report(diag::remark_mmap_load_module) << Name;
2226 for (
const auto &ModuleDecl : ParsedMod->second) {
2241 assert(
Target &&
"Missing target information");
2242 llvm::DenseMap<const FileEntry *, bool>::iterator Known =
2243 LoadedModuleMap.find(
File);
2244 if (Known != LoadedModuleMap.end())
2245 return Known->second;
2248 if (ID.isInvalid()) {
2255 auto FileCharacter =
2261 assert(
Target &&
"Missing target information");
2262 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.
getBufferOrNone(ID);
2264 return LoadedModuleMap[
File] =
true;
2265 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2266 "invalid buffer offset");
2268 std::optional<modulemap::ModuleMapFile> MMF =
2272 Diags.
Report(diag::remark_mmap_load) <<
File.getName();
2280 for (
const auto &Cb : Callbacks)
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
#define ALIAS(NAME, TOK, FLAGS)
#define KEYWORD(NAME, FLAGS)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
static Module * getTopLevelOrNull(Module *M)
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives.
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified file (real or virtual).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompilingModule() const
Are we compiling a module?
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Required to construct a Module.
bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD)
ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)
bool parseAndLoadModuleMapFile(const modulemap::ModuleMapFile &MMF)
bool loadModuleDecl(const modulemap::ModuleDecl &MD)
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
void dump()
Dump the contents of the module map, for debugging purposes.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
bool mayShadowNewModule(Module *ExistingModule)
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.
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
module_iterator module_begin() const
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
FileID getModuleMapFileIDForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
Module * findOrCreateModuleFirst(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Call ModuleMap::findOrCreateModule and throw away the information whether the module was found or cre...
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Module * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Create new submodule, assuming it does not exist.
module_iterator module_end() const
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
~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.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
void setTarget(const TargetInfo &Target)
Set the target information.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
ModuleHeaderRole
Flags describing the role of a module header.
@ PrivateHeader
This header is included but private.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ NormalHeader
This header is normally included in the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module interface unit.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)
Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...
Module * findOrLoadModule(StringRef Name)
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
SourceLocation InferredSubmoduleLoc
The location of the inferred submodule.
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
SourceLocation DefinitionLoc
The location of the module definition.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Module * Parent
The parent of this module.
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
void addHeader(HeaderKind HK, Header H)
std::string UmbrellaRelativeToRootModuleDirectory
OptionalDirectoryEntryRef Directory
The build directory of this module.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
ArrayRef< Header > getHeaders(HeaderKind HK) const
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
@ ModuleHeaderUnit
This is a C++20 header unit.
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
unsigned IsFramework
Whether this is a framework module.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned IsAvailable
Whether this module is available in the current translation unit.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
std::vector< Conflict > Conflicts
The list of conflicts.
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.
FileIDAndOffset getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isLoadedFileID(FileID FID) const
Returns true if FID came from a PCH/Module.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
Exposes information about the current target.
Defines the clang::TargetInfo interface.
bool Sub(InterpState &S, CodePtr OpPC)
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.
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.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ Keyword
The name has been typo-corrected to a keyword.
@ Other
Other implicit parameter.
The set of attributes that can be attached to a module.
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.
An unresolved conflict with another module.
std::string Message
The message provided to the user when there is a conflict.
ModuleId Id
The (unresolved) module id.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
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