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