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