ModuleMap.cpp revision 209977c4d809914a20fd44873876c76cf972a56d
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"
28using namespace clang;
29
30Module::ExportDecl
31ModuleMap::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
71ModuleMap::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
79ModuleMap::~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
89Module *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
133Module *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
141Module *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
150Module *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
161std::pair<Module *, bool>
162ModuleMap::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
178Module *
179ModuleMap::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
212const FileEntry *
213ModuleMap::getContainingModuleMapFile(Module *Module) {
214  if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
215    return 0;
216
217  return SourceMgr->getFileEntryForID(
218           SourceMgr->getFileID(Module->DefinitionLoc));
219}
220
221void 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
238bool 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
252Module *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
276namespace 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
375SourceLocation ModuleMapParser::consumeToken() {
376retry:
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
449void 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
490void 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
609void 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
701void 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
755void 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*
797bool 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
828bool 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