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()
143 << SourceRange(Id[0].second, Id[I-1].second);
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");
178 SmallString<128> FullPathName(Directory->getName());
182 expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
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(
"stdckdint.h",
true)
262 .Case(
"stdcountof.h",
true)
263 .Case(
"stddef.h",
true)
264 .Case(
"stdint.h",
true)
265 .Case(
"tgmath.h",
true)
266 .Case(
"unwind.h",
true)
273 return llvm::StringSwitch<bool>(ModuleName)
274 .Case(
"_Builtin_float",
true)
275 .Case(
"_Builtin_inttypes",
true)
276 .Case(
"_Builtin_iso646",
true)
277 .Case(
"_Builtin_limits",
true)
278 .Case(
"_Builtin_stdalign",
true)
279 .Case(
"_Builtin_stdarg",
true)
280 .Case(
"_Builtin_stdatomic",
true)
281 .Case(
"_Builtin_stdbool",
true)
282 .Case(
"_Builtin_stddef",
true)
283 .Case(
"_Builtin_stdint",
true)
284 .Case(
"_Builtin_stdnoreturn",
true)
285 .Case(
"_Builtin_tgmath",
true)
286 .Case(
"_Builtin_unwind",
true)
290void ModuleMap::resolveHeader(
Module *Mod,
292 bool &NeedsFramework) {
293 SmallString<128> RelativePathName;
295 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
297 const DirectoryEntry *UmbrellaDir = &
File->getDir().getDirEntry();
298 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
299 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
300 << UmbrellaMod->getFullModuleName();
304 RelativePathName.str());
306 Module::Header H = {Header.
FileName, std::string(RelativePathName),
328bool ModuleMap::resolveAsBuiltinHeader(
331 llvm::sys::path::is_absolute(Header.
FileName) ||
333 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
340 SmallString<128> Path;
341 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.
FileName);
342 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
355 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
356 HeaderInfo(HeaderInfo) {
362 assert((!this->Target || this->Target == &Target) &&
363 "Improper target override");
364 this->Target = &Target;
378 Buffer.push_back(
'_');
379 Buffer.reserve(Buffer.size() + Name.size());
380 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
382 Buffer.push_back(Name[I]);
384 Buffer.push_back(
'_');
387 Name = StringRef(Buffer.data(), Buffer.size());
390 while (llvm::StringSwitch<bool>(Name)
393#include
"clang/Basic/TokenKinds.def"
395 if (Name.data() != Buffer.data())
396 Buffer.append(Name.begin(), Name.end());
397 Buffer.push_back(
'_');
398 Name = StringRef(Buffer.data(), Buffer.size());
405 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
411 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
416ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(
FileEntryRef File) {
418 HeadersMap::iterator Known = Headers.find(
File);
422 return Headers.find(
File);
429 if (UmbrellaDirs.empty())
438 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
443 auto KnownDir = UmbrellaDirs.find(*Dir);
444 if (KnownDir != UmbrellaDirs.end())
447 IntermediateDirs.push_back(*Dir);
450 DirName = llvm::sys::path::parent_path(DirName);
455 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
468 bool IsPrivate =
false;
472 for (
auto Hs : HeaderList)
473 IsPrivate |= llvm::any_of(
475 assert(IsPrivate &&
"inconsistent headers and roles");
486 bool RequestingModuleIsModuleInterface,
494 if (RequestingModule) {
499 bool Excluded =
false;
501 Module *NotUsed =
nullptr;
503 HeadersMap::iterator Known = findKnownHeader(
File);
504 if (Known != Headers.end()) {
520 if (RequestingModule && LangOpts.ModulesDeclUse &&
535 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
542 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
548 if (Excluded || isHeaderInUmbrellaDirs(
File))
553 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
554 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
556 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
557 LangOpts.isCompilingModule()) {
560 diag::warn_non_modular_include_in_framework_module :
561 diag::warn_non_modular_include_in_module;
597 bool AllowExcluded) {
604 HeadersMap::iterator Known = findKnownHeader(
File);
605 if (Known != Headers.end()) {
614 return MakeResult(H);
618 return MakeResult(
Result);
621 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(
File));
626 assert(!Headers.count(
File) &&
"already have a module for this header");
629 KnownHeader H = findHeaderInUmbrellaDirs(
File, SkippedDirs);
637 UmbrellaModule = UmbrellaModule->
Parent;
651 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
657 UmbrellaDirs[SkippedDir] =
Result;
668 llvm::sys::path::stem(
File.getName()), NameBuf);
672 Result->addTopHeader(
File);
681 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
682 UmbrellaDirs[SkippedDirs[I]] =
Result;
686 Headers[
File].push_back(Header);
695 HeadersMap::iterator Known = findKnownHeader(
File);
696 if (Known != Headers.end())
697 return Known->second;
699 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
700 return Headers.find(
File)->second;
709 auto It = Headers.find(
File);
710 if (It == Headers.end())
722 HeadersMap::const_iterator Known = Headers.find(Header);
723 if (Known != Headers.end()) {
725 I = Known->second.begin(),
726 E = Known->second.end();
732 if (I->isAvailable() &&
733 (!RequestingModule ||
750 StringRef DirName = Dir->
getName();
752 auto IsUnavailable = [&](
const Module *M) {
760 auto KnownDir = UmbrellaDirs.find(*Dir);
761 if (KnownDir != UmbrellaDirs.end()) {
763 if (IsUnavailable(
Found))
771 UmbrellaModule = UmbrellaModule->
Parent;
778 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
782 if (IsUnavailable(
Found))
789 llvm::sys::path::stem(Header.
getName()),
796 return IsUnavailable(
Found);
799 SkippedDirs.push_back(*Dir);
802 DirName = llvm::sys::path::parent_path(DirName);
807 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
814 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
815 if (Known != Modules.end())
816 return Known->getValue();
832 if (
Result->InferExportWildcard)
839 for(; Context; Context = Context->Parent) {
851 return Context->findSubmodule(Name);
860 return std::make_pair(Sub,
false);
864 return std::make_pair(M,
true);
868 bool IsFramework,
bool IsExplicit) {
870 "Creating duplicate submodule");
874 IsFramework, IsExplicit, NumCreatedModules++);
876 if (LangOpts.CurrentModule == Name)
879 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
888 true, NumCreatedModules++);
893 PendingSubmodules.emplace_back(
Result);
900 assert(Parent &&
"We should only create an implicit global module fragment "
901 "in a module purview");
905 auto *
Result =
new (ModulesAlloc.Allocate())
907 false,
false, NumCreatedModules++);
917 true, NumCreatedModules++);
924 auto *
Result =
new (ModulesAlloc.Allocate())
926 false, NumCreatedModules++);
930 for (
auto &Submodule : PendingSubmodules)
931 Submodule->setParent(
Result);
932 PendingSubmodules.clear();
938 assert(LangOpts.CurrentModule == Name &&
"module name mismatch");
939 assert(!Modules[Name] &&
"redefining existing module");
943 Modules[Name] = SourceModule =
Result;
947 auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
948 assert(MainFile &&
"no input file for module interface");
956 assert(LangOpts.CurrentModule == Name &&
"module name mismatch");
959 "creating implementation module without an interface");
964 StringRef IName =
".ImplementationUnit";
965 assert(!Modules[IName] &&
"multiple implementation units?");
969 Modules[IName] = SourceModule =
Result;
972 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
973 "no input file for module implementation");
980 assert(LangOpts.CurrentModule == Name &&
"module name mismatch");
981 assert(!Modules[Name] &&
"redefining existing module");
983 auto *
Result =
new (ModulesAlloc.Allocate())
985 false, NumCreatedModules++);
987 Modules[Name] = SourceModule =
Result;
995 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
997 "Can only infer linking for top-level frameworks");
999 StringRef FrameworkName(Mod->
Name);
1000 FrameworkName.consume_back(
"_Private");
1006 bool IsSystem,
Module *Parent) {
1009 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
1013 Attributes Attrs,
Module *Parent) {
1018 StringRef FrameworkDirName =
1019 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
1026 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1039 bool canInfer =
false;
1040 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1042 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1043 if (
auto ParentDir =
FileMgr.getOptionalDirectoryRef(Parent)) {
1046 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1047 inferred = InferredDirectories.find(*ParentDir);
1048 if (inferred == InferredDirectories.end()) {
1051 bool IsFrameworkDir = Parent.ends_with(
".framework");
1057 inferred = InferredDirectories.find(*ParentDir);
1060 if (inferred == InferredDirectories.end())
1061 inferred = InferredDirectories.insert(
1062 std::make_pair(*ParentDir, InferredDirectory())).first;
1065 if (inferred->second.InferModules) {
1068 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1070 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1072 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1073 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1074 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1075 Attrs.NoUndeclaredIncludes |=
1076 inferred->second.Attrs.NoUndeclaredIncludes;
1077 ModuleMapFID = inferred->second.ModuleMapFID;
1090 SmallString<128> UmbrellaName = FrameworkDir.
getName();
1091 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1097 if (!UmbrellaHeader)
1101 Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,
1102 true,
false, NumCreatedModules++);
1105 if (LangOpts.CurrentModule == ModuleName)
1107 Modules[ModuleName] =
Result;
1108 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1111 Result->IsSystem |= Attrs.IsSystem;
1112 Result->IsExternC |= Attrs.IsExternC;
1113 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1114 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1115 Result->Directory = FrameworkDir;
1118 StringRef RelativePath = UmbrellaName.str().substr(
1119 Result->getTopLevelModule()->Directory->getName().size());
1120 RelativePath = llvm::sys::path::relative_path(RelativePath);
1130 Result->InferSubmodules =
true;
1131 Result->InferExportWildcard =
true;
1135 SmallString<128> SubframeworksDirName = FrameworkDir.
getName();
1136 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1137 llvm::sys::path::native(SubframeworksDirName);
1139 for (llvm::vfs::directory_iterator
1140 Dir = FS.dir_begin(SubframeworksDirName, EC),
1142 Dir != DirEnd && !EC; Dir.increment(EC)) {
1143 if (!StringRef(Dir->path()).ends_with(
".framework"))
1151 StringRef SubframeworkDirName =
1153 bool FoundParent =
false;
1157 = llvm::sys::path::parent_path(SubframeworkDirName);
1158 if (SubframeworkDirName.empty())
1163 if (*SubDir == FrameworkDir) {
1174 inferFrameworkModule(*SubframeworkDir, Attrs,
Result);
1180 if (!
Result->isSubFramework())
1187 Module *ShadowingModule) {
1192 IsFramework,
false, NumCreatedModules++);
1193 Result->ShadowingModule = ShadowingModule;
1194 Result->markUnavailable(
true);
1195 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1196 ShadowModules.push_back(
Result);
1203 const Twine &PathRelativeToRootModuleDirectory) {
1208 PathRelativeToRootModuleDirectory.str();
1209 UmbrellaDirs[UmbrellaHeader.
getDir()] = Mod;
1212 for (
const auto &Cb : Callbacks)
1213 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1218 const Twine &PathRelativeToRootModuleDirectory) {
1222 PathRelativeToRootModuleDirectory.str();
1223 UmbrellaDirs[UmbrellaDir] = Mod;
1226void ModuleMap::addUnresolvedHeader(
Module *Mod,
1228 bool &NeedsFramework) {
1231 if (resolveAsBuiltinHeader(Mod, Header)) {
1250 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1252 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1259 resolveHeader(Mod, Header, NeedsFramework);
1263 auto BySize = LazyHeadersBySize.find(
File->getSize());
1264 if (BySize != LazyHeadersBySize.end()) {
1265 for (
auto *M : BySize->second)
1267 LazyHeadersBySize.erase(BySize);
1270 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1271 if (ByModTime != LazyHeadersByModTime.end()) {
1272 for (
auto *M : ByModTime->second)
1274 LazyHeadersByModTime.erase(ByModTime);
1279 Module *Mod, std::optional<const FileEntry *>
File)
const {
1280 bool NeedsFramework =
false;
1282 const auto Size =
File ? (*File)->getSize() : 0;
1283 const auto ModTime =
File ? (*File)->getModificationTime() : 0;
1287 (Header.
Size && Header.
Size != Size)))
1288 NewHeaders.push_back(Header);
1292 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1306 auto &HeaderList = Headers[HeaderEntry];
1307 if (llvm::is_contained(HeaderList, KH))
1310 HeaderList.push_back(KH);
1313 bool isCompilingModuleHeader = Mod->
isForBuilding(LangOpts);
1314 if (!Imported || isCompilingModuleHeader) {
1317 HeaderInfo.MarkFileModuleHeader(HeaderEntry,
Role, isCompilingModuleHeader);
1321 for (
const auto &Cb : Callbacks)
1322 Cb->moduleMapAddHeader(HeaderEntry.
getName());
1328 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator
1329 Known = ParsedModuleMap.find(
File);
1330 if (Known != ParsedModuleMap.end())
1331 return Known->second ==
nullptr;
1334 if (ID.isInvalid()) {
1335 ID = SourceMgr.translateFile(
File);
1336 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {
1337 auto FileCharacter =
1339 ID = SourceMgr.createFileID(
File, ExternModuleLoc, FileCharacter);
1343 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
1345 ParsedModuleMap[
File] =
nullptr;
1349 Diags.Report(diag::remark_mmap_parse) <<
File.getName();
1350 std::optional<modulemap::ModuleMapFile> MaybeMMF =
1354 ParsedModuleMap[
File] =
nullptr;
1358 ParsedModuleMaps.push_back(
1359 std::make_unique<modulemap::ModuleMapFile>(std::move(*MaybeMMF)));
1361 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;
1363 std::visit(llvm::makeVisitor(
1369 ParsedModules[StringRef(MD.
Id.front().first)];
1370 ModuleDecls.push_back(std::pair(&MMF, &MD));
1373 PendingExternalModuleMaps.push_back(&EMD);
1379 StringRef FileNameRef = EMD->Path;
1381 if (llvm::sys::path::is_relative(FileNameRef)) {
1382 ModuleMapFileName += Dir.
getName();
1383 llvm::sys::path::append(ModuleMapFileName, EMD->Path);
1384 FileNameRef = ModuleMapFileName;
1388 SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {
1394 ParsedModuleMap[
File] = &MMF;
1396 for (
const auto &Cb : Callbacks)
1416 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1417 return InferredModuleAllowedBy.find(M)->second;
1429 InferredModuleAllowedBy[M] = ModMapFID;
1434 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1438 if (llvm::sys::path::filename(Dir) ==
"Modules") {
1439 StringRef Parent = llvm::sys::path::parent_path(Dir);
1440 if (Parent.ends_with(
".framework"))
1447 return llvm::errorToErrorCode(DirEntry.takeError());
1451 if (CanonicalDir != Dir)
1452 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1460 llvm::sys::path::remove_dots(Path);
1462 return std::error_code();
1471 llvm::errs() <<
"Modules:";
1472 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1473 MEnd = Modules.end();
1475 M->getValue()->
print(llvm::errs(), 2);
1477 llvm::errs() <<
"Headers:";
1478 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1480 llvm::errs() <<
" \"" << H->first.getName() <<
"\" -> ";
1482 E = H->second.end();
1484 if (I != H->second.begin())
1485 llvm::errs() <<
",";
1486 llvm::errs() << I->getModule()->getFullModuleName();
1488 llvm::errs() <<
"\n";
1497 if (Export.getPointer() || Export.getInt())
1498 Mod->
Exports.push_back(Export);
1507 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1508 Top->UnresolvedDirectUses.clear();
1510 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1512 Top->DirectUses.push_back(DirectUse);
1514 Top->UnresolvedDirectUses.push_back(UDU);
1516 return !Top->UnresolvedDirectUses.empty();
1523 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1525 Conflict.
Other = OtherMod;
1526 Conflict.
Message = UC.Message;
1559 bool HadError =
false;
1562 Module *ActiveModule =
nullptr;
1593 using Attributes = ModuleMap::Attributes;
1599 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),
1600 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
1613void ModuleMapLoader::diagnosePrivateModules(
SourceLocation StartLoc) {
1614 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1615 const Module *M, SourceRange ReplLoc) {
1616 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1617 diag::note_mmap_rename_top_level_private_module);
1618 D << BadName << M->Name;
1622 for (
auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1623 auto const *M = E->getValue();
1624 if (M->Directory != ActiveModule->Directory)
1627 SmallString<128> FullName(ActiveModule->getFullModuleName());
1628 if (!FullName.starts_with(M->Name) && !FullName.ends_with(
"Private"))
1630 SmallString<128> FixedPrivModDecl;
1631 SmallString<128> Canonical(M->Name);
1632 Canonical.append(
"_Private");
1635 if (ActiveModule->Parent && ActiveModule->Name ==
"Private" && !M->Parent &&
1636 M->Name == ActiveModule->Parent->Name) {
1637 Diags.Report(ActiveModule->DefinitionLoc,
1638 diag::warn_mmap_mismatched_private_submodule)
1641 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1643 FixItInitBegin = StartLoc;
1645 if (ActiveModule->Parent->IsFramework)
1646 FixedPrivModDecl.append(
"framework ");
1647 FixedPrivModDecl.append(
"module ");
1648 FixedPrivModDecl.append(Canonical);
1650 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1651 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1656 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1657 ActiveModule->Name != Canonical) {
1658 Diags.Report(ActiveModule->DefinitionLoc,
1659 diag::warn_mmap_mismatched_private_module_name)
1660 << ActiveModule->Name;
1661 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1662 SourceRange(ActiveModule->DefinitionLoc));
1668 if (MD.
Id.front().first ==
"*")
1669 return handleInferredModuleDecl(MD);
1673 Module *PreviousActiveModule = ActiveModule;
1674 if (MD.
Id.size() > 1) {
1677 ActiveModule =
nullptr;
1678 const Module *TopLevelModule =
nullptr;
1679 for (
unsigned I = 0, N = MD.
Id.size() - 1; I != N; ++I) {
1681 Map.lookupModuleQualified(MD.
Id[I].first, ActiveModule)) {
1683 TopLevelModule =
Next;
1684 ActiveModule =
Next;
1688 Diags.Report(MD.
Id[I].second, diag::err_mmap_missing_parent_module)
1689 << MD.
Id[I].first << (ActiveModule !=
nullptr)
1691 ? ActiveModule->getTopLevelModule()->getFullModuleName()
1696 if (TopLevelModule &&
1697 ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
1698 assert(ModuleMapFID !=
1699 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
1700 "submodule defined in same file as 'module *' that allowed its "
1701 "top-level module");
1702 Map.addAdditionalModuleMapFile(
1703 TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
1707 StringRef ModuleName = MD.
Id.back().first;
1708 SourceLocation ModuleNameLoc = MD.
Id.back().second;
1711 Module *ShadowingModule =
nullptr;
1712 if (
Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1717 bool LoadedFromASTFile = Existing->IsFromModuleFile;
1719 bool Inferred = Existing->IsInferred;
1735 bool PartOfFramework = MD.
Framework || Existing->isPartOfFramework();
1738 bool ParsedAsMainInput =
1740 Map.LangOpts.CurrentModule == ModuleName &&
1741 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1742 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1745 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;
1746 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||
1748 ActiveModule = PreviousActiveModule;
1753 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1754 ShadowingModule = Existing;
1757 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1759 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1766 if (ShadowingModule) {
1768 Map.createShadowedModule(ModuleName, MD.
Framework, ShadowingModule);
1770 ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
1774 ActiveModule->DefinitionLoc = ModuleNameLoc;
1776 ActiveModule->IsSystem =
true;
1778 ActiveModule->IsExternC =
true;
1780 ActiveModule->NoUndeclaredIncludes =
true;
1781 ActiveModule->Directory = Directory;
1783 StringRef MapFileName(
1784 SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
1785 if (MapFileName.ends_with(
"module.private.modulemap") ||
1786 MapFileName.ends_with(
"module_private.map")) {
1787 ActiveModule->ModuleMapIsPrivate =
true;
1793 SourceLocation StartLoc =
1794 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1795 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1796 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1798 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1800 ActiveModule->ModuleMapIsPrivate)
1801 diagnosePrivateModules(MD.
Location);
1806 [&](
const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },
1807 [&](
const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
1808 [&](
const modulemap::UmbrellaDirDecl &UDD) {
1809 handleUmbrellaDirDecl(UDD);
1811 [&](
const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
1812 [&](
const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
1813 [&](
const modulemap::ExportAsDecl &EAD) {
1814 handleExportAsDecl(EAD);
1816 [&](
const modulemap::ExternModuleDecl &EMD) {
1817 handleExternModuleDecl(EMD);
1819 [&](
const modulemap::UseDecl &UD) { handleUseDecl(UD); },
1820 [&](
const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
1821 [&](
const modulemap::ConfigMacrosDecl &CMD) {
1822 handleConfigMacros(CMD);
1824 [&](
const modulemap::ConflictDecl &CD) { handleConflict(CD); },
1825 [&](
const modulemap::ExcludeDecl &ED) {
1826 Diags.Report(ED.Location, diag::err_mmap_expected_member);
1833 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1834 ActiveModule->LinkLibraries.empty())
1839 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
1840 ActiveModule->Parent) {
1841 ActiveModule->getTopLevelModule()->markUnavailable(
false);
1842 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1843 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1847 ActiveModule = PreviousActiveModule;
1850void ModuleMapLoader::handleExternModuleDecl(
1852 StringRef FileNameRef = EMD.
Path;
1853 SmallString<128> ModuleMapFileName;
1854 if (llvm::sys::path::is_relative(FileNameRef)) {
1855 ModuleMapFileName += Directory.getName();
1856 llvm::sys::path::append(ModuleMapFileName, EMD.
Path);
1857 FileNameRef = ModuleMapFileName;
1859 if (
auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
1860 Map.parseAndLoadModuleMapFile(
1862 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1884 bool &IsRequiresExcludedHack) {
1888 IsRequiresExcludedHack =
true;
1899 for (
const modulemap::RequiresFeature &RF : RD.
Features) {
1900 bool IsRequiresExcludedHack =
false;
1901 bool ShouldAddRequirement =
1904 if (IsRequiresExcludedHack)
1905 UsesRequiresExcludedHack.insert(ActiveModule);
1907 if (ShouldAddRequirement) {
1928 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1934 Module::UnresolvedHeaderDirective Header;
1938 Header.
Kind = Map.headerRoleToKind(
Role);
1942 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
1943 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
1944 << ActiveModule->getFullModuleName();
1954 bool NeedsFramework =
false;
1958 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
1960 ActiveModule->fullModuleNameIs({
"_Builtin_stddef",
"max_align_t"}))
1961 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
1964 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
1965 << ActiveModule->getFullModuleName()
1974void ModuleMapLoader::handleUmbrellaDirDecl(
1976 std::string DirName = std::string(UDD.
Path);
1977 std::string DirNameAsWritten = DirName;
1980 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
1981 Diags.Report(UDD.
Location, diag::err_mmap_umbrella_clash)
1982 << ActiveModule->getFullModuleName();
1989 if (llvm::sys::path::is_absolute(DirName)) {
1990 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
1992 SmallString<128> PathName;
1993 PathName = Directory.getName();
1994 llvm::sys::path::append(PathName, DirName);
1995 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
1999 Diags.Report(UDD.
Location, diag::warn_mmap_umbrella_dir_not_found)
2004 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2010 SmallVector<Module::Header, 6> Headers;
2011 llvm::vfs::FileSystem &FS =
2012 SourceMgr.getFileManager().getVirtualFileSystem();
2013 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2014 I != E && !EC; I.increment(EC)) {
2015 if (
auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2016 Module::Header Header = {
"", std::string(I->path()), *FE};
2017 Headers.push_back(std::move(Header));
2024 for (
auto &Header : Headers)
2029 if (
Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2030 Diags.Report(UDD.
Location, diag::err_mmap_umbrella_clash)
2031 << OwningModule->getFullModuleName();
2037 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
2042 ActiveModule->UnresolvedExports.push_back(
Unresolved);
2046 const auto &ModName = EAD.
Id.front();
2048 if (!ActiveModule->ExportAsModule.empty()) {
2049 if (ActiveModule->ExportAsModule == ModName.first) {
2050 Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)
2051 << ActiveModule->Name << ModName.first;
2053 Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)
2054 << ActiveModule->Name << ActiveModule->ExportAsModule
2059 ActiveModule->ExportAsModule = ModName.first;
2060 Map.addLinkAsDependency(ActiveModule);
2064 if (ActiveModule->Parent)
2065 Diags.Report(UD.
Location, diag::err_mmap_use_decl_submodule);
2067 ActiveModule->UnresolvedDirectUses.push_back(UD.
Id);
2071 ActiveModule->LinkLibraries.push_back(
2075void ModuleMapLoader::handleConfigMacros(
2077 if (ActiveModule->Parent) {
2078 Diags.Report(CMD.
Location, diag::err_mmap_config_macro_submodule);
2085 ActiveModule->ConfigMacrosExhaustive =
true;
2087 ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),
2092 Module::UnresolvedConflict Conflict;
2094 Conflict.
Id = CD.
Id;
2098 ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));
2101void ModuleMapLoader::handleInferredModuleDecl(
2103 SourceLocation StarLoc = MD.
Id.front().second;
2107 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2113 if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
2114 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2119 if (ActiveModule->InferSubmodules) {
2120 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2121 if (ActiveModule->InferredSubmoduleLoc.isValid())
2122 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2123 diag::note_mmap_prev_definition);
2129 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2133 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2139 ActiveModule->InferSubmodules =
true;
2140 ActiveModule->InferredSubmoduleLoc = StarLoc;
2141 ActiveModule->InferExplicitSubmodules = MD.
Explicit;
2144 auto &InfDir = Map.InferredDirectories[Directory];
2145 InfDir.InferModules =
true;
2146 InfDir.Attrs = MD.
Attrs;
2147 InfDir.ModuleMapFID = ModuleMapFID;
2154 [&](
const auto &
Other) {
2155 Diags.Report(
Other.Location,
2156 diag::err_mmap_expected_inferred_member)
2157 << (ActiveModule !=
nullptr);
2159 [&](
const modulemap::ExcludeDecl &ED) {
2163 diag::err_mmap_expected_inferred_member)
2164 << (ActiveModule !=
nullptr);
2168 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(
2171 [&](
const modulemap::ExportDecl &ED) {
2173 if (!ActiveModule) {
2175 diag::err_mmap_expected_inferred_member)
2176 << (ActiveModule !=
nullptr);
2182 ActiveModule->InferExportWildcard =
true;
2184 Diags.Report(ED.
Id.front().second,
2185 diag::err_mmap_expected_export_wildcard);
2192 handleModuleDecl(MD);
2198 handleExternModuleDecl(EMD);
2209 handleExternModuleDecl(EMD);
2217 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
2218 if (Known != Modules.end())
2219 return Known->getValue();
2221 auto ParsedMod = ParsedModules.find(Name);
2222 if (ParsedMod == ParsedModules.end())
2225 Diags.Report(diag::remark_mmap_load_module) << Name;
2227 for (
const auto &ModuleDecl : ParsedMod->second) {
2242 assert(Target &&
"Missing target information");
2243 llvm::DenseMap<const FileEntry *, bool>::iterator Known =
2244 LoadedModuleMap.find(
File);
2245 if (Known != LoadedModuleMap.end())
2246 return Known->second;
2249 if (ID.isInvalid()) {
2250 ID = SourceMgr.translateFile(
File);
2255 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {
2256 auto FileCharacter =
2258 ID = SourceMgr.createFileID(
File, ExternModuleLoc, FileCharacter);
2262 assert(Target &&
"Missing target information");
2263 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
2265 return LoadedModuleMap[
File] =
true;
2266 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2267 "invalid buffer offset");
2269 std::optional<modulemap::ModuleMapFile> MMF =
2273 Diags.Report(diag::remark_mmap_load) <<
File.getName();
2281 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.
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.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Required to construct a Module.
bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD)
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...
friend class ModuleMapLoader
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 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.
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.
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.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
SourceLocation DefinitionLoc
The location of the module definition.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Module * Parent
The parent of this module.
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
void addHeader(HeaderKind HK, Header H)
std::string UmbrellaRelativeToRootModuleDirectory
OptionalDirectoryEntryRef Directory
The build directory of this module.
ArrayRef< Header > getHeaders(HeaderKind HK) const
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
@ ModuleHeaderUnit
This is a C++20 header unit.
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
unsigned IsFramework
Whether this is a framework module.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
std::vector< Conflict > Conflicts
The list of conflicts.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
Defines the clang::TargetInfo interface.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
bool Sub(InterpState &S, CodePtr OpPC)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
std::optional< ModuleMapFile > parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset)
Parse a module map file into an in memory representation.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ Keyword
The name has been typo-corrected to a keyword.
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
@ Other
Other implicit parameter.
unsigned IsExternC
Whether this is an extern "C" module.
unsigned IsSystem
Whether this is a system module.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
A conflict between two modules.
Module * Other
The module that this module conflicts with.
std::string Message
The message provided to the user when there is a conflict.
A library or framework to link against when an entity from this module is used.
std::string Message
The message provided to the user when there is a conflict.
ModuleId Id
The (unresolved) module id.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
std::vector< StringRef > Macros
ModuleAttributes Attrs
Points to the first keyword in the decl.
std::vector< Decl > Decls
Represents the parsed form of a module map file.
std::vector< TopLevelDecl > Decls
FileID ID
The FileID used to parse this module map. This is always a local ID.
OptionalDirectoryEntryRef Dir
The directory in which the module map was discovered.
std::vector< RequiresFeature > Features