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