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