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 CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
93 MMapLangOpts.LineComment = true;
96 ModuleMap::~ModuleMap() {
97 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
100 delete I->getValue();
104 void ModuleMap::setTarget(const TargetInfo &Target) {
105 assert((!this->Target || this->Target == &Target) &&
106 "Improper target override");
107 this->Target = &Target;
110 /// \brief "Sanitize" a filename so that it can be used as an identifier.
111 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
112 SmallVectorImpl<char> &Buffer) {
116 if (!isValidIdentifier(Name)) {
117 // If we don't already have something with the form of an identifier,
118 // create a buffer with the sanitized name.
120 if (isDigit(Name[0]))
121 Buffer.push_back('_');
122 Buffer.reserve(Buffer.size() + Name.size());
123 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
124 if (isIdentifierBody(Name[I]))
125 Buffer.push_back(Name[I]);
127 Buffer.push_back('_');
130 Name = StringRef(Buffer.data(), Buffer.size());
133 while (llvm::StringSwitch<bool>(Name)
134 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
135 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
136 #include "clang/Basic/TokenKinds.def"
138 if (Name.data() != Buffer.data())
139 Buffer.append(Name.begin(), Name.end());
140 Buffer.push_back('_');
141 Name = StringRef(Buffer.data(), Buffer.size());
147 /// \brief Determine whether the given file name is the name of a builtin
148 /// header, supplied by Clang to replace, override, or augment existing system
150 static bool isBuiltinHeader(StringRef FileName) {
151 return llvm::StringSwitch<bool>(FileName)
152 .Case("float.h", true)
153 .Case("iso646.h", true)
154 .Case("limits.h", true)
155 .Case("stdalign.h", true)
156 .Case("stdarg.h", true)
157 .Case("stdbool.h", true)
158 .Case("stddef.h", true)
159 .Case("stdint.h", true)
160 .Case("tgmath.h", true)
161 .Case("unwind.h", true)
165 ModuleMap::HeadersMap::iterator
166 ModuleMap::findKnownHeader(const FileEntry *File) {
167 HeadersMap::iterator Known = Headers.find(File);
168 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
169 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
170 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
171 HeaderInfo.loadTopLevelSystemModules();
172 return Headers.find(File);
177 ModuleMap::KnownHeader
178 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
179 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
180 if (UmbrellaDirs.empty())
181 return KnownHeader();
183 const DirectoryEntry *Dir = File->getDir();
184 assert(Dir && "file in no directory");
186 // Note: as an egregious but useful hack we use the real path here, because
187 // frameworks moving from top-level frameworks to embedded frameworks tend
188 // to be symlinked from the top-level location to the embedded location,
189 // and we need to resolve lookups as if we had found the embedded location.
190 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
192 // Keep walking up the directory hierarchy, looking for a directory with
193 // an umbrella header.
195 auto KnownDir = UmbrellaDirs.find(Dir);
196 if (KnownDir != UmbrellaDirs.end())
197 return KnownHeader(KnownDir->second, NormalHeader);
199 IntermediateDirs.push_back(Dir);
201 // Retrieve our parent path.
202 DirName = llvm::sys::path::parent_path(DirName);
206 // Resolve the parent path to a directory entry.
207 Dir = SourceMgr.getFileManager().getDirectory(DirName);
209 return KnownHeader();
212 static bool violatesPrivateInclude(Module *RequestingModule,
213 const FileEntry *IncFileEnt,
214 ModuleMap::ModuleHeaderRole Role,
215 Module *RequestedModule) {
216 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
219 // Check for consistency between the module header role
220 // as obtained from the lookup and as obtained from the module.
221 // This check is not cheap, so enable it only for debugging.
222 bool IsPrivate = false;
223 SmallVectorImpl<Module::Header> *HeaderList[] = {
224 &RequestedModule->Headers[Module::HK_Private],
225 &RequestedModule->Headers[Module::HK_PrivateTextual]};
226 for (auto *Hs : HeaderList)
228 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
229 return H.Entry == IncFileEnt;
231 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
234 return IsPrivateRole &&
235 // FIXME: Should we map RequestingModule to its top-level module here
236 // too? This check is redundant with the isSubModuleOf check in
237 // diagnoseHeaderInclusion.
238 RequestedModule->getTopLevelModule() != RequestingModule;
241 static Module *getTopLevelOrNull(Module *M) {
242 return M ? M->getTopLevelModule() : nullptr;
245 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
246 SourceLocation FilenameLoc,
248 const FileEntry *File) {
249 // No errors for indirect modules. This may be a bit of a problem for modules
250 // with no source files.
251 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
254 if (RequestingModule)
255 resolveUses(RequestingModule, /*Complain=*/false);
257 bool Excluded = false;
258 Module *Private = nullptr;
259 Module *NotUsed = nullptr;
261 HeadersMap::iterator Known = findKnownHeader(File);
262 if (Known != Headers.end()) {
263 for (const KnownHeader &Header : Known->second) {
264 // If 'File' is part of 'RequestingModule' we can definitely include it.
265 if (Header.getModule() &&
266 Header.getModule()->isSubModuleOf(RequestingModule))
269 // Remember private headers for later printing of a diagnostic.
270 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
271 Header.getModule())) {
272 Private = Header.getModule();
276 // If uses need to be specified explicitly, we are only allowed to return
277 // modules that are explicitly used by the requesting module.
278 if (RequestingModule && LangOpts.ModulesDeclUse &&
279 !RequestingModule->directlyUses(Header.getModule())) {
280 NotUsed = Header.getModule();
284 // We have found a module that we can happily use.
291 // We have found a header, but it is private.
293 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
298 // We have found a module, but we don't use it.
300 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
301 << RequestingModule->getFullModuleName() << Filename;
305 if (Excluded || isHeaderInUmbrellaDirs(File))
308 // At this point, only non-modular includes remain.
310 if (LangOpts.ModulesStrictDeclUse) {
311 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
312 << RequestingModule->getFullModuleName() << Filename;
313 } else if (RequestingModule) {
314 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
315 diag::warn_non_modular_include_in_framework_module :
316 diag::warn_non_modular_include_in_module;
317 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
321 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
322 const ModuleMap::KnownHeader &Old) {
323 // Prefer a public header over a private header.
324 if ((New.getRole() & ModuleMap::PrivateHeader) !=
325 (Old.getRole() & ModuleMap::PrivateHeader))
326 return !(New.getRole() & ModuleMap::PrivateHeader);
328 // Prefer a non-textual header over a textual header.
329 if ((New.getRole() & ModuleMap::TextualHeader) !=
330 (Old.getRole() & ModuleMap::TextualHeader))
331 return !(New.getRole() & ModuleMap::TextualHeader);
333 // Don't have a reason to choose between these. Just keep the first one.
337 ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
338 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
339 if (R.getRole() & ModuleMap::TextualHeader)
340 return ModuleMap::KnownHeader();
344 HeadersMap::iterator Known = findKnownHeader(File);
345 if (Known != Headers.end()) {
346 ModuleMap::KnownHeader Result;
347 // Iterate over all modules that 'File' is part of to find the best fit.
348 for (KnownHeader &H : Known->second) {
349 // Prefer a header from the current module over all others.
350 if (H.getModule()->getTopLevelModule() == CompilingModule)
351 return MakeResult(H);
352 // Cannot use a module if it is unavailable.
353 if (!H.getModule()->isAvailable())
355 if (!Result || isBetterKnownHeader(H, Result))
358 return MakeResult(Result);
361 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
362 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
364 Module *Result = H.getModule();
366 // Search up the module stack until we find a module with an umbrella
368 Module *UmbrellaModule = Result;
369 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
370 UmbrellaModule = UmbrellaModule->Parent;
372 if (UmbrellaModule->InferSubmodules) {
373 const FileEntry *UmbrellaModuleMap =
374 getModuleMapFileForUniquing(UmbrellaModule);
376 // Infer submodules for each of the directories we found between
377 // the directory of the umbrella header and the directory where
378 // the actual header is located.
379 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
381 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
382 // Find or create the module that corresponds to this directory name.
383 SmallString<32> NameBuf;
384 StringRef Name = sanitizeFilenameAsIdentifier(
385 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
386 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
388 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
389 Result->IsInferred = true;
391 // Associate the module and the directory.
392 UmbrellaDirs[SkippedDirs[I-1]] = Result;
394 // If inferred submodules export everything they import, add a
395 // wildcard to the set of exports.
396 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
397 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
400 // Infer a submodule with the same name as this header file.
401 SmallString<32> NameBuf;
402 StringRef Name = sanitizeFilenameAsIdentifier(
403 llvm::sys::path::stem(File->getName()), NameBuf);
404 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
406 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
407 Result->IsInferred = true;
408 Result->addTopHeader(File);
410 // If inferred submodules export everything they import, add a
411 // wildcard to the set of exports.
412 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
413 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
415 // Record each of the directories we stepped through as being part of
416 // the module we found, since the umbrella header covers them all.
417 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
418 UmbrellaDirs[SkippedDirs[I]] = Result;
421 Headers[File].push_back(KnownHeader(Result, NormalHeader));
423 // If a header corresponds to an unavailable module, don't report
424 // that it maps to anything.
425 if (!Result->isAvailable())
426 return KnownHeader();
428 return MakeResult(Headers[File].back());
431 return KnownHeader();
434 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
435 return isHeaderUnavailableInModule(Header, nullptr);
439 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
440 const Module *RequestingModule) const {
441 HeadersMap::const_iterator Known = Headers.find(Header);
442 if (Known != Headers.end()) {
443 for (SmallVectorImpl<KnownHeader>::const_iterator
444 I = Known->second.begin(),
445 E = Known->second.end();
447 if (I->isAvailable() && (!RequestingModule ||
448 I->getModule()->isSubModuleOf(RequestingModule)))
454 const DirectoryEntry *Dir = Header->getDir();
455 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
456 StringRef DirName = Dir->getName();
458 auto IsUnavailable = [&](const Module *M) {
459 return !M->isAvailable() && (!RequestingModule ||
460 M->isSubModuleOf(RequestingModule));
463 // Keep walking up the directory hierarchy, looking for a directory with
464 // an umbrella header.
466 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
467 = UmbrellaDirs.find(Dir);
468 if (KnownDir != UmbrellaDirs.end()) {
469 Module *Found = KnownDir->second;
470 if (IsUnavailable(Found))
473 // Search up the module stack until we find a module with an umbrella
475 Module *UmbrellaModule = Found;
476 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
477 UmbrellaModule = UmbrellaModule->Parent;
479 if (UmbrellaModule->InferSubmodules) {
480 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
481 // Find or create the module that corresponds to this directory name.
482 SmallString<32> NameBuf;
483 StringRef Name = sanitizeFilenameAsIdentifier(
484 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
486 Found = lookupModuleQualified(Name, Found);
489 if (IsUnavailable(Found))
493 // Infer a submodule with the same name as this header file.
494 SmallString<32> NameBuf;
495 StringRef Name = sanitizeFilenameAsIdentifier(
496 llvm::sys::path::stem(Header->getName()),
498 Found = lookupModuleQualified(Name, Found);
503 return IsUnavailable(Found);
506 SkippedDirs.push_back(Dir);
508 // Retrieve our parent path.
509 DirName = llvm::sys::path::parent_path(DirName);
513 // Resolve the parent path to a directory entry.
514 Dir = SourceMgr.getFileManager().getDirectory(DirName);
520 Module *ModuleMap::findModule(StringRef Name) const {
521 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
522 if (Known != Modules.end())
523 return Known->getValue();
528 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
529 Module *Context) const {
530 for(; Context; Context = Context->Parent) {
531 if (Module *Sub = lookupModuleQualified(Name, Context))
535 return findModule(Name);
538 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
540 return findModule(Name);
542 return Context->findSubmodule(Name);
545 std::pair<Module *, bool>
546 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
548 // Try to find an existing module with this name.
549 if (Module *Sub = lookupModuleQualified(Name, Parent))
550 return std::make_pair(Sub, false);
552 // Create a new module with this name.
553 Module *Result = new Module(Name, SourceLocation(), Parent,
554 IsFramework, IsExplicit, NumCreatedModules++);
555 if (LangOpts.CurrentModule == Name) {
556 SourceModule = Result;
557 SourceModuleName = Name;
560 Modules[Name] = Result;
561 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
562 Name == LangOpts.CurrentModule) {
563 CompilingModule = Result;
566 return std::make_pair(Result, true);
569 /// \brief For a framework module, infer the framework against which we
571 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
572 FileManager &FileMgr) {
573 assert(Mod->IsFramework && "Can only infer linking for framework modules");
574 assert(!Mod->isSubFramework() &&
575 "Can only infer linking for top-level frameworks");
577 SmallString<128> LibName;
578 LibName += FrameworkDir->getName();
579 llvm::sys::path::append(LibName, Mod->Name);
580 if (FileMgr.getFile(LibName)) {
581 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
582 /*IsFramework=*/true));
586 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
587 bool IsSystem, Module *Parent) {
589 Attrs.IsSystem = IsSystem;
590 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
593 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
594 Attributes Attrs, Module *Parent) {
595 // Note: as an egregious but useful hack we use the real path here, because
596 // we might be looking at an embedded framework that symlinks out to a
597 // top-level framework, and we need to infer as if we were naming the
598 // top-level framework.
599 StringRef FrameworkDirName =
600 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
602 // In case this is a case-insensitive filesystem, use the canonical
603 // directory name as the ModuleName, since modules are case-sensitive.
604 // FIXME: we should be able to give a fix-it hint for the correct spelling.
605 SmallString<32> ModuleNameStorage;
606 StringRef ModuleName = sanitizeFilenameAsIdentifier(
607 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
609 // Check whether we've already found this module.
610 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
613 FileManager &FileMgr = SourceMgr.getFileManager();
615 // If the framework has a parent path from which we're allowed to infer
616 // a framework module, do so.
617 const FileEntry *ModuleMapFile = nullptr;
619 // Determine whether we're allowed to infer a module map.
620 bool canInfer = false;
621 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
622 // Figure out the parent path.
623 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
624 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
625 // Check whether we have already looked into the parent directory
627 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
628 inferred = InferredDirectories.find(ParentDir);
629 if (inferred == InferredDirectories.end()) {
630 // We haven't looked here before. Load a module map, if there is
632 bool IsFrameworkDir = Parent.endswith(".framework");
633 if (const FileEntry *ModMapFile =
634 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
635 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
636 inferred = InferredDirectories.find(ParentDir);
639 if (inferred == InferredDirectories.end())
640 inferred = InferredDirectories.insert(
641 std::make_pair(ParentDir, InferredDirectory())).first;
644 if (inferred->second.InferModules) {
645 // We're allowed to infer for this directory, but make sure it's okay
646 // to infer this particular module.
647 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
648 canInfer = std::find(inferred->second.ExcludedModules.begin(),
649 inferred->second.ExcludedModules.end(),
650 Name) == inferred->second.ExcludedModules.end();
652 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
653 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
654 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
655 ModuleMapFile = inferred->second.ModuleMapFile;
660 // If we're not allowed to infer a framework module, don't.
664 ModuleMapFile = getModuleMapFileForUniquing(Parent);
667 // Look for an umbrella header.
668 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
669 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
670 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
672 // FIXME: If there's no umbrella header, we could probably scan the
673 // framework to load *everything*. But, it's not clear that this is a good
678 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
679 /*IsFramework=*/true, /*IsExplicit=*/false,
680 NumCreatedModules++);
681 InferredModuleAllowedBy[Result] = ModuleMapFile;
682 Result->IsInferred = true;
683 if (LangOpts.CurrentModule == ModuleName) {
684 SourceModule = Result;
685 SourceModuleName = ModuleName;
688 Result->IsSystem |= Attrs.IsSystem;
689 Result->IsExternC |= Attrs.IsExternC;
690 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
691 Result->Directory = FrameworkDir;
694 Modules[ModuleName] = Result;
696 // umbrella header "umbrella-header-name"
698 // The "Headers/" component of the name is implied because this is
699 // a framework module.
700 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
703 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
705 // module * { export * }
706 Result->InferSubmodules = true;
707 Result->InferExportWildcard = true;
709 // Look for subframeworks.
711 SmallString<128> SubframeworksDirName
712 = StringRef(FrameworkDir->getName());
713 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
714 llvm::sys::path::native(SubframeworksDirName);
715 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(".framework"))
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;
729 // Get the parent directory name.
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
735 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
744 // FIXME: Do we want to warn about subframeworks without umbrella headers?
745 inferFrameworkModule(SubframeworkDir, Attrs, Result);
749 // If the module is a top-level framework, automatically link against the
751 if (!Result->isSubFramework()) {
752 inferFrameworkLink(Result, FrameworkDir, FileMgr);
758 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
759 Twine NameAsWritten) {
760 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
761 Mod->Umbrella = UmbrellaHeader;
762 Mod->UmbrellaAsWritten = NameAsWritten.str();
763 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
766 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
767 Twine NameAsWritten) {
768 Mod->Umbrella = UmbrellaDir;
769 Mod->UmbrellaAsWritten = NameAsWritten.str();
770 UmbrellaDirs[UmbrellaDir] = Mod;
773 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
775 default: llvm_unreachable("unknown header role");
776 case ModuleMap::NormalHeader:
777 return Module::HK_Normal;
778 case ModuleMap::PrivateHeader:
779 return Module::HK_Private;
780 case ModuleMap::TextualHeader:
781 return Module::HK_Textual;
782 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
783 return Module::HK_PrivateTextual;
787 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
788 ModuleHeaderRole Role) {
789 if (!(Role & TextualHeader)) {
790 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
791 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
792 isCompilingModuleHeader);
794 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
796 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
799 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
800 // Add this as a known header so we won't implicitly add it to any
801 // umbrella directory module.
802 // FIXME: Should we only exclude it from umbrella modules within the
804 (void) Headers[Header.Entry];
806 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
810 ModuleMap::getContainingModuleMapFile(const Module *Module) const {
811 if (Module->DefinitionLoc.isInvalid())
814 return SourceMgr.getFileEntryForID(
815 SourceMgr.getFileID(Module->DefinitionLoc));
818 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
820 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
821 return InferredModuleAllowedBy.find(M)->second;
823 return getContainingModuleMapFile(M);
826 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
827 assert(M->IsInferred && "module not inferred");
828 InferredModuleAllowedBy[M] = ModMap;
831 void ModuleMap::dump() {
832 llvm::errs() << "Modules:";
833 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
834 MEnd = Modules.end();
836 M->getValue()->print(llvm::errs(), 2);
838 llvm::errs() << "Headers:";
839 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
841 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
842 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
845 if (I != H->second.begin())
847 llvm::errs() << I->getModule()->getFullModuleName();
849 llvm::errs() << "\n";
853 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
854 auto Unresolved = std::move(Mod->UnresolvedExports);
855 Mod->UnresolvedExports.clear();
856 for (auto &UE : Unresolved) {
857 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
858 if (Export.getPointer() || Export.getInt())
859 Mod->Exports.push_back(Export);
861 Mod->UnresolvedExports.push_back(UE);
863 return !Mod->UnresolvedExports.empty();
866 bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
867 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
868 Mod->UnresolvedDirectUses.clear();
869 for (auto &UDU : Unresolved) {
870 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
872 Mod->DirectUses.push_back(DirectUse);
874 Mod->UnresolvedDirectUses.push_back(UDU);
876 return !Mod->UnresolvedDirectUses.empty();
879 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
880 auto Unresolved = std::move(Mod->UnresolvedConflicts);
881 Mod->UnresolvedConflicts.clear();
882 for (auto &UC : Unresolved) {
883 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
884 Module::Conflict Conflict;
885 Conflict.Other = OtherMod;
886 Conflict.Message = UC.Message;
887 Mod->Conflicts.push_back(Conflict);
889 Mod->UnresolvedConflicts.push_back(UC);
891 return !Mod->UnresolvedConflicts.empty();
894 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
898 // Use the expansion location to determine which module we're in.
899 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
900 if (!ExpansionLoc.isFileID())
903 const SourceManager &SrcMgr = Loc.getManager();
904 FileID ExpansionFileID = ExpansionLoc.getFileID();
906 while (const FileEntry *ExpansionFile
907 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
908 // Find the module that owns this header (if any).
909 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
912 // No module owns this header, so look up the inclusion chain to see if
913 // any included header has an associated module.
914 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
915 if (IncludeLoc.isInvalid())
918 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
924 //----------------------------------------------------------------------------//
925 // Module map file parser
926 //----------------------------------------------------------------------------//
929 /// \brief A token in a module map file.
961 unsigned StringLength;
962 const char *StringData;
968 StringData = nullptr;
971 bool is(TokenKind K) const { return Kind == K; }
973 SourceLocation getLocation() const {
974 return SourceLocation::getFromRawEncoding(Location);
977 StringRef getString() const {
978 return StringRef(StringData, StringLength);
982 class ModuleMapParser {
984 SourceManager &SourceMgr;
986 /// \brief Default target information, used only for string literal
988 const TargetInfo *Target;
990 DiagnosticsEngine &Diags;
993 /// \brief The current module map file.
994 const FileEntry *ModuleMapFile;
996 /// \brief The directory that file names in this module map file should
997 /// be resolved relative to.
998 const DirectoryEntry *Directory;
1000 /// \brief The directory containing Clang-supplied headers.
1001 const DirectoryEntry *BuiltinIncludeDir;
1003 /// \brief Whether this module map is in a system header directory.
1006 /// \brief Whether an error occurred.
1009 /// \brief Stores string data for the various string literals referenced
1011 llvm::BumpPtrAllocator StringData;
1013 /// \brief The current token.
1016 /// \brief The active module.
1017 Module *ActiveModule;
1019 /// \brief Consume the current token and return its location.
1020 SourceLocation consumeToken();
1022 /// \brief Skip tokens until we reach the a token with the given kind
1023 /// (or the end of the file).
1024 void skipUntil(MMToken::TokenKind K);
1026 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
1027 bool parseModuleId(ModuleId &Id);
1028 void parseModuleDecl();
1029 void parseExternModuleDecl();
1030 void parseRequiresDecl();
1031 void parseHeaderDecl(clang::MMToken::TokenKind,
1032 SourceLocation LeadingLoc);
1033 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1034 void parseExportDecl();
1035 void parseUseDecl();
1036 void parseLinkDecl();
1037 void parseConfigMacros();
1038 void parseConflict();
1039 void parseInferredModuleDecl(bool Framework, bool Explicit);
1041 typedef ModuleMap::Attributes Attributes;
1042 bool parseOptionalAttributes(Attributes &Attrs);
1045 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1046 const TargetInfo *Target,
1047 DiagnosticsEngine &Diags,
1049 const FileEntry *ModuleMapFile,
1050 const DirectoryEntry *Directory,
1051 const DirectoryEntry *BuiltinIncludeDir,
1053 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1054 ModuleMapFile(ModuleMapFile), Directory(Directory),
1055 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1056 HadError(false), ActiveModule(nullptr)
1062 bool parseModuleMapFile();
1066 SourceLocation ModuleMapParser::consumeToken() {
1068 SourceLocation Result = Tok.getLocation();
1072 L.LexFromRawLexer(LToken);
1073 Tok.Location = LToken.getLocation().getRawEncoding();
1074 switch (LToken.getKind()) {
1075 case tok::raw_identifier: {
1076 StringRef RI = LToken.getRawIdentifier();
1077 Tok.StringData = RI.data();
1078 Tok.StringLength = RI.size();
1079 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1080 .Case("config_macros", MMToken::ConfigMacros)
1081 .Case("conflict", MMToken::Conflict)
1082 .Case("exclude", MMToken::ExcludeKeyword)
1083 .Case("explicit", MMToken::ExplicitKeyword)
1084 .Case("export", MMToken::ExportKeyword)
1085 .Case("extern", MMToken::ExternKeyword)
1086 .Case("framework", MMToken::FrameworkKeyword)
1087 .Case("header", MMToken::HeaderKeyword)
1088 .Case("link", MMToken::LinkKeyword)
1089 .Case("module", MMToken::ModuleKeyword)
1090 .Case("private", MMToken::PrivateKeyword)
1091 .Case("requires", MMToken::RequiresKeyword)
1092 .Case("textual", MMToken::TextualKeyword)
1093 .Case("umbrella", MMToken::UmbrellaKeyword)
1094 .Case("use", MMToken::UseKeyword)
1095 .Default(MMToken::Identifier);
1100 Tok.Kind = MMToken::Comma;
1104 Tok.Kind = MMToken::EndOfFile;
1108 Tok.Kind = MMToken::LBrace;
1112 Tok.Kind = MMToken::LSquare;
1116 Tok.Kind = MMToken::Period;
1120 Tok.Kind = MMToken::RBrace;
1124 Tok.Kind = MMToken::RSquare;
1128 Tok.Kind = MMToken::Star;
1132 Tok.Kind = MMToken::Exclaim;
1135 case tok::string_literal: {
1136 if (LToken.hasUDSuffix()) {
1137 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1142 // Parse the string literal.
1143 LangOptions LangOpts;
1144 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1145 if (StringLiteral.hadError)
1148 // Copy the string literal into our string data allocator.
1149 unsigned Length = StringLiteral.GetStringLength();
1150 char *Saved = StringData.Allocate<char>(Length + 1);
1151 memcpy(Saved, StringLiteral.GetString().data(), Length);
1155 Tok.Kind = MMToken::StringLiteral;
1156 Tok.StringData = Saved;
1157 Tok.StringLength = Length;
1165 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1173 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1174 unsigned braceDepth = 0;
1175 unsigned squareDepth = 0;
1178 case MMToken::EndOfFile:
1181 case MMToken::LBrace:
1182 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1188 case MMToken::LSquare:
1189 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1195 case MMToken::RBrace:
1202 case MMToken::RSquare:
1203 if (squareDepth > 0)
1210 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1219 /// \brief Parse a module-id.
1223 /// identifier '.' module-id
1225 /// \returns true if an error occurred, false otherwise.
1226 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1229 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1230 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1233 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1237 if (!Tok.is(MMToken::Period))
1247 /// \brief Enumerates the known attributes.
1248 enum AttributeKind {
1249 /// \brief An unknown attribute.
1251 /// \brief The 'system' attribute.
1253 /// \brief The 'extern_c' attribute.
1255 /// \brief The 'exhaustive' attribute.
1260 /// \brief Parse a module declaration.
1262 /// module-declaration:
1263 /// 'extern' 'module' module-id string-literal
1264 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1265 /// { module-member* }
1268 /// requires-declaration
1269 /// header-declaration
1270 /// submodule-declaration
1271 /// export-declaration
1272 /// link-declaration
1274 /// submodule-declaration:
1275 /// module-declaration
1276 /// inferred-submodule-declaration
1277 void ModuleMapParser::parseModuleDecl() {
1278 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1279 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1280 if (Tok.is(MMToken::ExternKeyword)) {
1281 parseExternModuleDecl();
1285 // Parse 'explicit' or 'framework' keyword, if present.
1286 SourceLocation ExplicitLoc;
1287 bool Explicit = false;
1288 bool Framework = false;
1290 // Parse 'explicit' keyword, if present.
1291 if (Tok.is(MMToken::ExplicitKeyword)) {
1292 ExplicitLoc = consumeToken();
1296 // Parse 'framework' keyword, if present.
1297 if (Tok.is(MMToken::FrameworkKeyword)) {
1302 // Parse 'module' keyword.
1303 if (!Tok.is(MMToken::ModuleKeyword)) {
1304 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1309 consumeToken(); // 'module' keyword
1311 // If we have a wildcard for the module name, this is an inferred submodule.
1313 if (Tok.is(MMToken::Star))
1314 return parseInferredModuleDecl(Framework, Explicit);
1316 // Parse the module name.
1318 if (parseModuleId(Id)) {
1324 if (Id.size() > 1) {
1325 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1326 << SourceRange(Id.front().second, Id.back().second);
1331 } else if (Id.size() == 1 && Explicit) {
1332 // Top-level modules can't be explicit.
1333 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1335 ExplicitLoc = SourceLocation();
1339 Module *PreviousActiveModule = ActiveModule;
1340 if (Id.size() > 1) {
1341 // This module map defines a submodule. Go find the module of which it
1343 ActiveModule = nullptr;
1344 const Module *TopLevelModule = nullptr;
1345 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1346 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1348 TopLevelModule = Next;
1349 ActiveModule = Next;
1354 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1356 << ActiveModule->getTopLevelModule()->getFullModuleName();
1358 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1364 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1365 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1366 "submodule defined in same file as 'module *' that allowed its "
1367 "top-level module");
1368 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1372 StringRef ModuleName = Id.back().first;
1373 SourceLocation ModuleNameLoc = Id.back().second;
1375 // Parse the optional attribute list.
1377 parseOptionalAttributes(Attrs);
1379 // Parse the opening brace.
1380 if (!Tok.is(MMToken::LBrace)) {
1381 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1386 SourceLocation LBraceLoc = consumeToken();
1388 // Determine whether this (sub)module has already been defined.
1389 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1390 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1391 // Skip the module definition.
1392 skipUntil(MMToken::RBrace);
1393 if (Tok.is(MMToken::RBrace))
1396 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1397 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1403 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1405 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1407 // Skip the module definition.
1408 skipUntil(MMToken::RBrace);
1409 if (Tok.is(MMToken::RBrace))
1416 // Start defining this module.
1417 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1419 ActiveModule->DefinitionLoc = ModuleNameLoc;
1420 if (Attrs.IsSystem || IsSystem)
1421 ActiveModule->IsSystem = true;
1422 if (Attrs.IsExternC)
1423 ActiveModule->IsExternC = true;
1424 ActiveModule->Directory = Directory;
1429 case MMToken::EndOfFile:
1430 case MMToken::RBrace:
1434 case MMToken::ConfigMacros:
1435 parseConfigMacros();
1438 case MMToken::Conflict:
1442 case MMToken::ExplicitKeyword:
1443 case MMToken::ExternKeyword:
1444 case MMToken::FrameworkKeyword:
1445 case MMToken::ModuleKeyword:
1449 case MMToken::ExportKeyword:
1453 case MMToken::UseKeyword:
1457 case MMToken::RequiresKeyword:
1458 parseRequiresDecl();
1461 case MMToken::TextualKeyword:
1462 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
1465 case MMToken::UmbrellaKeyword: {
1466 SourceLocation UmbrellaLoc = consumeToken();
1467 if (Tok.is(MMToken::HeaderKeyword))
1468 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1470 parseUmbrellaDirDecl(UmbrellaLoc);
1474 case MMToken::ExcludeKeyword:
1475 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
1478 case MMToken::PrivateKeyword:
1479 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
1482 case MMToken::HeaderKeyword:
1483 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
1486 case MMToken::LinkKeyword:
1491 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1497 if (Tok.is(MMToken::RBrace))
1500 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1501 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1505 // If the active module is a top-level framework, and there are no link
1506 // libraries, automatically link against the framework.
1507 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1508 ActiveModule->LinkLibraries.empty()) {
1509 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1512 // If the module meets all requirements but is still unavailable, mark the
1513 // whole tree as unavailable to prevent it from building.
1514 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1515 ActiveModule->Parent) {
1516 ActiveModule->getTopLevelModule()->markUnavailable();
1517 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1518 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1521 // We're done parsing this module. Pop back to the previous module.
1522 ActiveModule = PreviousActiveModule;
1525 /// \brief Parse an extern module declaration.
1527 /// extern module-declaration:
1528 /// 'extern' 'module' module-id string-literal
1529 void ModuleMapParser::parseExternModuleDecl() {
1530 assert(Tok.is(MMToken::ExternKeyword));
1531 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
1533 // Parse 'module' keyword.
1534 if (!Tok.is(MMToken::ModuleKeyword)) {
1535 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1540 consumeToken(); // 'module' keyword
1542 // Parse the module name.
1544 if (parseModuleId(Id)) {
1549 // Parse the referenced module map file name.
1550 if (!Tok.is(MMToken::StringLiteral)) {
1551 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1555 std::string FileName = Tok.getString();
1556 consumeToken(); // filename
1558 StringRef FileNameRef = FileName;
1559 SmallString<128> ModuleMapFileName;
1560 if (llvm::sys::path::is_relative(FileNameRef)) {
1561 ModuleMapFileName += Directory->getName();
1562 llvm::sys::path::append(ModuleMapFileName, FileName);
1563 FileNameRef = ModuleMapFileName;
1565 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1566 Map.parseModuleMapFile(
1567 File, /*IsSystem=*/false,
1568 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1570 : File->getDir(), ExternLoc);
1573 /// \brief Parse a requires declaration.
1575 /// requires-declaration:
1576 /// 'requires' feature-list
1579 /// feature ',' feature-list
1583 /// '!'[opt] identifier
1584 void ModuleMapParser::parseRequiresDecl() {
1585 assert(Tok.is(MMToken::RequiresKeyword));
1587 // Parse 'requires' keyword.
1590 // Parse the feature-list.
1592 bool RequiredState = true;
1593 if (Tok.is(MMToken::Exclaim)) {
1594 RequiredState = false;
1598 if (!Tok.is(MMToken::Identifier)) {
1599 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1604 // Consume the feature name.
1605 std::string Feature = Tok.getString();
1608 // Add this feature.
1609 ActiveModule->addRequirement(Feature, RequiredState,
1610 Map.LangOpts, *Map.Target);
1612 if (!Tok.is(MMToken::Comma))
1615 // Consume the comma.
1620 /// \brief Append to \p Paths the set of paths needed to get to the
1621 /// subframework in which the given module lives.
1622 static void appendSubframeworkPaths(Module *Mod,
1623 SmallVectorImpl<char> &Path) {
1624 // Collect the framework names from the given module to the top-level module.
1625 SmallVector<StringRef, 2> Paths;
1626 for (; Mod; Mod = Mod->Parent) {
1627 if (Mod->IsFramework)
1628 Paths.push_back(Mod->Name);
1634 // Add Frameworks/Name.framework for each subframework.
1635 for (unsigned I = Paths.size() - 1; I != 0; --I)
1636 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1639 /// \brief Parse a header declaration.
1641 /// header-declaration:
1642 /// 'textual'[opt] 'header' string-literal
1643 /// 'private' 'textual'[opt] 'header' string-literal
1644 /// 'exclude' 'header' string-literal
1645 /// 'umbrella' 'header' string-literal
1647 /// FIXME: Support 'private textual header'.
1648 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1649 SourceLocation LeadingLoc) {
1650 // We've already consumed the first token.
1651 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1652 if (LeadingToken == MMToken::PrivateKeyword) {
1653 Role = ModuleMap::PrivateHeader;
1654 // 'private' may optionally be followed by 'textual'.
1655 if (Tok.is(MMToken::TextualKeyword)) {
1656 LeadingToken = Tok.Kind;
1660 if (LeadingToken == MMToken::TextualKeyword)
1661 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1663 if (LeadingToken != MMToken::HeaderKeyword) {
1664 if (!Tok.is(MMToken::HeaderKeyword)) {
1665 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1666 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1667 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1668 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1674 // Parse the header name.
1675 if (!Tok.is(MMToken::StringLiteral)) {
1676 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1681 Module::UnresolvedHeaderDirective Header;
1682 Header.FileName = Tok.getString();
1683 Header.FileNameLoc = consumeToken();
1685 // Check whether we already have an umbrella.
1686 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1687 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1688 << ActiveModule->getFullModuleName();
1693 // Look for this file.
1694 const FileEntry *File = nullptr;
1695 const FileEntry *BuiltinFile = nullptr;
1696 SmallString<128> RelativePathName;
1697 if (llvm::sys::path::is_absolute(Header.FileName)) {
1698 RelativePathName = Header.FileName;
1699 File = SourceMgr.getFileManager().getFile(RelativePathName);
1701 // Search for the header file within the search directory.
1702 SmallString<128> FullPathName(Directory->getName());
1703 unsigned FullPathLength = FullPathName.size();
1705 if (ActiveModule->isPartOfFramework()) {
1706 appendSubframeworkPaths(ActiveModule, RelativePathName);
1708 // Check whether this file is in the public headers.
1709 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1710 llvm::sys::path::append(FullPathName, RelativePathName);
1711 File = SourceMgr.getFileManager().getFile(FullPathName);
1714 // Check whether this file is in the private headers.
1715 // FIXME: Should we retain the subframework paths here?
1716 RelativePathName.clear();
1717 FullPathName.resize(FullPathLength);
1718 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1720 llvm::sys::path::append(FullPathName, RelativePathName);
1721 File = SourceMgr.getFileManager().getFile(FullPathName);
1724 // Lookup for normal headers.
1725 llvm::sys::path::append(RelativePathName, Header.FileName);
1726 llvm::sys::path::append(FullPathName, RelativePathName);
1727 File = SourceMgr.getFileManager().getFile(FullPathName);
1729 // If this is a system module with a top-level header, this header
1730 // may have a counterpart (or replacement) in the set of headers
1731 // supplied by Clang. Find that builtin header.
1732 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1733 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1734 isBuiltinHeader(Header.FileName)) {
1735 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1736 llvm::sys::path::append(BuiltinPathName, Header.FileName);
1737 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1739 // If Clang supplies this header but the underlying system does not,
1740 // just silently swap in our builtin version. Otherwise, we'll end
1741 // up adding both (later).
1743 // For local visibility, entirely replace the system file with our
1744 // one and textually include the system one. We need to pass macros
1745 // from our header to the system one if we #include_next it.
1747 // FIXME: Can we do this in all cases?
1748 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
1750 RelativePathName = BuiltinPathName;
1751 BuiltinFile = nullptr;
1757 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1758 // Come up with a lazy way to do this.
1760 if (LeadingToken == MMToken::UmbrellaKeyword) {
1761 const DirectoryEntry *UmbrellaDir = File->getDir();
1762 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1763 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1764 << UmbrellaModule->getFullModuleName();
1767 // Record this umbrella header.
1768 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
1770 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1771 Module::Header H = {RelativePathName.str(), File};
1772 Map.excludeHeader(ActiveModule, H);
1774 // If there is a builtin counterpart to this file, add it now, before
1775 // the "real" header, so we build the built-in one first when building
1778 // FIXME: Taking the name from the FileEntry is unstable and can give
1779 // different results depending on how we've previously named that file
1781 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1782 Map.addHeader(ActiveModule, H, Role);
1785 // Record this header.
1786 Module::Header H = { RelativePathName.str(), File };
1787 Map.addHeader(ActiveModule, H, Role);
1789 } else if (LeadingToken != MMToken::ExcludeKeyword) {
1790 // Ignore excluded header files. They're optional anyway.
1792 // If we find a module that has a missing header, we mark this module as
1793 // unavailable and store the header directive for displaying diagnostics.
1794 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1795 ActiveModule->markUnavailable();
1796 ActiveModule->MissingHeaders.push_back(Header);
1800 /// \brief Parse an umbrella directory declaration.
1802 /// umbrella-dir-declaration:
1803 /// umbrella string-literal
1804 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1805 // Parse the directory name.
1806 if (!Tok.is(MMToken::StringLiteral)) {
1807 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1813 std::string DirName = Tok.getString();
1814 SourceLocation DirNameLoc = consumeToken();
1816 // Check whether we already have an umbrella.
1817 if (ActiveModule->Umbrella) {
1818 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1819 << ActiveModule->getFullModuleName();
1824 // Look for this file.
1825 const DirectoryEntry *Dir = nullptr;
1826 if (llvm::sys::path::is_absolute(DirName))
1827 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1829 SmallString<128> PathName;
1830 PathName = Directory->getName();
1831 llvm::sys::path::append(PathName, DirName);
1832 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1836 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1842 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1843 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1844 << OwningModule->getFullModuleName();
1849 // Record this umbrella directory.
1850 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
1853 /// \brief Parse a module export declaration.
1855 /// export-declaration:
1856 /// 'export' wildcard-module-id
1858 /// wildcard-module-id:
1861 /// identifier '.' wildcard-module-id
1862 void ModuleMapParser::parseExportDecl() {
1863 assert(Tok.is(MMToken::ExportKeyword));
1864 SourceLocation ExportLoc = consumeToken();
1866 // Parse the module-id with an optional wildcard at the end.
1867 ModuleId ParsedModuleId;
1868 bool Wildcard = false;
1870 // FIXME: Support string-literal module names here.
1871 if (Tok.is(MMToken::Identifier)) {
1872 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1873 Tok.getLocation()));
1876 if (Tok.is(MMToken::Period)) {
1884 if(Tok.is(MMToken::Star)) {
1890 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1895 Module::UnresolvedExportDecl Unresolved = {
1896 ExportLoc, ParsedModuleId, Wildcard
1898 ActiveModule->UnresolvedExports.push_back(Unresolved);
1901 /// \brief Parse a module use declaration.
1903 /// use-declaration:
1904 /// 'use' wildcard-module-id
1905 void ModuleMapParser::parseUseDecl() {
1906 assert(Tok.is(MMToken::UseKeyword));
1907 auto KWLoc = consumeToken();
1908 // Parse the module-id.
1909 ModuleId ParsedModuleId;
1910 parseModuleId(ParsedModuleId);
1912 if (ActiveModule->Parent)
1913 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
1915 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1918 /// \brief Parse a link declaration.
1920 /// module-declaration:
1921 /// 'link' 'framework'[opt] string-literal
1922 void ModuleMapParser::parseLinkDecl() {
1923 assert(Tok.is(MMToken::LinkKeyword));
1924 SourceLocation LinkLoc = consumeToken();
1926 // Parse the optional 'framework' keyword.
1927 bool IsFramework = false;
1928 if (Tok.is(MMToken::FrameworkKeyword)) {
1933 // Parse the library name
1934 if (!Tok.is(MMToken::StringLiteral)) {
1935 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1936 << IsFramework << SourceRange(LinkLoc);
1941 std::string LibraryName = Tok.getString();
1943 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1947 /// \brief Parse a configuration macro declaration.
1949 /// module-declaration:
1950 /// 'config_macros' attributes[opt] config-macro-list?
1952 /// config-macro-list:
1953 /// identifier (',' identifier)?
1954 void ModuleMapParser::parseConfigMacros() {
1955 assert(Tok.is(MMToken::ConfigMacros));
1956 SourceLocation ConfigMacrosLoc = consumeToken();
1958 // Only top-level modules can have configuration macros.
1959 if (ActiveModule->Parent) {
1960 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1963 // Parse the optional attributes.
1965 parseOptionalAttributes(Attrs);
1966 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1967 ActiveModule->ConfigMacrosExhaustive = true;
1970 // If we don't have an identifier, we're done.
1971 // FIXME: Support macros with the same name as a keyword here.
1972 if (!Tok.is(MMToken::Identifier))
1975 // Consume the first identifier.
1976 if (!ActiveModule->Parent) {
1977 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1982 // If there's a comma, consume it.
1983 if (!Tok.is(MMToken::Comma))
1987 // We expect to see a macro name here.
1988 // FIXME: Support macros with the same name as a keyword here.
1989 if (!Tok.is(MMToken::Identifier)) {
1990 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1994 // Consume the macro name.
1995 if (!ActiveModule->Parent) {
1996 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2002 /// \brief Format a module-id into a string.
2003 static std::string formatModuleId(const ModuleId &Id) {
2006 llvm::raw_string_ostream OS(result);
2008 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2018 /// \brief Parse a conflict declaration.
2020 /// module-declaration:
2021 /// 'conflict' module-id ',' string-literal
2022 void ModuleMapParser::parseConflict() {
2023 assert(Tok.is(MMToken::Conflict));
2024 SourceLocation ConflictLoc = consumeToken();
2025 Module::UnresolvedConflict Conflict;
2027 // Parse the module-id.
2028 if (parseModuleId(Conflict.Id))
2032 if (!Tok.is(MMToken::Comma)) {
2033 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2034 << SourceRange(ConflictLoc);
2039 // Parse the message.
2040 if (!Tok.is(MMToken::StringLiteral)) {
2041 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2042 << formatModuleId(Conflict.Id);
2045 Conflict.Message = Tok.getString().str();
2048 // Add this unresolved conflict.
2049 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2052 /// \brief Parse an inferred module declaration (wildcard modules).
2054 /// module-declaration:
2055 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2056 /// { inferred-module-member* }
2058 /// inferred-module-member:
2060 /// 'exclude' identifier
2061 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2062 assert(Tok.is(MMToken::Star));
2063 SourceLocation StarLoc = consumeToken();
2064 bool Failed = false;
2066 // Inferred modules must be submodules.
2067 if (!ActiveModule && !Framework) {
2068 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2073 // Inferred modules must have umbrella directories.
2074 if (!Failed && ActiveModule->IsAvailable &&
2075 !ActiveModule->getUmbrellaDir()) {
2076 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2080 // Check for redefinition of an inferred module.
2081 if (!Failed && ActiveModule->InferSubmodules) {
2082 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2083 if (ActiveModule->InferredSubmoduleLoc.isValid())
2084 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2085 diag::note_mmap_prev_definition);
2089 // Check for the 'framework' keyword, which is not permitted here.
2091 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2094 } else if (Explicit) {
2095 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2099 // If there were any problems with this inferred submodule, skip its body.
2101 if (Tok.is(MMToken::LBrace)) {
2103 skipUntil(MMToken::RBrace);
2104 if (Tok.is(MMToken::RBrace))
2111 // Parse optional attributes.
2113 parseOptionalAttributes(Attrs);
2116 // Note that we have an inferred submodule.
2117 ActiveModule->InferSubmodules = true;
2118 ActiveModule->InferredSubmoduleLoc = StarLoc;
2119 ActiveModule->InferExplicitSubmodules = Explicit;
2121 // We'll be inferring framework modules for this directory.
2122 Map.InferredDirectories[Directory].InferModules = true;
2123 Map.InferredDirectories[Directory].Attrs = Attrs;
2124 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2125 // FIXME: Handle the 'framework' keyword.
2128 // Parse the opening brace.
2129 if (!Tok.is(MMToken::LBrace)) {
2130 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2134 SourceLocation LBraceLoc = consumeToken();
2136 // Parse the body of the inferred submodule.
2140 case MMToken::EndOfFile:
2141 case MMToken::RBrace:
2145 case MMToken::ExcludeKeyword: {
2147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2148 << (ActiveModule != nullptr);
2154 // FIXME: Support string-literal module names here.
2155 if (!Tok.is(MMToken::Identifier)) {
2156 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2160 Map.InferredDirectories[Directory].ExcludedModules
2161 .push_back(Tok.getString());
2166 case MMToken::ExportKeyword:
2167 if (!ActiveModule) {
2168 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2169 << (ActiveModule != nullptr);
2175 if (Tok.is(MMToken::Star))
2176 ActiveModule->InferExportWildcard = true;
2178 Diags.Report(Tok.getLocation(),
2179 diag::err_mmap_expected_export_wildcard);
2183 case MMToken::ExplicitKeyword:
2184 case MMToken::ModuleKeyword:
2185 case MMToken::HeaderKeyword:
2186 case MMToken::PrivateKeyword:
2187 case MMToken::UmbrellaKeyword:
2189 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2190 << (ActiveModule != nullptr);
2196 if (Tok.is(MMToken::RBrace))
2199 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2200 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2205 /// \brief Parse optional attributes.
2208 /// attribute attributes
2214 /// \param Attrs Will be filled in with the parsed attributes.
2216 /// \returns true if an error occurred, false otherwise.
2217 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2218 bool HadError = false;
2220 while (Tok.is(MMToken::LSquare)) {
2222 SourceLocation LSquareLoc = consumeToken();
2224 // Check whether we have an attribute name here.
2225 if (!Tok.is(MMToken::Identifier)) {
2226 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2227 skipUntil(MMToken::RSquare);
2228 if (Tok.is(MMToken::RSquare))
2233 // Decode the attribute name.
2234 AttributeKind Attribute
2235 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2236 .Case("exhaustive", AT_exhaustive)
2237 .Case("extern_c", AT_extern_c)
2238 .Case("system", AT_system)
2239 .Default(AT_unknown);
2240 switch (Attribute) {
2242 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2247 Attrs.IsSystem = true;
2251 Attrs.IsExternC = true;
2255 Attrs.IsExhaustive = true;
2261 if (!Tok.is(MMToken::RSquare)) {
2262 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2263 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2264 skipUntil(MMToken::RSquare);
2268 if (Tok.is(MMToken::RSquare))
2275 /// \brief Parse a module map file.
2277 /// module-map-file:
2278 /// module-declaration*
2279 bool ModuleMapParser::parseModuleMapFile() {
2282 case MMToken::EndOfFile:
2285 case MMToken::ExplicitKeyword:
2286 case MMToken::ExternKeyword:
2287 case MMToken::ModuleKeyword:
2288 case MMToken::FrameworkKeyword:
2292 case MMToken::Comma:
2293 case MMToken::ConfigMacros:
2294 case MMToken::Conflict:
2295 case MMToken::Exclaim:
2296 case MMToken::ExcludeKeyword:
2297 case MMToken::ExportKeyword:
2298 case MMToken::HeaderKeyword:
2299 case MMToken::Identifier:
2300 case MMToken::LBrace:
2301 case MMToken::LinkKeyword:
2302 case MMToken::LSquare:
2303 case MMToken::Period:
2304 case MMToken::PrivateKeyword:
2305 case MMToken::RBrace:
2306 case MMToken::RSquare:
2307 case MMToken::RequiresKeyword:
2309 case MMToken::StringLiteral:
2310 case MMToken::TextualKeyword:
2311 case MMToken::UmbrellaKeyword:
2312 case MMToken::UseKeyword:
2313 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2321 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2322 const DirectoryEntry *Dir,
2323 SourceLocation ExternModuleLoc) {
2324 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2325 = ParsedModuleMap.find(File);
2326 if (Known != ParsedModuleMap.end())
2327 return Known->second;
2329 assert(Target && "Missing target information");
2330 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2331 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2332 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2334 return ParsedModuleMap[File] = true;
2336 // Parse this module map file.
2337 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2338 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
2339 BuiltinIncludeDir, IsSystem);
2340 bool Result = Parser.parseModuleMapFile();
2341 ParsedModuleMap[File] = Result;