xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision eb90e830850eca0c71886ad64ff2a7d0ff492ddb)
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.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "clang/Lex/ModuleMap.h"
15 #include "clang/Lex/Lexer.h"
16 #include "clang/Lex/LiteralSupport.h"
17 #include "clang/Lex/LexDiagnostic.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/TargetOptions.h"
22 #include "llvm/Support/Allocator.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Host.h"
25 #include "llvm/Support/PathV2.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/StringSwitch.h"
29 using namespace clang;
30 
31 Module::ExportDecl
32 ModuleMap::resolveExport(Module *Mod,
33                          const Module::UnresolvedExportDecl &Unresolved,
34                          bool Complain) {
35   // We may have just a wildcard.
36   if (Unresolved.Id.empty()) {
37     assert(Unresolved.Wildcard && "Invalid unresolved export");
38     return Module::ExportDecl(0, true);
39   }
40 
41   // Find the starting module.
42   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
43   if (!Context) {
44     if (Complain)
45       Diags->Report(Unresolved.Id[0].second,
46                     diag::err_mmap_missing_module_unqualified)
47         << Unresolved.Id[0].first << Mod->getFullModuleName();
48 
49     return Module::ExportDecl();
50   }
51 
52   // Dig into the module path.
53   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
54     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
55                                         Context);
56     if (!Sub) {
57       if (Complain)
58         Diags->Report(Unresolved.Id[I].second,
59                       diag::err_mmap_missing_module_qualified)
60           << Unresolved.Id[I].first << Context->getFullModuleName()
61           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
62 
63       return Module::ExportDecl();
64     }
65 
66     Context = Sub;
67   }
68 
69   return Module::ExportDecl(Context, Unresolved.Wildcard);
70 }
71 
72 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
73                      const LangOptions &LangOpts)
74   : LangOpts(LangOpts)
75 {
76   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
77   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
78             new DiagnosticsEngine(DiagIDs));
79   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
80   SourceMgr = new SourceManager(*Diags, FileMgr);
81 }
82 
83 ModuleMap::~ModuleMap() {
84   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
85                                         IEnd = Modules.end();
86        I != IEnd; ++I) {
87     delete I->getValue();
88   }
89 
90   delete SourceMgr;
91 }
92 
93 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
94   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
95     = Headers.find(File);
96   if (Known != Headers.end()) {
97     // If a header corresponds to an unavailable module, don't report
98     // that it maps to anything.
99     if (!Known->second->isAvailable())
100       return 0;
101 
102     return Known->second;
103   }
104 
105   const DirectoryEntry *Dir = File->getDir();
106   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
107   StringRef DirName = Dir->getName();
108 
109   // Keep walking up the directory hierarchy, looking for a directory with
110   // an umbrella header.
111   do {
112     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
113       = UmbrellaDirs.find(Dir);
114     if (KnownDir != UmbrellaDirs.end()) {
115       Module *Result = KnownDir->second;
116 
117       // Search up the module stack until we find a module with an umbrella
118       // directory.
119       Module *UmbrellaModule = Result;
120       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
121         UmbrellaModule = UmbrellaModule->Parent;
122 
123       if (UmbrellaModule->InferSubmodules) {
124         // Infer submodules for each of the directories we found between
125         // the directory of the umbrella header and the directory where
126         // the actual header is located.
127         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
128 
129         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
130           // Find or create the module that corresponds to this directory name.
131           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
132           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
133                                       Explicit).first;
134 
135           // Associate the module and the directory.
136           UmbrellaDirs[SkippedDirs[I-1]] = Result;
137 
138           // If inferred submodules export everything they import, add a
139           // wildcard to the set of exports.
140           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
141             Result->Exports.push_back(Module::ExportDecl(0, true));
142         }
143 
144         // Infer a submodule with the same name as this header file.
145         StringRef Name = llvm::sys::path::stem(File->getName());
146         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
147                                     Explicit).first;
148 
149         // If inferred submodules export everything they import, add a
150         // wildcard to the set of exports.
151         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
152           Result->Exports.push_back(Module::ExportDecl(0, true));
153       } else {
154         // Record each of the directories we stepped through as being part of
155         // the module we found, since the umbrella header covers them all.
156         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
157           UmbrellaDirs[SkippedDirs[I]] = Result;
158       }
159 
160       Headers[File] = Result;
161 
162       // If a header corresponds to an unavailable module, don't report
163       // that it maps to anything.
164       if (!Result->isAvailable())
165         return 0;
166 
167       return Result;
168     }
169 
170     SkippedDirs.push_back(Dir);
171 
172     // Retrieve our parent path.
173     DirName = llvm::sys::path::parent_path(DirName);
174     if (DirName.empty())
175       break;
176 
177     // Resolve the parent path to a directory entry.
178     Dir = SourceMgr->getFileManager().getDirectory(DirName);
179   } while (Dir);
180 
181   return 0;
182 }
183 
184 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
185   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
186     = Headers.find(Header);
187   if (Known != Headers.end())
188     return !Known->second->isAvailable();
189 
190   const DirectoryEntry *Dir = Header->getDir();
191   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
192   StringRef DirName = Dir->getName();
193 
194   // Keep walking up the directory hierarchy, looking for a directory with
195   // an umbrella header.
196   do {
197     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
198       = UmbrellaDirs.find(Dir);
199     if (KnownDir != UmbrellaDirs.end()) {
200       Module *Found = KnownDir->second;
201       if (!Found->isAvailable())
202         return true;
203 
204       // Search up the module stack until we find a module with an umbrella
205       // directory.
206       Module *UmbrellaModule = Found;
207       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
208         UmbrellaModule = UmbrellaModule->Parent;
209 
210       if (UmbrellaModule->InferSubmodules) {
211         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
212           // Find or create the module that corresponds to this directory name.
213           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
214           Found = lookupModuleQualified(Name, Found);
215           if (!Found)
216             return false;
217           if (!Found->isAvailable())
218             return true;
219         }
220 
221         // Infer a submodule with the same name as this header file.
222         StringRef Name = llvm::sys::path::stem(Header->getName());
223         Found = lookupModuleQualified(Name, Found);
224         if (!Found)
225           return false;
226       }
227 
228       return !Found->isAvailable();
229     }
230 
231     SkippedDirs.push_back(Dir);
232 
233     // Retrieve our parent path.
234     DirName = llvm::sys::path::parent_path(DirName);
235     if (DirName.empty())
236       break;
237 
238     // Resolve the parent path to a directory entry.
239     Dir = SourceMgr->getFileManager().getDirectory(DirName);
240   } while (Dir);
241 
242   return false;
243 }
244 
245 Module *ModuleMap::findModule(StringRef Name) {
246   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
247   if (Known != Modules.end())
248     return Known->getValue();
249 
250   return 0;
251 }
252 
253 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
254   for(; Context; Context = Context->Parent) {
255     if (Module *Sub = lookupModuleQualified(Name, Context))
256       return Sub;
257   }
258 
259   return findModule(Name);
260 }
261 
262 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
263   if (!Context)
264     return findModule(Name);
265 
266   return Context->findSubmodule(Name);
267 }
268 
269 std::pair<Module *, bool>
270 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
271                               bool IsExplicit) {
272   // Try to find an existing module with this name.
273   if (Module *Sub = lookupModuleQualified(Name, Parent))
274     return std::make_pair(Sub, false);
275 
276   // Create a new module with this name.
277   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
278                               IsExplicit);
279   if (!Parent)
280     Modules[Name] = Result;
281   return std::make_pair(Result, true);
282 }
283 
284 Module *
285 ModuleMap::inferFrameworkModule(StringRef ModuleName,
286                                 const DirectoryEntry *FrameworkDir,
287                                 Module *Parent) {
288   // Check whether we've already found this module.
289   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
290     return Mod;
291 
292   FileManager &FileMgr = SourceMgr->getFileManager();
293 
294   // Look for an umbrella header.
295   llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
296   llvm::sys::path::append(UmbrellaName, "Headers");
297   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
298   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
299 
300   // FIXME: If there's no umbrella header, we could probably scan the
301   // framework to load *everything*. But, it's not clear that this is a good
302   // idea.
303   if (!UmbrellaHeader)
304     return 0;
305 
306   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
307                               /*IsFramework=*/true, /*IsExplicit=*/false);
308   if (!Parent)
309     Modules[ModuleName] = Result;
310 
311   // umbrella header "umbrella-header-name"
312   Result->Umbrella = UmbrellaHeader;
313   Headers[UmbrellaHeader] = Result;
314   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
315 
316   // export *
317   Result->Exports.push_back(Module::ExportDecl(0, true));
318 
319   // module * { export * }
320   Result->InferSubmodules = true;
321   Result->InferExportWildcard = true;
322 
323   // Look for subframeworks.
324   llvm::error_code EC;
325   llvm::SmallString<128> SubframeworksDirName
326     = StringRef(FrameworkDir->getName());
327   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
328   llvm::SmallString<128> SubframeworksDirNameNative;
329   llvm::sys::path::native(SubframeworksDirName.str(),
330                           SubframeworksDirNameNative);
331   for (llvm::sys::fs::directory_iterator
332          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
333        Dir != DirEnd && !EC; Dir.increment(EC)) {
334     if (!StringRef(Dir->path()).endswith(".framework"))
335       continue;
336 
337     if (const DirectoryEntry *SubframeworkDir
338           = FileMgr.getDirectory(Dir->path())) {
339       // FIXME: Do we want to warn about subframeworks without umbrella headers?
340       inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
341                            Result);
342     }
343   }
344 
345   // Look for private headers.
346   llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName());
347   llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders");
348   if (const DirectoryEntry *Dir = FileMgr.getDirectory(PrivateHeadersDirName)) {
349     Module *Private = findOrCreateModule("Private", Result,
350                                          /*IsFramework=*/false,
351                                          /*IsExplicit=*/true).first;
352     setUmbrellaDir(Private, Dir);
353     Private->InferSubmodules = true;
354     Private->InferExplicitSubmodules = true;
355     Private->InferExportWildcard = true;
356   }
357 
358   return Result;
359 }
360 
361 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
362   Headers[UmbrellaHeader] = Mod;
363   Mod->Umbrella = UmbrellaHeader;
364   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
365 }
366 
367 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
368   Mod->Umbrella = UmbrellaDir;
369   UmbrellaDirs[UmbrellaDir] = Mod;
370 }
371 
372 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
373   Mod->Headers.push_back(Header);
374   Headers[Header] = Mod;
375 }
376 
377 const FileEntry *
378 ModuleMap::getContainingModuleMapFile(Module *Module) {
379   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
380     return 0;
381 
382   return SourceMgr->getFileEntryForID(
383            SourceMgr->getFileID(Module->DefinitionLoc));
384 }
385 
386 void ModuleMap::dump() {
387   llvm::errs() << "Modules:";
388   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
389                                         MEnd = Modules.end();
390        M != MEnd; ++M)
391     M->getValue()->print(llvm::errs(), 2);
392 
393   llvm::errs() << "Headers:";
394   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
395             H = Headers.begin(),
396          HEnd = Headers.end();
397        H != HEnd; ++H) {
398     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
399                  << H->second->getFullModuleName() << "\n";
400   }
401 }
402 
403 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
404   bool HadError = false;
405   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
406     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
407                                               Complain);
408     if (Export.getPointer() || Export.getInt())
409       Mod->Exports.push_back(Export);
410     else
411       HadError = true;
412   }
413   Mod->UnresolvedExports.clear();
414   return HadError;
415 }
416 
417 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
418   if (Loc.isInvalid())
419     return 0;
420 
421   // Use the expansion location to determine which module we're in.
422   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
423   if (!ExpansionLoc.isFileID())
424     return 0;
425 
426 
427   const SourceManager &SrcMgr = Loc.getManager();
428   FileID ExpansionFileID = ExpansionLoc.getFileID();
429   const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID);
430   if (!ExpansionFile)
431     return 0;
432 
433   // Find the module that owns this header.
434   return findModuleForHeader(ExpansionFile);
435 }
436 
437 //----------------------------------------------------------------------------//
438 // Module map file parser
439 //----------------------------------------------------------------------------//
440 
441 namespace clang {
442   /// \brief A token in a module map file.
443   struct MMToken {
444     enum TokenKind {
445       Comma,
446       EndOfFile,
447       HeaderKeyword,
448       Identifier,
449       ExplicitKeyword,
450       ExportKeyword,
451       FrameworkKeyword,
452       ModuleKeyword,
453       Period,
454       UmbrellaKeyword,
455       RequiresKeyword,
456       Star,
457       StringLiteral,
458       LBrace,
459       RBrace
460     } Kind;
461 
462     unsigned Location;
463     unsigned StringLength;
464     const char *StringData;
465 
466     void clear() {
467       Kind = EndOfFile;
468       Location = 0;
469       StringLength = 0;
470       StringData = 0;
471     }
472 
473     bool is(TokenKind K) const { return Kind == K; }
474 
475     SourceLocation getLocation() const {
476       return SourceLocation::getFromRawEncoding(Location);
477     }
478 
479     StringRef getString() const {
480       return StringRef(StringData, StringLength);
481     }
482   };
483 
484   class ModuleMapParser {
485     Lexer &L;
486     SourceManager &SourceMgr;
487     DiagnosticsEngine &Diags;
488     ModuleMap &Map;
489 
490     /// \brief The directory that this module map resides in.
491     const DirectoryEntry *Directory;
492 
493     /// \brief Whether an error occurred.
494     bool HadError;
495 
496     /// \brief Default target information, used only for string literal
497     /// parsing.
498     TargetInfo *Target;
499 
500     /// \brief Stores string data for the various string literals referenced
501     /// during parsing.
502     llvm::BumpPtrAllocator StringData;
503 
504     /// \brief The current token.
505     MMToken Tok;
506 
507     /// \brief The active module.
508     Module *ActiveModule;
509 
510     /// \brief Consume the current token and return its location.
511     SourceLocation consumeToken();
512 
513     /// \brief Skip tokens until we reach the a token with the given kind
514     /// (or the end of the file).
515     void skipUntil(MMToken::TokenKind K);
516 
517     typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
518       ModuleId;
519     bool parseModuleId(ModuleId &Id);
520     void parseModuleDecl();
521     void parseRequiresDecl();
522     void parseHeaderDecl(SourceLocation UmbrellaLoc);
523     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
524     void parseExportDecl();
525     void parseInferredSubmoduleDecl(bool Explicit);
526 
527     const DirectoryEntry *getOverriddenHeaderSearchDir();
528 
529   public:
530     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
531                              DiagnosticsEngine &Diags,
532                              ModuleMap &Map,
533                              const DirectoryEntry *Directory)
534       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
535         Directory(Directory), HadError(false), ActiveModule(0)
536     {
537       TargetOptions TargetOpts;
538       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
539       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
540 
541       Tok.clear();
542       consumeToken();
543     }
544 
545     bool parseModuleMapFile();
546   };
547 }
548 
549 SourceLocation ModuleMapParser::consumeToken() {
550 retry:
551   SourceLocation Result = Tok.getLocation();
552   Tok.clear();
553 
554   Token LToken;
555   L.LexFromRawLexer(LToken);
556   Tok.Location = LToken.getLocation().getRawEncoding();
557   switch (LToken.getKind()) {
558   case tok::raw_identifier:
559     Tok.StringData = LToken.getRawIdentifierData();
560     Tok.StringLength = LToken.getLength();
561     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
562                  .Case("header", MMToken::HeaderKeyword)
563                  .Case("explicit", MMToken::ExplicitKeyword)
564                  .Case("export", MMToken::ExportKeyword)
565                  .Case("framework", MMToken::FrameworkKeyword)
566                  .Case("module", MMToken::ModuleKeyword)
567                  .Case("requires", MMToken::RequiresKeyword)
568                  .Case("umbrella", MMToken::UmbrellaKeyword)
569                  .Default(MMToken::Identifier);
570     break;
571 
572   case tok::comma:
573     Tok.Kind = MMToken::Comma;
574     break;
575 
576   case tok::eof:
577     Tok.Kind = MMToken::EndOfFile;
578     break;
579 
580   case tok::l_brace:
581     Tok.Kind = MMToken::LBrace;
582     break;
583 
584   case tok::period:
585     Tok.Kind = MMToken::Period;
586     break;
587 
588   case tok::r_brace:
589     Tok.Kind = MMToken::RBrace;
590     break;
591 
592   case tok::star:
593     Tok.Kind = MMToken::Star;
594     break;
595 
596   case tok::string_literal: {
597     // Parse the string literal.
598     LangOptions LangOpts;
599     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
600     if (StringLiteral.hadError)
601       goto retry;
602 
603     // Copy the string literal into our string data allocator.
604     unsigned Length = StringLiteral.GetStringLength();
605     char *Saved = StringData.Allocate<char>(Length + 1);
606     memcpy(Saved, StringLiteral.GetString().data(), Length);
607     Saved[Length] = 0;
608 
609     // Form the token.
610     Tok.Kind = MMToken::StringLiteral;
611     Tok.StringData = Saved;
612     Tok.StringLength = Length;
613     break;
614   }
615 
616   case tok::comment:
617     goto retry;
618 
619   default:
620     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
621     HadError = true;
622     goto retry;
623   }
624 
625   return Result;
626 }
627 
628 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
629   unsigned braceDepth = 0;
630   do {
631     switch (Tok.Kind) {
632     case MMToken::EndOfFile:
633       return;
634 
635     case MMToken::LBrace:
636       if (Tok.is(K) && braceDepth == 0)
637         return;
638 
639       ++braceDepth;
640       break;
641 
642     case MMToken::RBrace:
643       if (braceDepth > 0)
644         --braceDepth;
645       else if (Tok.is(K))
646         return;
647       break;
648 
649     default:
650       if (braceDepth == 0 && Tok.is(K))
651         return;
652       break;
653     }
654 
655    consumeToken();
656   } while (true);
657 }
658 
659 /// \brief Parse a module-id.
660 ///
661 ///   module-id:
662 ///     identifier
663 ///     identifier '.' module-id
664 ///
665 /// \returns true if an error occurred, false otherwise.
666 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
667   Id.clear();
668   do {
669     if (Tok.is(MMToken::Identifier)) {
670       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
671       consumeToken();
672     } else {
673       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
674       return true;
675     }
676 
677     if (!Tok.is(MMToken::Period))
678       break;
679 
680     consumeToken();
681   } while (true);
682 
683   return false;
684 }
685 
686 /// \brief Parse a module declaration.
687 ///
688 ///   module-declaration:
689 ///     'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* }
690 ///
691 ///   module-member:
692 ///     requires-declaration
693 ///     header-declaration
694 ///     submodule-declaration
695 ///     export-declaration
696 ///
697 ///   submodule-declaration:
698 ///     module-declaration
699 ///     inferred-submodule-declaration
700 void ModuleMapParser::parseModuleDecl() {
701   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
702          Tok.is(MMToken::FrameworkKeyword));
703   // Parse 'explicit' or 'framework' keyword, if present.
704   SourceLocation ExplicitLoc;
705   bool Explicit = false;
706   bool Framework = false;
707 
708   // Parse 'explicit' keyword, if present.
709   if (Tok.is(MMToken::ExplicitKeyword)) {
710     ExplicitLoc = consumeToken();
711     Explicit = true;
712   }
713 
714   // Parse 'framework' keyword, if present.
715   if (Tok.is(MMToken::FrameworkKeyword)) {
716     consumeToken();
717     Framework = true;
718   }
719 
720   // Parse 'module' keyword.
721   if (!Tok.is(MMToken::ModuleKeyword)) {
722     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
723     consumeToken();
724     HadError = true;
725     return;
726   }
727   consumeToken(); // 'module' keyword
728 
729   // If we have a wildcard for the module name, this is an inferred submodule.
730   // Parse it.
731   if (Tok.is(MMToken::Star))
732     return parseInferredSubmoduleDecl(Explicit);
733 
734   // Parse the module name.
735   ModuleId Id;
736   if (parseModuleId(Id)) {
737     HadError = true;
738     return;
739   }
740 
741   if (ActiveModule) {
742     if (Id.size() > 1) {
743       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
744         << SourceRange(Id.front().second, Id.back().second);
745 
746       HadError = true;
747       return;
748     }
749   } else if (Id.size() == 1 && Explicit) {
750     // Top-level modules can't be explicit.
751     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
752     Explicit = false;
753     ExplicitLoc = SourceLocation();
754     HadError = true;
755   }
756 
757   Module *PreviousActiveModule = ActiveModule;
758   if (Id.size() > 1) {
759     // This module map defines a submodule. Go find the module of which it
760     // is a submodule.
761     ActiveModule = 0;
762     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
763       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
764         ActiveModule = Next;
765         continue;
766       }
767 
768       if (ActiveModule) {
769         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
770           << Id[I].first << ActiveModule->getTopLevelModule();
771       } else {
772         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
773       }
774       HadError = true;
775       return;
776     }
777   }
778 
779   StringRef ModuleName = Id.back().first;
780   SourceLocation ModuleNameLoc = Id.back().second;
781 
782   // Parse the opening brace.
783   if (!Tok.is(MMToken::LBrace)) {
784     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
785       << ModuleName;
786     HadError = true;
787     return;
788   }
789   SourceLocation LBraceLoc = consumeToken();
790 
791   // Determine whether this (sub)module has already been defined.
792   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
793     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
794       << ModuleName;
795     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
796 
797     // Skip the module definition.
798     skipUntil(MMToken::RBrace);
799     if (Tok.is(MMToken::RBrace))
800       consumeToken();
801 
802     HadError = true;
803     return;
804   }
805 
806   // Start defining this module.
807   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
808                                         Explicit).first;
809   ActiveModule->DefinitionLoc = ModuleNameLoc;
810 
811   bool Done = false;
812   do {
813     switch (Tok.Kind) {
814     case MMToken::EndOfFile:
815     case MMToken::RBrace:
816       Done = true;
817       break;
818 
819     case MMToken::ExplicitKeyword:
820     case MMToken::FrameworkKeyword:
821     case MMToken::ModuleKeyword:
822       parseModuleDecl();
823       break;
824 
825     case MMToken::ExportKeyword:
826       parseExportDecl();
827       break;
828 
829     case MMToken::RequiresKeyword:
830       parseRequiresDecl();
831       break;
832 
833     case MMToken::UmbrellaKeyword: {
834       SourceLocation UmbrellaLoc = consumeToken();
835       if (Tok.is(MMToken::HeaderKeyword))
836         parseHeaderDecl(UmbrellaLoc);
837       else
838         parseUmbrellaDirDecl(UmbrellaLoc);
839       break;
840     }
841 
842     case MMToken::HeaderKeyword:
843       parseHeaderDecl(SourceLocation());
844       break;
845 
846     default:
847       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
848       consumeToken();
849       break;
850     }
851   } while (!Done);
852 
853   if (Tok.is(MMToken::RBrace))
854     consumeToken();
855   else {
856     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
857     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
858     HadError = true;
859   }
860 
861   // We're done parsing this module. Pop back to the previous module.
862   ActiveModule = PreviousActiveModule;
863 }
864 
865 /// \brief Parse a requires declaration.
866 ///
867 ///   requires-declaration:
868 ///     'requires' feature-list
869 ///
870 ///   feature-list:
871 ///     identifier ',' feature-list
872 ///     identifier
873 void ModuleMapParser::parseRequiresDecl() {
874   assert(Tok.is(MMToken::RequiresKeyword));
875 
876   // Parse 'requires' keyword.
877   consumeToken();
878 
879   // Parse the feature-list.
880   do {
881     if (!Tok.is(MMToken::Identifier)) {
882       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
883       HadError = true;
884       return;
885     }
886 
887     // Consume the feature name.
888     std::string Feature = Tok.getString();
889     consumeToken();
890 
891     // Add this feature.
892     ActiveModule->addRequirement(Feature, Map.LangOpts);
893 
894     if (!Tok.is(MMToken::Comma))
895       break;
896 
897     // Consume the comma.
898     consumeToken();
899   } while (true);
900 }
901 
902 /// \brief Append to \p Paths the set of paths needed to get to the
903 /// subframework in which the given module lives.
904 void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
905   // Collect the framework names from the given module to the top-level module.
906   llvm::SmallVector<StringRef, 2> Paths;
907   for (; Mod; Mod = Mod->Parent) {
908     if (Mod->IsFramework)
909       Paths.push_back(Mod->Name);
910   }
911 
912   if (Paths.empty())
913     return;
914 
915   // Add Frameworks/Name.framework for each subframework.
916   for (unsigned I = Paths.size() - 1; I != 0; --I) {
917     llvm::sys::path::append(Path, "Frameworks");
918     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
919   }
920 }
921 
922 /// \brief Parse a header declaration.
923 ///
924 ///   header-declaration:
925 ///     'umbrella'[opt] 'header' string-literal
926 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
927   assert(Tok.is(MMToken::HeaderKeyword));
928   consumeToken();
929 
930   bool Umbrella = UmbrellaLoc.isValid();
931 
932   // Parse the header name.
933   if (!Tok.is(MMToken::StringLiteral)) {
934     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
935       << "header";
936     HadError = true;
937     return;
938   }
939   std::string FileName = Tok.getString();
940   SourceLocation FileNameLoc = consumeToken();
941 
942   // Check whether we already have an umbrella.
943   if (Umbrella && ActiveModule->Umbrella) {
944     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
945       << ActiveModule->getFullModuleName();
946     HadError = true;
947     return;
948   }
949 
950   // Look for this file.
951   const FileEntry *File = 0;
952   llvm::SmallString<128> PathName;
953   if (llvm::sys::path::is_absolute(FileName)) {
954     PathName = FileName;
955     File = SourceMgr.getFileManager().getFile(PathName);
956   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
957     PathName = Dir->getName();
958     llvm::sys::path::append(PathName, FileName);
959     File = SourceMgr.getFileManager().getFile(PathName);
960   } else {
961     // Search for the header file within the search directory.
962     PathName = Directory->getName();
963     unsigned PathLength = PathName.size();
964 
965     if (ActiveModule->isPartOfFramework()) {
966       appendSubframeworkPaths(ActiveModule, PathName);
967 
968       // Check whether this file is in the public headers.
969       llvm::sys::path::append(PathName, "Headers");
970       llvm::sys::path::append(PathName, FileName);
971       File = SourceMgr.getFileManager().getFile(PathName);
972 
973       if (!File) {
974         // Check whether this file is in the private headers.
975         PathName.resize(PathLength);
976         llvm::sys::path::append(PathName, "PrivateHeaders");
977         llvm::sys::path::append(PathName, FileName);
978         File = SourceMgr.getFileManager().getFile(PathName);
979       }
980     } else {
981       // Lookup for normal headers.
982       llvm::sys::path::append(PathName, FileName);
983       File = SourceMgr.getFileManager().getFile(PathName);
984     }
985   }
986 
987   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
988   // Come up with a lazy way to do this.
989   if (File) {
990     if (const Module *OwningModule = Map.Headers[File]) {
991       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
992         << FileName << OwningModule->getFullModuleName();
993       HadError = true;
994     } else if (Umbrella) {
995       const DirectoryEntry *UmbrellaDir = File->getDir();
996       if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
997         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
998           << OwningModule->getFullModuleName();
999         HadError = true;
1000       } else {
1001         // Record this umbrella header.
1002         Map.setUmbrellaHeader(ActiveModule, File);
1003       }
1004     } else {
1005       // Record this header.
1006       Map.addHeader(ActiveModule, File);
1007     }
1008   } else {
1009     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1010       << Umbrella << FileName;
1011     HadError = true;
1012   }
1013 }
1014 
1015 /// \brief Parse an umbrella directory declaration.
1016 ///
1017 ///   umbrella-dir-declaration:
1018 ///     umbrella string-literal
1019 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1020   // Parse the directory name.
1021   if (!Tok.is(MMToken::StringLiteral)) {
1022     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1023       << "umbrella";
1024     HadError = true;
1025     return;
1026   }
1027 
1028   std::string DirName = Tok.getString();
1029   SourceLocation DirNameLoc = consumeToken();
1030 
1031   // Check whether we already have an umbrella.
1032   if (ActiveModule->Umbrella) {
1033     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1034       << ActiveModule->getFullModuleName();
1035     HadError = true;
1036     return;
1037   }
1038 
1039   // Look for this file.
1040   const DirectoryEntry *Dir = 0;
1041   if (llvm::sys::path::is_absolute(DirName))
1042     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1043   else {
1044     llvm::SmallString<128> PathName;
1045     PathName = Directory->getName();
1046     llvm::sys::path::append(PathName, DirName);
1047     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1048   }
1049 
1050   if (!Dir) {
1051     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1052       << DirName;
1053     HadError = true;
1054     return;
1055   }
1056 
1057   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1058     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1059       << OwningModule->getFullModuleName();
1060     HadError = true;
1061     return;
1062   }
1063 
1064   // Record this umbrella directory.
1065   Map.setUmbrellaDir(ActiveModule, Dir);
1066 }
1067 
1068 /// \brief Parse a module export declaration.
1069 ///
1070 ///   export-declaration:
1071 ///     'export' wildcard-module-id
1072 ///
1073 ///   wildcard-module-id:
1074 ///     identifier
1075 ///     '*'
1076 ///     identifier '.' wildcard-module-id
1077 void ModuleMapParser::parseExportDecl() {
1078   assert(Tok.is(MMToken::ExportKeyword));
1079   SourceLocation ExportLoc = consumeToken();
1080 
1081   // Parse the module-id with an optional wildcard at the end.
1082   ModuleId ParsedModuleId;
1083   bool Wildcard = false;
1084   do {
1085     if (Tok.is(MMToken::Identifier)) {
1086       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1087                                               Tok.getLocation()));
1088       consumeToken();
1089 
1090       if (Tok.is(MMToken::Period)) {
1091         consumeToken();
1092         continue;
1093       }
1094 
1095       break;
1096     }
1097 
1098     if(Tok.is(MMToken::Star)) {
1099       Wildcard = true;
1100       consumeToken();
1101       break;
1102     }
1103 
1104     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1105     HadError = true;
1106     return;
1107   } while (true);
1108 
1109   Module::UnresolvedExportDecl Unresolved = {
1110     ExportLoc, ParsedModuleId, Wildcard
1111   };
1112   ActiveModule->UnresolvedExports.push_back(Unresolved);
1113 }
1114 
1115 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
1116   assert(Tok.is(MMToken::Star));
1117   SourceLocation StarLoc = consumeToken();
1118   bool Failed = false;
1119 
1120   // Inferred modules must be submodules.
1121   if (!ActiveModule) {
1122     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1123     Failed = true;
1124   }
1125 
1126   // Inferred modules must have umbrella directories.
1127   if (!Failed && !ActiveModule->getUmbrellaDir()) {
1128     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1129     Failed = true;
1130   }
1131 
1132   // Check for redefinition of an inferred module.
1133   if (!Failed && ActiveModule->InferSubmodules) {
1134     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1135     if (ActiveModule->InferredSubmoduleLoc.isValid())
1136       Diags.Report(ActiveModule->InferredSubmoduleLoc,
1137                    diag::note_mmap_prev_definition);
1138     Failed = true;
1139   }
1140 
1141   // If there were any problems with this inferred submodule, skip its body.
1142   if (Failed) {
1143     if (Tok.is(MMToken::LBrace)) {
1144       consumeToken();
1145       skipUntil(MMToken::RBrace);
1146       if (Tok.is(MMToken::RBrace))
1147         consumeToken();
1148     }
1149     HadError = true;
1150     return;
1151   }
1152 
1153   // Note that we have an inferred submodule.
1154   ActiveModule->InferSubmodules = true;
1155   ActiveModule->InferredSubmoduleLoc = StarLoc;
1156   ActiveModule->InferExplicitSubmodules = Explicit;
1157 
1158   // Parse the opening brace.
1159   if (!Tok.is(MMToken::LBrace)) {
1160     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1161     HadError = true;
1162     return;
1163   }
1164   SourceLocation LBraceLoc = consumeToken();
1165 
1166   // Parse the body of the inferred submodule.
1167   bool Done = false;
1168   do {
1169     switch (Tok.Kind) {
1170     case MMToken::EndOfFile:
1171     case MMToken::RBrace:
1172       Done = true;
1173       break;
1174 
1175     case MMToken::ExportKeyword: {
1176       consumeToken();
1177       if (Tok.is(MMToken::Star))
1178         ActiveModule->InferExportWildcard = true;
1179       else
1180         Diags.Report(Tok.getLocation(),
1181                      diag::err_mmap_expected_export_wildcard);
1182       consumeToken();
1183       break;
1184     }
1185 
1186     case MMToken::ExplicitKeyword:
1187     case MMToken::ModuleKeyword:
1188     case MMToken::HeaderKeyword:
1189     case MMToken::UmbrellaKeyword:
1190     default:
1191       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
1192       consumeToken();
1193       break;
1194     }
1195   } while (!Done);
1196 
1197   if (Tok.is(MMToken::RBrace))
1198     consumeToken();
1199   else {
1200     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1201     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1202     HadError = true;
1203   }
1204 }
1205 
1206 /// \brief If there is a specific header search directory due the presence
1207 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1208 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1209   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1210     // If we have an umbrella directory, use that.
1211     if (Mod->hasUmbrellaDir())
1212       return Mod->getUmbrellaDir();
1213 
1214     // If we have a framework directory, stop looking.
1215     if (Mod->IsFramework)
1216       return 0;
1217   }
1218 
1219   return 0;
1220 }
1221 
1222 /// \brief Parse a module map file.
1223 ///
1224 ///   module-map-file:
1225 ///     module-declaration*
1226 bool ModuleMapParser::parseModuleMapFile() {
1227   do {
1228     switch (Tok.Kind) {
1229     case MMToken::EndOfFile:
1230       return HadError;
1231 
1232     case MMToken::ExplicitKeyword:
1233     case MMToken::ModuleKeyword:
1234     case MMToken::FrameworkKeyword:
1235       parseModuleDecl();
1236       break;
1237 
1238     case MMToken::Comma:
1239     case MMToken::ExportKeyword:
1240     case MMToken::HeaderKeyword:
1241     case MMToken::Identifier:
1242     case MMToken::LBrace:
1243     case MMToken::Period:
1244     case MMToken::RBrace:
1245     case MMToken::RequiresKeyword:
1246     case MMToken::Star:
1247     case MMToken::StringLiteral:
1248     case MMToken::UmbrellaKeyword:
1249       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1250       HadError = true;
1251       consumeToken();
1252       break;
1253     }
1254   } while (true);
1255 
1256   return HadError;
1257 }
1258 
1259 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1260   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1261   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1262   if (!Buffer)
1263     return true;
1264 
1265   // Parse this module map file.
1266   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1267   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1268   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
1269   bool Result = Parser.parseModuleMapFile();
1270   Diags->getClient()->EndSourceFile();
1271 
1272   return Result;
1273 }
1274