26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/ADT/StringSwitch.h"
28 #include "llvm/Support/Allocator.h"
29 #include "llvm/Support/FileSystem.h"
30 #include "llvm/Support/Host.h"
31 #include "llvm/Support/Path.h"
32 #include "llvm/Support/raw_ostream.h"
34 #if defined(LLVM_ON_UNIX)
37 using namespace clang;
40 ModuleMap::resolveExport(
Module *Mod,
42 bool Complain)
const {
44 if (Unresolved.
Id.empty()) {
45 assert(Unresolved.
Wildcard &&
"Invalid unresolved export");
58 bool Complain)
const {
63 Diags.
Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
70 for (
unsigned I = 1, N = Id.size();
I != N; ++
I) {
74 Diags.
Report(Id[
I].second, diag::err_mmap_missing_module_qualified)
90 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
91 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
92 SourceModule(nullptr), NumCreatedModules(0) {
93 MMapLangOpts.LineComment =
true;
97 for (
auto &M : Modules)
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
118 Buffer.push_back(
'_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (
unsigned I = 0, N = Name.size();
I != N; ++
I) {
122 Buffer.push_back(Name[I]);
124 Buffer.push_back(
'_');
127 Name = StringRef(Buffer.data(), Buffer.size());
130 while (llvm::StringSwitch<bool>(Name)
131 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
132 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
133 #include "clang/Basic/TokenKinds.def"
135 if (Name.data() != Buffer.data())
136 Buffer.append(Name.begin(), Name.end());
137 Buffer.push_back(
'_');
138 Name = StringRef(Buffer.data(), Buffer.size());
148 return llvm::StringSwitch<bool>(
FileName)
149 .Case(
"float.h",
true)
150 .Case(
"iso646.h",
true)
151 .Case(
"limits.h",
true)
152 .Case(
"stdalign.h",
true)
153 .Case(
"stdarg.h",
true)
154 .Case(
"stdatomic.h",
true)
155 .Case(
"stdbool.h",
true)
156 .Case(
"stddef.h",
true)
157 .Case(
"stdint.h",
true)
158 .Case(
"tgmath.h",
true)
159 .Case(
"unwind.h",
true)
164 ModuleMap::findKnownHeader(
const FileEntry *File) {
167 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
170 return Headers.find(File);
176 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
178 if (UmbrellaDirs.empty())
179 return KnownHeader();
182 assert(Dir &&
"file in no directory");
193 auto KnownDir = UmbrellaDirs.find(Dir);
194 if (KnownDir != UmbrellaDirs.end())
197 IntermediateDirs.push_back(Dir);
200 DirName = llvm::sys::path::parent_path(DirName);
207 return KnownHeader();
218 bool IsPrivate =
false;
222 for (
auto *Hs : HeaderList)
224 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
225 return H.Entry == IncFileEnt;
227 assert(IsPrivate &&
"inconsistent headers and roles");
238 bool RequestingModuleIsModuleInterface,
247 if (RequestingModule)
250 bool Excluded =
false;
251 Module *Private =
nullptr;
252 Module *NotUsed =
nullptr;
255 if (Known != Headers.end()) {
265 if (RequestingModule && LangOpts.ModulesDeclUse &&
280 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
287 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
292 if (Excluded || isHeaderInUmbrellaDirs(File))
297 if (LangOpts.ModulesStrictDeclUse) {
298 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
300 }
else if (RequestingModule && RequestingModuleIsModuleInterface) {
302 diag::warn_non_modular_include_in_framework_module :
303 diag::warn_non_modular_include_in_module;
336 if (Known != Headers.end()) {
342 return MakeResult(H);
346 return MakeResult(Result);
349 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
353 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *File) {
354 assert(!Headers.count(File) &&
"already have a module for this header");
357 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
365 UmbrellaModule = UmbrellaModule->
Parent;
376 for (
unsigned I = SkippedDirs.size();
I != 0; --
I) {
380 llvm::sys::path::stem(SkippedDirs[
I-1]->getName()), NameBuf);
383 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
387 UmbrellaDirs[SkippedDirs[
I-1]] =
Result;
398 llvm::sys::path::stem(File->
getName()), NameBuf);
401 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
412 for (
unsigned I = 0, N = SkippedDirs.size();
I != N; ++
I)
413 UmbrellaDirs[SkippedDirs[
I]] = Result;
417 Headers[File].push_back(Header);
421 return KnownHeader();
426 auto It = Headers.find(File);
427 if (It == Headers.end())
438 const Module *RequestingModule)
const {
439 HeadersMap::const_iterator Known = Headers.find(Header);
440 if (Known != Headers.end()) {
442 I = Known->second.begin(),
443 E = Known->second.end();
445 if (
I->isAvailable() && (!RequestingModule ||
446 I->getModule()->isSubModuleOf(RequestingModule)))
454 StringRef DirName = Dir->
getName();
456 auto IsUnavailable = [&](
const Module *M) {
457 return !M->isAvailable() && (!RequestingModule ||
464 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
465 = UmbrellaDirs.find(Dir);
466 if (KnownDir != UmbrellaDirs.end()) {
467 Module *Found = KnownDir->second;
468 if (IsUnavailable(Found))
473 Module *UmbrellaModule = Found;
475 UmbrellaModule = UmbrellaModule->
Parent;
478 for (
unsigned I = SkippedDirs.size();
I != 0; --
I) {
482 llvm::sys::path::stem(SkippedDirs[
I-1]->getName()),
487 if (IsUnavailable(Found))
494 llvm::sys::path::stem(Header->
getName()),
501 return IsUnavailable(Found);
504 SkippedDirs.push_back(Dir);
507 DirName = llvm::sys::path::parent_path(DirName);
519 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
520 if (Known != Modules.end())
521 return Known->getValue();
543 std::pair<Module *, bool>
548 return std::make_pair(Sub,
false);
552 IsFramework, IsExplicit, NumCreatedModules++);
558 return std::make_pair(Result,
true);
565 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
567 "Can only infer linking for top-level frameworks");
570 LibName += FrameworkDir->
getName();
571 llvm::sys::path::append(LibName, Mod->
Name);
576 static const char *frameworkExtensions[] = {
"",
".tbd"};
577 for (
const auto *extension : frameworkExtensions) {
578 llvm::sys::path::replace_extension(LibName, extension);
579 if (FileMgr.
getFile(LibName)) {
588 bool IsSystem,
Module *Parent) {
591 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
595 Attributes Attrs,
Module *Parent) {
600 StringRef FrameworkDirName =
608 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
618 const FileEntry *ModuleMapFile =
nullptr;
621 bool canInfer =
false;
622 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
624 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
628 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
629 inferred = InferredDirectories.find(ParentDir);
630 if (inferred == InferredDirectories.end()) {
633 bool IsFrameworkDir = Parent.endswith(
".framework");
637 inferred = InferredDirectories.find(ParentDir);
640 if (inferred == InferredDirectories.end())
641 inferred = InferredDirectories.insert(
642 std::make_pair(ParentDir, InferredDirectory())).first;
645 if (inferred->second.InferModules) {
648 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
649 canInfer = std::find(inferred->second.ExcludedModules.begin(),
650 inferred->second.ExcludedModules.end(),
651 Name) == inferred->second.ExcludedModules.end();
653 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
654 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
655 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
656 ModuleMapFile = inferred->second.ModuleMapFile;
670 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
681 NumCreatedModules++);
682 InferredModuleAllowedBy[
Result] = ModuleMapFile;
687 Modules[ModuleName] =
Result;
711 = StringRef(FrameworkDir->
getName());
712 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
713 llvm::sys::path::native(SubframeworksDirName);
717 Dir != DirEnd && !EC; Dir.increment(EC)) {
718 if (!StringRef(Dir->
getName()).endswith(
".framework"))
728 bool FoundParent =
false;
732 = llvm::sys::path::parent_path(SubframeworkDirName);
733 if (SubframeworkDirName.empty())
736 if (FileMgr.
getDirectory(SubframeworkDirName) == FrameworkDir) {
746 inferFrameworkModule(SubframeworkDir, Attrs, Result);
760 Twine NameAsWritten) {
764 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
767 for (
const auto &Cb : Callbacks)
768 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.
getFileManager(), UmbrellaHeader);
772 Twine NameAsWritten) {
775 UmbrellaDirs[UmbrellaDir] = Mod;
780 default: llvm_unreachable(
"unknown header role");
799 auto &HeaderList = Headers[Header.
Entry];
800 for (
auto H : HeaderList)
804 HeaderList.push_back(KH);
807 bool isCompilingModuleHeader =
809 if (!Imported || isCompilingModuleHeader) {
813 isCompilingModuleHeader);
817 for (
const auto &Cb : Callbacks)
826 (void) Headers[Header.
Entry];
842 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
843 return InferredModuleAllowedBy.find(M)->second;
849 assert(M->
IsInferred &&
"module not inferred");
850 InferredModuleAllowedBy[M] = ModMap;
854 llvm::errs() <<
"Modules:";
856 MEnd = Modules.end();
858 M->getValue()->print(llvm::errs(), 2);
860 llvm::errs() <<
"Headers:";
863 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
867 if (
I != H->second.begin())
869 llvm::errs() <<
I->getModule()->getFullModuleName();
871 llvm::errs() <<
"\n";
878 for (
auto &UE : Unresolved) {
880 if (Export.getPointer() || Export.getInt())
881 Mod->
Exports.push_back(Export);
891 for (
auto &UDU : Unresolved) {
892 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
904 for (
auto &UC : Unresolved) {
905 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
907 Conflict.
Other = OtherMod;
920 if (UmbrellaDirs.empty() && Headers.empty())
943 ExpansionFileID = SrcMgr.
getFileID(IncludeLoc);
1036 llvm::BumpPtrAllocator StringData;
1052 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1062 bool parseModuleId(ModuleId &Id);
1063 void parseModuleDecl();
1064 void parseExternModuleDecl();
1065 void parseRequiresDecl();
1069 void parseExportDecl();
1070 void parseUseDecl();
1071 void parseLinkDecl();
1072 void parseConfigMacros();
1073 void parseConflict();
1074 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1076 typedef ModuleMap::Attributes Attributes;
1077 bool parseOptionalAttributes(Attributes &Attrs);
1088 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1089 ModuleMapFile(ModuleMapFile), Directory(Directory),
1090 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1091 HadError(
false), ActiveModule(nullptr)
1110 case tok::raw_identifier: {
1114 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1170 case tok::string_literal: {
1185 char *Saved = StringData.Allocate<
char>(Length + 1);
1209 unsigned braceDepth = 0;
1210 unsigned squareDepth = 0;
1217 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1224 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1238 if (squareDepth > 0)
1245 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1261 bool ModuleMapParser::parseModuleId(
ModuleId &Id) {
1312 void ModuleMapParser::parseModuleDecl() {
1316 parseExternModuleDecl();
1322 bool Explicit =
false;
1323 bool Framework =
false;
1327 ExplicitLoc = consumeToken();
1349 return parseInferredModuleDecl(Framework, Explicit);
1353 if (parseModuleId(Id)) {
1359 if (Id.size() > 1) {
1360 Diags.
Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1361 <<
SourceRange(Id.front().second, Id.back().second);
1366 }
else if (Id.size() == 1 && Explicit) {
1368 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1374 Module *PreviousActiveModule = ActiveModule;
1375 if (Id.size() > 1) {
1378 ActiveModule =
nullptr;
1379 const Module *TopLevelModule =
nullptr;
1380 for (
unsigned I = 0, N = Id.size() - 1;
I != N; ++
I) {
1383 TopLevelModule =
Next;
1384 ActiveModule =
Next;
1389 Diags.
Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1393 Diags.
Report(Id[I].second, diag::err_mmap_expected_module_name);
1401 "submodule defined in same file as 'module *' that allowed its "
1402 "top-level module");
1407 StringRef ModuleName = Id.back().first;
1412 if (parseOptionalAttributes(Attrs))
1427 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1434 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
1440 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1442 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1457 if (Attrs.IsSystem || IsSystem)
1459 if (Attrs.IsExternC)
1472 parseConfigMacros();
1495 parseRequiresDecl();
1507 parseUmbrellaDirDecl(UmbrellaLoc);
1538 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
1559 ActiveModule = PreviousActiveModule;
1566 void ModuleMapParser::parseExternModuleDecl() {
1581 if (parseModuleId(Id)) {
1597 if (llvm::sys::path::is_relative(FileNameRef)) {
1598 ModuleMapFileName += Directory->
getName();
1599 llvm::sys::path::append(ModuleMapFileName, FileName);
1600 FileNameRef = ModuleMapFileName;
1607 : File->
getDir(), ExternLoc);
1626 bool &IsRequiresExcludedHack) {
1627 static const StringRef DarwinCExcluded[] = {
"Darwin",
"C",
"excluded"};
1628 static const StringRef TclPrivate[] = {
"Tcl",
"Private"};
1629 static const StringRef IOKitAVC[] = {
"IOKit",
"avc"};
1633 IsRequiresExcludedHack =
true;
1653 void ModuleMapParser::parseRequiresDecl() {
1661 bool RequiredState =
true;
1663 RequiredState =
false;
1677 bool IsRequiresExcludedHack =
false;
1678 bool ShouldAddRequirement =
1681 if (IsRequiresExcludedHack)
1682 UsesRequiresExcludedHack.insert(ActiveModule);
1684 if (ShouldAddRequirement) {
1686 ActiveModule->
addRequirement(Feature, RequiredState, Map.LangOpts,
1704 for (; Mod; Mod = Mod->
Parent) {
1706 Paths.push_back(Mod->
Name);
1713 for (
unsigned I = Paths.size() - 1; I != 0; --
I)
1714 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
1734 LeadingToken = Tok.
Kind;
1742 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1782 if (llvm::sys::path::is_absolute(Header.
FileName)) {
1783 RelativePathName = Header.
FileName;
1788 unsigned FullPathLength = FullPathName.size();
1794 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
1795 llvm::sys::path::append(FullPathName, RelativePathName);
1801 RelativePathName.clear();
1802 FullPathName.resize(FullPathLength);
1803 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
1805 llvm::sys::path::append(FullPathName, RelativePathName);
1810 llvm::sys::path::append(RelativePathName, Header.
FileName);
1811 llvm::sys::path::append(FullPathName, RelativePathName);
1818 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1821 llvm::sys::path::append(BuiltinPathName, Header.
FileName);
1833 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
1835 RelativePathName = BuiltinPathName;
1836 BuiltinFile =
nullptr;
1847 if (
Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1848 Diags.
Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1894 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
1908 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1916 if (llvm::sys::path::is_absolute(DirName))
1920 PathName = Directory->
getName();
1921 llvm::sys::path::append(PathName, DirName);
1926 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1932 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1941 I !=
E && !EC; I.increment(EC)) {
1946 Headers.push_back(std::move(Header));
1953 for (
auto &Header : Headers)
1958 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1959 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1960 << OwningModule->getFullModuleName();
1978 void ModuleMapParser::parseExportDecl() {
1984 bool Wildcard =
false;
1988 ParsedModuleId.push_back(std::make_pair(Tok.
getString(),
2012 ExportLoc, ParsedModuleId, Wildcard
2021 void ModuleMapParser::parseUseDecl() {
2023 auto KWLoc = consumeToken();
2026 parseModuleId(ParsedModuleId);
2028 if (ActiveModule->
Parent)
2029 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
2038 void ModuleMapParser::parseLinkDecl() {
2043 bool IsFramework =
false;
2057 std::string LibraryName = Tok.
getString();
2070 void ModuleMapParser::parseConfigMacros() {
2075 if (ActiveModule->
Parent) {
2076 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2081 if (parseOptionalAttributes(Attrs))
2084 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
2094 if (!ActiveModule->
Parent) {
2113 if (!ActiveModule->
Parent) {
2124 llvm::raw_string_ostream OS(result);
2126 for (
unsigned I = 0, N = Id.size(); I != N; ++
I) {
2140 void ModuleMapParser::parseConflict() {
2146 if (parseModuleId(Conflict.
Id))
2179 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2182 bool Failed =
false;
2185 if (!ActiveModule && !Framework) {
2186 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2194 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2200 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2203 diag::note_mmap_prev_definition);
2209 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2212 }
else if (Explicit) {
2213 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2231 if (parseOptionalAttributes(Attrs))
2241 Map.InferredDirectories[Directory].InferModules =
true;
2242 Map.InferredDirectories[Directory].Attrs = Attrs;
2243 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2267 << (ActiveModule !=
nullptr);
2279 Map.InferredDirectories[Directory].ExcludedModules
2286 if (!ActiveModule) {
2288 << (ActiveModule !=
nullptr);
2298 diag::err_mmap_expected_export_wildcard);
2309 << (ActiveModule !=
nullptr);
2319 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2336 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2337 bool HadError =
false;
2354 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
2355 .Case(
"exhaustive", AT_exhaustive)
2356 .Case(
"extern_c", AT_extern_c)
2357 .Case(
"system", AT_system)
2358 .Default(AT_unknown);
2359 switch (Attribute) {
2366 Attrs.IsSystem =
true;
2370 Attrs.IsExternC =
true;
2374 Attrs.IsExhaustive =
true;
2382 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
2444 = ParsedModuleMap.find(File);
2445 if (Known != ParsedModuleMap.end())
2446 return Known->second;
2448 assert(Target &&
"Missing target information");
2453 return ParsedModuleMap[File] =
true;
2459 BuiltinIncludeDir, IsSystem);
2461 ParsedModuleMap[File] =
Result;
2464 for (
const auto &Cb : Callbacks)
2465 Cb->moduleMapFileRead(Start, *File, IsSystem);
unsigned IsAvailable
Whether this module is available in the current translation unit.
bool is(TokenKind K) const
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
std::string Name
The name of this module.
static Module * getTopLevelOrNull(Module *M)
This header is included but private.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup...
static LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
bool parseModuleMapFile(const FileEntry *File, bool IsSystem, const DirectoryEntry *HomeDir, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system...
std::string Message
The message provided to the user when there is a conflict.
Implements support for file system lookup, file system caching, and directory search management...
void dump()
Dump the contents of the module map, for debugging purposes.
Defines the clang::FileManager interface and associated types.
An unresolved conflict with another module.
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
This header is part of the module (for layering purposes) but should be textually included...
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "...
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
void excludeHeader(Module *Mod, Module::Header Header)
Marks this header as being excluded from the given module.
unsigned IsFramework
Whether this is a framework module.
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
const SourceManager & getManager() const
std::unique_ptr< llvm::MemoryBuffer > Buffer
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Parser - This implements a parser for the C family of languages.
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives...
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void markUnavailable(bool MissingRequirement=false)
Mark this module and all of its submodules as unavailable.
std::string getFullModuleName() const
Retrieve the full name of this module, including the path from its top-level module.
The virtual file system interface.
A library or framework to link against when an entity from this module is used.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
SourceLocation getLocation() const
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
Token - This structure provides full information about a lexed token.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, Twine NameAsWritten)
Sets the umbrella directory of the given module to the given directory.
An input iterator over the recursive contents of a virtual path, similar to llvm::sys::fs::recursive_...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e...
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
std::string Message
The message provided to the user when there is a conflict.
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File) const
Retrieve all the modules that contain the given header file.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
ModuleId Id
The (unresolved) module id.
Concrete class used by the front-end to report problems and issues.
Module * Parent
The parent of this module.
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
const FileEntry * getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
tok::TokenKind getKind() const
static bool isBuiltinHeader(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace...
detail::InMemoryDirectory::const_iterator I
void setTarget(const TargetInfo &Target)
Set the target information.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, const FileEntry *ModuleMapFile, const DirectoryEntry *Directory, const DirectoryEntry *BuiltinIncludeDir, bool IsSystem)
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
static LLVM_READONLY bool isValidIdentifier(StringRef S)
Return true if this is a valid ASCII identifier.
ModuleHeaderRole
Flags describing the role of a module header.
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
Exposes information about the current target.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
ModuleId Id
The name of the module.
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context...
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, unsigned LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
FileManager & getFileManager() const
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used...
static int compareModuleHeaders(const Module::Header *A, const Module::Header *B)
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isSubModuleOf(const Module *Other) const
Determine whether this module is a submodule of the given other module.
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, Twine NameAsWritten)
Sets the umbrella header of the given module to the given header.
static std::string formatModuleId(const ModuleId &Id)
Format a module-id into a string.
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
The result type of a method or function.
void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap)
enum clang::MMToken::TokenKind Kind
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
const DirectoryEntry * Directory
The build directory of this module.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, FileManager &FileMgr)
For a framework module, infer the framework against which we should link.
static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role)
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
const char * getName() const
Encodes a location in the source.
const TemplateArgument * iterator
bool isValid() const
Return true if this is a valid SourceLocation object.
Cached information about one file (either on disk or in the virtual file system). ...
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Defines the clang::TargetOptions class.
bool Wildcard
Whether this export declaration ends in a wildcard, indicating that all of its submodules should be e...
This header is normally included in the module.
const char * getName() const
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
bool parseModuleMapFile()
Parse a module map file.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
StringRef getCanonicalName(const DirectoryEntry *Dir)
Retrieve the canonical name for a given directory.
A conflict between two modules.
unsigned IsMissingRequirement
Whether this module is missing a feature from Requirements.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
Module * inferModuleFromLocation(FullSourceLoc Loc)
Infers the (sub)module based on the given source location and source manager.
SourceLocation InferredSubmoduleLoc
The location of the inferred submodule.
detail::InMemoryDirectory::const_iterator E
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
Defines the Diagnostic-related interfaces.
SourceLocation DefinitionLoc
The location of the module definition.
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
A token in a module map file.
std::vector< Conflict > Conflicts
The list of conflicts.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
KnownHeader findModuleForHeader(const FileEntry *File)
Retrieve the module that owns the given header file, if any.
Cached information about one directory (either on disk or in the virtual file system).
static LLVM_READONLY bool isIdentifierBody(unsigned char c, bool AllowDollar=false)
Returns true if this is a body character of a C identifier, which is [a-zA-Z0-9_].
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
StringRef getString() const
A SourceLocation and its associated SourceManager.
~ModuleMap()
Destroy the module map.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
FullSourceLoc getExpansionLoc() const
AttributeKind
Enumerates the known attributes.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Module * Other
The module that this module conflicts with.
A trivial tuple used to represent a source range.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap)
This class handles loading and caching of source files into memory.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.