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 CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
93 MMapLangOpts.LineComment =
true;
97 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
100 delete I->getValue();
105 assert((!this->Target || this->Target == &Target) &&
106 "Improper target override");
107 this->Target = &Target;
121 Buffer.push_back(
'_');
122 Buffer.reserve(Buffer.size() + Name.size());
123 for (
unsigned I = 0, N = Name.size(); I != N; ++I) {
125 Buffer.push_back(Name[I]);
127 Buffer.push_back(
'_');
130 Name = StringRef(Buffer.data(), Buffer.size());
133 while (llvm::StringSwitch<bool>(Name)
134 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
135 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
136 #include "clang/Basic/TokenKinds.def"
138 if (Name.data() != Buffer.data())
139 Buffer.append(Name.begin(), Name.end());
140 Buffer.push_back(
'_');
141 Name = StringRef(Buffer.data(), Buffer.size());
151 return llvm::StringSwitch<bool>(FileName)
152 .Case(
"float.h",
true)
153 .Case(
"iso646.h",
true)
154 .Case(
"limits.h",
true)
155 .Case(
"stdalign.h",
true)
156 .Case(
"stdarg.h",
true)
157 .Case(
"stdbool.h",
true)
158 .Case(
"stddef.h",
true)
159 .Case(
"stdint.h",
true)
160 .Case(
"tgmath.h",
true)
161 .Case(
"unwind.h",
true)
165 ModuleMap::HeadersMap::iterator
166 ModuleMap::findKnownHeader(
const FileEntry *File) {
167 HeadersMap::iterator Known = Headers.find(File);
169 Known == Headers.end() && File->
getDir() == BuiltinIncludeDir &&
172 return Headers.find(File);
178 ModuleMap::findHeaderInUmbrellaDirs(
const FileEntry *File,
180 if (UmbrellaDirs.empty())
181 return KnownHeader();
184 assert(Dir &&
"file in no directory");
195 auto KnownDir = UmbrellaDirs.find(Dir);
196 if (KnownDir != UmbrellaDirs.end())
199 IntermediateDirs.push_back(Dir);
202 DirName = llvm::sys::path::parent_path(DirName);
209 return KnownHeader();
215 Module *RequestedModule) {
222 bool IsPrivate =
false;
226 for (
auto *Hs : HeaderList)
228 std::find_if(Hs->begin(), Hs->end(), [&](
const Module::Header &H) {
229 return H.Entry == IncFileEnt;
231 assert((!IsPrivateRole || IsPrivate) &&
"inconsistent headers and roles");
234 return IsPrivateRole &&
254 if (RequestingModule)
257 bool Excluded =
false;
258 Module *Private =
nullptr;
259 Module *NotUsed =
nullptr;
261 HeadersMap::iterator Known = findKnownHeader(File);
262 if (Known != Headers.end()) {
278 if (RequestingModule && LangOpts.ModulesDeclUse &&
293 Diags.
Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
300 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
305 if (Excluded || isHeaderInUmbrellaDirs(File))
310 if (LangOpts.ModulesStrictDeclUse) {
311 Diags.
Report(FilenameLoc, diag::err_undeclared_use_of_module)
313 }
else if (RequestingModule) {
315 diag::warn_non_modular_include_in_framework_module :
316 diag::warn_non_modular_include_in_module;
344 HeadersMap::iterator Known = findKnownHeader(File);
345 if (Known != Headers.end()) {
351 return MakeResult(H);
358 return MakeResult(Result);
362 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
370 UmbrellaModule = UmbrellaModule->
Parent;
381 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
385 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
388 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
392 UmbrellaDirs[SkippedDirs[I-1]] =
Result;
403 llvm::sys::path::stem(File->
getName()), NameBuf);
406 InferredModuleAllowedBy[
Result] = UmbrellaModuleMap;
417 for (
unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
418 UmbrellaDirs[SkippedDirs[I]] = Result;
428 return MakeResult(Headers[File].back());
440 const Module *RequestingModule)
const {
441 HeadersMap::const_iterator Known = Headers.find(Header);
442 if (Known != Headers.end()) {
444 I = Known->second.begin(),
445 E = Known->second.end();
447 if (I->isAvailable() && (!RequestingModule ||
456 StringRef DirName = Dir->
getName();
458 auto IsUnavailable = [&](
const Module *M) {
459 return !M->isAvailable() && (!RequestingModule ||
466 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
467 = UmbrellaDirs.find(Dir);
468 if (KnownDir != UmbrellaDirs.end()) {
469 Module *Found = KnownDir->second;
470 if (IsUnavailable(Found))
475 Module *UmbrellaModule = Found;
477 UmbrellaModule = UmbrellaModule->
Parent;
480 for (
unsigned I = SkippedDirs.size(); I != 0; --I) {
484 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
489 if (IsUnavailable(Found))
496 llvm::sys::path::stem(Header->
getName()),
503 return IsUnavailable(Found);
506 SkippedDirs.push_back(Dir);
509 DirName = llvm::sys::path::parent_path(DirName);
521 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
522 if (Known != Modules.end())
523 return Known->getValue();
545 std::pair<Module *, bool>
550 return std::make_pair(Sub,
false);
554 IsFramework, IsExplicit, NumCreatedModules++);
566 return std::make_pair(Result,
true);
573 assert(Mod->
IsFramework &&
"Can only infer linking for framework modules");
575 "Can only infer linking for top-level frameworks");
578 LibName += FrameworkDir->
getName();
579 llvm::sys::path::append(LibName, Mod->
Name);
580 if (FileMgr.
getFile(LibName)) {
587 bool IsSystem,
Module *Parent) {
590 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
594 Attributes Attrs,
Module *Parent) {
599 StringRef FrameworkDirName =
607 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
617 const FileEntry *ModuleMapFile =
nullptr;
620 bool canInfer =
false;
621 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
623 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
627 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
628 inferred = InferredDirectories.find(ParentDir);
629 if (inferred == InferredDirectories.end()) {
632 bool IsFrameworkDir = Parent.endswith(
".framework");
636 inferred = InferredDirectories.find(ParentDir);
639 if (inferred == InferredDirectories.end())
640 inferred = InferredDirectories.insert(
641 std::make_pair(ParentDir, InferredDirectory())).first;
644 if (inferred->second.InferModules) {
647 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
648 canInfer = std::find(inferred->second.ExcludedModules.begin(),
649 inferred->second.ExcludedModules.end(),
650 Name) == inferred->second.ExcludedModules.end();
652 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
653 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
654 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
655 ModuleMapFile = inferred->second.ModuleMapFile;
669 llvm::sys::path::append(UmbrellaName,
"Headers", ModuleName +
".h");
680 NumCreatedModules++);
681 InferredModuleAllowedBy[
Result] = ModuleMapFile;
694 Modules[ModuleName] =
Result;
712 = StringRef(FrameworkDir->
getName());
713 llvm::sys::path::append(SubframeworksDirName,
"Frameworks");
714 llvm::sys::path::native(SubframeworksDirName);
715 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(
".framework"))
727 bool FoundParent =
false;
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
735 if (FileMgr.
getDirectory(SubframeworkDirName) == FrameworkDir) {
745 inferFrameworkModule(SubframeworkDir, Attrs, Result);
759 Twine NameAsWritten) {
763 UmbrellaDirs[UmbrellaHeader->
getDir()] = Mod;
767 Twine NameAsWritten) {
770 UmbrellaDirs[UmbrellaDir] = Mod;
775 default: llvm_unreachable(
"unknown header role");
792 isCompilingModuleHeader);
804 (void) Headers[Header.
Entry];
820 assert(InferredModuleAllowedBy.count(M) &&
"missing inferred module map");
821 return InferredModuleAllowedBy.find(M)->second;
827 assert(M->
IsInferred &&
"module not inferred");
828 InferredModuleAllowedBy[M] = ModMap;
832 llvm::errs() <<
"Modules:";
833 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
834 MEnd = Modules.end();
836 M->getValue()->print(llvm::errs(), 2);
838 llvm::errs() <<
"Headers:";
839 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
841 llvm::errs() <<
" \"" << H->first->getName() <<
"\" -> ";
845 if (I != H->second.begin())
847 llvm::errs() << I->getModule()->getFullModuleName();
849 llvm::errs() <<
"\n";
856 for (
auto &UE : Unresolved) {
858 if (Export.getPointer() || Export.getInt())
859 Mod->
Exports.push_back(Export);
869 for (
auto &UDU : Unresolved) {
870 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
882 for (
auto &UC : Unresolved) {
883 if (
Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
885 Conflict.
Other = OtherMod;
918 ExpansionFileID = SrcMgr.
getFileID(IncludeLoc);
1011 llvm::BumpPtrAllocator StringData;
1027 bool parseModuleId(ModuleId &Id);
1028 void parseModuleDecl();
1029 void parseExternModuleDecl();
1030 void parseRequiresDecl();
1034 void parseExportDecl();
1035 void parseUseDecl();
1036 void parseLinkDecl();
1037 void parseConfigMacros();
1038 void parseConflict();
1039 void parseInferredModuleDecl(
bool Framework,
bool Explicit);
1041 typedef ModuleMap::Attributes Attributes;
1042 bool parseOptionalAttributes(Attributes &Attrs);
1053 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1054 ModuleMapFile(ModuleMapFile), Directory(Directory),
1055 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1056 HadError(
false), ActiveModule(nullptr)
1075 case tok::raw_identifier: {
1079 Tok.
Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1135 case tok::string_literal: {
1150 char *Saved = StringData.Allocate<
char>(Length + 1);
1174 unsigned braceDepth = 0;
1175 unsigned squareDepth = 0;
1182 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1189 if (Tok.
is(K) && braceDepth == 0 && squareDepth == 0)
1203 if (squareDepth > 0)
1210 if (braceDepth == 0 && squareDepth == 0 && Tok.
is(K))
1226 bool ModuleMapParser::parseModuleId(
ModuleId &Id) {
1277 void ModuleMapParser::parseModuleDecl() {
1281 parseExternModuleDecl();
1287 bool Explicit =
false;
1288 bool Framework =
false;
1292 ExplicitLoc = consumeToken();
1314 return parseInferredModuleDecl(Framework, Explicit);
1318 if (parseModuleId(Id)) {
1324 if (Id.size() > 1) {
1325 Diags.
Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1326 <<
SourceRange(Id.front().second, Id.back().second);
1331 }
else if (Id.size() == 1 && Explicit) {
1333 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1339 Module *PreviousActiveModule = ActiveModule;
1340 if (Id.size() > 1) {
1343 ActiveModule =
nullptr;
1344 const Module *TopLevelModule =
nullptr;
1345 for (
unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1348 TopLevelModule =
Next;
1349 ActiveModule =
Next;
1354 Diags.
Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1358 Diags.
Report(Id[I].second, diag::err_mmap_expected_module_name);
1366 "submodule defined in same file as 'module *' that allowed its "
1367 "top-level module");
1372 StringRef ModuleName = Id.back().first;
1377 parseOptionalAttributes(Attrs);
1390 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1397 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
1403 Diags.
Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1405 Diags.
Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1420 if (Attrs.IsSystem || IsSystem)
1422 if (Attrs.IsExternC)
1435 parseConfigMacros();
1458 parseRequiresDecl();
1470 parseUmbrellaDirDecl(UmbrellaLoc);
1501 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
1522 ActiveModule = PreviousActiveModule;
1529 void ModuleMapParser::parseExternModuleDecl() {
1544 if (parseModuleId(Id)) {
1558 StringRef FileNameRef = FileName;
1560 if (llvm::sys::path::is_relative(FileNameRef)) {
1561 ModuleMapFileName += Directory->
getName();
1562 llvm::sys::path::append(ModuleMapFileName, FileName);
1563 FileNameRef = ModuleMapFileName;
1570 : File->
getDir(), ExternLoc);
1584 void ModuleMapParser::parseRequiresDecl() {
1592 bool RequiredState =
true;
1594 RequiredState =
false;
1610 Map.LangOpts, *Map.Target);
1626 for (; Mod; Mod = Mod->
Parent) {
1628 Paths.push_back(Mod->
Name);
1635 for (
unsigned I = Paths.size() - 1; I != 0; --I)
1636 llvm::sys::path::append(Path,
"Frameworks", Paths[I-1] +
".framework");
1656 LeadingToken = Tok.
Kind;
1697 if (llvm::sys::path::is_absolute(Header.
FileName)) {
1698 RelativePathName = Header.
FileName;
1703 unsigned FullPathLength = FullPathName.size();
1709 llvm::sys::path::append(RelativePathName,
"Headers", Header.
FileName);
1710 llvm::sys::path::append(FullPathName, RelativePathName);
1716 RelativePathName.clear();
1717 FullPathName.resize(FullPathLength);
1718 llvm::sys::path::append(RelativePathName,
"PrivateHeaders",
1720 llvm::sys::path::append(FullPathName, RelativePathName);
1725 llvm::sys::path::append(RelativePathName, Header.
FileName);
1726 llvm::sys::path::append(FullPathName, RelativePathName);
1733 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1736 llvm::sys::path::append(BuiltinPathName, Header.
FileName);
1748 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
1750 RelativePathName = BuiltinPathName;
1751 BuiltinFile =
nullptr;
1762 if (
Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1763 Diags.
Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1764 << UmbrellaModule->getFullModuleName();
1804 void ModuleMapParser::parseUmbrellaDirDecl(
SourceLocation UmbrellaLoc) {
1818 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1826 if (llvm::sys::path::is_absolute(DirName))
1830 PathName = Directory->
getName();
1831 llvm::sys::path::append(PathName, DirName);
1836 Diags.
Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1842 if (
Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1843 Diags.
Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1844 << OwningModule->getFullModuleName();
1862 void ModuleMapParser::parseExportDecl() {
1868 bool Wildcard =
false;
1872 ParsedModuleId.push_back(std::make_pair(Tok.
getString(),
1896 ExportLoc, ParsedModuleId, Wildcard
1905 void ModuleMapParser::parseUseDecl() {
1907 auto KWLoc = consumeToken();
1910 parseModuleId(ParsedModuleId);
1912 if (ActiveModule->
Parent)
1913 Diags.
Report(KWLoc, diag::err_mmap_use_decl_submodule);
1922 void ModuleMapParser::parseLinkDecl() {
1927 bool IsFramework =
false;
1941 std::string LibraryName = Tok.
getString();
1954 void ModuleMapParser::parseConfigMacros() {
1959 if (ActiveModule->
Parent) {
1960 Diags.
Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1965 parseOptionalAttributes(Attrs);
1966 if (Attrs.IsExhaustive && !ActiveModule->
Parent) {
1976 if (!ActiveModule->
Parent) {
1995 if (!ActiveModule->
Parent) {
2006 llvm::raw_string_ostream OS(result);
2008 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
2022 void ModuleMapParser::parseConflict() {
2028 if (parseModuleId(Conflict.
Id))
2061 void ModuleMapParser::parseInferredModuleDecl(
bool Framework,
bool Explicit) {
2064 bool Failed =
false;
2067 if (!ActiveModule && !Framework) {
2068 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2076 Diags.
Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2082 Diags.
Report(StarLoc, diag::err_mmap_inferred_redef);
2085 diag::note_mmap_prev_definition);
2091 Diags.
Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2094 }
else if (Explicit) {
2095 Diags.
Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2113 parseOptionalAttributes(Attrs);
2122 Map.InferredDirectories[Directory].InferModules =
true;
2123 Map.InferredDirectories[Directory].Attrs = Attrs;
2124 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2148 << (ActiveModule !=
nullptr);
2160 Map.InferredDirectories[Directory].ExcludedModules
2167 if (!ActiveModule) {
2169 << (ActiveModule !=
nullptr);
2179 diag::err_mmap_expected_export_wildcard);
2190 << (ActiveModule !=
nullptr);
2200 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
2217 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2218 bool HadError =
false;
2235 = llvm::StringSwitch<AttributeKind>(Tok.
getString())
2236 .Case(
"exhaustive", AT_exhaustive)
2237 .Case(
"extern_c", AT_extern_c)
2238 .Case(
"system", AT_system)
2239 .Default(AT_unknown);
2240 switch (Attribute) {
2247 Attrs.IsSystem =
true;
2251 Attrs.IsExternC =
true;
2255 Attrs.IsExhaustive =
true;
2263 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
2324 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2325 = ParsedModuleMap.find(File);
2326 if (Known != ParsedModuleMap.end())
2327 return Known->second;
2329 assert(Target &&
"Missing target information");
2332 const llvm::MemoryBuffer *Buffer = SourceMgr.
getBuffer(ID);
2334 return ParsedModuleMap[File] =
true;
2339 BuiltinIncludeDir, IsSystem);
2340 bool Result = Parser.parseModuleMapFile();
2341 ParsedModuleMap[File] =
Result;
unsigned IsAvailable
Whether this module is available in the current translation unit.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role)
Adds this header to the given module.
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].
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...
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)
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
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
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.
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.
A library or framework to link against when an entity from this module is used.
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
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, Twine NameAsWritten)
Sets the umbrella directory of the given module to the given directory.
std::string SourceModuleName
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.
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. This will be NULL for the top-level 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...
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)...
void diagnoseHeaderInclusion(Module *RequestingModule, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
StringRef getRawIdentifier() const
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.
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)
ModuleHeaderRole
Flags describing the role of a module header.
ID
Defines the set of possible language-specific address spaces.
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.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
ModuleId Id
The name of the module.
void dump()
Dump the contents of the module map, for debugging purposes.
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...
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. This is the directory in which the module is notionally built...
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 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. The SourceManager can decode this to get at the full include stack...
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
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.
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)
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::ModuleHeaderRole Role, Module *RequestedModule)
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.