xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision fcc54a3b91c9b429e0384238fbe42f73fec757ca)
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     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
794       // Skip the module definition.
795       skipUntil(MMToken::RBrace);
796       if (Tok.is(MMToken::RBrace))
797         consumeToken();
798       else {
799         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
800         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
801         HadError = true;
802       }
803       return;
804     }
805 
806     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
807       << ModuleName;
808     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
809 
810     // Skip the module definition.
811     skipUntil(MMToken::RBrace);
812     if (Tok.is(MMToken::RBrace))
813       consumeToken();
814 
815     HadError = true;
816     return;
817   }
818 
819   // Start defining this module.
820   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
821                                         Explicit).first;
822   ActiveModule->DefinitionLoc = ModuleNameLoc;
823 
824   bool Done = false;
825   do {
826     switch (Tok.Kind) {
827     case MMToken::EndOfFile:
828     case MMToken::RBrace:
829       Done = true;
830       break;
831 
832     case MMToken::ExplicitKeyword:
833     case MMToken::FrameworkKeyword:
834     case MMToken::ModuleKeyword:
835       parseModuleDecl();
836       break;
837 
838     case MMToken::ExportKeyword:
839       parseExportDecl();
840       break;
841 
842     case MMToken::RequiresKeyword:
843       parseRequiresDecl();
844       break;
845 
846     case MMToken::UmbrellaKeyword: {
847       SourceLocation UmbrellaLoc = consumeToken();
848       if (Tok.is(MMToken::HeaderKeyword))
849         parseHeaderDecl(UmbrellaLoc);
850       else
851         parseUmbrellaDirDecl(UmbrellaLoc);
852       break;
853     }
854 
855     case MMToken::HeaderKeyword:
856       parseHeaderDecl(SourceLocation());
857       break;
858 
859     default:
860       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
861       consumeToken();
862       break;
863     }
864   } while (!Done);
865 
866   if (Tok.is(MMToken::RBrace))
867     consumeToken();
868   else {
869     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
870     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
871     HadError = true;
872   }
873 
874   // We're done parsing this module. Pop back to the previous module.
875   ActiveModule = PreviousActiveModule;
876 }
877 
878 /// \brief Parse a requires declaration.
879 ///
880 ///   requires-declaration:
881 ///     'requires' feature-list
882 ///
883 ///   feature-list:
884 ///     identifier ',' feature-list
885 ///     identifier
886 void ModuleMapParser::parseRequiresDecl() {
887   assert(Tok.is(MMToken::RequiresKeyword));
888 
889   // Parse 'requires' keyword.
890   consumeToken();
891 
892   // Parse the feature-list.
893   do {
894     if (!Tok.is(MMToken::Identifier)) {
895       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
896       HadError = true;
897       return;
898     }
899 
900     // Consume the feature name.
901     std::string Feature = Tok.getString();
902     consumeToken();
903 
904     // Add this feature.
905     ActiveModule->addRequirement(Feature, Map.LangOpts);
906 
907     if (!Tok.is(MMToken::Comma))
908       break;
909 
910     // Consume the comma.
911     consumeToken();
912   } while (true);
913 }
914 
915 /// \brief Append to \p Paths the set of paths needed to get to the
916 /// subframework in which the given module lives.
917 void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
918   // Collect the framework names from the given module to the top-level module.
919   llvm::SmallVector<StringRef, 2> Paths;
920   for (; Mod; Mod = Mod->Parent) {
921     if (Mod->IsFramework)
922       Paths.push_back(Mod->Name);
923   }
924 
925   if (Paths.empty())
926     return;
927 
928   // Add Frameworks/Name.framework for each subframework.
929   for (unsigned I = Paths.size() - 1; I != 0; --I) {
930     llvm::sys::path::append(Path, "Frameworks");
931     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
932   }
933 }
934 
935 /// \brief Parse a header declaration.
936 ///
937 ///   header-declaration:
938 ///     'umbrella'[opt] 'header' string-literal
939 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
940   assert(Tok.is(MMToken::HeaderKeyword));
941   consumeToken();
942 
943   bool Umbrella = UmbrellaLoc.isValid();
944 
945   // Parse the header name.
946   if (!Tok.is(MMToken::StringLiteral)) {
947     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
948       << "header";
949     HadError = true;
950     return;
951   }
952   std::string FileName = Tok.getString();
953   SourceLocation FileNameLoc = consumeToken();
954 
955   // Check whether we already have an umbrella.
956   if (Umbrella && ActiveModule->Umbrella) {
957     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
958       << ActiveModule->getFullModuleName();
959     HadError = true;
960     return;
961   }
962 
963   // Look for this file.
964   const FileEntry *File = 0;
965   llvm::SmallString<128> PathName;
966   if (llvm::sys::path::is_absolute(FileName)) {
967     PathName = FileName;
968     File = SourceMgr.getFileManager().getFile(PathName);
969   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
970     PathName = Dir->getName();
971     llvm::sys::path::append(PathName, FileName);
972     File = SourceMgr.getFileManager().getFile(PathName);
973   } else {
974     // Search for the header file within the search directory.
975     PathName = Directory->getName();
976     unsigned PathLength = PathName.size();
977 
978     if (ActiveModule->isPartOfFramework()) {
979       appendSubframeworkPaths(ActiveModule, PathName);
980 
981       // Check whether this file is in the public headers.
982       llvm::sys::path::append(PathName, "Headers");
983       llvm::sys::path::append(PathName, FileName);
984       File = SourceMgr.getFileManager().getFile(PathName);
985 
986       if (!File) {
987         // Check whether this file is in the private headers.
988         PathName.resize(PathLength);
989         llvm::sys::path::append(PathName, "PrivateHeaders");
990         llvm::sys::path::append(PathName, FileName);
991         File = SourceMgr.getFileManager().getFile(PathName);
992       }
993     } else {
994       // Lookup for normal headers.
995       llvm::sys::path::append(PathName, FileName);
996       File = SourceMgr.getFileManager().getFile(PathName);
997     }
998   }
999 
1000   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1001   // Come up with a lazy way to do this.
1002   if (File) {
1003     if (const Module *OwningModule = Map.Headers[File]) {
1004       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1005         << FileName << OwningModule->getFullModuleName();
1006       HadError = true;
1007     } else if (Umbrella) {
1008       const DirectoryEntry *UmbrellaDir = File->getDir();
1009       if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
1010         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1011           << OwningModule->getFullModuleName();
1012         HadError = true;
1013       } else {
1014         // Record this umbrella header.
1015         Map.setUmbrellaHeader(ActiveModule, File);
1016       }
1017     } else {
1018       // Record this header.
1019       Map.addHeader(ActiveModule, File);
1020     }
1021   } else {
1022     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1023       << Umbrella << FileName;
1024     HadError = true;
1025   }
1026 }
1027 
1028 /// \brief Parse an umbrella directory declaration.
1029 ///
1030 ///   umbrella-dir-declaration:
1031 ///     umbrella string-literal
1032 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1033   // Parse the directory name.
1034   if (!Tok.is(MMToken::StringLiteral)) {
1035     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1036       << "umbrella";
1037     HadError = true;
1038     return;
1039   }
1040 
1041   std::string DirName = Tok.getString();
1042   SourceLocation DirNameLoc = consumeToken();
1043 
1044   // Check whether we already have an umbrella.
1045   if (ActiveModule->Umbrella) {
1046     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1047       << ActiveModule->getFullModuleName();
1048     HadError = true;
1049     return;
1050   }
1051 
1052   // Look for this file.
1053   const DirectoryEntry *Dir = 0;
1054   if (llvm::sys::path::is_absolute(DirName))
1055     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1056   else {
1057     llvm::SmallString<128> PathName;
1058     PathName = Directory->getName();
1059     llvm::sys::path::append(PathName, DirName);
1060     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1061   }
1062 
1063   if (!Dir) {
1064     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1065       << DirName;
1066     HadError = true;
1067     return;
1068   }
1069 
1070   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1071     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1072       << OwningModule->getFullModuleName();
1073     HadError = true;
1074     return;
1075   }
1076 
1077   // Record this umbrella directory.
1078   Map.setUmbrellaDir(ActiveModule, Dir);
1079 }
1080 
1081 /// \brief Parse a module export declaration.
1082 ///
1083 ///   export-declaration:
1084 ///     'export' wildcard-module-id
1085 ///
1086 ///   wildcard-module-id:
1087 ///     identifier
1088 ///     '*'
1089 ///     identifier '.' wildcard-module-id
1090 void ModuleMapParser::parseExportDecl() {
1091   assert(Tok.is(MMToken::ExportKeyword));
1092   SourceLocation ExportLoc = consumeToken();
1093 
1094   // Parse the module-id with an optional wildcard at the end.
1095   ModuleId ParsedModuleId;
1096   bool Wildcard = false;
1097   do {
1098     if (Tok.is(MMToken::Identifier)) {
1099       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1100                                               Tok.getLocation()));
1101       consumeToken();
1102 
1103       if (Tok.is(MMToken::Period)) {
1104         consumeToken();
1105         continue;
1106       }
1107 
1108       break;
1109     }
1110 
1111     if(Tok.is(MMToken::Star)) {
1112       Wildcard = true;
1113       consumeToken();
1114       break;
1115     }
1116 
1117     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1118     HadError = true;
1119     return;
1120   } while (true);
1121 
1122   Module::UnresolvedExportDecl Unresolved = {
1123     ExportLoc, ParsedModuleId, Wildcard
1124   };
1125   ActiveModule->UnresolvedExports.push_back(Unresolved);
1126 }
1127 
1128 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
1129   assert(Tok.is(MMToken::Star));
1130   SourceLocation StarLoc = consumeToken();
1131   bool Failed = false;
1132 
1133   // Inferred modules must be submodules.
1134   if (!ActiveModule) {
1135     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1136     Failed = true;
1137   }
1138 
1139   // Inferred modules must have umbrella directories.
1140   if (!Failed && !ActiveModule->getUmbrellaDir()) {
1141     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1142     Failed = true;
1143   }
1144 
1145   // Check for redefinition of an inferred module.
1146   if (!Failed && ActiveModule->InferSubmodules) {
1147     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1148     if (ActiveModule->InferredSubmoduleLoc.isValid())
1149       Diags.Report(ActiveModule->InferredSubmoduleLoc,
1150                    diag::note_mmap_prev_definition);
1151     Failed = true;
1152   }
1153 
1154   // If there were any problems with this inferred submodule, skip its body.
1155   if (Failed) {
1156     if (Tok.is(MMToken::LBrace)) {
1157       consumeToken();
1158       skipUntil(MMToken::RBrace);
1159       if (Tok.is(MMToken::RBrace))
1160         consumeToken();
1161     }
1162     HadError = true;
1163     return;
1164   }
1165 
1166   // Note that we have an inferred submodule.
1167   ActiveModule->InferSubmodules = true;
1168   ActiveModule->InferredSubmoduleLoc = StarLoc;
1169   ActiveModule->InferExplicitSubmodules = Explicit;
1170 
1171   // Parse the opening brace.
1172   if (!Tok.is(MMToken::LBrace)) {
1173     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1174     HadError = true;
1175     return;
1176   }
1177   SourceLocation LBraceLoc = consumeToken();
1178 
1179   // Parse the body of the inferred submodule.
1180   bool Done = false;
1181   do {
1182     switch (Tok.Kind) {
1183     case MMToken::EndOfFile:
1184     case MMToken::RBrace:
1185       Done = true;
1186       break;
1187 
1188     case MMToken::ExportKeyword: {
1189       consumeToken();
1190       if (Tok.is(MMToken::Star))
1191         ActiveModule->InferExportWildcard = true;
1192       else
1193         Diags.Report(Tok.getLocation(),
1194                      diag::err_mmap_expected_export_wildcard);
1195       consumeToken();
1196       break;
1197     }
1198 
1199     case MMToken::ExplicitKeyword:
1200     case MMToken::ModuleKeyword:
1201     case MMToken::HeaderKeyword:
1202     case MMToken::UmbrellaKeyword:
1203     default:
1204       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
1205       consumeToken();
1206       break;
1207     }
1208   } while (!Done);
1209 
1210   if (Tok.is(MMToken::RBrace))
1211     consumeToken();
1212   else {
1213     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1214     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1215     HadError = true;
1216   }
1217 }
1218 
1219 /// \brief If there is a specific header search directory due the presence
1220 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1221 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1222   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1223     // If we have an umbrella directory, use that.
1224     if (Mod->hasUmbrellaDir())
1225       return Mod->getUmbrellaDir();
1226 
1227     // If we have a framework directory, stop looking.
1228     if (Mod->IsFramework)
1229       return 0;
1230   }
1231 
1232   return 0;
1233 }
1234 
1235 /// \brief Parse a module map file.
1236 ///
1237 ///   module-map-file:
1238 ///     module-declaration*
1239 bool ModuleMapParser::parseModuleMapFile() {
1240   do {
1241     switch (Tok.Kind) {
1242     case MMToken::EndOfFile:
1243       return HadError;
1244 
1245     case MMToken::ExplicitKeyword:
1246     case MMToken::ModuleKeyword:
1247     case MMToken::FrameworkKeyword:
1248       parseModuleDecl();
1249       break;
1250 
1251     case MMToken::Comma:
1252     case MMToken::ExportKeyword:
1253     case MMToken::HeaderKeyword:
1254     case MMToken::Identifier:
1255     case MMToken::LBrace:
1256     case MMToken::Period:
1257     case MMToken::RBrace:
1258     case MMToken::RequiresKeyword:
1259     case MMToken::Star:
1260     case MMToken::StringLiteral:
1261     case MMToken::UmbrellaKeyword:
1262       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1263       HadError = true;
1264       consumeToken();
1265       break;
1266     }
1267   } while (true);
1268 
1269   return HadError;
1270 }
1271 
1272 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1273   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1274   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1275   if (!Buffer)
1276     return true;
1277 
1278   // Parse this module map file.
1279   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1280   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1281   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
1282   bool Result = Parser.parseModuleMapFile();
1283   Diags->getClient()->EndSourceFile();
1284 
1285   return Result;
1286 }
1287