31 #include "llvm/ADT/DenseMap.h" 32 #include "llvm/ADT/None.h" 33 #include "llvm/ADT/STLExtras.h" 34 #include "llvm/ADT/SmallPtrSet.h" 35 #include "llvm/ADT/SmallString.h" 36 #include "llvm/ADT/SmallVector.h" 37 #include "llvm/ADT/StringMap.h" 38 #include "llvm/ADT/StringRef.h" 39 #include "llvm/ADT/StringSwitch.h" 40 #include "llvm/Support/Allocator.h" 41 #include "llvm/Support/Compiler.h" 42 #include "llvm/Support/ErrorHandling.h" 43 #include "llvm/Support/MemoryBuffer.h" 44 #include "llvm/Support/Path.h" 45 #include "llvm/Support/VirtualFileSystem.h" 46 #include "llvm/Support/raw_ostream.h" 52 #include <system_error> 55 using namespace clang;
57 void ModuleMapCallbacks::anchor() {}
60 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
61 if (PendingLinkAs != PendingLinkAsModule.end()) {
62 for (
auto &Name : PendingLinkAs->second) {
63 auto *M = findModule(Name.getKey());
65 M->UseExportAsModuleLinkName =
true;
79 default: llvm_unreachable(
"unknown header role");
86 case PrivateHeader | TextualHeader:
103 llvm_unreachable(
"unexpected header kind");
105 llvm_unreachable(
"unknown header kind");
109 ModuleMap::resolveExport(
Module *Mod,
111 bool Complain)
const {
113 if (Unresolved.
Id.empty()) {
114 assert(Unresolved.
Wildcard &&
"Invalid unresolved export");
119 Module *Context = resolveModuleId(Unresolved.
Id, Mod, Complain);
127 bool Complain)
const {
129 Module *Context = lookupModuleUnqualified(
Id[0].first, Mod);
132 Diags.Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
139 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
140 Module *Sub = lookupModuleQualified(
Id[I].first, Context);
143 Diags.Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
162 for (; Mod; Mod = Mod->
Parent) {
164 Paths.push_back(Mod->
Name);
171 for (
unsigned I = Paths.size() - 1; I != 0; --I)
172 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
183 auto *File = SourceMgr.getFileManager().getFile(
Filename);
185 (Header.
Size && File->getSize() != *Header.
Size) ||
186 (Header.
ModTime && File->getModificationTime() != *Header.
ModTime))
191 auto GetFrameworkFile = [&]() ->
const FileEntry * {
192 unsigned FullPathLength = FullPathName.size();
194 unsigned RelativePathLength = RelativePathName.size();
197 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
198 llvm::sys::path::append(FullPathName, RelativePathName);
199 if (
auto *File = GetFile(FullPathName))
209 RelativePathName.clear();
211 RelativePathName.resize(RelativePathLength);
212 FullPathName.resize(FullPathLength);
213 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
215 llvm::sys::path::append(FullPathName, RelativePathName);
216 return GetFile(FullPathName);
219 if (llvm::sys::path::is_absolute(Header.
FileName)) {
220 RelativePathName.clear();
226 return GetFrameworkFile();
229 llvm::sys::path::append(RelativePathName, Header.
FileName);
230 llvm::sys::path::append(FullPathName, RelativePathName);
231 auto *NormalHdrFile = GetFile(FullPathName);
233 if (M && !NormalHdrFile && Directory->getName().endswith(
".framework")) {
237 FullPathName.assign(Directory->getName());
238 RelativePathName.clear();
239 if (GetFrameworkFile()) {
241 diag::warn_mmap_incomplete_framework_module_declaration)
243 NeedsFramework =
true;
248 return NormalHdrFile;
251 void ModuleMap::resolveHeader(
Module *Mod,
253 bool &NeedsFramework) {
256 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
259 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
260 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
261 << UmbrellaMod->getFullModuleName();
264 setUmbrellaHeader(Mod, File, RelativePathName.str());
268 excludeHeader(Mod, H);
270 addHeader(Mod, H, headerKindToRole(Header.
Kind));
290 bool ModuleMap::resolveAsBuiltinHeader(
293 llvm::sys::path::is_absolute(Header.
FileName) ||
295 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
303 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.
FileName);
304 auto *File = SourceMgr.getFileManager().getFile(Path);
308 auto Role = headerKindToRole(Header.
Kind);
310 addHeader(Mod, H, Role);
317 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
318 HeaderInfo(HeaderInfo) {
319 MMapLangOpts.LineComment =
true;
323 for (
auto &M : Modules)
325 for (
auto *M : ShadowModules)
330 assert((!this->Target || this->Target == &Target) &&
331 "Improper target override");
332 this->Target = &Target;
346 Buffer.push_back(
'_');
347 Buffer.reserve(Buffer.size() + Name.size());
348 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
350 Buffer.push_back(Name[I]);
352 Buffer.push_back(
'_');
355 Name = StringRef(Buffer.data(), Buffer.size());
358 while (llvm::StringSwitch<bool>(Name)
359 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 360 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 361 #include "clang/Basic/TokenKinds.def" 363 if (Name.data() != Buffer.data())
364 Buffer.append(Name.begin(), Name.end());
365 Buffer.push_back(
'_');
366 Name = StringRef(Buffer.data(), Buffer.size());
376 return llvm::StringSwitch<bool>(FileName)
377 .Case(
"float.h",
true)
378 .Case(
"iso646.h",
true)
379 .Case(
"limits.h",
true)
380 .Case(
"stdalign.h",
true)
381 .Case(
"stdarg.h",
true)
382 .Case(
"stdatomic.h",
true)
383 .Case(
"stdbool.h",
true)
384 .Case(
"stddef.h",
true)
385 .Case(
"stdint.h",
true)
386 .Case(
"tgmath.h",
true)
387 .Case(
"unwind.h",
true)
391 ModuleMap::HeadersMap::iterator
392 ModuleMap::findKnownHeader(
const FileEntry *File) {
394 HeadersMap::iterator Known = Headers.find(File);
396 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
399 return Headers.find(File);
405 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
407 if (UmbrellaDirs.empty())
411 assert(Dir &&
"file in no directory");
422 auto KnownDir = UmbrellaDirs.find(Dir);
423 if (KnownDir != UmbrellaDirs.end())
426 IntermediateDirs.push_back(Dir);
429 DirName = llvm::sys::path::parent_path(DirName);
447 bool IsPrivate =
false;
451 for (
auto *Hs : HeaderList)
453 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
454 return H.Entry == IncFileEnt;
456 assert(IsPrivate &&
"inconsistent headers and roles");
467 bool RequestingModuleIsModuleInterface,
476 if (RequestingModule) {
481 bool Excluded =
false;
482 Module *Private =
nullptr;
483 Module *NotUsed =
nullptr;
485 HeadersMap::iterator Known = findKnownHeader(File);
486 if (Known != Headers.end()) {
496 if (RequestingModule && LangOpts.ModulesDeclUse &&
511 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
518 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
523 if (Excluded || isHeaderInUmbrellaDirs(File))
528 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
529 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
531 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
535 diag::warn_non_modular_include_in_framework_module :
536 diag::warn_non_modular_include_in_module;
570 HeadersMap::iterator Known = findKnownHeader(File);
571 if (Known != Headers.end()) {
577 return MakeResult(H);
581 return MakeResult(Result);
584 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
588 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
589 assert(!Headers.count(File) &&
"already have a module for this header");
592 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
600 UmbrellaModule = UmbrellaModule->
Parent;
611 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
615 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()), NameBuf);
618 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
622 UmbrellaDirs[SkippedDirs[I-1]] =
Result;
633 llvm::sys::path::stem(File->
getName()), NameBuf);
636 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
647 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
648 UmbrellaDirs[SkippedDirs[I]] = Result;
652 Headers[File].push_back(Header);
662 auto It = Headers.find(File);
663 if (It == Headers.end())
674 const Module *RequestingModule)
const {
676 HeadersMap::const_iterator Known = Headers.find(Header);
677 if (Known != Headers.end()) {
679 I = Known->second.begin(),
680 E = Known->second.end();
683 if (I->isAvailable() &&
684 (!RequestingModule ||
701 StringRef DirName = Dir->
getName();
703 auto IsUnavailable = [&](
const Module *M) {
711 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
712 = UmbrellaDirs.find(Dir);
713 if (KnownDir != UmbrellaDirs.end()) {
714 Module *Found = KnownDir->second;
715 if (IsUnavailable(Found))
720 Module *UmbrellaModule = Found;
722 UmbrellaModule = UmbrellaModule->
Parent;
725 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
729 llvm::sys::path::stem(SkippedDirs[I-1]->
getName()),
734 if (IsUnavailable(Found))
741 llvm::sys::path::stem(Header->
getName()),
748 return IsUnavailable(Found);
751 SkippedDirs.push_back(Dir);
754 DirName = llvm::sys::path::parent_path(DirName);
766 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
767 if (Known != Modules.end())
768 return Known->getValue();
775 for(; Context; Context = Context->
Parent) {
796 return std::make_pair(Sub,
false);
800 IsExplicit, NumCreatedModules++);
805 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
807 return std::make_pair(Result,
true);
811 PendingSubmodules.emplace_back(
812 new Module(
"<global>", Loc,
nullptr,
false,
813 true, NumCreatedModules++));
815 return PendingSubmodules.back().get();
821 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
822 assert(!Modules[Name] &&
"redefining existing module");
825 new Module(Name, Loc,
nullptr,
false,
826 false, NumCreatedModules++);
828 Modules[Name] = SourceModule =
Result;
831 for (
auto &Submodule : PendingSubmodules) {
832 Submodule->setParent(
Result);
835 PendingSubmodules.clear();
840 assert(MainFile &&
"no input file for module interface");
848 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
849 assert(!Modules[Name] &&
"redefining existing module");
853 false, NumCreatedModules++);
855 Modules[Name] = SourceModule =
Result;
860 true, NumCreatedModules++);
873 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
875 "Can only infer linking for top-level frameworks");
878 LibName += FrameworkDir->
getName();
879 llvm::sys::path::append(LibName, Mod->
Name);
884 for (
const char *extension : {
"",
".tbd"}) {
885 llvm::sys::path::replace_extension(LibName, extension);
886 if (FileMgr.
getFile(LibName)) {
898 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
907 StringRef FrameworkDirName =
915 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
925 const FileEntry *ModuleMapFile =
nullptr;
928 bool canInfer =
false;
929 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
931 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
935 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
936 inferred = InferredDirectories.find(ParentDir);
937 if (inferred == InferredDirectories.end()) {
940 bool IsFrameworkDir = Parent.endswith(
".framework");
944 inferred = InferredDirectories.find(ParentDir);
947 if (inferred == InferredDirectories.end())
948 inferred = InferredDirectories.insert(
949 std::make_pair(ParentDir, InferredDirectory())).first;
952 if (inferred->second.InferModules) {
955 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
956 canInfer = std::find(inferred->second.ExcludedModules.begin(),
957 inferred->second.ExcludedModules.end(),
958 Name) == inferred->second.ExcludedModules.end();
960 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
961 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
962 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
963 Attrs.NoUndeclaredIncludes |=
964 inferred->second.Attrs.NoUndeclaredIncludes;
965 ModuleMapFile = inferred->second.ModuleMapFile;
979 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
990 NumCreatedModules++);
991 InferredModuleAllowedBy[
Result] = ModuleMapFile;
996 Modules[ModuleName] =
Result;
997 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1000 Result->
IsSystem |= Attrs.IsSystem;
1022 = StringRef(FrameworkDir->
getName());
1023 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1024 llvm::sys::path::native(SubframeworksDirName);
1026 for (llvm::vfs::directory_iterator
1027 Dir = FS.dir_begin(SubframeworksDirName, EC),
1029 Dir != DirEnd && !EC; Dir.increment(EC)) {
1030 if (!StringRef(Dir->path()).endswith(
".framework"))
1040 bool FoundParent =
false;
1044 = llvm::sys::path::parent_path(SubframeworkDirName);
1045 if (SubframeworkDirName.empty())
1048 if (FileMgr.
getDirectory(SubframeworkDirName) == FrameworkDir) {
1058 inferFrameworkModule(SubframeworkDir, Attrs, Result);
1072 Module *ShadowingModule) {
1077 false, NumCreatedModules++);
1080 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1081 ShadowModules.push_back(Result);
1087 Twine NameAsWritten) {
1091 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
1094 for (
const auto &Cb : Callbacks)
1095 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1099 Twine NameAsWritten) {
1102 UmbrellaDirs[UmbrellaDir] = Mod;
1105 void ModuleMap::addUnresolvedHeader(
Module *Mod,
1107 bool &NeedsFramework) {
1110 if (resolveAsBuiltinHeader(Mod, Header)) {
1129 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1131 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1138 resolveHeader(Mod, Header, NeedsFramework);
1142 auto BySize = LazyHeadersBySize.find(File->
getSize());
1143 if (BySize != LazyHeadersBySize.end()) {
1144 for (
auto *M : BySize->second)
1146 LazyHeadersBySize.erase(BySize);
1150 if (ByModTime != LazyHeadersByModTime.end()) {
1151 for (
auto *M : ByModTime->second)
1153 LazyHeadersByModTime.erase(ByModTime);
1158 bool NeedsFramework =
false;
1162 const_cast<ModuleMap*
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1173 auto &HeaderList = Headers[Header.
Entry];
1174 for (
auto H : HeaderList)
1178 HeaderList.push_back(KH);
1181 bool isCompilingModuleHeader =
1183 if (!Imported || isCompilingModuleHeader) {
1187 isCompilingModuleHeader);
1191 for (
const auto &Cb : Callbacks)
1200 (void) Headers[Header.
Entry];
1216 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1217 return InferredModuleAllowedBy.find(M)->second;
1223 assert(M->
IsInferred &&
"module not inferred");
1224 InferredModuleAllowedBy[M] = ModMap;
1228 llvm::errs() <<
"Modules:";
1229 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1230 MEnd = Modules.end();
1232 M->getValue()->
print(llvm::errs(), 2);
1234 llvm::errs() <<
"Headers:";
1235 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1237 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1239 E = H->second.end();
1241 if (I != H->second.begin())
1242 llvm::errs() <<
",";
1243 llvm::errs() << I->getModule()->getFullModuleName();
1245 llvm::errs() <<
"\n";
1252 for (
auto &UE : Unresolved) {
1254 if (Export.getPointer() || Export.getInt())
1255 Mod->
Exports.push_back(Export);
1265 for (
auto &UDU : Unresolved) {
1266 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1278 for (
auto &UC : Unresolved) {
1279 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1281 Conflict.
Other = OtherMod;
1282 Conflict.
Message = UC.Message;
1343 StringData =
nullptr;
1358 : StringRef(StringData, StringLength);
1387 bool HadError =
false;
1391 llvm::BumpPtrAllocator StringData;
1397 Module *ActiveModule =
nullptr;
1407 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1418 bool parseModuleId(ModuleId &
Id);
1419 void parseModuleDecl();
1420 void parseExternModuleDecl();
1421 void parseRequiresDecl();
1424 void parseExportDecl();
1425 void parseExportAsDecl();
1426 void parseUseDecl();
1427 void parseLinkDecl();
1428 void parseConfigMacros();
1429 void parseConflict();
1430 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1439 using Attributes = ModuleMap::Attributes;
1441 bool parseOptionalAttributes(Attributes &Attrs);
1448 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1449 ModuleMapFile(ModuleMapFile), Directory(Directory),
1450 IsSystem(IsSystem) {
1469 L.LexFromRawLexer(LToken);
1472 case tok::raw_identifier: {
1474 Tok.StringData = RI.data();
1475 Tok.StringLength = RI.size();
1476 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1533 case tok::string_literal: {
1535 Diags.Report(LToken.
getLocation(), diag::err_invalid_string_udl);
1548 char *Saved = StringData.Allocate<
char>(Length + 1);
1554 Tok.StringData = Saved;
1555 Tok.StringLength = Length;
1559 case tok::numeric_constant: {
1562 SpellingBuffer.resize(LToken.
getLength() + 1);
1563 const char *Start = SpellingBuffer.data();
1567 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1568 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1587 auto NextIsIdent = [&](StringRef Str) ->
bool {
1588 L.LexFromRawLexer(LToken);
1592 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1593 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1601 Diags.Report(
Tok.getLocation(), diag::err_mmap_unknown_token);
1610 unsigned braceDepth = 0;
1611 unsigned squareDepth = 0;
1618 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1625 if (
Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1639 if (squareDepth > 0)
1646 if (braceDepth == 0 && squareDepth == 0 &&
Tok.
is(K))
1662 bool ModuleMapParser::parseModuleId(ModuleId &
Id) {
1666 Id.push_back(std::make_pair(
Tok.getString(),
Tok.getLocation()));
1669 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module_name);
1699 AT_no_undeclared_includes
1708 void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1710 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1712 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1713 diag::note_mmap_rename_top_level_private_module);
1714 D << BadName << M->Name;
1718 for (
auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1719 auto const *M = E->getValue();
1720 if (M->Directory != ActiveModule->Directory)
1724 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1728 Canonical.append(
"_Private");
1731 if (ActiveModule->Parent && ActiveModule->Name ==
"Private" && !M->Parent &&
1732 M->Name == ActiveModule->Parent->Name) {
1733 Diags.Report(ActiveModule->DefinitionLoc,
1734 diag::warn_mmap_mismatched_private_submodule)
1739 FixItInitBegin = FrameworkLoc;
1741 FixItInitBegin = ExplicitLoc;
1743 if (FrameworkLoc.
isValid() || ActiveModule->Parent->IsFramework)
1744 FixedPrivModDecl.append(
"framework ");
1745 FixedPrivModDecl.append(
"module ");
1746 FixedPrivModDecl.append(Canonical);
1748 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1749 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1754 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1755 ActiveModule->Name != Canonical) {
1756 Diags.Report(ActiveModule->DefinitionLoc,
1757 diag::warn_mmap_mismatched_private_module_name)
1758 << ActiveModule->Name;
1759 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1783 void ModuleMapParser::parseModuleDecl() {
1787 parseExternModuleDecl();
1794 bool Explicit =
false;
1795 bool Framework =
false;
1799 ExplicitLoc = consumeToken();
1805 FrameworkLoc = consumeToken();
1811 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
1816 CurrModuleDeclLoc = consumeToken();
1821 return parseInferredModuleDecl(Framework, Explicit);
1825 if (parseModuleId(Id)) {
1831 if (Id.size() > 1) {
1832 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1833 <<
SourceRange(Id.front().second, Id.back().second);
1838 }
else if (Id.size() == 1 && Explicit) {
1840 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1846 Module *PreviousActiveModule = ActiveModule;
1847 if (Id.size() > 1) {
1850 ActiveModule =
nullptr;
1851 const Module *TopLevelModule =
nullptr;
1852 for (
unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1853 if (
Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1855 TopLevelModule = Next;
1856 ActiveModule = Next;
1861 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1863 << ActiveModule->getTopLevelModule()->getFullModuleName();
1865 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1871 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1872 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1873 "submodule defined in same file as 'module *' that allowed its " 1874 "top-level module");
1875 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1879 StringRef ModuleName = Id.back().first;
1884 if (parseOptionalAttributes(Attrs))
1889 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace)
1897 Module *ShadowingModule =
nullptr;
1898 if (
Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1906 bool ParsedAsMainInput =
1908 Map.LangOpts.CurrentModule == ModuleName &&
1909 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1910 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1911 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
1917 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
1918 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1924 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1925 ShadowingModule = Existing;
1928 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1930 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1943 if (ShadowingModule) {
1945 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
1948 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
1952 ActiveModule->DefinitionLoc = ModuleNameLoc;
1953 if (Attrs.IsSystem || IsSystem)
1954 ActiveModule->IsSystem =
true;
1955 if (Attrs.IsExternC)
1956 ActiveModule->IsExternC =
true;
1957 if (Attrs.NoUndeclaredIncludes ||
1958 (!ActiveModule->Parent && ModuleName ==
"Darwin"))
1959 ActiveModule->NoUndeclaredIncludes =
true;
1960 ActiveModule->Directory = Directory;
1962 StringRef MapFileName(ModuleMapFile->getName());
1963 if (MapFileName.endswith(
"module.private.modulemap") ||
1964 MapFileName.endswith(
"module_private.map")) {
1965 ActiveModule->ModuleMapIsPrivate =
true;
1972 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1973 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1974 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1976 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1978 ActiveModule->ModuleMapIsPrivate)
1979 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
1990 parseConfigMacros();
2009 parseExportAsDecl();
2017 parseRequiresDecl();
2029 parseUmbrellaDirDecl(UmbrellaLoc);
2050 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_member);
2059 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2060 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2066 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2067 ActiveModule->LinkLibraries.empty()) {
2073 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
2074 ActiveModule->Parent) {
2075 ActiveModule->getTopLevelModule()->markUnavailable();
2076 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2077 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2081 ActiveModule = PreviousActiveModule;
2088 void ModuleMapParser::parseExternModuleDecl() {
2094 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2103 if (parseModuleId(Id)) {
2110 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2114 std::string FileName =
Tok.getString();
2117 StringRef FileNameRef = FileName;
2119 if (llvm::sys::path::is_relative(FileNameRef)) {
2120 ModuleMapFileName += Directory->getName();
2121 llvm::sys::path::append(ModuleMapFileName, FileName);
2122 FileNameRef = ModuleMapFileName;
2124 if (
const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
2125 Map.parseModuleMapFile(
2127 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2130 FileID(),
nullptr, ExternLoc);
2149 bool &IsRequiresExcludedHack) {
2150 if (Feature ==
"excluded" &&
2153 IsRequiresExcludedHack =
true;
2155 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2173 void ModuleMapParser::parseRequiresDecl() {
2181 bool RequiredState =
true;
2183 RequiredState =
false;
2188 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_feature);
2194 std::string Feature =
Tok.getString();
2197 bool IsRequiresExcludedHack =
false;
2198 bool ShouldAddRequirement =
2201 if (IsRequiresExcludedHack)
2202 UsesRequiresExcludedHack.insert(ActiveModule);
2204 if (ShouldAddRequirement) {
2206 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2235 LeadingToken =
Tok.Kind;
2243 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2251 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2262 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2273 : Map.headerRoleToKind(Role));
2276 if (Header.
IsUmbrella && ActiveModule->Umbrella) {
2277 Diags.Report(Header.
FileNameLoc, diag::err_mmap_umbrella_clash)
2278 << ActiveModule->getFullModuleName();
2289 enum Attribute { Size, ModTime, Unknown };
2290 StringRef Str =
Tok.getString();
2292 switch (llvm::StringSwitch<Attribute>(Str)
2294 .Case(
"mtime", ModTime)
2298 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2300 Diags.Report(
Tok.getLocation(),
2301 diag::err_mmap_invalid_header_attribute_value) << Str;
2305 Header.
Size =
Tok.getInteger();
2311 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2313 Diags.Report(
Tok.getLocation(),
2314 diag::err_mmap_invalid_header_attribute_value) << Str;
2323 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2332 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2333 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2338 bool NeedsFramework =
false;
2339 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2341 if (NeedsFramework && ActiveModule)
2342 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2343 << ActiveModule->getFullModuleName()
2356 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2359 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_header)
2365 std::string DirName =
Tok.getString();
2369 if (ActiveModule->Umbrella) {
2370 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2371 << ActiveModule->getFullModuleName();
2378 if (llvm::sys::path::is_absolute(DirName))
2379 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2382 PathName = Directory->getName();
2383 llvm::sys::path::append(PathName, DirName);
2384 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2388 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2393 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2400 llvm::vfs::FileSystem &FS =
2401 *SourceMgr.getFileManager().getVirtualFileSystem();
2402 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2403 I != E && !EC; I.increment(EC)) {
2404 if (
const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
2407 Headers.push_back(std::move(Header));
2414 for (
auto &Header : Headers)
2419 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2420 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2421 << OwningModule->getFullModuleName();
2427 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2439 void ModuleMapParser::parseExportDecl() {
2445 bool Wildcard =
false;
2449 ParsedModuleId.push_back(std::make_pair(
Tok.getString(),
2450 Tok.getLocation()));
2467 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2473 ExportLoc, ParsedModuleId, Wildcard
2475 ActiveModule->UnresolvedExports.push_back(Unresolved);
2482 void ModuleMapParser::parseExportAsDecl() {
2487 Diags.Report(
Tok.getLocation(), diag::err_mmap_module_id);
2492 if (ActiveModule->Parent) {
2493 Diags.Report(
Tok.getLocation(), diag::err_mmap_submodule_export_as);
2498 if (!ActiveModule->ExportAsModule.empty()) {
2499 if (ActiveModule->ExportAsModule ==
Tok.getString()) {
2500 Diags.Report(
Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2501 << ActiveModule->Name <<
Tok.getString();
2503 Diags.Report(
Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2504 << ActiveModule->Name << ActiveModule->ExportAsModule
2509 ActiveModule->ExportAsModule =
Tok.getString();
2510 Map.addLinkAsDependency(ActiveModule);
2519 void ModuleMapParser::parseUseDecl() {
2521 auto KWLoc = consumeToken();
2524 parseModuleId(ParsedModuleId);
2526 if (ActiveModule->Parent)
2527 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2529 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2536 void ModuleMapParser::parseLinkDecl() {
2541 bool IsFramework =
false;
2549 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_library_name)
2555 std::string LibraryName =
Tok.getString();
2568 void ModuleMapParser::parseConfigMacros() {
2573 if (ActiveModule->Parent) {
2574 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2579 if (parseOptionalAttributes(Attrs))
2582 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2583 ActiveModule->ConfigMacrosExhaustive =
true;
2592 if (!ActiveModule->Parent) {
2593 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2606 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_config_macro);
2611 if (!ActiveModule->Parent) {
2612 ActiveModule->ConfigMacros.push_back(
Tok.getString().str());
2622 llvm::raw_string_ostream OS(result);
2624 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
2638 void ModuleMapParser::parseConflict() {
2644 if (parseModuleId(Conflict.
Id))
2649 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2657 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2665 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2677 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2680 bool Failed =
false;
2683 if (!ActiveModule && !Framework) {
2684 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2690 if (!Failed && ActiveModule->IsAvailable &&
2691 !ActiveModule->getUmbrellaDir()) {
2692 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2697 if (!Failed && ActiveModule->InferSubmodules) {
2698 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2699 if (ActiveModule->InferredSubmoduleLoc.isValid())
2700 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2701 diag::note_mmap_prev_definition);
2707 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2710 }
else if (Explicit) {
2711 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2729 if (parseOptionalAttributes(Attrs))
2734 ActiveModule->InferSubmodules =
true;
2735 ActiveModule->InferredSubmoduleLoc = StarLoc;
2736 ActiveModule->InferExplicitSubmodules = Explicit;
2739 Map.InferredDirectories[Directory].InferModules =
true;
2740 Map.InferredDirectories[Directory].Attrs = Attrs;
2741 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2747 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2764 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2765 << (ActiveModule !=
nullptr);
2773 Diags.Report(
Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2777 Map.InferredDirectories[Directory].ExcludedModules
2778 .push_back(
Tok.getString());
2783 if (!ActiveModule) {
2784 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2785 << (ActiveModule !=
nullptr);
2792 ActiveModule->InferExportWildcard =
true;
2794 Diags.Report(
Tok.getLocation(),
2795 diag::err_mmap_expected_export_wildcard);
2805 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2806 << (ActiveModule !=
nullptr);
2815 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rbrace);
2816 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2833 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2834 bool HadError =
false;
2842 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_attribute);
2851 = llvm::StringSwitch<AttributeKind>(
Tok.getString())
2852 .Case(
"exhaustive", AT_exhaustive)
2853 .Case(
"extern_c", AT_extern_c)
2854 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2855 .Case(
"system", AT_system)
2856 .Default(AT_unknown);
2857 switch (Attribute) {
2859 Diags.Report(
Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2864 Attrs.IsSystem =
true;
2868 Attrs.IsExternC =
true;
2872 Attrs.IsExhaustive =
true;
2875 case AT_no_undeclared_includes:
2876 Attrs.NoUndeclaredIncludes =
true;
2883 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_rsquare);
2884 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2936 Diags.Report(
Tok.getLocation(), diag::err_mmap_expected_module);
2948 assert(
Target &&
"Missing target information");
2949 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2950 = ParsedModuleMap.find(File);
2951 if (Known != ParsedModuleMap.end())
2952 return Known->second;
2956 auto FileCharacter =
2958 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2961 assert(
Target &&
"Missing target information");
2962 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2964 return ParsedModuleMap[File] =
true;
2965 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2966 "invalid buffer offset");
2969 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2970 Buffer->getBufferStart(),
2971 Buffer->getBufferStart() + (Offset ? *
Offset : 0),
2972 Buffer->getBufferEnd());
2977 ParsedModuleMap[File] =
Result;
2980 auto Loc = SourceMgr.getDecomposedLoc(Parser.
getLocation());
2981 assert(Loc.first == ID &&
"stopped in a different file?");
2982 *Offset = Loc.second;
2986 for (
const auto &Cb : Callbacks)
2987 Cb->moduleMapFileRead(Start, *File, IsSystem);
unsigned IsAvailable
Whether this module is available in the current translation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer...
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap)
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
SourceLocation getLocation() const
std::string Name
The name of this module.
static Module * getTopLevelOrNull(Module *M)
This header is included but private.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system...
std::string Message
The message provided to the user when there is a conflict.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Implements support for file system lookup, file system caching, and directory search management...
void dump()
Dump the contents of the module map, for debugging purposes.
Defines the clang::FileManager interface and associated types.
An unresolved conflict with another module.
time_t getModificationTime() const
This header is part of the module (for layering purposes) but should be textually included...
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Defines the SourceManager interface.
Defines the clang::Module class, which describes a module in the source code.
void excludeHeader(Module *Mod, Module::Header Header)
Marks this header as being excluded from the given module.
unsigned IsFramework
Whether this is a framework module.
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, const FileEntry *ModuleMapFile, const DirectoryEntry *Directory, bool IsSystem)
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isCompilingModule() const
Are we compiling a module interface (.cppm or module map)?
Parser - This implements a parser for the C family of languages.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Module * createHeaderModule(StringRef Name, ArrayRef< Module::Header > Headers)
Create a header module from the specified list of headers.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup...
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives...
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
tok::TokenKind getKind() const
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.
unsigned GetStringLength() const
FileManager & getFileManager() const
A library or framework to link against when an entity from this module is used.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Token - This structure provides full information about a lexed token.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, Twine NameAsWritten)
Sets the umbrella directory of the given module to the given directory.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Compiling a module from a module map.
Describes a module or submodule.
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
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?
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)
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_].
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
unsigned getLength() const
bool terminatedByDirective()
SourceLocation DefinitionLoc
The location of the module definition.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
uint64_t getInteger() const
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
A token in a module map file.
std::vector< Conflict > Conflicts
The list of conflicts.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Cached information about one directory (either on disk or in the virtual file system).
Defines the clang::SourceLocation class and associated facilities.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
~ModuleMap()
Destroy the module map.
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
AttributeKind
Enumerates the known attributes.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Module * Other
The module that this module conflicts with.
A trivial tuple used to represent a source range.
This class handles loading and caching of source files into memory.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystem() const
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
This is a C++ Modules TS module interface unit.
StringRef getName() const