30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/ADT/SmallString.h"
34#include "llvm/ADT/SmallVector.h"
35#include "llvm/ADT/StringMap.h"
36#include "llvm/ADT/StringRef.h"
37#include "llvm/ADT/StringSwitch.h"
38#include "llvm/Support/Allocator.h"
39#include "llvm/Support/Compiler.h"
40#include "llvm/Support/ErrorHandling.h"
41#include "llvm/Support/MemoryBuffer.h"
42#include "llvm/Support/Path.h"
43#include "llvm/Support/VirtualFileSystem.h"
44#include "llvm/Support/raw_ostream.h"
51#include <system_error>
56void ModuleMapCallbacks::anchor() {}
59 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
60 if (PendingLinkAs != PendingLinkAsModule.end()) {
61 for (
auto &Name : PendingLinkAs->second) {
64 M->UseExportAsModuleLinkName =
true;
89 llvm_unreachable(
"unknown header role");
106 llvm_unreachable(
"unknown header kind");
114ModuleMap::resolveExport(
Module *Mod,
116 bool Complain)
const {
119 assert(
Unresolved.Wildcard &&
"Invalid unresolved export");
132 bool Complain)
const {
137 Diags.
Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
144 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
148 Diags.
Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
149 <<
Id[I].first << Context->getFullModuleName()
167 for (; Mod; Mod = Mod->
Parent) {
169 Paths.push_back(Mod->
Name);
176 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
177 llvm::sys::path::append(
Path,
"Frameworks", Framework +
".framework");
197 unsigned FullPathLength = FullPathName.size();
199 unsigned RelativePathLength = RelativePathName.size();
202 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
203 llvm::sys::path::append(FullPathName, RelativePathName);
204 if (
auto File = GetFile(FullPathName))
214 RelativePathName.clear();
216 RelativePathName.resize(RelativePathLength);
217 FullPathName.resize(FullPathLength);
218 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
220 llvm::sys::path::append(FullPathName, RelativePathName);
221 return GetFile(FullPathName);
224 if (llvm::sys::path::is_absolute(Header.
FileName)) {
225 RelativePathName.clear();
231 return GetFrameworkFile();
234 llvm::sys::path::append(RelativePathName, Header.
FileName);
235 llvm::sys::path::append(FullPathName, RelativePathName);
236 auto NormalHdrFile = GetFile(FullPathName);
238 if (!NormalHdrFile && Directory->getName().ends_with(
".framework")) {
242 FullPathName.assign(Directory->getName());
243 RelativePathName.clear();
244 if (GetFrameworkFile()) {
246 diag::warn_mmap_incomplete_framework_module_declaration)
248 NeedsFramework =
true;
253 return NormalHdrFile;
260 return llvm::StringSwitch<bool>(
FileName)
261 .Case(
"float.h",
true)
262 .Case(
"iso646.h",
true)
263 .Case(
"limits.h",
true)
264 .Case(
"stdalign.h",
true)
265 .Case(
"stdarg.h",
true)
266 .Case(
"stdatomic.h",
true)
267 .Case(
"stdbool.h",
true)
268 .Case(
"stddef.h",
true)
269 .Case(
"stdint.h",
true)
270 .Case(
"tgmath.h",
true)
271 .Case(
"unwind.h",
true)
278 return llvm::StringSwitch<bool>(ModuleName)
279 .Case(
"_Builtin_float",
true)
280 .Case(
"_Builtin_inttypes",
true)
281 .Case(
"_Builtin_iso646",
true)
282 .Case(
"_Builtin_limits",
true)
283 .Case(
"_Builtin_stdalign",
true)
284 .Case(
"_Builtin_stdarg",
true)
285 .Case(
"_Builtin_stdatomic",
true)
286 .Case(
"_Builtin_stdbool",
true)
287 .Case(
"_Builtin_stddef",
true)
288 .Case(
"_Builtin_stdint",
true)
289 .Case(
"_Builtin_stdnoreturn",
true)
290 .Case(
"_Builtin_tgmath",
true)
291 .Case(
"_Builtin_unwind",
true)
295void ModuleMap::resolveHeader(
Module *Mod,
297 bool &NeedsFramework) {
300 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
303 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
305 << UmbrellaMod->getFullModuleName();
309 RelativePathName.str());
333bool ModuleMap::resolveAsBuiltinHeader(
336 llvm::sys::path::is_absolute(Header.
FileName) ||
338 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
360 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts),
Target(
Target),
361 HeaderInfo(HeaderInfo) {
362 MMapLangOpts.LineComment =
true;
366 for (
auto &M : Modules)
368 for (
auto *M : ShadowModules)
373 assert((!this->Target || this->Target == &
Target) &&
374 "Improper target override");
389 Buffer.push_back(
'_');
390 Buffer.reserve(Buffer.size() + Name.size());
391 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
393 Buffer.push_back(Name[I]);
395 Buffer.push_back(
'_');
398 Name = StringRef(Buffer.data(), Buffer.size());
401 while (llvm::StringSwitch<bool>(Name)
402#define
KEYWORD(Keyword,Conditions) .Case(#Keyword,
true)
403#define
ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword,
true)
404#include
"clang/Basic/TokenKinds.def"
406 if (Name.data() != Buffer.data())
407 Buffer.append(Name.begin(), Name.end());
408 Buffer.push_back(
'_');
409 Name = StringRef(Buffer.data(), Buffer.size());
416 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
422 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
427ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(
FileEntryRef File) {
429 HeadersMap::iterator Known = Headers.find(
File);
433 return Headers.find(
File);
440 if (UmbrellaDirs.empty())
454 auto KnownDir = UmbrellaDirs.find(*Dir);
455 if (KnownDir != UmbrellaDirs.end())
458 IntermediateDirs.push_back(*Dir);
461 DirName = llvm::sys::path::parent_path(DirName);
479 bool IsPrivate =
false;
483 for (
auto *Hs : HeaderList)
484 IsPrivate |= llvm::any_of(
486 assert(IsPrivate &&
"inconsistent headers and roles");
497 bool RequestingModuleIsModuleInterface,
505 if (RequestingModule) {
510 bool Excluded =
false;
512 Module *NotUsed =
nullptr;
514 HeadersMap::iterator Known = findKnownHeader(
File);
515 if (Known != Headers.end()) {
531 if (RequestingModule && LangOpts.ModulesDeclUse &&
546 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
553 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
559 if (Excluded || isHeaderInUmbrellaDirs(
File))
564 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
565 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
567 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
571 diag::warn_non_modular_include_in_framework_module :
572 diag::warn_non_modular_include_in_module;
608 bool AllowExcluded) {
615 HeadersMap::iterator Known = findKnownHeader(
File);
616 if (Known != Headers.end()) {
625 return MakeResult(H);
629 return MakeResult(
Result);
632 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(
File));
637 assert(!Headers.count(
File) &&
"already have a module for this header");
640 KnownHeader H = findHeaderInUmbrellaDirs(
File, SkippedDirs);
648 UmbrellaModule = UmbrellaModule->
Parent;
662 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
665 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
666 Result->IsInferred =
true;
669 UmbrellaDirs[SkippedDir] =
Result;
680 llvm::sys::path::stem(
File.getName()), NameBuf);
683 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
684 Result->IsInferred =
true;
694 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
695 UmbrellaDirs[SkippedDirs[I]] =
Result;
699 Headers[
File].push_back(Header);
708 HeadersMap::iterator Known = findKnownHeader(
File);
709 if (Known != Headers.end())
710 return Known->second;
712 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
713 return Headers.find(
File)->second;
722 auto It = Headers.find(
File);
723 if (It == Headers.end())
735 HeadersMap::const_iterator Known = Headers.find(Header);
736 if (Known != Headers.end()) {
738 I = Known->second.begin(),
739 E = Known->second.end();
745 if (I->isAvailable() &&
746 (!RequestingModule ||
763 StringRef DirName = Dir->
getName();
765 auto IsUnavailable = [&](
const Module *M) {
773 auto KnownDir = UmbrellaDirs.find(*Dir);
774 if (KnownDir != UmbrellaDirs.end()) {
776 if (IsUnavailable(
Found))
784 UmbrellaModule = UmbrellaModule->
Parent;
791 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
795 if (IsUnavailable(
Found))
802 llvm::sys::path::stem(Header.
getName()),
809 return IsUnavailable(
Found);
812 SkippedDirs.push_back(*Dir);
815 DirName = llvm::sys::path::parent_path(DirName);
827 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
828 if (Known != Modules.end())
829 return Known->getValue();
836 for(; Context; Context = Context->Parent) {
848 return Context->findSubmodule(Name);
857 return std::make_pair(Sub,
false);
861 IsExplicit, NumCreatedModules++);
866 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
868 return std::make_pair(
Result,
true);
874 true, NumCreatedModules++);
879 PendingSubmodules.emplace_back(
Result);
886 assert(
Parent &&
"We should only create an implicit global module fragment "
887 "in a module purview");
893 false, NumCreatedModules++);
903 true, NumCreatedModules++);
912 false, NumCreatedModules++);
916 for (
auto &Submodule : PendingSubmodules) {
917 Submodule->setParent(
Result);
920 PendingSubmodules.clear();
926 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
927 assert(!Modules[Name] &&
"redefining existing module");
931 Modules[Name] = SourceModule =
Result;
936 assert(MainFile &&
"no input file for module interface");
944 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
947 "creating implementation module without an interface");
952 StringRef IName =
".ImplementationUnit";
953 assert(!Modules[IName] &&
"multiple implementation units?");
957 Modules[IName] = SourceModule =
Result;
961 "no input file for module implementation");
968 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
969 assert(!Modules[Name] &&
"redefining existing module");
972 false, NumCreatedModules++);
974 Modules[Name] = SourceModule =
Result;
982 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
984 "Can only infer linking for top-level frameworks");
986 StringRef FrameworkName(Mod->
Name);
987 FrameworkName.consume_back(
"_Private");
996 return inferFrameworkModule(FrameworkDir, Attrs,
Parent);
1005 StringRef FrameworkDirName =
1013 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1026 bool canInfer =
false;
1027 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1029 StringRef
Parent = llvm::sys::path::parent_path(FrameworkDirName);
1033 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1034 inferred = InferredDirectories.find(*ParentDir);
1035 if (inferred == InferredDirectories.end()) {
1038 bool IsFrameworkDir =
Parent.ends_with(
".framework");
1042 inferred = InferredDirectories.find(*ParentDir);
1045 if (inferred == InferredDirectories.end())
1046 inferred = InferredDirectories.insert(
1047 std::make_pair(*ParentDir, InferredDirectory())).first;
1050 if (inferred->second.InferModules) {
1053 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1055 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1057 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1058 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1059 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1060 Attrs.NoUndeclaredIncludes |=
1061 inferred->second.Attrs.NoUndeclaredIncludes;
1062 ModuleMapFID = inferred->second.ModuleMapFID;
1076 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1082 if (!UmbrellaHeader)
1087 NumCreatedModules++);
1088 InferredModuleAllowedBy[
Result] = ModuleMapFID;
1089 Result->IsInferred =
true;
1093 Modules[ModuleName] =
Result;
1094 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1097 Result->IsSystem |= Attrs.IsSystem;
1098 Result->IsExternC |= Attrs.IsExternC;
1099 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1100 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1101 Result->Directory = FrameworkDir;
1104 StringRef RelativePath = UmbrellaName.str().substr(
1105 Result->getTopLevelModule()->Directory->getName().size());
1106 RelativePath = llvm::sys::path::relative_path(RelativePath);
1116 Result->InferSubmodules =
true;
1117 Result->InferExportWildcard =
true;
1122 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1123 llvm::sys::path::native(SubframeworksDirName);
1125 for (llvm::vfs::directory_iterator
1126 Dir = FS.dir_begin(SubframeworksDirName, EC),
1128 Dir != DirEnd && !EC; Dir.increment(EC)) {
1129 if (!StringRef(Dir->path()).ends_with(
".framework"))
1137 StringRef SubframeworkDirName =
1139 bool FoundParent =
false;
1143 = llvm::sys::path::parent_path(SubframeworkDirName);
1144 if (SubframeworkDirName.empty())
1147 if (
auto SubDir = FileMgr.
getDirectory(SubframeworkDirName)) {
1148 if (*SubDir == FrameworkDir) {
1159 inferFrameworkModule(*SubframeworkDir, Attrs,
Result);
1165 if (!
Result->isSubFramework())
1172 Module *ShadowingModule) {
1177 false, NumCreatedModules++);
1178 Result->ShadowingModule = ShadowingModule;
1179 Result->markUnavailable(
true);
1180 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1181 ShadowModules.push_back(
Result);
1188 const Twine &PathRelativeToRootModuleDirectory) {
1193 PathRelativeToRootModuleDirectory.str();
1194 UmbrellaDirs[UmbrellaHeader.
getDir()] = Mod;
1197 for (
const auto &Cb : Callbacks)
1198 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1203 const Twine &PathRelativeToRootModuleDirectory) {
1207 PathRelativeToRootModuleDirectory.str();
1208 UmbrellaDirs[UmbrellaDir] = Mod;
1211void ModuleMap::addUnresolvedHeader(
Module *Mod,
1213 bool &NeedsFramework) {
1216 if (resolveAsBuiltinHeader(Mod, Header)) {
1235 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1237 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1244 resolveHeader(Mod, Header, NeedsFramework);
1248 auto BySize = LazyHeadersBySize.find(
File->getSize());
1249 if (BySize != LazyHeadersBySize.end()) {
1250 for (
auto *M : BySize->second)
1252 LazyHeadersBySize.erase(BySize);
1255 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1256 if (ByModTime != LazyHeadersByModTime.end()) {
1257 for (
auto *M : ByModTime->second)
1259 LazyHeadersByModTime.erase(ByModTime);
1264 Module *Mod, std::optional<const FileEntry *>
File)
const {
1265 bool NeedsFramework =
false;
1267 const auto Size =
File ? (*File)->getSize() : 0;
1268 const auto ModTime =
File ? (*File)->getModificationTime() : 0;
1272 (Header.
Size && Header.
Size != Size)))
1273 NewHeaders.push_back(Header);
1277 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1289 auto &HeaderList = Headers[Header.
Entry];
1290 if (llvm::is_contained(HeaderList, KH))
1293 HeaderList.push_back(KH);
1296 bool isCompilingModuleHeader = Mod->
isForBuilding(LangOpts);
1297 if (!Imported || isCompilingModuleHeader) {
1301 isCompilingModuleHeader);
1305 for (
const auto &Cb : Callbacks)
1323 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1324 return InferredModuleAllowedBy.find(M)->second;
1335 assert(M->
IsInferred &&
"module not inferred");
1336 InferredModuleAllowedBy[M] = ModMapFID;
1341 StringRef Dir = llvm::sys::path::parent_path({
Path.data(),
Path.size()});
1345 if (llvm::sys::path::filename(Dir) ==
"Modules") {
1346 StringRef
Parent = llvm::sys::path::parent_path(Dir);
1347 if (
Parent.ends_with(
".framework"))
1354 return llvm::errorToErrorCode(DirEntry.takeError());
1358 if (CanonicalDir != Dir)
1359 llvm::sys::path::replace_path_prefix(
Path, Dir, CanonicalDir);
1367 llvm::sys::path::remove_dots(
Path);
1369 return std::error_code();
1378 llvm::errs() <<
"Modules:";
1379 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1380 MEnd = Modules.end();
1382 M->getValue()->
print(llvm::errs(), 2);
1384 llvm::errs() <<
"Headers:";
1385 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1387 llvm::errs() <<
" \"" << H->first.getName() <<
"\" -> ";
1389 E = H->second.end();
1391 if (I != H->second.begin())
1392 llvm::errs() <<
",";
1393 llvm::errs() << I->getModule()->getFullModuleName();
1395 llvm::errs() <<
"\n";
1404 if (Export.getPointer() || Export.getInt())
1405 Mod->
Exports.push_back(Export);
1414 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1415 Top->UnresolvedDirectUses.clear();
1417 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1419 Top->DirectUses.push_back(DirectUse);
1421 Top->UnresolvedDirectUses.push_back(UDU);
1423 return !Top->UnresolvedDirectUses.empty();
1430 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1432 Conflict.
Other = OtherMod;
1433 Conflict.
Message = UC.Message;
1538 bool HadError =
false;
1542 llvm::BumpPtrAllocator StringData;
1548 Module *ActiveModule =
nullptr;
1568 void parseModuleDecl();
1569 void parseExternModuleDecl();
1570 void parseRequiresDecl();
1573 void parseExportDecl();
1574 void parseExportAsDecl();
1575 void parseUseDecl();
1576 void parseLinkDecl();
1577 void parseConfigMacros();
1578 void parseConflict();
1579 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1588 using Attributes = ModuleMap::Attributes;
1590 bool parseOptionalAttributes(Attributes &Attrs);
1597 : L(L), SourceMgr(SourceMgr),
Target(
Target), Diags(Diags), Map(Map),
1598 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {
1620 case tok::raw_identifier: {
1624 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1681 case tok::string_literal: {
1696 char *Saved = StringData.Allocate<
char>(Length + 1);
1707 case tok::numeric_constant: {
1710 SpellingBuffer.resize(LToken.
getLength() + 1);
1711 const char *Start = SpellingBuffer.data();
1715 if (StringRef(Start, Length).getAsInteger(0,
Value)) {
1735 auto NextIsIdent = [&](StringRef Str) ->
bool {
1740 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1741 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1758 unsigned braceDepth = 0;
1759 unsigned squareDepth = 0;
1766 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1773 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1787 if (squareDepth > 0)
1794 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1810bool ModuleMapParser::parseModuleId(
ModuleId &
Id) {
1834 enum AttributeKind {
1848 AT_no_undeclared_includes
1857void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1859 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1862 diag::note_mmap_rename_top_level_private_module);
1863 D << BadName << M->Name;
1868 auto const *M =
E->getValue();
1869 if (M->Directory != ActiveModule->
Directory)
1877 Canonical.append(
"_Private");
1880 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->Parent &&
1883 diag::warn_mmap_mismatched_private_submodule)
1888 FixItInitBegin = FrameworkLoc;
1890 FixItInitBegin = ExplicitLoc;
1893 FixedPrivModDecl.append(
"framework ");
1894 FixedPrivModDecl.append(
"module ");
1895 FixedPrivModDecl.append(Canonical);
1897 GenNoteAndFixIt(
FullName, FixedPrivModDecl, M,
1904 ActiveModule->
Name != Canonical) {
1906 diag::warn_mmap_mismatched_private_module_name)
1907 << ActiveModule->
Name;
1908 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M,
1932void ModuleMapParser::parseModuleDecl() {
1936 parseExternModuleDecl();
1943 bool Explicit =
false;
1944 bool Framework =
false;
1948 ExplicitLoc = consumeToken();
1954 FrameworkLoc = consumeToken();
1965 CurrModuleDeclLoc = consumeToken();
1970 return parseInferredModuleDecl(Framework, Explicit);
1974 if (parseModuleId(
Id)) {
1980 if (
Id.size() > 1) {
1981 Diags.
Report(
Id.front().second, diag::err_mmap_nested_submodule_id)
1987 }
else if (
Id.size() == 1 && Explicit) {
1989 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1995 Module *PreviousActiveModule = ActiveModule;
1996 if (
Id.size() > 1) {
1999 ActiveModule =
nullptr;
2000 const Module *TopLevelModule =
nullptr;
2001 for (
unsigned I = 0, N =
Id.size() - 1; I != N; ++I) {
2004 TopLevelModule = Next;
2005 ActiveModule = Next;
2009 Diags.
Report(
Id[I].second, diag::err_mmap_missing_parent_module)
2010 <<
Id[I].first << (ActiveModule !=
nullptr)
2017 if (TopLevelModule &&
2019 assert(ModuleMapFID !=
2021 "submodule defined in same file as 'module *' that allowed its "
2022 "top-level module");
2028 StringRef ModuleName =
Id.back().first;
2033 if (parseOptionalAttributes(Attrs))
2046 Module *ShadowingModule =
nullptr;
2054 bool Inferred = Existing->IsInferred;
2070 bool PartOfFramework = Framework || Existing->isPartOfFramework();
2073 bool ParsedAsMainInput =
2078 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
2079 ActiveModule = PreviousActiveModule;
2086 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2093 ShadowingModule = Existing;
2096 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2098 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2111 if (ShadowingModule) {
2121 if (Attrs.IsSystem || IsSystem)
2123 if (Attrs.IsExternC)
2125 if (Attrs.NoUndeclaredIncludes)
2129 StringRef MapFileName(
2131 if (MapFileName.ends_with(
"module.private.modulemap") ||
2132 MapFileName.ends_with(
"module_private.map")) {
2142 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_submodule,
2144 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_module_name,
2147 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2158 parseConfigMacros();
2177 parseExportAsDecl();
2185 parseRequiresDecl();
2197 parseUmbrellaDirDecl(UmbrellaLoc);
2228 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2248 ActiveModule = PreviousActiveModule;
2255void ModuleMapParser::parseExternModuleDecl() {
2270 if (parseModuleId(
Id)) {
2286 if (llvm::sys::path::is_relative(FileNameRef)) {
2287 ModuleMapFileName += Directory.
getName();
2288 llvm::sys::path::append(ModuleMapFileName,
FileName);
2289 FileNameRef = ModuleMapFileName;
2297 FileID(),
nullptr, ExternLoc);
2316 bool &IsRequiresExcludedHack) {
2317 if (Feature ==
"excluded" &&
2320 IsRequiresExcludedHack =
true;
2322 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2340void ModuleMapParser::parseRequiresDecl() {
2348 bool RequiredState =
true;
2350 RequiredState =
false;
2361 std::string Feature = std::string(Tok.
getString());
2364 bool IsRequiresExcludedHack =
false;
2365 bool ShouldAddRequirement =
2368 if (IsRequiresExcludedHack)
2369 UsesRequiresExcludedHack.insert(ActiveModule);
2371 if (ShouldAddRequirement) {
2373 ActiveModule->
addRequirement(Feature, RequiredState, Map.LangOpts,
2403 LeadingToken = Tok.
Kind;
2413 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2445 !std::holds_alternative<std::monostate>(ActiveModule->
Umbrella)) {
2461 switch (llvm::StringSwitch<Attribute>(Str)
2463 .Case(
"mtime", ModTime)
2467 Diags.
Report(
Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2470 diag::err_mmap_invalid_header_attribute_value) << Str;
2480 Diags.
Report(
Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2483 diag::err_mmap_invalid_header_attribute_value) << Str;
2492 Diags.
Report(
Loc, diag::err_mmap_expected_header_attribute);
2502 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2507 bool NeedsFramework =
false;
2511 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
2514 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2517 Diags.
Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2531void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2540 std::string DirName = std::string(Tok.
getString());
2541 std::string DirNameAsWritten = DirName;
2545 if (!std::holds_alternative<std::monostate>(ActiveModule->
Umbrella)) {
2546 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2554 if (llvm::sys::path::is_absolute(DirName)) {
2558 PathName = Directory.
getName();
2559 llvm::sys::path::append(PathName, DirName);
2564 Diags.
Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2569 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2576 llvm::vfs::FileSystem &FS =
2578 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC),
E;
2579 I !=
E && !EC; I.increment(EC)) {
2582 Headers.push_back(std::move(Header));
2589 for (
auto &Header : Headers)
2594 if (
Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2595 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2596 << OwningModule->getFullModuleName();
2614void ModuleMapParser::parseExportDecl() {
2620 bool Wildcard =
false;
2624 ParsedModuleId.push_back(
2648 ExportLoc, ParsedModuleId, Wildcard
2657void ModuleMapParser::parseExportAsDecl() {
2667 if (ActiveModule->
Parent) {
2694void ModuleMapParser::parseUseDecl() {
2696 auto KWLoc = consumeToken();
2699 parseModuleId(ParsedModuleId);
2701 if (ActiveModule->
Parent)
2702 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
2711void ModuleMapParser::parseLinkDecl() {
2716 bool IsFramework =
false;
2730 std::string LibraryName = std::string(Tok.
getString());
2743void ModuleMapParser::parseConfigMacros() {
2748 if (ActiveModule->
Parent) {
2749 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2754 if (parseOptionalAttributes(Attrs))
2757 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
2767 if (!ActiveModule->
Parent) {
2786 if (!ActiveModule->
Parent) {
2797 llvm::raw_string_ostream OS(result);
2799 for (
unsigned I = 0, N =
Id.size(); I != N; ++I) {
2813void ModuleMapParser::parseConflict() {
2819 if (parseModuleId(Conflict.
Id))
2852void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2855 bool Failed =
false;
2858 if (!ActiveModule && !Framework) {
2859 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2867 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2873 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2876 diag::note_mmap_prev_definition);
2882 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2885 }
else if (Explicit) {
2886 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2904 if (parseOptionalAttributes(Attrs))
2914 Map.InferredDirectories[Directory].InferModules =
true;
2915 Map.InferredDirectories[Directory].Attrs = Attrs;
2916 Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID;
2940 << (ActiveModule !=
nullptr);
2952 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2958 if (!ActiveModule) {
2960 << (ActiveModule !=
nullptr);
2970 diag::err_mmap_expected_export_wildcard);
2981 << (ActiveModule !=
nullptr);
2991 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
3008bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
3009 bool HadError =
false;
3025 AttributeKind Attribute
3026 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
3027 .Case(
"exhaustive", AT_exhaustive)
3028 .Case(
"extern_c", AT_extern_c)
3029 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
3030 .Case(
"system", AT_system)
3031 .Default(AT_unknown);
3032 switch (Attribute) {
3039 Attrs.IsSystem =
true;
3043 Attrs.IsExternC =
true;
3047 Attrs.IsExhaustive =
true;
3050 case AT_no_undeclared_includes:
3051 Attrs.NoUndeclaredIncludes =
true;
3059 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
3123 assert(
Target &&
"Missing target information");
3124 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3125 = ParsedModuleMap.find(
File);
3126 if (Known != ParsedModuleMap.end())
3127 return Known->second;
3130 if (ID.isInvalid()) {
3131 auto FileCharacter =
3136 assert(
Target &&
"Missing target information");
3137 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.
getBufferOrNone(ID);
3139 return ParsedModuleMap[
File] =
true;
3140 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
3141 "invalid buffer offset");
3145 Buffer->getBufferStart(),
3146 Buffer->getBufferStart() + (Offset ? *Offset : 0),
3147 Buffer->getBufferEnd());
3155 assert(
Loc.first == ID &&
"stopped in a different file?");
3156 *Offset =
Loc.second;
3160 for (
const auto &Cb : Callbacks)
3161 Cb->moduleMapFileRead(Start,
File, IsSystem);
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
#define ALIAS(NAME, TOK, FLAGS)
#define KEYWORD(NAME, FLAGS)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
static Module * getTopLevelOrNull(Module *M)
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives.
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
static std::string formatModuleId(const ModuleId &Id)
Format a module-id into a string.
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompilingModule() const
Are we compiling a module?
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
SourceLocation getSourceLocation(const char *Loc, unsigned TokLen=1) const
getSourceLocation - Return a source location identifier for the specified offset in the current file.
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,...
SourceLocation getLocation()
bool terminatedByDirective()
bool parseModuleMapFile()
Parse a module map file.
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
void dump()
Dump the contents of the module map, for debugging purposes.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
bool mayShadowNewModule(Module *ExistingModule)
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
module_iterator module_begin() const
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
FileID getModuleMapFileIDForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
module_iterator module_end() const
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
~ModuleMap()
Destroy the module map.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
void setTarget(const TargetInfo &Target)
Set the target information.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
ModuleHeaderRole
Flags describing the role of a module header.
@ PrivateHeader
This header is included but private.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ NormalHeader
This header is normally included in the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module interface unit.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)
Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
SourceLocation InferredSubmoduleLoc
The location of the inferred submodule.
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
SourceLocation DefinitionLoc
The location of the module definition.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Module * Parent
The parent of this module.
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
std::string UmbrellaRelativeToRootModuleDirectory
OptionalDirectoryEntryRef Directory
The build directory of this module.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
@ ModuleHeaderUnit
This is a C++20 header unit.
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
unsigned IsFramework
Whether this is a framework module.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned IsAvailable
Whether this module is available in the current translation unit.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
std::vector< Conflict > Conflicts
The list of conflicts.
Parser - This implements a parser for the C family of languages.
Encodes a location in the source.
static SourceLocation getFromRawEncoding(UIntTy Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
StringLiteral - This represents a string literal expression, e.g.
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
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)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
Defines the clang::TargetInfo interface.
bool Sub(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
A token in a module map file.
SourceLocation getLocation() const
bool is(TokenKind K) const
SourceLocation::UIntTy Location
StringRef getString() const
enum clang::MMToken::TokenKind Kind
uint64_t getInteger() const
A conflict between two modules.
Module * Other
The module that this module conflicts with.
std::string Message
The message provided to the user when there is a conflict.
A library or framework to link against when an entity from this module is used.
An unresolved conflict with another module.
std::string Message
The message provided to the user when there is a conflict.
ModuleId Id
The (unresolved) module id.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...