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