1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ModuleMap implementation, which describes the layout 11 // of a module as it relates to headers. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "clang/Lex/ModuleMap.h" 15 #include "clang/Lex/Lexer.h" 16 #include "clang/Lex/LiteralSupport.h" 17 #include "clang/Lex/LexDiagnostic.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/TargetInfo.h" 21 #include "clang/Basic/TargetOptions.h" 22 #include "llvm/Support/Allocator.h" 23 #include "llvm/Support/FileSystem.h" 24 #include "llvm/Support/Host.h" 25 #include "llvm/Support/PathV2.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include "llvm/ADT/StringRef.h" 28 #include "llvm/ADT/StringSwitch.h" 29 using namespace clang; 30 31 Module::ExportDecl 32 ModuleMap::resolveExport(Module *Mod, 33 const Module::UnresolvedExportDecl &Unresolved, 34 bool Complain) { 35 // We may have just a wildcard. 36 if (Unresolved.Id.empty()) { 37 assert(Unresolved.Wildcard && "Invalid unresolved export"); 38 return Module::ExportDecl(0, true); 39 } 40 41 // Find the starting module. 42 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 43 if (!Context) { 44 if (Complain) 45 Diags->Report(Unresolved.Id[0].second, 46 diag::err_mmap_missing_module_unqualified) 47 << Unresolved.Id[0].first << Mod->getFullModuleName(); 48 49 return Module::ExportDecl(); 50 } 51 52 // Dig into the module path. 53 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 54 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 55 Context); 56 if (!Sub) { 57 if (Complain) 58 Diags->Report(Unresolved.Id[I].second, 59 diag::err_mmap_missing_module_qualified) 60 << Unresolved.Id[I].first << Context->getFullModuleName() 61 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 62 63 return Module::ExportDecl(); 64 } 65 66 Context = Sub; 67 } 68 69 return Module::ExportDecl(Context, Unresolved.Wildcard); 70 } 71 72 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, 73 const LangOptions &LangOpts, const TargetInfo *Target) 74 : LangOpts(LangOpts), Target(Target) 75 { 76 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 77 Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 78 new DiagnosticsEngine(DiagIDs)); 79 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 80 SourceMgr = new SourceManager(*Diags, FileMgr); 81 } 82 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 93 void ModuleMap::setTarget(const TargetInfo &Target) { 94 assert((!this->Target || this->Target == &Target) && 95 "Improper target override"); 96 this->Target = &Target; 97 } 98 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 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 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 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 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> 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 * 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 llvm::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 llvm::SmallString<128> SubframeworksDirName 336 = StringRef(FrameworkDir->getName()); 337 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 338 llvm::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 358 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 359 Headers[UmbrellaHeader] = Mod; 360 Mod->Umbrella = UmbrellaHeader; 361 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 362 } 363 364 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 365 Mod->Umbrella = UmbrellaDir; 366 UmbrellaDirs[UmbrellaDir] = Mod; 367 } 368 369 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) { 370 Mod->Headers.push_back(Header); 371 Headers[Header] = Mod; 372 } 373 374 const FileEntry * 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 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 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 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 476 void clear() { 477 Kind = EndOfFile; 478 Location = 0; 479 StringLength = 0; 480 StringData = 0; 481 } 482 483 bool is(TokenKind K) const { return Kind == K; } 484 485 SourceLocation getLocation() const { 486 return SourceLocation::getFromRawEncoding(Location); 487 } 488 489 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 ⤅ 499 500 /// \brief The directory that this module map resides in. 501 const DirectoryEntry *Directory; 502 503 /// \brief Whether an error occurred. 504 bool HadError; 505 506 /// \brief Default target information, used only for string literal 507 /// parsing. 508 TargetInfo *Target; 509 510 /// \brief Stores string data for the various string literals referenced 511 /// during parsing. 512 llvm::BumpPtrAllocator StringData; 513 514 /// \brief The current token. 515 MMToken Tok; 516 517 /// \brief The active module. 518 Module *ActiveModule; 519 520 /// \brief Consume the current token and return its location. 521 SourceLocation consumeToken(); 522 523 /// \brief Skip tokens until we reach the a token with the given kind 524 /// (or the end of the file). 525 void skipUntil(MMToken::TokenKind K); 526 527 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 528 ModuleId; 529 bool parseModuleId(ModuleId &Id); 530 void parseModuleDecl(); 531 void parseRequiresDecl(); 532 void parseHeaderDecl(SourceLocation UmbrellaLoc); 533 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 534 void parseExportDecl(); 535 void parseInferredSubmoduleDecl(bool Explicit); 536 537 const DirectoryEntry *getOverriddenHeaderSearchDir(); 538 539 public: 540 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 541 DiagnosticsEngine &Diags, 542 ModuleMap &Map, 543 const DirectoryEntry *Directory) 544 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 545 Directory(Directory), HadError(false), ActiveModule(0) 546 { 547 TargetOptions TargetOpts; 548 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 549 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 550 551 Tok.clear(); 552 consumeToken(); 553 } 554 555 bool parseModuleMapFile(); 556 }; 557 } 558 559 SourceLocation ModuleMapParser::consumeToken() { 560 retry: 561 SourceLocation Result = Tok.getLocation(); 562 Tok.clear(); 563 564 Token LToken; 565 L.LexFromRawLexer(LToken); 566 Tok.Location = LToken.getLocation().getRawEncoding(); 567 switch (LToken.getKind()) { 568 case tok::raw_identifier: 569 Tok.StringData = LToken.getRawIdentifierData(); 570 Tok.StringLength = LToken.getLength(); 571 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 572 .Case("header", MMToken::HeaderKeyword) 573 .Case("explicit", MMToken::ExplicitKeyword) 574 .Case("export", MMToken::ExportKeyword) 575 .Case("framework", MMToken::FrameworkKeyword) 576 .Case("module", MMToken::ModuleKeyword) 577 .Case("requires", MMToken::RequiresKeyword) 578 .Case("umbrella", MMToken::UmbrellaKeyword) 579 .Default(MMToken::Identifier); 580 break; 581 582 case tok::comma: 583 Tok.Kind = MMToken::Comma; 584 break; 585 586 case tok::eof: 587 Tok.Kind = MMToken::EndOfFile; 588 break; 589 590 case tok::l_brace: 591 Tok.Kind = MMToken::LBrace; 592 break; 593 594 case tok::l_square: 595 Tok.Kind = MMToken::LSquare; 596 break; 597 598 case tok::period: 599 Tok.Kind = MMToken::Period; 600 break; 601 602 case tok::r_brace: 603 Tok.Kind = MMToken::RBrace; 604 break; 605 606 case tok::r_square: 607 Tok.Kind = MMToken::RSquare; 608 break; 609 610 case tok::star: 611 Tok.Kind = MMToken::Star; 612 break; 613 614 case tok::string_literal: { 615 // Parse the string literal. 616 LangOptions LangOpts; 617 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 618 if (StringLiteral.hadError) 619 goto retry; 620 621 // Copy the string literal into our string data allocator. 622 unsigned Length = StringLiteral.GetStringLength(); 623 char *Saved = StringData.Allocate<char>(Length + 1); 624 memcpy(Saved, StringLiteral.GetString().data(), Length); 625 Saved[Length] = 0; 626 627 // Form the token. 628 Tok.Kind = MMToken::StringLiteral; 629 Tok.StringData = Saved; 630 Tok.StringLength = Length; 631 break; 632 } 633 634 case tok::comment: 635 goto retry; 636 637 default: 638 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 639 HadError = true; 640 goto retry; 641 } 642 643 return Result; 644 } 645 646 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 647 unsigned braceDepth = 0; 648 unsigned squareDepth = 0; 649 do { 650 switch (Tok.Kind) { 651 case MMToken::EndOfFile: 652 return; 653 654 case MMToken::LBrace: 655 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 656 return; 657 658 ++braceDepth; 659 break; 660 661 case MMToken::LSquare: 662 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 663 return; 664 665 ++squareDepth; 666 break; 667 668 case MMToken::RBrace: 669 if (braceDepth > 0) 670 --braceDepth; 671 else if (Tok.is(K)) 672 return; 673 break; 674 675 case MMToken::RSquare: 676 if (squareDepth > 0) 677 --squareDepth; 678 else if (Tok.is(K)) 679 return; 680 break; 681 682 default: 683 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 684 return; 685 break; 686 } 687 688 consumeToken(); 689 } while (true); 690 } 691 692 /// \brief Parse a module-id. 693 /// 694 /// module-id: 695 /// identifier 696 /// identifier '.' module-id 697 /// 698 /// \returns true if an error occurred, false otherwise. 699 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 700 Id.clear(); 701 do { 702 if (Tok.is(MMToken::Identifier)) { 703 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 704 consumeToken(); 705 } else { 706 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 707 return true; 708 } 709 710 if (!Tok.is(MMToken::Period)) 711 break; 712 713 consumeToken(); 714 } while (true); 715 716 return false; 717 } 718 719 namespace { 720 /// \brief Enumerates the known attributes. 721 enum AttributeKind { 722 /// \brief An unknown attribute. 723 AT_unknown, 724 /// \brief The 'system' attribute. 725 AT_system 726 }; 727 } 728 729 /// \brief Parse a module declaration. 730 /// 731 /// module-declaration: 732 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 733 /// { module-member* } 734 /// 735 /// attributes: 736 /// attribute attributes 737 /// attribute 738 /// 739 /// attribute: 740 /// [ identifier ] 741 /// 742 /// module-member: 743 /// requires-declaration 744 /// header-declaration 745 /// submodule-declaration 746 /// export-declaration 747 /// 748 /// submodule-declaration: 749 /// module-declaration 750 /// inferred-submodule-declaration 751 void ModuleMapParser::parseModuleDecl() { 752 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 753 Tok.is(MMToken::FrameworkKeyword)); 754 // Parse 'explicit' or 'framework' keyword, if present. 755 SourceLocation ExplicitLoc; 756 bool Explicit = false; 757 bool Framework = false; 758 759 // Parse 'explicit' keyword, if present. 760 if (Tok.is(MMToken::ExplicitKeyword)) { 761 ExplicitLoc = consumeToken(); 762 Explicit = true; 763 } 764 765 // Parse 'framework' keyword, if present. 766 if (Tok.is(MMToken::FrameworkKeyword)) { 767 consumeToken(); 768 Framework = true; 769 } 770 771 // Parse 'module' keyword. 772 if (!Tok.is(MMToken::ModuleKeyword)) { 773 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 774 consumeToken(); 775 HadError = true; 776 return; 777 } 778 consumeToken(); // 'module' keyword 779 780 // If we have a wildcard for the module name, this is an inferred submodule. 781 // Parse it. 782 if (Tok.is(MMToken::Star)) 783 return parseInferredSubmoduleDecl(Explicit); 784 785 // Parse the module name. 786 ModuleId Id; 787 if (parseModuleId(Id)) { 788 HadError = true; 789 return; 790 } 791 792 if (ActiveModule) { 793 if (Id.size() > 1) { 794 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 795 << SourceRange(Id.front().second, Id.back().second); 796 797 HadError = true; 798 return; 799 } 800 } else if (Id.size() == 1 && Explicit) { 801 // Top-level modules can't be explicit. 802 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 803 Explicit = false; 804 ExplicitLoc = SourceLocation(); 805 HadError = true; 806 } 807 808 Module *PreviousActiveModule = ActiveModule; 809 if (Id.size() > 1) { 810 // This module map defines a submodule. Go find the module of which it 811 // is a submodule. 812 ActiveModule = 0; 813 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 814 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 815 ActiveModule = Next; 816 continue; 817 } 818 819 if (ActiveModule) { 820 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 821 << Id[I].first << ActiveModule->getTopLevelModule(); 822 } else { 823 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 824 } 825 HadError = true; 826 return; 827 } 828 } 829 830 StringRef ModuleName = Id.back().first; 831 SourceLocation ModuleNameLoc = Id.back().second; 832 833 // Parse the optional attribute list. 834 bool IsSystem = false; 835 while (Tok.is(MMToken::LSquare)) { 836 // Consume the '['. 837 SourceLocation LSquareLoc = consumeToken(); 838 839 // Check whether we have an attribute name here. 840 if (!Tok.is(MMToken::Identifier)) { 841 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 842 skipUntil(MMToken::RSquare); 843 if (Tok.is(MMToken::RSquare)) 844 consumeToken(); 845 continue; 846 } 847 848 // Decode the attribute name. 849 AttributeKind Attribute 850 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 851 .Case("system", AT_system) 852 .Default(AT_unknown); 853 switch (Attribute) { 854 case AT_unknown: 855 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 856 << Tok.getString(); 857 break; 858 859 case AT_system: 860 IsSystem = true; 861 break; 862 } 863 consumeToken(); 864 865 // Consume the ']'. 866 if (!Tok.is(MMToken::RSquare)) { 867 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 868 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 869 skipUntil(MMToken::RSquare); 870 } 871 872 if (Tok.is(MMToken::RSquare)) 873 consumeToken(); 874 } 875 876 // Parse the opening brace. 877 if (!Tok.is(MMToken::LBrace)) { 878 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 879 << ModuleName; 880 HadError = true; 881 return; 882 } 883 SourceLocation LBraceLoc = consumeToken(); 884 885 // Determine whether this (sub)module has already been defined. 886 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 887 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 888 // Skip the module definition. 889 skipUntil(MMToken::RBrace); 890 if (Tok.is(MMToken::RBrace)) 891 consumeToken(); 892 else { 893 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 894 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 895 HadError = true; 896 } 897 return; 898 } 899 900 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 901 << ModuleName; 902 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 903 904 // Skip the module definition. 905 skipUntil(MMToken::RBrace); 906 if (Tok.is(MMToken::RBrace)) 907 consumeToken(); 908 909 HadError = true; 910 return; 911 } 912 913 // Start defining this module. 914 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 915 Explicit).first; 916 ActiveModule->DefinitionLoc = ModuleNameLoc; 917 if (IsSystem) 918 ActiveModule->IsSystem = true; 919 920 bool Done = false; 921 do { 922 switch (Tok.Kind) { 923 case MMToken::EndOfFile: 924 case MMToken::RBrace: 925 Done = true; 926 break; 927 928 case MMToken::ExplicitKeyword: 929 case MMToken::FrameworkKeyword: 930 case MMToken::ModuleKeyword: 931 parseModuleDecl(); 932 break; 933 934 case MMToken::ExportKeyword: 935 parseExportDecl(); 936 break; 937 938 case MMToken::RequiresKeyword: 939 parseRequiresDecl(); 940 break; 941 942 case MMToken::UmbrellaKeyword: { 943 SourceLocation UmbrellaLoc = consumeToken(); 944 if (Tok.is(MMToken::HeaderKeyword)) 945 parseHeaderDecl(UmbrellaLoc); 946 else 947 parseUmbrellaDirDecl(UmbrellaLoc); 948 break; 949 } 950 951 case MMToken::HeaderKeyword: 952 parseHeaderDecl(SourceLocation()); 953 break; 954 955 default: 956 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 957 consumeToken(); 958 break; 959 } 960 } while (!Done); 961 962 if (Tok.is(MMToken::RBrace)) 963 consumeToken(); 964 else { 965 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 966 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 967 HadError = true; 968 } 969 970 // We're done parsing this module. Pop back to the previous module. 971 ActiveModule = PreviousActiveModule; 972 } 973 974 /// \brief Parse a requires declaration. 975 /// 976 /// requires-declaration: 977 /// 'requires' feature-list 978 /// 979 /// feature-list: 980 /// identifier ',' feature-list 981 /// identifier 982 void ModuleMapParser::parseRequiresDecl() { 983 assert(Tok.is(MMToken::RequiresKeyword)); 984 985 // Parse 'requires' keyword. 986 consumeToken(); 987 988 // Parse the feature-list. 989 do { 990 if (!Tok.is(MMToken::Identifier)) { 991 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 992 HadError = true; 993 return; 994 } 995 996 // Consume the feature name. 997 std::string Feature = Tok.getString(); 998 consumeToken(); 999 1000 // Add this feature. 1001 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 1002 1003 if (!Tok.is(MMToken::Comma)) 1004 break; 1005 1006 // Consume the comma. 1007 consumeToken(); 1008 } while (true); 1009 } 1010 1011 /// \brief Append to \p Paths the set of paths needed to get to the 1012 /// subframework in which the given module lives. 1013 void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) { 1014 // Collect the framework names from the given module to the top-level module. 1015 llvm::SmallVector<StringRef, 2> Paths; 1016 for (; Mod; Mod = Mod->Parent) { 1017 if (Mod->IsFramework) 1018 Paths.push_back(Mod->Name); 1019 } 1020 1021 if (Paths.empty()) 1022 return; 1023 1024 // Add Frameworks/Name.framework for each subframework. 1025 for (unsigned I = Paths.size() - 1; I != 0; --I) { 1026 llvm::sys::path::append(Path, "Frameworks"); 1027 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 1028 } 1029 } 1030 1031 /// \brief Parse a header declaration. 1032 /// 1033 /// header-declaration: 1034 /// 'umbrella'[opt] 'header' string-literal 1035 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) { 1036 assert(Tok.is(MMToken::HeaderKeyword)); 1037 consumeToken(); 1038 1039 bool Umbrella = UmbrellaLoc.isValid(); 1040 1041 // Parse the header name. 1042 if (!Tok.is(MMToken::StringLiteral)) { 1043 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1044 << "header"; 1045 HadError = true; 1046 return; 1047 } 1048 std::string FileName = Tok.getString(); 1049 SourceLocation FileNameLoc = consumeToken(); 1050 1051 // Check whether we already have an umbrella. 1052 if (Umbrella && ActiveModule->Umbrella) { 1053 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1054 << ActiveModule->getFullModuleName(); 1055 HadError = true; 1056 return; 1057 } 1058 1059 // Look for this file. 1060 const FileEntry *File = 0; 1061 llvm::SmallString<128> PathName; 1062 if (llvm::sys::path::is_absolute(FileName)) { 1063 PathName = FileName; 1064 File = SourceMgr.getFileManager().getFile(PathName); 1065 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1066 PathName = Dir->getName(); 1067 llvm::sys::path::append(PathName, FileName); 1068 File = SourceMgr.getFileManager().getFile(PathName); 1069 } else { 1070 // Search for the header file within the search directory. 1071 PathName = Directory->getName(); 1072 unsigned PathLength = PathName.size(); 1073 1074 if (ActiveModule->isPartOfFramework()) { 1075 appendSubframeworkPaths(ActiveModule, PathName); 1076 1077 // Check whether this file is in the public headers. 1078 llvm::sys::path::append(PathName, "Headers"); 1079 llvm::sys::path::append(PathName, FileName); 1080 File = SourceMgr.getFileManager().getFile(PathName); 1081 1082 if (!File) { 1083 // Check whether this file is in the private headers. 1084 PathName.resize(PathLength); 1085 llvm::sys::path::append(PathName, "PrivateHeaders"); 1086 llvm::sys::path::append(PathName, FileName); 1087 File = SourceMgr.getFileManager().getFile(PathName); 1088 } 1089 } else { 1090 // Lookup for normal headers. 1091 llvm::sys::path::append(PathName, FileName); 1092 File = SourceMgr.getFileManager().getFile(PathName); 1093 } 1094 } 1095 1096 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1097 // Come up with a lazy way to do this. 1098 if (File) { 1099 if (const Module *OwningModule = Map.Headers[File]) { 1100 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1101 << FileName << OwningModule->getFullModuleName(); 1102 HadError = true; 1103 } else if (Umbrella) { 1104 const DirectoryEntry *UmbrellaDir = File->getDir(); 1105 if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 1106 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1107 << OwningModule->getFullModuleName(); 1108 HadError = true; 1109 } else { 1110 // Record this umbrella header. 1111 Map.setUmbrellaHeader(ActiveModule, File); 1112 } 1113 } else { 1114 // Record this header. 1115 Map.addHeader(ActiveModule, File); 1116 } 1117 } else { 1118 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1119 << Umbrella << FileName; 1120 HadError = true; 1121 } 1122 } 1123 1124 /// \brief Parse an umbrella directory declaration. 1125 /// 1126 /// umbrella-dir-declaration: 1127 /// umbrella string-literal 1128 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1129 // Parse the directory name. 1130 if (!Tok.is(MMToken::StringLiteral)) { 1131 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1132 << "umbrella"; 1133 HadError = true; 1134 return; 1135 } 1136 1137 std::string DirName = Tok.getString(); 1138 SourceLocation DirNameLoc = consumeToken(); 1139 1140 // Check whether we already have an umbrella. 1141 if (ActiveModule->Umbrella) { 1142 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1143 << ActiveModule->getFullModuleName(); 1144 HadError = true; 1145 return; 1146 } 1147 1148 // Look for this file. 1149 const DirectoryEntry *Dir = 0; 1150 if (llvm::sys::path::is_absolute(DirName)) 1151 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1152 else { 1153 llvm::SmallString<128> PathName; 1154 PathName = Directory->getName(); 1155 llvm::sys::path::append(PathName, DirName); 1156 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1157 } 1158 1159 if (!Dir) { 1160 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1161 << DirName; 1162 HadError = true; 1163 return; 1164 } 1165 1166 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1167 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1168 << OwningModule->getFullModuleName(); 1169 HadError = true; 1170 return; 1171 } 1172 1173 // Record this umbrella directory. 1174 Map.setUmbrellaDir(ActiveModule, Dir); 1175 } 1176 1177 /// \brief Parse a module export declaration. 1178 /// 1179 /// export-declaration: 1180 /// 'export' wildcard-module-id 1181 /// 1182 /// wildcard-module-id: 1183 /// identifier 1184 /// '*' 1185 /// identifier '.' wildcard-module-id 1186 void ModuleMapParser::parseExportDecl() { 1187 assert(Tok.is(MMToken::ExportKeyword)); 1188 SourceLocation ExportLoc = consumeToken(); 1189 1190 // Parse the module-id with an optional wildcard at the end. 1191 ModuleId ParsedModuleId; 1192 bool Wildcard = false; 1193 do { 1194 if (Tok.is(MMToken::Identifier)) { 1195 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1196 Tok.getLocation())); 1197 consumeToken(); 1198 1199 if (Tok.is(MMToken::Period)) { 1200 consumeToken(); 1201 continue; 1202 } 1203 1204 break; 1205 } 1206 1207 if(Tok.is(MMToken::Star)) { 1208 Wildcard = true; 1209 consumeToken(); 1210 break; 1211 } 1212 1213 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1214 HadError = true; 1215 return; 1216 } while (true); 1217 1218 Module::UnresolvedExportDecl Unresolved = { 1219 ExportLoc, ParsedModuleId, Wildcard 1220 }; 1221 ActiveModule->UnresolvedExports.push_back(Unresolved); 1222 } 1223 1224 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 1225 assert(Tok.is(MMToken::Star)); 1226 SourceLocation StarLoc = consumeToken(); 1227 bool Failed = false; 1228 1229 // Inferred modules must be submodules. 1230 if (!ActiveModule) { 1231 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1232 Failed = true; 1233 } 1234 1235 // Inferred modules must have umbrella directories. 1236 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1237 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1238 Failed = true; 1239 } 1240 1241 // Check for redefinition of an inferred module. 1242 if (!Failed && ActiveModule->InferSubmodules) { 1243 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1244 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1245 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1246 diag::note_mmap_prev_definition); 1247 Failed = true; 1248 } 1249 1250 // If there were any problems with this inferred submodule, skip its body. 1251 if (Failed) { 1252 if (Tok.is(MMToken::LBrace)) { 1253 consumeToken(); 1254 skipUntil(MMToken::RBrace); 1255 if (Tok.is(MMToken::RBrace)) 1256 consumeToken(); 1257 } 1258 HadError = true; 1259 return; 1260 } 1261 1262 // Note that we have an inferred submodule. 1263 ActiveModule->InferSubmodules = true; 1264 ActiveModule->InferredSubmoduleLoc = StarLoc; 1265 ActiveModule->InferExplicitSubmodules = Explicit; 1266 1267 // Parse the opening brace. 1268 if (!Tok.is(MMToken::LBrace)) { 1269 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1270 HadError = true; 1271 return; 1272 } 1273 SourceLocation LBraceLoc = consumeToken(); 1274 1275 // Parse the body of the inferred submodule. 1276 bool Done = false; 1277 do { 1278 switch (Tok.Kind) { 1279 case MMToken::EndOfFile: 1280 case MMToken::RBrace: 1281 Done = true; 1282 break; 1283 1284 case MMToken::ExportKeyword: { 1285 consumeToken(); 1286 if (Tok.is(MMToken::Star)) 1287 ActiveModule->InferExportWildcard = true; 1288 else 1289 Diags.Report(Tok.getLocation(), 1290 diag::err_mmap_expected_export_wildcard); 1291 consumeToken(); 1292 break; 1293 } 1294 1295 case MMToken::ExplicitKeyword: 1296 case MMToken::ModuleKeyword: 1297 case MMToken::HeaderKeyword: 1298 case MMToken::UmbrellaKeyword: 1299 default: 1300 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 1301 consumeToken(); 1302 break; 1303 } 1304 } while (!Done); 1305 1306 if (Tok.is(MMToken::RBrace)) 1307 consumeToken(); 1308 else { 1309 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1310 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1311 HadError = true; 1312 } 1313 } 1314 1315 /// \brief If there is a specific header search directory due the presence 1316 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1317 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1318 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1319 // If we have an umbrella directory, use that. 1320 if (Mod->hasUmbrellaDir()) 1321 return Mod->getUmbrellaDir(); 1322 1323 // If we have a framework directory, stop looking. 1324 if (Mod->IsFramework) 1325 return 0; 1326 } 1327 1328 return 0; 1329 } 1330 1331 /// \brief Parse a module map file. 1332 /// 1333 /// module-map-file: 1334 /// module-declaration* 1335 bool ModuleMapParser::parseModuleMapFile() { 1336 do { 1337 switch (Tok.Kind) { 1338 case MMToken::EndOfFile: 1339 return HadError; 1340 1341 case MMToken::ExplicitKeyword: 1342 case MMToken::ModuleKeyword: 1343 case MMToken::FrameworkKeyword: 1344 parseModuleDecl(); 1345 break; 1346 1347 case MMToken::Comma: 1348 case MMToken::ExportKeyword: 1349 case MMToken::HeaderKeyword: 1350 case MMToken::Identifier: 1351 case MMToken::LBrace: 1352 case MMToken::LSquare: 1353 case MMToken::Period: 1354 case MMToken::RBrace: 1355 case MMToken::RSquare: 1356 case MMToken::RequiresKeyword: 1357 case MMToken::Star: 1358 case MMToken::StringLiteral: 1359 case MMToken::UmbrellaKeyword: 1360 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1361 HadError = true; 1362 consumeToken(); 1363 break; 1364 } 1365 } while (true); 1366 } 1367 1368 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1369 assert(Target != 0 && "Missing target information"); 1370 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1371 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1372 if (!Buffer) 1373 return true; 1374 1375 // Parse this module map file. 1376 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1377 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1378 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 1379 bool Result = Parser.parseModuleMapFile(); 1380 Diags->getClient()->EndSourceFile(); 1381 1382 return Result; 1383 } 1384