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