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