etc/services - sync with NetBSD-8
[minix.git] / external / bsd / llvm / dist / clang / lib / Lex / ModuleMap.cpp
blobef322d8cdc4c1191faad8ce1c3dd6b7ab4a20238
1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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"
33 #include <stdlib.h>
34 #if defined(LLVM_ON_UNIX)
35 #include <limits.h>
36 #endif
37 using namespace clang;
39 Module::ExportDecl
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);
51 if (!Context)
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);
61 if (!Context) {
62 if (Complain)
63 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
64 << Id[0].first << Mod->getFullModuleName();
66 return nullptr;
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);
72 if (!Sub) {
73 if (Complain)
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);
78 return nullptr;
81 Context = Sub;
84 return Context;
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 CompilingModule(nullptr), SourceModule(nullptr) {}
94 ModuleMap::~ModuleMap() {
95 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
96 IEnd = Modules.end();
97 I != IEnd; ++I) {
98 delete I->getValue();
102 void ModuleMap::setTarget(const TargetInfo &Target) {
103 assert((!this->Target || this->Target == &Target) &&
104 "Improper target override");
105 this->Target = &Target;
108 /// \brief "Sanitize" a filename so that it can be used as an identifier.
109 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
110 SmallVectorImpl<char> &Buffer) {
111 if (Name.empty())
112 return Name;
114 if (!isValidIdentifier(Name)) {
115 // If we don't already have something with the form of an identifier,
116 // create a buffer with the sanitized name.
117 Buffer.clear();
118 if (isDigit(Name[0]))
119 Buffer.push_back('_');
120 Buffer.reserve(Buffer.size() + Name.size());
121 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
122 if (isIdentifierBody(Name[I]))
123 Buffer.push_back(Name[I]);
124 else
125 Buffer.push_back('_');
128 Name = StringRef(Buffer.data(), Buffer.size());
131 while (llvm::StringSwitch<bool>(Name)
132 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
133 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
134 #include "clang/Basic/TokenKinds.def"
135 .Default(false)) {
136 if (Name.data() != Buffer.data())
137 Buffer.append(Name.begin(), Name.end());
138 Buffer.push_back('_');
139 Name = StringRef(Buffer.data(), Buffer.size());
142 return Name;
145 /// \brief Determine whether the given file name is the name of a builtin
146 /// header, supplied by Clang to replace, override, or augment existing system
147 /// headers.
148 static bool isBuiltinHeader(StringRef FileName) {
149 return llvm::StringSwitch<bool>(FileName)
150 .Case("float.h", true)
151 .Case("iso646.h", true)
152 .Case("limits.h", true)
153 .Case("stdalign.h", true)
154 .Case("stdarg.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)
160 .Default(false);
163 ModuleMap::HeadersMap::iterator
164 ModuleMap::findKnownHeader(const FileEntry *File) {
165 HeadersMap::iterator Known = Headers.find(File);
166 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
167 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
168 HeaderInfo.loadTopLevelSystemModules();
169 return Headers.find(File);
171 return Known;
174 ModuleMap::KnownHeader
175 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
176 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
177 const DirectoryEntry *Dir = File->getDir();
178 assert(Dir && "file in no directory");
180 // Note: as an egregious but useful hack we use the real path here, because
181 // frameworks moving from top-level frameworks to embedded frameworks tend
182 // to be symlinked from the top-level location to the embedded location,
183 // and we need to resolve lookups as if we had found the embedded location.
184 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
186 // Keep walking up the directory hierarchy, looking for a directory with
187 // an umbrella header.
188 do {
189 auto KnownDir = UmbrellaDirs.find(Dir);
190 if (KnownDir != UmbrellaDirs.end())
191 return KnownHeader(KnownDir->second, NormalHeader);
193 IntermediateDirs.push_back(Dir);
195 // Retrieve our parent path.
196 DirName = llvm::sys::path::parent_path(DirName);
197 if (DirName.empty())
198 break;
200 // Resolve the parent path to a directory entry.
201 Dir = SourceMgr.getFileManager().getDirectory(DirName);
202 } while (Dir);
203 return KnownHeader();
206 // Returns true if RequestingModule directly uses RequestedModule.
207 static bool directlyUses(const Module *RequestingModule,
208 const Module *RequestedModule) {
209 return std::find(RequestingModule->DirectUses.begin(),
210 RequestingModule->DirectUses.end(),
211 RequestedModule) != RequestingModule->DirectUses.end();
214 static bool violatesPrivateInclude(Module *RequestingModule,
215 const FileEntry *IncFileEnt,
216 ModuleMap::ModuleHeaderRole Role,
217 Module *RequestedModule) {
218 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
219 #ifndef NDEBUG
220 // Check for consistency between the module header role
221 // as obtained from the lookup and as obtained from the module.
222 // This check is not cheap, so enable it only for debugging.
223 bool IsPrivate = false;
224 SmallVectorImpl<Module::Header> *HeaderList[] =
225 {&RequestedModule->Headers[Module::HK_Private],
226 &RequestedModule->Headers[Module::HK_PrivateTextual]};
227 for (auto *Hdrs : HeaderList)
228 IsPrivate |=
229 std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) {
230 return H.Entry == IncFileEnt;
231 }) != Hdrs->end();
232 assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
233 #endif
234 return IsPrivateRole &&
235 RequestedModule->getTopLevelModule() != RequestingModule;
238 static Module *getTopLevelOrNull(Module *M) {
239 return M ? M->getTopLevelModule() : nullptr;
242 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
243 SourceLocation FilenameLoc,
244 StringRef Filename,
245 const FileEntry *File) {
246 // No errors for indirect modules. This may be a bit of a problem for modules
247 // with no source files.
248 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
249 return;
251 if (RequestingModule)
252 resolveUses(RequestingModule, /*Complain=*/false);
254 bool Excluded = false;
255 Module *Private = nullptr;
256 Module *NotUsed = nullptr;
258 HeadersMap::iterator Known = findKnownHeader(File);
259 if (Known != Headers.end()) {
260 for (const KnownHeader &Header : Known->second) {
261 // If 'File' is part of 'RequestingModule' we can definitely include it.
262 if (Header.getModule() == RequestingModule)
263 return;
265 // Remember private headers for later printing of a diagnostic.
266 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
267 Header.getModule())) {
268 Private = Header.getModule();
269 continue;
272 // If uses need to be specified explicitly, we are only allowed to return
273 // modules that are explicitly used by the requesting module.
274 if (RequestingModule && LangOpts.ModulesDeclUse &&
275 !directlyUses(RequestingModule, Header.getModule())) {
276 NotUsed = Header.getModule();
277 continue;
280 // We have found a module that we can happily use.
281 return;
284 Excluded = true;
287 // We have found a header, but it is private.
288 if (Private) {
289 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
290 << Filename;
291 return;
294 // We have found a module, but we don't use it.
295 if (NotUsed) {
296 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
297 << RequestingModule->getFullModuleName() << Filename;
298 return;
301 if (Excluded || isHeaderInUmbrellaDirs(File))
302 return;
304 // At this point, only non-modular includes remain.
306 if (LangOpts.ModulesStrictDeclUse) {
307 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
308 << RequestingModule->getFullModuleName() << Filename;
309 } else if (RequestingModule) {
310 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
311 diag::warn_non_modular_include_in_framework_module :
312 diag::warn_non_modular_include_in_module;
313 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
317 ModuleMap::KnownHeader
318 ModuleMap::findModuleForHeader(const FileEntry *File,
319 Module *RequestingModule,
320 bool IncludeTextualHeaders) {
321 HeadersMap::iterator Known = findKnownHeader(File);
323 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
324 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
325 return ModuleMap::KnownHeader();
326 return R;
329 if (Known != Headers.end()) {
330 ModuleMap::KnownHeader Result;
332 // Iterate over all modules that 'File' is part of to find the best fit.
333 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
334 E = Known->second.end();
335 I != E; ++I) {
336 // Cannot use a module if it is unavailable.
337 if (!I->getModule()->isAvailable())
338 continue;
340 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
341 // module we are looking for.
342 if (I->getModule() == RequestingModule)
343 return MakeResult(*I);
345 // If uses need to be specified explicitly, we are only allowed to return
346 // modules that are explicitly used by the requesting module.
347 if (RequestingModule && LangOpts.ModulesDeclUse &&
348 !directlyUses(RequestingModule, I->getModule()))
349 continue;
351 // Prefer a public header over a private header.
352 if (!Result || (Result.getRole() & ModuleMap::PrivateHeader))
353 Result = *I;
355 return MakeResult(Result);
358 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
359 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
360 if (H) {
361 Module *Result = H.getModule();
363 // Search up the module stack until we find a module with an umbrella
364 // directory.
365 Module *UmbrellaModule = Result;
366 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
367 UmbrellaModule = UmbrellaModule->Parent;
369 if (UmbrellaModule->InferSubmodules) {
370 const FileEntry *UmbrellaModuleMap =
371 getModuleMapFileForUniquing(UmbrellaModule);
373 // Infer submodules for each of the directories we found between
374 // the directory of the umbrella header and the directory where
375 // the actual header is located.
376 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
378 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
379 // Find or create the module that corresponds to this directory name.
380 SmallString<32> NameBuf;
381 StringRef Name = sanitizeFilenameAsIdentifier(
382 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
383 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
384 Explicit).first;
385 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
386 Result->IsInferred = true;
388 // Associate the module and the directory.
389 UmbrellaDirs[SkippedDirs[I-1]] = Result;
391 // If inferred submodules export everything they import, add a
392 // wildcard to the set of exports.
393 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
394 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
397 // Infer a submodule with the same name as this header file.
398 SmallString<32> NameBuf;
399 StringRef Name = sanitizeFilenameAsIdentifier(
400 llvm::sys::path::stem(File->getName()), NameBuf);
401 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
402 Explicit).first;
403 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
404 Result->IsInferred = true;
405 Result->addTopHeader(File);
407 // If inferred submodules export everything they import, add a
408 // wildcard to the set of exports.
409 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
410 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
411 } else {
412 // Record each of the directories we stepped through as being part of
413 // the module we found, since the umbrella header covers them all.
414 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
415 UmbrellaDirs[SkippedDirs[I]] = Result;
418 Headers[File].push_back(KnownHeader(Result, NormalHeader));
420 // If a header corresponds to an unavailable module, don't report
421 // that it maps to anything.
422 if (!Result->isAvailable())
423 return KnownHeader();
425 return MakeResult(Headers[File].back());
428 return KnownHeader();
431 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
432 return isHeaderUnavailableInModule(Header, nullptr);
435 bool
436 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
437 const Module *RequestingModule) const {
438 HeadersMap::const_iterator Known = Headers.find(Header);
439 if (Known != Headers.end()) {
440 for (SmallVectorImpl<KnownHeader>::const_iterator
441 I = Known->second.begin(),
442 E = Known->second.end();
443 I != E; ++I) {
444 if (I->isAvailable() && (!RequestingModule ||
445 I->getModule()->isSubModuleOf(RequestingModule)))
446 return false;
448 return true;
451 const DirectoryEntry *Dir = Header->getDir();
452 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
453 StringRef DirName = Dir->getName();
455 auto IsUnavailable = [&](const Module *M) {
456 return !M->isAvailable() && (!RequestingModule ||
457 M->isSubModuleOf(RequestingModule));
460 // Keep walking up the directory hierarchy, looking for a directory with
461 // an umbrella header.
462 do {
463 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
464 = UmbrellaDirs.find(Dir);
465 if (KnownDir != UmbrellaDirs.end()) {
466 Module *Found = KnownDir->second;
467 if (IsUnavailable(Found))
468 return true;
470 // Search up the module stack until we find a module with an umbrella
471 // directory.
472 Module *UmbrellaModule = Found;
473 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
474 UmbrellaModule = UmbrellaModule->Parent;
476 if (UmbrellaModule->InferSubmodules) {
477 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
478 // Find or create the module that corresponds to this directory name.
479 SmallString<32> NameBuf;
480 StringRef Name = sanitizeFilenameAsIdentifier(
481 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
482 NameBuf);
483 Found = lookupModuleQualified(Name, Found);
484 if (!Found)
485 return false;
486 if (IsUnavailable(Found))
487 return true;
490 // Infer a submodule with the same name as this header file.
491 SmallString<32> NameBuf;
492 StringRef Name = sanitizeFilenameAsIdentifier(
493 llvm::sys::path::stem(Header->getName()),
494 NameBuf);
495 Found = lookupModuleQualified(Name, Found);
496 if (!Found)
497 return false;
500 return IsUnavailable(Found);
503 SkippedDirs.push_back(Dir);
505 // Retrieve our parent path.
506 DirName = llvm::sys::path::parent_path(DirName);
507 if (DirName.empty())
508 break;
510 // Resolve the parent path to a directory entry.
511 Dir = SourceMgr.getFileManager().getDirectory(DirName);
512 } while (Dir);
514 return false;
517 Module *ModuleMap::findModule(StringRef Name) const {
518 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
519 if (Known != Modules.end())
520 return Known->getValue();
522 return nullptr;
525 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
526 Module *Context) const {
527 for(; Context; Context = Context->Parent) {
528 if (Module *Sub = lookupModuleQualified(Name, Context))
529 return Sub;
532 return findModule(Name);
535 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
536 if (!Context)
537 return findModule(Name);
539 return Context->findSubmodule(Name);
542 std::pair<Module *, bool>
543 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
544 bool IsExplicit) {
545 // Try to find an existing module with this name.
546 if (Module *Sub = lookupModuleQualified(Name, Parent))
547 return std::make_pair(Sub, false);
549 // Create a new module with this name.
550 Module *Result = new Module(Name, SourceLocation(), Parent,
551 IsFramework, IsExplicit);
552 if (LangOpts.CurrentModule == Name) {
553 SourceModule = Result;
554 SourceModuleName = Name;
556 if (!Parent) {
557 Modules[Name] = Result;
558 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
559 Name == LangOpts.CurrentModule) {
560 CompilingModule = Result;
563 return std::make_pair(Result, true);
566 /// \brief For a framework module, infer the framework against which we
567 /// should link.
568 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
569 FileManager &FileMgr) {
570 assert(Mod->IsFramework && "Can only infer linking for framework modules");
571 assert(!Mod->isSubFramework() &&
572 "Can only infer linking for top-level frameworks");
574 SmallString<128> LibName;
575 LibName += FrameworkDir->getName();
576 llvm::sys::path::append(LibName, Mod->Name);
577 if (FileMgr.getFile(LibName)) {
578 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
579 /*IsFramework=*/true));
583 Module *
584 ModuleMap::inferFrameworkModule(StringRef ModuleName,
585 const DirectoryEntry *FrameworkDir,
586 bool IsSystem,
587 Module *Parent) {
588 Attributes Attrs;
589 Attrs.IsSystem = IsSystem;
590 return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
593 Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
594 const DirectoryEntry *FrameworkDir,
595 Attributes Attrs, Module *Parent) {
597 // Check whether we've already found this module.
598 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
599 return Mod;
601 FileManager &FileMgr = SourceMgr.getFileManager();
603 // If the framework has a parent path from which we're allowed to infer
604 // a framework module, do so.
605 const FileEntry *ModuleMapFile = nullptr;
606 if (!Parent) {
607 // Determine whether we're allowed to infer a module map.
609 // Note: as an egregious but useful hack we use the real path here, because
610 // we might be looking at an embedded framework that symlinks out to a
611 // top-level framework, and we need to infer as if we were naming the
612 // top-level framework.
613 StringRef FrameworkDirName
614 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
616 // In case this is a case-insensitive filesystem, make sure the canonical
617 // directory name matches ModuleName exactly. Modules are case-sensitive.
618 // FIXME: we should be able to give a fix-it hint for the correct spelling.
619 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
620 return nullptr;
622 bool canInfer = false;
623 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
624 // Figure out the parent path.
625 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
626 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
627 // Check whether we have already looked into the parent directory
628 // for a module map.
629 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
630 inferred = InferredDirectories.find(ParentDir);
631 if (inferred == InferredDirectories.end()) {
632 // We haven't looked here before. Load a module map, if there is
633 // one.
634 bool IsFrameworkDir = Parent.endswith(".framework");
635 if (const FileEntry *ModMapFile =
636 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
637 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
638 inferred = InferredDirectories.find(ParentDir);
641 if (inferred == InferredDirectories.end())
642 inferred = InferredDirectories.insert(
643 std::make_pair(ParentDir, InferredDirectory())).first;
646 if (inferred->second.InferModules) {
647 // We're allowed to infer for this directory, but make sure it's okay
648 // to infer this particular module.
649 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
650 canInfer = std::find(inferred->second.ExcludedModules.begin(),
651 inferred->second.ExcludedModules.end(),
652 Name) == inferred->second.ExcludedModules.end();
654 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
655 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
656 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
657 ModuleMapFile = inferred->second.ModuleMapFile;
662 // If we're not allowed to infer a framework module, don't.
663 if (!canInfer)
664 return nullptr;
665 } else
666 ModuleMapFile = getModuleMapFileForUniquing(Parent);
669 // Look for an umbrella header.
670 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
671 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
672 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
674 // FIXME: If there's no umbrella header, we could probably scan the
675 // framework to load *everything*. But, it's not clear that this is a good
676 // idea.
677 if (!UmbrellaHeader)
678 return nullptr;
680 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
681 /*IsFramework=*/true, /*IsExplicit=*/false);
682 InferredModuleAllowedBy[Result] = ModuleMapFile;
683 Result->IsInferred = true;
684 if (LangOpts.CurrentModule == ModuleName) {
685 SourceModule = Result;
686 SourceModuleName = ModuleName;
689 Result->IsSystem |= Attrs.IsSystem;
690 Result->IsExternC |= Attrs.IsExternC;
691 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
693 if (!Parent)
694 Modules[ModuleName] = Result;
696 // umbrella header "umbrella-header-name"
697 Result->Umbrella = UmbrellaHeader;
698 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
699 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
701 // export *
702 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
704 // module * { export * }
705 Result->InferSubmodules = true;
706 Result->InferExportWildcard = true;
708 // Look for subframeworks.
709 std::error_code EC;
710 SmallString<128> SubframeworksDirName
711 = StringRef(FrameworkDir->getName());
712 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
713 llvm::sys::path::native(SubframeworksDirName);
714 for (llvm::sys::fs::directory_iterator
715 Dir(SubframeworksDirName.str(), EC), DirEnd;
716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(".framework"))
718 continue;
720 if (const DirectoryEntry *SubframeworkDir
721 = FileMgr.getDirectory(Dir->path())) {
722 // Note: as an egregious but useful hack, we use the real path here and
723 // check whether it is actually a subdirectory of the parent directory.
724 // This will not be the case if the 'subframework' is actually a symlink
725 // out to a top-level framework.
726 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
727 bool FoundParent = false;
728 do {
729 // Get the parent directory name.
730 SubframeworkDirName
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
733 break;
735 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
736 FoundParent = true;
737 break;
739 } while (true);
741 if (!FoundParent)
742 continue;
744 // FIXME: Do we want to warn about subframeworks without umbrella headers?
745 SmallString<32> NameBuf;
746 inferFrameworkModule(sanitizeFilenameAsIdentifier(
747 llvm::sys::path::stem(Dir->path()), NameBuf),
748 SubframeworkDir, Attrs, Result);
752 // If the module is a top-level framework, automatically link against the
753 // framework.
754 if (!Result->isSubFramework()) {
755 inferFrameworkLink(Result, FrameworkDir, FileMgr);
758 return Result;
761 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
762 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
763 Mod->Umbrella = UmbrellaHeader;
764 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
767 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
768 Mod->Umbrella = UmbrellaDir;
769 UmbrellaDirs[UmbrellaDir] = Mod;
772 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
773 switch ((int)Role) {
774 default: llvm_unreachable("unknown header role");
775 case ModuleMap::NormalHeader:
776 return Module::HK_Normal;
777 case ModuleMap::PrivateHeader:
778 return Module::HK_Private;
779 case ModuleMap::TextualHeader:
780 return Module::HK_Textual;
781 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
782 return Module::HK_PrivateTextual;
786 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
787 ModuleHeaderRole Role) {
788 if (!(Role & TextualHeader)) {
789 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
790 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
791 isCompilingModuleHeader);
793 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
795 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
798 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
799 // Add this as a known header so we won't implicitly add it to any
800 // umbrella directory module.
801 // FIXME: Should we only exclude it from umbrella modules within the
802 // specified module?
803 (void) Headers[Header.Entry];
805 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
808 const FileEntry *
809 ModuleMap::getContainingModuleMapFile(const Module *Module) const {
810 if (Module->DefinitionLoc.isInvalid())
811 return nullptr;
813 return SourceMgr.getFileEntryForID(
814 SourceMgr.getFileID(Module->DefinitionLoc));
817 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
818 if (M->IsInferred) {
819 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
820 return InferredModuleAllowedBy.find(M)->second;
822 return getContainingModuleMapFile(M);
825 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
826 assert(M->IsInferred && "module not inferred");
827 InferredModuleAllowedBy[M] = ModMap;
830 void ModuleMap::dump() {
831 llvm::errs() << "Modules:";
832 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
833 MEnd = Modules.end();
834 M != MEnd; ++M)
835 M->getValue()->print(llvm::errs(), 2);
837 llvm::errs() << "Headers:";
838 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
839 H != HEnd; ++H) {
840 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
841 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
842 E = H->second.end();
843 I != E; ++I) {
844 if (I != H->second.begin())
845 llvm::errs() << ",";
846 llvm::errs() << I->getModule()->getFullModuleName();
848 llvm::errs() << "\n";
852 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
853 bool HadError = false;
854 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
855 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
856 Complain);
857 if (Export.getPointer() || Export.getInt())
858 Mod->Exports.push_back(Export);
859 else
860 HadError = true;
862 Mod->UnresolvedExports.clear();
863 return HadError;
866 bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
867 bool HadError = false;
868 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
869 Module *DirectUse =
870 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
871 if (DirectUse)
872 Mod->DirectUses.push_back(DirectUse);
873 else
874 HadError = true;
876 Mod->UnresolvedDirectUses.clear();
877 return HadError;
880 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
881 bool HadError = false;
882 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
883 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
884 Mod, Complain);
885 if (!OtherMod) {
886 HadError = true;
887 continue;
890 Module::Conflict Conflict;
891 Conflict.Other = OtherMod;
892 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
893 Mod->Conflicts.push_back(Conflict);
895 Mod->UnresolvedConflicts.clear();
896 return HadError;
899 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
900 if (Loc.isInvalid())
901 return nullptr;
903 // Use the expansion location to determine which module we're in.
904 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
905 if (!ExpansionLoc.isFileID())
906 return nullptr;
908 const SourceManager &SrcMgr = Loc.getManager();
909 FileID ExpansionFileID = ExpansionLoc.getFileID();
911 while (const FileEntry *ExpansionFile
912 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
913 // Find the module that owns this header (if any).
914 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
915 return Mod;
917 // No module owns this header, so look up the inclusion chain to see if
918 // any included header has an associated module.
919 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
920 if (IncludeLoc.isInvalid())
921 return nullptr;
923 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
926 return nullptr;
929 //----------------------------------------------------------------------------//
930 // Module map file parser
931 //----------------------------------------------------------------------------//
933 namespace clang {
934 /// \brief A token in a module map file.
935 struct MMToken {
936 enum TokenKind {
937 Comma,
938 ConfigMacros,
939 Conflict,
940 EndOfFile,
941 HeaderKeyword,
942 Identifier,
943 Exclaim,
944 ExcludeKeyword,
945 ExplicitKeyword,
946 ExportKeyword,
947 ExternKeyword,
948 FrameworkKeyword,
949 LinkKeyword,
950 ModuleKeyword,
951 Period,
952 PrivateKeyword,
953 UmbrellaKeyword,
954 UseKeyword,
955 RequiresKeyword,
956 Star,
957 StringLiteral,
958 TextualKeyword,
959 LBrace,
960 RBrace,
961 LSquare,
962 RSquare
963 } Kind;
965 unsigned Location;
966 unsigned StringLength;
967 const char *StringData;
969 void clear() {
970 Kind = EndOfFile;
971 Location = 0;
972 StringLength = 0;
973 StringData = nullptr;
976 bool is(TokenKind K) const { return Kind == K; }
978 SourceLocation getLocation() const {
979 return SourceLocation::getFromRawEncoding(Location);
982 StringRef getString() const {
983 return StringRef(StringData, StringLength);
987 class ModuleMapParser {
988 Lexer &L;
989 SourceManager &SourceMgr;
991 /// \brief Default target information, used only for string literal
992 /// parsing.
993 const TargetInfo *Target;
995 DiagnosticsEngine &Diags;
996 ModuleMap &Map;
998 /// \brief The current module map file.
999 const FileEntry *ModuleMapFile;
1001 /// \brief The directory that file names in this module map file should
1002 /// be resolved relative to.
1003 const DirectoryEntry *Directory;
1005 /// \brief The directory containing Clang-supplied headers.
1006 const DirectoryEntry *BuiltinIncludeDir;
1008 /// \brief Whether this module map is in a system header directory.
1009 bool IsSystem;
1011 /// \brief Whether an error occurred.
1012 bool HadError;
1014 /// \brief Stores string data for the various string literals referenced
1015 /// during parsing.
1016 llvm::BumpPtrAllocator StringData;
1018 /// \brief The current token.
1019 MMToken Tok;
1021 /// \brief The active module.
1022 Module *ActiveModule;
1024 /// \brief Consume the current token and return its location.
1025 SourceLocation consumeToken();
1027 /// \brief Skip tokens until we reach the a token with the given kind
1028 /// (or the end of the file).
1029 void skipUntil(MMToken::TokenKind K);
1031 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
1032 bool parseModuleId(ModuleId &Id);
1033 void parseModuleDecl();
1034 void parseExternModuleDecl();
1035 void parseRequiresDecl();
1036 void parseHeaderDecl(clang::MMToken::TokenKind,
1037 SourceLocation LeadingLoc);
1038 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1039 void parseExportDecl();
1040 void parseUseDecl();
1041 void parseLinkDecl();
1042 void parseConfigMacros();
1043 void parseConflict();
1044 void parseInferredModuleDecl(bool Framework, bool Explicit);
1046 typedef ModuleMap::Attributes Attributes;
1047 bool parseOptionalAttributes(Attributes &Attrs);
1049 public:
1050 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1051 const TargetInfo *Target,
1052 DiagnosticsEngine &Diags,
1053 ModuleMap &Map,
1054 const FileEntry *ModuleMapFile,
1055 const DirectoryEntry *Directory,
1056 const DirectoryEntry *BuiltinIncludeDir,
1057 bool IsSystem)
1058 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1059 ModuleMapFile(ModuleMapFile), Directory(Directory),
1060 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1061 HadError(false), ActiveModule(nullptr)
1063 Tok.clear();
1064 consumeToken();
1067 bool parseModuleMapFile();
1071 SourceLocation ModuleMapParser::consumeToken() {
1072 retry:
1073 SourceLocation Result = Tok.getLocation();
1074 Tok.clear();
1076 Token LToken;
1077 L.LexFromRawLexer(LToken);
1078 Tok.Location = LToken.getLocation().getRawEncoding();
1079 switch (LToken.getKind()) {
1080 case tok::raw_identifier: {
1081 StringRef RI = LToken.getRawIdentifier();
1082 Tok.StringData = RI.data();
1083 Tok.StringLength = RI.size();
1084 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1085 .Case("config_macros", MMToken::ConfigMacros)
1086 .Case("conflict", MMToken::Conflict)
1087 .Case("exclude", MMToken::ExcludeKeyword)
1088 .Case("explicit", MMToken::ExplicitKeyword)
1089 .Case("export", MMToken::ExportKeyword)
1090 .Case("extern", MMToken::ExternKeyword)
1091 .Case("framework", MMToken::FrameworkKeyword)
1092 .Case("header", MMToken::HeaderKeyword)
1093 .Case("link", MMToken::LinkKeyword)
1094 .Case("module", MMToken::ModuleKeyword)
1095 .Case("private", MMToken::PrivateKeyword)
1096 .Case("requires", MMToken::RequiresKeyword)
1097 .Case("textual", MMToken::TextualKeyword)
1098 .Case("umbrella", MMToken::UmbrellaKeyword)
1099 .Case("use", MMToken::UseKeyword)
1100 .Default(MMToken::Identifier);
1101 break;
1104 case tok::comma:
1105 Tok.Kind = MMToken::Comma;
1106 break;
1108 case tok::eof:
1109 Tok.Kind = MMToken::EndOfFile;
1110 break;
1112 case tok::l_brace:
1113 Tok.Kind = MMToken::LBrace;
1114 break;
1116 case tok::l_square:
1117 Tok.Kind = MMToken::LSquare;
1118 break;
1120 case tok::period:
1121 Tok.Kind = MMToken::Period;
1122 break;
1124 case tok::r_brace:
1125 Tok.Kind = MMToken::RBrace;
1126 break;
1128 case tok::r_square:
1129 Tok.Kind = MMToken::RSquare;
1130 break;
1132 case tok::star:
1133 Tok.Kind = MMToken::Star;
1134 break;
1136 case tok::exclaim:
1137 Tok.Kind = MMToken::Exclaim;
1138 break;
1140 case tok::string_literal: {
1141 if (LToken.hasUDSuffix()) {
1142 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1143 HadError = true;
1144 goto retry;
1147 // Parse the string literal.
1148 LangOptions LangOpts;
1149 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1150 if (StringLiteral.hadError)
1151 goto retry;
1153 // Copy the string literal into our string data allocator.
1154 unsigned Length = StringLiteral.GetStringLength();
1155 char *Saved = StringData.Allocate<char>(Length + 1);
1156 memcpy(Saved, StringLiteral.GetString().data(), Length);
1157 Saved[Length] = 0;
1159 // Form the token.
1160 Tok.Kind = MMToken::StringLiteral;
1161 Tok.StringData = Saved;
1162 Tok.StringLength = Length;
1163 break;
1166 case tok::comment:
1167 goto retry;
1169 default:
1170 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1171 HadError = true;
1172 goto retry;
1175 return Result;
1178 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1179 unsigned braceDepth = 0;
1180 unsigned squareDepth = 0;
1181 do {
1182 switch (Tok.Kind) {
1183 case MMToken::EndOfFile:
1184 return;
1186 case MMToken::LBrace:
1187 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1188 return;
1190 ++braceDepth;
1191 break;
1193 case MMToken::LSquare:
1194 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1195 return;
1197 ++squareDepth;
1198 break;
1200 case MMToken::RBrace:
1201 if (braceDepth > 0)
1202 --braceDepth;
1203 else if (Tok.is(K))
1204 return;
1205 break;
1207 case MMToken::RSquare:
1208 if (squareDepth > 0)
1209 --squareDepth;
1210 else if (Tok.is(K))
1211 return;
1212 break;
1214 default:
1215 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1216 return;
1217 break;
1220 consumeToken();
1221 } while (true);
1224 /// \brief Parse a module-id.
1226 /// module-id:
1227 /// identifier
1228 /// identifier '.' module-id
1230 /// \returns true if an error occurred, false otherwise.
1231 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1232 Id.clear();
1233 do {
1234 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1235 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1236 consumeToken();
1237 } else {
1238 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1239 return true;
1242 if (!Tok.is(MMToken::Period))
1243 break;
1245 consumeToken();
1246 } while (true);
1248 return false;
1251 namespace {
1252 /// \brief Enumerates the known attributes.
1253 enum AttributeKind {
1254 /// \brief An unknown attribute.
1255 AT_unknown,
1256 /// \brief The 'system' attribute.
1257 AT_system,
1258 /// \brief The 'extern_c' attribute.
1259 AT_extern_c,
1260 /// \brief The 'exhaustive' attribute.
1261 AT_exhaustive
1265 /// \brief Parse a module declaration.
1267 /// module-declaration:
1268 /// 'extern' 'module' module-id string-literal
1269 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1270 /// { module-member* }
1272 /// module-member:
1273 /// requires-declaration
1274 /// header-declaration
1275 /// submodule-declaration
1276 /// export-declaration
1277 /// link-declaration
1279 /// submodule-declaration:
1280 /// module-declaration
1281 /// inferred-submodule-declaration
1282 void ModuleMapParser::parseModuleDecl() {
1283 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1284 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1285 if (Tok.is(MMToken::ExternKeyword)) {
1286 parseExternModuleDecl();
1287 return;
1290 // Parse 'explicit' or 'framework' keyword, if present.
1291 SourceLocation ExplicitLoc;
1292 bool Explicit = false;
1293 bool Framework = false;
1295 // Parse 'explicit' keyword, if present.
1296 if (Tok.is(MMToken::ExplicitKeyword)) {
1297 ExplicitLoc = consumeToken();
1298 Explicit = true;
1301 // Parse 'framework' keyword, if present.
1302 if (Tok.is(MMToken::FrameworkKeyword)) {
1303 consumeToken();
1304 Framework = true;
1307 // Parse 'module' keyword.
1308 if (!Tok.is(MMToken::ModuleKeyword)) {
1309 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1310 consumeToken();
1311 HadError = true;
1312 return;
1314 consumeToken(); // 'module' keyword
1316 // If we have a wildcard for the module name, this is an inferred submodule.
1317 // Parse it.
1318 if (Tok.is(MMToken::Star))
1319 return parseInferredModuleDecl(Framework, Explicit);
1321 // Parse the module name.
1322 ModuleId Id;
1323 if (parseModuleId(Id)) {
1324 HadError = true;
1325 return;
1328 if (ActiveModule) {
1329 if (Id.size() > 1) {
1330 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1331 << SourceRange(Id.front().second, Id.back().second);
1333 HadError = true;
1334 return;
1336 } else if (Id.size() == 1 && Explicit) {
1337 // Top-level modules can't be explicit.
1338 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1339 Explicit = false;
1340 ExplicitLoc = SourceLocation();
1341 HadError = true;
1344 Module *PreviousActiveModule = ActiveModule;
1345 if (Id.size() > 1) {
1346 // This module map defines a submodule. Go find the module of which it
1347 // is a submodule.
1348 ActiveModule = nullptr;
1349 const Module *TopLevelModule = nullptr;
1350 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1351 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1352 if (I == 0)
1353 TopLevelModule = Next;
1354 ActiveModule = Next;
1355 continue;
1358 if (ActiveModule) {
1359 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1360 << Id[I].first
1361 << ActiveModule->getTopLevelModule()->getFullModuleName();
1362 } else {
1363 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1365 HadError = true;
1366 return;
1369 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1370 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1371 "submodule defined in same file as 'module *' that allowed its "
1372 "top-level module");
1373 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1377 StringRef ModuleName = Id.back().first;
1378 SourceLocation ModuleNameLoc = Id.back().second;
1380 // Parse the optional attribute list.
1381 Attributes Attrs;
1382 parseOptionalAttributes(Attrs);
1384 // Parse the opening brace.
1385 if (!Tok.is(MMToken::LBrace)) {
1386 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1387 << ModuleName;
1388 HadError = true;
1389 return;
1391 SourceLocation LBraceLoc = consumeToken();
1393 // Determine whether this (sub)module has already been defined.
1394 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1395 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1396 // Skip the module definition.
1397 skipUntil(MMToken::RBrace);
1398 if (Tok.is(MMToken::RBrace))
1399 consumeToken();
1400 else {
1401 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1402 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1403 HadError = true;
1405 return;
1408 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1409 << ModuleName;
1410 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1412 // Skip the module definition.
1413 skipUntil(MMToken::RBrace);
1414 if (Tok.is(MMToken::RBrace))
1415 consumeToken();
1417 HadError = true;
1418 return;
1421 // Start defining this module.
1422 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1423 Explicit).first;
1424 ActiveModule->DefinitionLoc = ModuleNameLoc;
1425 if (Attrs.IsSystem || IsSystem)
1426 ActiveModule->IsSystem = true;
1427 if (Attrs.IsExternC)
1428 ActiveModule->IsExternC = true;
1429 ActiveModule->Directory = Directory;
1431 bool Done = false;
1432 do {
1433 switch (Tok.Kind) {
1434 case MMToken::EndOfFile:
1435 case MMToken::RBrace:
1436 Done = true;
1437 break;
1439 case MMToken::ConfigMacros:
1440 parseConfigMacros();
1441 break;
1443 case MMToken::Conflict:
1444 parseConflict();
1445 break;
1447 case MMToken::ExplicitKeyword:
1448 case MMToken::ExternKeyword:
1449 case MMToken::FrameworkKeyword:
1450 case MMToken::ModuleKeyword:
1451 parseModuleDecl();
1452 break;
1454 case MMToken::ExportKeyword:
1455 parseExportDecl();
1456 break;
1458 case MMToken::UseKeyword:
1459 parseUseDecl();
1460 break;
1462 case MMToken::RequiresKeyword:
1463 parseRequiresDecl();
1464 break;
1466 case MMToken::TextualKeyword:
1467 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
1468 break;
1470 case MMToken::UmbrellaKeyword: {
1471 SourceLocation UmbrellaLoc = consumeToken();
1472 if (Tok.is(MMToken::HeaderKeyword))
1473 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1474 else
1475 parseUmbrellaDirDecl(UmbrellaLoc);
1476 break;
1479 case MMToken::ExcludeKeyword:
1480 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
1481 break;
1483 case MMToken::PrivateKeyword:
1484 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
1485 break;
1487 case MMToken::HeaderKeyword:
1488 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
1489 break;
1491 case MMToken::LinkKeyword:
1492 parseLinkDecl();
1493 break;
1495 default:
1496 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1497 consumeToken();
1498 break;
1500 } while (!Done);
1502 if (Tok.is(MMToken::RBrace))
1503 consumeToken();
1504 else {
1505 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1506 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1507 HadError = true;
1510 // If the active module is a top-level framework, and there are no link
1511 // libraries, automatically link against the framework.
1512 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1513 ActiveModule->LinkLibraries.empty()) {
1514 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1517 // If the module meets all requirements but is still unavailable, mark the
1518 // whole tree as unavailable to prevent it from building.
1519 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1520 ActiveModule->Parent) {
1521 ActiveModule->getTopLevelModule()->markUnavailable();
1522 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1523 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1526 // We're done parsing this module. Pop back to the previous module.
1527 ActiveModule = PreviousActiveModule;
1530 /// \brief Parse an extern module declaration.
1532 /// extern module-declaration:
1533 /// 'extern' 'module' module-id string-literal
1534 void ModuleMapParser::parseExternModuleDecl() {
1535 assert(Tok.is(MMToken::ExternKeyword));
1536 consumeToken(); // 'extern' keyword
1538 // Parse 'module' keyword.
1539 if (!Tok.is(MMToken::ModuleKeyword)) {
1540 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1541 consumeToken();
1542 HadError = true;
1543 return;
1545 consumeToken(); // 'module' keyword
1547 // Parse the module name.
1548 ModuleId Id;
1549 if (parseModuleId(Id)) {
1550 HadError = true;
1551 return;
1554 // Parse the referenced module map file name.
1555 if (!Tok.is(MMToken::StringLiteral)) {
1556 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1557 HadError = true;
1558 return;
1560 std::string FileName = Tok.getString();
1561 consumeToken(); // filename
1563 StringRef FileNameRef = FileName;
1564 SmallString<128> ModuleMapFileName;
1565 if (llvm::sys::path::is_relative(FileNameRef)) {
1566 ModuleMapFileName += Directory->getName();
1567 llvm::sys::path::append(ModuleMapFileName, FileName);
1568 FileNameRef = ModuleMapFileName.str();
1570 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1571 Map.parseModuleMapFile(
1572 File, /*IsSystem=*/false,
1573 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1574 ? Directory
1575 : File->getDir());
1578 /// \brief Parse a requires declaration.
1580 /// requires-declaration:
1581 /// 'requires' feature-list
1583 /// feature-list:
1584 /// feature ',' feature-list
1585 /// feature
1587 /// feature:
1588 /// '!'[opt] identifier
1589 void ModuleMapParser::parseRequiresDecl() {
1590 assert(Tok.is(MMToken::RequiresKeyword));
1592 // Parse 'requires' keyword.
1593 consumeToken();
1595 // Parse the feature-list.
1596 do {
1597 bool RequiredState = true;
1598 if (Tok.is(MMToken::Exclaim)) {
1599 RequiredState = false;
1600 consumeToken();
1603 if (!Tok.is(MMToken::Identifier)) {
1604 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1605 HadError = true;
1606 return;
1609 // Consume the feature name.
1610 std::string Feature = Tok.getString();
1611 consumeToken();
1613 // Add this feature.
1614 ActiveModule->addRequirement(Feature, RequiredState,
1615 Map.LangOpts, *Map.Target);
1617 if (!Tok.is(MMToken::Comma))
1618 break;
1620 // Consume the comma.
1621 consumeToken();
1622 } while (true);
1625 /// \brief Append to \p Paths the set of paths needed to get to the
1626 /// subframework in which the given module lives.
1627 static void appendSubframeworkPaths(Module *Mod,
1628 SmallVectorImpl<char> &Path) {
1629 // Collect the framework names from the given module to the top-level module.
1630 SmallVector<StringRef, 2> Paths;
1631 for (; Mod; Mod = Mod->Parent) {
1632 if (Mod->IsFramework)
1633 Paths.push_back(Mod->Name);
1636 if (Paths.empty())
1637 return;
1639 // Add Frameworks/Name.framework for each subframework.
1640 for (unsigned I = Paths.size() - 1; I != 0; --I)
1641 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1644 /// \brief Parse a header declaration.
1646 /// header-declaration:
1647 /// 'textual'[opt] 'header' string-literal
1648 /// 'private' 'textual'[opt] 'header' string-literal
1649 /// 'exclude' 'header' string-literal
1650 /// 'umbrella' 'header' string-literal
1652 /// FIXME: Support 'private textual header'.
1653 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1654 SourceLocation LeadingLoc) {
1655 // We've already consumed the first token.
1656 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1657 if (LeadingToken == MMToken::PrivateKeyword) {
1658 Role = ModuleMap::PrivateHeader;
1659 // 'private' may optionally be followed by 'textual'.
1660 if (Tok.is(MMToken::TextualKeyword)) {
1661 LeadingToken = Tok.Kind;
1662 consumeToken();
1665 if (LeadingToken == MMToken::TextualKeyword)
1666 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1668 if (LeadingToken != MMToken::HeaderKeyword) {
1669 if (!Tok.is(MMToken::HeaderKeyword)) {
1670 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1671 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1672 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1673 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1674 return;
1676 consumeToken();
1679 // Parse the header name.
1680 if (!Tok.is(MMToken::StringLiteral)) {
1681 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1682 << "header";
1683 HadError = true;
1684 return;
1686 Module::UnresolvedHeaderDirective Header;
1687 Header.FileName = Tok.getString();
1688 Header.FileNameLoc = consumeToken();
1690 // Check whether we already have an umbrella.
1691 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1692 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1693 << ActiveModule->getFullModuleName();
1694 HadError = true;
1695 return;
1698 // Look for this file.
1699 const FileEntry *File = nullptr;
1700 const FileEntry *BuiltinFile = nullptr;
1701 SmallString<128> RelativePathName;
1702 if (llvm::sys::path::is_absolute(Header.FileName)) {
1703 RelativePathName = Header.FileName;
1704 File = SourceMgr.getFileManager().getFile(RelativePathName);
1705 } else {
1706 // Search for the header file within the search directory.
1707 SmallString<128> FullPathName(Directory->getName());
1708 unsigned FullPathLength = FullPathName.size();
1710 if (ActiveModule->isPartOfFramework()) {
1711 appendSubframeworkPaths(ActiveModule, RelativePathName);
1713 // Check whether this file is in the public headers.
1714 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1715 llvm::sys::path::append(FullPathName, RelativePathName.str());
1716 File = SourceMgr.getFileManager().getFile(FullPathName);
1718 if (!File) {
1719 // Check whether this file is in the private headers.
1720 // FIXME: Should we retain the subframework paths here?
1721 RelativePathName.clear();
1722 FullPathName.resize(FullPathLength);
1723 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1724 Header.FileName);
1725 llvm::sys::path::append(FullPathName, RelativePathName.str());
1726 File = SourceMgr.getFileManager().getFile(FullPathName);
1728 } else {
1729 // Lookup for normal headers.
1730 llvm::sys::path::append(RelativePathName, Header.FileName);
1731 llvm::sys::path::append(FullPathName, RelativePathName.str());
1732 File = SourceMgr.getFileManager().getFile(FullPathName);
1734 // If this is a system module with a top-level header, this header
1735 // may have a counterpart (or replacement) in the set of headers
1736 // supplied by Clang. Find that builtin header.
1737 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1738 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1739 isBuiltinHeader(Header.FileName)) {
1740 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1741 llvm::sys::path::append(BuiltinPathName, Header.FileName);
1742 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1744 // If Clang supplies this header but the underlying system does not,
1745 // just silently swap in our builtin version. Otherwise, we'll end
1746 // up adding both (later).
1747 if (!File && BuiltinFile) {
1748 File = BuiltinFile;
1749 RelativePathName = BuiltinPathName;
1750 BuiltinFile = nullptr;
1756 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1757 // Come up with a lazy way to do this.
1758 if (File) {
1759 if (LeadingToken == MMToken::UmbrellaKeyword) {
1760 const DirectoryEntry *UmbrellaDir = File->getDir();
1761 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1762 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1763 << UmbrellaModule->getFullModuleName();
1764 HadError = true;
1765 } else {
1766 // Record this umbrella header.
1767 Map.setUmbrellaHeader(ActiveModule, File);
1769 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1770 Module::Header H = {RelativePathName.str(), File};
1771 Map.excludeHeader(ActiveModule, H);
1772 } else {
1773 // If there is a builtin counterpart to this file, add it now, before
1774 // the "real" header, so we build the built-in one first when building
1775 // the module.
1776 if (BuiltinFile) {
1777 // FIXME: Taking the name from the FileEntry is unstable and can give
1778 // different results depending on how we've previously named that file
1779 // in this build.
1780 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1781 Map.addHeader(ActiveModule, H, Role);
1784 // Record this header.
1785 Module::Header H = { RelativePathName.str(), File };
1786 Map.addHeader(ActiveModule, H, Role);
1788 } else if (LeadingToken != MMToken::ExcludeKeyword) {
1789 // Ignore excluded header files. They're optional anyway.
1791 // If we find a module that has a missing header, we mark this module as
1792 // unavailable and store the header directive for displaying diagnostics.
1793 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1794 ActiveModule->markUnavailable();
1795 ActiveModule->MissingHeaders.push_back(Header);
1799 /// \brief Parse an umbrella directory declaration.
1801 /// umbrella-dir-declaration:
1802 /// umbrella string-literal
1803 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1804 // Parse the directory name.
1805 if (!Tok.is(MMToken::StringLiteral)) {
1806 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1807 << "umbrella";
1808 HadError = true;
1809 return;
1812 std::string DirName = Tok.getString();
1813 SourceLocation DirNameLoc = consumeToken();
1815 // Check whether we already have an umbrella.
1816 if (ActiveModule->Umbrella) {
1817 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1818 << ActiveModule->getFullModuleName();
1819 HadError = true;
1820 return;
1823 // Look for this file.
1824 const DirectoryEntry *Dir = nullptr;
1825 if (llvm::sys::path::is_absolute(DirName))
1826 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1827 else {
1828 SmallString<128> PathName;
1829 PathName = Directory->getName();
1830 llvm::sys::path::append(PathName, DirName);
1831 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1834 if (!Dir) {
1835 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1836 << DirName;
1837 HadError = true;
1838 return;
1841 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1842 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1843 << OwningModule->getFullModuleName();
1844 HadError = true;
1845 return;
1848 // Record this umbrella directory.
1849 Map.setUmbrellaDir(ActiveModule, Dir);
1852 /// \brief Parse a module export declaration.
1854 /// export-declaration:
1855 /// 'export' wildcard-module-id
1857 /// wildcard-module-id:
1858 /// identifier
1859 /// '*'
1860 /// identifier '.' wildcard-module-id
1861 void ModuleMapParser::parseExportDecl() {
1862 assert(Tok.is(MMToken::ExportKeyword));
1863 SourceLocation ExportLoc = consumeToken();
1865 // Parse the module-id with an optional wildcard at the end.
1866 ModuleId ParsedModuleId;
1867 bool Wildcard = false;
1868 do {
1869 // FIXME: Support string-literal module names here.
1870 if (Tok.is(MMToken::Identifier)) {
1871 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1872 Tok.getLocation()));
1873 consumeToken();
1875 if (Tok.is(MMToken::Period)) {
1876 consumeToken();
1877 continue;
1880 break;
1883 if(Tok.is(MMToken::Star)) {
1884 Wildcard = true;
1885 consumeToken();
1886 break;
1889 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1890 HadError = true;
1891 return;
1892 } while (true);
1894 Module::UnresolvedExportDecl Unresolved = {
1895 ExportLoc, ParsedModuleId, Wildcard
1897 ActiveModule->UnresolvedExports.push_back(Unresolved);
1900 /// \brief Parse a module uses declaration.
1902 /// uses-declaration:
1903 /// 'uses' wildcard-module-id
1904 void ModuleMapParser::parseUseDecl() {
1905 assert(Tok.is(MMToken::UseKeyword));
1906 consumeToken();
1907 // Parse the module-id.
1908 ModuleId ParsedModuleId;
1909 parseModuleId(ParsedModuleId);
1911 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1914 /// \brief Parse a link declaration.
1916 /// module-declaration:
1917 /// 'link' 'framework'[opt] string-literal
1918 void ModuleMapParser::parseLinkDecl() {
1919 assert(Tok.is(MMToken::LinkKeyword));
1920 SourceLocation LinkLoc = consumeToken();
1922 // Parse the optional 'framework' keyword.
1923 bool IsFramework = false;
1924 if (Tok.is(MMToken::FrameworkKeyword)) {
1925 consumeToken();
1926 IsFramework = true;
1929 // Parse the library name
1930 if (!Tok.is(MMToken::StringLiteral)) {
1931 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1932 << IsFramework << SourceRange(LinkLoc);
1933 HadError = true;
1934 return;
1937 std::string LibraryName = Tok.getString();
1938 consumeToken();
1939 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1940 IsFramework));
1943 /// \brief Parse a configuration macro declaration.
1945 /// module-declaration:
1946 /// 'config_macros' attributes[opt] config-macro-list?
1948 /// config-macro-list:
1949 /// identifier (',' identifier)?
1950 void ModuleMapParser::parseConfigMacros() {
1951 assert(Tok.is(MMToken::ConfigMacros));
1952 SourceLocation ConfigMacrosLoc = consumeToken();
1954 // Only top-level modules can have configuration macros.
1955 if (ActiveModule->Parent) {
1956 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1959 // Parse the optional attributes.
1960 Attributes Attrs;
1961 parseOptionalAttributes(Attrs);
1962 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1963 ActiveModule->ConfigMacrosExhaustive = true;
1966 // If we don't have an identifier, we're done.
1967 // FIXME: Support macros with the same name as a keyword here.
1968 if (!Tok.is(MMToken::Identifier))
1969 return;
1971 // Consume the first identifier.
1972 if (!ActiveModule->Parent) {
1973 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1975 consumeToken();
1977 do {
1978 // If there's a comma, consume it.
1979 if (!Tok.is(MMToken::Comma))
1980 break;
1981 consumeToken();
1983 // We expect to see a macro name here.
1984 // FIXME: Support macros with the same name as a keyword here.
1985 if (!Tok.is(MMToken::Identifier)) {
1986 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1987 break;
1990 // Consume the macro name.
1991 if (!ActiveModule->Parent) {
1992 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1994 consumeToken();
1995 } while (true);
1998 /// \brief Format a module-id into a string.
1999 static std::string formatModuleId(const ModuleId &Id) {
2000 std::string result;
2002 llvm::raw_string_ostream OS(result);
2004 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2005 if (I)
2006 OS << ".";
2007 OS << Id[I].first;
2011 return result;
2014 /// \brief Parse a conflict declaration.
2016 /// module-declaration:
2017 /// 'conflict' module-id ',' string-literal
2018 void ModuleMapParser::parseConflict() {
2019 assert(Tok.is(MMToken::Conflict));
2020 SourceLocation ConflictLoc = consumeToken();
2021 Module::UnresolvedConflict Conflict;
2023 // Parse the module-id.
2024 if (parseModuleId(Conflict.Id))
2025 return;
2027 // Parse the ','.
2028 if (!Tok.is(MMToken::Comma)) {
2029 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2030 << SourceRange(ConflictLoc);
2031 return;
2033 consumeToken();
2035 // Parse the message.
2036 if (!Tok.is(MMToken::StringLiteral)) {
2037 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2038 << formatModuleId(Conflict.Id);
2039 return;
2041 Conflict.Message = Tok.getString().str();
2042 consumeToken();
2044 // Add this unresolved conflict.
2045 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2048 /// \brief Parse an inferred module declaration (wildcard modules).
2050 /// module-declaration:
2051 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2052 /// { inferred-module-member* }
2054 /// inferred-module-member:
2055 /// 'export' '*'
2056 /// 'exclude' identifier
2057 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2058 assert(Tok.is(MMToken::Star));
2059 SourceLocation StarLoc = consumeToken();
2060 bool Failed = false;
2062 // Inferred modules must be submodules.
2063 if (!ActiveModule && !Framework) {
2064 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2065 Failed = true;
2068 if (ActiveModule) {
2069 // Inferred modules must have umbrella directories.
2070 if (!Failed && ActiveModule->IsAvailable &&
2071 !ActiveModule->getUmbrellaDir()) {
2072 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2073 Failed = true;
2076 // Check for redefinition of an inferred module.
2077 if (!Failed && ActiveModule->InferSubmodules) {
2078 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2079 if (ActiveModule->InferredSubmoduleLoc.isValid())
2080 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2081 diag::note_mmap_prev_definition);
2082 Failed = true;
2085 // Check for the 'framework' keyword, which is not permitted here.
2086 if (Framework) {
2087 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2088 Framework = false;
2090 } else if (Explicit) {
2091 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2092 Explicit = false;
2095 // If there were any problems with this inferred submodule, skip its body.
2096 if (Failed) {
2097 if (Tok.is(MMToken::LBrace)) {
2098 consumeToken();
2099 skipUntil(MMToken::RBrace);
2100 if (Tok.is(MMToken::RBrace))
2101 consumeToken();
2103 HadError = true;
2104 return;
2107 // Parse optional attributes.
2108 Attributes Attrs;
2109 parseOptionalAttributes(Attrs);
2111 if (ActiveModule) {
2112 // Note that we have an inferred submodule.
2113 ActiveModule->InferSubmodules = true;
2114 ActiveModule->InferredSubmoduleLoc = StarLoc;
2115 ActiveModule->InferExplicitSubmodules = Explicit;
2116 } else {
2117 // We'll be inferring framework modules for this directory.
2118 Map.InferredDirectories[Directory].InferModules = true;
2119 Map.InferredDirectories[Directory].Attrs = Attrs;
2120 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2121 // FIXME: Handle the 'framework' keyword.
2124 // Parse the opening brace.
2125 if (!Tok.is(MMToken::LBrace)) {
2126 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2127 HadError = true;
2128 return;
2130 SourceLocation LBraceLoc = consumeToken();
2132 // Parse the body of the inferred submodule.
2133 bool Done = false;
2134 do {
2135 switch (Tok.Kind) {
2136 case MMToken::EndOfFile:
2137 case MMToken::RBrace:
2138 Done = true;
2139 break;
2141 case MMToken::ExcludeKeyword: {
2142 if (ActiveModule) {
2143 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2144 << (ActiveModule != nullptr);
2145 consumeToken();
2146 break;
2149 consumeToken();
2150 // FIXME: Support string-literal module names here.
2151 if (!Tok.is(MMToken::Identifier)) {
2152 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2153 break;
2156 Map.InferredDirectories[Directory].ExcludedModules
2157 .push_back(Tok.getString());
2158 consumeToken();
2159 break;
2162 case MMToken::ExportKeyword:
2163 if (!ActiveModule) {
2164 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2165 << (ActiveModule != nullptr);
2166 consumeToken();
2167 break;
2170 consumeToken();
2171 if (Tok.is(MMToken::Star))
2172 ActiveModule->InferExportWildcard = true;
2173 else
2174 Diags.Report(Tok.getLocation(),
2175 diag::err_mmap_expected_export_wildcard);
2176 consumeToken();
2177 break;
2179 case MMToken::ExplicitKeyword:
2180 case MMToken::ModuleKeyword:
2181 case MMToken::HeaderKeyword:
2182 case MMToken::PrivateKeyword:
2183 case MMToken::UmbrellaKeyword:
2184 default:
2185 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2186 << (ActiveModule != nullptr);
2187 consumeToken();
2188 break;
2190 } while (!Done);
2192 if (Tok.is(MMToken::RBrace))
2193 consumeToken();
2194 else {
2195 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2196 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2197 HadError = true;
2201 /// \brief Parse optional attributes.
2203 /// attributes:
2204 /// attribute attributes
2205 /// attribute
2207 /// attribute:
2208 /// [ identifier ]
2210 /// \param Attrs Will be filled in with the parsed attributes.
2212 /// \returns true if an error occurred, false otherwise.
2213 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2214 bool HadError = false;
2216 while (Tok.is(MMToken::LSquare)) {
2217 // Consume the '['.
2218 SourceLocation LSquareLoc = consumeToken();
2220 // Check whether we have an attribute name here.
2221 if (!Tok.is(MMToken::Identifier)) {
2222 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2223 skipUntil(MMToken::RSquare);
2224 if (Tok.is(MMToken::RSquare))
2225 consumeToken();
2226 HadError = true;
2229 // Decode the attribute name.
2230 AttributeKind Attribute
2231 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2232 .Case("exhaustive", AT_exhaustive)
2233 .Case("extern_c", AT_extern_c)
2234 .Case("system", AT_system)
2235 .Default(AT_unknown);
2236 switch (Attribute) {
2237 case AT_unknown:
2238 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2239 << Tok.getString();
2240 break;
2242 case AT_system:
2243 Attrs.IsSystem = true;
2244 break;
2246 case AT_extern_c:
2247 Attrs.IsExternC = true;
2248 break;
2250 case AT_exhaustive:
2251 Attrs.IsExhaustive = true;
2252 break;
2254 consumeToken();
2256 // Consume the ']'.
2257 if (!Tok.is(MMToken::RSquare)) {
2258 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2259 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2260 skipUntil(MMToken::RSquare);
2261 HadError = true;
2264 if (Tok.is(MMToken::RSquare))
2265 consumeToken();
2268 return HadError;
2271 /// \brief Parse a module map file.
2273 /// module-map-file:
2274 /// module-declaration*
2275 bool ModuleMapParser::parseModuleMapFile() {
2276 do {
2277 switch (Tok.Kind) {
2278 case MMToken::EndOfFile:
2279 return HadError;
2281 case MMToken::ExplicitKeyword:
2282 case MMToken::ExternKeyword:
2283 case MMToken::ModuleKeyword:
2284 case MMToken::FrameworkKeyword:
2285 parseModuleDecl();
2286 break;
2288 case MMToken::Comma:
2289 case MMToken::ConfigMacros:
2290 case MMToken::Conflict:
2291 case MMToken::Exclaim:
2292 case MMToken::ExcludeKeyword:
2293 case MMToken::ExportKeyword:
2294 case MMToken::HeaderKeyword:
2295 case MMToken::Identifier:
2296 case MMToken::LBrace:
2297 case MMToken::LinkKeyword:
2298 case MMToken::LSquare:
2299 case MMToken::Period:
2300 case MMToken::PrivateKeyword:
2301 case MMToken::RBrace:
2302 case MMToken::RSquare:
2303 case MMToken::RequiresKeyword:
2304 case MMToken::Star:
2305 case MMToken::StringLiteral:
2306 case MMToken::TextualKeyword:
2307 case MMToken::UmbrellaKeyword:
2308 case MMToken::UseKeyword:
2309 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2310 HadError = true;
2311 consumeToken();
2312 break;
2314 } while (true);
2317 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2318 const DirectoryEntry *Dir) {
2319 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2320 = ParsedModuleMap.find(File);
2321 if (Known != ParsedModuleMap.end())
2322 return Known->second;
2324 assert(Target && "Missing target information");
2325 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2326 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
2327 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2328 if (!Buffer)
2329 return ParsedModuleMap[File] = true;
2331 // Parse this module map file.
2332 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2333 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
2334 BuiltinIncludeDir, IsSystem);
2335 bool Result = Parser.parseModuleMapFile();
2336 ParsedModuleMap[File] = Result;
2337 return Result;