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 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 74 Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 75 new DiagnosticsEngine(DiagIDs)); 76 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 77 SourceMgr = new SourceManager(*Diags, FileMgr); 78 } 79 80 ModuleMap::~ModuleMap() { 81 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 82 IEnd = Modules.end(); 83 I != IEnd; ++I) { 84 delete I->getValue(); 85 } 86 87 delete SourceMgr; 88 } 89 90 Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 91 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 92 = Headers.find(File); 93 if (Known != Headers.end()) 94 return Known->second; 95 96 const DirectoryEntry *Dir = File->getDir(); 97 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 98 StringRef DirName = Dir->getName(); 99 100 // Keep walking up the directory hierarchy, looking for a directory with 101 // an umbrella header. 102 do { 103 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 104 = UmbrellaDirs.find(Dir); 105 if (KnownDir != UmbrellaDirs.end()) { 106 Module *Result = KnownDir->second; 107 108 // Search up the module stack until we find a module with an umbrella 109 // header. 110 Module *UmbrellaModule = Result; 111 while (!UmbrellaModule->UmbrellaHeader && UmbrellaModule->Parent) 112 UmbrellaModule = UmbrellaModule->Parent; 113 114 if (UmbrellaModule->InferSubmodules) { 115 // Infer submodules for each of the directories we found between 116 // the directory of the umbrella header and the directory where 117 // the actual header is located. 118 119 // For a framework module, the umbrella directory is the framework 120 // directory, so strip off the "Headers" or "PrivateHeaders". 121 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 122 unsigned LastSkippedDir = SkippedDirs.size(); 123 if (LastSkippedDir && UmbrellaModule->IsFramework) { 124 if (llvm::sys::path::filename(SkippedDirs.back()->getName()) 125 == "PrivateHeaders") { 126 // For private headers, add an explicit "Private" module. 127 // FIXME: This feels somewhat hackish. Do we want to introduce 128 // some kind of "umbrella directory" here? 129 Result = findOrCreateModule("Private", Result, 130 /*IsFramework=*/false, 131 /*IsExplicit=*/true).first; 132 Explicit = true; 133 } 134 135 --LastSkippedDir; 136 } 137 138 for (unsigned I = LastSkippedDir; I != 0; --I) { 139 // Find or create the module that corresponds to this directory name. 140 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 141 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 142 Explicit).first; 143 144 // Associate the module and the directory. 145 UmbrellaDirs[SkippedDirs[I-1]] = Result; 146 147 // If inferred submodules export everything they import, add a 148 // wildcard to the set of exports. 149 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 150 Result->Exports.push_back(Module::ExportDecl(0, true)); 151 } 152 153 // Infer a submodule with the same name as this header file. 154 StringRef Name = llvm::sys::path::stem(File->getName()); 155 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 156 Explicit).first; 157 158 // If inferred submodules export everything they import, add a 159 // wildcard to the set of exports. 160 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 161 Result->Exports.push_back(Module::ExportDecl(0, true)); 162 } else { 163 // Record each of the directories we stepped through as being part of 164 // the module we found, since the umbrella header covers them all. 165 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 166 UmbrellaDirs[SkippedDirs[I]] = Result; 167 } 168 169 Headers[File] = Result; 170 return Result; 171 } 172 173 SkippedDirs.push_back(Dir); 174 175 // Retrieve our parent path. 176 DirName = llvm::sys::path::parent_path(DirName); 177 if (DirName.empty()) 178 break; 179 180 // Resolve the parent path to a directory entry. 181 Dir = SourceMgr->getFileManager().getDirectory(DirName); 182 } while (Dir); 183 184 return 0; 185 } 186 187 Module *ModuleMap::findModule(StringRef Name) { 188 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 189 if (Known != Modules.end()) 190 return Known->getValue(); 191 192 return 0; 193 } 194 195 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 196 for(; Context; Context = Context->Parent) { 197 if (Module *Sub = lookupModuleQualified(Name, Context)) 198 return Sub; 199 } 200 201 return findModule(Name); 202 } 203 204 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 205 if (!Context) 206 return findModule(Name); 207 208 llvm::StringMap<Module *>::iterator Sub = Context->SubModules.find(Name); 209 if (Sub != Context->SubModules.end()) 210 return Sub->getValue(); 211 212 return 0; 213 } 214 215 std::pair<Module *, bool> 216 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 217 bool IsExplicit) { 218 // Try to find an existing module with this name. 219 if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name]) 220 return std::make_pair(Found, false); 221 222 // Create a new module with this name. 223 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 224 IsExplicit); 225 if (Parent) 226 Parent->SubModules[Name] = Result; 227 else 228 Modules[Name] = Result; 229 return std::make_pair(Result, true); 230 } 231 232 Module * 233 ModuleMap::inferFrameworkModule(StringRef ModuleName, 234 const DirectoryEntry *FrameworkDir, 235 Module *Parent) { 236 // Check whether we've already found this module. 237 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 238 return Mod; 239 240 FileManager &FileMgr = SourceMgr->getFileManager(); 241 242 // Look for an umbrella header. 243 llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 244 llvm::sys::path::append(UmbrellaName, "Headers"); 245 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 246 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 247 248 // FIXME: If there's no umbrella header, we could probably scan the 249 // framework to load *everything*. But, it's not clear that this is a good 250 // idea. 251 if (!UmbrellaHeader) 252 return 0; 253 254 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 255 /*IsFramework=*/true, /*IsExplicit=*/false); 256 257 if (Parent) 258 Parent->SubModules[ModuleName] = Result; 259 else 260 Modules[ModuleName] = Result; 261 262 // umbrella "umbrella-header-name" 263 Result->UmbrellaHeader = UmbrellaHeader; 264 Headers[UmbrellaHeader] = Result; 265 UmbrellaDirs[FrameworkDir] = Result; 266 267 // export * 268 Result->Exports.push_back(Module::ExportDecl(0, true)); 269 270 // module * { export * } 271 Result->InferSubmodules = true; 272 Result->InferExportWildcard = true; 273 274 // Look for subframeworks. 275 llvm::error_code EC; 276 llvm::SmallString<128> SubframeworksDirName = StringRef(FrameworkDir->getName()); 277 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 278 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName.str(), EC), 279 DirEnd; 280 Dir != DirEnd && !EC; Dir.increment(EC)) { 281 if (!StringRef(Dir->path()).endswith(".framework")) 282 continue; 283 284 if (const DirectoryEntry *SubframeworkDir 285 = FileMgr.getDirectory(Dir->path())) { 286 // FIXME: Do we want to warn about subframeworks without umbrella headers? 287 inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, 288 Result); 289 } 290 } 291 292 // Look for private headers. 293 Module *ModulePrivate = 0; 294 llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName()); 295 llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders"); 296 for (llvm::sys::fs::directory_iterator Dir(PrivateHeadersDirName.str(), EC), 297 DirEnd; 298 Dir != DirEnd && !EC; Dir.increment(EC)) { 299 // Check whether this entry has an extension typically associated with 300 // headers. 301 if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path())) 302 .Cases(".h", ".H", ".hh", ".hpp", true) 303 .Default(false)) 304 continue; 305 306 if (const FileEntry *PrivateHeader = FileMgr.getFile(Dir->path())) { 307 // Create the "private" submodule, if we haven't done so already. 308 if (!ModulePrivate) { 309 ModulePrivate = findOrCreateModule("Private", Result, 310 /*IsFramework=*/false, 311 /*IsExplicit=*/true).first; 312 } 313 314 Module *Sub = findOrCreateModule(llvm::sys::path::stem(Dir->path()), 315 ModulePrivate, /*IsFramework=*/false, 316 /*IsExplicit=*/true).first; 317 // header "the private header" 318 Sub->Headers.push_back(PrivateHeader); 319 320 // export * 321 Sub->Exports.push_back(Module::ExportDecl(0, true)); 322 323 Headers[PrivateHeader] = Sub; 324 } 325 } 326 327 return Result; 328 } 329 330 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 331 Headers[UmbrellaHeader] = Mod; 332 Mod->UmbrellaHeader = UmbrellaHeader; 333 334 const DirectoryEntry *UmbrellaDir = UmbrellaHeader->getDir(); 335 if (Mod->IsFramework) 336 UmbrellaDir = SourceMgr->getFileManager().getDirectory( 337 llvm::sys::path::parent_path(UmbrellaDir->getName())); 338 339 UmbrellaDirs[UmbrellaDir] = Mod; 340 } 341 342 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) { 343 Mod->Headers.push_back(Header); 344 Headers[Header] = Mod; 345 } 346 347 const FileEntry * 348 ModuleMap::getContainingModuleMapFile(Module *Module) { 349 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 350 return 0; 351 352 return SourceMgr->getFileEntryForID( 353 SourceMgr->getFileID(Module->DefinitionLoc)); 354 } 355 356 void ModuleMap::dump() { 357 llvm::errs() << "Modules:"; 358 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 359 MEnd = Modules.end(); 360 M != MEnd; ++M) 361 M->getValue()->print(llvm::errs(), 2); 362 363 llvm::errs() << "Headers:"; 364 for (llvm::DenseMap<const FileEntry *, Module *>::iterator 365 H = Headers.begin(), 366 HEnd = Headers.end(); 367 H != HEnd; ++H) { 368 llvm::errs() << " \"" << H->first->getName() << "\" -> " 369 << H->second->getFullModuleName() << "\n"; 370 } 371 } 372 373 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 374 bool HadError = false; 375 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 376 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 377 Complain); 378 if (Export.getPointer() || Export.getInt()) 379 Mod->Exports.push_back(Export); 380 else 381 HadError = true; 382 } 383 Mod->UnresolvedExports.clear(); 384 return HadError; 385 } 386 387 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 388 if (Loc.isInvalid()) 389 return 0; 390 391 // Use the expansion location to determine which module we're in. 392 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 393 if (!ExpansionLoc.isFileID()) 394 return 0; 395 396 397 const SourceManager &SrcMgr = Loc.getManager(); 398 FileID ExpansionFileID = ExpansionLoc.getFileID(); 399 const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID); 400 if (!ExpansionFile) 401 return 0; 402 403 // Find the module that owns this header. 404 return findModuleForHeader(ExpansionFile); 405 } 406 407 //----------------------------------------------------------------------------// 408 // Module map file parser 409 //----------------------------------------------------------------------------// 410 411 namespace clang { 412 /// \brief A token in a module map file. 413 struct MMToken { 414 enum TokenKind { 415 EndOfFile, 416 HeaderKeyword, 417 Identifier, 418 ExplicitKeyword, 419 ExportKeyword, 420 FrameworkKeyword, 421 ModuleKeyword, 422 Period, 423 UmbrellaKeyword, 424 Star, 425 StringLiteral, 426 LBrace, 427 RBrace 428 } Kind; 429 430 unsigned Location; 431 unsigned StringLength; 432 const char *StringData; 433 434 void clear() { 435 Kind = EndOfFile; 436 Location = 0; 437 StringLength = 0; 438 StringData = 0; 439 } 440 441 bool is(TokenKind K) const { return Kind == K; } 442 443 SourceLocation getLocation() const { 444 return SourceLocation::getFromRawEncoding(Location); 445 } 446 447 StringRef getString() const { 448 return StringRef(StringData, StringLength); 449 } 450 }; 451 452 class ModuleMapParser { 453 Lexer &L; 454 SourceManager &SourceMgr; 455 DiagnosticsEngine &Diags; 456 ModuleMap ⤅ 457 458 /// \brief The directory that this module map resides in. 459 const DirectoryEntry *Directory; 460 461 /// \brief Whether an error occurred. 462 bool HadError; 463 464 /// \brief Default target information, used only for string literal 465 /// parsing. 466 TargetInfo *Target; 467 468 /// \brief Stores string data for the various string literals referenced 469 /// during parsing. 470 llvm::BumpPtrAllocator StringData; 471 472 /// \brief The current token. 473 MMToken Tok; 474 475 /// \brief The active module. 476 Module *ActiveModule; 477 478 /// \brief Consume the current token and return its location. 479 SourceLocation consumeToken(); 480 481 /// \brief Skip tokens until we reach the a token with the given kind 482 /// (or the end of the file). 483 void skipUntil(MMToken::TokenKind K); 484 485 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 486 ModuleId; 487 bool parseModuleId(ModuleId &Id); 488 void parseModuleDecl(); 489 void parseUmbrellaDecl(); 490 void parseHeaderDecl(); 491 void parseExportDecl(); 492 void parseInferredSubmoduleDecl(bool Explicit); 493 494 public: 495 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 496 DiagnosticsEngine &Diags, 497 ModuleMap &Map, 498 const DirectoryEntry *Directory) 499 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 500 Directory(Directory), HadError(false), ActiveModule(0) 501 { 502 TargetOptions TargetOpts; 503 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 504 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 505 506 Tok.clear(); 507 consumeToken(); 508 } 509 510 bool parseModuleMapFile(); 511 }; 512 } 513 514 SourceLocation ModuleMapParser::consumeToken() { 515 retry: 516 SourceLocation Result = Tok.getLocation(); 517 Tok.clear(); 518 519 Token LToken; 520 L.LexFromRawLexer(LToken); 521 Tok.Location = LToken.getLocation().getRawEncoding(); 522 switch (LToken.getKind()) { 523 case tok::raw_identifier: 524 Tok.StringData = LToken.getRawIdentifierData(); 525 Tok.StringLength = LToken.getLength(); 526 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 527 .Case("header", MMToken::HeaderKeyword) 528 .Case("explicit", MMToken::ExplicitKeyword) 529 .Case("export", MMToken::ExportKeyword) 530 .Case("framework", MMToken::FrameworkKeyword) 531 .Case("module", MMToken::ModuleKeyword) 532 .Case("umbrella", MMToken::UmbrellaKeyword) 533 .Default(MMToken::Identifier); 534 break; 535 536 case tok::eof: 537 Tok.Kind = MMToken::EndOfFile; 538 break; 539 540 case tok::l_brace: 541 Tok.Kind = MMToken::LBrace; 542 break; 543 544 case tok::period: 545 Tok.Kind = MMToken::Period; 546 break; 547 548 case tok::r_brace: 549 Tok.Kind = MMToken::RBrace; 550 break; 551 552 case tok::star: 553 Tok.Kind = MMToken::Star; 554 break; 555 556 case tok::string_literal: { 557 // Parse the string literal. 558 LangOptions LangOpts; 559 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 560 if (StringLiteral.hadError) 561 goto retry; 562 563 // Copy the string literal into our string data allocator. 564 unsigned Length = StringLiteral.GetStringLength(); 565 char *Saved = StringData.Allocate<char>(Length + 1); 566 memcpy(Saved, StringLiteral.GetString().data(), Length); 567 Saved[Length] = 0; 568 569 // Form the token. 570 Tok.Kind = MMToken::StringLiteral; 571 Tok.StringData = Saved; 572 Tok.StringLength = Length; 573 break; 574 } 575 576 case tok::comment: 577 goto retry; 578 579 default: 580 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 581 HadError = true; 582 goto retry; 583 } 584 585 return Result; 586 } 587 588 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 589 unsigned braceDepth = 0; 590 do { 591 switch (Tok.Kind) { 592 case MMToken::EndOfFile: 593 return; 594 595 case MMToken::LBrace: 596 if (Tok.is(K) && braceDepth == 0) 597 return; 598 599 ++braceDepth; 600 break; 601 602 case MMToken::RBrace: 603 if (braceDepth > 0) 604 --braceDepth; 605 else if (Tok.is(K)) 606 return; 607 break; 608 609 default: 610 if (braceDepth == 0 && Tok.is(K)) 611 return; 612 break; 613 } 614 615 consumeToken(); 616 } while (true); 617 } 618 619 /// \brief Parse a module-id. 620 /// 621 /// module-id: 622 /// identifier 623 /// identifier '.' module-id 624 /// 625 /// \returns true if an error occurred, false otherwise. 626 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 627 Id.clear(); 628 do { 629 if (Tok.is(MMToken::Identifier)) { 630 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 631 consumeToken(); 632 } else { 633 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 634 return true; 635 } 636 637 if (!Tok.is(MMToken::Period)) 638 break; 639 640 consumeToken(); 641 } while (true); 642 643 return false; 644 } 645 646 /// \brief Parse a module declaration. 647 /// 648 /// module-declaration: 649 /// 'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* } 650 /// 651 /// module-member: 652 /// umbrella-declaration 653 /// header-declaration 654 /// submodule-declaration 655 /// export-declaration 656 /// 657 /// submodule-declaration: 658 /// module-declaration 659 /// inferred-submodule-declaration 660 void ModuleMapParser::parseModuleDecl() { 661 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 662 Tok.is(MMToken::FrameworkKeyword)); 663 // Parse 'explicit' or 'framework' keyword, if present. 664 SourceLocation ExplicitLoc; 665 bool Explicit = false; 666 bool Framework = false; 667 668 // Parse 'explicit' keyword, if present. 669 if (Tok.is(MMToken::ExplicitKeyword)) { 670 ExplicitLoc = consumeToken(); 671 Explicit = true; 672 } 673 674 // Parse 'framework' keyword, if present. 675 if (Tok.is(MMToken::FrameworkKeyword)) { 676 consumeToken(); 677 Framework = true; 678 } 679 680 // Parse 'module' keyword. 681 if (!Tok.is(MMToken::ModuleKeyword)) { 682 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 683 consumeToken(); 684 HadError = true; 685 return; 686 } 687 consumeToken(); // 'module' keyword 688 689 // If we have a wildcard for the module name, this is an inferred submodule. 690 // Parse it. 691 if (Tok.is(MMToken::Star)) 692 return parseInferredSubmoduleDecl(Explicit); 693 694 // Parse the module name. 695 ModuleId Id; 696 if (parseModuleId(Id)) { 697 HadError = true; 698 return; 699 } 700 701 if (ActiveModule) { 702 if (Id.size() > 1) { 703 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 704 << SourceRange(Id.front().second, Id.back().second); 705 706 HadError = true; 707 return; 708 } 709 } else if (Id.size() == 1 && Explicit) { 710 // Top-level modules can't be explicit. 711 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 712 Explicit = false; 713 ExplicitLoc = SourceLocation(); 714 HadError = true; 715 } 716 717 Module *PreviousActiveModule = ActiveModule; 718 if (Id.size() > 1) { 719 // This module map defines a submodule. Go find the module of which it 720 // is a submodule. 721 ActiveModule = 0; 722 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 723 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 724 ActiveModule = Next; 725 continue; 726 } 727 728 if (ActiveModule) { 729 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 730 << Id[I].first << ActiveModule->getTopLevelModule(); 731 } else { 732 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 733 } 734 HadError = true; 735 return; 736 } 737 } 738 739 StringRef ModuleName = Id.back().first; 740 SourceLocation ModuleNameLoc = Id.back().second; 741 742 // Parse the opening brace. 743 if (!Tok.is(MMToken::LBrace)) { 744 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 745 << ModuleName; 746 HadError = true; 747 return; 748 } 749 SourceLocation LBraceLoc = consumeToken(); 750 751 // Determine whether this (sub)module has already been defined. 752 llvm::StringMap<Module *> &ModuleSpace 753 = ActiveModule? ActiveModule->SubModules : Map.Modules; 754 llvm::StringMap<Module *>::iterator ExistingModule 755 = ModuleSpace.find(ModuleName); 756 if (ExistingModule != ModuleSpace.end()) { 757 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 758 << ModuleName; 759 Diags.Report(ExistingModule->getValue()->DefinitionLoc, 760 diag::note_mmap_prev_definition); 761 762 // Skip the module definition. 763 skipUntil(MMToken::RBrace); 764 if (Tok.is(MMToken::RBrace)) 765 consumeToken(); 766 767 HadError = true; 768 return; 769 } 770 771 // Start defining this module. 772 ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 773 Explicit); 774 ModuleSpace[ModuleName] = ActiveModule; 775 776 bool Done = false; 777 do { 778 switch (Tok.Kind) { 779 case MMToken::EndOfFile: 780 case MMToken::RBrace: 781 Done = true; 782 break; 783 784 case MMToken::ExplicitKeyword: 785 case MMToken::FrameworkKeyword: 786 case MMToken::ModuleKeyword: 787 parseModuleDecl(); 788 break; 789 790 case MMToken::ExportKeyword: 791 parseExportDecl(); 792 break; 793 794 case MMToken::HeaderKeyword: 795 parseHeaderDecl(); 796 break; 797 798 case MMToken::UmbrellaKeyword: 799 parseUmbrellaDecl(); 800 break; 801 802 default: 803 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 804 consumeToken(); 805 break; 806 } 807 } while (!Done); 808 809 if (Tok.is(MMToken::RBrace)) 810 consumeToken(); 811 else { 812 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 813 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 814 HadError = true; 815 } 816 817 // We're done parsing this module. Pop back to the previous module. 818 ActiveModule = PreviousActiveModule; 819 } 820 821 /// \brief Append to \p Paths the set of paths needed to get to the 822 /// subframework in which the given module lives. 823 void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) { 824 // Collect the framework names from the given module to the top-level module. 825 llvm::SmallVector<StringRef, 2> Paths; 826 for (; Mod; Mod = Mod->Parent) { 827 if (Mod->IsFramework) 828 Paths.push_back(Mod->Name); 829 } 830 831 if (Paths.empty()) 832 return; 833 834 // Add Frameworks/Name.framework for each subframework. 835 for (unsigned I = Paths.size() - 1; I != 0; --I) { 836 llvm::sys::path::append(Path, "Frameworks"); 837 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 838 } 839 } 840 841 /// \brief Parse an umbrella header declaration. 842 /// 843 /// umbrella-declaration: 844 /// 'umbrella' string-literal 845 void ModuleMapParser::parseUmbrellaDecl() { 846 assert(Tok.is(MMToken::UmbrellaKeyword)); 847 SourceLocation UmbrellaLoc = consumeToken(); 848 849 // Parse the header name. 850 if (!Tok.is(MMToken::StringLiteral)) { 851 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 852 << "umbrella"; 853 HadError = true; 854 return; 855 } 856 std::string FileName = Tok.getString(); 857 SourceLocation FileNameLoc = consumeToken(); 858 859 // Check whether we already have an umbrella header. 860 if (ActiveModule->UmbrellaHeader) { 861 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict) 862 << ActiveModule->getFullModuleName() 863 << ActiveModule->UmbrellaHeader->getName(); 864 HadError = true; 865 return; 866 } 867 868 // Look for this file. 869 llvm::SmallString<128> PathName; 870 const FileEntry *File = 0; 871 872 if (llvm::sys::path::is_absolute(FileName)) { 873 PathName = FileName; 874 File = SourceMgr.getFileManager().getFile(PathName); 875 } else { 876 // Search for the header file within the search directory. 877 PathName += Directory->getName(); 878 unsigned PathLength = PathName.size(); 879 880 if (ActiveModule->isPartOfFramework()) { 881 appendSubframeworkPaths(ActiveModule, PathName); 882 883 // Check whether this file is in the public headers. 884 llvm::sys::path::append(PathName, "Headers"); 885 llvm::sys::path::append(PathName, FileName); 886 File = SourceMgr.getFileManager().getFile(PathName); 887 888 if (!File) { 889 // Check whether this file is in the private headers. 890 PathName.resize(PathLength); 891 llvm::sys::path::append(PathName, "PrivateHeaders"); 892 llvm::sys::path::append(PathName, FileName); 893 File = SourceMgr.getFileManager().getFile(PathName); 894 } 895 } else { 896 // Lookup for normal headers. 897 llvm::sys::path::append(PathName, FileName); 898 File = SourceMgr.getFileManager().getFile(PathName); 899 } 900 } 901 902 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 903 // Come up with a lazy way to do this. 904 if (File) { 905 const DirectoryEntry *UmbrellaDir = File->getDir(); 906 if (ActiveModule->IsFramework) { 907 // For framework modules, use the framework directory as the umbrella 908 // directory. 909 UmbrellaDir = SourceMgr.getFileManager().getDirectory( 910 llvm::sys::path::parent_path(UmbrellaDir->getName())); 911 } 912 913 if (const Module *OwningModule = Map.Headers[File]) { 914 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 915 << FileName << OwningModule->getFullModuleName(); 916 HadError = true; 917 } else if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 918 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 919 << OwningModule->getFullModuleName(); 920 HadError = true; 921 } else { 922 // Record this umbrella header. 923 Map.setUmbrellaHeader(ActiveModule, File); 924 } 925 } else { 926 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 927 << true << FileName; 928 HadError = true; 929 } 930 } 931 932 /// \brief Parse a header declaration. 933 /// 934 /// header-declaration: 935 /// 'header' string-literal 936 void ModuleMapParser::parseHeaderDecl() { 937 assert(Tok.is(MMToken::HeaderKeyword)); 938 consumeToken(); 939 940 // Parse the header name. 941 if (!Tok.is(MMToken::StringLiteral)) { 942 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 943 << "header"; 944 HadError = true; 945 return; 946 } 947 std::string FileName = Tok.getString(); 948 SourceLocation FileNameLoc = consumeToken(); 949 950 // Look for this file. 951 const FileEntry *File = 0; 952 llvm::SmallString<128> PathName; 953 if (llvm::sys::path::is_absolute(FileName)) { 954 PathName = FileName; 955 File = SourceMgr.getFileManager().getFile(PathName); 956 } else { 957 // Search for the header file within the search directory. 958 PathName += Directory->getName(); 959 unsigned PathLength = PathName.size(); 960 961 if (ActiveModule->isPartOfFramework()) { 962 appendSubframeworkPaths(ActiveModule, PathName); 963 964 // Check whether this file is in the public headers. 965 llvm::sys::path::append(PathName, "Headers"); 966 llvm::sys::path::append(PathName, FileName); 967 File = SourceMgr.getFileManager().getFile(PathName); 968 969 if (!File) { 970 // Check whether this file is in the private headers. 971 PathName.resize(PathLength); 972 llvm::sys::path::append(PathName, "PrivateHeaders"); 973 llvm::sys::path::append(PathName, FileName); 974 File = SourceMgr.getFileManager().getFile(PathName); 975 } 976 } else { 977 // Lookup for normal headers. 978 llvm::sys::path::append(PathName, FileName); 979 File = SourceMgr.getFileManager().getFile(PathName); 980 } 981 } 982 983 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 984 // Come up with a lazy way to do this. 985 if (File) { 986 if (const Module *OwningModule = Map.Headers[File]) { 987 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 988 << FileName << OwningModule->getFullModuleName(); 989 HadError = true; 990 } else { 991 // Record this file. 992 Map.addHeader(ActiveModule, File); 993 } 994 } else { 995 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 996 << false << FileName; 997 HadError = true; 998 } 999 } 1000 1001 /// \brief Parse a module export declaration. 1002 /// 1003 /// export-declaration: 1004 /// 'export' wildcard-module-id 1005 /// 1006 /// wildcard-module-id: 1007 /// identifier 1008 /// '*' 1009 /// identifier '.' wildcard-module-id 1010 void ModuleMapParser::parseExportDecl() { 1011 assert(Tok.is(MMToken::ExportKeyword)); 1012 SourceLocation ExportLoc = consumeToken(); 1013 1014 // Parse the module-id with an optional wildcard at the end. 1015 ModuleId ParsedModuleId; 1016 bool Wildcard = false; 1017 do { 1018 if (Tok.is(MMToken::Identifier)) { 1019 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1020 Tok.getLocation())); 1021 consumeToken(); 1022 1023 if (Tok.is(MMToken::Period)) { 1024 consumeToken(); 1025 continue; 1026 } 1027 1028 break; 1029 } 1030 1031 if(Tok.is(MMToken::Star)) { 1032 Wildcard = true; 1033 consumeToken(); 1034 break; 1035 } 1036 1037 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1038 HadError = true; 1039 return; 1040 } while (true); 1041 1042 Module::UnresolvedExportDecl Unresolved = { 1043 ExportLoc, ParsedModuleId, Wildcard 1044 }; 1045 ActiveModule->UnresolvedExports.push_back(Unresolved); 1046 } 1047 1048 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 1049 assert(Tok.is(MMToken::Star)); 1050 SourceLocation StarLoc = consumeToken(); 1051 bool Failed = false; 1052 1053 // Inferred modules must be submodules. 1054 if (!ActiveModule) { 1055 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1056 Failed = true; 1057 } 1058 1059 // Inferred modules must have umbrella headers. 1060 if (!Failed && !ActiveModule->UmbrellaHeader) { 1061 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1062 Failed = true; 1063 } 1064 1065 // Check for redefinition of an inferred module. 1066 if (!Failed && ActiveModule->InferSubmodules) { 1067 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1068 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1069 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1070 diag::note_mmap_prev_definition); 1071 Failed = true; 1072 } 1073 1074 // If there were any problems with this inferred submodule, skip its body. 1075 if (Failed) { 1076 if (Tok.is(MMToken::LBrace)) { 1077 consumeToken(); 1078 skipUntil(MMToken::RBrace); 1079 if (Tok.is(MMToken::RBrace)) 1080 consumeToken(); 1081 } 1082 HadError = true; 1083 return; 1084 } 1085 1086 // Note that we have an inferred submodule. 1087 ActiveModule->InferSubmodules = true; 1088 ActiveModule->InferredSubmoduleLoc = StarLoc; 1089 ActiveModule->InferExplicitSubmodules = Explicit; 1090 1091 // Parse the opening brace. 1092 if (!Tok.is(MMToken::LBrace)) { 1093 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1094 HadError = true; 1095 return; 1096 } 1097 SourceLocation LBraceLoc = consumeToken(); 1098 1099 // Parse the body of the inferred submodule. 1100 bool Done = false; 1101 do { 1102 switch (Tok.Kind) { 1103 case MMToken::EndOfFile: 1104 case MMToken::RBrace: 1105 Done = true; 1106 break; 1107 1108 case MMToken::ExportKeyword: { 1109 consumeToken(); 1110 if (Tok.is(MMToken::Star)) 1111 ActiveModule->InferExportWildcard = true; 1112 else 1113 Diags.Report(Tok.getLocation(), 1114 diag::err_mmap_expected_export_wildcard); 1115 consumeToken(); 1116 break; 1117 } 1118 1119 case MMToken::ExplicitKeyword: 1120 case MMToken::ModuleKeyword: 1121 case MMToken::HeaderKeyword: 1122 case MMToken::UmbrellaKeyword: 1123 default: 1124 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 1125 consumeToken(); 1126 break; 1127 } 1128 } while (!Done); 1129 1130 if (Tok.is(MMToken::RBrace)) 1131 consumeToken(); 1132 else { 1133 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1134 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1135 HadError = true; 1136 } 1137 } 1138 1139 /// \brief Parse a module map file. 1140 /// 1141 /// module-map-file: 1142 /// module-declaration* 1143 bool ModuleMapParser::parseModuleMapFile() { 1144 do { 1145 switch (Tok.Kind) { 1146 case MMToken::EndOfFile: 1147 return HadError; 1148 1149 case MMToken::ExplicitKeyword: 1150 case MMToken::ModuleKeyword: 1151 case MMToken::FrameworkKeyword: 1152 parseModuleDecl(); 1153 break; 1154 1155 case MMToken::ExportKeyword: 1156 case MMToken::HeaderKeyword: 1157 case MMToken::Identifier: 1158 case MMToken::LBrace: 1159 case MMToken::Period: 1160 case MMToken::RBrace: 1161 case MMToken::Star: 1162 case MMToken::StringLiteral: 1163 case MMToken::UmbrellaKeyword: 1164 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1165 HadError = true; 1166 consumeToken(); 1167 break; 1168 } 1169 } while (true); 1170 1171 return HadError; 1172 } 1173 1174 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1175 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1176 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1177 if (!Buffer) 1178 return true; 1179 1180 // Parse this module map file. 1181 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 1182 Diags->getClient()->BeginSourceFile(LangOpts); 1183 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 1184 bool Result = Parser.parseModuleMapFile(); 1185 Diags->getClient()->EndSourceFile(); 1186 1187 return Result; 1188 } 1189