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