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;
58 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
59 if (PendingLinkAs != PendingLinkAsModule.end()) {
60 for (
auto &Name : PendingLinkAs->second) {
77 default: llvm_unreachable(
"unknown header role");
101 llvm_unreachable(
"unexpected header kind");
103 llvm_unreachable(
"unknown header kind");
107 ModuleMap::resolveExport(
Module *Mod,
109 bool Complain)
const {
111 if (Unresolved.
Id.empty()) {
112 assert(Unresolved.
Wildcard &&
"Invalid unresolved export");
117 Module *Context = resolveModuleId(Unresolved.
Id, Mod, Complain);
125 bool Complain)
const {
130 Diags.
Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
137 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
141 Diags.
Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
160 for (; Mod; Mod = Mod->
Parent) {
162 Paths.push_back(Mod->
Name);
169 for (
unsigned I = Paths.size() - 1; I != 0; --I)
170 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
183 (Header.
Size && File->getSize() != *Header.
Size) ||
184 (Header.
ModTime && File->getModificationTime() != *Header.
ModTime))
189 auto GetFrameworkFile = [&]() ->
const FileEntry * {
190 unsigned FullPathLength = FullPathName.size();
192 unsigned RelativePathLength = RelativePathName.size();
195 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
196 llvm::sys::path::append(FullPathName, RelativePathName);
197 if (
auto *File = GetFile(FullPathName))
207 RelativePathName.clear();
209 RelativePathName.resize(RelativePathLength);
210 FullPathName.resize(FullPathLength);
211 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
213 llvm::sys::path::append(FullPathName, RelativePathName);
214 return GetFile(FullPathName);
217 if (llvm::sys::path::is_absolute(Header.
FileName)) {
218 RelativePathName.clear();
224 return GetFrameworkFile();
227 llvm::sys::path::append(RelativePathName, Header.
FileName);
228 llvm::sys::path::append(FullPathName, RelativePathName);
229 auto *NormalHdrFile = GetFile(FullPathName);
231 if (M && !NormalHdrFile && Directory->getName().endswith(
".framework")) {
235 FullPathName.assign(Directory->getName());
236 RelativePathName.clear();
237 if (GetFrameworkFile()) {
239 diag::warn_mmap_incomplete_framework_module_declaration)
241 NeedsFramework =
true;
246 return NormalHdrFile;
249 void ModuleMap::resolveHeader(
Module *Mod,
251 bool &NeedsFramework) {
254 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
257 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
259 << UmbrellaMod->getFullModuleName();
288 bool ModuleMap::resolveAsBuiltinHeader(
291 llvm::sys::path::is_absolute(Header.
FileName) ||
293 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
301 llvm::sys::path::append(Path, BuiltinIncludeDir->
getName(), Header.
FileName);
315 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
316 HeaderInfo(HeaderInfo) {
317 MMapLangOpts.LineComment =
true;
321 for (
auto &M : Modules)
323 for (
auto *M : ShadowModules)
328 assert((!this->Target || this->Target == &Target) &&
329 "Improper target override");
330 this->Target = &Target;
344 Buffer.push_back(
'_');
345 Buffer.reserve(Buffer.size() + Name.size());
346 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
348 Buffer.push_back(Name[I]);
350 Buffer.push_back(
'_');
353 Name = StringRef(Buffer.data(), Buffer.size());
356 while (llvm::StringSwitch<bool>(Name)
357 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 358 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 359 #include "clang/Basic/TokenKinds.def" 361 if (Name.data() != Buffer.data())
362 Buffer.append(Name.begin(), Name.end());
363 Buffer.push_back(
'_');
364 Name = StringRef(Buffer.data(), Buffer.size());
374 return llvm::StringSwitch<bool>(FileName)
375 .Case(
"float.h",
true)
376 .Case(
"iso646.h",
true)
377 .Case(
"limits.h",
true)
378 .Case(
"stdalign.h",
true)
379 .Case(
"stdarg.h",
true)
380 .Case(
"stdatomic.h",
true)
381 .Case(
"stdbool.h",
true)
382 .Case(
"stddef.h",
true)
383 .Case(
"stdint.h",
true)
384 .Case(
"tgmath.h",
true)
385 .Case(
"unwind.h",
true)
389 ModuleMap::HeadersMap::iterator
390 ModuleMap::findKnownHeader(
const FileEntry *File) {
392 HeadersMap::iterator Known = Headers.find(File);
394 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
397 return Headers.find(File);
403 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
405 if (UmbrellaDirs.empty())
409 assert(Dir &&
"file in no directory");
420 auto KnownDir = UmbrellaDirs.find(Dir);
421 if (KnownDir != UmbrellaDirs.end())
424 IntermediateDirs.push_back(Dir);
427 DirName = llvm::sys::path::parent_path(DirName);
445 bool IsPrivate =
false;
449 for (
auto *Hs : HeaderList)
451 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
452 return H.Entry == IncFileEnt;
454 assert(IsPrivate &&
"inconsistent headers and roles");
465 bool RequestingModuleIsModuleInterface,
474 if (RequestingModule) {
479 bool Excluded =
false;
480 Module *Private =
nullptr;
481 Module *NotUsed =
nullptr;
483 HeadersMap::iterator Known = findKnownHeader(File);
484 if (Known != Headers.end()) {
494 if (RequestingModule && LangOpts.ModulesDeclUse &&
509 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
516 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
521 if (Excluded || isHeaderInUmbrellaDirs(File))
526 if (LangOpts.ModulesStrictDeclUse) {
527 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
529 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
533 diag::warn_non_modular_include_in_framework_module :
534 diag::warn_non_modular_include_in_module;
568 HeadersMap::iterator Known = findKnownHeader(File);
569 if (Known != Headers.end()) {
575 return MakeResult(H);
579 return MakeResult(Result);
582 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
586 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
587 assert(!Headers.count(File) &&
"already have a module for this header");
590 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
598 UmbrellaModule = UmbrellaModule->
Parent;
609 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
613 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()), NameBuf);
616 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
620 UmbrellaDirs[SkippedDirs[I-1]] =
Result;
631 llvm::sys::path::stem(File->
getName()), NameBuf);
634 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
645 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
646 UmbrellaDirs[SkippedDirs[I]] = Result;
650 Headers[File].push_back(Header);
660 auto It = Headers.find(File);
661 if (It == Headers.end())
672 const Module *RequestingModule)
const {
674 HeadersMap::const_iterator Known = Headers.find(Header);
675 if (Known != Headers.end()) {
677 I = Known->second.begin(),
678 E = Known->second.end();
681 if (I->isAvailable() &&
682 (!RequestingModule ||
683 I->getModule()->isSubModuleOf(RequestingModule))) {
699 StringRef DirName = Dir->
getName();
701 auto IsUnavailable = [&](
const Module *M) {
709 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
710 = UmbrellaDirs.find(Dir);
711 if (KnownDir != UmbrellaDirs.end()) {
712 Module *Found = KnownDir->second;
713 if (IsUnavailable(Found))
718 Module *UmbrellaModule = Found;
720 UmbrellaModule = UmbrellaModule->
Parent;
723 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
727 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()),
732 if (IsUnavailable(Found))
739 llvm::sys::path::stem(Header->
getName()),
746 return IsUnavailable(Found);
749 SkippedDirs.push_back(Dir);
752 DirName = llvm::sys::path::parent_path(DirName);
764 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
765 if (Known != Modules.end())
766 return Known->getValue();
773 for(; Context; Context = Context->
Parent) {
794 return std::make_pair(Sub,
false);
798 IsExplicit, NumCreatedModules++);
803 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
805 return std::make_pair(Result,
true);
809 assert(!PendingGlobalModule &&
"created multiple global modules");
810 PendingGlobalModule.reset(
811 new Module(
"<global>", Loc,
nullptr,
false,
812 true, NumCreatedModules++));
814 return PendingGlobalModule.get();
820 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
821 assert(!Modules[Name] &&
"redefining existing module");
824 new Module(Name, Loc,
nullptr,
false,
825 false, NumCreatedModules++);
827 Modules[Name] = SourceModule =
Result;
830 assert(GlobalModule == PendingGlobalModule.get() &&
831 "unexpected global module");
833 PendingGlobalModule.release();
838 assert(MainFile &&
"no input file for module interface");
848 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
850 "Can only infer linking for top-level frameworks");
853 LibName += FrameworkDir->
getName();
854 llvm::sys::path::append(LibName, Mod->
Name);
859 for (
const char *extension : {
"",
".tbd"}) {
860 llvm::sys::path::replace_extension(LibName, extension);
861 if (FileMgr.
getFile(LibName)) {
873 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
882 StringRef FrameworkDirName =
890 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
900 const FileEntry *ModuleMapFile =
nullptr;
903 bool canInfer =
false;
904 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
906 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
910 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
911 inferred = InferredDirectories.find(ParentDir);
912 if (inferred == InferredDirectories.end()) {
915 bool IsFrameworkDir = Parent.endswith(
".framework");
919 inferred = InferredDirectories.find(ParentDir);
922 if (inferred == InferredDirectories.end())
923 inferred = InferredDirectories.insert(
924 std::make_pair(ParentDir, InferredDirectory())).first;
927 if (inferred->second.InferModules) {
930 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
931 canInfer = std::find(inferred->second.ExcludedModules.begin(),
932 inferred->second.ExcludedModules.end(),
933 Name) == inferred->second.ExcludedModules.end();
935 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
936 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
937 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
938 Attrs.NoUndeclaredIncludes |=
939 inferred->second.Attrs.NoUndeclaredIncludes;
940 ModuleMapFile = inferred->second.ModuleMapFile;
954 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
965 NumCreatedModules++);
966 InferredModuleAllowedBy[
Result] = ModuleMapFile;
971 Modules[ModuleName] =
Result;
972 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
997 = StringRef(FrameworkDir->
getName());
998 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
999 llvm::sys::path::native(SubframeworksDirName);
1003 Dir != DirEnd && !EC; Dir.
increment(EC)) {
1004 if (!StringRef(Dir->getName()).endswith(
".framework"))
1014 bool FoundParent =
false;
1018 = llvm::sys::path::parent_path(SubframeworkDirName);
1019 if (SubframeworkDirName.empty())
1022 if (FileMgr.
getDirectory(SubframeworkDirName) == FrameworkDir) {
1032 inferFrameworkModule(SubframeworkDir, Attrs, Result);
1046 Module *ShadowingModule) {
1051 false, NumCreatedModules++);
1054 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1055 ShadowModules.push_back(Result);
1061 Twine NameAsWritten) {
1065 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
1068 for (
const auto &Cb : Callbacks)
1069 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1073 Twine NameAsWritten) {
1076 UmbrellaDirs[UmbrellaDir] = Mod;
1079 void ModuleMap::addUnresolvedHeader(
Module *Mod,
1081 bool &NeedsFramework) {
1084 if (resolveAsBuiltinHeader(Mod, Header)) {
1103 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1105 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1112 resolveHeader(Mod, Header, NeedsFramework);
1116 auto BySize = LazyHeadersBySize.find(File->
getSize());
1117 if (BySize != LazyHeadersBySize.end()) {
1118 for (
auto *M : BySize->second)
1120 LazyHeadersBySize.erase(BySize);
1124 if (ByModTime != LazyHeadersByModTime.end()) {
1125 for (
auto *M : ByModTime->second)
1127 LazyHeadersByModTime.erase(ByModTime);
1132 bool NeedsFramework =
false;
1136 const_cast<ModuleMap*
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1147 auto &HeaderList = Headers[Header.
Entry];
1148 for (
auto H : HeaderList)
1152 HeaderList.push_back(KH);
1155 bool isCompilingModuleHeader =
1157 if (!Imported || isCompilingModuleHeader) {
1161 isCompilingModuleHeader);
1165 for (
const auto &Cb : Callbacks)
1174 (void) Headers[Header.
Entry];
1190 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1191 return InferredModuleAllowedBy.find(M)->second;
1197 assert(M->
IsInferred &&
"module not inferred");
1198 InferredModuleAllowedBy[M] = ModMap;
1202 llvm::errs() <<
"Modules:";
1203 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1204 MEnd = Modules.end();
1206 M->getValue()->
print(llvm::errs(), 2);
1208 llvm::errs() <<
"Headers:";
1209 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1211 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1213 E = H->second.end();
1215 if (I != H->second.begin())
1216 llvm::errs() <<
",";
1217 llvm::errs() << I->getModule()->getFullModuleName();
1219 llvm::errs() <<
"\n";
1226 for (
auto &UE : Unresolved) {
1228 if (Export.getPointer() || Export.getInt())
1229 Mod->
Exports.push_back(Export);
1239 for (
auto &UDU : Unresolved) {
1240 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1252 for (
auto &UC : Unresolved) {
1253 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1255 Conflict.
Other = OtherMod;
1256 Conflict.
Message = UC.Message;
1317 StringData =
nullptr;
1332 : StringRef(StringData, StringLength);
1361 bool HadError =
false;
1365 llvm::BumpPtrAllocator StringData;
1371 Module *ActiveModule =
nullptr;
1381 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1392 bool parseModuleId(ModuleId &
Id);
1393 void parseModuleDecl();
1394 void parseExternModuleDecl();
1395 void parseRequiresDecl();
1398 void parseExportDecl();
1399 void parseExportAsDecl();
1400 void parseUseDecl();
1401 void parseLinkDecl();
1402 void parseConfigMacros();
1403 void parseConflict();
1404 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1413 using Attributes = ModuleMap::Attributes;
1415 bool parseOptionalAttributes(Attributes &Attrs);
1422 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1423 ModuleMapFile(ModuleMapFile), Directory(Directory),
1424 IsSystem(IsSystem) {
1443 L.LexFromRawLexer(LToken);
1446 case tok::raw_identifier: {
1448 Tok.StringData = RI.data();
1449 Tok.StringLength = RI.size();
1450 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1507 case tok::string_literal: {
1509 Diags.Report(LToken.
getLocation(), diag::err_invalid_string_udl);
1522 char *Saved = StringData.Allocate<
char>(Length + 1);
1528 Tok.StringData = Saved;
1529 Tok.StringLength = Length;
1533 case tok::numeric_constant: {
1536 SpellingBuffer.resize(LToken.
getLength() + 1);
1537 const char *Start = SpellingBuffer.data();
1541 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1542 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1561 auto NextIsIdent = [&](StringRef Str) ->
bool {
1562 L.LexFromRawLexer(LToken);
1566 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1567 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1575 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1584 unsigned braceDepth = 0;
1585 unsigned squareDepth = 0;
1592 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1599 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1613 if (squareDepth > 0)
1620 if (braceDepth == 0 && squareDepth == 0 &&
Tok.
is(K))
1636 bool ModuleMapParser::parseModuleId(ModuleId &
Id) {
1640 Id.push_back(std::make_pair(
Tok.getString(),
Tok.getLocation()));
1643 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module_name);
1673 AT_no_undeclared_includes
1682 void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1684 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1686 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1687 diag::note_mmap_rename_top_level_private_module);
1688 D << BadName << M->Name;
1692 for (
auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1693 auto const *M = E->getValue();
1694 if (M->Directory != ActiveModule->Directory)
1698 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1702 Canonical.append(
"_Private");
1705 if (ActiveModule->Parent && ActiveModule->Name ==
"Private" && !M->Parent &&
1706 M->Name == ActiveModule->Parent->Name) {
1707 Diags.Report(ActiveModule->DefinitionLoc,
1708 diag::warn_mmap_mismatched_private_submodule)
1713 FixItInitBegin = FrameworkLoc;
1715 FixItInitBegin = ExplicitLoc;
1717 if (FrameworkLoc.
isValid() || ActiveModule->Parent->IsFramework)
1718 FixedPrivModDecl.append(
"framework ");
1719 FixedPrivModDecl.append(
"module ");
1720 FixedPrivModDecl.append(Canonical);
1722 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1723 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1728 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1729 ActiveModule->Name != Canonical) {
1730 Diags.Report(ActiveModule->DefinitionLoc,
1731 diag::warn_mmap_mismatched_private_module_name)
1732 << ActiveModule->Name;
1733 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1757 void ModuleMapParser::parseModuleDecl() {
1761 parseExternModuleDecl();
1768 bool Explicit =
false;
1769 bool Framework =
false;
1773 ExplicitLoc = consumeToken();
1779 FrameworkLoc = consumeToken();
1785 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
1790 CurrModuleDeclLoc = consumeToken();
1795 return parseInferredModuleDecl(Framework, Explicit);
1799 if (parseModuleId(Id)) {
1805 if (Id.size() > 1) {
1806 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1807 <<
SourceRange(Id.front().second, Id.back().second);
1812 }
else if (Id.size() == 1 && Explicit) {
1814 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1820 Module *PreviousActiveModule = ActiveModule;
1821 if (Id.size() > 1) {
1824 ActiveModule =
nullptr;
1825 const Module *TopLevelModule =
nullptr;
1826 for (
unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1827 if (
Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1829 TopLevelModule = Next;
1830 ActiveModule = Next;
1835 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1837 << ActiveModule->getTopLevelModule()->getFullModuleName();
1839 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1845 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1846 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1847 "submodule defined in same file as 'module *' that allowed its " 1848 "top-level module");
1849 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1853 StringRef ModuleName = Id.back().first;
1858 if (parseOptionalAttributes(Attrs))
1863 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace)
1871 Module *ShadowingModule =
nullptr;
1872 if (
Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1880 bool ParsedAsMainInput =
1882 Map.LangOpts.CurrentModule == ModuleName &&
1883 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1884 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1885 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
1891 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
1892 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1898 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1899 ShadowingModule = Existing;
1902 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1904 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1917 if (ShadowingModule) {
1919 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
1922 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
1926 ActiveModule->DefinitionLoc = ModuleNameLoc;
1927 if (Attrs.IsSystem || IsSystem)
1928 ActiveModule->IsSystem =
true;
1929 if (Attrs.IsExternC)
1930 ActiveModule->IsExternC =
true;
1931 if (Attrs.NoUndeclaredIncludes ||
1932 (!ActiveModule->Parent && ModuleName ==
"Darwin"))
1933 ActiveModule->NoUndeclaredIncludes =
true;
1934 ActiveModule->Directory = Directory;
1936 StringRef MapFileName(ModuleMapFile->getName());
1937 if (MapFileName.endswith(
"module.private.modulemap") ||
1938 MapFileName.endswith(
"module_private.map")) {
1939 ActiveModule->ModuleMapIsPrivate =
true;
1946 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1947 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1948 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1950 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1952 ActiveModule->ModuleMapIsPrivate)
1953 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
1964 parseConfigMacros();
1983 parseExportAsDecl();
1991 parseRequiresDecl();
2003 parseUmbrellaDirDecl(UmbrellaLoc);
2024 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_member);
2033 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2034 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2040 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2041 ActiveModule->LinkLibraries.empty()) {
2047 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
2048 ActiveModule->Parent) {
2049 ActiveModule->getTopLevelModule()->markUnavailable();
2050 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2051 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2055 ActiveModule = PreviousActiveModule;
2062 void ModuleMapParser::parseExternModuleDecl() {
2068 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2077 if (parseModuleId(Id)) {
2084 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2088 std::string FileName =
Tok.getString();
2091 StringRef FileNameRef = FileName;
2093 if (llvm::sys::path::is_relative(FileNameRef)) {
2094 ModuleMapFileName += Directory->getName();
2095 llvm::sys::path::append(ModuleMapFileName, FileName);
2096 FileNameRef = ModuleMapFileName;
2098 if (
const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
2099 Map.parseModuleMapFile(
2101 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2104 FileID(),
nullptr, ExternLoc);
2123 bool &IsRequiresExcludedHack) {
2124 if (Feature ==
"excluded" &&
2127 IsRequiresExcludedHack =
true;
2129 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2147 void ModuleMapParser::parseRequiresDecl() {
2155 bool RequiredState =
true;
2157 RequiredState =
false;
2162 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_feature);
2168 std::string Feature =
Tok.getString();
2171 bool IsRequiresExcludedHack =
false;
2172 bool ShouldAddRequirement =
2175 if (IsRequiresExcludedHack)
2176 UsesRequiresExcludedHack.insert(ActiveModule);
2178 if (ShouldAddRequirement) {
2180 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2209 LeadingToken =
Tok.Kind;
2217 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2225 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2236 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2247 : Map.headerRoleToKind(Role));
2250 if (Header.
IsUmbrella && ActiveModule->Umbrella) {
2251 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
2252 << ActiveModule->getFullModuleName();
2263 enum Attribute { Size, ModTime, Unknown };
2264 StringRef Str =
Tok.getString();
2266 switch (llvm::StringSwitch<Attribute>(Str)
2268 .Case(
"mtime", ModTime)
2272 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2274 Diags.Report(
Tok.getLocation(),
2275 diag::err_mmap_invalid_header_attribute_value) << Str;
2279 Header.
Size =
Tok.getInteger();
2285 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2287 Diags.Report(
Tok.getLocation(),
2288 diag::err_mmap_invalid_header_attribute_value) << Str;
2297 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2306 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2307 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2312 bool NeedsFramework =
false;
2313 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2315 if (NeedsFramework && ActiveModule)
2316 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2317 << ActiveModule->getFullModuleName()
2330 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2333 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2339 std::string DirName =
Tok.getString();
2343 if (ActiveModule->Umbrella) {
2344 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2345 << ActiveModule->getFullModuleName();
2352 if (llvm::sys::path::is_absolute(DirName))
2353 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2356 PathName = Directory->getName();
2357 llvm::sys::path::append(PathName, DirName);
2358 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2362 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2367 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2374 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2376 I != E && !EC; I.increment(EC)) {
2378 SourceMgr.getFileManager().getFile(I->getName())) {
2381 Headers.push_back(std::move(Header));
2388 for (
auto &Header : Headers)
2393 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2394 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2395 << OwningModule->getFullModuleName();
2401 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2413 void ModuleMapParser::parseExportDecl() {
2419 bool Wildcard =
false;
2423 ParsedModuleId.push_back(std::make_pair(
Tok.getString(),
2424 Tok.getLocation()));
2441 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2447 ExportLoc, ParsedModuleId, Wildcard
2449 ActiveModule->UnresolvedExports.push_back(Unresolved);
2456 void ModuleMapParser::parseExportAsDecl() {
2461 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2466 if (ActiveModule->Parent) {
2467 Diags.Report(
Tok.getLocation(), diag::err_mmap_submodule_export_as);
2472 if (!ActiveModule->ExportAsModule.empty()) {
2473 if (ActiveModule->ExportAsModule ==
Tok.getString()) {
2474 Diags.Report(
Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2475 << ActiveModule->Name <<
Tok.getString();
2477 Diags.Report(
Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2478 << ActiveModule->Name << ActiveModule->ExportAsModule
2483 ActiveModule->ExportAsModule =
Tok.getString();
2484 Map.addLinkAsDependency(ActiveModule);
2493 void ModuleMapParser::parseUseDecl() {
2495 auto KWLoc = consumeToken();
2498 parseModuleId(ParsedModuleId);
2500 if (ActiveModule->Parent)
2501 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2503 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2510 void ModuleMapParser::parseLinkDecl() {
2515 bool IsFramework =
false;
2523 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_library_name)
2529 std::string LibraryName =
Tok.getString();
2542 void ModuleMapParser::parseConfigMacros() {
2547 if (ActiveModule->Parent) {
2548 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2553 if (parseOptionalAttributes(Attrs))
2556 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2557 ActiveModule->ConfigMacrosExhaustive =
true;
2566 if (!ActiveModule->Parent) {
2567 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2580 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_config_macro);
2585 if (!ActiveModule->Parent) {
2586 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2596 llvm::raw_string_ostream OS(result);
2598 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
2612 void ModuleMapParser::parseConflict() {
2618 if (parseModuleId(Conflict.
Id))
2623 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2631 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2639 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2651 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2654 bool Failed =
false;
2657 if (!ActiveModule && !Framework) {
2658 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2664 if (!Failed && ActiveModule->IsAvailable &&
2665 !ActiveModule->getUmbrellaDir()) {
2666 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2671 if (!Failed && ActiveModule->InferSubmodules) {
2672 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2673 if (ActiveModule->InferredSubmoduleLoc.isValid())
2674 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2675 diag::note_mmap_prev_definition);
2681 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2684 }
else if (Explicit) {
2685 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2703 if (parseOptionalAttributes(Attrs))
2708 ActiveModule->InferSubmodules =
true;
2709 ActiveModule->InferredSubmoduleLoc = StarLoc;
2710 ActiveModule->InferExplicitSubmodules = Explicit;
2713 Map.InferredDirectories[Directory].InferModules =
true;
2714 Map.InferredDirectories[Directory].Attrs = Attrs;
2715 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2721 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2738 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2739 << (ActiveModule !=
nullptr);
2747 Diags.Report(
Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2751 Map.InferredDirectories[Directory].ExcludedModules
2752 .push_back(
Tok.getString());
2757 if (!ActiveModule) {
2758 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2759 << (ActiveModule !=
nullptr);
2766 ActiveModule->InferExportWildcard =
true;
2768 Diags.Report(
Tok.getLocation(),
2769 diag::err_mmap_expected_export_wildcard);
2779 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2780 << (ActiveModule !=
nullptr);
2789 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2790 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2807 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2808 bool HadError =
false;
2816 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_attribute);
2825 = llvm::StringSwitch<AttributeKind>(
Tok.getString())
2826 .Case(
"exhaustive", AT_exhaustive)
2827 .Case(
"extern_c", AT_extern_c)
2828 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2829 .Case(
"system", AT_system)
2830 .Default(AT_unknown);
2831 switch (Attribute) {
2833 Diags.Report(
Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2838 Attrs.IsSystem =
true;
2842 Attrs.IsExternC =
true;
2846 Attrs.IsExhaustive =
true;
2849 case AT_no_undeclared_includes:
2850 Attrs.NoUndeclaredIncludes =
true;
2857 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rsquare);
2858 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2910 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2922 assert(Target &&
"Missing target information");
2923 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2924 = ParsedModuleMap.find(File);
2925 if (Known != ParsedModuleMap.end())
2926 return Known->second;
2930 auto FileCharacter =
2932 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2935 assert(Target &&
"Missing target information");
2936 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2938 return ParsedModuleMap[File] =
true;
2940 "invalid buffer offset");
2943 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2944 Buffer->getBufferStart(),
2945 Buffer->getBufferStart() + (Offset ? *
Offset : 0),
2946 Buffer->getBufferEnd());
2951 ParsedModuleMap[File] =
Result;
2954 auto Loc = SourceMgr.getDecomposedLoc(Parser.
getLocation());
2955 assert(Loc.first == ID &&
"stopped in a different file?");
2956 *Offset = Loc.second;
2960 for (
const auto &Cb : Callbacks)
2961 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...
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...
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
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
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.
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.
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.
__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.
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_].
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
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).
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.
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.
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