1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ModuleMap implementation, which describes the layout
11 // of a module as it relates to headers.
13 //===----------------------------------------------------------------------===//
14 #include "clang/Lex/ModuleMap.h"
15 #include "clang/Basic/CharInfo.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticOptions.h"
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Basic/TargetInfo.h"
20 #include "clang/Basic/TargetOptions.h"
21 #include "clang/Lex/HeaderSearch.h"
22 #include "clang/Lex/HeaderSearchOptions.h"
23 #include "clang/Lex/LexDiagnostic.h"
24 #include "clang/Lex/Lexer.h"
25 #include "clang/Lex/LiteralSupport.h"
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,
41 const Module::UnresolvedExportDecl &Unresolved,
42 bool Complain) const {
43 // We may have just a wildcard.
44 if (Unresolved.Id.empty()) {
45 assert(Unresolved.Wildcard && "Invalid unresolved export");
46 return Module::ExportDecl(nullptr, true);
49 // Resolve the module-id.
50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
52 return Module::ExportDecl();
54 return Module::ExportDecl(Context, Unresolved.Wildcard);
57 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
58 bool Complain) const {
59 // Find the starting module.
60 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
63 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
64 << Id[0].first << Mod->getFullModuleName();
69 // Dig into the module path.
70 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
71 Module *Sub = lookupModuleQualified(Id[I].first, Context);
74 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
75 << Id[I].first << Context->getFullModuleName()
76 << SourceRange(Id[0].second, Id[I-1].second);
87 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
88 const LangOptions &LangOpts, const TargetInfo *Target,
89 HeaderSearch &HeaderInfo)
90 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
91 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
92 SourceModule(nullptr), NumCreatedModules(0) {
93 MMapLangOpts.LineComment = true;
96 ModuleMap::~ModuleMap() {
97 for (auto &M : Modules)
101 void ModuleMap::setTarget(const TargetInfo &Target) {
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
107 /// \brief "Sanitize" a filename so that it can be used as an identifier.
108 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
109 SmallVectorImpl<char> &Buffer) {
113 if (!isValidIdentifier(Name)) {
114 // If we don't already have something with the form of an identifier,
115 // create a buffer with the sanitized name.
117 if (isDigit(Name[0]))
118 Buffer.push_back('_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
121 if (isIdentifierBody(Name[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());
144 /// \brief Determine whether the given file name is the name of a builtin
145 /// header, supplied by Clang to replace, override, or augment existing system
147 static bool isBuiltinHeader(StringRef FileName) {
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)
163 ModuleMap::HeadersMap::iterator
164 ModuleMap::findKnownHeader(const FileEntry *File) {
165 HeadersMap::iterator Known = Headers.find(File);
166 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
167 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
168 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
169 HeaderInfo.loadTopLevelSystemModules();
170 return Headers.find(File);
175 ModuleMap::KnownHeader
176 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
177 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
178 if (UmbrellaDirs.empty())
179 return KnownHeader();
181 const DirectoryEntry *Dir = File->getDir();
182 assert(Dir && "file in no directory");
184 // Note: as an egregious but useful hack we use the real path here, because
185 // frameworks moving from top-level frameworks to embedded frameworks tend
186 // to be symlinked from the top-level location to the embedded location,
187 // and we need to resolve lookups as if we had found the embedded location.
188 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
190 // Keep walking up the directory hierarchy, looking for a directory with
191 // an umbrella header.
193 auto KnownDir = UmbrellaDirs.find(Dir);
194 if (KnownDir != UmbrellaDirs.end())
195 return KnownHeader(KnownDir->second, NormalHeader);
197 IntermediateDirs.push_back(Dir);
199 // Retrieve our parent path.
200 DirName = llvm::sys::path::parent_path(DirName);
204 // Resolve the parent path to a directory entry.
205 Dir = SourceMgr.getFileManager().getDirectory(DirName);
207 return KnownHeader();
210 static bool violatesPrivateInclude(Module *RequestingModule,
211 const FileEntry *IncFileEnt,
212 ModuleMap::KnownHeader Header) {
214 if (Header.getRole() & ModuleMap::PrivateHeader) {
215 // Check for consistency between the module header role
216 // as obtained from the lookup and as obtained from the module.
217 // This check is not cheap, so enable it only for debugging.
218 bool IsPrivate = false;
219 SmallVectorImpl<Module::Header> *HeaderList[] = {
220 &Header.getModule()->Headers[Module::HK_Private],
221 &Header.getModule()->Headers[Module::HK_PrivateTextual]};
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");
230 return !Header.isAccessibleFrom(RequestingModule);
233 static Module *getTopLevelOrNull(Module *M) {
234 return M ? M->getTopLevelModule() : nullptr;
237 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
238 bool RequestingModuleIsModuleInterface,
239 SourceLocation FilenameLoc,
241 const FileEntry *File) {
242 // No errors for indirect modules. This may be a bit of a problem for modules
243 // with no source files.
244 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
247 if (RequestingModule)
248 resolveUses(RequestingModule, /*Complain=*/false);
250 bool Excluded = false;
251 Module *Private = nullptr;
252 Module *NotUsed = nullptr;
254 HeadersMap::iterator Known = findKnownHeader(File);
255 if (Known != Headers.end()) {
256 for (const KnownHeader &Header : Known->second) {
257 // Remember private headers for later printing of a diagnostic.
258 if (violatesPrivateInclude(RequestingModule, File, Header)) {
259 Private = Header.getModule();
263 // If uses need to be specified explicitly, we are only allowed to return
264 // modules that are explicitly used by the requesting module.
265 if (RequestingModule && LangOpts.ModulesDeclUse &&
266 !RequestingModule->directlyUses(Header.getModule())) {
267 NotUsed = Header.getModule();
271 // We have found a module that we can happily use.
278 // We have found a header, but it is private.
280 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
285 // We have found a module, but we don't use it.
287 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
288 << RequestingModule->getFullModuleName() << Filename;
292 if (Excluded || isHeaderInUmbrellaDirs(File))
295 // At this point, only non-modular includes remain.
297 if (LangOpts.ModulesStrictDeclUse) {
298 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
299 << RequestingModule->getFullModuleName() << Filename;
300 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
301 LangOpts.isCompilingModule()) {
302 // Do not diagnose when we are not compiling a module.
303 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
304 diag::warn_non_modular_include_in_framework_module :
305 diag::warn_non_modular_include_in_module;
306 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
311 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
312 const ModuleMap::KnownHeader &Old) {
313 // Prefer available modules.
314 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
317 // Prefer a public header over a private header.
318 if ((New.getRole() & ModuleMap::PrivateHeader) !=
319 (Old.getRole() & ModuleMap::PrivateHeader))
320 return !(New.getRole() & ModuleMap::PrivateHeader);
322 // Prefer a non-textual header over a textual header.
323 if ((New.getRole() & ModuleMap::TextualHeader) !=
324 (Old.getRole() & ModuleMap::TextualHeader))
325 return !(New.getRole() & ModuleMap::TextualHeader);
327 // Don't have a reason to choose between these. Just keep the first one.
331 ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
333 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
334 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
335 return ModuleMap::KnownHeader();
339 HeadersMap::iterator Known = findKnownHeader(File);
340 if (Known != Headers.end()) {
341 ModuleMap::KnownHeader Result;
342 // Iterate over all modules that 'File' is part of to find the best fit.
343 for (KnownHeader &H : Known->second) {
344 // Prefer a header from the source module over all others.
345 if (H.getModule()->getTopLevelModule() == SourceModule)
346 return MakeResult(H);
347 if (!Result || isBetterKnownHeader(H, Result))
350 return MakeResult(Result);
353 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
356 ModuleMap::KnownHeader
357 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
358 assert(!Headers.count(File) && "already have a module for this header");
360 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
361 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
363 Module *Result = H.getModule();
365 // Search up the module stack until we find a module with an umbrella
367 Module *UmbrellaModule = Result;
368 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
369 UmbrellaModule = UmbrellaModule->Parent;
371 if (UmbrellaModule->InferSubmodules) {
372 const FileEntry *UmbrellaModuleMap =
373 getModuleMapFileForUniquing(UmbrellaModule);
375 // Infer submodules for each of the directories we found between
376 // the directory of the umbrella header and the directory where
377 // the actual header is located.
378 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
380 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
381 // Find or create the module that corresponds to this directory name.
382 SmallString<32> NameBuf;
383 StringRef Name = sanitizeFilenameAsIdentifier(
384 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
385 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
387 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
388 Result->IsInferred = true;
390 // Associate the module and the directory.
391 UmbrellaDirs[SkippedDirs[I-1]] = Result;
393 // If inferred submodules export everything they import, add a
394 // wildcard to the set of exports.
395 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
396 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
399 // Infer a submodule with the same name as this header file.
400 SmallString<32> NameBuf;
401 StringRef Name = sanitizeFilenameAsIdentifier(
402 llvm::sys::path::stem(File->getName()), NameBuf);
403 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
405 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
406 Result->IsInferred = true;
407 Result->addTopHeader(File);
409 // If inferred submodules export everything they import, add a
410 // wildcard to the set of exports.
411 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
412 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
414 // Record each of the directories we stepped through as being part of
415 // the module we found, since the umbrella header covers them all.
416 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
417 UmbrellaDirs[SkippedDirs[I]] = Result;
420 KnownHeader Header(Result, NormalHeader);
421 Headers[File].push_back(Header);
425 return KnownHeader();
428 ArrayRef<ModuleMap::KnownHeader>
429 ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
430 auto It = Headers.find(File);
431 if (It == Headers.end())
436 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
437 return isHeaderUnavailableInModule(Header, nullptr);
441 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
442 const Module *RequestingModule) const {
443 HeadersMap::const_iterator Known = Headers.find(Header);
444 if (Known != Headers.end()) {
445 for (SmallVectorImpl<KnownHeader>::const_iterator
446 I = Known->second.begin(),
447 E = Known->second.end();
449 if (I->isAvailable() && (!RequestingModule ||
450 I->getModule()->isSubModuleOf(RequestingModule)))
456 const DirectoryEntry *Dir = Header->getDir();
457 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
458 StringRef DirName = Dir->getName();
460 auto IsUnavailable = [&](const Module *M) {
461 return !M->isAvailable() && (!RequestingModule ||
462 M->isSubModuleOf(RequestingModule));
465 // Keep walking up the directory hierarchy, looking for a directory with
466 // an umbrella header.
468 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
469 = UmbrellaDirs.find(Dir);
470 if (KnownDir != UmbrellaDirs.end()) {
471 Module *Found = KnownDir->second;
472 if (IsUnavailable(Found))
475 // Search up the module stack until we find a module with an umbrella
477 Module *UmbrellaModule = Found;
478 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
479 UmbrellaModule = UmbrellaModule->Parent;
481 if (UmbrellaModule->InferSubmodules) {
482 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
483 // Find or create the module that corresponds to this directory name.
484 SmallString<32> NameBuf;
485 StringRef Name = sanitizeFilenameAsIdentifier(
486 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
488 Found = lookupModuleQualified(Name, Found);
491 if (IsUnavailable(Found))
495 // Infer a submodule with the same name as this header file.
496 SmallString<32> NameBuf;
497 StringRef Name = sanitizeFilenameAsIdentifier(
498 llvm::sys::path::stem(Header->getName()),
500 Found = lookupModuleQualified(Name, Found);
505 return IsUnavailable(Found);
508 SkippedDirs.push_back(Dir);
510 // Retrieve our parent path.
511 DirName = llvm::sys::path::parent_path(DirName);
515 // Resolve the parent path to a directory entry.
516 Dir = SourceMgr.getFileManager().getDirectory(DirName);
522 Module *ModuleMap::findModule(StringRef Name) const {
523 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
524 if (Known != Modules.end())
525 return Known->getValue();
530 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
531 Module *Context) const {
532 for(; Context; Context = Context->Parent) {
533 if (Module *Sub = lookupModuleQualified(Name, Context))
537 return findModule(Name);
540 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
542 return findModule(Name);
544 return Context->findSubmodule(Name);
547 std::pair<Module *, bool>
548 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
550 // Try to find an existing module with this name.
551 if (Module *Sub = lookupModuleQualified(Name, Parent))
552 return std::make_pair(Sub, false);
554 // Create a new module with this name.
555 Module *Result = new Module(Name, SourceLocation(), Parent,
556 IsFramework, IsExplicit, NumCreatedModules++);
558 if (LangOpts.CurrentModule == Name)
559 SourceModule = Result;
560 Modules[Name] = Result;
562 return std::make_pair(Result, true);
565 Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
567 assert(LangOpts.CurrentModule == Name && "module name mismatch");
568 assert(!Modules[Name] && "redefining existing module");
571 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
572 /*IsExplicit*/ false, NumCreatedModules++);
573 Modules[Name] = SourceModule = Result;
575 // Mark the main source file as being within the newly-created module so that
576 // declarations and macros are properly visibility-restricted to it.
577 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
578 assert(MainFile && "no input file for module interface");
579 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
584 /// \brief For a framework module, infer the framework against which we
586 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
587 FileManager &FileMgr) {
588 assert(Mod->IsFramework && "Can only infer linking for framework modules");
589 assert(!Mod->isSubFramework() &&
590 "Can only infer linking for top-level frameworks");
592 SmallString<128> LibName;
593 LibName += FrameworkDir->getName();
594 llvm::sys::path::append(LibName, Mod->Name);
596 // The library name of a framework has more than one possible extension since
597 // the introduction of the text-based dynamic library format. We need to check
598 // for both before we give up.
599 for (const char *extension : {"", ".tbd"}) {
600 llvm::sys::path::replace_extension(LibName, extension);
601 if (FileMgr.getFile(LibName)) {
602 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
603 /*IsFramework=*/true));
609 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
610 bool IsSystem, Module *Parent) {
612 Attrs.IsSystem = IsSystem;
613 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
616 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
617 Attributes Attrs, Module *Parent) {
618 // Note: as an egregious but useful hack we use the real path here, because
619 // we might be looking at an embedded framework that symlinks out to a
620 // top-level framework, and we need to infer as if we were naming the
621 // top-level framework.
622 StringRef FrameworkDirName =
623 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
625 // In case this is a case-insensitive filesystem, use the canonical
626 // directory name as the ModuleName, since modules are case-sensitive.
627 // FIXME: we should be able to give a fix-it hint for the correct spelling.
628 SmallString<32> ModuleNameStorage;
629 StringRef ModuleName = sanitizeFilenameAsIdentifier(
630 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
632 // Check whether we've already found this module.
633 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
636 FileManager &FileMgr = SourceMgr.getFileManager();
638 // If the framework has a parent path from which we're allowed to infer
639 // a framework module, do so.
640 const FileEntry *ModuleMapFile = nullptr;
642 // Determine whether we're allowed to infer a module map.
643 bool canInfer = false;
644 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
645 // Figure out the parent path.
646 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
647 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
648 // Check whether we have already looked into the parent directory
650 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
651 inferred = InferredDirectories.find(ParentDir);
652 if (inferred == InferredDirectories.end()) {
653 // We haven't looked here before. Load a module map, if there is
655 bool IsFrameworkDir = Parent.endswith(".framework");
656 if (const FileEntry *ModMapFile =
657 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
658 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
659 inferred = InferredDirectories.find(ParentDir);
662 if (inferred == InferredDirectories.end())
663 inferred = InferredDirectories.insert(
664 std::make_pair(ParentDir, InferredDirectory())).first;
667 if (inferred->second.InferModules) {
668 // We're allowed to infer for this directory, but make sure it's okay
669 // to infer this particular module.
670 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
671 canInfer = std::find(inferred->second.ExcludedModules.begin(),
672 inferred->second.ExcludedModules.end(),
673 Name) == inferred->second.ExcludedModules.end();
675 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
676 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
677 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
678 Attrs.NoUndeclaredIncludes |=
679 inferred->second.Attrs.NoUndeclaredIncludes;
680 ModuleMapFile = inferred->second.ModuleMapFile;
685 // If we're not allowed to infer a framework module, don't.
689 ModuleMapFile = getModuleMapFileForUniquing(Parent);
692 // Look for an umbrella header.
693 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
694 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
695 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
697 // FIXME: If there's no umbrella header, we could probably scan the
698 // framework to load *everything*. But, it's not clear that this is a good
703 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
704 /*IsFramework=*/true, /*IsExplicit=*/false,
705 NumCreatedModules++);
706 InferredModuleAllowedBy[Result] = ModuleMapFile;
707 Result->IsInferred = true;
709 if (LangOpts.CurrentModule == ModuleName)
710 SourceModule = Result;
711 Modules[ModuleName] = Result;
714 Result->IsSystem |= Attrs.IsSystem;
715 Result->IsExternC |= Attrs.IsExternC;
716 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
717 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
718 Result->Directory = FrameworkDir;
720 // umbrella header "umbrella-header-name"
722 // The "Headers/" component of the name is implied because this is
723 // a framework module.
724 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
727 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
729 // module * { export * }
730 Result->InferSubmodules = true;
731 Result->InferExportWildcard = true;
733 // Look for subframeworks.
735 SmallString<128> SubframeworksDirName
736 = StringRef(FrameworkDir->getName());
737 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
738 llvm::sys::path::native(SubframeworksDirName);
739 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
740 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
742 Dir != DirEnd && !EC; Dir.increment(EC)) {
743 if (!StringRef(Dir->getName()).endswith(".framework"))
746 if (const DirectoryEntry *SubframeworkDir =
747 FileMgr.getDirectory(Dir->getName())) {
748 // Note: as an egregious but useful hack, we use the real path here and
749 // check whether it is actually a subdirectory of the parent directory.
750 // This will not be the case if the 'subframework' is actually a symlink
751 // out to a top-level framework.
752 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
753 bool FoundParent = false;
755 // Get the parent directory name.
757 = llvm::sys::path::parent_path(SubframeworkDirName);
758 if (SubframeworkDirName.empty())
761 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
770 // FIXME: Do we want to warn about subframeworks without umbrella headers?
771 inferFrameworkModule(SubframeworkDir, Attrs, Result);
775 // If the module is a top-level framework, automatically link against the
777 if (!Result->isSubFramework()) {
778 inferFrameworkLink(Result, FrameworkDir, FileMgr);
784 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
785 Twine NameAsWritten) {
786 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
787 Mod->Umbrella = UmbrellaHeader;
788 Mod->UmbrellaAsWritten = NameAsWritten.str();
789 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
791 // Notify callbacks that we just added a new header.
792 for (const auto &Cb : Callbacks)
793 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
796 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
797 Twine NameAsWritten) {
798 Mod->Umbrella = UmbrellaDir;
799 Mod->UmbrellaAsWritten = NameAsWritten.str();
800 UmbrellaDirs[UmbrellaDir] = Mod;
803 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
805 default: llvm_unreachable("unknown header role");
806 case ModuleMap::NormalHeader:
807 return Module::HK_Normal;
808 case ModuleMap::PrivateHeader:
809 return Module::HK_Private;
810 case ModuleMap::TextualHeader:
811 return Module::HK_Textual;
812 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
813 return Module::HK_PrivateTextual;
817 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
818 ModuleHeaderRole Role, bool Imported) {
819 KnownHeader KH(Mod, Role);
821 // Only add each header to the headers list once.
822 // FIXME: Should we diagnose if a header is listed twice in the
823 // same module definition?
824 auto &HeaderList = Headers[Header.Entry];
825 for (auto H : HeaderList)
829 HeaderList.push_back(KH);
830 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
832 bool isCompilingModuleHeader =
833 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
834 if (!Imported || isCompilingModuleHeader) {
835 // When we import HeaderFileInfo, the external source is expected to
836 // set the isModuleHeader flag itself.
837 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
838 isCompilingModuleHeader);
841 // Notify callbacks that we just added a new header.
842 for (const auto &Cb : Callbacks)
843 Cb->moduleMapAddHeader(Header.Entry->getName());
846 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
847 // Add this as a known header so we won't implicitly add it to any
848 // umbrella directory module.
849 // FIXME: Should we only exclude it from umbrella modules within the
851 (void) Headers[Header.Entry];
853 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
857 ModuleMap::getContainingModuleMapFile(const Module *Module) const {
858 if (Module->DefinitionLoc.isInvalid())
861 return SourceMgr.getFileEntryForID(
862 SourceMgr.getFileID(Module->DefinitionLoc));
865 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
867 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
868 return InferredModuleAllowedBy.find(M)->second;
870 return getContainingModuleMapFile(M);
873 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
874 assert(M->IsInferred && "module not inferred");
875 InferredModuleAllowedBy[M] = ModMap;
878 LLVM_DUMP_METHOD void ModuleMap::dump() {
879 llvm::errs() << "Modules:";
880 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
881 MEnd = Modules.end();
883 M->getValue()->print(llvm::errs(), 2);
885 llvm::errs() << "Headers:";
886 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
888 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
889 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
892 if (I != H->second.begin())
894 llvm::errs() << I->getModule()->getFullModuleName();
896 llvm::errs() << "\n";
900 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
901 auto Unresolved = std::move(Mod->UnresolvedExports);
902 Mod->UnresolvedExports.clear();
903 for (auto &UE : Unresolved) {
904 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
905 if (Export.getPointer() || Export.getInt())
906 Mod->Exports.push_back(Export);
908 Mod->UnresolvedExports.push_back(UE);
910 return !Mod->UnresolvedExports.empty();
913 bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
914 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
915 Mod->UnresolvedDirectUses.clear();
916 for (auto &UDU : Unresolved) {
917 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
919 Mod->DirectUses.push_back(DirectUse);
921 Mod->UnresolvedDirectUses.push_back(UDU);
923 return !Mod->UnresolvedDirectUses.empty();
926 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
927 auto Unresolved = std::move(Mod->UnresolvedConflicts);
928 Mod->UnresolvedConflicts.clear();
929 for (auto &UC : Unresolved) {
930 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
931 Module::Conflict Conflict;
932 Conflict.Other = OtherMod;
933 Conflict.Message = UC.Message;
934 Mod->Conflicts.push_back(Conflict);
936 Mod->UnresolvedConflicts.push_back(UC);
938 return !Mod->UnresolvedConflicts.empty();
941 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
945 if (UmbrellaDirs.empty() && Headers.empty())
948 // Use the expansion location to determine which module we're in.
949 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
950 if (!ExpansionLoc.isFileID())
953 const SourceManager &SrcMgr = Loc.getManager();
954 FileID ExpansionFileID = ExpansionLoc.getFileID();
956 while (const FileEntry *ExpansionFile
957 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
958 // Find the module that owns this header (if any).
959 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
962 // No module owns this header, so look up the inclusion chain to see if
963 // any included header has an associated module.
964 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
965 if (IncludeLoc.isInvalid())
968 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
974 //----------------------------------------------------------------------------//
975 // Module map file parser
976 //----------------------------------------------------------------------------//
979 /// \brief A token in a module map file.
1011 unsigned StringLength;
1012 const char *StringData;
1018 StringData = nullptr;
1021 bool is(TokenKind K) const { return Kind == K; }
1023 SourceLocation getLocation() const {
1024 return SourceLocation::getFromRawEncoding(Location);
1027 StringRef getString() const {
1028 return StringRef(StringData, StringLength);
1032 class ModuleMapParser {
1034 SourceManager &SourceMgr;
1036 /// \brief Default target information, used only for string literal
1038 const TargetInfo *Target;
1040 DiagnosticsEngine &Diags;
1043 /// \brief The current module map file.
1044 const FileEntry *ModuleMapFile;
1046 /// \brief The directory that file names in this module map file should
1047 /// be resolved relative to.
1048 const DirectoryEntry *Directory;
1050 /// \brief The directory containing Clang-supplied headers.
1051 const DirectoryEntry *BuiltinIncludeDir;
1053 /// \brief Whether this module map is in a system header directory.
1056 /// \brief Whether an error occurred.
1059 /// \brief Stores string data for the various string literals referenced
1061 llvm::BumpPtrAllocator StringData;
1063 /// \brief The current token.
1066 /// \brief The active module.
1067 Module *ActiveModule;
1069 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1070 /// contents as 'textual'.
1072 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1073 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1074 /// non-modular headers. For backwards compatibility, we continue to
1075 /// support this idiom for just these modules, and map the headers to
1076 /// 'textual' to match the original intent.
1077 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1079 /// \brief Consume the current token and return its location.
1080 SourceLocation consumeToken();
1082 /// \brief Skip tokens until we reach the a token with the given kind
1083 /// (or the end of the file).
1084 void skipUntil(MMToken::TokenKind K);
1086 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
1087 bool parseModuleId(ModuleId &Id);
1088 void parseModuleDecl();
1089 void parseExternModuleDecl();
1090 void parseRequiresDecl();
1091 void parseHeaderDecl(clang::MMToken::TokenKind,
1092 SourceLocation LeadingLoc);
1093 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1094 void parseExportDecl();
1095 void parseUseDecl();
1096 void parseLinkDecl();
1097 void parseConfigMacros();
1098 void parseConflict();
1099 void parseInferredModuleDecl(bool Framework, bool Explicit);
1101 typedef ModuleMap::Attributes Attributes;
1102 bool parseOptionalAttributes(Attributes &Attrs);
1105 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1106 const TargetInfo *Target,
1107 DiagnosticsEngine &Diags,
1109 const FileEntry *ModuleMapFile,
1110 const DirectoryEntry *Directory,
1111 const DirectoryEntry *BuiltinIncludeDir,
1113 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1114 ModuleMapFile(ModuleMapFile), Directory(Directory),
1115 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1116 HadError(false), ActiveModule(nullptr)
1122 bool parseModuleMapFile();
1126 SourceLocation ModuleMapParser::consumeToken() {
1128 SourceLocation Result = Tok.getLocation();
1132 L.LexFromRawLexer(LToken);
1133 Tok.Location = LToken.getLocation().getRawEncoding();
1134 switch (LToken.getKind()) {
1135 case tok::raw_identifier: {
1136 StringRef RI = LToken.getRawIdentifier();
1137 Tok.StringData = RI.data();
1138 Tok.StringLength = RI.size();
1139 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1140 .Case("config_macros", MMToken::ConfigMacros)
1141 .Case("conflict", MMToken::Conflict)
1142 .Case("exclude", MMToken::ExcludeKeyword)
1143 .Case("explicit", MMToken::ExplicitKeyword)
1144 .Case("export", MMToken::ExportKeyword)
1145 .Case("extern", MMToken::ExternKeyword)
1146 .Case("framework", MMToken::FrameworkKeyword)
1147 .Case("header", MMToken::HeaderKeyword)
1148 .Case("link", MMToken::LinkKeyword)
1149 .Case("module", MMToken::ModuleKeyword)
1150 .Case("private", MMToken::PrivateKeyword)
1151 .Case("requires", MMToken::RequiresKeyword)
1152 .Case("textual", MMToken::TextualKeyword)
1153 .Case("umbrella", MMToken::UmbrellaKeyword)
1154 .Case("use", MMToken::UseKeyword)
1155 .Default(MMToken::Identifier);
1160 Tok.Kind = MMToken::Comma;
1164 Tok.Kind = MMToken::EndOfFile;
1168 Tok.Kind = MMToken::LBrace;
1172 Tok.Kind = MMToken::LSquare;
1176 Tok.Kind = MMToken::Period;
1180 Tok.Kind = MMToken::RBrace;
1184 Tok.Kind = MMToken::RSquare;
1188 Tok.Kind = MMToken::Star;
1192 Tok.Kind = MMToken::Exclaim;
1195 case tok::string_literal: {
1196 if (LToken.hasUDSuffix()) {
1197 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1202 // Parse the string literal.
1203 LangOptions LangOpts;
1204 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1205 if (StringLiteral.hadError)
1208 // Copy the string literal into our string data allocator.
1209 unsigned Length = StringLiteral.GetStringLength();
1210 char *Saved = StringData.Allocate<char>(Length + 1);
1211 memcpy(Saved, StringLiteral.GetString().data(), Length);
1215 Tok.Kind = MMToken::StringLiteral;
1216 Tok.StringData = Saved;
1217 Tok.StringLength = Length;
1225 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1233 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1234 unsigned braceDepth = 0;
1235 unsigned squareDepth = 0;
1238 case MMToken::EndOfFile:
1241 case MMToken::LBrace:
1242 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1248 case MMToken::LSquare:
1249 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1255 case MMToken::RBrace:
1262 case MMToken::RSquare:
1263 if (squareDepth > 0)
1270 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1279 /// \brief Parse a module-id.
1283 /// identifier '.' module-id
1285 /// \returns true if an error occurred, false otherwise.
1286 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1289 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1290 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1293 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1297 if (!Tok.is(MMToken::Period))
1307 /// \brief Enumerates the known attributes.
1308 enum AttributeKind {
1309 /// \brief An unknown attribute.
1311 /// \brief The 'system' attribute.
1313 /// \brief The 'extern_c' attribute.
1315 /// \brief The 'exhaustive' attribute.
1317 /// \brief The 'no_undeclared_includes' attribute.
1318 AT_no_undeclared_includes
1322 /// \brief Parse a module declaration.
1324 /// module-declaration:
1325 /// 'extern' 'module' module-id string-literal
1326 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1327 /// { module-member* }
1330 /// requires-declaration
1331 /// header-declaration
1332 /// submodule-declaration
1333 /// export-declaration
1334 /// link-declaration
1336 /// submodule-declaration:
1337 /// module-declaration
1338 /// inferred-submodule-declaration
1339 void ModuleMapParser::parseModuleDecl() {
1340 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1341 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1342 if (Tok.is(MMToken::ExternKeyword)) {
1343 parseExternModuleDecl();
1347 // Parse 'explicit' or 'framework' keyword, if present.
1348 SourceLocation ExplicitLoc;
1349 bool Explicit = false;
1350 bool Framework = false;
1352 // Parse 'explicit' keyword, if present.
1353 if (Tok.is(MMToken::ExplicitKeyword)) {
1354 ExplicitLoc = consumeToken();
1358 // Parse 'framework' keyword, if present.
1359 if (Tok.is(MMToken::FrameworkKeyword)) {
1364 // Parse 'module' keyword.
1365 if (!Tok.is(MMToken::ModuleKeyword)) {
1366 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1371 consumeToken(); // 'module' keyword
1373 // If we have a wildcard for the module name, this is an inferred submodule.
1375 if (Tok.is(MMToken::Star))
1376 return parseInferredModuleDecl(Framework, Explicit);
1378 // Parse the module name.
1380 if (parseModuleId(Id)) {
1386 if (Id.size() > 1) {
1387 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1388 << SourceRange(Id.front().second, Id.back().second);
1393 } else if (Id.size() == 1 && Explicit) {
1394 // Top-level modules can't be explicit.
1395 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1397 ExplicitLoc = SourceLocation();
1401 Module *PreviousActiveModule = ActiveModule;
1402 if (Id.size() > 1) {
1403 // This module map defines a submodule. Go find the module of which it
1405 ActiveModule = nullptr;
1406 const Module *TopLevelModule = nullptr;
1407 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1408 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1410 TopLevelModule = Next;
1411 ActiveModule = Next;
1416 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1418 << ActiveModule->getTopLevelModule()->getFullModuleName();
1420 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1426 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1427 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1428 "submodule defined in same file as 'module *' that allowed its "
1429 "top-level module");
1430 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1434 StringRef ModuleName = Id.back().first;
1435 SourceLocation ModuleNameLoc = Id.back().second;
1437 // Parse the optional attribute list.
1439 if (parseOptionalAttributes(Attrs))
1443 // Parse the opening brace.
1444 if (!Tok.is(MMToken::LBrace)) {
1445 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1450 SourceLocation LBraceLoc = consumeToken();
1452 // Determine whether this (sub)module has already been defined.
1453 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1454 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1455 // Skip the module definition.
1456 skipUntil(MMToken::RBrace);
1457 if (Tok.is(MMToken::RBrace))
1460 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1461 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1467 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1469 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1471 // Skip the module definition.
1472 skipUntil(MMToken::RBrace);
1473 if (Tok.is(MMToken::RBrace))
1480 // Start defining this module.
1481 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1483 ActiveModule->DefinitionLoc = ModuleNameLoc;
1484 if (Attrs.IsSystem || IsSystem)
1485 ActiveModule->IsSystem = true;
1486 if (Attrs.IsExternC)
1487 ActiveModule->IsExternC = true;
1488 if (Attrs.NoUndeclaredIncludes ||
1489 (!ActiveModule->Parent && ModuleName == "Darwin"))
1490 ActiveModule->NoUndeclaredIncludes = true;
1491 ActiveModule->Directory = Directory;
1493 if (!ActiveModule->Parent) {
1494 StringRef MapFileName(ModuleMapFile->getName());
1495 if (MapFileName.endswith("module.private.modulemap") ||
1496 MapFileName.endswith("module_private.map")) {
1497 // Adding a top-level module from a private modulemap is likely a
1498 // user error; we check to see if there's another top-level module
1499 // defined in the non-private map in the same dir, and if so emit a
1501 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1502 auto const *M = E->getValue();
1504 M->Directory == ActiveModule->Directory &&
1505 M->Name != ActiveModule->Name) {
1506 Diags.Report(ActiveModule->DefinitionLoc,
1507 diag::warn_mmap_mismatched_top_level_private)
1508 << ActiveModule->Name << M->Name;
1509 // The pattern we're defending against here is typically due to
1510 // a module named FooPrivate which is supposed to be a submodule
1511 // called Foo.Private. Emit a fixit in that case.
1513 Diags.Report(ActiveModule->DefinitionLoc,
1514 diag::note_mmap_rename_top_level_private_as_submodule);
1515 D << ActiveModule->Name << M->Name;
1516 StringRef Bad(ActiveModule->Name);
1517 if (Bad.consume_back("Private")) {
1518 SmallString<128> Fixed = Bad;
1519 Fixed.append(".Private");
1520 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
1532 case MMToken::EndOfFile:
1533 case MMToken::RBrace:
1537 case MMToken::ConfigMacros:
1538 parseConfigMacros();
1541 case MMToken::Conflict:
1545 case MMToken::ExplicitKeyword:
1546 case MMToken::ExternKeyword:
1547 case MMToken::FrameworkKeyword:
1548 case MMToken::ModuleKeyword:
1552 case MMToken::ExportKeyword:
1556 case MMToken::UseKeyword:
1560 case MMToken::RequiresKeyword:
1561 parseRequiresDecl();
1564 case MMToken::TextualKeyword:
1565 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
1568 case MMToken::UmbrellaKeyword: {
1569 SourceLocation UmbrellaLoc = consumeToken();
1570 if (Tok.is(MMToken::HeaderKeyword))
1571 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1573 parseUmbrellaDirDecl(UmbrellaLoc);
1577 case MMToken::ExcludeKeyword:
1578 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
1581 case MMToken::PrivateKeyword:
1582 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
1585 case MMToken::HeaderKeyword:
1586 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
1589 case MMToken::LinkKeyword:
1594 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1600 if (Tok.is(MMToken::RBrace))
1603 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1604 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1608 // If the active module is a top-level framework, and there are no link
1609 // libraries, automatically link against the framework.
1610 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1611 ActiveModule->LinkLibraries.empty()) {
1612 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1615 // If the module meets all requirements but is still unavailable, mark the
1616 // whole tree as unavailable to prevent it from building.
1617 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1618 ActiveModule->Parent) {
1619 ActiveModule->getTopLevelModule()->markUnavailable();
1620 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1621 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1624 // We're done parsing this module. Pop back to the previous module.
1625 ActiveModule = PreviousActiveModule;
1628 /// \brief Parse an extern module declaration.
1630 /// extern module-declaration:
1631 /// 'extern' 'module' module-id string-literal
1632 void ModuleMapParser::parseExternModuleDecl() {
1633 assert(Tok.is(MMToken::ExternKeyword));
1634 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
1636 // Parse 'module' keyword.
1637 if (!Tok.is(MMToken::ModuleKeyword)) {
1638 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1643 consumeToken(); // 'module' keyword
1645 // Parse the module name.
1647 if (parseModuleId(Id)) {
1652 // Parse the referenced module map file name.
1653 if (!Tok.is(MMToken::StringLiteral)) {
1654 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1658 std::string FileName = Tok.getString();
1659 consumeToken(); // filename
1661 StringRef FileNameRef = FileName;
1662 SmallString<128> ModuleMapFileName;
1663 if (llvm::sys::path::is_relative(FileNameRef)) {
1664 ModuleMapFileName += Directory->getName();
1665 llvm::sys::path::append(ModuleMapFileName, FileName);
1666 FileNameRef = ModuleMapFileName;
1668 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1669 Map.parseModuleMapFile(
1670 File, /*IsSystem=*/false,
1671 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1673 : File->getDir(), ExternLoc);
1676 /// Whether to add the requirement \p Feature to the module \p M.
1678 /// This preserves backwards compatibility for two hacks in the Darwin system
1679 /// module map files:
1681 /// 1. The use of 'requires excluded' to make headers non-modular, which
1682 /// should really be mapped to 'textual' now that we have this feature. We
1683 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1684 /// true. Later, this bit will be used to map all the headers inside this
1685 /// module to 'textual'.
1687 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1689 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1690 /// was never correct and causes issues now that we check it, so drop it.
1691 static bool shouldAddRequirement(Module *M, StringRef Feature,
1692 bool &IsRequiresExcludedHack) {
1693 if (Feature == "excluded" &&
1694 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
1695 M->fullModuleNameIs({"Tcl", "Private"}))) {
1696 IsRequiresExcludedHack = true;
1698 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
1705 /// \brief Parse a requires declaration.
1707 /// requires-declaration:
1708 /// 'requires' feature-list
1711 /// feature ',' feature-list
1715 /// '!'[opt] identifier
1716 void ModuleMapParser::parseRequiresDecl() {
1717 assert(Tok.is(MMToken::RequiresKeyword));
1719 // Parse 'requires' keyword.
1722 // Parse the feature-list.
1724 bool RequiredState = true;
1725 if (Tok.is(MMToken::Exclaim)) {
1726 RequiredState = false;
1730 if (!Tok.is(MMToken::Identifier)) {
1731 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1736 // Consume the feature name.
1737 std::string Feature = Tok.getString();
1740 bool IsRequiresExcludedHack = false;
1741 bool ShouldAddRequirement =
1742 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1744 if (IsRequiresExcludedHack)
1745 UsesRequiresExcludedHack.insert(ActiveModule);
1747 if (ShouldAddRequirement) {
1748 // Add this feature.
1749 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1753 if (!Tok.is(MMToken::Comma))
1756 // Consume the comma.
1761 /// \brief Append to \p Paths the set of paths needed to get to the
1762 /// subframework in which the given module lives.
1763 static void appendSubframeworkPaths(Module *Mod,
1764 SmallVectorImpl<char> &Path) {
1765 // Collect the framework names from the given module to the top-level module.
1766 SmallVector<StringRef, 2> Paths;
1767 for (; Mod; Mod = Mod->Parent) {
1768 if (Mod->IsFramework)
1769 Paths.push_back(Mod->Name);
1775 // Add Frameworks/Name.framework for each subframework.
1776 for (unsigned I = Paths.size() - 1; I != 0; --I)
1777 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1780 /// \brief Parse a header declaration.
1782 /// header-declaration:
1783 /// 'textual'[opt] 'header' string-literal
1784 /// 'private' 'textual'[opt] 'header' string-literal
1785 /// 'exclude' 'header' string-literal
1786 /// 'umbrella' 'header' string-literal
1788 /// FIXME: Support 'private textual header'.
1789 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1790 SourceLocation LeadingLoc) {
1791 // We've already consumed the first token.
1792 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1793 if (LeadingToken == MMToken::PrivateKeyword) {
1794 Role = ModuleMap::PrivateHeader;
1795 // 'private' may optionally be followed by 'textual'.
1796 if (Tok.is(MMToken::TextualKeyword)) {
1797 LeadingToken = Tok.Kind;
1802 if (LeadingToken == MMToken::TextualKeyword)
1803 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1805 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1806 // Mark this header 'textual' (see doc comment for
1807 // Module::UsesRequiresExcludedHack).
1808 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1811 if (LeadingToken != MMToken::HeaderKeyword) {
1812 if (!Tok.is(MMToken::HeaderKeyword)) {
1813 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1814 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1815 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1816 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1822 // Parse the header name.
1823 if (!Tok.is(MMToken::StringLiteral)) {
1824 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1829 Module::UnresolvedHeaderDirective Header;
1830 Header.FileName = Tok.getString();
1831 Header.FileNameLoc = consumeToken();
1833 // Check whether we already have an umbrella.
1834 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1835 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1836 << ActiveModule->getFullModuleName();
1841 // Look for this file.
1842 const FileEntry *File = nullptr;
1843 const FileEntry *BuiltinFile = nullptr;
1844 SmallString<128> RelativePathName;
1845 if (llvm::sys::path::is_absolute(Header.FileName)) {
1846 RelativePathName = Header.FileName;
1847 File = SourceMgr.getFileManager().getFile(RelativePathName);
1849 // Search for the header file within the search directory.
1850 SmallString<128> FullPathName(Directory->getName());
1851 unsigned FullPathLength = FullPathName.size();
1853 if (ActiveModule->isPartOfFramework()) {
1854 appendSubframeworkPaths(ActiveModule, RelativePathName);
1856 // Check whether this file is in the public headers.
1857 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1858 llvm::sys::path::append(FullPathName, RelativePathName);
1859 File = SourceMgr.getFileManager().getFile(FullPathName);
1862 // Check whether this file is in the private headers.
1863 // FIXME: Should we retain the subframework paths here?
1864 RelativePathName.clear();
1865 FullPathName.resize(FullPathLength);
1866 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1868 llvm::sys::path::append(FullPathName, RelativePathName);
1869 File = SourceMgr.getFileManager().getFile(FullPathName);
1872 // Lookup for normal headers.
1873 llvm::sys::path::append(RelativePathName, Header.FileName);
1874 llvm::sys::path::append(FullPathName, RelativePathName);
1875 File = SourceMgr.getFileManager().getFile(FullPathName);
1877 // If this is a system module with a top-level header, this header
1878 // may have a counterpart (or replacement) in the set of headers
1879 // supplied by Clang. Find that builtin header.
1880 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1881 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1882 isBuiltinHeader(Header.FileName)) {
1883 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1884 llvm::sys::path::append(BuiltinPathName, Header.FileName);
1885 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1887 // If Clang supplies this header but the underlying system does not,
1888 // just silently swap in our builtin version. Otherwise, we'll end
1889 // up adding both (later).
1890 if (BuiltinFile && !File) {
1892 RelativePathName = BuiltinPathName;
1893 BuiltinFile = nullptr;
1899 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1900 // Come up with a lazy way to do this.
1902 if (LeadingToken == MMToken::UmbrellaKeyword) {
1903 const DirectoryEntry *UmbrellaDir = File->getDir();
1904 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1905 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1906 << UmbrellaModule->getFullModuleName();
1909 // Record this umbrella header.
1910 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
1912 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1913 Module::Header H = {RelativePathName.str(), File};
1914 Map.excludeHeader(ActiveModule, H);
1916 // If there is a builtin counterpart to this file, add it now so it can
1917 // wrap the system header.
1919 // FIXME: Taking the name from the FileEntry is unstable and can give
1920 // different results depending on how we've previously named that file
1922 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1923 Map.addHeader(ActiveModule, H, Role);
1925 // If we have both a builtin and system version of the file, the
1926 // builtin version may want to inject macros into the system header, so
1927 // force the system header to be treated as a textual header in this
1929 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1932 // Record this header.
1933 Module::Header H = { RelativePathName.str(), File };
1934 Map.addHeader(ActiveModule, H, Role);
1936 } else if (LeadingToken != MMToken::ExcludeKeyword) {
1937 // Ignore excluded header files. They're optional anyway.
1939 // If we find a module that has a missing header, we mark this module as
1940 // unavailable and store the header directive for displaying diagnostics.
1941 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1942 ActiveModule->markUnavailable();
1943 ActiveModule->MissingHeaders.push_back(Header);
1947 static int compareModuleHeaders(const Module::Header *A,
1948 const Module::Header *B) {
1949 return A->NameAsWritten.compare(B->NameAsWritten);
1952 /// \brief Parse an umbrella directory declaration.
1954 /// umbrella-dir-declaration:
1955 /// umbrella string-literal
1956 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1957 // Parse the directory name.
1958 if (!Tok.is(MMToken::StringLiteral)) {
1959 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1965 std::string DirName = Tok.getString();
1966 SourceLocation DirNameLoc = consumeToken();
1968 // Check whether we already have an umbrella.
1969 if (ActiveModule->Umbrella) {
1970 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1971 << ActiveModule->getFullModuleName();
1976 // Look for this file.
1977 const DirectoryEntry *Dir = nullptr;
1978 if (llvm::sys::path::is_absolute(DirName))
1979 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1981 SmallString<128> PathName;
1982 PathName = Directory->getName();
1983 llvm::sys::path::append(PathName, DirName);
1984 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1988 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1994 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1995 // Mark this header 'textual' (see doc comment for
1996 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1997 // directory is relatively expensive, in practice this only applies to the
1998 // uncommonly used Tcl module on Darwin platforms.
2000 SmallVector<Module::Header, 6> Headers;
2001 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2002 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2003 I != E && !EC; I.increment(EC)) {
2004 if (const FileEntry *FE =
2005 SourceMgr.getFileManager().getFile(I->getName())) {
2007 Module::Header Header = {I->getName(), FE};
2008 Headers.push_back(std::move(Header));
2012 // Sort header paths so that the pcm doesn't depend on iteration order.
2013 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2015 for (auto &Header : Headers)
2016 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2020 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2021 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2022 << OwningModule->getFullModuleName();
2027 // Record this umbrella directory.
2028 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2031 /// \brief Parse a module export declaration.
2033 /// export-declaration:
2034 /// 'export' wildcard-module-id
2036 /// wildcard-module-id:
2039 /// identifier '.' wildcard-module-id
2040 void ModuleMapParser::parseExportDecl() {
2041 assert(Tok.is(MMToken::ExportKeyword));
2042 SourceLocation ExportLoc = consumeToken();
2044 // Parse the module-id with an optional wildcard at the end.
2045 ModuleId ParsedModuleId;
2046 bool Wildcard = false;
2048 // FIXME: Support string-literal module names here.
2049 if (Tok.is(MMToken::Identifier)) {
2050 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
2051 Tok.getLocation()));
2054 if (Tok.is(MMToken::Period)) {
2062 if(Tok.is(MMToken::Star)) {
2068 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2073 Module::UnresolvedExportDecl Unresolved = {
2074 ExportLoc, ParsedModuleId, Wildcard
2076 ActiveModule->UnresolvedExports.push_back(Unresolved);
2079 /// \brief Parse a module use declaration.
2081 /// use-declaration:
2082 /// 'use' wildcard-module-id
2083 void ModuleMapParser::parseUseDecl() {
2084 assert(Tok.is(MMToken::UseKeyword));
2085 auto KWLoc = consumeToken();
2086 // Parse the module-id.
2087 ModuleId ParsedModuleId;
2088 parseModuleId(ParsedModuleId);
2090 if (ActiveModule->Parent)
2091 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2093 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2096 /// \brief Parse a link declaration.
2098 /// module-declaration:
2099 /// 'link' 'framework'[opt] string-literal
2100 void ModuleMapParser::parseLinkDecl() {
2101 assert(Tok.is(MMToken::LinkKeyword));
2102 SourceLocation LinkLoc = consumeToken();
2104 // Parse the optional 'framework' keyword.
2105 bool IsFramework = false;
2106 if (Tok.is(MMToken::FrameworkKeyword)) {
2111 // Parse the library name
2112 if (!Tok.is(MMToken::StringLiteral)) {
2113 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2114 << IsFramework << SourceRange(LinkLoc);
2119 std::string LibraryName = Tok.getString();
2121 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2125 /// \brief Parse a configuration macro declaration.
2127 /// module-declaration:
2128 /// 'config_macros' attributes[opt] config-macro-list?
2130 /// config-macro-list:
2131 /// identifier (',' identifier)?
2132 void ModuleMapParser::parseConfigMacros() {
2133 assert(Tok.is(MMToken::ConfigMacros));
2134 SourceLocation ConfigMacrosLoc = consumeToken();
2136 // Only top-level modules can have configuration macros.
2137 if (ActiveModule->Parent) {
2138 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2141 // Parse the optional attributes.
2143 if (parseOptionalAttributes(Attrs))
2146 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2147 ActiveModule->ConfigMacrosExhaustive = true;
2150 // If we don't have an identifier, we're done.
2151 // FIXME: Support macros with the same name as a keyword here.
2152 if (!Tok.is(MMToken::Identifier))
2155 // Consume the first identifier.
2156 if (!ActiveModule->Parent) {
2157 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2162 // If there's a comma, consume it.
2163 if (!Tok.is(MMToken::Comma))
2167 // We expect to see a macro name here.
2168 // FIXME: Support macros with the same name as a keyword here.
2169 if (!Tok.is(MMToken::Identifier)) {
2170 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2174 // Consume the macro name.
2175 if (!ActiveModule->Parent) {
2176 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2182 /// \brief Format a module-id into a string.
2183 static std::string formatModuleId(const ModuleId &Id) {
2186 llvm::raw_string_ostream OS(result);
2188 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2198 /// \brief Parse a conflict declaration.
2200 /// module-declaration:
2201 /// 'conflict' module-id ',' string-literal
2202 void ModuleMapParser::parseConflict() {
2203 assert(Tok.is(MMToken::Conflict));
2204 SourceLocation ConflictLoc = consumeToken();
2205 Module::UnresolvedConflict Conflict;
2207 // Parse the module-id.
2208 if (parseModuleId(Conflict.Id))
2212 if (!Tok.is(MMToken::Comma)) {
2213 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2214 << SourceRange(ConflictLoc);
2219 // Parse the message.
2220 if (!Tok.is(MMToken::StringLiteral)) {
2221 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2222 << formatModuleId(Conflict.Id);
2225 Conflict.Message = Tok.getString().str();
2228 // Add this unresolved conflict.
2229 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2232 /// \brief Parse an inferred module declaration (wildcard modules).
2234 /// module-declaration:
2235 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2236 /// { inferred-module-member* }
2238 /// inferred-module-member:
2240 /// 'exclude' identifier
2241 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2242 assert(Tok.is(MMToken::Star));
2243 SourceLocation StarLoc = consumeToken();
2244 bool Failed = false;
2246 // Inferred modules must be submodules.
2247 if (!ActiveModule && !Framework) {
2248 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2253 // Inferred modules must have umbrella directories.
2254 if (!Failed && ActiveModule->IsAvailable &&
2255 !ActiveModule->getUmbrellaDir()) {
2256 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2260 // Check for redefinition of an inferred module.
2261 if (!Failed && ActiveModule->InferSubmodules) {
2262 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2263 if (ActiveModule->InferredSubmoduleLoc.isValid())
2264 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2265 diag::note_mmap_prev_definition);
2269 // Check for the 'framework' keyword, which is not permitted here.
2271 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2274 } else if (Explicit) {
2275 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2279 // If there were any problems with this inferred submodule, skip its body.
2281 if (Tok.is(MMToken::LBrace)) {
2283 skipUntil(MMToken::RBrace);
2284 if (Tok.is(MMToken::RBrace))
2291 // Parse optional attributes.
2293 if (parseOptionalAttributes(Attrs))
2297 // Note that we have an inferred submodule.
2298 ActiveModule->InferSubmodules = true;
2299 ActiveModule->InferredSubmoduleLoc = StarLoc;
2300 ActiveModule->InferExplicitSubmodules = Explicit;
2302 // We'll be inferring framework modules for this directory.
2303 Map.InferredDirectories[Directory].InferModules = true;
2304 Map.InferredDirectories[Directory].Attrs = Attrs;
2305 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2306 // FIXME: Handle the 'framework' keyword.
2309 // Parse the opening brace.
2310 if (!Tok.is(MMToken::LBrace)) {
2311 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2315 SourceLocation LBraceLoc = consumeToken();
2317 // Parse the body of the inferred submodule.
2321 case MMToken::EndOfFile:
2322 case MMToken::RBrace:
2326 case MMToken::ExcludeKeyword: {
2328 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2329 << (ActiveModule != nullptr);
2335 // FIXME: Support string-literal module names here.
2336 if (!Tok.is(MMToken::Identifier)) {
2337 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2341 Map.InferredDirectories[Directory].ExcludedModules
2342 .push_back(Tok.getString());
2347 case MMToken::ExportKeyword:
2348 if (!ActiveModule) {
2349 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2350 << (ActiveModule != nullptr);
2356 if (Tok.is(MMToken::Star))
2357 ActiveModule->InferExportWildcard = true;
2359 Diags.Report(Tok.getLocation(),
2360 diag::err_mmap_expected_export_wildcard);
2364 case MMToken::ExplicitKeyword:
2365 case MMToken::ModuleKeyword:
2366 case MMToken::HeaderKeyword:
2367 case MMToken::PrivateKeyword:
2368 case MMToken::UmbrellaKeyword:
2370 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2371 << (ActiveModule != nullptr);
2377 if (Tok.is(MMToken::RBrace))
2380 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2381 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2386 /// \brief Parse optional attributes.
2389 /// attribute attributes
2395 /// \param Attrs Will be filled in with the parsed attributes.
2397 /// \returns true if an error occurred, false otherwise.
2398 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2399 bool HadError = false;
2401 while (Tok.is(MMToken::LSquare)) {
2403 SourceLocation LSquareLoc = consumeToken();
2405 // Check whether we have an attribute name here.
2406 if (!Tok.is(MMToken::Identifier)) {
2407 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2408 skipUntil(MMToken::RSquare);
2409 if (Tok.is(MMToken::RSquare))
2414 // Decode the attribute name.
2415 AttributeKind Attribute
2416 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2417 .Case("exhaustive", AT_exhaustive)
2418 .Case("extern_c", AT_extern_c)
2419 .Case("no_undeclared_includes", AT_no_undeclared_includes)
2420 .Case("system", AT_system)
2421 .Default(AT_unknown);
2422 switch (Attribute) {
2424 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2429 Attrs.IsSystem = true;
2433 Attrs.IsExternC = true;
2437 Attrs.IsExhaustive = true;
2440 case AT_no_undeclared_includes:
2441 Attrs.NoUndeclaredIncludes = true;
2447 if (!Tok.is(MMToken::RSquare)) {
2448 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2449 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2450 skipUntil(MMToken::RSquare);
2454 if (Tok.is(MMToken::RSquare))
2461 /// \brief Parse a module map file.
2463 /// module-map-file:
2464 /// module-declaration*
2465 bool ModuleMapParser::parseModuleMapFile() {
2468 case MMToken::EndOfFile:
2471 case MMToken::ExplicitKeyword:
2472 case MMToken::ExternKeyword:
2473 case MMToken::ModuleKeyword:
2474 case MMToken::FrameworkKeyword:
2478 case MMToken::Comma:
2479 case MMToken::ConfigMacros:
2480 case MMToken::Conflict:
2481 case MMToken::Exclaim:
2482 case MMToken::ExcludeKeyword:
2483 case MMToken::ExportKeyword:
2484 case MMToken::HeaderKeyword:
2485 case MMToken::Identifier:
2486 case MMToken::LBrace:
2487 case MMToken::LinkKeyword:
2488 case MMToken::LSquare:
2489 case MMToken::Period:
2490 case MMToken::PrivateKeyword:
2491 case MMToken::RBrace:
2492 case MMToken::RSquare:
2493 case MMToken::RequiresKeyword:
2495 case MMToken::StringLiteral:
2496 case MMToken::TextualKeyword:
2497 case MMToken::UmbrellaKeyword:
2498 case MMToken::UseKeyword:
2499 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2507 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2508 const DirectoryEntry *Dir,
2509 SourceLocation ExternModuleLoc) {
2510 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2511 = ParsedModuleMap.find(File);
2512 if (Known != ParsedModuleMap.end())
2513 return Known->second;
2515 assert(Target && "Missing target information");
2516 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2517 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2518 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2520 return ParsedModuleMap[File] = true;
2522 // Parse this module map file.
2523 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2524 SourceLocation Start = L.getSourceLocation();
2525 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
2526 BuiltinIncludeDir, IsSystem);
2527 bool Result = Parser.parseModuleMapFile();
2528 ParsedModuleMap[File] = Result;
2530 // Notify callbacks that we parsed it.
2531 for (const auto &Cb : Callbacks)
2532 Cb->moduleMapFileRead(Start, *File, IsSystem);