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().endswith(
".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 ||
346 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.
FileName);
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 &&
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;
504 Module *Private =
nullptr;
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;
656 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
659 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
660 Result->IsInferred =
true;
663 UmbrellaDirs[SkippedDir] =
Result;
674 llvm::sys::path::stem(
File.getName()), NameBuf);
677 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
678 Result->IsInferred =
true;
688 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
689 UmbrellaDirs[SkippedDirs[I]] =
Result;
693 Headers[
File].push_back(Header);
702 HeadersMap::iterator Known = findKnownHeader(
File);
703 if (Known != Headers.end())
704 return Known->second;
706 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
707 return Headers.find(
File)->second;
716 auto It = Headers.find(
File);
717 if (It == Headers.end())
729 HeadersMap::const_iterator Known = Headers.find(Header);
730 if (Known != Headers.end()) {
732 I = Known->second.begin(),
733 E = Known->second.end();
739 if (I->isAvailable() &&
740 (!RequestingModule ||
757 StringRef DirName = Dir->
getName();
759 auto IsUnavailable = [&](
const Module *M) {
767 auto KnownDir = UmbrellaDirs.find(*Dir);
768 if (KnownDir != UmbrellaDirs.end()) {
769 Module *Found = KnownDir->second;
770 if (IsUnavailable(Found))
775 Module *UmbrellaModule = Found;
778 UmbrellaModule = UmbrellaModule->
Parent;
785 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
789 if (IsUnavailable(Found))
796 llvm::sys::path::stem(Header.
getName()),
803 return IsUnavailable(Found);
806 SkippedDirs.push_back(*Dir);
809 DirName = llvm::sys::path::parent_path(DirName);
821 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
822 if (Known != Modules.end())
823 return Known->getValue();
830 for(; Context; Context = Context->Parent) {
842 return Context->findSubmodule(Name);
851 return std::make_pair(Sub,
false);
855 IsExplicit, NumCreatedModules++);
860 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
862 return std::make_pair(
Result,
true);
868 true, NumCreatedModules++);
873 PendingSubmodules.emplace_back(
Result);
879 assert(
Parent &&
"We should only create an implicit global module fragment "
880 "in a module purview");
884 auto *
Result =
new Module(IsExported ?
"<exported implicit global>"
885 :
"<implicit global>",
887 !IsExported, NumCreatedModules++);
897 true, NumCreatedModules++);
905 new Module(Name, Loc,
nullptr,
false,
906 false, NumCreatedModules++);
910 for (
auto &Submodule : PendingSubmodules) {
911 Submodule->setParent(
Result);
914 PendingSubmodules.clear();
920 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
921 assert(!Modules[Name] &&
"redefining existing module");
925 Modules[Name] = SourceModule =
Result;
930 assert(MainFile &&
"no input file for module interface");
938 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
941 "creating implementation module without an interface");
946 StringRef IName =
".ImplementationUnit";
947 assert(!Modules[IName] &&
"multiple implementation units?");
951 Modules[IName] = SourceModule =
Result;
955 "no input file for module implementation");
962 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
963 assert(!Modules[Name] &&
"redefining existing module");
966 false, NumCreatedModules++);
968 Modules[Name] = SourceModule =
Result;
976 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
978 "Can only infer linking for top-level frameworks");
988 return inferFrameworkModule(FrameworkDir, Attrs,
Parent);
997 StringRef FrameworkDirName =
1005 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1018 bool canInfer =
false;
1019 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1021 StringRef
Parent = llvm::sys::path::parent_path(FrameworkDirName);
1025 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1026 inferred = InferredDirectories.find(*ParentDir);
1027 if (inferred == InferredDirectories.end()) {
1030 bool IsFrameworkDir =
Parent.endswith(
".framework");
1034 inferred = InferredDirectories.find(*ParentDir);
1037 if (inferred == InferredDirectories.end())
1038 inferred = InferredDirectories.insert(
1039 std::make_pair(*ParentDir, InferredDirectory())).first;
1042 if (inferred->second.InferModules) {
1045 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1047 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1049 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1050 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1051 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1052 Attrs.NoUndeclaredIncludes |=
1053 inferred->second.Attrs.NoUndeclaredIncludes;
1054 ModuleMapFile = inferred->second.ModuleMapFile;
1065 ModuleMapFile = ModuleMapRef;
1070 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1076 if (!UmbrellaHeader)
1081 NumCreatedModules++);
1082 InferredModuleAllowedBy[
Result] = ModuleMapFile;
1083 Result->IsInferred =
true;
1087 Modules[ModuleName] =
Result;
1088 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1091 Result->IsSystem |= Attrs.IsSystem;
1092 Result->IsExternC |= Attrs.IsExternC;
1093 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1094 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1095 Result->Directory = FrameworkDir;
1098 StringRef RelativePath = UmbrellaName.str().substr(
1099 Result->getTopLevelModule()->Directory->getName().size());
1100 RelativePath = llvm::sys::path::relative_path(RelativePath);
1110 Result->InferSubmodules =
true;
1111 Result->InferExportWildcard =
true;
1116 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1117 llvm::sys::path::native(SubframeworksDirName);
1119 for (llvm::vfs::directory_iterator
1120 Dir = FS.dir_begin(SubframeworksDirName, EC),
1122 Dir != DirEnd && !EC; Dir.increment(EC)) {
1123 if (!StringRef(Dir->path()).endswith(
".framework"))
1131 StringRef SubframeworkDirName =
1133 bool FoundParent =
false;
1137 = llvm::sys::path::parent_path(SubframeworkDirName);
1138 if (SubframeworkDirName.empty())
1141 if (
auto SubDir = FileMgr.
getDirectory(SubframeworkDirName)) {
1142 if (*SubDir == FrameworkDir) {
1153 inferFrameworkModule(*SubframeworkDir, Attrs,
Result);
1159 if (!
Result->isSubFramework())
1166 Module *ShadowingModule) {
1171 false, NumCreatedModules++);
1172 Result->ShadowingModule = ShadowingModule;
1173 Result->markUnavailable(
true);
1174 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1175 ShadowModules.push_back(
Result);
1182 const Twine &PathRelativeToRootModuleDirectory) {
1187 PathRelativeToRootModuleDirectory.str();
1188 UmbrellaDirs[UmbrellaHeader.
getDir()] = Mod;
1191 for (
const auto &Cb : Callbacks)
1192 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1197 const Twine &PathRelativeToRootModuleDirectory) {
1201 PathRelativeToRootModuleDirectory.str();
1202 UmbrellaDirs[UmbrellaDir] = Mod;
1205void ModuleMap::addUnresolvedHeader(
Module *Mod,
1207 bool &NeedsFramework) {
1210 if (resolveAsBuiltinHeader(Mod, Header)) {
1229 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1231 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1238 resolveHeader(Mod, Header, NeedsFramework);
1242 auto BySize = LazyHeadersBySize.find(
File->getSize());
1243 if (BySize != LazyHeadersBySize.end()) {
1244 for (
auto *M : BySize->second)
1246 LazyHeadersBySize.erase(BySize);
1249 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1250 if (ByModTime != LazyHeadersByModTime.end()) {
1251 for (
auto *M : ByModTime->second)
1253 LazyHeadersByModTime.erase(ByModTime);
1258 Module *Mod, std::optional<const FileEntry *>
File)
const {
1259 bool NeedsFramework =
false;
1261 const auto Size =
File ? (*File)->getSize() : 0;
1262 const auto ModTime =
File ? (*File)->getModificationTime() : 0;
1266 (Header.
Size && Header.
Size != Size)))
1267 NewHeaders.push_back(Header);
1271 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1283 auto &HeaderList = Headers[Header.
Entry];
1284 if (llvm::is_contained(HeaderList, KH))
1287 HeaderList.push_back(KH);
1290 bool isCompilingModuleHeader = Mod->
isForBuilding(LangOpts);
1291 if (!Imported || isCompilingModuleHeader) {
1295 isCompilingModuleHeader);
1299 for (
const auto &Cb : Callbacks)
1306 return std::nullopt;
1315 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1316 return InferredModuleAllowedBy.find(M)->second;
1323 assert(M->
IsInferred &&
"module not inferred");
1324 InferredModuleAllowedBy[M] = ModMap;
1329 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1333 if (llvm::sys::path::filename(Dir) ==
"Modules") {
1334 StringRef
Parent = llvm::sys::path::parent_path(Dir);
1335 if (
Parent.endswith(
".framework"))
1342 return llvm::errorToErrorCode(DirEntry.takeError());
1346 if (CanonicalDir != Dir)
1347 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1355 llvm::sys::path::remove_dots(Path);
1357 return std::error_code();
1366 llvm::errs() <<
"Modules:";
1367 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1368 MEnd = Modules.end();
1370 M->getValue()->
print(llvm::errs(), 2);
1372 llvm::errs() <<
"Headers:";
1373 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1375 llvm::errs() <<
" \"" << H->first.getName() <<
"\" -> ";
1377 E = H->second.end();
1379 if (I != H->second.begin())
1380 llvm::errs() <<
",";
1381 llvm::errs() << I->getModule()->getFullModuleName();
1383 llvm::errs() <<
"\n";
1392 if (Export.getPointer() || Export.getInt())
1393 Mod->
Exports.push_back(Export);
1404 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1417 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1419 Conflict.
Other = OtherMod;
1420 Conflict.
Message = UC.Message;
1525 bool HadError =
false;
1529 llvm::BumpPtrAllocator StringData;
1535 Module *ActiveModule =
nullptr;
1557 void parseModuleDecl();
1558 void parseExternModuleDecl();
1559 void parseRequiresDecl();
1562 void parseExportDecl();
1563 void parseExportAsDecl();
1564 void parseUseDecl();
1565 void parseLinkDecl();
1566 void parseConfigMacros();
1567 void parseConflict();
1568 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1577 using Attributes = ModuleMap::Attributes;
1579 bool parseOptionalAttributes(Attributes &Attrs);
1586 : L(L), SourceMgr(SourceMgr),
Target(
Target), Diags(Diags), Map(Map),
1587 ModuleMapFile(ModuleMapFile), Directory(Directory),
1588 IsSystem(IsSystem) {
1610 case tok::raw_identifier: {
1614 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1671 case tok::string_literal: {
1686 char *Saved = StringData.Allocate<
char>(Length + 1);
1697 case tok::numeric_constant: {
1700 SpellingBuffer.resize(LToken.
getLength() + 1);
1701 const char *Start = SpellingBuffer.data();
1705 if (StringRef(Start, Length).getAsInteger(0,
Value)) {
1725 auto NextIsIdent = [&](StringRef Str) ->
bool {
1730 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1731 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1748 unsigned braceDepth = 0;
1749 unsigned squareDepth = 0;
1756 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1763 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1777 if (squareDepth > 0)
1784 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1800bool ModuleMapParser::parseModuleId(
ModuleId &
Id) {
1824 enum AttributeKind {
1838 AT_no_undeclared_includes
1847void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1849 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1852 diag::note_mmap_rename_top_level_private_module);
1853 D << BadName << M->Name;
1858 auto const *M = E->getValue();
1859 if (M->Directory != ActiveModule->
Directory)
1863 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1867 Canonical.append(
"_Private");
1870 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->Parent &&
1873 diag::warn_mmap_mismatched_private_submodule)
1878 FixItInitBegin = FrameworkLoc;
1880 FixItInitBegin = ExplicitLoc;
1883 FixedPrivModDecl.append(
"framework ");
1884 FixedPrivModDecl.append(
"module ");
1885 FixedPrivModDecl.append(Canonical);
1887 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1894 ActiveModule->
Name != Canonical) {
1896 diag::warn_mmap_mismatched_private_module_name)
1897 << ActiveModule->
Name;
1898 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M,
1922void ModuleMapParser::parseModuleDecl() {
1926 parseExternModuleDecl();
1933 bool Explicit =
false;
1934 bool Framework =
false;
1938 ExplicitLoc = consumeToken();
1944 FrameworkLoc = consumeToken();
1955 CurrModuleDeclLoc = consumeToken();
1960 return parseInferredModuleDecl(Framework, Explicit);
1964 if (parseModuleId(
Id)) {
1970 if (
Id.size() > 1) {
1971 Diags.
Report(
Id.front().second, diag::err_mmap_nested_submodule_id)
1977 }
else if (
Id.size() == 1 && Explicit) {
1979 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1985 Module *PreviousActiveModule = ActiveModule;
1986 if (
Id.size() > 1) {
1989 ActiveModule =
nullptr;
1990 const Module *TopLevelModule =
nullptr;
1991 for (
unsigned I = 0, N =
Id.size() - 1; I != N; ++I) {
1994 TopLevelModule = Next;
1995 ActiveModule = Next;
1999 Diags.
Report(
Id[I].second, diag::err_mmap_missing_parent_module)
2000 <<
Id[I].first << (ActiveModule !=
nullptr)
2007 if (TopLevelModule &&
2010 "submodule defined in same file as 'module *' that allowed its "
2011 "top-level module");
2016 StringRef ModuleName =
Id.back().first;
2021 if (parseOptionalAttributes(Attrs))
2034 Module *ShadowingModule =
nullptr;
2042 bool Inferred = Existing->IsInferred;
2058 bool PartOfFramework = Framework || Existing->isPartOfFramework();
2061 bool ParsedAsMainInput =
2066 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
2067 ActiveModule = PreviousActiveModule;
2074 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2081 ShadowingModule = Existing;
2084 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2086 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2099 if (ShadowingModule) {
2109 if (Attrs.IsSystem || IsSystem)
2111 if (Attrs.IsExternC)
2113 if (Attrs.NoUndeclaredIncludes)
2117 StringRef MapFileName(ModuleMapFile.getName());
2118 if (MapFileName.endswith(
"module.private.modulemap") ||
2119 MapFileName.endswith(
"module_private.map")) {
2129 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_submodule,
2131 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_module_name,
2134 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2145 parseConfigMacros();
2164 parseExportAsDecl();
2172 parseRequiresDecl();
2184 parseUmbrellaDirDecl(UmbrellaLoc);
2215 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2235 ActiveModule = PreviousActiveModule;
2242void ModuleMapParser::parseExternModuleDecl() {
2257 if (parseModuleId(
Id)) {
2268 std::string FileName = std::string(Tok.
getString());
2271 StringRef FileNameRef = FileName;
2273 if (llvm::sys::path::is_relative(FileNameRef)) {
2274 ModuleMapFileName += Directory.
getName();
2275 llvm::sys::path::append(ModuleMapFileName, FileName);
2276 FileNameRef = ModuleMapFileName;
2284 FileID(),
nullptr, ExternLoc);
2303 bool &IsRequiresExcludedHack) {
2304 if (Feature ==
"excluded" &&
2307 IsRequiresExcludedHack =
true;
2309 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2327void ModuleMapParser::parseRequiresDecl() {
2335 bool RequiredState =
true;
2337 RequiredState =
false;
2348 std::string Feature = std::string(Tok.
getString());
2351 bool IsRequiresExcludedHack =
false;
2352 bool ShouldAddRequirement =
2355 if (IsRequiresExcludedHack)
2356 UsesRequiresExcludedHack.insert(ActiveModule);
2358 if (ShouldAddRequirement) {
2360 ActiveModule->
addRequirement(Feature, RequiredState, Map.LangOpts,
2390 LeadingToken = Tok.
Kind;
2400 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2447 switch (llvm::StringSwitch<Attribute>(Str)
2449 .Case(
"mtime", ModTime)
2453 Diags.
Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2456 diag::err_mmap_invalid_header_attribute_value) << Str;
2466 Diags.
Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2469 diag::err_mmap_invalid_header_attribute_value) << Str;
2478 Diags.
Report(Loc, diag::err_mmap_expected_header_attribute);
2488 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2493 bool NeedsFramework =
false;
2497 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2500 Diags.
Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2514void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2523 std::string DirName = std::string(Tok.
getString());
2524 std::string DirNameAsWritten = DirName;
2529 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2537 if (llvm::sys::path::is_absolute(DirName)) {
2541 PathName = Directory.
getName();
2542 llvm::sys::path::append(PathName, DirName);
2547 Diags.
Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2552 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2559 llvm::vfs::FileSystem &FS =
2561 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2562 I != E && !EC; I.increment(EC)) {
2565 Headers.push_back(std::move(Header));
2572 for (
auto &Header : Headers)
2577 if (
Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2578 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2579 << OwningModule->getFullModuleName();
2597void ModuleMapParser::parseExportDecl() {
2603 bool Wildcard =
false;
2607 ParsedModuleId.push_back(
2631 ExportLoc, ParsedModuleId, Wildcard
2640void ModuleMapParser::parseExportAsDecl() {
2650 if (ActiveModule->
Parent) {
2677void ModuleMapParser::parseUseDecl() {
2679 auto KWLoc = consumeToken();
2682 parseModuleId(ParsedModuleId);
2684 if (ActiveModule->
Parent)
2685 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
2694void ModuleMapParser::parseLinkDecl() {
2699 bool IsFramework =
false;
2713 std::string LibraryName = std::string(Tok.
getString());
2726void ModuleMapParser::parseConfigMacros() {
2731 if (ActiveModule->
Parent) {
2732 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2737 if (parseOptionalAttributes(Attrs))
2740 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
2750 if (!ActiveModule->
Parent) {
2769 if (!ActiveModule->
Parent) {
2780 llvm::raw_string_ostream OS(result);
2782 for (
unsigned I = 0, N =
Id.size(); I != N; ++I) {
2796void ModuleMapParser::parseConflict() {
2802 if (parseModuleId(Conflict.
Id))
2835void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2838 bool Failed =
false;
2841 if (!ActiveModule && !Framework) {
2842 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2850 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2856 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2859 diag::note_mmap_prev_definition);
2865 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2868 }
else if (Explicit) {
2869 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2887 if (parseOptionalAttributes(Attrs))
2897 Map.InferredDirectories[Directory].InferModules =
true;
2898 Map.InferredDirectories[Directory].Attrs = Attrs;
2899 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2923 << (ActiveModule !=
nullptr);
2935 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2941 if (!ActiveModule) {
2943 << (ActiveModule !=
nullptr);
2953 diag::err_mmap_expected_export_wildcard);
2964 << (ActiveModule !=
nullptr);
2974 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2991bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2992 bool HadError =
false;
3008 AttributeKind Attribute
3009 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
3010 .Case(
"exhaustive", AT_exhaustive)
3011 .Case(
"extern_c", AT_extern_c)
3012 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
3013 .Case(
"system", AT_system)
3014 .Default(AT_unknown);
3015 switch (Attribute) {
3022 Attrs.IsSystem =
true;
3026 Attrs.IsExternC =
true;
3030 Attrs.IsExhaustive =
true;
3033 case AT_no_undeclared_includes:
3034 Attrs.NoUndeclaredIncludes =
true;
3042 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
3106 assert(Target &&
"Missing target information");
3107 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3108 = ParsedModuleMap.find(
File);
3109 if (Known != ParsedModuleMap.end())
3110 return Known->second;
3113 if (ID.isInvalid()) {
3114 auto FileCharacter =
3119 assert(Target &&
"Missing target information");
3120 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.
getBufferOrNone(ID);
3122 return ParsedModuleMap[
File] =
true;
3123 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
3124 "invalid buffer offset");
3128 Buffer->getBufferStart(),
3129 Buffer->getBufferStart() + (Offset ? *Offset : 0),
3130 Buffer->getBufferEnd());
3139 assert(Loc.first == ID &&
"stopped in a different file?");
3140 *Offset = Loc.second;
3144 for (
const auto &Cb : Callbacks)
3145 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.
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 int 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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
@ CMK_ModuleMap
Compiling a module from a module map.
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,...
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, FileEntryRef ModuleMapFile, DirectoryEntryRef Directory, bool IsSystem)
SourceLocation getLocation()
bool terminatedByDirective()
bool parseModuleMapFile()
Parse a module map file.
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
Retrieve the module map file containing the definition of the given module.
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.
void setInferredModuleAllowedBy(Module *M, OptionalFileEntryRef ModMap)
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
Get the module map file that (along with the module name) uniquely identifies this module.
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.
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'.
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.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, bool IsExported, Module *Parent=nullptr)
~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 * 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.
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.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr Directory
The build directory of this module.
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
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.
SmallVector< Module *, 2 > DirectUses
The directly 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....
bool isSubModule() const
Determine whether this module is a submodule.
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.
llvm::PointerUnion< FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
@ 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.
Wrapper around OptionalFileEntryRef that degrades to 'const FileEntry*', facilitating incremental pat...
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.
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
FileID createFileID(const FileEntry *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...
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)
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].
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c, bool AllowDollar=false)
Returns true if this is a body character of a C identifier, which is [a-zA-Z0-9_].
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
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 ...