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