30 #include "llvm/ADT/DenseMap.h" 31 #include "llvm/ADT/None.h" 32 #include "llvm/ADT/STLExtras.h" 33 #include "llvm/ADT/SmallPtrSet.h" 34 #include "llvm/ADT/SmallString.h" 35 #include "llvm/ADT/SmallVector.h" 36 #include "llvm/ADT/StringMap.h" 37 #include "llvm/ADT/StringRef.h" 38 #include "llvm/ADT/StringSwitch.h" 39 #include "llvm/Support/Allocator.h" 40 #include "llvm/Support/Compiler.h" 41 #include "llvm/Support/ErrorHandling.h" 42 #include "llvm/Support/MemoryBuffer.h" 43 #include "llvm/Support/Path.h" 44 #include "llvm/Support/VirtualFileSystem.h" 45 #include "llvm/Support/raw_ostream.h" 51 #include <system_error> 54 using namespace clang;
56 void ModuleMapCallbacks::anchor() {}
59 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
60 if (PendingLinkAs != PendingLinkAsModule.end()) {
61 for (
auto &Name : PendingLinkAs->second) {
62 auto *M = findModule(Name.getKey());
64 M->UseExportAsModuleLinkName =
true;
78 default: llvm_unreachable(
"unknown header role");
85 case PrivateHeader | TextualHeader:
102 llvm_unreachable(
"unexpected header kind");
104 llvm_unreachable(
"unknown header kind");
108 ModuleMap::resolveExport(
Module *Mod,
110 bool Complain)
const {
112 if (Unresolved.
Id.empty()) {
113 assert(Unresolved.
Wildcard &&
"Invalid unresolved export");
118 Module *Context = resolveModuleId(Unresolved.
Id, Mod, Complain);
126 bool Complain)
const {
128 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
131 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
138 for (
unsigned I = 1, N = Id.size(); I != N; ++I) {
139 Module *Sub = lookupModuleQualified(Id[I].first, Context);
142 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
161 for (; Mod; Mod = Mod->
Parent) {
163 Paths.push_back(Mod->
Name);
170 for (
unsigned I = Paths.size() - 1; I != 0; --I)
171 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
182 auto *File = SourceMgr.getFileManager().getFile(
Filename);
184 (Header.
Size && File->getSize() != *Header.
Size) ||
185 (Header.
ModTime && File->getModificationTime() != *Header.
ModTime))
190 auto GetFrameworkFile = [&]() ->
const FileEntry * {
191 unsigned FullPathLength = FullPathName.size();
193 unsigned RelativePathLength = RelativePathName.size();
196 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
197 llvm::sys::path::append(FullPathName, RelativePathName);
198 if (
auto *File = GetFile(FullPathName))
208 RelativePathName.clear();
210 RelativePathName.resize(RelativePathLength);
211 FullPathName.resize(FullPathLength);
212 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
214 llvm::sys::path::append(FullPathName, RelativePathName);
215 return GetFile(FullPathName);
218 if (llvm::sys::path::is_absolute(Header.
FileName)) {
219 RelativePathName.clear();
225 return GetFrameworkFile();
228 llvm::sys::path::append(RelativePathName, Header.
FileName);
229 llvm::sys::path::append(FullPathName, RelativePathName);
230 auto *NormalHdrFile = GetFile(FullPathName);
232 if (M && !NormalHdrFile && Directory->getName().endswith(
".framework")) {
236 FullPathName.assign(Directory->getName());
237 RelativePathName.clear();
238 if (GetFrameworkFile()) {
240 diag::warn_mmap_incomplete_framework_module_declaration)
242 NeedsFramework =
true;
247 return NormalHdrFile;
250 void ModuleMap::resolveHeader(
Module *Mod,
252 bool &NeedsFramework) {
255 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
258 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
259 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
260 << UmbrellaMod->getFullModuleName();
263 setUmbrellaHeader(Mod, File, RelativePathName.str());
267 excludeHeader(Mod, H);
269 addHeader(Mod, H, headerKindToRole(Header.
Kind));
289 bool ModuleMap::resolveAsBuiltinHeader(
292 llvm::sys::path::is_absolute(Header.
FileName) ||
294 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
302 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.
FileName);
303 auto *File = SourceMgr.getFileManager().getFile(Path);
307 auto Role = headerKindToRole(Header.
Kind);
309 addHeader(Mod, H, Role);
316 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
317 HeaderInfo(HeaderInfo) {
318 MMapLangOpts.LineComment =
true;
322 for (
auto &M : Modules)
324 for (
auto *M : ShadowModules)
329 assert((!this->Target || this->Target == &Target) &&
330 "Improper target override");
331 this->Target = &Target;
345 Buffer.push_back(
'_');
346 Buffer.reserve(Buffer.size() + Name.size());
347 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
349 Buffer.push_back(Name[I]);
351 Buffer.push_back(
'_');
354 Name = StringRef(Buffer.data(), Buffer.size());
357 while (llvm::StringSwitch<bool>(Name)
358 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 359 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 360 #include "clang/Basic/TokenKinds.def" 362 if (Name.data() != Buffer.data())
363 Buffer.append(Name.begin(), Name.end());
364 Buffer.push_back(
'_');
365 Name = StringRef(Buffer.data(), Buffer.size());
375 return llvm::StringSwitch<bool>(FileName)
376 .Case(
"float.h",
true)
377 .Case(
"iso646.h",
true)
378 .Case(
"limits.h",
true)
379 .Case(
"stdalign.h",
true)
380 .Case(
"stdarg.h",
true)
381 .Case(
"stdatomic.h",
true)
382 .Case(
"stdbool.h",
true)
383 .Case(
"stddef.h",
true)
384 .Case(
"stdint.h",
true)
385 .Case(
"tgmath.h",
true)
386 .Case(
"unwind.h",
true)
390 ModuleMap::HeadersMap::iterator
391 ModuleMap::findKnownHeader(
const FileEntry *File) {
393 HeadersMap::iterator Known = Headers.find(File);
395 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
398 return Headers.find(File);
404 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
406 if (UmbrellaDirs.empty())
410 assert(Dir &&
"file in no directory");
421 auto KnownDir = UmbrellaDirs.find(Dir);
422 if (KnownDir != UmbrellaDirs.end())
425 IntermediateDirs.push_back(Dir);
428 DirName = llvm::sys::path::parent_path(DirName);
446 bool IsPrivate =
false;
450 for (
auto *Hs : HeaderList)
452 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
453 return H.Entry == IncFileEnt;
455 assert(IsPrivate &&
"inconsistent headers and roles");
466 bool RequestingModuleIsModuleInterface,
475 if (RequestingModule) {
480 bool Excluded =
false;
481 Module *Private =
nullptr;
482 Module *NotUsed =
nullptr;
484 HeadersMap::iterator Known = findKnownHeader(File);
485 if (Known != Headers.end()) {
495 if (RequestingModule && LangOpts.ModulesDeclUse &&
510 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
517 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
522 if (Excluded || isHeaderInUmbrellaDirs(File))
527 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
528 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
530 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
534 diag::warn_non_modular_include_in_framework_module :
535 diag::warn_non_modular_include_in_module;
569 HeadersMap::iterator Known = findKnownHeader(File);
570 if (Known != Headers.end()) {
576 return MakeResult(H);
580 return MakeResult(Result);
583 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
587 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
588 assert(!Headers.count(File) &&
"already have a module for this header");
591 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
599 UmbrellaModule = UmbrellaModule->
Parent;
610 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
614 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()), NameBuf);
617 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
621 UmbrellaDirs[SkippedDirs[I-1]] =
Result;
632 llvm::sys::path::stem(File->
getName()), NameBuf);
635 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
646 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
647 UmbrellaDirs[SkippedDirs[I]] = Result;
651 Headers[File].push_back(Header);
661 auto It = Headers.find(File);
662 if (It == Headers.end())
673 const Module *RequestingModule)
const {
675 HeadersMap::const_iterator Known = Headers.find(Header);
676 if (Known != Headers.end()) {
678 I = Known->second.begin(),
679 E = Known->second.end();
682 if (I->isAvailable() &&
683 (!RequestingModule ||
700 StringRef DirName = Dir->
getName();
702 auto IsUnavailable = [&](
const Module *M) {
710 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
711 = UmbrellaDirs.find(Dir);
712 if (KnownDir != UmbrellaDirs.end()) {
713 Module *Found = KnownDir->second;
714 if (IsUnavailable(Found))
719 Module *UmbrellaModule = Found;
721 UmbrellaModule = UmbrellaModule->
Parent;
724 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
728 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()),
733 if (IsUnavailable(Found))
740 llvm::sys::path::stem(Header->
getName()),
747 return IsUnavailable(Found);
750 SkippedDirs.push_back(Dir);
753 DirName = llvm::sys::path::parent_path(DirName);
765 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
766 if (Known != Modules.end())
767 return Known->getValue();
774 for(; Context; Context = Context->
Parent) {
795 return std::make_pair(Sub,
false);
799 IsExplicit, NumCreatedModules++);
804 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
806 return std::make_pair(Result,
true);
810 PendingSubmodules.emplace_back(
811 new Module(
"<global>", Loc,
nullptr,
false,
812 true, NumCreatedModules++));
814 return PendingSubmodules.back().get();
821 new Module(
"<private>", Loc, Parent,
false,
822 true, NumCreatedModules++);
830 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
831 assert(!Modules[Name] &&
"redefining existing module");
834 new Module(Name, Loc,
nullptr,
false,
835 false, NumCreatedModules++);
837 Modules[Name] = SourceModule =
Result;
840 for (
auto &Submodule : PendingSubmodules) {
841 Submodule->setParent(
Result);
844 PendingSubmodules.clear();
849 assert(MainFile &&
"no input file for module interface");
857 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
858 assert(!Modules[Name] &&
"redefining existing module");
862 false, NumCreatedModules++);
864 Modules[Name] = SourceModule =
Result;
869 true, NumCreatedModules++);
882 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
884 "Can only infer linking for top-level frameworks");
887 LibName += FrameworkDir->
getName();
888 llvm::sys::path::append(LibName, Mod->
Name);
893 for (
const char *extension : {
"",
".tbd"}) {
894 llvm::sys::path::replace_extension(LibName, extension);
895 if (FileMgr.
getFile(LibName)) {
907 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
916 StringRef FrameworkDirName =
924 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
934 const FileEntry *ModuleMapFile =
nullptr;
937 bool canInfer =
false;
938 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
940 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
944 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
945 inferred = InferredDirectories.find(ParentDir);
946 if (inferred == InferredDirectories.end()) {
949 bool IsFrameworkDir = Parent.endswith(
".framework");
953 inferred = InferredDirectories.find(ParentDir);
956 if (inferred == InferredDirectories.end())
957 inferred = InferredDirectories.insert(
958 std::make_pair(ParentDir, InferredDirectory())).first;
961 if (inferred->second.InferModules) {
964 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
965 canInfer = std::find(inferred->second.ExcludedModules.begin(),
966 inferred->second.ExcludedModules.end(),
967 Name) == inferred->second.ExcludedModules.end();
969 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
970 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
971 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
972 Attrs.NoUndeclaredIncludes |=
973 inferred->second.Attrs.NoUndeclaredIncludes;
974 ModuleMapFile = inferred->second.ModuleMapFile;
988 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
999 NumCreatedModules++);
1000 InferredModuleAllowedBy[
Result] = ModuleMapFile;
1005 Modules[ModuleName] =
Result;
1006 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1009 Result->
IsSystem |= Attrs.IsSystem;
1031 = StringRef(FrameworkDir->
getName());
1032 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1033 llvm::sys::path::native(SubframeworksDirName);
1035 for (llvm::vfs::directory_iterator
1036 Dir = FS.dir_begin(SubframeworksDirName, EC),
1038 Dir != DirEnd && !EC; Dir.increment(EC)) {
1039 if (!StringRef(Dir->path()).endswith(
".framework"))
1049 bool FoundParent =
false;
1053 = llvm::sys::path::parent_path(SubframeworkDirName);
1054 if (SubframeworkDirName.empty())
1057 if (FileMgr.
getDirectory(SubframeworkDirName) == FrameworkDir) {
1067 inferFrameworkModule(SubframeworkDir, Attrs, Result);
1081 Module *ShadowingModule) {
1086 false, NumCreatedModules++);
1089 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1090 ShadowModules.push_back(Result);
1096 Twine NameAsWritten) {
1100 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
1103 for (
const auto &Cb : Callbacks)
1104 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1108 Twine NameAsWritten) {
1111 UmbrellaDirs[UmbrellaDir] = Mod;
1114 void ModuleMap::addUnresolvedHeader(
Module *Mod,
1116 bool &NeedsFramework) {
1119 if (resolveAsBuiltinHeader(Mod, Header)) {
1138 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1140 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1147 resolveHeader(Mod, Header, NeedsFramework);
1151 auto BySize = LazyHeadersBySize.find(File->
getSize());
1152 if (BySize != LazyHeadersBySize.end()) {
1153 for (
auto *M : BySize->second)
1155 LazyHeadersBySize.erase(BySize);
1159 if (ByModTime != LazyHeadersByModTime.end()) {
1160 for (
auto *M : ByModTime->second)
1162 LazyHeadersByModTime.erase(ByModTime);
1167 bool NeedsFramework =
false;
1171 const_cast<ModuleMap*
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1182 auto &HeaderList = Headers[Header.
Entry];
1183 for (
auto H : HeaderList)
1187 HeaderList.push_back(KH);
1190 bool isCompilingModuleHeader =
1192 if (!Imported || isCompilingModuleHeader) {
1196 isCompilingModuleHeader);
1200 for (
const auto &Cb : Callbacks)
1209 (void) Headers[Header.
Entry];
1225 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1226 return InferredModuleAllowedBy.find(M)->second;
1232 assert(M->
IsInferred &&
"module not inferred");
1233 InferredModuleAllowedBy[M] = ModMap;
1237 llvm::errs() <<
"Modules:";
1238 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1239 MEnd = Modules.end();
1241 M->getValue()->
print(llvm::errs(), 2);
1243 llvm::errs() <<
"Headers:";
1244 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1246 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1248 E = H->second.end();
1250 if (I != H->second.begin())
1251 llvm::errs() <<
",";
1252 llvm::errs() << I->getModule()->getFullModuleName();
1254 llvm::errs() <<
"\n";
1261 for (
auto &UE : Unresolved) {
1263 if (Export.getPointer() || Export.getInt())
1264 Mod->
Exports.push_back(Export);
1274 for (
auto &UDU : Unresolved) {
1275 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1287 for (
auto &UC : Unresolved) {
1288 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1290 Conflict.
Other = OtherMod;
1291 Conflict.
Message = UC.Message;
1352 StringData =
nullptr;
1367 : StringRef(StringData, StringLength);
1396 bool HadError =
false;
1400 llvm::BumpPtrAllocator StringData;
1406 Module *ActiveModule =
nullptr;
1416 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1428 void parseModuleDecl();
1429 void parseExternModuleDecl();
1430 void parseRequiresDecl();
1433 void parseExportDecl();
1434 void parseExportAsDecl();
1435 void parseUseDecl();
1436 void parseLinkDecl();
1437 void parseConfigMacros();
1438 void parseConflict();
1439 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1448 using Attributes = ModuleMap::Attributes;
1450 bool parseOptionalAttributes(Attributes &Attrs);
1457 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1458 ModuleMapFile(ModuleMapFile), Directory(Directory),
1459 IsSystem(IsSystem) {
1478 L.LexFromRawLexer(LToken);
1481 case tok::raw_identifier: {
1483 Tok.StringData = RI.data();
1484 Tok.StringLength = RI.size();
1485 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1542 case tok::string_literal: {
1544 Diags.Report(LToken.
getLocation(), diag::err_invalid_string_udl);
1557 char *Saved = StringData.Allocate<
char>(Length + 1);
1563 Tok.StringData = Saved;
1564 Tok.StringLength = Length;
1568 case tok::numeric_constant: {
1571 SpellingBuffer.resize(LToken.
getLength() + 1);
1572 const char *Start = SpellingBuffer.data();
1576 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1577 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1596 auto NextIsIdent = [&](StringRef Str) ->
bool {
1597 L.LexFromRawLexer(LToken);
1601 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1602 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1610 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1619 unsigned braceDepth = 0;
1620 unsigned squareDepth = 0;
1627 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1634 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1648 if (squareDepth > 0)
1655 if (braceDepth == 0 && squareDepth == 0 &&
Tok.
is(K))
1671 bool ModuleMapParser::parseModuleId(
ModuleId &Id) {
1675 Id.push_back(std::make_pair(
Tok.getString(),
Tok.getLocation()));
1678 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module_name);
1708 AT_no_undeclared_includes
1717 void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1719 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1721 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1722 diag::note_mmap_rename_top_level_private_module);
1723 D << BadName << M->Name;
1727 for (
auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1728 auto const *M = E->getValue();
1729 if (M->Directory != ActiveModule->Directory)
1733 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1737 Canonical.append(
"_Private");
1740 if (ActiveModule->Parent && ActiveModule->Name ==
"Private" && !M->Parent &&
1741 M->Name == ActiveModule->Parent->Name) {
1742 Diags.Report(ActiveModule->DefinitionLoc,
1743 diag::warn_mmap_mismatched_private_submodule)
1748 FixItInitBegin = FrameworkLoc;
1750 FixItInitBegin = ExplicitLoc;
1752 if (FrameworkLoc.
isValid() || ActiveModule->Parent->IsFramework)
1753 FixedPrivModDecl.append(
"framework ");
1754 FixedPrivModDecl.append(
"module ");
1755 FixedPrivModDecl.append(Canonical);
1757 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1758 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1763 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1764 ActiveModule->Name != Canonical) {
1765 Diags.Report(ActiveModule->DefinitionLoc,
1766 diag::warn_mmap_mismatched_private_module_name)
1767 << ActiveModule->Name;
1768 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1792 void ModuleMapParser::parseModuleDecl() {
1796 parseExternModuleDecl();
1803 bool Explicit =
false;
1804 bool Framework =
false;
1808 ExplicitLoc = consumeToken();
1814 FrameworkLoc = consumeToken();
1820 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
1825 CurrModuleDeclLoc = consumeToken();
1830 return parseInferredModuleDecl(Framework, Explicit);
1834 if (parseModuleId(Id)) {
1840 if (Id.size() > 1) {
1841 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1842 <<
SourceRange(Id.front().second, Id.back().second);
1847 }
else if (Id.size() == 1 && Explicit) {
1849 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1855 Module *PreviousActiveModule = ActiveModule;
1856 if (Id.size() > 1) {
1859 ActiveModule =
nullptr;
1860 const Module *TopLevelModule =
nullptr;
1861 for (
unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1862 if (
Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1864 TopLevelModule = Next;
1865 ActiveModule = Next;
1870 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1872 << ActiveModule->getTopLevelModule()->getFullModuleName();
1874 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1880 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1881 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1882 "submodule defined in same file as 'module *' that allowed its " 1883 "top-level module");
1884 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1888 StringRef ModuleName = Id.back().first;
1893 if (parseOptionalAttributes(Attrs))
1898 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace)
1906 Module *ShadowingModule =
nullptr;
1907 if (
Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1915 bool ParsedAsMainInput =
1917 Map.LangOpts.CurrentModule == ModuleName &&
1918 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1919 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1920 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
1926 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
1927 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1933 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1934 ShadowingModule = Existing;
1937 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1939 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1952 if (ShadowingModule) {
1954 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
1957 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
1961 ActiveModule->DefinitionLoc = ModuleNameLoc;
1962 if (Attrs.IsSystem || IsSystem)
1963 ActiveModule->IsSystem =
true;
1964 if (Attrs.IsExternC)
1965 ActiveModule->IsExternC =
true;
1966 if (Attrs.NoUndeclaredIncludes ||
1967 (!ActiveModule->Parent && ModuleName ==
"Darwin"))
1968 ActiveModule->NoUndeclaredIncludes =
true;
1969 ActiveModule->Directory = Directory;
1971 StringRef MapFileName(ModuleMapFile->getName());
1972 if (MapFileName.endswith(
"module.private.modulemap") ||
1973 MapFileName.endswith(
"module_private.map")) {
1974 ActiveModule->ModuleMapIsPrivate =
true;
1981 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1982 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1983 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1985 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1987 ActiveModule->ModuleMapIsPrivate)
1988 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
1999 parseConfigMacros();
2018 parseExportAsDecl();
2026 parseRequiresDecl();
2038 parseUmbrellaDirDecl(UmbrellaLoc);
2059 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_member);
2068 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2069 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2075 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2076 ActiveModule->LinkLibraries.empty()) {
2082 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
2083 ActiveModule->Parent) {
2084 ActiveModule->getTopLevelModule()->markUnavailable();
2085 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2086 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2090 ActiveModule = PreviousActiveModule;
2097 void ModuleMapParser::parseExternModuleDecl() {
2103 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2112 if (parseModuleId(Id)) {
2119 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2123 std::string FileName =
Tok.getString();
2126 StringRef FileNameRef = FileName;
2128 if (llvm::sys::path::is_relative(FileNameRef)) {
2129 ModuleMapFileName += Directory->getName();
2130 llvm::sys::path::append(ModuleMapFileName, FileName);
2131 FileNameRef = ModuleMapFileName;
2133 if (
const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
2134 Map.parseModuleMapFile(
2136 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2139 FileID(),
nullptr, ExternLoc);
2158 bool &IsRequiresExcludedHack) {
2159 if (Feature ==
"excluded" &&
2162 IsRequiresExcludedHack =
true;
2164 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2182 void ModuleMapParser::parseRequiresDecl() {
2190 bool RequiredState =
true;
2192 RequiredState =
false;
2197 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_feature);
2203 std::string Feature =
Tok.getString();
2206 bool IsRequiresExcludedHack =
false;
2207 bool ShouldAddRequirement =
2210 if (IsRequiresExcludedHack)
2211 UsesRequiresExcludedHack.insert(ActiveModule);
2213 if (ShouldAddRequirement) {
2215 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2244 LeadingToken =
Tok.Kind;
2252 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2260 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2271 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2282 : Map.headerRoleToKind(Role));
2285 if (Header.
IsUmbrella && ActiveModule->Umbrella) {
2286 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
2287 << ActiveModule->getFullModuleName();
2298 enum Attribute { Size, ModTime, Unknown };
2299 StringRef Str =
Tok.getString();
2301 switch (llvm::StringSwitch<Attribute>(Str)
2303 .Case(
"mtime", ModTime)
2307 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2309 Diags.Report(
Tok.getLocation(),
2310 diag::err_mmap_invalid_header_attribute_value) << Str;
2314 Header.
Size =
Tok.getInteger();
2320 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2322 Diags.Report(
Tok.getLocation(),
2323 diag::err_mmap_invalid_header_attribute_value) << Str;
2332 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2341 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2342 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2347 bool NeedsFramework =
false;
2348 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2350 if (NeedsFramework && ActiveModule)
2351 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2352 << ActiveModule->getFullModuleName()
2365 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2368 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2374 std::string DirName =
Tok.getString();
2378 if (ActiveModule->Umbrella) {
2379 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2380 << ActiveModule->getFullModuleName();
2387 if (llvm::sys::path::is_absolute(DirName))
2388 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2391 PathName = Directory->getName();
2392 llvm::sys::path::append(PathName, DirName);
2393 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2397 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2402 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2409 llvm::vfs::FileSystem &FS =
2410 SourceMgr.getFileManager().getVirtualFileSystem();
2411 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2412 I != E && !EC; I.increment(EC)) {
2413 if (
const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
2416 Headers.push_back(std::move(Header));
2423 for (
auto &Header : Headers)
2428 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2429 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2430 << OwningModule->getFullModuleName();
2436 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2448 void ModuleMapParser::parseExportDecl() {
2454 bool Wildcard =
false;
2458 ParsedModuleId.push_back(std::make_pair(
Tok.getString(),
2459 Tok.getLocation()));
2476 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2482 ExportLoc, ParsedModuleId, Wildcard
2484 ActiveModule->UnresolvedExports.push_back(Unresolved);
2491 void ModuleMapParser::parseExportAsDecl() {
2496 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2501 if (ActiveModule->Parent) {
2502 Diags.Report(
Tok.getLocation(), diag::err_mmap_submodule_export_as);
2507 if (!ActiveModule->ExportAsModule.empty()) {
2508 if (ActiveModule->ExportAsModule ==
Tok.getString()) {
2509 Diags.Report(
Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2510 << ActiveModule->Name <<
Tok.getString();
2512 Diags.Report(
Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2513 << ActiveModule->Name << ActiveModule->ExportAsModule
2518 ActiveModule->ExportAsModule =
Tok.getString();
2519 Map.addLinkAsDependency(ActiveModule);
2528 void ModuleMapParser::parseUseDecl() {
2530 auto KWLoc = consumeToken();
2533 parseModuleId(ParsedModuleId);
2535 if (ActiveModule->Parent)
2536 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2538 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2545 void ModuleMapParser::parseLinkDecl() {
2550 bool IsFramework =
false;
2558 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_library_name)
2564 std::string LibraryName =
Tok.getString();
2577 void ModuleMapParser::parseConfigMacros() {
2582 if (ActiveModule->Parent) {
2583 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2588 if (parseOptionalAttributes(Attrs))
2591 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2592 ActiveModule->ConfigMacrosExhaustive =
true;
2601 if (!ActiveModule->Parent) {
2602 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2615 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_config_macro);
2620 if (!ActiveModule->Parent) {
2621 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2631 llvm::raw_string_ostream OS(result);
2633 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
2647 void ModuleMapParser::parseConflict() {
2653 if (parseModuleId(Conflict.
Id))
2658 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2666 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2674 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2686 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2689 bool Failed =
false;
2692 if (!ActiveModule && !Framework) {
2693 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2699 if (!Failed && ActiveModule->IsAvailable &&
2700 !ActiveModule->getUmbrellaDir()) {
2701 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2706 if (!Failed && ActiveModule->InferSubmodules) {
2707 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2708 if (ActiveModule->InferredSubmoduleLoc.isValid())
2709 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2710 diag::note_mmap_prev_definition);
2716 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2719 }
else if (Explicit) {
2720 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2738 if (parseOptionalAttributes(Attrs))
2743 ActiveModule->InferSubmodules =
true;
2744 ActiveModule->InferredSubmoduleLoc = StarLoc;
2745 ActiveModule->InferExplicitSubmodules = Explicit;
2748 Map.InferredDirectories[Directory].InferModules =
true;
2749 Map.InferredDirectories[Directory].Attrs = Attrs;
2750 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2756 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2773 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2774 << (ActiveModule !=
nullptr);
2782 Diags.Report(
Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2786 Map.InferredDirectories[Directory].ExcludedModules
2787 .push_back(
Tok.getString());
2792 if (!ActiveModule) {
2793 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2794 << (ActiveModule !=
nullptr);
2801 ActiveModule->InferExportWildcard =
true;
2803 Diags.Report(
Tok.getLocation(),
2804 diag::err_mmap_expected_export_wildcard);
2814 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2815 << (ActiveModule !=
nullptr);
2824 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2825 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2842 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2843 bool HadError =
false;
2851 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_attribute);
2860 = llvm::StringSwitch<AttributeKind>(
Tok.getString())
2861 .Case(
"exhaustive", AT_exhaustive)
2862 .Case(
"extern_c", AT_extern_c)
2863 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2864 .Case(
"system", AT_system)
2865 .Default(AT_unknown);
2866 switch (Attribute) {
2868 Diags.Report(
Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2873 Attrs.IsSystem =
true;
2877 Attrs.IsExternC =
true;
2881 Attrs.IsExhaustive =
true;
2884 case AT_no_undeclared_includes:
2885 Attrs.NoUndeclaredIncludes =
true;
2892 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rsquare);
2893 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2945 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2957 assert(
Target &&
"Missing target information");
2958 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2959 = ParsedModuleMap.find(File);
2960 if (Known != ParsedModuleMap.end())
2961 return Known->second;
2965 auto FileCharacter =
2967 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2970 assert(
Target &&
"Missing target information");
2971 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2973 return ParsedModuleMap[File] =
true;
2974 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2975 "invalid buffer offset");
2978 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2979 Buffer->getBufferStart(),
2980 Buffer->getBufferStart() + (Offset ? *
Offset : 0),
2981 Buffer->getBufferEnd());
2986 ParsedModuleMap[File] =
Result;
2989 auto Loc = SourceMgr.getDecomposedLoc(Parser.
getLocation());
2990 assert(Loc.first == ID &&
"stopped in a different file?");
2991 *Offset = Loc.second;
2995 for (
const auto &Cb : Callbacks)
2996 Cb->moduleMapFileRead(Start, *File, IsSystem);
unsigned IsAvailable
Whether this module is available in the current translation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer...
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap)
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
SourceLocation getLocation() const
std::string Name
The name of this module.
static Module * getTopLevelOrNull(Module *M)
This header is included but private.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system...
std::string Message
The message provided to the user when there is a conflict.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Implements support for file system lookup, file system caching, and directory search management...
void dump()
Dump the contents of the module map, for debugging purposes.
Defines the clang::FileManager interface and associated types.
An unresolved conflict with another module.
time_t getModificationTime() const
This header is part of the module (for layering purposes) but should be textually included...
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Defines the SourceManager interface.
Defines the clang::Module class, which describes a module in the source code.
void excludeHeader(Module *Mod, Module::Header Header)
Marks this header as being excluded from the given module.
unsigned IsFramework
Whether this is a framework module.
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, const FileEntry *ModuleMapFile, const DirectoryEntry *Directory, bool IsSystem)
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isCompilingModule() const
Are we compiling a module interface (.cppm or module map)?
Parser - This implements a parser for the C family of languages.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Module * createHeaderModule(StringRef Name, ArrayRef< Module::Header > Headers)
Create a header module from the specified list of headers.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup...
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives...
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
tok::TokenKind getKind() const
void markUnavailable(bool MissingRequirement=false)
Mark this module and all of its submodules as unavailable.
This is the private module fragment within some C++ module.
unsigned GetStringLength() const
FileManager & getFileManager() const
A library or framework to link against when an entity from this module is used.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Token - This structure provides full information about a lexed token.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, Twine NameAsWritten)
Sets the umbrella directory of the given module to the given directory.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Compiling a module from a module map.
Describes a module or submodule.
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
std::string Message
The message provided to the user when there is a conflict.
ModuleId Id
The (unresolved) module id.
Concrete class used by the front-end to report problems and issues.
bool isSubModuleOf(const Module *Other) const
Determine whether this module is a submodule of the given other module.
Module * Parent
The parent of this module.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Defines the Diagnostic-related interfaces.
void setTarget(const TargetInfo &Target)
Set the target information.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules...
StringRef getString() const
const FileEntry * getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name, Module *GlobalModule)
Create a new module for a C++ module interface unit.
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
bool parseModuleMapFile(const FileEntry *File, bool IsSystem, const DirectoryEntry *HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
ModuleHeaderRole
Flags describing the role of a module header.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc)
Create a global module fragment for a C++ module unit.
Exposes information about the current target.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
Defines the clang::LangOptions interface.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
ModuleId Id
The name of the module.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used...
static int compareModuleHeaders(const Module::Header *A, const Module::Header *B)
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false)
Retrieve the module that owns the given header file, if any.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, Twine NameAsWritten)
Sets the umbrella header of the given module to the given header.
static std::string formatModuleId(const ModuleId &Id)
Format a module-id into a string.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
The result type of a method or function.
StringRef GetString() const
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
const DirectoryEntry * Directory
The build directory of this module.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, FileManager &FileMgr)
For a framework module, infer the framework against which we should link.
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
SourceLocation getLocation()
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
LLVM_READONLY bool isValidIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
Encodes a location in the source.
StringRef getName() const
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed, for use in "private" modules.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
bool is(TokenKind K) const
Cached information about one file (either on disk or in the virtual file system). ...
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
This is a fragment of the global module within some C++ module.
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context...
bool Wildcard
Whether this export declaration ends in a wildcard, indicating that all of its submodules should be e...
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
This header is normally included in the module.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
bool parseModuleMapFile()
Parse a module map file.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
A conflict between two modules.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
static std::string getName(const CallEvent &Call)
Module * ShadowingModule
A module with the same name that shadows this module.
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File) const
Retrieve all the modules that contain the given header file.
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
LLVM_READONLY bool isIdentifierBody(unsigned char c, bool AllowDollar=false)
Returns true if this is a body character of a C identifier, which is [a-zA-Z0-9_].
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
unsigned getLength() const
bool terminatedByDirective()
SourceLocation DefinitionLoc
The location of the module definition.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
uint64_t getInteger() const
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
A token in a module map file.
std::vector< Conflict > Conflicts
The list of conflicts.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Cached information about one directory (either on disk or in the virtual file system).
Defines the clang::SourceLocation class and associated facilities.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
~ModuleMap()
Destroy the module map.
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
AttributeKind
Enumerates the known attributes.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Module * Other
The module that this module conflicts with.
A trivial tuple used to represent a source range.
llvm::vfs::FileSystem & getVirtualFileSystem() const
This class handles loading and caching of source files into memory.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
This is a C++ Modules TS module interface unit.
StringRef getName() const