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