30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/StringMap.h"
35#include "llvm/ADT/StringRef.h"
36#include "llvm/ADT/StringSwitch.h"
37#include "llvm/Support/Allocator.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/ErrorHandling.h"
40#include "llvm/Support/Path.h"
41#include "llvm/Support/VirtualFileSystem.h"
42#include "llvm/Support/raw_ostream.h"
49#include <system_error>
54void ModuleMapCallbacks::anchor() {}
57 auto PendingLinkAs = PendingLinkAsModule.find(Mod->
Name);
58 if (PendingLinkAs != PendingLinkAsModule.end()) {
59 for (
auto &Name : PendingLinkAs->second) {
62 M->UseExportAsModuleLinkName =
true;
87 llvm_unreachable(
"unknown header role");
104 llvm_unreachable(
"unknown header kind");
112ModuleMap::resolveExport(
Module *Mod,
114 bool Complain)
const {
117 assert(
Unresolved.Wildcard &&
"Invalid unresolved export");
130 bool Complain)
const {
135 Diags.
Report(
Id[0].second, diag::err_mmap_missing_module_unqualified)
142 for (
unsigned I = 1, N =
Id.size(); I != N; ++I) {
146 Diags.
Report(
Id[I].second, diag::err_mmap_missing_module_qualified)
147 <<
Id[I].first << Context->getFullModuleName()
165 for (; Mod; Mod = Mod->
Parent) {
167 Paths.push_back(Mod->
Name);
174 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
175 llvm::sys::path::append(
Path,
"Frameworks", Framework +
".framework");
195 unsigned FullPathLength = FullPathName.size();
197 unsigned RelativePathLength = RelativePathName.size();
200 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
201 llvm::sys::path::append(FullPathName, RelativePathName);
202 if (
auto File = GetFile(FullPathName))
212 RelativePathName.clear();
214 RelativePathName.resize(RelativePathLength);
215 FullPathName.resize(FullPathLength);
216 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
218 llvm::sys::path::append(FullPathName, RelativePathName);
219 return GetFile(FullPathName);
222 if (llvm::sys::path::is_absolute(Header.
FileName)) {
223 RelativePathName.clear();
229 return GetFrameworkFile();
232 llvm::sys::path::append(RelativePathName, Header.
FileName);
233 llvm::sys::path::append(FullPathName, RelativePathName);
234 auto NormalHdrFile = GetFile(FullPathName);
236 if (!NormalHdrFile && Directory->getName().ends_with(
".framework")) {
240 FullPathName.assign(Directory->getName());
241 RelativePathName.clear();
242 if (GetFrameworkFile()) {
244 diag::warn_mmap_incomplete_framework_module_declaration)
246 NeedsFramework =
true;
251 return NormalHdrFile;
258 return llvm::StringSwitch<bool>(
FileName)
259 .Case(
"float.h",
true)
260 .Case(
"iso646.h",
true)
261 .Case(
"limits.h",
true)
262 .Case(
"stdalign.h",
true)
263 .Case(
"stdarg.h",
true)
264 .Case(
"stdatomic.h",
true)
265 .Case(
"stdbool.h",
true)
266 .Case(
"stddef.h",
true)
267 .Case(
"stdint.h",
true)
268 .Case(
"tgmath.h",
true)
269 .Case(
"unwind.h",
true)
276 return llvm::StringSwitch<bool>(ModuleName)
277 .Case(
"_Builtin_float",
true)
278 .Case(
"_Builtin_inttypes",
true)
279 .Case(
"_Builtin_iso646",
true)
280 .Case(
"_Builtin_limits",
true)
281 .Case(
"_Builtin_stdalign",
true)
282 .Case(
"_Builtin_stdarg",
true)
283 .Case(
"_Builtin_stdatomic",
true)
284 .Case(
"_Builtin_stdbool",
true)
285 .Case(
"_Builtin_stddef",
true)
286 .Case(
"_Builtin_stdint",
true)
287 .Case(
"_Builtin_stdnoreturn",
true)
288 .Case(
"_Builtin_tgmath",
true)
289 .Case(
"_Builtin_unwind",
true)
293void ModuleMap::resolveHeader(
Module *Mod,
295 bool &NeedsFramework) {
298 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
301 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
303 << UmbrellaMod->getFullModuleName();
307 RelativePathName.str());
331bool ModuleMap::resolveAsBuiltinHeader(
334 llvm::sys::path::is_absolute(Header.
FileName) ||
336 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
358 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts),
Target(
Target),
359 HeaderInfo(HeaderInfo) {
360 MMapLangOpts.LineComment =
true;
366 assert((!this->Target || this->Target == &
Target) &&
367 "Improper target override");
382 Buffer.push_back(
'_');
383 Buffer.reserve(Buffer.size() + Name.size());
384 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
386 Buffer.push_back(Name[I]);
388 Buffer.push_back(
'_');
391 Name = StringRef(Buffer.data(), Buffer.size());
394 while (llvm::StringSwitch<bool>(Name)
395#define
KEYWORD(Keyword,Conditions) .Case(#Keyword,
true)
396#define
ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword,
true)
397#include
"clang/Basic/TokenKinds.def"
399 if (Name.data() != Buffer.data())
400 Buffer.append(Name.begin(), Name.end());
401 Buffer.push_back(
'_');
402 Name = StringRef(Buffer.data(), Buffer.size());
409 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
415 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
420ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(
FileEntryRef File) {
422 HeadersMap::iterator Known = Headers.find(
File);
426 return Headers.find(
File);
433 if (UmbrellaDirs.empty())
447 auto KnownDir = UmbrellaDirs.find(*Dir);
448 if (KnownDir != UmbrellaDirs.end())
451 IntermediateDirs.push_back(*Dir);
454 DirName = llvm::sys::path::parent_path(DirName);
472 bool IsPrivate =
false;
476 for (
auto Hs : HeaderList)
477 IsPrivate |= llvm::any_of(
479 assert(IsPrivate &&
"inconsistent headers and roles");
490 bool RequestingModuleIsModuleInterface,
498 if (RequestingModule) {
503 bool Excluded =
false;
505 Module *NotUsed =
nullptr;
507 HeadersMap::iterator Known = findKnownHeader(
File);
508 if (Known != Headers.end()) {
524 if (RequestingModule && LangOpts.ModulesDeclUse &&
539 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
546 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
552 if (Excluded || isHeaderInUmbrellaDirs(
File))
557 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
558 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
560 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
564 diag::warn_non_modular_include_in_framework_module :
565 diag::warn_non_modular_include_in_module;
601 bool AllowExcluded) {
608 HeadersMap::iterator Known = findKnownHeader(
File);
609 if (Known != Headers.end()) {
618 return MakeResult(H);
622 return MakeResult(
Result);
625 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(
File));
630 assert(!Headers.count(
File) &&
"already have a module for this header");
633 KnownHeader H = findHeaderInUmbrellaDirs(
File, SkippedDirs);
641 UmbrellaModule = UmbrellaModule->
Parent;
655 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
661 UmbrellaDirs[SkippedDir] =
Result;
672 llvm::sys::path::stem(
File.getName()), NameBuf);
685 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
686 UmbrellaDirs[SkippedDirs[I]] =
Result;
690 Headers[
File].push_back(Header);
699 HeadersMap::iterator Known = findKnownHeader(
File);
700 if (Known != Headers.end())
701 return Known->second;
703 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
704 return Headers.find(
File)->second;
713 auto It = Headers.find(
File);
714 if (It == Headers.end())
726 HeadersMap::const_iterator Known = Headers.find(Header);
727 if (Known != Headers.end()) {
729 I = Known->second.begin(),
730 E = Known->second.end();
736 if (I->isAvailable() &&
737 (!RequestingModule ||
754 StringRef DirName = Dir->
getName();
756 auto IsUnavailable = [&](
const Module *M) {
764 auto KnownDir = UmbrellaDirs.find(*Dir);
765 if (KnownDir != UmbrellaDirs.end()) {
767 if (IsUnavailable(
Found))
775 UmbrellaModule = UmbrellaModule->
Parent;
782 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
786 if (IsUnavailable(
Found))
793 llvm::sys::path::stem(Header.
getName()),
800 return IsUnavailable(
Found);
803 SkippedDirs.push_back(*Dir);
806 DirName = llvm::sys::path::parent_path(DirName);
818 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
819 if (Known != Modules.end())
820 return Known->getValue();
828 if (!
Parent->InferSubmodules)
832 Parent->InferExplicitSubmodules, 0);
833 Result->InferExplicitSubmodules =
Parent->InferExplicitSubmodules;
835 Result->InferExportWildcard =
Parent->InferExportWildcard;
836 if (
Result->InferExportWildcard)
843 for(; Context; Context = Context->Parent) {
855 return Context->findSubmodule(Name);
864 return std::make_pair(Sub,
false);
868 return std::make_pair(M,
true);
872 bool IsFramework,
bool IsExplicit) {
874 "Creating duplicate submodule");
878 IsFramework, IsExplicit, NumCreatedModules++);
883 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
892 true, NumCreatedModules++);
897 PendingSubmodules.emplace_back(
Result);
904 assert(
Parent &&
"We should only create an implicit global module fragment "
905 "in a module purview");
909 auto *
Result =
new (ModulesAlloc.Allocate())
911 false,
false, NumCreatedModules++);
921 true, NumCreatedModules++);
928 auto *
Result =
new (ModulesAlloc.Allocate())
930 false, NumCreatedModules++);
934 for (
auto &Submodule : PendingSubmodules)
935 Submodule->setParent(
Result);
936 PendingSubmodules.clear();
942 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
943 assert(!Modules[Name] &&
"redefining existing module");
947 Modules[Name] = SourceModule =
Result;
952 assert(MainFile &&
"no input file for module interface");
960 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
963 "creating implementation module without an interface");
968 StringRef IName =
".ImplementationUnit";
969 assert(!Modules[IName] &&
"multiple implementation units?");
973 Modules[IName] = SourceModule =
Result;
977 "no input file for module implementation");
984 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
985 assert(!Modules[Name] &&
"redefining existing module");
987 auto *
Result =
new (ModulesAlloc.Allocate())
989 false, NumCreatedModules++);
991 Modules[Name] = SourceModule =
Result;
999 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
1001 "Can only infer linking for top-level frameworks");
1003 StringRef FrameworkName(Mod->
Name);
1004 FrameworkName.consume_back(
"_Private");
1013 return inferFrameworkModule(FrameworkDir, Attrs,
Parent);
1022 StringRef FrameworkDirName =
1030 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1043 bool canInfer =
false;
1044 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1046 StringRef
Parent = llvm::sys::path::parent_path(FrameworkDirName);
1050 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1051 inferred = InferredDirectories.find(*ParentDir);
1052 if (inferred == InferredDirectories.end()) {
1055 bool IsFrameworkDir =
Parent.ends_with(
".framework");
1059 inferred = InferredDirectories.find(*ParentDir);
1062 if (inferred == InferredDirectories.end())
1063 inferred = InferredDirectories.insert(
1064 std::make_pair(*ParentDir, InferredDirectory())).first;
1067 if (inferred->second.InferModules) {
1070 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1072 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1074 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1075 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1076 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1077 Attrs.NoUndeclaredIncludes |=
1078 inferred->second.Attrs.NoUndeclaredIncludes;
1079 ModuleMapFID = inferred->second.ModuleMapFID;
1093 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1099 if (!UmbrellaHeader)
1104 true,
false, NumCreatedModules++);
1109 Modules[ModuleName] =
Result;
1110 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1113 Result->IsSystem |= Attrs.IsSystem;
1114 Result->IsExternC |= Attrs.IsExternC;
1115 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1116 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1117 Result->Directory = FrameworkDir;
1120 StringRef RelativePath = UmbrellaName.str().substr(
1121 Result->getTopLevelModule()->Directory->getName().size());
1122 RelativePath = llvm::sys::path::relative_path(RelativePath);
1132 Result->InferSubmodules =
true;
1133 Result->InferExportWildcard =
true;
1138 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1139 llvm::sys::path::native(SubframeworksDirName);
1141 for (llvm::vfs::directory_iterator
1142 Dir = FS.dir_begin(SubframeworksDirName, EC),
1144 Dir != DirEnd && !EC; Dir.increment(EC)) {
1145 if (!StringRef(Dir->path()).ends_with(
".framework"))
1153 StringRef SubframeworkDirName =
1155 bool FoundParent =
false;
1159 = llvm::sys::path::parent_path(SubframeworkDirName);
1160 if (SubframeworkDirName.empty())
1165 if (*SubDir == FrameworkDir) {
1176 inferFrameworkModule(*SubframeworkDir, Attrs,
Result);
1182 if (!
Result->isSubFramework())
1189 Module *ShadowingModule) {
1194 IsFramework,
false, NumCreatedModules++);
1195 Result->ShadowingModule = ShadowingModule;
1196 Result->markUnavailable(
true);
1197 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1198 ShadowModules.push_back(
Result);
1205 const Twine &PathRelativeToRootModuleDirectory) {
1210 PathRelativeToRootModuleDirectory.str();
1211 UmbrellaDirs[UmbrellaHeader.
getDir()] = Mod;
1214 for (
const auto &Cb : Callbacks)
1215 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1220 const Twine &PathRelativeToRootModuleDirectory) {
1224 PathRelativeToRootModuleDirectory.str();
1225 UmbrellaDirs[UmbrellaDir] = Mod;
1228void ModuleMap::addUnresolvedHeader(
Module *Mod,
1230 bool &NeedsFramework) {
1233 if (resolveAsBuiltinHeader(Mod, Header)) {
1252 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1254 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1261 resolveHeader(Mod, Header, NeedsFramework);
1265 auto BySize = LazyHeadersBySize.find(
File->getSize());
1266 if (BySize != LazyHeadersBySize.end()) {
1267 for (
auto *M : BySize->second)
1269 LazyHeadersBySize.erase(BySize);
1272 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1273 if (ByModTime != LazyHeadersByModTime.end()) {
1274 for (
auto *M : ByModTime->second)
1276 LazyHeadersByModTime.erase(ByModTime);
1281 Module *Mod, std::optional<const FileEntry *>
File)
const {
1282 bool NeedsFramework =
false;
1284 const auto Size =
File ? (*File)->getSize() : 0;
1285 const auto ModTime =
File ? (*File)->getModificationTime() : 0;
1289 (Header.
Size && Header.
Size != Size)))
1290 NewHeaders.push_back(Header);
1294 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1308 auto &HeaderList = Headers[HeaderEntry];
1309 if (llvm::is_contained(HeaderList, KH))
1312 HeaderList.push_back(KH);
1315 bool isCompilingModuleHeader = Mod->
isForBuilding(LangOpts);
1316 if (!Imported || isCompilingModuleHeader) {
1323 for (
const auto &Cb : Callbacks)
1324 Cb->moduleMapAddHeader(HeaderEntry.
getName());
1341 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1342 return InferredModuleAllowedBy.find(M)->second;
1354 InferredModuleAllowedBy[M] = ModMapFID;
1359 StringRef Dir = llvm::sys::path::parent_path({
Path.data(),
Path.size()});
1363 if (llvm::sys::path::filename(Dir) ==
"Modules") {
1364 StringRef
Parent = llvm::sys::path::parent_path(Dir);
1365 if (
Parent.ends_with(
".framework"))
1372 return llvm::errorToErrorCode(DirEntry.takeError());
1376 if (CanonicalDir != Dir)
1377 llvm::sys::path::replace_path_prefix(
Path, Dir, CanonicalDir);
1385 llvm::sys::path::remove_dots(
Path);
1387 return std::error_code();
1396 llvm::errs() <<
"Modules:";
1397 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1398 MEnd = Modules.end();
1400 M->getValue()->
print(llvm::errs(), 2);
1402 llvm::errs() <<
"Headers:";
1403 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1405 llvm::errs() <<
" \"" << H->first.getName() <<
"\" -> ";
1407 E = H->second.end();
1409 if (I != H->second.begin())
1410 llvm::errs() <<
",";
1411 llvm::errs() << I->getModule()->getFullModuleName();
1413 llvm::errs() <<
"\n";
1422 if (Export.getPointer() || Export.getInt())
1423 Mod->
Exports.push_back(Export);
1432 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1433 Top->UnresolvedDirectUses.clear();
1435 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1437 Top->DirectUses.push_back(DirectUse);
1439 Top->UnresolvedDirectUses.push_back(UDU);
1441 return !Top->UnresolvedDirectUses.empty();
1448 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1450 Conflict.
Other = OtherMod;
1451 Conflict.
Message = UC.Message;
1556 bool HadError =
false;
1560 llvm::BumpPtrAllocator StringData;
1566 Module *ActiveModule =
nullptr;
1586 void parseModuleDecl();
1587 void parseExternModuleDecl();
1588 void parseRequiresDecl();
1591 void parseExportDecl();
1592 void parseExportAsDecl();
1593 void parseUseDecl();
1594 void parseLinkDecl();
1595 void parseConfigMacros();
1596 void parseConflict();
1597 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1606 using Attributes = ModuleMap::Attributes;
1608 bool parseOptionalAttributes(Attributes &Attrs);
1615 : L(L), SourceMgr(SourceMgr),
Target(
Target), Diags(Diags), Map(Map),
1616 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {
1638 case tok::raw_identifier: {
1642 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1699 case tok::string_literal: {
1714 char *Saved = StringData.Allocate<
char>(Length + 1);
1725 case tok::numeric_constant: {
1728 SpellingBuffer.resize(LToken.
getLength() + 1);
1729 const char *Start = SpellingBuffer.data();
1733 if (StringRef(Start, Length).getAsInteger(0,
Value)) {
1753 auto NextIsIdent = [&](StringRef Str) ->
bool {
1758 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1759 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1776 unsigned braceDepth = 0;
1777 unsigned squareDepth = 0;
1784 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1791 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1805 if (squareDepth > 0)
1812 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1828bool ModuleMapParser::parseModuleId(
ModuleId &
Id) {
1852 enum AttributeKind {
1866 AT_no_undeclared_includes
1875void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1877 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1880 diag::note_mmap_rename_top_level_private_module);
1881 D << BadName << M->Name;
1886 auto const *M =
E->getValue();
1887 if (M->Directory != ActiveModule->
Directory)
1895 Canonical.append(
"_Private");
1898 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->Parent &&
1901 diag::warn_mmap_mismatched_private_submodule)
1906 FixItInitBegin = FrameworkLoc;
1908 FixItInitBegin = ExplicitLoc;
1911 FixedPrivModDecl.append(
"framework ");
1912 FixedPrivModDecl.append(
"module ");
1913 FixedPrivModDecl.append(Canonical);
1915 GenNoteAndFixIt(
FullName, FixedPrivModDecl, M,
1922 ActiveModule->
Name != Canonical) {
1924 diag::warn_mmap_mismatched_private_module_name)
1925 << ActiveModule->
Name;
1926 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M,
1950void ModuleMapParser::parseModuleDecl() {
1954 parseExternModuleDecl();
1962 bool Framework =
false;
1966 ExplicitLoc = consumeToken();
1972 FrameworkLoc = consumeToken();
1983 CurrModuleDeclLoc = consumeToken();
1988 return parseInferredModuleDecl(Framework,
Explicit);
1992 if (parseModuleId(
Id)) {
1998 if (
Id.size() > 1) {
1999 Diags.
Report(
Id.front().second, diag::err_mmap_nested_submodule_id)
2007 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
2013 Module *PreviousActiveModule = ActiveModule;
2014 if (
Id.size() > 1) {
2017 ActiveModule =
nullptr;
2018 const Module *TopLevelModule =
nullptr;
2019 for (
unsigned I = 0, N =
Id.size() - 1; I != N; ++I) {
2022 TopLevelModule = Next;
2023 ActiveModule = Next;
2027 Diags.
Report(
Id[I].second, diag::err_mmap_missing_parent_module)
2028 <<
Id[I].first << (ActiveModule !=
nullptr)
2035 if (TopLevelModule &&
2037 assert(ModuleMapFID !=
2039 "submodule defined in same file as 'module *' that allowed its "
2040 "top-level module");
2046 StringRef ModuleName =
Id.back().first;
2051 if (parseOptionalAttributes(Attrs))
2064 Module *ShadowingModule =
nullptr;
2072 bool Inferred = Existing->IsInferred;
2088 bool PartOfFramework = Framework || Existing->isPartOfFramework();
2091 bool ParsedAsMainInput =
2096 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
2097 ActiveModule = PreviousActiveModule;
2104 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2111 ShadowingModule = Existing;
2114 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2116 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2129 if (ShadowingModule) {
2138 if (Attrs.IsSystem || IsSystem)
2140 if (Attrs.IsExternC)
2142 if (Attrs.NoUndeclaredIncludes)
2146 StringRef MapFileName(
2148 if (MapFileName.ends_with(
"module.private.modulemap") ||
2149 MapFileName.ends_with(
"module_private.map")) {
2159 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_submodule,
2161 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_module_name,
2164 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2175 parseConfigMacros();
2194 parseExportAsDecl();
2202 parseRequiresDecl();
2214 parseUmbrellaDirDecl(UmbrellaLoc);
2245 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2265 ActiveModule = PreviousActiveModule;
2272void ModuleMapParser::parseExternModuleDecl() {
2287 if (parseModuleId(
Id)) {
2303 if (llvm::sys::path::is_relative(FileNameRef)) {
2304 ModuleMapFileName += Directory.
getName();
2305 llvm::sys::path::append(ModuleMapFileName,
FileName);
2306 FileNameRef = ModuleMapFileName;
2314 FileID(),
nullptr, ExternLoc);
2333 bool &IsRequiresExcludedHack) {
2334 if (Feature ==
"excluded" &&
2337 IsRequiresExcludedHack =
true;
2339 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2357void ModuleMapParser::parseRequiresDecl() {
2365 bool RequiredState =
true;
2367 RequiredState =
false;
2378 std::string Feature = std::string(Tok.
getString());
2381 bool IsRequiresExcludedHack =
false;
2382 bool ShouldAddRequirement =
2385 if (IsRequiresExcludedHack)
2386 UsesRequiresExcludedHack.insert(ActiveModule);
2388 if (ShouldAddRequirement) {
2390 ActiveModule->
addRequirement(Feature, RequiredState, Map.LangOpts,
2420 LeadingToken = Tok.
Kind;
2430 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2462 !std::holds_alternative<std::monostate>(ActiveModule->
Umbrella)) {
2478 switch (llvm::StringSwitch<Attribute>(Str)
2480 .Case(
"mtime", ModTime)
2484 Diags.
Report(
Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2487 diag::err_mmap_invalid_header_attribute_value) << Str;
2497 Diags.
Report(
Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2500 diag::err_mmap_invalid_header_attribute_value) << Str;
2509 Diags.
Report(
Loc, diag::err_mmap_expected_header_attribute);
2519 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2524 bool NeedsFramework =
false;
2528 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
2531 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2534 Diags.
Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2548void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2557 std::string DirName = std::string(Tok.
getString());
2558 std::string DirNameAsWritten = DirName;
2562 if (!std::holds_alternative<std::monostate>(ActiveModule->
Umbrella)) {
2563 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2571 if (llvm::sys::path::is_absolute(DirName)) {
2575 PathName = Directory.
getName();
2576 llvm::sys::path::append(PathName, DirName);
2581 Diags.
Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2586 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2593 llvm::vfs::FileSystem &FS =
2595 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC),
E;
2596 I !=
E && !EC; I.increment(EC)) {
2599 Headers.push_back(std::move(Header));
2606 for (
auto &Header : Headers)
2611 if (
Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2612 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2613 << OwningModule->getFullModuleName();
2631void ModuleMapParser::parseExportDecl() {
2637 bool Wildcard =
false;
2641 ParsedModuleId.push_back(
2665 ExportLoc, ParsedModuleId, Wildcard
2674void ModuleMapParser::parseExportAsDecl() {
2684 if (ActiveModule->
Parent) {
2711void ModuleMapParser::parseUseDecl() {
2713 auto KWLoc = consumeToken();
2716 parseModuleId(ParsedModuleId);
2718 if (ActiveModule->
Parent)
2719 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
2728void ModuleMapParser::parseLinkDecl() {
2733 bool IsFramework =
false;
2747 std::string LibraryName = std::string(Tok.
getString());
2760void ModuleMapParser::parseConfigMacros() {
2765 if (ActiveModule->
Parent) {
2766 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2771 if (parseOptionalAttributes(Attrs))
2774 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
2784 if (!ActiveModule->
Parent) {
2803 if (!ActiveModule->
Parent) {
2814 llvm::raw_string_ostream OS(result);
2816 for (
unsigned I = 0, N =
Id.size(); I != N; ++I) {
2830void ModuleMapParser::parseConflict() {
2836 if (parseModuleId(Conflict.
Id))
2869void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2872 bool Failed =
false;
2875 if (!ActiveModule && !Framework) {
2876 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2884 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2890 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2893 diag::note_mmap_prev_definition);
2899 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2903 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2921 if (parseOptionalAttributes(Attrs))
2931 Map.InferredDirectories[Directory].InferModules =
true;
2932 Map.InferredDirectories[Directory].Attrs = Attrs;
2933 Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID;
2957 << (ActiveModule !=
nullptr);
2969 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2975 if (!ActiveModule) {
2977 << (ActiveModule !=
nullptr);
2987 diag::err_mmap_expected_export_wildcard);
2998 << (ActiveModule !=
nullptr);
3008 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
3025bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
3026 bool HadError =
false;
3042 AttributeKind Attribute
3043 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
3044 .Case(
"exhaustive", AT_exhaustive)
3045 .Case(
"extern_c", AT_extern_c)
3046 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
3047 .Case(
"system", AT_system)
3048 .Default(AT_unknown);
3049 switch (Attribute) {
3056 Attrs.IsSystem =
true;
3060 Attrs.IsExternC =
true;
3064 Attrs.IsExhaustive =
true;
3067 case AT_no_undeclared_includes:
3068 Attrs.NoUndeclaredIncludes =
true;
3076 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
3140 assert(
Target &&
"Missing target information");
3141 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3142 = ParsedModuleMap.find(
File);
3143 if (Known != ParsedModuleMap.end())
3144 return Known->second;
3147 if (ID.isInvalid()) {
3148 auto FileCharacter =
3153 assert(
Target &&
"Missing target information");
3154 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.
getBufferOrNone(ID);
3156 return ParsedModuleMap[
File] =
true;
3157 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
3158 "invalid buffer offset");
3162 Buffer->getBufferStart(),
3163 Buffer->getBufferStart() + (Offset ? *Offset : 0),
3164 Buffer->getBufferEnd());
3172 assert(
Loc.first == ID &&
"stopped in a different file?");
3173 *Offset =
Loc.second;
3177 for (
const auto &Cb : Callbacks)
3178 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.
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_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified directory (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,...
Required to construct a Module.
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 * findOrCreateModuleFirst(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Call ModuleMap::findOrCreateModule and throw away the information whether the module was found or cre...
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 * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Create new submodule, assuming it does not exist.
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.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
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.
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.
void addHeader(HeaderKind HK, Header H)
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.
ArrayRef< Header > getHeaders(HeaderKind HK) const
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.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
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 ...