32 #include "llvm/ADT/DenseMap.h" 33 #include "llvm/ADT/None.h" 34 #include "llvm/ADT/STLExtras.h" 35 #include "llvm/ADT/SmallPtrSet.h" 36 #include "llvm/ADT/SmallString.h" 37 #include "llvm/ADT/SmallVector.h" 38 #include "llvm/ADT/StringMap.h" 39 #include "llvm/ADT/StringRef.h" 40 #include "llvm/ADT/StringSwitch.h" 41 #include "llvm/Support/Allocator.h" 42 #include "llvm/Support/Compiler.h" 43 #include "llvm/Support/ErrorHandling.h" 44 #include "llvm/Support/MemoryBuffer.h" 45 #include "llvm/Support/Path.h" 46 #include "llvm/Support/raw_ostream.h" 52 #include <system_error> 55 using namespace clang;
59 default: llvm_unreachable(
"unknown header role");
83 llvm_unreachable(
"unexpected header kind");
85 llvm_unreachable(
"unknown header kind");
89 ModuleMap::resolveExport(
Module *Mod,
91 bool Complain)
const {
93 if (Unresolved.
Id.empty()) {
94 assert(Unresolved.
Wildcard &&
"Invalid unresolved export");
99 Module *Context = resolveModuleId(Unresolved.
Id, Mod, Complain);
107 bool Complain)
const {
112 Diags.
Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
119 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
123 Diags.
Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
142 for (; Mod; Mod = Mod->
Parent) {
144 Paths.push_back(Mod->
Name);
151 for (
unsigned I = Paths.size() - 1; I != 0; --I)
152 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
156 ModuleMap::findHeader(
Module *M,
162 (Header.
Size && File->getSize() != *Header.
Size) ||
163 (Header.
ModTime && File->getModificationTime() != *Header.
ModTime))
168 if (llvm::sys::path::is_absolute(Header.
FileName)) {
169 RelativePathName.clear();
177 unsigned FullPathLength = FullPathName.size();
181 unsigned RelativePathLength = RelativePathName.size();
184 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
185 llvm::sys::path::append(FullPathName, RelativePathName);
186 if (
auto *File = GetFile(FullPathName))
196 RelativePathName.clear();
198 RelativePathName.resize(RelativePathLength);
199 FullPathName.resize(FullPathLength);
200 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
202 llvm::sys::path::append(FullPathName, RelativePathName);
203 return GetFile(FullPathName);
207 llvm::sys::path::append(RelativePathName, Header.
FileName);
208 llvm::sys::path::append(FullPathName, RelativePathName);
209 return GetFile(FullPathName);
212 void ModuleMap::resolveHeader(
Module *Mod,
215 if (
const FileEntry *File = findHeader(Mod, Header, RelativePathName)) {
218 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
220 << UmbrellaMod->getFullModuleName();
249 bool ModuleMap::resolveAsBuiltinHeader(
252 llvm::sys::path::is_absolute(Header.
FileName) ||
254 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
262 llvm::sys::path::append(Path, BuiltinIncludeDir->
getName(), Header.
FileName);
276 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
277 HeaderInfo(HeaderInfo) {
278 MMapLangOpts.LineComment =
true;
282 for (
auto &M : Modules)
287 assert((!this->Target || this->Target == &Target) &&
288 "Improper target override");
289 this->Target = &Target;
303 Buffer.push_back(
'_');
304 Buffer.reserve(Buffer.size() + Name.size());
305 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
307 Buffer.push_back(Name[I]);
309 Buffer.push_back(
'_');
312 Name = StringRef(Buffer.data(), Buffer.size());
315 while (llvm::StringSwitch<bool>(Name)
316 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 317 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 318 #include "clang/Basic/TokenKinds.def" 320 if (Name.data() != Buffer.data())
321 Buffer.append(Name.begin(), Name.end());
322 Buffer.push_back(
'_');
323 Name = StringRef(Buffer.data(), Buffer.size());
333 return llvm::StringSwitch<bool>(FileName)
334 .Case(
"float.h",
true)
335 .Case(
"iso646.h",
true)
336 .Case(
"limits.h",
true)
337 .Case(
"stdalign.h",
true)
338 .Case(
"stdarg.h",
true)
339 .Case(
"stdatomic.h",
true)
340 .Case(
"stdbool.h",
true)
341 .Case(
"stddef.h",
true)
342 .Case(
"stdint.h",
true)
343 .Case(
"tgmath.h",
true)
344 .Case(
"unwind.h",
true)
348 ModuleMap::HeadersMap::iterator
349 ModuleMap::findKnownHeader(
const FileEntry *File) {
351 HeadersMap::iterator Known = Headers.find(File);
353 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
356 return Headers.find(File);
362 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
364 if (UmbrellaDirs.empty())
368 assert(Dir &&
"file in no directory");
379 auto KnownDir = UmbrellaDirs.find(Dir);
380 if (KnownDir != UmbrellaDirs.end())
383 IntermediateDirs.push_back(Dir);
386 DirName = llvm::sys::path::parent_path(DirName);
404 bool IsPrivate =
false;
408 for (
auto *Hs : HeaderList)
410 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
411 return H.Entry == IncFileEnt;
413 assert(IsPrivate &&
"inconsistent headers and roles");
424 bool RequestingModuleIsModuleInterface,
433 if (RequestingModule) {
438 bool Excluded =
false;
439 Module *Private =
nullptr;
440 Module *NotUsed =
nullptr;
442 HeadersMap::iterator Known = findKnownHeader(File);
443 if (Known != Headers.end()) {
453 if (RequestingModule && LangOpts.ModulesDeclUse &&
468 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
475 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
480 if (Excluded || isHeaderInUmbrellaDirs(File))
485 if (LangOpts.ModulesStrictDeclUse) {
486 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
488 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
492 diag::warn_non_modular_include_in_framework_module :
493 diag::warn_non_modular_include_in_module;
527 HeadersMap::iterator Known = findKnownHeader(File);
528 if (Known != Headers.end()) {
534 return MakeResult(H);
538 return MakeResult(Result);
541 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
545 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
546 assert(!Headers.count(File) &&
"already have a module for this header");
549 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
557 UmbrellaModule = UmbrellaModule->
Parent;
568 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
572 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
575 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
579 UmbrellaDirs[SkippedDirs[I-1]] =
Result;
590 llvm::sys::path::stem(File->
getName()), NameBuf);
593 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
604 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
605 UmbrellaDirs[SkippedDirs[I]] = Result;
609 Headers[File].push_back(Header);
619 auto It = Headers.find(File);
620 if (It == Headers.end())
631 const Module *RequestingModule)
const {
633 HeadersMap::const_iterator Known = Headers.find(Header);
634 if (Known != Headers.end()) {
636 I = Known->second.begin(),
637 E = Known->second.end();
640 if (I->isAvailable() &&
641 (!RequestingModule ||
642 I->getModule()->isSubModuleOf(RequestingModule))) {
658 StringRef DirName = Dir->
getName();
660 auto IsUnavailable = [&](
const Module *M) {
668 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
669 = UmbrellaDirs.find(Dir);
670 if (KnownDir != UmbrellaDirs.end()) {
671 Module *Found = KnownDir->second;
672 if (IsUnavailable(Found))
677 Module *UmbrellaModule = Found;
679 UmbrellaModule = UmbrellaModule->
Parent;
682 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
686 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
691 if (IsUnavailable(Found))
698 llvm::sys::path::stem(Header->
getName()),
705 return IsUnavailable(Found);
708 SkippedDirs.push_back(Dir);
711 DirName = llvm::sys::path::parent_path(DirName);
723 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
724 if (Known != Modules.end())
725 return Known->getValue();
732 for(; Context; Context = Context->
Parent) {
753 return std::make_pair(Sub,
false);
757 IsExplicit, NumCreatedModules++);
763 return std::make_pair(Result,
true);
767 assert(!PendingGlobalModule &&
"created multiple global modules");
768 PendingGlobalModule.reset(
769 new Module(
"<global>", Loc,
nullptr,
false,
770 true, NumCreatedModules++));
772 return PendingGlobalModule.get();
778 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
779 assert(!Modules[Name] &&
"redefining existing module");
782 new Module(Name, Loc,
nullptr,
false,
783 false, NumCreatedModules++);
785 Modules[Name] = SourceModule =
Result;
788 assert(GlobalModule == PendingGlobalModule.get() &&
789 "unexpected global module");
791 PendingGlobalModule.release();
796 assert(MainFile &&
"no input file for module interface");
806 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
808 "Can only infer linking for top-level frameworks");
811 LibName += FrameworkDir->
getName();
812 llvm::sys::path::append(LibName, Mod->
Name);
817 for (
const char *extension : {
"",
".tbd"}) {
818 llvm::sys::path::replace_extension(LibName, extension);
819 if (FileMgr.
getFile(LibName)) {
831 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
840 StringRef FrameworkDirName =
848 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
858 const FileEntry *ModuleMapFile =
nullptr;
861 bool canInfer =
false;
862 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
864 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
868 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
869 inferred = InferredDirectories.find(ParentDir);
870 if (inferred == InferredDirectories.end()) {
873 bool IsFrameworkDir = Parent.endswith(
".framework");
877 inferred = InferredDirectories.find(ParentDir);
880 if (inferred == InferredDirectories.end())
881 inferred = InferredDirectories.insert(
882 std::make_pair(ParentDir, InferredDirectory())).first;
885 if (inferred->second.InferModules) {
888 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
889 canInfer = std::find(inferred->second.ExcludedModules.begin(),
890 inferred->second.ExcludedModules.end(),
891 Name) == inferred->second.ExcludedModules.end();
893 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
894 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
895 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
896 Attrs.NoUndeclaredIncludes |=
897 inferred->second.Attrs.NoUndeclaredIncludes;
898 ModuleMapFile = inferred->second.ModuleMapFile;
912 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
923 NumCreatedModules++);
924 InferredModuleAllowedBy[
Result] = ModuleMapFile;
929 Modules[ModuleName] =
Result;
954 = StringRef(FrameworkDir->
getName());
955 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
956 llvm::sys::path::native(SubframeworksDirName);
960 Dir != DirEnd && !EC; Dir.
increment(EC)) {
961 if (!StringRef(Dir->getName()).endswith(
".framework"))
971 bool FoundParent =
false;
975 = llvm::sys::path::parent_path(SubframeworkDirName);
976 if (SubframeworkDirName.empty())
979 if (FileMgr.
getDirectory(SubframeworkDirName) == FrameworkDir) {
989 inferFrameworkModule(SubframeworkDir, Attrs, Result);
1003 Twine NameAsWritten) {
1007 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
1010 for (
const auto &Cb : Callbacks)
1011 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1015 Twine NameAsWritten) {
1018 UmbrellaDirs[UmbrellaDir] = Mod;
1021 void ModuleMap::addUnresolvedHeader(
Module *Mod,
1025 if (resolveAsBuiltinHeader(Mod, Header)) {
1044 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1046 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1053 resolveHeader(Mod, Header);
1057 auto BySize = LazyHeadersBySize.find(File->
getSize());
1058 if (BySize != LazyHeadersBySize.end()) {
1059 for (
auto *M : BySize->second)
1061 LazyHeadersBySize.erase(BySize);
1065 if (ByModTime != LazyHeadersByModTime.end()) {
1066 for (
auto *M : ByModTime->second)
1068 LazyHeadersByModTime.erase(ByModTime);
1076 const_cast<ModuleMap*
>(
this)->resolveHeader(Mod, Header);
1087 auto &HeaderList = Headers[Header.
Entry];
1088 for (
auto H : HeaderList)
1092 HeaderList.push_back(KH);
1095 bool isCompilingModuleHeader =
1097 if (!Imported || isCompilingModuleHeader) {
1101 isCompilingModuleHeader);
1105 for (
const auto &Cb : Callbacks)
1114 (void) Headers[Header.
Entry];
1130 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1131 return InferredModuleAllowedBy.find(M)->second;
1137 assert(M->
IsInferred &&
"module not inferred");
1138 InferredModuleAllowedBy[M] = ModMap;
1142 llvm::errs() <<
"Modules:";
1143 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1144 MEnd = Modules.end();
1146 M->getValue()->
print(llvm::errs(), 2);
1148 llvm::errs() <<
"Headers:";
1149 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1151 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1153 E = H->second.end();
1155 if (I != H->second.begin())
1156 llvm::errs() <<
",";
1157 llvm::errs() << I->getModule()->getFullModuleName();
1159 llvm::errs() <<
"\n";
1166 for (
auto &UE : Unresolved) {
1168 if (Export.getPointer() || Export.getInt())
1169 Mod->
Exports.push_back(Export);
1179 for (
auto &UDU : Unresolved) {
1180 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1192 for (
auto &UC : Unresolved) {
1193 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1195 Conflict.
Other = OtherMod;
1196 Conflict.
Message = UC.Message;
1257 StringData =
nullptr;
1272 : StringRef(StringData, StringLength);
1298 bool HadError =
false;
1302 llvm::BumpPtrAllocator StringData;
1308 Module *ActiveModule =
nullptr;
1318 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1329 bool parseModuleId(ModuleId &
Id);
1330 void parseModuleDecl();
1331 void parseExternModuleDecl();
1332 void parseRequiresDecl();
1335 void parseExportDecl();
1336 void parseExportAsDecl();
1337 void parseUseDecl();
1338 void parseLinkDecl();
1339 void parseConfigMacros();
1340 void parseConflict();
1341 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1343 using Attributes = ModuleMap::Attributes;
1345 bool parseOptionalAttributes(Attributes &Attrs);
1355 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1356 ModuleMapFile(ModuleMapFile), Directory(Directory),
1357 IsSystem(IsSystem) {
1376 L.LexFromRawLexer(LToken);
1379 case tok::raw_identifier: {
1381 Tok.StringData = RI.data();
1382 Tok.StringLength = RI.size();
1383 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1440 case tok::string_literal: {
1442 Diags.Report(LToken.
getLocation(), diag::err_invalid_string_udl);
1455 char *Saved = StringData.Allocate<
char>(Length + 1);
1456 memcpy(Saved, StringLiteral.
GetString().data(), Length);
1461 Tok.StringData = Saved;
1462 Tok.StringLength = Length;
1466 case tok::numeric_constant: {
1469 SpellingBuffer.resize(LToken.
getLength() + 1);
1470 const char *Start = SpellingBuffer.data();
1474 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1475 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1494 auto NextIsIdent = [&](StringRef Str) ->
bool {
1495 L.LexFromRawLexer(LToken);
1499 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1500 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1508 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1517 unsigned braceDepth = 0;
1518 unsigned squareDepth = 0;
1525 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1532 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1546 if (squareDepth > 0)
1553 if (braceDepth == 0 && squareDepth == 0 &&
Tok.
is(K))
1569 bool ModuleMapParser::parseModuleId(ModuleId &
Id) {
1573 Id.push_back(std::make_pair(
Tok.getString(),
Tok.getLocation()));
1576 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module_name);
1606 AT_no_undeclared_includes
1617 const Module *ActiveModule) {
1619 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1622 diag::note_mmap_rename_top_level_private_module);
1623 D << BadName << M->
Name;
1628 auto const *M = E->getValue();
1633 if (!FullName.startswith(M->
Name) && !FullName.endswith(
"Private"))
1636 Canonical.append(
"_Private");
1639 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->
Parent &&
1642 diag::warn_mmap_mismatched_private_submodule)
1644 GenNoteAndFixIt(FullName, Canonical, M);
1650 ActiveModule->
Name != Canonical) {
1652 diag::warn_mmap_mismatched_private_module_name)
1653 << ActiveModule->
Name;
1654 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M);
1677 void ModuleMapParser::parseModuleDecl() {
1681 parseExternModuleDecl();
1687 bool Explicit =
false;
1688 bool Framework =
false;
1692 ExplicitLoc = consumeToken();
1704 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
1714 return parseInferredModuleDecl(Framework, Explicit);
1718 if (parseModuleId(Id)) {
1724 if (Id.size() > 1) {
1725 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1726 <<
SourceRange(Id.front().second, Id.back().second);
1731 }
else if (Id.size() == 1 && Explicit) {
1733 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1739 Module *PreviousActiveModule = ActiveModule;
1740 if (Id.size() > 1) {
1743 ActiveModule =
nullptr;
1744 const Module *TopLevelModule =
nullptr;
1745 for (
unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1746 if (
Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1748 TopLevelModule = Next;
1749 ActiveModule = Next;
1754 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1756 << ActiveModule->getTopLevelModule()->getFullModuleName();
1758 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1764 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1765 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1766 "submodule defined in same file as 'module *' that allowed its " 1767 "top-level module");
1768 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1772 StringRef ModuleName = Id.back().first;
1777 if (parseOptionalAttributes(Attrs))
1782 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace)
1790 if (
Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1795 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
1798 bool ParsedAsMainInput =
1800 Map.LangOpts.CurrentModule == ModuleName &&
1801 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1802 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1803 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
1809 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
1810 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1816 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1818 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1830 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1832 ActiveModule->DefinitionLoc = ModuleNameLoc;
1833 if (Attrs.IsSystem || IsSystem)
1834 ActiveModule->IsSystem =
true;
1835 if (Attrs.IsExternC)
1836 ActiveModule->IsExternC =
true;
1837 if (Attrs.NoUndeclaredIncludes ||
1838 (!ActiveModule->Parent && ModuleName ==
"Darwin"))
1839 ActiveModule->NoUndeclaredIncludes =
true;
1840 ActiveModule->Directory = Directory;
1847 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1848 StringRef MapFileName(ModuleMapFile->getName());
1849 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1850 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1852 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1854 (MapFileName.endswith(
"module.private.modulemap") ||
1855 MapFileName.endswith(
"module_private.map")))
1867 parseConfigMacros();
1886 parseExportAsDecl();
1894 parseRequiresDecl();
1906 parseUmbrellaDirDecl(UmbrellaLoc);
1927 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_member);
1936 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
1937 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1943 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1944 ActiveModule->LinkLibraries.empty()) {
1950 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1951 ActiveModule->Parent) {
1952 ActiveModule->getTopLevelModule()->markUnavailable();
1953 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1954 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1958 ActiveModule = PreviousActiveModule;
1965 void ModuleMapParser::parseExternModuleDecl() {
1971 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
1980 if (parseModuleId(Id)) {
1987 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1991 std::string FileName =
Tok.getString();
1994 StringRef FileNameRef = FileName;
1996 if (llvm::sys::path::is_relative(FileNameRef)) {
1997 ModuleMapFileName += Directory->getName();
1998 llvm::sys::path::append(ModuleMapFileName, FileName);
1999 FileNameRef = ModuleMapFileName;
2001 if (
const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
2002 Map.parseModuleMapFile(
2004 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2007 FileID(),
nullptr, ExternLoc);
2026 bool &IsRequiresExcludedHack) {
2027 if (Feature ==
"excluded" &&
2030 IsRequiresExcludedHack =
true;
2032 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2050 void ModuleMapParser::parseRequiresDecl() {
2058 bool RequiredState =
true;
2060 RequiredState =
false;
2065 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_feature);
2071 std::string Feature =
Tok.getString();
2074 bool IsRequiresExcludedHack =
false;
2075 bool ShouldAddRequirement =
2078 if (IsRequiresExcludedHack)
2079 UsesRequiresExcludedHack.insert(ActiveModule);
2081 if (ShouldAddRequirement) {
2083 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2112 LeadingToken =
Tok.Kind;
2120 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2128 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2139 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2150 : Map.headerRoleToKind(Role));
2153 if (Header.
IsUmbrella && ActiveModule->Umbrella) {
2154 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
2155 << ActiveModule->getFullModuleName();
2166 enum Attribute { Size, ModTime, Unknown };
2167 StringRef Str =
Tok.getString();
2169 switch (llvm::StringSwitch<Attribute>(Str)
2171 .Case(
"mtime", ModTime)
2175 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2177 Diags.Report(
Tok.getLocation(),
2178 diag::err_mmap_invalid_header_attribute_value) << Str;
2182 Header.
Size =
Tok.getInteger();
2188 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2190 Diags.Report(
Tok.getLocation(),
2191 diag::err_mmap_invalid_header_attribute_value) << Str;
2200 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2209 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2210 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2215 Map.addUnresolvedHeader(ActiveModule, std::move(Header));
2227 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2230 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2236 std::string DirName =
Tok.getString();
2240 if (ActiveModule->Umbrella) {
2241 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2242 << ActiveModule->getFullModuleName();
2249 if (llvm::sys::path::is_absolute(DirName))
2250 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2253 PathName = Directory->getName();
2254 llvm::sys::path::append(PathName, DirName);
2255 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2259 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2264 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2271 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2273 I != E && !EC; I.increment(EC)) {
2275 SourceMgr.getFileManager().getFile(I->getName())) {
2278 Headers.push_back(std::move(Header));
2285 for (
auto &Header : Headers)
2290 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2291 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2292 << OwningModule->getFullModuleName();
2298 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2310 void ModuleMapParser::parseExportDecl() {
2316 bool Wildcard =
false;
2320 ParsedModuleId.push_back(std::make_pair(
Tok.getString(),
2321 Tok.getLocation()));
2338 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2344 ExportLoc, ParsedModuleId, Wildcard
2346 ActiveModule->UnresolvedExports.push_back(Unresolved);
2353 void ModuleMapParser::parseExportAsDecl() {
2358 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2363 if (ActiveModule->Parent) {
2364 Diags.Report(
Tok.getLocation(), diag::err_mmap_submodule_export_as);
2369 if (!ActiveModule->ExportAsModule.empty()) {
2370 if (ActiveModule->ExportAsModule ==
Tok.getString()) {
2371 Diags.Report(
Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2372 << ActiveModule->Name <<
Tok.getString();
2374 Diags.Report(
Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2375 << ActiveModule->Name << ActiveModule->ExportAsModule
2380 ActiveModule->ExportAsModule =
Tok.getString();
2388 void ModuleMapParser::parseUseDecl() {
2390 auto KWLoc = consumeToken();
2393 parseModuleId(ParsedModuleId);
2395 if (ActiveModule->Parent)
2396 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2398 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2405 void ModuleMapParser::parseLinkDecl() {
2410 bool IsFramework =
false;
2418 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_library_name)
2424 std::string LibraryName =
Tok.getString();
2437 void ModuleMapParser::parseConfigMacros() {
2442 if (ActiveModule->Parent) {
2443 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2448 if (parseOptionalAttributes(Attrs))
2451 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2452 ActiveModule->ConfigMacrosExhaustive =
true;
2461 if (!ActiveModule->Parent) {
2462 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2475 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_config_macro);
2480 if (!ActiveModule->Parent) {
2481 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2491 llvm::raw_string_ostream OS(result);
2493 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
2507 void ModuleMapParser::parseConflict() {
2513 if (parseModuleId(Conflict.
Id))
2518 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2526 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2534 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2546 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2549 bool Failed =
false;
2552 if (!ActiveModule && !Framework) {
2553 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2559 if (!Failed && ActiveModule->IsAvailable &&
2560 !ActiveModule->getUmbrellaDir()) {
2561 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2566 if (!Failed && ActiveModule->InferSubmodules) {
2567 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2568 if (ActiveModule->InferredSubmoduleLoc.isValid())
2569 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2570 diag::note_mmap_prev_definition);
2576 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2579 }
else if (Explicit) {
2580 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2598 if (parseOptionalAttributes(Attrs))
2603 ActiveModule->InferSubmodules =
true;
2604 ActiveModule->InferredSubmoduleLoc = StarLoc;
2605 ActiveModule->InferExplicitSubmodules = Explicit;
2608 Map.InferredDirectories[Directory].InferModules =
true;
2609 Map.InferredDirectories[Directory].Attrs = Attrs;
2610 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2616 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2633 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2634 << (ActiveModule !=
nullptr);
2642 Diags.Report(
Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2646 Map.InferredDirectories[Directory].ExcludedModules
2647 .push_back(
Tok.getString());
2652 if (!ActiveModule) {
2653 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2654 << (ActiveModule !=
nullptr);
2661 ActiveModule->InferExportWildcard =
true;
2663 Diags.Report(
Tok.getLocation(),
2664 diag::err_mmap_expected_export_wildcard);
2674 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2675 << (ActiveModule !=
nullptr);
2684 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2685 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2702 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2703 bool HadError =
false;
2711 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_attribute);
2720 = llvm::StringSwitch<AttributeKind>(
Tok.getString())
2721 .Case(
"exhaustive", AT_exhaustive)
2722 .Case(
"extern_c", AT_extern_c)
2723 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2724 .Case(
"system", AT_system)
2725 .Default(AT_unknown);
2726 switch (Attribute) {
2728 Diags.Report(
Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2733 Attrs.IsSystem =
true;
2737 Attrs.IsExternC =
true;
2741 Attrs.IsExhaustive =
true;
2744 case AT_no_undeclared_includes:
2745 Attrs.NoUndeclaredIncludes =
true;
2752 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rsquare);
2753 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2805 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2817 assert(Target &&
"Missing target information");
2818 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2819 = ParsedModuleMap.find(File);
2820 if (Known != ParsedModuleMap.end())
2821 return Known->second;
2825 auto FileCharacter =
2827 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2830 assert(Target &&
"Missing target information");
2831 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2833 return ParsedModuleMap[File] =
true;
2835 "invalid buffer offset");
2838 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2839 Buffer->getBufferStart(),
2840 Buffer->getBufferStart() + (Offset ? *
Offset : 0),
2841 Buffer->getBufferEnd());
2846 ParsedModuleMap[File] =
Result;
2849 auto Loc = SourceMgr.getDecomposedLoc(Parser.
getLocation());
2850 assert(Loc.first == ID &&
"stopped in a different file?");
2851 *Offset = Loc.second;
2855 for (
const auto &Cb : Callbacks)
2856 Cb->moduleMapFileRead(Start, *File, IsSystem);
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...
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.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup...
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.
The virtual file system interface.
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.
An input iterator over the recursive contents of a virtual path, similar to llvm::sys::fs::recursive_...
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.
Module * createGlobalModuleForInterfaceUnit(SourceLocation Loc)
Create a 'global module' for a C++ Modules TS module interface unit.
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
directory_iterator & increment(std::error_code &EC)
Equivalent to operator++, with an error code.
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++ Modules TS 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)
void setParent(Module *M)
Set the parent of this module.
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.
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
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.
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)
LLVM_READONLY bool isValidIdentifier(StringRef S)
Return true if this is a valid ASCII identifier.
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.
module_iterator module_begin() const
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.
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
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++ Modules TS 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.
This header is normally included in the module.
module_iterator module_end() const
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.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
static void diagnosePrivateModules(const ModuleMap &Map, DiagnosticsEngine &Diags, const Module *ActiveModule)
Private modules are canonicalized as Foo_Private.
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_].
Defines the virtual file system interface vfs::FileSystem.
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
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).
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
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.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
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.
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.
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap)
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