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 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
302 diag::warn_non_modular_include_in_framework_module :
303 diag::warn_non_modular_include_in_module;
304 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
308 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
309 const ModuleMap::KnownHeader &Old) {
310 // Prefer available modules.
311 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
314 // Prefer a public header over a private header.
315 if ((New.getRole() & ModuleMap::PrivateHeader) !=
316 (Old.getRole() & ModuleMap::PrivateHeader))
317 return !(New.getRole() & ModuleMap::PrivateHeader);
319 // Prefer a non-textual header over a textual header.
320 if ((New.getRole() & ModuleMap::TextualHeader) !=
321 (Old.getRole() & ModuleMap::TextualHeader))
322 return !(New.getRole() & ModuleMap::TextualHeader);
324 // Don't have a reason to choose between these. Just keep the first one.
328 ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
329 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
330 if (R.getRole() & ModuleMap::TextualHeader)
331 return ModuleMap::KnownHeader();
335 HeadersMap::iterator Known = findKnownHeader(File);
336 if (Known != Headers.end()) {
337 ModuleMap::KnownHeader Result;
338 // Iterate over all modules that 'File' is part of to find the best fit.
339 for (KnownHeader &H : Known->second) {
340 // Prefer a header from the source module over all others.
341 if (H.getModule()->getTopLevelModule() == SourceModule)
342 return MakeResult(H);
343 if (!Result || isBetterKnownHeader(H, Result))
346 return MakeResult(Result);
349 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
352 ModuleMap::KnownHeader
353 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
354 assert(!Headers.count(File) && "already have a module for this header");
356 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
357 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
359 Module *Result = H.getModule();
361 // Search up the module stack until we find a module with an umbrella
363 Module *UmbrellaModule = Result;
364 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
365 UmbrellaModule = UmbrellaModule->Parent;
367 if (UmbrellaModule->InferSubmodules) {
368 const FileEntry *UmbrellaModuleMap =
369 getModuleMapFileForUniquing(UmbrellaModule);
371 // Infer submodules for each of the directories we found between
372 // the directory of the umbrella header and the directory where
373 // the actual header is located.
374 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
376 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
377 // Find or create the module that corresponds to this directory name.
378 SmallString<32> NameBuf;
379 StringRef Name = sanitizeFilenameAsIdentifier(
380 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
381 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
383 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
384 Result->IsInferred = true;
386 // Associate the module and the directory.
387 UmbrellaDirs[SkippedDirs[I-1]] = Result;
389 // If inferred submodules export everything they import, add a
390 // wildcard to the set of exports.
391 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
392 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
395 // Infer a submodule with the same name as this header file.
396 SmallString<32> NameBuf;
397 StringRef Name = sanitizeFilenameAsIdentifier(
398 llvm::sys::path::stem(File->getName()), NameBuf);
399 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
401 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
402 Result->IsInferred = true;
403 Result->addTopHeader(File);
405 // If inferred submodules export everything they import, add a
406 // wildcard to the set of exports.
407 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
408 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
410 // Record each of the directories we stepped through as being part of
411 // the module we found, since the umbrella header covers them all.
412 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
413 UmbrellaDirs[SkippedDirs[I]] = Result;
416 KnownHeader Header(Result, NormalHeader);
417 Headers[File].push_back(Header);
421 return KnownHeader();
424 ArrayRef<ModuleMap::KnownHeader>
425 ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
426 auto It = Headers.find(File);
427 if (It == Headers.end())
432 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
433 return isHeaderUnavailableInModule(Header, nullptr);
437 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
438 const Module *RequestingModule) const {
439 HeadersMap::const_iterator Known = Headers.find(Header);
440 if (Known != Headers.end()) {
441 for (SmallVectorImpl<KnownHeader>::const_iterator
442 I = Known->second.begin(),
443 E = Known->second.end();
445 if (I->isAvailable() && (!RequestingModule ||
446 I->getModule()->isSubModuleOf(RequestingModule)))
452 const DirectoryEntry *Dir = Header->getDir();
453 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
454 StringRef DirName = Dir->getName();
456 auto IsUnavailable = [&](const Module *M) {
457 return !M->isAvailable() && (!RequestingModule ||
458 M->isSubModuleOf(RequestingModule));
461 // Keep walking up the directory hierarchy, looking for a directory with
462 // an umbrella header.
464 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
465 = UmbrellaDirs.find(Dir);
466 if (KnownDir != UmbrellaDirs.end()) {
467 Module *Found = KnownDir->second;
468 if (IsUnavailable(Found))
471 // Search up the module stack until we find a module with an umbrella
473 Module *UmbrellaModule = Found;
474 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
475 UmbrellaModule = UmbrellaModule->Parent;
477 if (UmbrellaModule->InferSubmodules) {
478 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
479 // Find or create the module that corresponds to this directory name.
480 SmallString<32> NameBuf;
481 StringRef Name = sanitizeFilenameAsIdentifier(
482 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
484 Found = lookupModuleQualified(Name, Found);
487 if (IsUnavailable(Found))
491 // Infer a submodule with the same name as this header file.
492 SmallString<32> NameBuf;
493 StringRef Name = sanitizeFilenameAsIdentifier(
494 llvm::sys::path::stem(Header->getName()),
496 Found = lookupModuleQualified(Name, Found);
501 return IsUnavailable(Found);
504 SkippedDirs.push_back(Dir);
506 // Retrieve our parent path.
507 DirName = llvm::sys::path::parent_path(DirName);
511 // Resolve the parent path to a directory entry.
512 Dir = SourceMgr.getFileManager().getDirectory(DirName);
518 Module *ModuleMap::findModule(StringRef Name) const {
519 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
520 if (Known != Modules.end())
521 return Known->getValue();
526 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
527 Module *Context) const {
528 for(; Context; Context = Context->Parent) {
529 if (Module *Sub = lookupModuleQualified(Name, Context))
533 return findModule(Name);
536 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
538 return findModule(Name);
540 return Context->findSubmodule(Name);
543 std::pair<Module *, bool>
544 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
546 // Try to find an existing module with this name.
547 if (Module *Sub = lookupModuleQualified(Name, Parent))
548 return std::make_pair(Sub, false);
550 // Create a new module with this name.
551 Module *Result = new Module(Name, SourceLocation(), Parent,
552 IsFramework, IsExplicit, NumCreatedModules++);
554 if (LangOpts.CurrentModule == Name)
555 SourceModule = Result;
556 Modules[Name] = Result;
558 return std::make_pair(Result, true);
561 /// \brief For a framework module, infer the framework against which we
563 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
564 FileManager &FileMgr) {
565 assert(Mod->IsFramework && "Can only infer linking for framework modules");
566 assert(!Mod->isSubFramework() &&
567 "Can only infer linking for top-level frameworks");
569 SmallString<128> LibName;
570 LibName += FrameworkDir->getName();
571 llvm::sys::path::append(LibName, Mod->Name);
573 // The library name of a framework has more than one possible extension since
574 // the introduction of the text-based dynamic library format. We need to check
575 // for both before we give up.
576 static const char *frameworkExtensions[] = {"", ".tbd"};
577 for (const auto *extension : frameworkExtensions) {
578 llvm::sys::path::replace_extension(LibName, extension);
579 if (FileMgr.getFile(LibName)) {
580 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
581 /*IsFramework=*/true));
587 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
588 bool IsSystem, Module *Parent) {
590 Attrs.IsSystem = IsSystem;
591 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
594 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
595 Attributes Attrs, Module *Parent) {
596 // Note: as an egregious but useful hack we use the real path here, because
597 // we might be looking at an embedded framework that symlinks out to a
598 // top-level framework, and we need to infer as if we were naming the
599 // top-level framework.
600 StringRef FrameworkDirName =
601 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
603 // In case this is a case-insensitive filesystem, use the canonical
604 // directory name as the ModuleName, since modules are case-sensitive.
605 // FIXME: we should be able to give a fix-it hint for the correct spelling.
606 SmallString<32> ModuleNameStorage;
607 StringRef ModuleName = sanitizeFilenameAsIdentifier(
608 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
610 // Check whether we've already found this module.
611 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
614 FileManager &FileMgr = SourceMgr.getFileManager();
616 // If the framework has a parent path from which we're allowed to infer
617 // a framework module, do so.
618 const FileEntry *ModuleMapFile = nullptr;
620 // Determine whether we're allowed to infer a module map.
621 bool canInfer = false;
622 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
623 // Figure out the parent path.
624 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
625 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
626 // Check whether we have already looked into the parent directory
628 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
629 inferred = InferredDirectories.find(ParentDir);
630 if (inferred == InferredDirectories.end()) {
631 // We haven't looked here before. Load a module map, if there is
633 bool IsFrameworkDir = Parent.endswith(".framework");
634 if (const FileEntry *ModMapFile =
635 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
636 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
637 inferred = InferredDirectories.find(ParentDir);
640 if (inferred == InferredDirectories.end())
641 inferred = InferredDirectories.insert(
642 std::make_pair(ParentDir, InferredDirectory())).first;
645 if (inferred->second.InferModules) {
646 // We're allowed to infer for this directory, but make sure it's okay
647 // to infer this particular module.
648 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
649 canInfer = std::find(inferred->second.ExcludedModules.begin(),
650 inferred->second.ExcludedModules.end(),
651 Name) == inferred->second.ExcludedModules.end();
653 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
654 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
655 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
656 ModuleMapFile = inferred->second.ModuleMapFile;
661 // If we're not allowed to infer a framework module, don't.
665 ModuleMapFile = getModuleMapFileForUniquing(Parent);
668 // Look for an umbrella header.
669 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
670 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
671 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
673 // FIXME: If there's no umbrella header, we could probably scan the
674 // framework to load *everything*. But, it's not clear that this is a good
679 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
680 /*IsFramework=*/true, /*IsExplicit=*/false,
681 NumCreatedModules++);
682 InferredModuleAllowedBy[Result] = ModuleMapFile;
683 Result->IsInferred = true;
685 if (LangOpts.CurrentModule == ModuleName)
686 SourceModule = Result;
687 Modules[ModuleName] = Result;
690 Result->IsSystem |= Attrs.IsSystem;
691 Result->IsExternC |= Attrs.IsExternC;
692 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
693 Result->Directory = FrameworkDir;
695 // umbrella header "umbrella-header-name"
697 // The "Headers/" component of the name is implied because this is
698 // a framework module.
699 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
702 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
704 // module * { export * }
705 Result->InferSubmodules = true;
706 Result->InferExportWildcard = true;
708 // Look for subframeworks.
710 SmallString<128> SubframeworksDirName
711 = StringRef(FrameworkDir->getName());
712 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
713 llvm::sys::path::native(SubframeworksDirName);
714 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
715 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
717 Dir != DirEnd && !EC; Dir.increment(EC)) {
718 if (!StringRef(Dir->getName()).endswith(".framework"))
721 if (const DirectoryEntry *SubframeworkDir =
722 FileMgr.getDirectory(Dir->getName())) {
723 // Note: as an egregious but useful hack, we use the real path here and
724 // check whether it is actually a subdirectory of the parent directory.
725 // This will not be the case if the 'subframework' is actually a symlink
726 // out to a top-level framework.
727 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
728 bool FoundParent = false;
730 // Get the parent directory name.
732 = llvm::sys::path::parent_path(SubframeworkDirName);
733 if (SubframeworkDirName.empty())
736 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
745 // FIXME: Do we want to warn about subframeworks without umbrella headers?
746 inferFrameworkModule(SubframeworkDir, Attrs, Result);
750 // If the module is a top-level framework, automatically link against the
752 if (!Result->isSubFramework()) {
753 inferFrameworkLink(Result, FrameworkDir, FileMgr);
759 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
760 Twine NameAsWritten) {
761 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
762 Mod->Umbrella = UmbrellaHeader;
763 Mod->UmbrellaAsWritten = NameAsWritten.str();
764 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
766 // Notify callbacks that we just added a new header.
767 for (const auto &Cb : Callbacks)
768 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
771 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
772 Twine NameAsWritten) {
773 Mod->Umbrella = UmbrellaDir;
774 Mod->UmbrellaAsWritten = NameAsWritten.str();
775 UmbrellaDirs[UmbrellaDir] = Mod;
778 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
780 default: llvm_unreachable("unknown header role");
781 case ModuleMap::NormalHeader:
782 return Module::HK_Normal;
783 case ModuleMap::PrivateHeader:
784 return Module::HK_Private;
785 case ModuleMap::TextualHeader:
786 return Module::HK_Textual;
787 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
788 return Module::HK_PrivateTextual;
792 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
793 ModuleHeaderRole Role, bool Imported) {
794 KnownHeader KH(Mod, Role);
796 // Only add each header to the headers list once.
797 // FIXME: Should we diagnose if a header is listed twice in the
798 // same module definition?
799 auto &HeaderList = Headers[Header.Entry];
800 for (auto H : HeaderList)
804 HeaderList.push_back(KH);
805 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
807 bool isCompilingModuleHeader =
808 LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
809 if (!Imported || isCompilingModuleHeader) {
810 // When we import HeaderFileInfo, the external source is expected to
811 // set the isModuleHeader flag itself.
812 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
813 isCompilingModuleHeader);
816 // Notify callbacks that we just added a new header.
817 for (const auto &Cb : Callbacks)
818 Cb->moduleMapAddHeader(Header.Entry->getName());
821 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
822 // Add this as a known header so we won't implicitly add it to any
823 // umbrella directory module.
824 // FIXME: Should we only exclude it from umbrella modules within the
826 (void) Headers[Header.Entry];
828 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
832 ModuleMap::getContainingModuleMapFile(const Module *Module) const {
833 if (Module->DefinitionLoc.isInvalid())
836 return SourceMgr.getFileEntryForID(
837 SourceMgr.getFileID(Module->DefinitionLoc));
840 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
842 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
843 return InferredModuleAllowedBy.find(M)->second;
845 return getContainingModuleMapFile(M);
848 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
849 assert(M->IsInferred && "module not inferred");
850 InferredModuleAllowedBy[M] = ModMap;
853 LLVM_DUMP_METHOD void ModuleMap::dump() {
854 llvm::errs() << "Modules:";
855 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
856 MEnd = Modules.end();
858 M->getValue()->print(llvm::errs(), 2);
860 llvm::errs() << "Headers:";
861 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
863 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
864 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
867 if (I != H->second.begin())
869 llvm::errs() << I->getModule()->getFullModuleName();
871 llvm::errs() << "\n";
875 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
876 auto Unresolved = std::move(Mod->UnresolvedExports);
877 Mod->UnresolvedExports.clear();
878 for (auto &UE : Unresolved) {
879 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
880 if (Export.getPointer() || Export.getInt())
881 Mod->Exports.push_back(Export);
883 Mod->UnresolvedExports.push_back(UE);
885 return !Mod->UnresolvedExports.empty();
888 bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
889 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
890 Mod->UnresolvedDirectUses.clear();
891 for (auto &UDU : Unresolved) {
892 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
894 Mod->DirectUses.push_back(DirectUse);
896 Mod->UnresolvedDirectUses.push_back(UDU);
898 return !Mod->UnresolvedDirectUses.empty();
901 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
902 auto Unresolved = std::move(Mod->UnresolvedConflicts);
903 Mod->UnresolvedConflicts.clear();
904 for (auto &UC : Unresolved) {
905 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
906 Module::Conflict Conflict;
907 Conflict.Other = OtherMod;
908 Conflict.Message = UC.Message;
909 Mod->Conflicts.push_back(Conflict);
911 Mod->UnresolvedConflicts.push_back(UC);
913 return !Mod->UnresolvedConflicts.empty();
916 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
920 if (UmbrellaDirs.empty() && Headers.empty())
923 // Use the expansion location to determine which module we're in.
924 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
925 if (!ExpansionLoc.isFileID())
928 const SourceManager &SrcMgr = Loc.getManager();
929 FileID ExpansionFileID = ExpansionLoc.getFileID();
931 while (const FileEntry *ExpansionFile
932 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
933 // Find the module that owns this header (if any).
934 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
937 // No module owns this header, so look up the inclusion chain to see if
938 // any included header has an associated module.
939 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
940 if (IncludeLoc.isInvalid())
943 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
949 //----------------------------------------------------------------------------//
950 // Module map file parser
951 //----------------------------------------------------------------------------//
954 /// \brief A token in a module map file.
986 unsigned StringLength;
987 const char *StringData;
993 StringData = nullptr;
996 bool is(TokenKind K) const { return Kind == K; }
998 SourceLocation getLocation() const {
999 return SourceLocation::getFromRawEncoding(Location);
1002 StringRef getString() const {
1003 return StringRef(StringData, StringLength);
1007 class ModuleMapParser {
1009 SourceManager &SourceMgr;
1011 /// \brief Default target information, used only for string literal
1013 const TargetInfo *Target;
1015 DiagnosticsEngine &Diags;
1018 /// \brief The current module map file.
1019 const FileEntry *ModuleMapFile;
1021 /// \brief The directory that file names in this module map file should
1022 /// be resolved relative to.
1023 const DirectoryEntry *Directory;
1025 /// \brief The directory containing Clang-supplied headers.
1026 const DirectoryEntry *BuiltinIncludeDir;
1028 /// \brief Whether this module map is in a system header directory.
1031 /// \brief Whether an error occurred.
1034 /// \brief Stores string data for the various string literals referenced
1036 llvm::BumpPtrAllocator StringData;
1038 /// \brief The current token.
1041 /// \brief The active module.
1042 Module *ActiveModule;
1044 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1045 /// contents as 'textual'.
1047 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1048 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1049 /// non-modular headers. For backwards compatibility, we continue to
1050 /// support this idiom for just these modules, and map the headers to
1051 /// 'textual' to match the original intent.
1052 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1054 /// \brief Consume the current token and return its location.
1055 SourceLocation consumeToken();
1057 /// \brief Skip tokens until we reach the a token with the given kind
1058 /// (or the end of the file).
1059 void skipUntil(MMToken::TokenKind K);
1061 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
1062 bool parseModuleId(ModuleId &Id);
1063 void parseModuleDecl();
1064 void parseExternModuleDecl();
1065 void parseRequiresDecl();
1066 void parseHeaderDecl(clang::MMToken::TokenKind,
1067 SourceLocation LeadingLoc);
1068 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1069 void parseExportDecl();
1070 void parseUseDecl();
1071 void parseLinkDecl();
1072 void parseConfigMacros();
1073 void parseConflict();
1074 void parseInferredModuleDecl(bool Framework, bool Explicit);
1076 typedef ModuleMap::Attributes Attributes;
1077 bool parseOptionalAttributes(Attributes &Attrs);
1080 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1081 const TargetInfo *Target,
1082 DiagnosticsEngine &Diags,
1084 const FileEntry *ModuleMapFile,
1085 const DirectoryEntry *Directory,
1086 const DirectoryEntry *BuiltinIncludeDir,
1088 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1089 ModuleMapFile(ModuleMapFile), Directory(Directory),
1090 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1091 HadError(false), ActiveModule(nullptr)
1097 bool parseModuleMapFile();
1101 SourceLocation ModuleMapParser::consumeToken() {
1103 SourceLocation Result = Tok.getLocation();
1107 L.LexFromRawLexer(LToken);
1108 Tok.Location = LToken.getLocation().getRawEncoding();
1109 switch (LToken.getKind()) {
1110 case tok::raw_identifier: {
1111 StringRef RI = LToken.getRawIdentifier();
1112 Tok.StringData = RI.data();
1113 Tok.StringLength = RI.size();
1114 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1115 .Case("config_macros", MMToken::ConfigMacros)
1116 .Case("conflict", MMToken::Conflict)
1117 .Case("exclude", MMToken::ExcludeKeyword)
1118 .Case("explicit", MMToken::ExplicitKeyword)
1119 .Case("export", MMToken::ExportKeyword)
1120 .Case("extern", MMToken::ExternKeyword)
1121 .Case("framework", MMToken::FrameworkKeyword)
1122 .Case("header", MMToken::HeaderKeyword)
1123 .Case("link", MMToken::LinkKeyword)
1124 .Case("module", MMToken::ModuleKeyword)
1125 .Case("private", MMToken::PrivateKeyword)
1126 .Case("requires", MMToken::RequiresKeyword)
1127 .Case("textual", MMToken::TextualKeyword)
1128 .Case("umbrella", MMToken::UmbrellaKeyword)
1129 .Case("use", MMToken::UseKeyword)
1130 .Default(MMToken::Identifier);
1135 Tok.Kind = MMToken::Comma;
1139 Tok.Kind = MMToken::EndOfFile;
1143 Tok.Kind = MMToken::LBrace;
1147 Tok.Kind = MMToken::LSquare;
1151 Tok.Kind = MMToken::Period;
1155 Tok.Kind = MMToken::RBrace;
1159 Tok.Kind = MMToken::RSquare;
1163 Tok.Kind = MMToken::Star;
1167 Tok.Kind = MMToken::Exclaim;
1170 case tok::string_literal: {
1171 if (LToken.hasUDSuffix()) {
1172 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1177 // Parse the string literal.
1178 LangOptions LangOpts;
1179 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1180 if (StringLiteral.hadError)
1183 // Copy the string literal into our string data allocator.
1184 unsigned Length = StringLiteral.GetStringLength();
1185 char *Saved = StringData.Allocate<char>(Length + 1);
1186 memcpy(Saved, StringLiteral.GetString().data(), Length);
1190 Tok.Kind = MMToken::StringLiteral;
1191 Tok.StringData = Saved;
1192 Tok.StringLength = Length;
1200 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1208 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1209 unsigned braceDepth = 0;
1210 unsigned squareDepth = 0;
1213 case MMToken::EndOfFile:
1216 case MMToken::LBrace:
1217 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1223 case MMToken::LSquare:
1224 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1230 case MMToken::RBrace:
1237 case MMToken::RSquare:
1238 if (squareDepth > 0)
1245 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1254 /// \brief Parse a module-id.
1258 /// identifier '.' module-id
1260 /// \returns true if an error occurred, false otherwise.
1261 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1264 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1265 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1268 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1272 if (!Tok.is(MMToken::Period))
1282 /// \brief Enumerates the known attributes.
1283 enum AttributeKind {
1284 /// \brief An unknown attribute.
1286 /// \brief The 'system' attribute.
1288 /// \brief The 'extern_c' attribute.
1290 /// \brief The 'exhaustive' attribute.
1295 /// \brief Parse a module declaration.
1297 /// module-declaration:
1298 /// 'extern' 'module' module-id string-literal
1299 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1300 /// { module-member* }
1303 /// requires-declaration
1304 /// header-declaration
1305 /// submodule-declaration
1306 /// export-declaration
1307 /// link-declaration
1309 /// submodule-declaration:
1310 /// module-declaration
1311 /// inferred-submodule-declaration
1312 void ModuleMapParser::parseModuleDecl() {
1313 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1314 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1315 if (Tok.is(MMToken::ExternKeyword)) {
1316 parseExternModuleDecl();
1320 // Parse 'explicit' or 'framework' keyword, if present.
1321 SourceLocation ExplicitLoc;
1322 bool Explicit = false;
1323 bool Framework = false;
1325 // Parse 'explicit' keyword, if present.
1326 if (Tok.is(MMToken::ExplicitKeyword)) {
1327 ExplicitLoc = consumeToken();
1331 // Parse 'framework' keyword, if present.
1332 if (Tok.is(MMToken::FrameworkKeyword)) {
1337 // Parse 'module' keyword.
1338 if (!Tok.is(MMToken::ModuleKeyword)) {
1339 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1344 consumeToken(); // 'module' keyword
1346 // If we have a wildcard for the module name, this is an inferred submodule.
1348 if (Tok.is(MMToken::Star))
1349 return parseInferredModuleDecl(Framework, Explicit);
1351 // Parse the module name.
1353 if (parseModuleId(Id)) {
1359 if (Id.size() > 1) {
1360 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1361 << SourceRange(Id.front().second, Id.back().second);
1366 } else if (Id.size() == 1 && Explicit) {
1367 // Top-level modules can't be explicit.
1368 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1370 ExplicitLoc = SourceLocation();
1374 Module *PreviousActiveModule = ActiveModule;
1375 if (Id.size() > 1) {
1376 // This module map defines a submodule. Go find the module of which it
1378 ActiveModule = nullptr;
1379 const Module *TopLevelModule = nullptr;
1380 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1381 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1383 TopLevelModule = Next;
1384 ActiveModule = Next;
1389 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1391 << ActiveModule->getTopLevelModule()->getFullModuleName();
1393 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1399 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1400 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1401 "submodule defined in same file as 'module *' that allowed its "
1402 "top-level module");
1403 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1407 StringRef ModuleName = Id.back().first;
1408 SourceLocation ModuleNameLoc = Id.back().second;
1410 // Parse the optional attribute list.
1412 if (parseOptionalAttributes(Attrs))
1416 // Parse the opening brace.
1417 if (!Tok.is(MMToken::LBrace)) {
1418 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1423 SourceLocation LBraceLoc = consumeToken();
1425 // Determine whether this (sub)module has already been defined.
1426 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1427 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1428 // Skip the module definition.
1429 skipUntil(MMToken::RBrace);
1430 if (Tok.is(MMToken::RBrace))
1433 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1434 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1440 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1442 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1444 // Skip the module definition.
1445 skipUntil(MMToken::RBrace);
1446 if (Tok.is(MMToken::RBrace))
1453 // Start defining this module.
1454 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1456 ActiveModule->DefinitionLoc = ModuleNameLoc;
1457 if (Attrs.IsSystem || IsSystem)
1458 ActiveModule->IsSystem = true;
1459 if (Attrs.IsExternC)
1460 ActiveModule->IsExternC = true;
1461 ActiveModule->Directory = Directory;
1466 case MMToken::EndOfFile:
1467 case MMToken::RBrace:
1471 case MMToken::ConfigMacros:
1472 parseConfigMacros();
1475 case MMToken::Conflict:
1479 case MMToken::ExplicitKeyword:
1480 case MMToken::ExternKeyword:
1481 case MMToken::FrameworkKeyword:
1482 case MMToken::ModuleKeyword:
1486 case MMToken::ExportKeyword:
1490 case MMToken::UseKeyword:
1494 case MMToken::RequiresKeyword:
1495 parseRequiresDecl();
1498 case MMToken::TextualKeyword:
1499 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
1502 case MMToken::UmbrellaKeyword: {
1503 SourceLocation UmbrellaLoc = consumeToken();
1504 if (Tok.is(MMToken::HeaderKeyword))
1505 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1507 parseUmbrellaDirDecl(UmbrellaLoc);
1511 case MMToken::ExcludeKeyword:
1512 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
1515 case MMToken::PrivateKeyword:
1516 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
1519 case MMToken::HeaderKeyword:
1520 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
1523 case MMToken::LinkKeyword:
1528 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1534 if (Tok.is(MMToken::RBrace))
1537 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1538 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1542 // If the active module is a top-level framework, and there are no link
1543 // libraries, automatically link against the framework.
1544 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1545 ActiveModule->LinkLibraries.empty()) {
1546 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1549 // If the module meets all requirements but is still unavailable, mark the
1550 // whole tree as unavailable to prevent it from building.
1551 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1552 ActiveModule->Parent) {
1553 ActiveModule->getTopLevelModule()->markUnavailable();
1554 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1555 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1558 // We're done parsing this module. Pop back to the previous module.
1559 ActiveModule = PreviousActiveModule;
1562 /// \brief Parse an extern module declaration.
1564 /// extern module-declaration:
1565 /// 'extern' 'module' module-id string-literal
1566 void ModuleMapParser::parseExternModuleDecl() {
1567 assert(Tok.is(MMToken::ExternKeyword));
1568 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
1570 // Parse 'module' keyword.
1571 if (!Tok.is(MMToken::ModuleKeyword)) {
1572 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1577 consumeToken(); // 'module' keyword
1579 // Parse the module name.
1581 if (parseModuleId(Id)) {
1586 // Parse the referenced module map file name.
1587 if (!Tok.is(MMToken::StringLiteral)) {
1588 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1592 std::string FileName = Tok.getString();
1593 consumeToken(); // filename
1595 StringRef FileNameRef = FileName;
1596 SmallString<128> ModuleMapFileName;
1597 if (llvm::sys::path::is_relative(FileNameRef)) {
1598 ModuleMapFileName += Directory->getName();
1599 llvm::sys::path::append(ModuleMapFileName, FileName);
1600 FileNameRef = ModuleMapFileName;
1602 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1603 Map.parseModuleMapFile(
1604 File, /*IsSystem=*/false,
1605 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1607 : File->getDir(), ExternLoc);
1610 /// Whether to add the requirement \p Feature to the module \p M.
1612 /// This preserves backwards compatibility for two hacks in the Darwin system
1613 /// module map files:
1615 /// 1. The use of 'requires excluded' to make headers non-modular, which
1616 /// should really be mapped to 'textual' now that we have this feature. We
1617 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1618 /// true. Later, this bit will be used to map all the headers inside this
1619 /// module to 'textual'.
1621 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1623 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1624 /// was never correct and causes issues now that we check it, so drop it.
1625 static bool shouldAddRequirement(Module *M, StringRef Feature,
1626 bool &IsRequiresExcludedHack) {
1627 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1628 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1629 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1631 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1632 M->fullModuleNameIs(TclPrivate))) {
1633 IsRequiresExcludedHack = true;
1635 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1642 /// \brief Parse a requires declaration.
1644 /// requires-declaration:
1645 /// 'requires' feature-list
1648 /// feature ',' feature-list
1652 /// '!'[opt] identifier
1653 void ModuleMapParser::parseRequiresDecl() {
1654 assert(Tok.is(MMToken::RequiresKeyword));
1656 // Parse 'requires' keyword.
1659 // Parse the feature-list.
1661 bool RequiredState = true;
1662 if (Tok.is(MMToken::Exclaim)) {
1663 RequiredState = false;
1667 if (!Tok.is(MMToken::Identifier)) {
1668 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1673 // Consume the feature name.
1674 std::string Feature = Tok.getString();
1677 bool IsRequiresExcludedHack = false;
1678 bool ShouldAddRequirement =
1679 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1681 if (IsRequiresExcludedHack)
1682 UsesRequiresExcludedHack.insert(ActiveModule);
1684 if (ShouldAddRequirement) {
1685 // Add this feature.
1686 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1690 if (!Tok.is(MMToken::Comma))
1693 // Consume the comma.
1698 /// \brief Append to \p Paths the set of paths needed to get to the
1699 /// subframework in which the given module lives.
1700 static void appendSubframeworkPaths(Module *Mod,
1701 SmallVectorImpl<char> &Path) {
1702 // Collect the framework names from the given module to the top-level module.
1703 SmallVector<StringRef, 2> Paths;
1704 for (; Mod; Mod = Mod->Parent) {
1705 if (Mod->IsFramework)
1706 Paths.push_back(Mod->Name);
1712 // Add Frameworks/Name.framework for each subframework.
1713 for (unsigned I = Paths.size() - 1; I != 0; --I)
1714 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1717 /// \brief Parse a header declaration.
1719 /// header-declaration:
1720 /// 'textual'[opt] 'header' string-literal
1721 /// 'private' 'textual'[opt] 'header' string-literal
1722 /// 'exclude' 'header' string-literal
1723 /// 'umbrella' 'header' string-literal
1725 /// FIXME: Support 'private textual header'.
1726 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1727 SourceLocation LeadingLoc) {
1728 // We've already consumed the first token.
1729 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1730 if (LeadingToken == MMToken::PrivateKeyword) {
1731 Role = ModuleMap::PrivateHeader;
1732 // 'private' may optionally be followed by 'textual'.
1733 if (Tok.is(MMToken::TextualKeyword)) {
1734 LeadingToken = Tok.Kind;
1739 if (LeadingToken == MMToken::TextualKeyword)
1740 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1742 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1743 // Mark this header 'textual' (see doc comment for
1744 // Module::UsesRequiresExcludedHack).
1745 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1748 if (LeadingToken != MMToken::HeaderKeyword) {
1749 if (!Tok.is(MMToken::HeaderKeyword)) {
1750 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1751 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1752 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1753 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1759 // Parse the header name.
1760 if (!Tok.is(MMToken::StringLiteral)) {
1761 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1766 Module::UnresolvedHeaderDirective Header;
1767 Header.FileName = Tok.getString();
1768 Header.FileNameLoc = consumeToken();
1770 // Check whether we already have an umbrella.
1771 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1772 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1773 << ActiveModule->getFullModuleName();
1778 // Look for this file.
1779 const FileEntry *File = nullptr;
1780 const FileEntry *BuiltinFile = nullptr;
1781 SmallString<128> RelativePathName;
1782 if (llvm::sys::path::is_absolute(Header.FileName)) {
1783 RelativePathName = Header.FileName;
1784 File = SourceMgr.getFileManager().getFile(RelativePathName);
1786 // Search for the header file within the search directory.
1787 SmallString<128> FullPathName(Directory->getName());
1788 unsigned FullPathLength = FullPathName.size();
1790 if (ActiveModule->isPartOfFramework()) {
1791 appendSubframeworkPaths(ActiveModule, RelativePathName);
1793 // Check whether this file is in the public headers.
1794 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1795 llvm::sys::path::append(FullPathName, RelativePathName);
1796 File = SourceMgr.getFileManager().getFile(FullPathName);
1799 // Check whether this file is in the private headers.
1800 // FIXME: Should we retain the subframework paths here?
1801 RelativePathName.clear();
1802 FullPathName.resize(FullPathLength);
1803 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1805 llvm::sys::path::append(FullPathName, RelativePathName);
1806 File = SourceMgr.getFileManager().getFile(FullPathName);
1809 // Lookup for normal headers.
1810 llvm::sys::path::append(RelativePathName, Header.FileName);
1811 llvm::sys::path::append(FullPathName, RelativePathName);
1812 File = SourceMgr.getFileManager().getFile(FullPathName);
1814 // If this is a system module with a top-level header, this header
1815 // may have a counterpart (or replacement) in the set of headers
1816 // supplied by Clang. Find that builtin header.
1817 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1818 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1819 isBuiltinHeader(Header.FileName)) {
1820 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1821 llvm::sys::path::append(BuiltinPathName, Header.FileName);
1822 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1824 // If Clang supplies this header but the underlying system does not,
1825 // just silently swap in our builtin version. Otherwise, we'll end
1826 // up adding both (later).
1828 // For local visibility, entirely replace the system file with our
1829 // one and textually include the system one. We need to pass macros
1830 // from our header to the system one if we #include_next it.
1832 // FIXME: Can we do this in all cases?
1833 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
1835 RelativePathName = BuiltinPathName;
1836 BuiltinFile = nullptr;
1842 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1843 // Come up with a lazy way to do this.
1845 if (LeadingToken == MMToken::UmbrellaKeyword) {
1846 const DirectoryEntry *UmbrellaDir = File->getDir();
1847 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1848 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1849 << UmbrellaModule->getFullModuleName();
1852 // Record this umbrella header.
1853 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
1855 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1856 Module::Header H = {RelativePathName.str(), File};
1857 Map.excludeHeader(ActiveModule, H);
1859 // If there is a builtin counterpart to this file, add it now, before
1860 // the "real" header, so we build the built-in one first when building
1863 // FIXME: Taking the name from the FileEntry is unstable and can give
1864 // different results depending on how we've previously named that file
1866 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1867 Map.addHeader(ActiveModule, H, Role);
1870 // Record this header.
1871 Module::Header H = { RelativePathName.str(), File };
1872 Map.addHeader(ActiveModule, H, Role);
1874 } else if (LeadingToken != MMToken::ExcludeKeyword) {
1875 // Ignore excluded header files. They're optional anyway.
1877 // If we find a module that has a missing header, we mark this module as
1878 // unavailable and store the header directive for displaying diagnostics.
1879 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1880 ActiveModule->markUnavailable();
1881 ActiveModule->MissingHeaders.push_back(Header);
1885 static int compareModuleHeaders(const Module::Header *A,
1886 const Module::Header *B) {
1887 return A->NameAsWritten.compare(B->NameAsWritten);
1890 /// \brief Parse an umbrella directory declaration.
1892 /// umbrella-dir-declaration:
1893 /// umbrella string-literal
1894 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1895 // Parse the directory name.
1896 if (!Tok.is(MMToken::StringLiteral)) {
1897 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1903 std::string DirName = Tok.getString();
1904 SourceLocation DirNameLoc = consumeToken();
1906 // Check whether we already have an umbrella.
1907 if (ActiveModule->Umbrella) {
1908 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1909 << ActiveModule->getFullModuleName();
1914 // Look for this file.
1915 const DirectoryEntry *Dir = nullptr;
1916 if (llvm::sys::path::is_absolute(DirName))
1917 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1919 SmallString<128> PathName;
1920 PathName = Directory->getName();
1921 llvm::sys::path::append(PathName, DirName);
1922 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1926 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1932 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1933 // Mark this header 'textual' (see doc comment for
1934 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1935 // directory is relatively expensive, in practice this only applies to the
1936 // uncommonly used Tcl module on Darwin platforms.
1938 SmallVector<Module::Header, 6> Headers;
1939 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
1940 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
1941 I != E && !EC; I.increment(EC)) {
1942 if (const FileEntry *FE =
1943 SourceMgr.getFileManager().getFile(I->getName())) {
1945 Module::Header Header = {I->getName(), FE};
1946 Headers.push_back(std::move(Header));
1950 // Sort header paths so that the pcm doesn't depend on iteration order.
1951 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1953 for (auto &Header : Headers)
1954 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1958 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1959 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1960 << OwningModule->getFullModuleName();
1965 // Record this umbrella directory.
1966 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
1969 /// \brief Parse a module export declaration.
1971 /// export-declaration:
1972 /// 'export' wildcard-module-id
1974 /// wildcard-module-id:
1977 /// identifier '.' wildcard-module-id
1978 void ModuleMapParser::parseExportDecl() {
1979 assert(Tok.is(MMToken::ExportKeyword));
1980 SourceLocation ExportLoc = consumeToken();
1982 // Parse the module-id with an optional wildcard at the end.
1983 ModuleId ParsedModuleId;
1984 bool Wildcard = false;
1986 // FIXME: Support string-literal module names here.
1987 if (Tok.is(MMToken::Identifier)) {
1988 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1989 Tok.getLocation()));
1992 if (Tok.is(MMToken::Period)) {
2000 if(Tok.is(MMToken::Star)) {
2006 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2011 Module::UnresolvedExportDecl Unresolved = {
2012 ExportLoc, ParsedModuleId, Wildcard
2014 ActiveModule->UnresolvedExports.push_back(Unresolved);
2017 /// \brief Parse a module use declaration.
2019 /// use-declaration:
2020 /// 'use' wildcard-module-id
2021 void ModuleMapParser::parseUseDecl() {
2022 assert(Tok.is(MMToken::UseKeyword));
2023 auto KWLoc = consumeToken();
2024 // Parse the module-id.
2025 ModuleId ParsedModuleId;
2026 parseModuleId(ParsedModuleId);
2028 if (ActiveModule->Parent)
2029 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2031 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2034 /// \brief Parse a link declaration.
2036 /// module-declaration:
2037 /// 'link' 'framework'[opt] string-literal
2038 void ModuleMapParser::parseLinkDecl() {
2039 assert(Tok.is(MMToken::LinkKeyword));
2040 SourceLocation LinkLoc = consumeToken();
2042 // Parse the optional 'framework' keyword.
2043 bool IsFramework = false;
2044 if (Tok.is(MMToken::FrameworkKeyword)) {
2049 // Parse the library name
2050 if (!Tok.is(MMToken::StringLiteral)) {
2051 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2052 << IsFramework << SourceRange(LinkLoc);
2057 std::string LibraryName = Tok.getString();
2059 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2063 /// \brief Parse a configuration macro declaration.
2065 /// module-declaration:
2066 /// 'config_macros' attributes[opt] config-macro-list?
2068 /// config-macro-list:
2069 /// identifier (',' identifier)?
2070 void ModuleMapParser::parseConfigMacros() {
2071 assert(Tok.is(MMToken::ConfigMacros));
2072 SourceLocation ConfigMacrosLoc = consumeToken();
2074 // Only top-level modules can have configuration macros.
2075 if (ActiveModule->Parent) {
2076 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2079 // Parse the optional attributes.
2081 if (parseOptionalAttributes(Attrs))
2084 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2085 ActiveModule->ConfigMacrosExhaustive = true;
2088 // If we don't have an identifier, we're done.
2089 // FIXME: Support macros with the same name as a keyword here.
2090 if (!Tok.is(MMToken::Identifier))
2093 // Consume the first identifier.
2094 if (!ActiveModule->Parent) {
2095 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2100 // If there's a comma, consume it.
2101 if (!Tok.is(MMToken::Comma))
2105 // We expect to see a macro name here.
2106 // FIXME: Support macros with the same name as a keyword here.
2107 if (!Tok.is(MMToken::Identifier)) {
2108 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2112 // Consume the macro name.
2113 if (!ActiveModule->Parent) {
2114 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2120 /// \brief Format a module-id into a string.
2121 static std::string formatModuleId(const ModuleId &Id) {
2124 llvm::raw_string_ostream OS(result);
2126 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2136 /// \brief Parse a conflict declaration.
2138 /// module-declaration:
2139 /// 'conflict' module-id ',' string-literal
2140 void ModuleMapParser::parseConflict() {
2141 assert(Tok.is(MMToken::Conflict));
2142 SourceLocation ConflictLoc = consumeToken();
2143 Module::UnresolvedConflict Conflict;
2145 // Parse the module-id.
2146 if (parseModuleId(Conflict.Id))
2150 if (!Tok.is(MMToken::Comma)) {
2151 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2152 << SourceRange(ConflictLoc);
2157 // Parse the message.
2158 if (!Tok.is(MMToken::StringLiteral)) {
2159 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2160 << formatModuleId(Conflict.Id);
2163 Conflict.Message = Tok.getString().str();
2166 // Add this unresolved conflict.
2167 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2170 /// \brief Parse an inferred module declaration (wildcard modules).
2172 /// module-declaration:
2173 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2174 /// { inferred-module-member* }
2176 /// inferred-module-member:
2178 /// 'exclude' identifier
2179 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2180 assert(Tok.is(MMToken::Star));
2181 SourceLocation StarLoc = consumeToken();
2182 bool Failed = false;
2184 // Inferred modules must be submodules.
2185 if (!ActiveModule && !Framework) {
2186 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2191 // Inferred modules must have umbrella directories.
2192 if (!Failed && ActiveModule->IsAvailable &&
2193 !ActiveModule->getUmbrellaDir()) {
2194 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2198 // Check for redefinition of an inferred module.
2199 if (!Failed && ActiveModule->InferSubmodules) {
2200 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2201 if (ActiveModule->InferredSubmoduleLoc.isValid())
2202 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2203 diag::note_mmap_prev_definition);
2207 // Check for the 'framework' keyword, which is not permitted here.
2209 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2212 } else if (Explicit) {
2213 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2217 // If there were any problems with this inferred submodule, skip its body.
2219 if (Tok.is(MMToken::LBrace)) {
2221 skipUntil(MMToken::RBrace);
2222 if (Tok.is(MMToken::RBrace))
2229 // Parse optional attributes.
2231 if (parseOptionalAttributes(Attrs))
2235 // Note that we have an inferred submodule.
2236 ActiveModule->InferSubmodules = true;
2237 ActiveModule->InferredSubmoduleLoc = StarLoc;
2238 ActiveModule->InferExplicitSubmodules = Explicit;
2240 // We'll be inferring framework modules for this directory.
2241 Map.InferredDirectories[Directory].InferModules = true;
2242 Map.InferredDirectories[Directory].Attrs = Attrs;
2243 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2244 // FIXME: Handle the 'framework' keyword.
2247 // Parse the opening brace.
2248 if (!Tok.is(MMToken::LBrace)) {
2249 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2253 SourceLocation LBraceLoc = consumeToken();
2255 // Parse the body of the inferred submodule.
2259 case MMToken::EndOfFile:
2260 case MMToken::RBrace:
2264 case MMToken::ExcludeKeyword: {
2266 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2267 << (ActiveModule != nullptr);
2273 // FIXME: Support string-literal module names here.
2274 if (!Tok.is(MMToken::Identifier)) {
2275 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2279 Map.InferredDirectories[Directory].ExcludedModules
2280 .push_back(Tok.getString());
2285 case MMToken::ExportKeyword:
2286 if (!ActiveModule) {
2287 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2288 << (ActiveModule != nullptr);
2294 if (Tok.is(MMToken::Star))
2295 ActiveModule->InferExportWildcard = true;
2297 Diags.Report(Tok.getLocation(),
2298 diag::err_mmap_expected_export_wildcard);
2302 case MMToken::ExplicitKeyword:
2303 case MMToken::ModuleKeyword:
2304 case MMToken::HeaderKeyword:
2305 case MMToken::PrivateKeyword:
2306 case MMToken::UmbrellaKeyword:
2308 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2309 << (ActiveModule != nullptr);
2315 if (Tok.is(MMToken::RBrace))
2318 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2319 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2324 /// \brief Parse optional attributes.
2327 /// attribute attributes
2333 /// \param Attrs Will be filled in with the parsed attributes.
2335 /// \returns true if an error occurred, false otherwise.
2336 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2337 bool HadError = false;
2339 while (Tok.is(MMToken::LSquare)) {
2341 SourceLocation LSquareLoc = consumeToken();
2343 // Check whether we have an attribute name here.
2344 if (!Tok.is(MMToken::Identifier)) {
2345 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2346 skipUntil(MMToken::RSquare);
2347 if (Tok.is(MMToken::RSquare))
2352 // Decode the attribute name.
2353 AttributeKind Attribute
2354 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2355 .Case("exhaustive", AT_exhaustive)
2356 .Case("extern_c", AT_extern_c)
2357 .Case("system", AT_system)
2358 .Default(AT_unknown);
2359 switch (Attribute) {
2361 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2366 Attrs.IsSystem = true;
2370 Attrs.IsExternC = true;
2374 Attrs.IsExhaustive = true;
2380 if (!Tok.is(MMToken::RSquare)) {
2381 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2382 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2383 skipUntil(MMToken::RSquare);
2387 if (Tok.is(MMToken::RSquare))
2394 /// \brief Parse a module map file.
2396 /// module-map-file:
2397 /// module-declaration*
2398 bool ModuleMapParser::parseModuleMapFile() {
2401 case MMToken::EndOfFile:
2404 case MMToken::ExplicitKeyword:
2405 case MMToken::ExternKeyword:
2406 case MMToken::ModuleKeyword:
2407 case MMToken::FrameworkKeyword:
2411 case MMToken::Comma:
2412 case MMToken::ConfigMacros:
2413 case MMToken::Conflict:
2414 case MMToken::Exclaim:
2415 case MMToken::ExcludeKeyword:
2416 case MMToken::ExportKeyword:
2417 case MMToken::HeaderKeyword:
2418 case MMToken::Identifier:
2419 case MMToken::LBrace:
2420 case MMToken::LinkKeyword:
2421 case MMToken::LSquare:
2422 case MMToken::Period:
2423 case MMToken::PrivateKeyword:
2424 case MMToken::RBrace:
2425 case MMToken::RSquare:
2426 case MMToken::RequiresKeyword:
2428 case MMToken::StringLiteral:
2429 case MMToken::TextualKeyword:
2430 case MMToken::UmbrellaKeyword:
2431 case MMToken::UseKeyword:
2432 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2440 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2441 const DirectoryEntry *Dir,
2442 SourceLocation ExternModuleLoc) {
2443 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2444 = ParsedModuleMap.find(File);
2445 if (Known != ParsedModuleMap.end())
2446 return Known->second;
2448 assert(Target && "Missing target information");
2449 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2450 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2451 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2453 return ParsedModuleMap[File] = true;
2455 // Parse this module map file.
2456 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2457 SourceLocation Start = L.getSourceLocation();
2458 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
2459 BuiltinIncludeDir, IsSystem);
2460 bool Result = Parser.parseModuleMapFile();
2461 ParsedModuleMap[File] = Result;
2463 // Notify callbacks that we parsed it.
2464 for (const auto &Cb : Callbacks)
2465 Cb->moduleMapFileRead(Start, *File, IsSystem);