xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision d8bd7537ec31090a1b0f4300d76da5fa21eea93f)
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 
355   public:
356     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
357                              DiagnosticsEngine &Diags,
358                              ModuleMap &Map,
359                              const DirectoryEntry *Directory)
360       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
361         Directory(Directory), HadError(false), ActiveModule(0)
362     {
363       TargetOptions TargetOpts;
364       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
365       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
366 
367       Tok.clear();
368       consumeToken();
369     }
370 
371     bool parseModuleMapFile();
372   };
373 }
374 
375 SourceLocation ModuleMapParser::consumeToken() {
376 retry:
377   SourceLocation Result = Tok.getLocation();
378   Tok.clear();
379 
380   Token LToken;
381   L.LexFromRawLexer(LToken);
382   Tok.Location = LToken.getLocation().getRawEncoding();
383   switch (LToken.getKind()) {
384   case tok::raw_identifier:
385     Tok.StringData = LToken.getRawIdentifierData();
386     Tok.StringLength = LToken.getLength();
387     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
388                  .Case("header", MMToken::HeaderKeyword)
389                  .Case("explicit", MMToken::ExplicitKeyword)
390                  .Case("export", MMToken::ExportKeyword)
391                  .Case("framework", MMToken::FrameworkKeyword)
392                  .Case("module", MMToken::ModuleKeyword)
393                  .Case("umbrella", MMToken::UmbrellaKeyword)
394                  .Default(MMToken::Identifier);
395     break;
396 
397   case tok::eof:
398     Tok.Kind = MMToken::EndOfFile;
399     break;
400 
401   case tok::l_brace:
402     Tok.Kind = MMToken::LBrace;
403     break;
404 
405   case tok::period:
406     Tok.Kind = MMToken::Period;
407     break;
408 
409   case tok::r_brace:
410     Tok.Kind = MMToken::RBrace;
411     break;
412 
413   case tok::star:
414     Tok.Kind = MMToken::Star;
415     break;
416 
417   case tok::string_literal: {
418     // Parse the string literal.
419     LangOptions LangOpts;
420     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
421     if (StringLiteral.hadError)
422       goto retry;
423 
424     // Copy the string literal into our string data allocator.
425     unsigned Length = StringLiteral.GetStringLength();
426     char *Saved = StringData.Allocate<char>(Length + 1);
427     memcpy(Saved, StringLiteral.GetString().data(), Length);
428     Saved[Length] = 0;
429 
430     // Form the token.
431     Tok.Kind = MMToken::StringLiteral;
432     Tok.StringData = Saved;
433     Tok.StringLength = Length;
434     break;
435   }
436 
437   case tok::comment:
438     goto retry;
439 
440   default:
441     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
442     HadError = true;
443     goto retry;
444   }
445 
446   return Result;
447 }
448 
449 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
450   unsigned braceDepth = 0;
451   do {
452     switch (Tok.Kind) {
453     case MMToken::EndOfFile:
454       return;
455 
456     case MMToken::LBrace:
457       if (Tok.is(K) && braceDepth == 0)
458         return;
459 
460       ++braceDepth;
461       break;
462 
463     case MMToken::RBrace:
464       if (braceDepth > 0)
465         --braceDepth;
466       else if (Tok.is(K))
467         return;
468       break;
469 
470     default:
471       if (braceDepth == 0 && Tok.is(K))
472         return;
473       break;
474     }
475 
476    consumeToken();
477   } while (true);
478 }
479 
480 /// \brief Parse a module declaration.
481 ///
482 ///   module-declaration:
483 ///     'framework'[opt] 'module' identifier { module-member* }
484 ///
485 ///   module-member:
486 ///     umbrella-declaration
487 ///     header-declaration
488 ///     'explicit'[opt] module-declaration
489 ///     export-declaration
490 void ModuleMapParser::parseModuleDecl() {
491   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
492          Tok.is(MMToken::FrameworkKeyword));
493 
494   // Parse 'framework' or 'explicit' keyword, if present.
495   bool Framework = false;
496   bool Explicit = false;
497 
498   if (Tok.is(MMToken::FrameworkKeyword)) {
499     consumeToken();
500     Framework = true;
501   }
502   // Parse 'explicit' keyword, if present.
503   else if (Tok.is(MMToken::ExplicitKeyword)) {
504     consumeToken();
505     Explicit = true;
506   }
507 
508   // Parse 'module' keyword.
509   if (!Tok.is(MMToken::ModuleKeyword)) {
510     Diags.Report(Tok.getLocation(),
511                  diag::err_mmap_expected_module_after_explicit);
512     consumeToken();
513     HadError = true;
514     return;
515   }
516   consumeToken(); // 'module' keyword
517 
518   // Parse the module name.
519   if (!Tok.is(MMToken::Identifier)) {
520     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
521     HadError = true;
522     return;
523   }
524   StringRef ModuleName = Tok.getString();
525   SourceLocation ModuleNameLoc = consumeToken();
526 
527   // Parse the opening brace.
528   if (!Tok.is(MMToken::LBrace)) {
529     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
530       << ModuleName;
531     HadError = true;
532     return;
533   }
534   SourceLocation LBraceLoc = consumeToken();
535 
536   // Determine whether this (sub)module has already been defined.
537   llvm::StringMap<Module *> &ModuleSpace
538     = ActiveModule? ActiveModule->SubModules : Map.Modules;
539   llvm::StringMap<Module *>::iterator ExistingModule
540     = ModuleSpace.find(ModuleName);
541   if (ExistingModule != ModuleSpace.end()) {
542     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
543       << ModuleName;
544     Diags.Report(ExistingModule->getValue()->DefinitionLoc,
545                  diag::note_mmap_prev_definition);
546 
547     // Skip the module definition.
548     skipUntil(MMToken::RBrace);
549     if (Tok.is(MMToken::RBrace))
550       consumeToken();
551 
552     HadError = true;
553     return;
554   }
555 
556   // Start defining this module.
557   ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework,
558                             Explicit);
559   ModuleSpace[ModuleName] = ActiveModule;
560 
561   bool Done = false;
562   do {
563     switch (Tok.Kind) {
564     case MMToken::EndOfFile:
565     case MMToken::RBrace:
566       Done = true;
567       break;
568 
569     case MMToken::ExplicitKeyword:
570     case MMToken::ModuleKeyword:
571       parseModuleDecl();
572       break;
573 
574     case MMToken::ExportKeyword:
575       parseExportDecl();
576       break;
577 
578     case MMToken::HeaderKeyword:
579       parseHeaderDecl();
580       break;
581 
582     case MMToken::UmbrellaKeyword:
583       parseUmbrellaDecl();
584       break;
585 
586     default:
587       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
588       consumeToken();
589       break;
590     }
591   } while (!Done);
592 
593   if (Tok.is(MMToken::RBrace))
594     consumeToken();
595   else {
596     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
597     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
598     HadError = true;
599   }
600 
601   // We're done parsing this module. Pop back to our parent scope.
602   ActiveModule = ActiveModule->Parent;
603 }
604 
605 /// \brief Parse an umbrella header declaration.
606 ///
607 ///   umbrella-declaration:
608 ///     'umbrella' string-literal
609 void ModuleMapParser::parseUmbrellaDecl() {
610   assert(Tok.is(MMToken::UmbrellaKeyword));
611   SourceLocation UmbrellaLoc = consumeToken();
612 
613   // Parse the header name.
614   if (!Tok.is(MMToken::StringLiteral)) {
615     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
616       << "umbrella";
617     HadError = true;
618     return;
619   }
620   StringRef FileName = Tok.getString();
621   SourceLocation FileNameLoc = consumeToken();
622 
623   // Check whether we already have an umbrella header.
624   if (ActiveModule->UmbrellaHeader) {
625     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
626       << ActiveModule->getFullModuleName()
627       << ActiveModule->UmbrellaHeader->getName();
628     HadError = true;
629     return;
630   }
631 
632   // Only top-level modules can have umbrella headers.
633   if (ActiveModule->Parent) {
634     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule)
635       << ActiveModule->getFullModuleName();
636     HadError = true;
637     return;
638   }
639 
640   // Look for this file.
641   llvm::SmallString<128> PathName;
642   const FileEntry *File = 0;
643 
644   if (llvm::sys::path::is_absolute(FileName)) {
645     PathName = FileName;
646     File = SourceMgr.getFileManager().getFile(PathName);
647   } else {
648     // Search for the header file within the search directory.
649     PathName += Directory->getName();
650     unsigned PathLength = PathName.size();
651     if (ActiveModule->isPartOfFramework()) {
652       // Check whether this file is in the public headers.
653       llvm::sys::path::append(PathName, "Headers");
654       llvm::sys::path::append(PathName, FileName);
655       File = SourceMgr.getFileManager().getFile(PathName);
656 
657       if (!File) {
658         // Check whether this file is in the private headers.
659         PathName.resize(PathLength);
660         llvm::sys::path::append(PathName, "PrivateHeaders");
661         llvm::sys::path::append(PathName, FileName);
662         File = SourceMgr.getFileManager().getFile(PathName);
663       }
664 
665       // FIXME: Deal with subframeworks.
666     } else {
667       // Lookup for normal headers.
668       llvm::sys::path::append(PathName, FileName);
669       File = SourceMgr.getFileManager().getFile(PathName);
670     }
671   }
672 
673   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
674   // Come up with a lazy way to do this.
675   if (File) {
676     if (const Module *OwningModule = Map.Headers[File]) {
677       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
678         << FileName << OwningModule->getFullModuleName();
679       HadError = true;
680     } else if ((OwningModule = Map.UmbrellaDirs[Directory])) {
681       Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
682         << OwningModule->getFullModuleName();
683       HadError = true;
684     } else {
685       // Record this umbrella header.
686       ActiveModule->UmbrellaHeader = File;
687       Map.Headers[File] = ActiveModule;
688       Map.UmbrellaDirs[Directory] = ActiveModule;
689     }
690   } else {
691     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
692       << true << FileName;
693     HadError = true;
694   }
695 }
696 
697 /// \brief Parse a header declaration.
698 ///
699 ///   header-declaration:
700 ///     'header' string-literal
701 void ModuleMapParser::parseHeaderDecl() {
702   assert(Tok.is(MMToken::HeaderKeyword));
703   consumeToken();
704 
705   // Parse the header name.
706   if (!Tok.is(MMToken::StringLiteral)) {
707     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
708       << "header";
709     HadError = true;
710     return;
711   }
712   StringRef FileName = Tok.getString();
713   SourceLocation FileNameLoc = consumeToken();
714 
715   // Look for this file.
716   llvm::SmallString<128> PathName;
717   if (llvm::sys::path::is_relative(FileName)) {
718     // FIXME: Change this search to also look for private headers!
719     PathName += Directory->getName();
720 
721     if (ActiveModule->isPartOfFramework())
722       llvm::sys::path::append(PathName, "Headers");
723   }
724 
725   llvm::sys::path::append(PathName, FileName);
726 
727   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
728   // Come up with a lazy way to do this.
729   if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) {
730     if (const Module *OwningModule = Map.Headers[File]) {
731       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
732         << FileName << OwningModule->getFullModuleName();
733       HadError = true;
734     } else {
735       // Record this file.
736       ActiveModule->Headers.push_back(File);
737       Map.Headers[File] = ActiveModule;
738     }
739   } else {
740     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
741       << false << FileName;
742     HadError = true;
743   }
744 }
745 
746 /// \brief Parse a module export declaration.
747 ///
748 ///   export-declaration:
749 ///     'export' wildcard-module-id
750 ///
751 ///   wildcard-module-id:
752 ///     identifier
753 ///     '*'
754 ///     identifier '.' wildcard-module-id
755 void ModuleMapParser::parseExportDecl() {
756   assert(Tok.is(MMToken::ExportKeyword));
757   SourceLocation ExportLoc = consumeToken();
758 
759   // Parse the module-id with an optional wildcard at the end.
760   ModuleId ParsedModuleId;
761   bool Wildcard = false;
762   do {
763     if (Tok.is(MMToken::Identifier)) {
764       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
765                                               Tok.getLocation()));
766       consumeToken();
767 
768       if (Tok.is(MMToken::Period)) {
769         consumeToken();
770         continue;
771       }
772 
773       break;
774     }
775 
776     if(Tok.is(MMToken::Star)) {
777       Wildcard = true;
778       consumeToken();
779       break;
780     }
781 
782     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
783     HadError = true;
784     return;
785   } while (true);
786 
787   Module::UnresolvedExportDecl Unresolved = {
788     ExportLoc, ParsedModuleId, Wildcard
789   };
790   ActiveModule->UnresolvedExports.push_back(Unresolved);
791 }
792 
793 /// \brief Parse a module map file.
794 ///
795 ///   module-map-file:
796 ///     module-declaration*
797 bool ModuleMapParser::parseModuleMapFile() {
798   do {
799     switch (Tok.Kind) {
800     case MMToken::EndOfFile:
801       return HadError;
802 
803     case MMToken::ModuleKeyword:
804     case MMToken::FrameworkKeyword:
805       parseModuleDecl();
806       break;
807 
808     case MMToken::ExplicitKeyword:
809     case MMToken::ExportKeyword:
810     case MMToken::HeaderKeyword:
811     case MMToken::Identifier:
812     case MMToken::LBrace:
813     case MMToken::Period:
814     case MMToken::RBrace:
815     case MMToken::Star:
816     case MMToken::StringLiteral:
817     case MMToken::UmbrellaKeyword:
818       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
819       HadError = true;
820       consumeToken();
821       break;
822     }
823   } while (true);
824 
825   return HadError;
826 }
827 
828 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
829   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
830   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
831   if (!Buffer)
832     return true;
833 
834   // Parse this module map file.
835   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts);
836   Diags->getClient()->BeginSourceFile(LangOpts);
837   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
838   bool Result = Parser.parseModuleMapFile();
839   Diags->getClient()->EndSourceFile();
840 
841   return Result;
842 }
843