xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision 734410916a6d83c70dffcecae1686a15f8a50d71)
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/Host.h"
24 #include "llvm/Support/PathV2.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/ADT/StringSwitch.h"
28 using namespace clang;
29 
30 Module::ExportDecl
31 ModuleMap::resolveExport(Module *Mod,
32                          const Module::UnresolvedExportDecl &Unresolved,
33                          bool Complain) {
34   // We may have just a wildcard.
35   if (Unresolved.Id.empty()) {
36     assert(Unresolved.Wildcard && "Invalid unresolved export");
37     return Module::ExportDecl(0, true);
38   }
39 
40   // Find the starting module.
41   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
42   if (!Context) {
43     if (Complain)
44       Diags->Report(Unresolved.Id[0].second,
45                     diag::err_mmap_missing_module_unqualified)
46         << Unresolved.Id[0].first << Mod->getFullModuleName();
47 
48     return Module::ExportDecl();
49   }
50 
51   // Dig into the module path.
52   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
53     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
54                                         Context);
55     if (!Sub) {
56       if (Complain)
57         Diags->Report(Unresolved.Id[I].second,
58                       diag::err_mmap_missing_module_qualified)
59           << Unresolved.Id[I].first << Context->getFullModuleName()
60           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
61 
62       return Module::ExportDecl();
63     }
64 
65     Context = Sub;
66   }
67 
68   return Module::ExportDecl(Context, Unresolved.Wildcard);
69 }
70 
71 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) {
72   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
73   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
74             new DiagnosticsEngine(DiagIDs));
75   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
76   SourceMgr = new SourceManager(*Diags, FileMgr);
77 }
78 
79 ModuleMap::~ModuleMap() {
80   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
81                                         IEnd = Modules.end();
82        I != IEnd; ++I) {
83     delete I->getValue();
84   }
85 
86   delete SourceMgr;
87 }
88 
89 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
90   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
91     = Headers.find(File);
92   if (Known != Headers.end())
93     return Known->second;
94 
95   const DirectoryEntry *Dir = File->getDir();
96   llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
97     = UmbrellaDirs.find(Dir);
98   if (KnownDir != UmbrellaDirs.end())
99     return KnownDir->second;
100 
101   // Walk up the directory hierarchy looking for umbrella headers.
102   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
103   StringRef DirName = Dir->getName();
104   do {
105     // Retrieve our parent path.
106     DirName = llvm::sys::path::parent_path(DirName);
107     if (DirName.empty())
108       break;
109 
110     // Resolve the parent path to a directory entry.
111     Dir = SourceMgr->getFileManager().getDirectory(DirName);
112     if (!Dir)
113       break;
114 
115     KnownDir = UmbrellaDirs.find(Dir);
116     if (KnownDir != UmbrellaDirs.end()) {
117       Module *Result = KnownDir->second;
118 
119       // Record each of the directories we stepped through as being part of
120       // the module we found, since the umbrella header covers them all.
121       for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
122         UmbrellaDirs[SkippedDirs[I]] = Result;
123 
124       return Result;
125     }
126 
127     SkippedDirs.push_back(Dir);
128   } while (true);
129 
130   return 0;
131 }
132 
133 Module *ModuleMap::findModule(StringRef Name) {
134   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
135   if (Known != Modules.end())
136     return Known->getValue();
137 
138   return 0;
139 }
140 
141 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
142   for(; Context; Context = Context->Parent) {
143     if (Module *Sub = lookupModuleQualified(Name, Context))
144       return Sub;
145   }
146 
147   return findModule(Name);
148 }
149 
150 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
151   if (!Context)
152     return findModule(Name);
153 
154   llvm::StringMap<Module *>::iterator Sub = Context->SubModules.find(Name);
155   if (Sub != Context->SubModules.end())
156     return Sub->getValue();
157 
158   return 0;
159 }
160 
161 std::pair<Module *, bool>
162 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
163                               bool IsExplicit) {
164   // Try to find an existing module with this name.
165   if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name])
166     return std::make_pair(Found, false);
167 
168   // Create a new module with this name.
169   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
170                               IsExplicit);
171   if (Parent)
172     Parent->SubModules[Name] = Result;
173   else
174     Modules[Name] = Result;
175   return std::make_pair(Result, true);
176 }
177 
178 Module *
179 ModuleMap::inferFrameworkModule(StringRef ModuleName,
180                                 const DirectoryEntry *FrameworkDir) {
181   // Check whether we've already found this module.
182   if (Module *Module = findModule(ModuleName))
183     return Module;
184 
185   // Look for an umbrella header.
186   llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
187   llvm::sys::path::append(UmbrellaName, "Headers");
188   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
189   const FileEntry *UmbrellaHeader
190     = SourceMgr->getFileManager().getFile(UmbrellaName);
191 
192   // FIXME: If there's no umbrella header, we could probably scan the
193   // framework to load *everything*. But, it's not clear that this is a good
194   // idea.
195   if (!UmbrellaHeader)
196     return 0;
197 
198   Module *Result = new Module(ModuleName, SourceLocation(),
199                               /*IsFramework=*/true);
200   // umbrella "umbrella-header-name"
201   Result->UmbrellaHeader = UmbrellaHeader;
202   Headers[UmbrellaHeader] = Result;
203   UmbrellaDirs[FrameworkDir] = Result;
204 
205   // export *
206   Result->Exports.push_back(Module::ExportDecl(0, true));
207 
208   Modules[ModuleName] = Result;
209   return Result;
210 }
211 
212 const FileEntry *
213 ModuleMap::getContainingModuleMapFile(Module *Module) {
214   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
215     return 0;
216 
217   return SourceMgr->getFileEntryForID(
218            SourceMgr->getFileID(Module->DefinitionLoc));
219 }
220 
221 void ModuleMap::dump() {
222   llvm::errs() << "Modules:";
223   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
224                                         MEnd = Modules.end();
225        M != MEnd; ++M)
226     M->getValue()->print(llvm::errs(), 2);
227 
228   llvm::errs() << "Headers:";
229   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
230             H = Headers.begin(),
231          HEnd = Headers.end();
232        H != HEnd; ++H) {
233     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
234                  << H->second->getFullModuleName() << "\n";
235   }
236 }
237 
238 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
239   bool HadError = false;
240   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
241     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
242                                               Complain);
243     if (Export.getPointer() || Export.getInt())
244       Mod->Exports.push_back(Export);
245     else
246       HadError = true;
247   }
248   Mod->UnresolvedExports.clear();
249   return HadError;
250 }
251 
252 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
253   if (Loc.isInvalid())
254     return 0;
255 
256   // Use the expansion location to determine which module we're in.
257   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
258   if (!ExpansionLoc.isFileID())
259     return 0;
260 
261 
262   const SourceManager &SrcMgr = Loc.getManager();
263   FileID ExpansionFileID = ExpansionLoc.getFileID();
264   const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID);
265   if (!ExpansionFile)
266     return 0;
267 
268   // Find the module that owns this header.
269   return findModuleForHeader(ExpansionFile);
270 }
271 
272 //----------------------------------------------------------------------------//
273 // Module map file parser
274 //----------------------------------------------------------------------------//
275 
276 namespace clang {
277   /// \brief A token in a module map file.
278   struct MMToken {
279     enum TokenKind {
280       EndOfFile,
281       HeaderKeyword,
282       Identifier,
283       ExplicitKeyword,
284       ExportKeyword,
285       FrameworkKeyword,
286       ModuleKeyword,
287       Period,
288       UmbrellaKeyword,
289       Star,
290       StringLiteral,
291       LBrace,
292       RBrace
293     } Kind;
294 
295     unsigned Location;
296     unsigned StringLength;
297     const char *StringData;
298 
299     void clear() {
300       Kind = EndOfFile;
301       Location = 0;
302       StringLength = 0;
303       StringData = 0;
304     }
305 
306     bool is(TokenKind K) const { return Kind == K; }
307 
308     SourceLocation getLocation() const {
309       return SourceLocation::getFromRawEncoding(Location);
310     }
311 
312     StringRef getString() const {
313       return StringRef(StringData, StringLength);
314     }
315   };
316 
317   class ModuleMapParser {
318     Lexer &L;
319     SourceManager &SourceMgr;
320     DiagnosticsEngine &Diags;
321     ModuleMap &Map;
322 
323     /// \brief The directory that this module map resides in.
324     const DirectoryEntry *Directory;
325 
326     /// \brief Whether an error occurred.
327     bool HadError;
328 
329     /// \brief Default target information, used only for string literal
330     /// parsing.
331     TargetInfo *Target;
332 
333     /// \brief Stores string data for the various string literals referenced
334     /// during parsing.
335     llvm::BumpPtrAllocator StringData;
336 
337     /// \brief The current token.
338     MMToken Tok;
339 
340     /// \brief The active module.
341     Module *ActiveModule;
342 
343     /// \brief Consume the current token and return its location.
344     SourceLocation consumeToken();
345 
346     /// \brief Skip tokens until we reach the a token with the given kind
347     /// (or the end of the file).
348     void skipUntil(MMToken::TokenKind K);
349 
350     void parseModuleDecl();
351     void parseUmbrellaDecl();
352     void parseHeaderDecl();
353     void parseExportDecl();
354     void parseInferredSubmoduleDecl(bool Explicit);
355 
356   public:
357     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
358                              DiagnosticsEngine &Diags,
359                              ModuleMap &Map,
360                              const DirectoryEntry *Directory)
361       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
362         Directory(Directory), HadError(false), ActiveModule(0)
363     {
364       TargetOptions TargetOpts;
365       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
366       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
367 
368       Tok.clear();
369       consumeToken();
370     }
371 
372     bool parseModuleMapFile();
373   };
374 }
375 
376 SourceLocation ModuleMapParser::consumeToken() {
377 retry:
378   SourceLocation Result = Tok.getLocation();
379   Tok.clear();
380 
381   Token LToken;
382   L.LexFromRawLexer(LToken);
383   Tok.Location = LToken.getLocation().getRawEncoding();
384   switch (LToken.getKind()) {
385   case tok::raw_identifier:
386     Tok.StringData = LToken.getRawIdentifierData();
387     Tok.StringLength = LToken.getLength();
388     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
389                  .Case("header", MMToken::HeaderKeyword)
390                  .Case("explicit", MMToken::ExplicitKeyword)
391                  .Case("export", MMToken::ExportKeyword)
392                  .Case("framework", MMToken::FrameworkKeyword)
393                  .Case("module", MMToken::ModuleKeyword)
394                  .Case("umbrella", MMToken::UmbrellaKeyword)
395                  .Default(MMToken::Identifier);
396     break;
397 
398   case tok::eof:
399     Tok.Kind = MMToken::EndOfFile;
400     break;
401 
402   case tok::l_brace:
403     Tok.Kind = MMToken::LBrace;
404     break;
405 
406   case tok::period:
407     Tok.Kind = MMToken::Period;
408     break;
409 
410   case tok::r_brace:
411     Tok.Kind = MMToken::RBrace;
412     break;
413 
414   case tok::star:
415     Tok.Kind = MMToken::Star;
416     break;
417 
418   case tok::string_literal: {
419     // Parse the string literal.
420     LangOptions LangOpts;
421     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
422     if (StringLiteral.hadError)
423       goto retry;
424 
425     // Copy the string literal into our string data allocator.
426     unsigned Length = StringLiteral.GetStringLength();
427     char *Saved = StringData.Allocate<char>(Length + 1);
428     memcpy(Saved, StringLiteral.GetString().data(), Length);
429     Saved[Length] = 0;
430 
431     // Form the token.
432     Tok.Kind = MMToken::StringLiteral;
433     Tok.StringData = Saved;
434     Tok.StringLength = Length;
435     break;
436   }
437 
438   case tok::comment:
439     goto retry;
440 
441   default:
442     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
443     HadError = true;
444     goto retry;
445   }
446 
447   return Result;
448 }
449 
450 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
451   unsigned braceDepth = 0;
452   do {
453     switch (Tok.Kind) {
454     case MMToken::EndOfFile:
455       return;
456 
457     case MMToken::LBrace:
458       if (Tok.is(K) && braceDepth == 0)
459         return;
460 
461       ++braceDepth;
462       break;
463 
464     case MMToken::RBrace:
465       if (braceDepth > 0)
466         --braceDepth;
467       else if (Tok.is(K))
468         return;
469       break;
470 
471     default:
472       if (braceDepth == 0 && Tok.is(K))
473         return;
474       break;
475     }
476 
477    consumeToken();
478   } while (true);
479 }
480 
481 /// \brief Parse a module declaration.
482 ///
483 ///   module-declaration:
484 ///     'framework'[opt] 'module' identifier { module-member* }
485 ///
486 ///   module-member:
487 ///     umbrella-declaration
488 ///     header-declaration
489 ///     'explicit'[opt] submodule-declaration
490 ///     export-declaration
491 ///
492 ///   submodule-declaration:
493 ///     module-declaration
494 ///     inferred-submodule-declaration
495 void ModuleMapParser::parseModuleDecl() {
496   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
497          Tok.is(MMToken::FrameworkKeyword));
498 
499   // Parse 'framework' or 'explicit' keyword, if present.
500   bool Framework = false;
501   bool Explicit = false;
502 
503   if (Tok.is(MMToken::FrameworkKeyword)) {
504     consumeToken();
505     Framework = true;
506   }
507   // Parse 'explicit' keyword, if present.
508   else if (Tok.is(MMToken::ExplicitKeyword)) {
509     consumeToken();
510     Explicit = true;
511   }
512 
513   // Parse 'module' keyword.
514   if (!Tok.is(MMToken::ModuleKeyword)) {
515     Diags.Report(Tok.getLocation(),
516                  diag::err_mmap_expected_module_after_explicit);
517     consumeToken();
518     HadError = true;
519     return;
520   }
521   consumeToken(); // 'module' keyword
522 
523   // If we have a wildcard for the module name, this is an inferred submodule.
524   // Parse it.
525   if (Tok.is(MMToken::Star))
526     return parseInferredSubmoduleDecl(Explicit);
527 
528   // Parse the module name.
529   if (!Tok.is(MMToken::Identifier)) {
530     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
531     HadError = true;
532     return;
533   }
534   StringRef ModuleName = Tok.getString();
535   SourceLocation ModuleNameLoc = consumeToken();
536 
537   // Parse the opening brace.
538   if (!Tok.is(MMToken::LBrace)) {
539     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
540       << ModuleName;
541     HadError = true;
542     return;
543   }
544   SourceLocation LBraceLoc = consumeToken();
545 
546   // Determine whether this (sub)module has already been defined.
547   llvm::StringMap<Module *> &ModuleSpace
548     = ActiveModule? ActiveModule->SubModules : Map.Modules;
549   llvm::StringMap<Module *>::iterator ExistingModule
550     = ModuleSpace.find(ModuleName);
551   if (ExistingModule != ModuleSpace.end()) {
552     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
553       << ModuleName;
554     Diags.Report(ExistingModule->getValue()->DefinitionLoc,
555                  diag::note_mmap_prev_definition);
556 
557     // Skip the module definition.
558     skipUntil(MMToken::RBrace);
559     if (Tok.is(MMToken::RBrace))
560       consumeToken();
561 
562     HadError = true;
563     return;
564   }
565 
566   // Start defining this module.
567   ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework,
568                             Explicit);
569   ModuleSpace[ModuleName] = ActiveModule;
570 
571   bool Done = false;
572   do {
573     switch (Tok.Kind) {
574     case MMToken::EndOfFile:
575     case MMToken::RBrace:
576       Done = true;
577       break;
578 
579     case MMToken::ExplicitKeyword:
580     case MMToken::ModuleKeyword:
581       parseModuleDecl();
582       break;
583 
584     case MMToken::ExportKeyword:
585       parseExportDecl();
586       break;
587 
588     case MMToken::HeaderKeyword:
589       parseHeaderDecl();
590       break;
591 
592     case MMToken::UmbrellaKeyword:
593       parseUmbrellaDecl();
594       break;
595 
596     default:
597       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
598       consumeToken();
599       break;
600     }
601   } while (!Done);
602 
603   if (Tok.is(MMToken::RBrace))
604     consumeToken();
605   else {
606     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
607     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
608     HadError = true;
609   }
610 
611   // We're done parsing this module. Pop back to our parent scope.
612   ActiveModule = ActiveModule->Parent;
613 }
614 
615 /// \brief Parse an umbrella header declaration.
616 ///
617 ///   umbrella-declaration:
618 ///     'umbrella' string-literal
619 void ModuleMapParser::parseUmbrellaDecl() {
620   assert(Tok.is(MMToken::UmbrellaKeyword));
621   SourceLocation UmbrellaLoc = consumeToken();
622 
623   // Parse the header name.
624   if (!Tok.is(MMToken::StringLiteral)) {
625     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
626       << "umbrella";
627     HadError = true;
628     return;
629   }
630   StringRef FileName = Tok.getString();
631   SourceLocation FileNameLoc = consumeToken();
632 
633   // Check whether we already have an umbrella header.
634   if (ActiveModule->UmbrellaHeader) {
635     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
636       << ActiveModule->getFullModuleName()
637       << ActiveModule->UmbrellaHeader->getName();
638     HadError = true;
639     return;
640   }
641 
642   // Only top-level modules can have umbrella headers.
643   if (ActiveModule->Parent) {
644     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule)
645       << ActiveModule->getFullModuleName();
646     HadError = true;
647     return;
648   }
649 
650   // Look for this file.
651   llvm::SmallString<128> PathName;
652   const FileEntry *File = 0;
653 
654   if (llvm::sys::path::is_absolute(FileName)) {
655     PathName = FileName;
656     File = SourceMgr.getFileManager().getFile(PathName);
657   } else {
658     // Search for the header file within the search directory.
659     PathName += Directory->getName();
660     unsigned PathLength = PathName.size();
661     if (ActiveModule->isPartOfFramework()) {
662       // Check whether this file is in the public headers.
663       llvm::sys::path::append(PathName, "Headers");
664       llvm::sys::path::append(PathName, FileName);
665       File = SourceMgr.getFileManager().getFile(PathName);
666 
667       if (!File) {
668         // Check whether this file is in the private headers.
669         PathName.resize(PathLength);
670         llvm::sys::path::append(PathName, "PrivateHeaders");
671         llvm::sys::path::append(PathName, FileName);
672         File = SourceMgr.getFileManager().getFile(PathName);
673       }
674 
675       // FIXME: Deal with subframeworks.
676     } else {
677       // Lookup for normal headers.
678       llvm::sys::path::append(PathName, FileName);
679       File = SourceMgr.getFileManager().getFile(PathName);
680     }
681   }
682 
683   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
684   // Come up with a lazy way to do this.
685   if (File) {
686     if (const Module *OwningModule = Map.Headers[File]) {
687       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
688         << FileName << OwningModule->getFullModuleName();
689       HadError = true;
690     } else if ((OwningModule = Map.UmbrellaDirs[Directory])) {
691       Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
692         << OwningModule->getFullModuleName();
693       HadError = true;
694     } else {
695       // Record this umbrella header.
696       ActiveModule->UmbrellaHeader = File;
697       Map.Headers[File] = ActiveModule;
698       Map.UmbrellaDirs[Directory] = ActiveModule;
699     }
700   } else {
701     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
702       << true << FileName;
703     HadError = true;
704   }
705 }
706 
707 /// \brief Parse a header declaration.
708 ///
709 ///   header-declaration:
710 ///     'header' string-literal
711 void ModuleMapParser::parseHeaderDecl() {
712   assert(Tok.is(MMToken::HeaderKeyword));
713   consumeToken();
714 
715   // Parse the header name.
716   if (!Tok.is(MMToken::StringLiteral)) {
717     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
718       << "header";
719     HadError = true;
720     return;
721   }
722   StringRef FileName = Tok.getString();
723   SourceLocation FileNameLoc = consumeToken();
724 
725   // Look for this file.
726   llvm::SmallString<128> PathName;
727   if (llvm::sys::path::is_relative(FileName)) {
728     // FIXME: Change this search to also look for private headers!
729     PathName += Directory->getName();
730 
731     if (ActiveModule->isPartOfFramework())
732       llvm::sys::path::append(PathName, "Headers");
733   }
734 
735   llvm::sys::path::append(PathName, FileName);
736 
737   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
738   // Come up with a lazy way to do this.
739   if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) {
740     if (const Module *OwningModule = Map.Headers[File]) {
741       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
742         << FileName << OwningModule->getFullModuleName();
743       HadError = true;
744     } else {
745       // Record this file.
746       ActiveModule->Headers.push_back(File);
747       Map.Headers[File] = ActiveModule;
748     }
749   } else {
750     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
751       << false << FileName;
752     HadError = true;
753   }
754 }
755 
756 /// \brief Parse a module export declaration.
757 ///
758 ///   export-declaration:
759 ///     'export' wildcard-module-id
760 ///
761 ///   wildcard-module-id:
762 ///     identifier
763 ///     '*'
764 ///     identifier '.' wildcard-module-id
765 void ModuleMapParser::parseExportDecl() {
766   assert(Tok.is(MMToken::ExportKeyword));
767   SourceLocation ExportLoc = consumeToken();
768 
769   // Parse the module-id with an optional wildcard at the end.
770   ModuleId ParsedModuleId;
771   bool Wildcard = false;
772   do {
773     if (Tok.is(MMToken::Identifier)) {
774       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
775                                               Tok.getLocation()));
776       consumeToken();
777 
778       if (Tok.is(MMToken::Period)) {
779         consumeToken();
780         continue;
781       }
782 
783       break;
784     }
785 
786     if(Tok.is(MMToken::Star)) {
787       Wildcard = true;
788       consumeToken();
789       break;
790     }
791 
792     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
793     HadError = true;
794     return;
795   } while (true);
796 
797   Module::UnresolvedExportDecl Unresolved = {
798     ExportLoc, ParsedModuleId, Wildcard
799   };
800   ActiveModule->UnresolvedExports.push_back(Unresolved);
801 }
802 
803 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
804   assert(Tok.is(MMToken::Star));
805   SourceLocation StarLoc = consumeToken();
806   bool Failed = false;
807 
808   // Inferred modules must be submodules.
809   if (!ActiveModule) {
810     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
811     Failed = true;
812   }
813 
814   // Inferred modules must have umbrella headers.
815   if (!Failed && !ActiveModule->getTopLevelModule()->UmbrellaHeader) {
816     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
817     Failed = true;
818   }
819 
820   // Check for redefinition of an inferred module.
821   if (!Failed && ActiveModule->getTopLevelModule()->InferSubmodules) {
822     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
823     if (ActiveModule->getTopLevelModule()->InferredSubmoduleLoc.isValid())
824       Diags.Report(ActiveModule->getTopLevelModule()->InferredSubmoduleLoc,
825                    diag::note_mmap_prev_definition);
826     Failed = true;
827   }
828 
829   // If there were any problems with this inferred submodule, skip its body.
830   if (Failed) {
831     if (Tok.is(MMToken::LBrace)) {
832       consumeToken();
833       skipUntil(MMToken::RBrace);
834       if (Tok.is(MMToken::RBrace))
835         consumeToken();
836     }
837     HadError = true;
838     return;
839   }
840 
841   // Note that we have an inferred submodule.
842   Module *TopModule = ActiveModule->getTopLevelModule();
843   TopModule->InferSubmodules = true;
844   TopModule->InferredSubmoduleLoc = StarLoc;
845   TopModule->InferExplicitSubmodules = Explicit;
846 
847   // Parse the opening brace.
848   if (!Tok.is(MMToken::LBrace)) {
849     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
850     HadError = true;
851     return;
852   }
853   SourceLocation LBraceLoc = consumeToken();
854 
855   // Parse the body of the inferred submodule.
856   bool Done = false;
857   do {
858     switch (Tok.Kind) {
859     case MMToken::EndOfFile:
860     case MMToken::RBrace:
861       Done = true;
862       break;
863 
864     case MMToken::ExportKeyword: {
865       consumeToken();
866       if (Tok.is(MMToken::Star))
867         TopModule->InferExportWildcard = true;
868       else
869         Diags.Report(Tok.getLocation(),
870                      diag::err_mmap_expected_export_wildcard);
871       consumeToken();
872       break;
873     }
874 
875     case MMToken::ExplicitKeyword:
876     case MMToken::ModuleKeyword:
877     case MMToken::HeaderKeyword:
878     case MMToken::UmbrellaKeyword:
879     default:
880       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
881       consumeToken();
882       break;
883     }
884   } while (!Done);
885 
886   if (Tok.is(MMToken::RBrace))
887     consumeToken();
888   else {
889     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
890     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
891     HadError = true;
892   }
893 }
894 
895 /// \brief Parse a module map file.
896 ///
897 ///   module-map-file:
898 ///     module-declaration*
899 bool ModuleMapParser::parseModuleMapFile() {
900   do {
901     switch (Tok.Kind) {
902     case MMToken::EndOfFile:
903       return HadError;
904 
905     case MMToken::ModuleKeyword:
906     case MMToken::FrameworkKeyword:
907       parseModuleDecl();
908       break;
909 
910     case MMToken::ExplicitKeyword:
911     case MMToken::ExportKeyword:
912     case MMToken::HeaderKeyword:
913     case MMToken::Identifier:
914     case MMToken::LBrace:
915     case MMToken::Period:
916     case MMToken::RBrace:
917     case MMToken::Star:
918     case MMToken::StringLiteral:
919     case MMToken::UmbrellaKeyword:
920       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
921       HadError = true;
922       consumeToken();
923       break;
924     }
925   } while (true);
926 
927   return HadError;
928 }
929 
930 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
931   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
932   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
933   if (!Buffer)
934     return true;
935 
936   // Parse this module map file.
937   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts);
938   Diags->getClient()->BeginSourceFile(LangOpts);
939   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
940   bool Result = Parser.parseModuleMapFile();
941   Diags->getClient()->EndSourceFile();
942 
943   return Result;
944 }
945