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