1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ModuleMap implementation, which describes the layout 11 // of a module as it relates to headers. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "clang/Lex/ModuleMap.h" 15 #include "clang/Lex/Lexer.h" 16 #include "clang/Lex/LiteralSupport.h" 17 #include "clang/Lex/LexDiagnostic.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/TargetInfo.h" 21 #include "clang/Basic/TargetOptions.h" 22 #include "llvm/Support/Allocator.h" 23 #include "llvm/Support/Host.h" 24 #include "llvm/Support/PathV2.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/ADT/StringSwitch.h" 28 using namespace clang; 29 30 //----------------------------------------------------------------------------// 31 // Module 32 //----------------------------------------------------------------------------// 33 34 ModuleMap::Module::~Module() { 35 for (llvm::StringMap<Module *>::iterator I = SubModules.begin(), 36 IEnd = SubModules.end(); 37 I != IEnd; ++I) { 38 delete I->getValue(); 39 } 40 41 } 42 43 std::string ModuleMap::Module::getFullModuleName() const { 44 llvm::SmallVector<StringRef, 2> Names; 45 46 // Build up the set of module names (from innermost to outermost). 47 for (const Module *M = this; M; M = M->Parent) 48 Names.push_back(M->Name); 49 50 std::string Result; 51 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 52 IEnd = Names.rend(); 53 I != IEnd; ++I) { 54 if (!Result.empty()) 55 Result += '.'; 56 57 Result += *I; 58 } 59 60 return Result; 61 } 62 63 StringRef ModuleMap::Module::getTopLevelModuleName() const { 64 const Module *Top = this; 65 while (Top->Parent) 66 Top = Top->Parent; 67 68 return Top->Name; 69 } 70 71 void ModuleMap::Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 72 OS.indent(Indent); 73 if (IsFramework) 74 OS << "framework "; 75 if (IsExplicit) 76 OS << "explicit "; 77 OS << "module " << Name << " {\n"; 78 79 if (UmbrellaHeader) { 80 OS.indent(Indent + 2); 81 OS << "umbrella \""; 82 OS.write_escaped(UmbrellaHeader->getName()); 83 OS << "\"\n"; 84 } 85 86 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 87 OS.indent(Indent + 2); 88 OS << "header \""; 89 OS.write_escaped(Headers[I]->getName()); 90 OS << "\"\n"; 91 } 92 93 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(), 94 MIEnd = SubModules.end(); 95 MI != MIEnd; ++MI) 96 MI->getValue()->print(OS, Indent + 2); 97 98 OS.indent(Indent); 99 OS << "}\n"; 100 } 101 102 void ModuleMap::Module::dump() const { 103 print(llvm::errs()); 104 } 105 106 //----------------------------------------------------------------------------// 107 // Module map 108 //----------------------------------------------------------------------------// 109 110 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) { 111 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 112 Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 113 new DiagnosticsEngine(DiagIDs)); 114 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 115 SourceMgr = new SourceManager(*Diags, FileMgr); 116 } 117 118 ModuleMap::~ModuleMap() { 119 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 120 IEnd = Modules.end(); 121 I != IEnd; ++I) { 122 delete I->getValue(); 123 } 124 125 delete SourceMgr; 126 } 127 128 ModuleMap::Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 129 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 130 = Headers.find(File); 131 if (Known != Headers.end()) 132 return Known->second; 133 134 const DirectoryEntry *Dir = File->getDir(); 135 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 136 = UmbrellaDirs.find(Dir); 137 if (KnownDir != UmbrellaDirs.end()) 138 return KnownDir->second; 139 140 // Walk up the directory hierarchy looking for umbrella headers. 141 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 142 StringRef DirName = Dir->getName(); 143 do { 144 // Retrieve our parent path. 145 DirName = llvm::sys::path::parent_path(DirName); 146 if (DirName.empty()) 147 break; 148 149 // Resolve the parent path to a directory entry. 150 Dir = SourceMgr->getFileManager().getDirectory(DirName); 151 if (!Dir) 152 break; 153 154 KnownDir = UmbrellaDirs.find(Dir); 155 if (KnownDir != UmbrellaDirs.end()) { 156 Module *Result = KnownDir->second; 157 158 // Record each of the directories we stepped through as being part of 159 // the module we found, since the umbrella header covers them all. 160 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 161 UmbrellaDirs[SkippedDirs[I]] = Result; 162 163 return Result; 164 } 165 166 SkippedDirs.push_back(Dir); 167 } while (true); 168 169 return 0; 170 } 171 172 ModuleMap::Module *ModuleMap::findModule(StringRef Name) { 173 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 174 if (Known != Modules.end()) 175 return Known->getValue(); 176 177 return 0; 178 } 179 180 std::pair<ModuleMap::Module *, bool> 181 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 182 bool IsExplicit) { 183 // Try to find an existing module with this name. 184 if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name]) 185 return std::make_pair(Found, false); 186 187 // Create a new module with this name. 188 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 189 IsExplicit); 190 if (Parent) 191 Parent->SubModules[Name] = Result; 192 else 193 Modules[Name] = Result; 194 return std::make_pair(Result, true); 195 } 196 197 ModuleMap::Module * 198 ModuleMap::inferFrameworkModule(StringRef ModuleName, 199 const DirectoryEntry *FrameworkDir) { 200 // Check whether we've already found this module. 201 if (Module *Module = findModule(ModuleName)) 202 return Module; 203 204 // Look for an umbrella header. 205 llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 206 llvm::sys::path::append(UmbrellaName, "Headers"); 207 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 208 const FileEntry *UmbrellaHeader 209 = SourceMgr->getFileManager().getFile(UmbrellaName); 210 211 // FIXME: If there's no umbrella header, we could probably scan the 212 // framework to load *everything*. But, it's not clear that this is a good 213 // idea. 214 if (!UmbrellaHeader) 215 return 0; 216 217 Module *Result = new Module(ModuleName, SourceLocation(), 218 /*IsFramework=*/true); 219 Result->UmbrellaHeader = UmbrellaHeader; 220 Headers[UmbrellaHeader] = Result; 221 UmbrellaDirs[FrameworkDir] = Result; 222 Modules[ModuleName] = Result; 223 return Result; 224 } 225 226 const FileEntry * 227 ModuleMap::getContainingModuleMapFile(ModuleMap::Module *Module) { 228 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 229 return 0; 230 231 return SourceMgr->getFileEntryForID( 232 SourceMgr->getFileID(Module->DefinitionLoc)); 233 } 234 235 void ModuleMap::dump() { 236 llvm::errs() << "Modules:"; 237 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 238 MEnd = Modules.end(); 239 M != MEnd; ++M) 240 M->getValue()->print(llvm::errs(), 2); 241 242 llvm::errs() << "Headers:"; 243 for (llvm::DenseMap<const FileEntry *, Module *>::iterator 244 H = Headers.begin(), 245 HEnd = Headers.end(); 246 H != HEnd; ++H) { 247 llvm::errs() << " \"" << H->first->getName() << "\" -> " 248 << H->second->getFullModuleName() << "\n"; 249 } 250 } 251 252 //----------------------------------------------------------------------------// 253 // Module map file parser 254 //----------------------------------------------------------------------------// 255 256 namespace clang { 257 /// \brief A token in a module map file. 258 struct MMToken { 259 enum TokenKind { 260 EndOfFile, 261 HeaderKeyword, 262 Identifier, 263 ExplicitKeyword, 264 FrameworkKeyword, 265 ModuleKeyword, 266 UmbrellaKeyword, 267 StringLiteral, 268 LBrace, 269 RBrace 270 } Kind; 271 272 unsigned Location; 273 unsigned StringLength; 274 const char *StringData; 275 276 void clear() { 277 Kind = EndOfFile; 278 Location = 0; 279 StringLength = 0; 280 StringData = 0; 281 } 282 283 bool is(TokenKind K) const { return Kind == K; } 284 285 SourceLocation getLocation() const { 286 return SourceLocation::getFromRawEncoding(Location); 287 } 288 289 StringRef getString() const { 290 return StringRef(StringData, StringLength); 291 } 292 }; 293 294 class ModuleMapParser { 295 Lexer &L; 296 SourceManager &SourceMgr; 297 DiagnosticsEngine &Diags; 298 ModuleMap ⤅ 299 300 /// \brief The directory that this module map resides in. 301 const DirectoryEntry *Directory; 302 303 /// \brief Whether an error occurred. 304 bool HadError; 305 306 /// \brief Default target information, used only for string literal 307 /// parsing. 308 TargetInfo *Target; 309 310 /// \brief Stores string data for the various string literals referenced 311 /// during parsing. 312 llvm::BumpPtrAllocator StringData; 313 314 /// \brief The current token. 315 MMToken Tok; 316 317 /// \brief The active module. 318 ModuleMap::Module *ActiveModule; 319 320 /// \brief Consume the current token and return its location. 321 SourceLocation consumeToken(); 322 323 /// \brief Skip tokens until we reach the a token with the given kind 324 /// (or the end of the file). 325 void skipUntil(MMToken::TokenKind K); 326 327 void parseModuleDecl(); 328 void parseUmbrellaDecl(); 329 void parseHeaderDecl(); 330 331 public: 332 typedef ModuleMap::Module Module; 333 334 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 335 DiagnosticsEngine &Diags, 336 ModuleMap &Map, 337 const DirectoryEntry *Directory) 338 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 339 Directory(Directory), HadError(false), ActiveModule(0) 340 { 341 TargetOptions TargetOpts; 342 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 343 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 344 345 Tok.clear(); 346 consumeToken(); 347 } 348 349 bool parseModuleMapFile(); 350 }; 351 } 352 353 SourceLocation ModuleMapParser::consumeToken() { 354 retry: 355 SourceLocation Result = Tok.getLocation(); 356 Tok.clear(); 357 358 Token LToken; 359 L.LexFromRawLexer(LToken); 360 Tok.Location = LToken.getLocation().getRawEncoding(); 361 switch (LToken.getKind()) { 362 case tok::raw_identifier: 363 Tok.StringData = LToken.getRawIdentifierData(); 364 Tok.StringLength = LToken.getLength(); 365 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 366 .Case("header", MMToken::HeaderKeyword) 367 .Case("explicit", MMToken::ExplicitKeyword) 368 .Case("framework", MMToken::FrameworkKeyword) 369 .Case("module", MMToken::ModuleKeyword) 370 .Case("umbrella", MMToken::UmbrellaKeyword) 371 .Default(MMToken::Identifier); 372 break; 373 374 case tok::eof: 375 Tok.Kind = MMToken::EndOfFile; 376 break; 377 378 case tok::l_brace: 379 Tok.Kind = MMToken::LBrace; 380 break; 381 382 case tok::r_brace: 383 Tok.Kind = MMToken::RBrace; 384 break; 385 386 case tok::string_literal: { 387 // Parse the string literal. 388 LangOptions LangOpts; 389 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 390 if (StringLiteral.hadError) 391 goto retry; 392 393 // Copy the string literal into our string data allocator. 394 unsigned Length = StringLiteral.GetStringLength(); 395 char *Saved = StringData.Allocate<char>(Length + 1); 396 memcpy(Saved, StringLiteral.GetString().data(), Length); 397 Saved[Length] = 0; 398 399 // Form the token. 400 Tok.Kind = MMToken::StringLiteral; 401 Tok.StringData = Saved; 402 Tok.StringLength = Length; 403 break; 404 } 405 406 case tok::comment: 407 goto retry; 408 409 default: 410 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 411 HadError = true; 412 goto retry; 413 } 414 415 return Result; 416 } 417 418 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 419 unsigned braceDepth = 0; 420 do { 421 switch (Tok.Kind) { 422 case MMToken::EndOfFile: 423 return; 424 425 case MMToken::LBrace: 426 if (Tok.is(K) && braceDepth == 0) 427 return; 428 429 ++braceDepth; 430 break; 431 432 case MMToken::RBrace: 433 if (braceDepth > 0) 434 --braceDepth; 435 else if (Tok.is(K)) 436 return; 437 break; 438 439 default: 440 if (braceDepth == 0 && Tok.is(K)) 441 return; 442 break; 443 } 444 445 consumeToken(); 446 } while (true); 447 } 448 449 /// \brief Parse a module declaration. 450 /// 451 /// module-declaration: 452 /// 'framework'[opt] 'module' identifier { module-member* } 453 /// 454 /// module-member: 455 /// umbrella-declaration 456 /// header-declaration 457 /// 'explicit'[opt] module-declaration 458 void ModuleMapParser::parseModuleDecl() { 459 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 460 Tok.is(MMToken::FrameworkKeyword)); 461 462 // Parse 'framework' or 'explicit' keyword, if present. 463 bool Framework = false; 464 bool Explicit = false; 465 466 if (Tok.is(MMToken::FrameworkKeyword)) { 467 consumeToken(); 468 Framework = true; 469 } 470 // Parse 'explicit' keyword, if present. 471 else if (Tok.is(MMToken::ExplicitKeyword)) { 472 consumeToken(); 473 Explicit = true; 474 } 475 476 // Parse 'module' keyword. 477 if (!Tok.is(MMToken::ModuleKeyword)) { 478 Diags.Report(Tok.getLocation(), 479 diag::err_mmap_expected_module_after_explicit); 480 consumeToken(); 481 HadError = true; 482 return; 483 } 484 consumeToken(); // 'module' keyword 485 486 // Parse the module name. 487 if (!Tok.is(MMToken::Identifier)) { 488 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 489 HadError = true; 490 return; 491 } 492 StringRef ModuleName = Tok.getString(); 493 SourceLocation ModuleNameLoc = consumeToken(); 494 495 // Parse the opening brace. 496 if (!Tok.is(MMToken::LBrace)) { 497 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 498 << ModuleName; 499 HadError = true; 500 return; 501 } 502 SourceLocation LBraceLoc = consumeToken(); 503 504 // Determine whether this (sub)module has already been defined. 505 llvm::StringMap<Module *> &ModuleSpace 506 = ActiveModule? ActiveModule->SubModules : Map.Modules; 507 llvm::StringMap<Module *>::iterator ExistingModule 508 = ModuleSpace.find(ModuleName); 509 if (ExistingModule != ModuleSpace.end()) { 510 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 511 << ModuleName; 512 Diags.Report(ExistingModule->getValue()->DefinitionLoc, 513 diag::note_mmap_prev_definition); 514 515 // Skip the module definition. 516 skipUntil(MMToken::RBrace); 517 if (Tok.is(MMToken::RBrace)) 518 consumeToken(); 519 520 HadError = true; 521 return; 522 } 523 524 // Start defining this module. 525 ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 526 Explicit); 527 ModuleSpace[ModuleName] = ActiveModule; 528 529 bool Done = false; 530 do { 531 switch (Tok.Kind) { 532 case MMToken::EndOfFile: 533 case MMToken::RBrace: 534 Done = true; 535 break; 536 537 case MMToken::ExplicitKeyword: 538 case MMToken::ModuleKeyword: 539 parseModuleDecl(); 540 break; 541 542 case MMToken::HeaderKeyword: 543 parseHeaderDecl(); 544 break; 545 546 case MMToken::UmbrellaKeyword: 547 parseUmbrellaDecl(); 548 break; 549 550 default: 551 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 552 consumeToken(); 553 break; 554 } 555 } while (!Done); 556 557 if (Tok.is(MMToken::RBrace)) 558 consumeToken(); 559 else { 560 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 561 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 562 HadError = true; 563 } 564 565 // We're done parsing this module. Pop back to our parent scope. 566 ActiveModule = ActiveModule->Parent; 567 } 568 569 /// \brief Parse an umbrella header declaration. 570 /// 571 /// umbrella-declaration: 572 /// 'umbrella' string-literal 573 void ModuleMapParser::parseUmbrellaDecl() { 574 assert(Tok.is(MMToken::UmbrellaKeyword)); 575 SourceLocation UmbrellaLoc = consumeToken(); 576 577 // Parse the header name. 578 if (!Tok.is(MMToken::StringLiteral)) { 579 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 580 << "umbrella"; 581 HadError = true; 582 return; 583 } 584 StringRef FileName = Tok.getString(); 585 SourceLocation FileNameLoc = consumeToken(); 586 587 // Check whether we already have an umbrella header. 588 if (ActiveModule->UmbrellaHeader) { 589 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict) 590 << ActiveModule->getFullModuleName() 591 << ActiveModule->UmbrellaHeader->getName(); 592 HadError = true; 593 return; 594 } 595 596 // Only top-level modules can have umbrella headers. 597 if (ActiveModule->Parent) { 598 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule) 599 << ActiveModule->getFullModuleName(); 600 HadError = true; 601 return; 602 } 603 604 // Look for this file. 605 llvm::SmallString<128> PathName; 606 const FileEntry *File = 0; 607 608 if (llvm::sys::path::is_absolute(FileName)) { 609 PathName = FileName; 610 File = SourceMgr.getFileManager().getFile(PathName); 611 } else { 612 // Search for the header file within the search directory. 613 PathName += Directory->getName(); 614 unsigned PathLength = PathName.size(); 615 if (ActiveModule->isPartOfFramework()) { 616 // Check whether this file is in the public headers. 617 llvm::sys::path::append(PathName, "Headers"); 618 llvm::sys::path::append(PathName, FileName); 619 File = SourceMgr.getFileManager().getFile(PathName); 620 621 if (!File) { 622 // Check whether this file is in the private headers. 623 PathName.resize(PathLength); 624 llvm::sys::path::append(PathName, "PrivateHeaders"); 625 llvm::sys::path::append(PathName, FileName); 626 File = SourceMgr.getFileManager().getFile(PathName); 627 } 628 629 // FIXME: Deal with subframeworks. 630 } else { 631 // Lookup for normal headers. 632 llvm::sys::path::append(PathName, FileName); 633 File = SourceMgr.getFileManager().getFile(PathName); 634 } 635 } 636 637 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 638 // Come up with a lazy way to do this. 639 if (File) { 640 if (const Module *OwningModule = Map.Headers[File]) { 641 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 642 << FileName << OwningModule->getFullModuleName(); 643 HadError = true; 644 } else if ((OwningModule = Map.UmbrellaDirs[Directory])) { 645 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 646 << OwningModule->getFullModuleName(); 647 HadError = true; 648 } else { 649 // Record this umbrella header. 650 ActiveModule->UmbrellaHeader = File; 651 Map.Headers[File] = ActiveModule; 652 Map.UmbrellaDirs[Directory] = ActiveModule; 653 } 654 } else { 655 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 656 << true << FileName; 657 HadError = true; 658 } 659 } 660 661 /// \brief Parse a header declaration. 662 /// 663 /// header-declaration: 664 /// 'header' string-literal 665 void ModuleMapParser::parseHeaderDecl() { 666 assert(Tok.is(MMToken::HeaderKeyword)); 667 consumeToken(); 668 669 // Parse the header name. 670 if (!Tok.is(MMToken::StringLiteral)) { 671 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 672 << "header"; 673 HadError = true; 674 return; 675 } 676 StringRef FileName = Tok.getString(); 677 SourceLocation FileNameLoc = consumeToken(); 678 679 // Look for this file. 680 llvm::SmallString<128> PathName; 681 if (llvm::sys::path::is_relative(FileName)) { 682 // FIXME: Change this search to also look for private headers! 683 PathName += Directory->getName(); 684 685 if (ActiveModule->isPartOfFramework()) 686 llvm::sys::path::append(PathName, "Headers"); 687 } 688 689 llvm::sys::path::append(PathName, FileName); 690 691 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 692 // Come up with a lazy way to do this. 693 if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) { 694 if (const Module *OwningModule = Map.Headers[File]) { 695 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 696 << FileName << OwningModule->getFullModuleName(); 697 HadError = true; 698 } else { 699 // Record this file. 700 ActiveModule->Headers.push_back(File); 701 Map.Headers[File] = ActiveModule; 702 } 703 } else { 704 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 705 << false << FileName; 706 HadError = true; 707 } 708 } 709 710 /// \brief Parse a module map file. 711 /// 712 /// module-map-file: 713 /// module-declaration* 714 bool ModuleMapParser::parseModuleMapFile() { 715 do { 716 switch (Tok.Kind) { 717 case MMToken::EndOfFile: 718 return HadError; 719 720 case MMToken::ModuleKeyword: 721 case MMToken::FrameworkKeyword: 722 parseModuleDecl(); 723 break; 724 725 case MMToken::ExplicitKeyword: 726 case MMToken::HeaderKeyword: 727 case MMToken::Identifier: 728 case MMToken::LBrace: 729 case MMToken::RBrace: 730 case MMToken::StringLiteral: 731 case MMToken::UmbrellaKeyword: 732 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 733 HadError = true; 734 consumeToken(); 735 break; 736 } 737 } while (true); 738 739 return HadError; 740 } 741 742 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 743 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 744 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 745 if (!Buffer) 746 return true; 747 748 // Parse this module map file. 749 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 750 Diags->getClient()->BeginSourceFile(LangOpts); 751 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 752 bool Result = Parser.parseModuleMapFile(); 753 Diags->getClient()->EndSourceFile(); 754 755 return Result; 756 } 757