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;
256void ModuleMap::resolveHeader(
Module *Mod,
258 bool &NeedsFramework) {
261 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
264 if (
Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
266 << UmbrellaMod->getFullModuleName();
293bool ModuleMap::resolveAsBuiltinHeader(
296 llvm::sys::path::is_absolute(Header.
FileName) ||
298 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->
Directory ||
306 llvm::sys::path::append(Path, BuiltinIncludeDir->
getName(), Header.
FileName);
320 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts),
Target(
Target),
321 HeaderInfo(HeaderInfo) {
322 MMapLangOpts.LineComment =
true;
326 for (
auto &M : Modules)
328 for (
auto *M : ShadowModules)
333 assert((!this->Target || this->Target == &
Target) &&
334 "Improper target override");
349 Buffer.push_back(
'_');
350 Buffer.reserve(Buffer.size() + Name.size());
351 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
353 Buffer.push_back(Name[I]);
355 Buffer.push_back(
'_');
358 Name = StringRef(Buffer.data(), Buffer.size());
361 while (llvm::StringSwitch<bool>(Name)
362#define
KEYWORD(Keyword,Conditions) .Case(#Keyword,
true)
363#define
ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword,
true)
364#include
"clang/Basic/TokenKinds.def"
366 if (Name.data() != Buffer.data())
367 Buffer.append(Name.begin(), Name.end());
368 Buffer.push_back(
'_');
369 Name = StringRef(Buffer.data(), Buffer.size());
379 return llvm::StringSwitch<bool>(FileName)
380 .Case(
"float.h",
true)
381 .Case(
"iso646.h",
true)
382 .Case(
"limits.h",
true)
383 .Case(
"stdalign.h",
true)
384 .Case(
"stdarg.h",
true)
385 .Case(
"stdatomic.h",
true)
386 .Case(
"stdbool.h",
true)
387 .Case(
"stddef.h",
true)
388 .Case(
"stdint.h",
true)
389 .Case(
"tgmath.h",
true)
390 .Case(
"unwind.h",
true)
395 return File->getDir() == BuiltinIncludeDir &&
399ModuleMap::HeadersMap::iterator
402 HeadersMap::iterator Known = Headers.find(
File);
406 return Headers.find(
File);
414 if (UmbrellaDirs.empty())
418 assert(Dir &&
"file in no directory");
429 auto KnownDir = UmbrellaDirs.find(Dir);
430 if (KnownDir != UmbrellaDirs.end())
433 IntermediateDirs.push_back(Dir);
436 DirName = llvm::sys::path::parent_path(DirName);
457 bool IsPrivate =
false;
461 for (
auto *Hs : HeaderList)
462 IsPrivate |= llvm::any_of(
464 assert(IsPrivate &&
"inconsistent headers and roles");
475 bool RequestingModuleIsModuleInterface,
483 if (RequestingModule) {
488 bool Excluded =
false;
489 Module *Private =
nullptr;
490 Module *NotUsed =
nullptr;
492 HeadersMap::iterator Known = findKnownHeader(
File);
493 if (Known != Headers.end()) {
509 if (RequestingModule && LangOpts.ModulesDeclUse &&
524 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
531 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
537 if (Excluded || isHeaderInUmbrellaDirs(
File))
542 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
543 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
545 }
else if (RequestingModule && RequestingModuleIsModuleInterface &&
549 diag::warn_non_modular_include_in_framework_module :
550 diag::warn_non_modular_include_in_module;
586 bool AllowExcluded) {
593 HeadersMap::iterator Known = findKnownHeader(
File);
594 if (Known != Headers.end()) {
603 return MakeResult(H);
607 return MakeResult(
Result);
610 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(
File));
614ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *
File) {
615 assert(!Headers.count(
File) &&
"already have a module for this header");
618 KnownHeader H = findHeaderInUmbrellaDirs(
File, SkippedDirs);
626 UmbrellaModule = UmbrellaModule->
Parent;
637 for (
const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) {
641 llvm::sys::path::stem(SkippedDir->getName()), NameBuf);
644 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
645 Result->IsInferred =
true;
648 UmbrellaDirs[SkippedDir] =
Result;
659 llvm::sys::path::stem(
File->getName()), NameBuf);
662 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
663 Result->IsInferred =
true;
673 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
674 UmbrellaDirs[SkippedDirs[I]] =
Result;
678 Headers[
File].push_back(Header);
687 HeadersMap::iterator Known = findKnownHeader(
File);
688 if (Known != Headers.end())
689 return Known->second;
691 if (findOrCreateModuleForHeaderInUmbrellaDir(
File))
692 return Headers.find(
File)->second;
701 auto It = Headers.find(
File);
702 if (It == Headers.end())
713 const Module *RequestingModule)
const {
715 HeadersMap::const_iterator Known = Headers.find(Header);
716 if (Known != Headers.end()) {
718 I = Known->second.begin(),
719 E = Known->second.end();
725 if (I->isAvailable() &&
726 (!RequestingModule ||
743 StringRef DirName = Dir->
getName();
745 auto IsUnavailable = [&](
const Module *M) {
753 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
754 = UmbrellaDirs.find(Dir);
755 if (KnownDir != UmbrellaDirs.end()) {
756 Module *Found = KnownDir->second;
757 if (IsUnavailable(Found))
762 Module *UmbrellaModule = Found;
764 UmbrellaModule = UmbrellaModule->
Parent;
767 for (
const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) {
771 llvm::sys::path::stem(SkippedDir->getName()), NameBuf);
775 if (IsUnavailable(Found))
782 llvm::sys::path::stem(Header->
getName()),
789 return IsUnavailable(Found);
792 SkippedDirs.push_back(Dir);
795 DirName = llvm::sys::path::parent_path(DirName);
810 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
811 if (Known != Modules.end())
812 return Known->getValue();
819 for(; Context; Context = Context->Parent) {
831 return Context->findSubmodule(Name);
840 return std::make_pair(Sub,
false);
844 IsExplicit, NumCreatedModules++);
849 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
851 return std::make_pair(
Result,
true);
857 true, NumCreatedModules++);
862 PendingSubmodules.emplace_back(
Result);
868 assert(
Parent &&
"We should only create an implicit global module fragment "
869 "in a module purview");
873 auto *
Result =
new Module(IsExported ?
"<exported implicit global>"
874 :
"<implicit global>",
876 !IsExported, NumCreatedModules++);
886 true, NumCreatedModules++);
893 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
894 assert(!Modules[Name] &&
"redefining existing module");
897 new Module(Name, Loc,
nullptr,
false,
898 false, NumCreatedModules++);
900 Modules[Name] = SourceModule =
Result;
903 for (
auto &Submodule : PendingSubmodules) {
904 Submodule->setParent(
Result);
907 PendingSubmodules.clear();
912 assert(MainFile &&
"no input file for module interface");
920 assert(LangOpts.
CurrentModule == Name &&
"module name mismatch");
921 assert(!Modules[Name] &&
"redefining existing module");
924 false, NumCreatedModules++);
926 Modules[Name] = SourceModule =
Result;
934 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
936 "Can only infer linking for top-level frameworks");
946 return inferFrameworkModule(FrameworkDir, Attrs,
Parent);
955 StringRef FrameworkDirName =
963 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
973 const FileEntry *ModuleMapFile =
nullptr;
976 bool canInfer =
false;
977 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
979 StringRef
Parent = llvm::sys::path::parent_path(FrameworkDirName);
983 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
984 inferred = InferredDirectories.find(*ParentDir);
985 if (inferred == InferredDirectories.end()) {
988 bool IsFrameworkDir =
Parent.endswith(
".framework");
992 inferred = InferredDirectories.find(*ParentDir);
995 if (inferred == InferredDirectories.end())
996 inferred = InferredDirectories.insert(
997 std::make_pair(*ParentDir, InferredDirectory())).first;
1000 if (inferred->second.InferModules) {
1003 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1005 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1007 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1008 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1009 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1010 Attrs.NoUndeclaredIncludes |=
1011 inferred->second.Attrs.NoUndeclaredIncludes;
1012 ModuleMapFile = inferred->second.ModuleMapFile;
1023 ModuleMapFile = ModuleMapRef;
1028 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
1034 if (!UmbrellaHeader)
1039 NumCreatedModules++);
1040 InferredModuleAllowedBy[
Result] = ModuleMapFile;
1041 Result->IsInferred =
true;
1045 Modules[ModuleName] =
Result;
1046 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1049 Result->IsSystem |= Attrs.IsSystem;
1050 Result->IsExternC |= Attrs.IsExternC;
1051 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1052 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1053 Result->Directory = FrameworkDir;
1056 StringRef RelativePath = UmbrellaName.str().substr(
1057 Result->getTopLevelModule()->Directory->getName().size());
1058 RelativePath = llvm::sys::path::relative_path(RelativePath);
1067 Result->InferSubmodules =
true;
1068 Result->InferExportWildcard =
true;
1073 = StringRef(FrameworkDir->
getName());
1074 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
1075 llvm::sys::path::native(SubframeworksDirName);
1077 for (llvm::vfs::directory_iterator
1078 Dir = FS.dir_begin(SubframeworksDirName, EC),
1080 Dir != DirEnd && !EC; Dir.increment(EC)) {
1081 if (!StringRef(Dir->path()).endswith(
".framework"))
1084 if (
auto SubframeworkDir =
1090 StringRef SubframeworkDirName =
1092 bool FoundParent =
false;
1096 = llvm::sys::path::parent_path(SubframeworkDirName);
1097 if (SubframeworkDirName.empty())
1100 if (
auto SubDir = FileMgr.
getDirectory(SubframeworkDirName)) {
1101 if (*SubDir == FrameworkDir) {
1112 inferFrameworkModule(*SubframeworkDir, Attrs,
Result);
1118 if (!
Result->isSubFramework())
1125 Module *ShadowingModule) {
1130 false, NumCreatedModules++);
1131 Result->ShadowingModule = ShadowingModule;
1132 Result->markUnavailable(
true);
1133 ModuleScopeIDs[
Result] = CurrentModuleScopeID;
1134 ShadowModules.push_back(
Result);
1141 const Twine &PathRelativeToRootModuleDirectory) {
1146 PathRelativeToRootModuleDirectory.str();
1147 UmbrellaDirs[UmbrellaHeader.
getDir()] = Mod;
1150 for (
const auto &Cb : Callbacks)
1151 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
1155 const Twine &NameAsWritten,
1156 const Twine &PathRelativeToRootModuleDirectory) {
1160 PathRelativeToRootModuleDirectory.str();
1161 UmbrellaDirs[UmbrellaDir] = Mod;
1164void ModuleMap::addUnresolvedHeader(
Module *Mod,
1166 bool &NeedsFramework) {
1169 if (resolveAsBuiltinHeader(Mod, Header)) {
1188 LazyHeadersByModTime[*Header.
ModTime].push_back(Mod);
1190 LazyHeadersBySize[*Header.
Size].push_back(Mod);
1197 resolveHeader(Mod, Header, NeedsFramework);
1201 auto BySize = LazyHeadersBySize.find(
File->getSize());
1202 if (BySize != LazyHeadersBySize.end()) {
1203 for (
auto *M : BySize->second)
1205 LazyHeadersBySize.erase(BySize);
1208 auto ByModTime = LazyHeadersByModTime.find(
File->getModificationTime());
1209 if (ByModTime != LazyHeadersByModTime.end()) {
1210 for (
auto *M : ByModTime->second)
1212 LazyHeadersByModTime.erase(ByModTime);
1217 Module *Mod, std::optional<const FileEntry *>
File)
const {
1218 bool NeedsFramework =
false;
1220 const auto Size =
File ? (*File)->getSize() : 0;
1221 const auto ModTime =
File ? (*File)->getModificationTime() : 0;
1225 (Header.
Size && Header.
Size != Size)))
1226 NewHeaders.push_back(Header);
1230 const_cast<ModuleMap *
>(
this)->resolveHeader(Mod, Header, NeedsFramework);
1242 auto &HeaderList = Headers[Header.
Entry];
1243 if (llvm::is_contained(HeaderList, KH))
1246 HeaderList.push_back(KH);
1249 bool isCompilingModuleHeader =
1251 if (!Imported || isCompilingModuleHeader) {
1255 isCompilingModuleHeader);
1259 for (
const auto &Cb : Callbacks)
1260 Cb->moduleMapAddHeader(Header.
Entry->getName());
1266 return std::nullopt;
1275 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
1277 return InferredModuleAllowedBy.find(M)->second->getLastRef();
1283 assert(M->
IsInferred &&
"module not inferred");
1284 InferredModuleAllowedBy[M] = ModMap;
1289 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1293 if (llvm::sys::path::filename(Dir) ==
"Modules") {
1294 StringRef
Parent = llvm::sys::path::parent_path(Dir);
1295 if (
Parent.endswith(
".framework"))
1300 auto DirEntry = FM.
getDirectory(Dir.empty() ?
"." : Dir);
1302 return DirEntry.getError();
1306 if (CanonicalDir != Dir) {
1307 auto CanonicalDirEntry = FM.
getDirectory(CanonicalDir);
1312 if (CanonicalDirEntry && *CanonicalDirEntry == *DirEntry) {
1313 bool Done = llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1315 assert(Done &&
"Path should always start with Dir");
1325 llvm::sys::path::remove_dots(Path);
1327 return std::error_code();
1336 llvm::errs() <<
"Modules:";
1337 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1338 MEnd = Modules.end();
1340 M->getValue()->
print(llvm::errs(), 2);
1342 llvm::errs() <<
"Headers:";
1343 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1345 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
1347 E = H->second.end();
1349 if (I != H->second.begin())
1350 llvm::errs() <<
",";
1351 llvm::errs() << I->getModule()->getFullModuleName();
1353 llvm::errs() <<
"\n";
1362 if (Export.getPointer() || Export.getInt())
1363 Mod->
Exports.push_back(Export);
1374 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1387 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1389 Conflict.
Other = OtherMod;
1390 Conflict.
Message = UC.Message;
1495 bool HadError =
false;
1499 llvm::BumpPtrAllocator StringData;
1505 Module *ActiveModule =
nullptr;
1527 void parseModuleDecl();
1528 void parseExternModuleDecl();
1529 void parseRequiresDecl();
1532 void parseExportDecl();
1533 void parseExportAsDecl();
1534 void parseUseDecl();
1535 void parseLinkDecl();
1536 void parseConfigMacros();
1537 void parseConflict();
1538 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1547 using Attributes = ModuleMap::Attributes;
1549 bool parseOptionalAttributes(Attributes &Attrs);
1556 : L(L), SourceMgr(SourceMgr),
Target(
Target), Diags(Diags), Map(Map),
1557 ModuleMapFile(ModuleMapFile), Directory(Directory),
1558 IsSystem(IsSystem) {
1580 case tok::raw_identifier: {
1584 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1641 case tok::string_literal: {
1656 char *Saved = StringData.Allocate<
char>(Length + 1);
1667 case tok::numeric_constant: {
1670 SpellingBuffer.resize(LToken.
getLength() + 1);
1671 const char *Start = SpellingBuffer.data();
1675 if (StringRef(Start, Length).getAsInteger(0,
Value)) {
1695 auto NextIsIdent = [&](StringRef Str) ->
bool {
1700 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
1701 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
1718 unsigned braceDepth = 0;
1719 unsigned squareDepth = 0;
1726 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1733 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1747 if (squareDepth > 0)
1754 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1770bool ModuleMapParser::parseModuleId(
ModuleId &
Id) {
1794 enum AttributeKind {
1808 AT_no_undeclared_includes
1817void ModuleMapParser::diagnosePrivateModules(
SourceLocation ExplicitLoc,
1819 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1822 diag::note_mmap_rename_top_level_private_module);
1823 D << BadName << M->Name;
1828 auto const *M = E->getValue();
1829 if (M->Directory != ActiveModule->
Directory)
1833 if (!FullName.startswith(M->Name) && !FullName.endswith(
"Private"))
1837 Canonical.append(
"_Private");
1840 if (ActiveModule->
Parent && ActiveModule->
Name ==
"Private" && !M->Parent &&
1843 diag::warn_mmap_mismatched_private_submodule)
1848 FixItInitBegin = FrameworkLoc;
1850 FixItInitBegin = ExplicitLoc;
1853 FixedPrivModDecl.append(
"framework ");
1854 FixedPrivModDecl.append(
"module ");
1855 FixedPrivModDecl.append(Canonical);
1857 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1864 ActiveModule->
Name != Canonical) {
1866 diag::warn_mmap_mismatched_private_module_name)
1867 << ActiveModule->
Name;
1868 GenNoteAndFixIt(ActiveModule->
Name, Canonical, M,
1892void ModuleMapParser::parseModuleDecl() {
1896 parseExternModuleDecl();
1903 bool Explicit =
false;
1904 bool Framework =
false;
1908 ExplicitLoc = consumeToken();
1914 FrameworkLoc = consumeToken();
1925 CurrModuleDeclLoc = consumeToken();
1930 return parseInferredModuleDecl(Framework, Explicit);
1934 if (parseModuleId(
Id)) {
1940 if (
Id.size() > 1) {
1941 Diags.
Report(
Id.front().second, diag::err_mmap_nested_submodule_id)
1947 }
else if (
Id.size() == 1 && Explicit) {
1949 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1955 Module *PreviousActiveModule = ActiveModule;
1956 if (
Id.size() > 1) {
1959 ActiveModule =
nullptr;
1960 const Module *TopLevelModule =
nullptr;
1961 for (
unsigned I = 0, N =
Id.size() - 1; I != N; ++I) {
1964 TopLevelModule = Next;
1965 ActiveModule = Next;
1969 Diags.
Report(
Id[I].second, diag::err_mmap_missing_parent_module)
1970 <<
Id[I].first << (ActiveModule !=
nullptr)
1977 if (TopLevelModule &&
1980 "submodule defined in same file as 'module *' that allowed its "
1981 "top-level module");
1986 StringRef ModuleName =
Id.back().first;
1991 if (parseOptionalAttributes(Attrs))
2004 Module *ShadowingModule =
nullptr;
2013 bool ParsedAsMainInput =
2018 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
2025 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2032 ShadowingModule = Existing;
2035 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2037 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2050 if (ShadowingModule) {
2060 if (Attrs.IsSystem || IsSystem)
2062 if (Attrs.IsExternC)
2064 if (Attrs.NoUndeclaredIncludes)
2068 StringRef MapFileName(ModuleMapFile->
getName());
2069 if (MapFileName.endswith(
"module.private.modulemap") ||
2070 MapFileName.endswith(
"module_private.map")) {
2080 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_submodule,
2082 !Diags.
isIgnored(diag::warn_mmap_mismatched_private_module_name,
2085 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2096 parseConfigMacros();
2115 parseExportAsDecl();
2123 parseRequiresDecl();
2135 parseUmbrellaDirDecl(UmbrellaLoc);
2166 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2186 ActiveModule = PreviousActiveModule;
2193void ModuleMapParser::parseExternModuleDecl() {
2208 if (parseModuleId(
Id)) {
2219 std::string FileName = std::string(Tok.
getString());
2222 StringRef FileNameRef = FileName;
2224 if (llvm::sys::path::is_relative(FileNameRef)) {
2225 ModuleMapFileName += Directory->
getName();
2226 llvm::sys::path::append(ModuleMapFileName, FileName);
2227 FileNameRef = ModuleMapFileName;
2234 : (*File)->getDir(),
2235 FileID(),
nullptr, ExternLoc);
2254 bool &IsRequiresExcludedHack) {
2255 if (Feature ==
"excluded" &&
2258 IsRequiresExcludedHack =
true;
2260 }
else if (Feature ==
"cplusplus" && M->
fullModuleNameIs({
"IOKit",
"avc"})) {
2278void ModuleMapParser::parseRequiresDecl() {
2286 bool RequiredState =
true;
2288 RequiredState =
false;
2299 std::string Feature = std::string(Tok.
getString());
2302 bool IsRequiresExcludedHack =
false;
2303 bool ShouldAddRequirement =
2306 if (IsRequiresExcludedHack)
2307 UsesRequiresExcludedHack.insert(ActiveModule);
2309 if (ShouldAddRequirement) {
2311 ActiveModule->
addRequirement(Feature, RequiredState, Map.LangOpts,
2341 LeadingToken = Tok.
Kind;
2351 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2398 switch (llvm::StringSwitch<Attribute>(Str)
2400 .Case(
"mtime", ModTime)
2404 Diags.
Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2407 diag::err_mmap_invalid_header_attribute_value) << Str;
2417 Diags.
Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2420 diag::err_mmap_invalid_header_attribute_value) << Str;
2429 Diags.
Report(Loc, diag::err_mmap_expected_header_attribute);
2439 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2444 bool NeedsFramework =
false;
2445 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2447 if (NeedsFramework && ActiveModule)
2448 Diags.
Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2462void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
2471 std::string DirName = std::string(Tok.
getString());
2472 std::string DirNameAsWritten = DirName;
2477 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2485 if (llvm::sys::path::is_absolute(DirName)) {
2490 PathName = Directory->
getName();
2491 llvm::sys::path::append(PathName, DirName);
2497 Diags.
Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2502 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2509 llvm::vfs::FileSystem &FS =
2511 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->
getName(), EC), E;
2512 I != E && !EC; I.increment(EC)) {
2515 Headers.push_back(std::move(Header));
2522 for (
auto &Header : Headers)
2527 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2528 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2529 << OwningModule->getFullModuleName();
2535 Map.
setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
2547void ModuleMapParser::parseExportDecl() {
2553 bool Wildcard =
false;
2557 ParsedModuleId.push_back(
2581 ExportLoc, ParsedModuleId, Wildcard
2590void ModuleMapParser::parseExportAsDecl() {
2600 if (ActiveModule->
Parent) {
2627void ModuleMapParser::parseUseDecl() {
2629 auto KWLoc = consumeToken();
2632 parseModuleId(ParsedModuleId);
2634 if (ActiveModule->
Parent)
2635 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
2644void ModuleMapParser::parseLinkDecl() {
2649 bool IsFramework =
false;
2663 std::string LibraryName = std::string(Tok.
getString());
2676void ModuleMapParser::parseConfigMacros() {
2681 if (ActiveModule->
Parent) {
2682 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2687 if (parseOptionalAttributes(Attrs))
2690 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
2700 if (!ActiveModule->
Parent) {
2719 if (!ActiveModule->
Parent) {
2730 llvm::raw_string_ostream OS(result);
2732 for (
unsigned I = 0, N =
Id.size(); I != N; ++I) {
2746void ModuleMapParser::parseConflict() {
2752 if (parseModuleId(Conflict.
Id))
2785void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2788 bool Failed =
false;
2791 if (!ActiveModule && !Framework) {
2792 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2800 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2806 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2809 diag::note_mmap_prev_definition);
2815 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2818 }
else if (Explicit) {
2819 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2837 if (parseOptionalAttributes(Attrs))
2847 Map.InferredDirectories[Directory].InferModules =
true;
2848 Map.InferredDirectories[Directory].Attrs = Attrs;
2849 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2873 << (ActiveModule !=
nullptr);
2885 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2891 if (!ActiveModule) {
2893 << (ActiveModule !=
nullptr);
2903 diag::err_mmap_expected_export_wildcard);
2914 << (ActiveModule !=
nullptr);
2924 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2941bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2942 bool HadError =
false;
2958 AttributeKind Attribute
2959 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
2960 .Case(
"exhaustive", AT_exhaustive)
2961 .Case(
"extern_c", AT_extern_c)
2962 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
2963 .Case(
"system", AT_system)
2964 .Default(AT_unknown);
2965 switch (Attribute) {
2972 Attrs.IsSystem =
true;
2976 Attrs.IsExternC =
true;
2980 Attrs.IsExhaustive =
true;
2983 case AT_no_undeclared_includes:
2984 Attrs.NoUndeclaredIncludes =
true;
2992 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
3056 assert(Target &&
"Missing target information");
3057 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3058 = ParsedModuleMap.find(
File);
3059 if (Known != ParsedModuleMap.end())
3060 return Known->second;
3063 if (ID.isInvalid()) {
3064 auto FileCharacter =
3069 assert(Target &&
"Missing target information");
3070 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.
getBufferOrNone(ID);
3072 return ParsedModuleMap[
File] =
true;
3073 assert((!
Offset || *Offset <= Buffer->getBufferSize()) &&
3074 "invalid buffer offset");
3078 Buffer->getBufferStart(),
3080 Buffer->getBufferEnd());
3089 assert(Loc.first == ID &&
"stopped in a different file?");
3094 for (
const auto &Cb : Callbacks)
3095 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 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.
Cached information about one directory (either on disk or in the virtual file system).
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
const clang::FileEntryRef::MapEntry & getMapEntry() const
Expose the underlying MapEntry to simplify packing in a PointerIntPair or PointerUnion and allow cons...
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
const DirectoryEntry * getDir() const
Return the directory the file lives in.
StringRef getName() const
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).
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
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, const FileEntry *ModuleMapFile, const DirectoryEntry *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 setUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
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 diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
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)
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
bool parseModuleMapFile(const FileEntry *File, bool IsSystem, const DirectoryEntry *HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
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.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap)
module_iterator module_begin() const
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap)
ArrayRef< KnownHeader > findResolvedModulesForHeader(const FileEntry *File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
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.
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File)
Retrieve all the modules that contain the given header file.
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
module_iterator module_end() const
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.
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
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.
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
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.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
llvm::PointerUnion< const FileEntryRef::MapEntry *, const DirectoryEntry * > Umbrella
The umbrella header or directory.
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.
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
std::string UmbrellaRelativeToRootModuleDirectory
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
const DirectoryEntry * Directory
The build directory of this module.
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....
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
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.
@ 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.
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 ...