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 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 794 // Skip the module definition. 795 skipUntil(MMToken::RBrace); 796 if (Tok.is(MMToken::RBrace)) 797 consumeToken(); 798 else { 799 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 800 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 801 HadError = true; 802 } 803 return; 804 } 805 806 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 807 << ModuleName; 808 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 809 810 // Skip the module definition. 811 skipUntil(MMToken::RBrace); 812 if (Tok.is(MMToken::RBrace)) 813 consumeToken(); 814 815 HadError = true; 816 return; 817 } 818 819 // Start defining this module. 820 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 821 Explicit).first; 822 ActiveModule->DefinitionLoc = ModuleNameLoc; 823 824 bool Done = false; 825 do { 826 switch (Tok.Kind) { 827 case MMToken::EndOfFile: 828 case MMToken::RBrace: 829 Done = true; 830 break; 831 832 case MMToken::ExplicitKeyword: 833 case MMToken::FrameworkKeyword: 834 case MMToken::ModuleKeyword: 835 parseModuleDecl(); 836 break; 837 838 case MMToken::ExportKeyword: 839 parseExportDecl(); 840 break; 841 842 case MMToken::RequiresKeyword: 843 parseRequiresDecl(); 844 break; 845 846 case MMToken::UmbrellaKeyword: { 847 SourceLocation UmbrellaLoc = consumeToken(); 848 if (Tok.is(MMToken::HeaderKeyword)) 849 parseHeaderDecl(UmbrellaLoc); 850 else 851 parseUmbrellaDirDecl(UmbrellaLoc); 852 break; 853 } 854 855 case MMToken::HeaderKeyword: 856 parseHeaderDecl(SourceLocation()); 857 break; 858 859 default: 860 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 861 consumeToken(); 862 break; 863 } 864 } while (!Done); 865 866 if (Tok.is(MMToken::RBrace)) 867 consumeToken(); 868 else { 869 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 870 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 871 HadError = true; 872 } 873 874 // We're done parsing this module. Pop back to the previous module. 875 ActiveModule = PreviousActiveModule; 876 } 877 878 /// \brief Parse a requires declaration. 879 /// 880 /// requires-declaration: 881 /// 'requires' feature-list 882 /// 883 /// feature-list: 884 /// identifier ',' feature-list 885 /// identifier 886 void ModuleMapParser::parseRequiresDecl() { 887 assert(Tok.is(MMToken::RequiresKeyword)); 888 889 // Parse 'requires' keyword. 890 consumeToken(); 891 892 // Parse the feature-list. 893 do { 894 if (!Tok.is(MMToken::Identifier)) { 895 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 896 HadError = true; 897 return; 898 } 899 900 // Consume the feature name. 901 std::string Feature = Tok.getString(); 902 consumeToken(); 903 904 // Add this feature. 905 ActiveModule->addRequirement(Feature, Map.LangOpts); 906 907 if (!Tok.is(MMToken::Comma)) 908 break; 909 910 // Consume the comma. 911 consumeToken(); 912 } while (true); 913 } 914 915 /// \brief Append to \p Paths the set of paths needed to get to the 916 /// subframework in which the given module lives. 917 void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) { 918 // Collect the framework names from the given module to the top-level module. 919 llvm::SmallVector<StringRef, 2> Paths; 920 for (; Mod; Mod = Mod->Parent) { 921 if (Mod->IsFramework) 922 Paths.push_back(Mod->Name); 923 } 924 925 if (Paths.empty()) 926 return; 927 928 // Add Frameworks/Name.framework for each subframework. 929 for (unsigned I = Paths.size() - 1; I != 0; --I) { 930 llvm::sys::path::append(Path, "Frameworks"); 931 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 932 } 933 } 934 935 /// \brief Parse a header declaration. 936 /// 937 /// header-declaration: 938 /// 'umbrella'[opt] 'header' string-literal 939 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) { 940 assert(Tok.is(MMToken::HeaderKeyword)); 941 consumeToken(); 942 943 bool Umbrella = UmbrellaLoc.isValid(); 944 945 // Parse the header name. 946 if (!Tok.is(MMToken::StringLiteral)) { 947 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 948 << "header"; 949 HadError = true; 950 return; 951 } 952 std::string FileName = Tok.getString(); 953 SourceLocation FileNameLoc = consumeToken(); 954 955 // Check whether we already have an umbrella. 956 if (Umbrella && ActiveModule->Umbrella) { 957 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 958 << ActiveModule->getFullModuleName(); 959 HadError = true; 960 return; 961 } 962 963 // Look for this file. 964 const FileEntry *File = 0; 965 llvm::SmallString<128> PathName; 966 if (llvm::sys::path::is_absolute(FileName)) { 967 PathName = FileName; 968 File = SourceMgr.getFileManager().getFile(PathName); 969 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 970 PathName = Dir->getName(); 971 llvm::sys::path::append(PathName, FileName); 972 File = SourceMgr.getFileManager().getFile(PathName); 973 } else { 974 // Search for the header file within the search directory. 975 PathName = Directory->getName(); 976 unsigned PathLength = PathName.size(); 977 978 if (ActiveModule->isPartOfFramework()) { 979 appendSubframeworkPaths(ActiveModule, PathName); 980 981 // Check whether this file is in the public headers. 982 llvm::sys::path::append(PathName, "Headers"); 983 llvm::sys::path::append(PathName, FileName); 984 File = SourceMgr.getFileManager().getFile(PathName); 985 986 if (!File) { 987 // Check whether this file is in the private headers. 988 PathName.resize(PathLength); 989 llvm::sys::path::append(PathName, "PrivateHeaders"); 990 llvm::sys::path::append(PathName, FileName); 991 File = SourceMgr.getFileManager().getFile(PathName); 992 } 993 } else { 994 // Lookup for normal headers. 995 llvm::sys::path::append(PathName, FileName); 996 File = SourceMgr.getFileManager().getFile(PathName); 997 } 998 } 999 1000 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1001 // Come up with a lazy way to do this. 1002 if (File) { 1003 if (const Module *OwningModule = Map.Headers[File]) { 1004 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1005 << FileName << OwningModule->getFullModuleName(); 1006 HadError = true; 1007 } else if (Umbrella) { 1008 const DirectoryEntry *UmbrellaDir = File->getDir(); 1009 if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 1010 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1011 << OwningModule->getFullModuleName(); 1012 HadError = true; 1013 } else { 1014 // Record this umbrella header. 1015 Map.setUmbrellaHeader(ActiveModule, File); 1016 } 1017 } else { 1018 // Record this header. 1019 Map.addHeader(ActiveModule, File); 1020 } 1021 } else { 1022 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1023 << Umbrella << FileName; 1024 HadError = true; 1025 } 1026 } 1027 1028 /// \brief Parse an umbrella directory declaration. 1029 /// 1030 /// umbrella-dir-declaration: 1031 /// umbrella string-literal 1032 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1033 // Parse the directory name. 1034 if (!Tok.is(MMToken::StringLiteral)) { 1035 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1036 << "umbrella"; 1037 HadError = true; 1038 return; 1039 } 1040 1041 std::string DirName = Tok.getString(); 1042 SourceLocation DirNameLoc = consumeToken(); 1043 1044 // Check whether we already have an umbrella. 1045 if (ActiveModule->Umbrella) { 1046 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1047 << ActiveModule->getFullModuleName(); 1048 HadError = true; 1049 return; 1050 } 1051 1052 // Look for this file. 1053 const DirectoryEntry *Dir = 0; 1054 if (llvm::sys::path::is_absolute(DirName)) 1055 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1056 else { 1057 llvm::SmallString<128> PathName; 1058 PathName = Directory->getName(); 1059 llvm::sys::path::append(PathName, DirName); 1060 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1061 } 1062 1063 if (!Dir) { 1064 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1065 << DirName; 1066 HadError = true; 1067 return; 1068 } 1069 1070 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1071 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1072 << OwningModule->getFullModuleName(); 1073 HadError = true; 1074 return; 1075 } 1076 1077 // Record this umbrella directory. 1078 Map.setUmbrellaDir(ActiveModule, Dir); 1079 } 1080 1081 /// \brief Parse a module export declaration. 1082 /// 1083 /// export-declaration: 1084 /// 'export' wildcard-module-id 1085 /// 1086 /// wildcard-module-id: 1087 /// identifier 1088 /// '*' 1089 /// identifier '.' wildcard-module-id 1090 void ModuleMapParser::parseExportDecl() { 1091 assert(Tok.is(MMToken::ExportKeyword)); 1092 SourceLocation ExportLoc = consumeToken(); 1093 1094 // Parse the module-id with an optional wildcard at the end. 1095 ModuleId ParsedModuleId; 1096 bool Wildcard = false; 1097 do { 1098 if (Tok.is(MMToken::Identifier)) { 1099 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1100 Tok.getLocation())); 1101 consumeToken(); 1102 1103 if (Tok.is(MMToken::Period)) { 1104 consumeToken(); 1105 continue; 1106 } 1107 1108 break; 1109 } 1110 1111 if(Tok.is(MMToken::Star)) { 1112 Wildcard = true; 1113 consumeToken(); 1114 break; 1115 } 1116 1117 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1118 HadError = true; 1119 return; 1120 } while (true); 1121 1122 Module::UnresolvedExportDecl Unresolved = { 1123 ExportLoc, ParsedModuleId, Wildcard 1124 }; 1125 ActiveModule->UnresolvedExports.push_back(Unresolved); 1126 } 1127 1128 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 1129 assert(Tok.is(MMToken::Star)); 1130 SourceLocation StarLoc = consumeToken(); 1131 bool Failed = false; 1132 1133 // Inferred modules must be submodules. 1134 if (!ActiveModule) { 1135 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1136 Failed = true; 1137 } 1138 1139 // Inferred modules must have umbrella directories. 1140 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1141 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1142 Failed = true; 1143 } 1144 1145 // Check for redefinition of an inferred module. 1146 if (!Failed && ActiveModule->InferSubmodules) { 1147 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1148 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1149 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1150 diag::note_mmap_prev_definition); 1151 Failed = true; 1152 } 1153 1154 // If there were any problems with this inferred submodule, skip its body. 1155 if (Failed) { 1156 if (Tok.is(MMToken::LBrace)) { 1157 consumeToken(); 1158 skipUntil(MMToken::RBrace); 1159 if (Tok.is(MMToken::RBrace)) 1160 consumeToken(); 1161 } 1162 HadError = true; 1163 return; 1164 } 1165 1166 // Note that we have an inferred submodule. 1167 ActiveModule->InferSubmodules = true; 1168 ActiveModule->InferredSubmoduleLoc = StarLoc; 1169 ActiveModule->InferExplicitSubmodules = Explicit; 1170 1171 // Parse the opening brace. 1172 if (!Tok.is(MMToken::LBrace)) { 1173 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1174 HadError = true; 1175 return; 1176 } 1177 SourceLocation LBraceLoc = consumeToken(); 1178 1179 // Parse the body of the inferred submodule. 1180 bool Done = false; 1181 do { 1182 switch (Tok.Kind) { 1183 case MMToken::EndOfFile: 1184 case MMToken::RBrace: 1185 Done = true; 1186 break; 1187 1188 case MMToken::ExportKeyword: { 1189 consumeToken(); 1190 if (Tok.is(MMToken::Star)) 1191 ActiveModule->InferExportWildcard = true; 1192 else 1193 Diags.Report(Tok.getLocation(), 1194 diag::err_mmap_expected_export_wildcard); 1195 consumeToken(); 1196 break; 1197 } 1198 1199 case MMToken::ExplicitKeyword: 1200 case MMToken::ModuleKeyword: 1201 case MMToken::HeaderKeyword: 1202 case MMToken::UmbrellaKeyword: 1203 default: 1204 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 1205 consumeToken(); 1206 break; 1207 } 1208 } while (!Done); 1209 1210 if (Tok.is(MMToken::RBrace)) 1211 consumeToken(); 1212 else { 1213 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1214 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1215 HadError = true; 1216 } 1217 } 1218 1219 /// \brief If there is a specific header search directory due the presence 1220 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1221 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1222 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1223 // If we have an umbrella directory, use that. 1224 if (Mod->hasUmbrellaDir()) 1225 return Mod->getUmbrellaDir(); 1226 1227 // If we have a framework directory, stop looking. 1228 if (Mod->IsFramework) 1229 return 0; 1230 } 1231 1232 return 0; 1233 } 1234 1235 /// \brief Parse a module map file. 1236 /// 1237 /// module-map-file: 1238 /// module-declaration* 1239 bool ModuleMapParser::parseModuleMapFile() { 1240 do { 1241 switch (Tok.Kind) { 1242 case MMToken::EndOfFile: 1243 return HadError; 1244 1245 case MMToken::ExplicitKeyword: 1246 case MMToken::ModuleKeyword: 1247 case MMToken::FrameworkKeyword: 1248 parseModuleDecl(); 1249 break; 1250 1251 case MMToken::Comma: 1252 case MMToken::ExportKeyword: 1253 case MMToken::HeaderKeyword: 1254 case MMToken::Identifier: 1255 case MMToken::LBrace: 1256 case MMToken::Period: 1257 case MMToken::RBrace: 1258 case MMToken::RequiresKeyword: 1259 case MMToken::Star: 1260 case MMToken::StringLiteral: 1261 case MMToken::UmbrellaKeyword: 1262 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1263 HadError = true; 1264 consumeToken(); 1265 break; 1266 } 1267 } while (true); 1268 1269 return HadError; 1270 } 1271 1272 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1273 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1274 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1275 if (!Buffer) 1276 return true; 1277 1278 // Parse this module map file. 1279 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1280 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1281 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 1282 bool Result = Parser.parseModuleMapFile(); 1283 Diags->getClient()->EndSourceFile(); 1284 1285 return Result; 1286 } 1287