1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ModuleMap implementation, which describes the layout 11 // of a module as it relates to headers. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "clang/Lex/ModuleMap.h" 15 #include "clang/Lex/Lexer.h" 16 #include "clang/Lex/LiteralSupport.h" 17 #include "clang/Lex/LexDiagnostic.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/TargetInfo.h" 21 #include "clang/Basic/TargetOptions.h" 22 #include "llvm/Support/Allocator.h" 23 #include "llvm/Support/Host.h" 24 #include "llvm/Support/PathV2.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/ADT/StringSwitch.h" 28 using namespace clang; 29 30 Module::ExportDecl 31 ModuleMap::resolveExport(Module *Mod, 32 const Module::UnresolvedExportDecl &Unresolved, 33 bool Complain) { 34 // We may have just a wildcard. 35 if (Unresolved.Id.empty()) { 36 assert(Unresolved.Wildcard && "Invalid unresolved export"); 37 return Module::ExportDecl(0, true); 38 } 39 40 // Find the starting module. 41 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 42 if (!Context) { 43 if (Complain) 44 Diags->Report(Unresolved.Id[0].second, 45 diag::err_mmap_missing_module_unqualified) 46 << Unresolved.Id[0].first << Mod->getFullModuleName(); 47 48 return Module::ExportDecl(); 49 } 50 51 // Dig into the module path. 52 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 53 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 54 Context); 55 if (!Sub) { 56 if (Complain) 57 Diags->Report(Unresolved.Id[I].second, 58 diag::err_mmap_missing_module_qualified) 59 << Unresolved.Id[I].first << Context->getFullModuleName() 60 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 61 62 return Module::ExportDecl(); 63 } 64 65 Context = Sub; 66 } 67 68 return Module::ExportDecl(Context, Unresolved.Wildcard); 69 } 70 71 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) { 72 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 73 Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 74 new DiagnosticsEngine(DiagIDs)); 75 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 76 SourceMgr = new SourceManager(*Diags, FileMgr); 77 } 78 79 ModuleMap::~ModuleMap() { 80 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 81 IEnd = Modules.end(); 82 I != IEnd; ++I) { 83 delete I->getValue(); 84 } 85 86 delete SourceMgr; 87 } 88 89 Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 90 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 91 = Headers.find(File); 92 if (Known != Headers.end()) 93 return Known->second; 94 95 const DirectoryEntry *Dir = File->getDir(); 96 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 97 = UmbrellaDirs.find(Dir); 98 if (KnownDir != UmbrellaDirs.end()) 99 return KnownDir->second; 100 101 // Walk up the directory hierarchy looking for umbrella headers. 102 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 103 StringRef DirName = Dir->getName(); 104 do { 105 // Retrieve our parent path. 106 DirName = llvm::sys::path::parent_path(DirName); 107 if (DirName.empty()) 108 break; 109 110 // Resolve the parent path to a directory entry. 111 Dir = SourceMgr->getFileManager().getDirectory(DirName); 112 if (!Dir) 113 break; 114 115 KnownDir = UmbrellaDirs.find(Dir); 116 if (KnownDir != UmbrellaDirs.end()) { 117 Module *Result = KnownDir->second; 118 119 // Record each of the directories we stepped through as being part of 120 // the module we found, since the umbrella header covers them all. 121 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 122 UmbrellaDirs[SkippedDirs[I]] = Result; 123 124 return Result; 125 } 126 127 SkippedDirs.push_back(Dir); 128 } while (true); 129 130 return 0; 131 } 132 133 Module *ModuleMap::findModule(StringRef Name) { 134 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 135 if (Known != Modules.end()) 136 return Known->getValue(); 137 138 return 0; 139 } 140 141 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 142 for(; Context; Context = Context->Parent) { 143 if (Module *Sub = lookupModuleQualified(Name, Context)) 144 return Sub; 145 } 146 147 return findModule(Name); 148 } 149 150 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 151 if (!Context) 152 return findModule(Name); 153 154 llvm::StringMap<Module *>::iterator Sub = Context->SubModules.find(Name); 155 if (Sub != Context->SubModules.end()) 156 return Sub->getValue(); 157 158 return 0; 159 } 160 161 std::pair<Module *, bool> 162 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 163 bool IsExplicit) { 164 // Try to find an existing module with this name. 165 if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name]) 166 return std::make_pair(Found, false); 167 168 // Create a new module with this name. 169 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 170 IsExplicit); 171 if (Parent) 172 Parent->SubModules[Name] = Result; 173 else 174 Modules[Name] = Result; 175 return std::make_pair(Result, true); 176 } 177 178 Module * 179 ModuleMap::inferFrameworkModule(StringRef ModuleName, 180 const DirectoryEntry *FrameworkDir) { 181 // Check whether we've already found this module. 182 if (Module *Module = findModule(ModuleName)) 183 return Module; 184 185 // Look for an umbrella header. 186 llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 187 llvm::sys::path::append(UmbrellaName, "Headers"); 188 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 189 const FileEntry *UmbrellaHeader 190 = SourceMgr->getFileManager().getFile(UmbrellaName); 191 192 // FIXME: If there's no umbrella header, we could probably scan the 193 // framework to load *everything*. But, it's not clear that this is a good 194 // idea. 195 if (!UmbrellaHeader) 196 return 0; 197 198 Module *Result = new Module(ModuleName, SourceLocation(), 199 /*IsFramework=*/true); 200 // umbrella "umbrella-header-name" 201 Result->UmbrellaHeader = UmbrellaHeader; 202 Headers[UmbrellaHeader] = Result; 203 UmbrellaDirs[FrameworkDir] = Result; 204 205 // export * 206 Result->Exports.push_back(Module::ExportDecl(0, true)); 207 208 Modules[ModuleName] = Result; 209 return Result; 210 } 211 212 const FileEntry * 213 ModuleMap::getContainingModuleMapFile(Module *Module) { 214 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 215 return 0; 216 217 return SourceMgr->getFileEntryForID( 218 SourceMgr->getFileID(Module->DefinitionLoc)); 219 } 220 221 void ModuleMap::dump() { 222 llvm::errs() << "Modules:"; 223 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 224 MEnd = Modules.end(); 225 M != MEnd; ++M) 226 M->getValue()->print(llvm::errs(), 2); 227 228 llvm::errs() << "Headers:"; 229 for (llvm::DenseMap<const FileEntry *, Module *>::iterator 230 H = Headers.begin(), 231 HEnd = Headers.end(); 232 H != HEnd; ++H) { 233 llvm::errs() << " \"" << H->first->getName() << "\" -> " 234 << H->second->getFullModuleName() << "\n"; 235 } 236 } 237 238 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 239 bool HadError = false; 240 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 241 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 242 Complain); 243 if (Export.getPointer() || Export.getInt()) 244 Mod->Exports.push_back(Export); 245 else 246 HadError = true; 247 } 248 Mod->UnresolvedExports.clear(); 249 return HadError; 250 } 251 252 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 253 if (Loc.isInvalid()) 254 return 0; 255 256 // Use the expansion location to determine which module we're in. 257 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 258 if (!ExpansionLoc.isFileID()) 259 return 0; 260 261 262 const SourceManager &SrcMgr = Loc.getManager(); 263 FileID ExpansionFileID = ExpansionLoc.getFileID(); 264 const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID); 265 if (!ExpansionFile) 266 return 0; 267 268 // Find the module that owns this header. 269 return findModuleForHeader(ExpansionFile); 270 } 271 272 //----------------------------------------------------------------------------// 273 // Module map file parser 274 //----------------------------------------------------------------------------// 275 276 namespace clang { 277 /// \brief A token in a module map file. 278 struct MMToken { 279 enum TokenKind { 280 EndOfFile, 281 HeaderKeyword, 282 Identifier, 283 ExplicitKeyword, 284 ExportKeyword, 285 FrameworkKeyword, 286 ModuleKeyword, 287 Period, 288 UmbrellaKeyword, 289 Star, 290 StringLiteral, 291 LBrace, 292 RBrace 293 } Kind; 294 295 unsigned Location; 296 unsigned StringLength; 297 const char *StringData; 298 299 void clear() { 300 Kind = EndOfFile; 301 Location = 0; 302 StringLength = 0; 303 StringData = 0; 304 } 305 306 bool is(TokenKind K) const { return Kind == K; } 307 308 SourceLocation getLocation() const { 309 return SourceLocation::getFromRawEncoding(Location); 310 } 311 312 StringRef getString() const { 313 return StringRef(StringData, StringLength); 314 } 315 }; 316 317 class ModuleMapParser { 318 Lexer &L; 319 SourceManager &SourceMgr; 320 DiagnosticsEngine &Diags; 321 ModuleMap ⤅ 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 void parseInferredSubmoduleDecl(bool Explicit); 355 356 public: 357 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 358 DiagnosticsEngine &Diags, 359 ModuleMap &Map, 360 const DirectoryEntry *Directory) 361 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 362 Directory(Directory), HadError(false), ActiveModule(0) 363 { 364 TargetOptions TargetOpts; 365 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 366 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 367 368 Tok.clear(); 369 consumeToken(); 370 } 371 372 bool parseModuleMapFile(); 373 }; 374 } 375 376 SourceLocation ModuleMapParser::consumeToken() { 377 retry: 378 SourceLocation Result = Tok.getLocation(); 379 Tok.clear(); 380 381 Token LToken; 382 L.LexFromRawLexer(LToken); 383 Tok.Location = LToken.getLocation().getRawEncoding(); 384 switch (LToken.getKind()) { 385 case tok::raw_identifier: 386 Tok.StringData = LToken.getRawIdentifierData(); 387 Tok.StringLength = LToken.getLength(); 388 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 389 .Case("header", MMToken::HeaderKeyword) 390 .Case("explicit", MMToken::ExplicitKeyword) 391 .Case("export", MMToken::ExportKeyword) 392 .Case("framework", MMToken::FrameworkKeyword) 393 .Case("module", MMToken::ModuleKeyword) 394 .Case("umbrella", MMToken::UmbrellaKeyword) 395 .Default(MMToken::Identifier); 396 break; 397 398 case tok::eof: 399 Tok.Kind = MMToken::EndOfFile; 400 break; 401 402 case tok::l_brace: 403 Tok.Kind = MMToken::LBrace; 404 break; 405 406 case tok::period: 407 Tok.Kind = MMToken::Period; 408 break; 409 410 case tok::r_brace: 411 Tok.Kind = MMToken::RBrace; 412 break; 413 414 case tok::star: 415 Tok.Kind = MMToken::Star; 416 break; 417 418 case tok::string_literal: { 419 // Parse the string literal. 420 LangOptions LangOpts; 421 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 422 if (StringLiteral.hadError) 423 goto retry; 424 425 // Copy the string literal into our string data allocator. 426 unsigned Length = StringLiteral.GetStringLength(); 427 char *Saved = StringData.Allocate<char>(Length + 1); 428 memcpy(Saved, StringLiteral.GetString().data(), Length); 429 Saved[Length] = 0; 430 431 // Form the token. 432 Tok.Kind = MMToken::StringLiteral; 433 Tok.StringData = Saved; 434 Tok.StringLength = Length; 435 break; 436 } 437 438 case tok::comment: 439 goto retry; 440 441 default: 442 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 443 HadError = true; 444 goto retry; 445 } 446 447 return Result; 448 } 449 450 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 451 unsigned braceDepth = 0; 452 do { 453 switch (Tok.Kind) { 454 case MMToken::EndOfFile: 455 return; 456 457 case MMToken::LBrace: 458 if (Tok.is(K) && braceDepth == 0) 459 return; 460 461 ++braceDepth; 462 break; 463 464 case MMToken::RBrace: 465 if (braceDepth > 0) 466 --braceDepth; 467 else if (Tok.is(K)) 468 return; 469 break; 470 471 default: 472 if (braceDepth == 0 && Tok.is(K)) 473 return; 474 break; 475 } 476 477 consumeToken(); 478 } while (true); 479 } 480 481 /// \brief Parse a module declaration. 482 /// 483 /// module-declaration: 484 /// 'framework'[opt] 'module' identifier { module-member* } 485 /// 486 /// module-member: 487 /// umbrella-declaration 488 /// header-declaration 489 /// 'explicit'[opt] submodule-declaration 490 /// export-declaration 491 /// 492 /// submodule-declaration: 493 /// module-declaration 494 /// inferred-submodule-declaration 495 void ModuleMapParser::parseModuleDecl() { 496 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 497 Tok.is(MMToken::FrameworkKeyword)); 498 499 // Parse 'framework' or 'explicit' keyword, if present. 500 bool Framework = false; 501 bool Explicit = false; 502 503 if (Tok.is(MMToken::FrameworkKeyword)) { 504 consumeToken(); 505 Framework = true; 506 } 507 // Parse 'explicit' keyword, if present. 508 else if (Tok.is(MMToken::ExplicitKeyword)) { 509 consumeToken(); 510 Explicit = true; 511 } 512 513 // Parse 'module' keyword. 514 if (!Tok.is(MMToken::ModuleKeyword)) { 515 Diags.Report(Tok.getLocation(), 516 diag::err_mmap_expected_module_after_explicit); 517 consumeToken(); 518 HadError = true; 519 return; 520 } 521 consumeToken(); // 'module' keyword 522 523 // If we have a wildcard for the module name, this is an inferred submodule. 524 // Parse it. 525 if (Tok.is(MMToken::Star)) 526 return parseInferredSubmoduleDecl(Explicit); 527 528 // Parse the module name. 529 if (!Tok.is(MMToken::Identifier)) { 530 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 531 HadError = true; 532 return; 533 } 534 StringRef ModuleName = Tok.getString(); 535 SourceLocation ModuleNameLoc = consumeToken(); 536 537 // Parse the opening brace. 538 if (!Tok.is(MMToken::LBrace)) { 539 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 540 << ModuleName; 541 HadError = true; 542 return; 543 } 544 SourceLocation LBraceLoc = consumeToken(); 545 546 // Determine whether this (sub)module has already been defined. 547 llvm::StringMap<Module *> &ModuleSpace 548 = ActiveModule? ActiveModule->SubModules : Map.Modules; 549 llvm::StringMap<Module *>::iterator ExistingModule 550 = ModuleSpace.find(ModuleName); 551 if (ExistingModule != ModuleSpace.end()) { 552 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 553 << ModuleName; 554 Diags.Report(ExistingModule->getValue()->DefinitionLoc, 555 diag::note_mmap_prev_definition); 556 557 // Skip the module definition. 558 skipUntil(MMToken::RBrace); 559 if (Tok.is(MMToken::RBrace)) 560 consumeToken(); 561 562 HadError = true; 563 return; 564 } 565 566 // Start defining this module. 567 ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 568 Explicit); 569 ModuleSpace[ModuleName] = ActiveModule; 570 571 bool Done = false; 572 do { 573 switch (Tok.Kind) { 574 case MMToken::EndOfFile: 575 case MMToken::RBrace: 576 Done = true; 577 break; 578 579 case MMToken::ExplicitKeyword: 580 case MMToken::ModuleKeyword: 581 parseModuleDecl(); 582 break; 583 584 case MMToken::ExportKeyword: 585 parseExportDecl(); 586 break; 587 588 case MMToken::HeaderKeyword: 589 parseHeaderDecl(); 590 break; 591 592 case MMToken::UmbrellaKeyword: 593 parseUmbrellaDecl(); 594 break; 595 596 default: 597 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 598 consumeToken(); 599 break; 600 } 601 } while (!Done); 602 603 if (Tok.is(MMToken::RBrace)) 604 consumeToken(); 605 else { 606 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 607 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 608 HadError = true; 609 } 610 611 // We're done parsing this module. Pop back to our parent scope. 612 ActiveModule = ActiveModule->Parent; 613 } 614 615 /// \brief Parse an umbrella header declaration. 616 /// 617 /// umbrella-declaration: 618 /// 'umbrella' string-literal 619 void ModuleMapParser::parseUmbrellaDecl() { 620 assert(Tok.is(MMToken::UmbrellaKeyword)); 621 SourceLocation UmbrellaLoc = consumeToken(); 622 623 // Parse the header name. 624 if (!Tok.is(MMToken::StringLiteral)) { 625 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 626 << "umbrella"; 627 HadError = true; 628 return; 629 } 630 StringRef FileName = Tok.getString(); 631 SourceLocation FileNameLoc = consumeToken(); 632 633 // Check whether we already have an umbrella header. 634 if (ActiveModule->UmbrellaHeader) { 635 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict) 636 << ActiveModule->getFullModuleName() 637 << ActiveModule->UmbrellaHeader->getName(); 638 HadError = true; 639 return; 640 } 641 642 // Only top-level modules can have umbrella headers. 643 if (ActiveModule->Parent) { 644 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule) 645 << ActiveModule->getFullModuleName(); 646 HadError = true; 647 return; 648 } 649 650 // Look for this file. 651 llvm::SmallString<128> PathName; 652 const FileEntry *File = 0; 653 654 if (llvm::sys::path::is_absolute(FileName)) { 655 PathName = FileName; 656 File = SourceMgr.getFileManager().getFile(PathName); 657 } else { 658 // Search for the header file within the search directory. 659 PathName += Directory->getName(); 660 unsigned PathLength = PathName.size(); 661 if (ActiveModule->isPartOfFramework()) { 662 // Check whether this file is in the public headers. 663 llvm::sys::path::append(PathName, "Headers"); 664 llvm::sys::path::append(PathName, FileName); 665 File = SourceMgr.getFileManager().getFile(PathName); 666 667 if (!File) { 668 // Check whether this file is in the private headers. 669 PathName.resize(PathLength); 670 llvm::sys::path::append(PathName, "PrivateHeaders"); 671 llvm::sys::path::append(PathName, FileName); 672 File = SourceMgr.getFileManager().getFile(PathName); 673 } 674 675 // FIXME: Deal with subframeworks. 676 } else { 677 // Lookup for normal headers. 678 llvm::sys::path::append(PathName, FileName); 679 File = SourceMgr.getFileManager().getFile(PathName); 680 } 681 } 682 683 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 684 // Come up with a lazy way to do this. 685 if (File) { 686 if (const Module *OwningModule = Map.Headers[File]) { 687 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 688 << FileName << OwningModule->getFullModuleName(); 689 HadError = true; 690 } else if ((OwningModule = Map.UmbrellaDirs[Directory])) { 691 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 692 << OwningModule->getFullModuleName(); 693 HadError = true; 694 } else { 695 // Record this umbrella header. 696 ActiveModule->UmbrellaHeader = File; 697 Map.Headers[File] = ActiveModule; 698 Map.UmbrellaDirs[Directory] = ActiveModule; 699 } 700 } else { 701 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 702 << true << FileName; 703 HadError = true; 704 } 705 } 706 707 /// \brief Parse a header declaration. 708 /// 709 /// header-declaration: 710 /// 'header' string-literal 711 void ModuleMapParser::parseHeaderDecl() { 712 assert(Tok.is(MMToken::HeaderKeyword)); 713 consumeToken(); 714 715 // Parse the header name. 716 if (!Tok.is(MMToken::StringLiteral)) { 717 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 718 << "header"; 719 HadError = true; 720 return; 721 } 722 StringRef FileName = Tok.getString(); 723 SourceLocation FileNameLoc = consumeToken(); 724 725 // Look for this file. 726 llvm::SmallString<128> PathName; 727 if (llvm::sys::path::is_relative(FileName)) { 728 // FIXME: Change this search to also look for private headers! 729 PathName += Directory->getName(); 730 731 if (ActiveModule->isPartOfFramework()) 732 llvm::sys::path::append(PathName, "Headers"); 733 } 734 735 llvm::sys::path::append(PathName, FileName); 736 737 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 738 // Come up with a lazy way to do this. 739 if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) { 740 if (const Module *OwningModule = Map.Headers[File]) { 741 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 742 << FileName << OwningModule->getFullModuleName(); 743 HadError = true; 744 } else { 745 // Record this file. 746 ActiveModule->Headers.push_back(File); 747 Map.Headers[File] = ActiveModule; 748 } 749 } else { 750 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 751 << false << FileName; 752 HadError = true; 753 } 754 } 755 756 /// \brief Parse a module export declaration. 757 /// 758 /// export-declaration: 759 /// 'export' wildcard-module-id 760 /// 761 /// wildcard-module-id: 762 /// identifier 763 /// '*' 764 /// identifier '.' wildcard-module-id 765 void ModuleMapParser::parseExportDecl() { 766 assert(Tok.is(MMToken::ExportKeyword)); 767 SourceLocation ExportLoc = consumeToken(); 768 769 // Parse the module-id with an optional wildcard at the end. 770 ModuleId ParsedModuleId; 771 bool Wildcard = false; 772 do { 773 if (Tok.is(MMToken::Identifier)) { 774 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 775 Tok.getLocation())); 776 consumeToken(); 777 778 if (Tok.is(MMToken::Period)) { 779 consumeToken(); 780 continue; 781 } 782 783 break; 784 } 785 786 if(Tok.is(MMToken::Star)) { 787 Wildcard = true; 788 consumeToken(); 789 break; 790 } 791 792 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 793 HadError = true; 794 return; 795 } while (true); 796 797 Module::UnresolvedExportDecl Unresolved = { 798 ExportLoc, ParsedModuleId, Wildcard 799 }; 800 ActiveModule->UnresolvedExports.push_back(Unresolved); 801 } 802 803 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 804 assert(Tok.is(MMToken::Star)); 805 SourceLocation StarLoc = consumeToken(); 806 bool Failed = false; 807 808 // Inferred modules must be submodules. 809 if (!ActiveModule) { 810 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 811 Failed = true; 812 } 813 814 // Inferred modules must have umbrella headers. 815 if (!Failed && !ActiveModule->getTopLevelModule()->UmbrellaHeader) { 816 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 817 Failed = true; 818 } 819 820 // Check for redefinition of an inferred module. 821 if (!Failed && ActiveModule->getTopLevelModule()->InferSubmodules) { 822 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 823 if (ActiveModule->getTopLevelModule()->InferredSubmoduleLoc.isValid()) 824 Diags.Report(ActiveModule->getTopLevelModule()->InferredSubmoduleLoc, 825 diag::note_mmap_prev_definition); 826 Failed = true; 827 } 828 829 // If there were any problems with this inferred submodule, skip its body. 830 if (Failed) { 831 if (Tok.is(MMToken::LBrace)) { 832 consumeToken(); 833 skipUntil(MMToken::RBrace); 834 if (Tok.is(MMToken::RBrace)) 835 consumeToken(); 836 } 837 HadError = true; 838 return; 839 } 840 841 // Note that we have an inferred submodule. 842 Module *TopModule = ActiveModule->getTopLevelModule(); 843 TopModule->InferSubmodules = true; 844 TopModule->InferredSubmoduleLoc = StarLoc; 845 TopModule->InferExplicitSubmodules = Explicit; 846 847 // Parse the opening brace. 848 if (!Tok.is(MMToken::LBrace)) { 849 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 850 HadError = true; 851 return; 852 } 853 SourceLocation LBraceLoc = consumeToken(); 854 855 // Parse the body of the inferred submodule. 856 bool Done = false; 857 do { 858 switch (Tok.Kind) { 859 case MMToken::EndOfFile: 860 case MMToken::RBrace: 861 Done = true; 862 break; 863 864 case MMToken::ExportKeyword: { 865 consumeToken(); 866 if (Tok.is(MMToken::Star)) 867 TopModule->InferExportWildcard = true; 868 else 869 Diags.Report(Tok.getLocation(), 870 diag::err_mmap_expected_export_wildcard); 871 consumeToken(); 872 break; 873 } 874 875 case MMToken::ExplicitKeyword: 876 case MMToken::ModuleKeyword: 877 case MMToken::HeaderKeyword: 878 case MMToken::UmbrellaKeyword: 879 default: 880 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 881 consumeToken(); 882 break; 883 } 884 } while (!Done); 885 886 if (Tok.is(MMToken::RBrace)) 887 consumeToken(); 888 else { 889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 890 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 891 HadError = true; 892 } 893 } 894 895 /// \brief Parse a module map file. 896 /// 897 /// module-map-file: 898 /// module-declaration* 899 bool ModuleMapParser::parseModuleMapFile() { 900 do { 901 switch (Tok.Kind) { 902 case MMToken::EndOfFile: 903 return HadError; 904 905 case MMToken::ModuleKeyword: 906 case MMToken::FrameworkKeyword: 907 parseModuleDecl(); 908 break; 909 910 case MMToken::ExplicitKeyword: 911 case MMToken::ExportKeyword: 912 case MMToken::HeaderKeyword: 913 case MMToken::Identifier: 914 case MMToken::LBrace: 915 case MMToken::Period: 916 case MMToken::RBrace: 917 case MMToken::Star: 918 case MMToken::StringLiteral: 919 case MMToken::UmbrellaKeyword: 920 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 921 HadError = true; 922 consumeToken(); 923 break; 924 } 925 } while (true); 926 927 return HadError; 928 } 929 930 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 931 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 932 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 933 if (!Buffer) 934 return true; 935 936 // Parse this module map file. 937 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 938 Diags->getClient()->BeginSourceFile(LangOpts); 939 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 940 bool Result = Parser.parseModuleMapFile(); 941 Diags->getClient()->EndSourceFile(); 942 943 return Result; 944 } 945