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 #include <stdlib.h> 30 using namespace clang; 31 32 Module::ExportDecl 33 ModuleMap::resolveExport(Module *Mod, 34 const Module::UnresolvedExportDecl &Unresolved, 35 bool Complain) { 36 // We may have just a wildcard. 37 if (Unresolved.Id.empty()) { 38 assert(Unresolved.Wildcard && "Invalid unresolved export"); 39 return Module::ExportDecl(0, true); 40 } 41 42 // Find the starting module. 43 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 44 if (!Context) { 45 if (Complain) 46 Diags->Report(Unresolved.Id[0].second, 47 diag::err_mmap_missing_module_unqualified) 48 << Unresolved.Id[0].first << Mod->getFullModuleName(); 49 50 return Module::ExportDecl(); 51 } 52 53 // Dig into the module path. 54 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 55 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 56 Context); 57 if (!Sub) { 58 if (Complain) 59 Diags->Report(Unresolved.Id[I].second, 60 diag::err_mmap_missing_module_qualified) 61 << Unresolved.Id[I].first << Context->getFullModuleName() 62 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 63 64 return Module::ExportDecl(); 65 } 66 67 Context = Sub; 68 } 69 70 return Module::ExportDecl(Context, Unresolved.Wildcard); 71 } 72 73 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, 74 const LangOptions &LangOpts, const TargetInfo *Target) 75 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0) 76 { 77 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 78 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( 79 new DiagnosticsEngine(DiagIDs)); 80 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 81 SourceMgr = new SourceManager(*Diags, FileMgr); 82 } 83 84 ModuleMap::~ModuleMap() { 85 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 86 IEnd = Modules.end(); 87 I != IEnd; ++I) { 88 delete I->getValue(); 89 } 90 91 delete SourceMgr; 92 } 93 94 void ModuleMap::setTarget(const TargetInfo &Target) { 95 assert((!this->Target || this->Target == &Target) && 96 "Improper target override"); 97 this->Target = &Target; 98 } 99 100 Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 101 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 102 = Headers.find(File); 103 if (Known != Headers.end()) { 104 // If a header corresponds to an unavailable module, don't report 105 // that it maps to anything. 106 if (!Known->second->isAvailable()) 107 return 0; 108 109 return Known->second; 110 } 111 112 const DirectoryEntry *Dir = File->getDir(); 113 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 114 StringRef DirName = Dir->getName(); 115 116 // Keep walking up the directory hierarchy, looking for a directory with 117 // an umbrella header. 118 do { 119 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 120 = UmbrellaDirs.find(Dir); 121 if (KnownDir != UmbrellaDirs.end()) { 122 Module *Result = KnownDir->second; 123 124 // Search up the module stack until we find a module with an umbrella 125 // directory. 126 Module *UmbrellaModule = Result; 127 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 128 UmbrellaModule = UmbrellaModule->Parent; 129 130 if (UmbrellaModule->InferSubmodules) { 131 // Infer submodules for each of the directories we found between 132 // the directory of the umbrella header and the directory where 133 // the actual header is located. 134 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 135 136 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 137 // Find or create the module that corresponds to this directory name. 138 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 139 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 140 Explicit).first; 141 142 // Associate the module and the directory. 143 UmbrellaDirs[SkippedDirs[I-1]] = Result; 144 145 // If inferred submodules export everything they import, add a 146 // wildcard to the set of exports. 147 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 148 Result->Exports.push_back(Module::ExportDecl(0, true)); 149 } 150 151 // Infer a submodule with the same name as this header file. 152 StringRef Name = llvm::sys::path::stem(File->getName()); 153 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 154 Explicit).first; 155 Result->TopHeaders.insert(File); 156 157 // If inferred submodules export everything they import, add a 158 // wildcard to the set of exports. 159 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 160 Result->Exports.push_back(Module::ExportDecl(0, true)); 161 } else { 162 // Record each of the directories we stepped through as being part of 163 // the module we found, since the umbrella header covers them all. 164 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 165 UmbrellaDirs[SkippedDirs[I]] = Result; 166 } 167 168 Headers[File] = Result; 169 170 // If a header corresponds to an unavailable module, don't report 171 // that it maps to anything. 172 if (!Result->isAvailable()) 173 return 0; 174 175 return Result; 176 } 177 178 SkippedDirs.push_back(Dir); 179 180 // Retrieve our parent path. 181 DirName = llvm::sys::path::parent_path(DirName); 182 if (DirName.empty()) 183 break; 184 185 // Resolve the parent path to a directory entry. 186 Dir = SourceMgr->getFileManager().getDirectory(DirName); 187 } while (Dir); 188 189 return 0; 190 } 191 192 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) { 193 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 194 = Headers.find(Header); 195 if (Known != Headers.end()) 196 return !Known->second->isAvailable(); 197 198 const DirectoryEntry *Dir = Header->getDir(); 199 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 200 StringRef DirName = Dir->getName(); 201 202 // Keep walking up the directory hierarchy, looking for a directory with 203 // an umbrella header. 204 do { 205 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 206 = UmbrellaDirs.find(Dir); 207 if (KnownDir != UmbrellaDirs.end()) { 208 Module *Found = KnownDir->second; 209 if (!Found->isAvailable()) 210 return true; 211 212 // Search up the module stack until we find a module with an umbrella 213 // directory. 214 Module *UmbrellaModule = Found; 215 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 216 UmbrellaModule = UmbrellaModule->Parent; 217 218 if (UmbrellaModule->InferSubmodules) { 219 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 220 // Find or create the module that corresponds to this directory name. 221 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 222 Found = lookupModuleQualified(Name, Found); 223 if (!Found) 224 return false; 225 if (!Found->isAvailable()) 226 return true; 227 } 228 229 // Infer a submodule with the same name as this header file. 230 StringRef Name = llvm::sys::path::stem(Header->getName()); 231 Found = lookupModuleQualified(Name, Found); 232 if (!Found) 233 return false; 234 } 235 236 return !Found->isAvailable(); 237 } 238 239 SkippedDirs.push_back(Dir); 240 241 // Retrieve our parent path. 242 DirName = llvm::sys::path::parent_path(DirName); 243 if (DirName.empty()) 244 break; 245 246 // Resolve the parent path to a directory entry. 247 Dir = SourceMgr->getFileManager().getDirectory(DirName); 248 } while (Dir); 249 250 return false; 251 } 252 253 Module *ModuleMap::findModule(StringRef Name) { 254 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 255 if (Known != Modules.end()) 256 return Known->getValue(); 257 258 return 0; 259 } 260 261 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 262 for(; Context; Context = Context->Parent) { 263 if (Module *Sub = lookupModuleQualified(Name, Context)) 264 return Sub; 265 } 266 267 return findModule(Name); 268 } 269 270 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 271 if (!Context) 272 return findModule(Name); 273 274 return Context->findSubmodule(Name); 275 } 276 277 std::pair<Module *, bool> 278 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 279 bool IsExplicit) { 280 // Try to find an existing module with this name. 281 if (Module *Sub = lookupModuleQualified(Name, Parent)) 282 return std::make_pair(Sub, false); 283 284 // Create a new module with this name. 285 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 286 IsExplicit); 287 if (!Parent) 288 Modules[Name] = Result; 289 return std::make_pair(Result, true); 290 } 291 292 Module * 293 ModuleMap::inferFrameworkModule(StringRef ModuleName, 294 const DirectoryEntry *FrameworkDir, 295 bool IsSystem, 296 Module *Parent) { 297 // Check whether we've already found this module. 298 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 299 return Mod; 300 301 FileManager &FileMgr = SourceMgr->getFileManager(); 302 303 // Look for an umbrella header. 304 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 305 llvm::sys::path::append(UmbrellaName, "Headers"); 306 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 307 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 308 309 // FIXME: If there's no umbrella header, we could probably scan the 310 // framework to load *everything*. But, it's not clear that this is a good 311 // idea. 312 if (!UmbrellaHeader) 313 return 0; 314 315 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 316 /*IsFramework=*/true, /*IsExplicit=*/false); 317 if (IsSystem) 318 Result->IsSystem = IsSystem; 319 320 if (!Parent) 321 Modules[ModuleName] = Result; 322 323 // umbrella header "umbrella-header-name" 324 Result->Umbrella = UmbrellaHeader; 325 Headers[UmbrellaHeader] = Result; 326 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 327 328 // export * 329 Result->Exports.push_back(Module::ExportDecl(0, true)); 330 331 // module * { export * } 332 Result->InferSubmodules = true; 333 Result->InferExportWildcard = true; 334 335 // Look for subframeworks. 336 llvm::error_code EC; 337 SmallString<128> SubframeworksDirName 338 = StringRef(FrameworkDir->getName()); 339 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 340 SmallString<128> SubframeworksDirNameNative; 341 llvm::sys::path::native(SubframeworksDirName.str(), 342 SubframeworksDirNameNative); 343 for (llvm::sys::fs::directory_iterator 344 Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 345 Dir != DirEnd && !EC; Dir.increment(EC)) { 346 if (!StringRef(Dir->path()).endswith(".framework")) 347 continue; 348 349 if (const DirectoryEntry *SubframeworkDir 350 = FileMgr.getDirectory(Dir->path())) { 351 // Note: as an egregious but useful hack, we use the real path here and 352 // check whether it is actually a subdirectory of the parent directory. 353 // This will not be the case if the 'subframework' is actually a symlink 354 // out to a top-level framework. 355 #ifdef LLVM_ON_UNIX 356 char RealSubframeworkDirName[PATH_MAX]; 357 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) { 358 StringRef SubframeworkDirName = RealSubframeworkDirName; 359 360 bool FoundParent = false; 361 do { 362 // Get the parent directory name. 363 SubframeworkDirName 364 = llvm::sys::path::parent_path(SubframeworkDirName); 365 if (SubframeworkDirName.empty()) 366 break; 367 368 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 369 FoundParent = true; 370 break; 371 } 372 } while (true); 373 374 if (!FoundParent) 375 continue; 376 } 377 #endif 378 379 // FIXME: Do we want to warn about subframeworks without umbrella headers? 380 inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, 381 IsSystem, Result); 382 } 383 } 384 385 return Result; 386 } 387 388 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 389 Headers[UmbrellaHeader] = Mod; 390 Mod->Umbrella = UmbrellaHeader; 391 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 392 } 393 394 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 395 Mod->Umbrella = UmbrellaDir; 396 UmbrellaDirs[UmbrellaDir] = Mod; 397 } 398 399 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) { 400 Mod->Headers.push_back(Header); 401 Headers[Header] = Mod; 402 } 403 404 const FileEntry * 405 ModuleMap::getContainingModuleMapFile(Module *Module) { 406 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 407 return 0; 408 409 return SourceMgr->getFileEntryForID( 410 SourceMgr->getFileID(Module->DefinitionLoc)); 411 } 412 413 void ModuleMap::dump() { 414 llvm::errs() << "Modules:"; 415 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 416 MEnd = Modules.end(); 417 M != MEnd; ++M) 418 M->getValue()->print(llvm::errs(), 2); 419 420 llvm::errs() << "Headers:"; 421 for (llvm::DenseMap<const FileEntry *, Module *>::iterator 422 H = Headers.begin(), 423 HEnd = Headers.end(); 424 H != HEnd; ++H) { 425 llvm::errs() << " \"" << H->first->getName() << "\" -> " 426 << H->second->getFullModuleName() << "\n"; 427 } 428 } 429 430 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 431 bool HadError = false; 432 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 433 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 434 Complain); 435 if (Export.getPointer() || Export.getInt()) 436 Mod->Exports.push_back(Export); 437 else 438 HadError = true; 439 } 440 Mod->UnresolvedExports.clear(); 441 return HadError; 442 } 443 444 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 445 if (Loc.isInvalid()) 446 return 0; 447 448 // Use the expansion location to determine which module we're in. 449 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 450 if (!ExpansionLoc.isFileID()) 451 return 0; 452 453 454 const SourceManager &SrcMgr = Loc.getManager(); 455 FileID ExpansionFileID = ExpansionLoc.getFileID(); 456 457 while (const FileEntry *ExpansionFile 458 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 459 // Find the module that owns this header (if any). 460 if (Module *Mod = findModuleForHeader(ExpansionFile)) 461 return Mod; 462 463 // No module owns this header, so look up the inclusion chain to see if 464 // any included header has an associated module. 465 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 466 if (IncludeLoc.isInvalid()) 467 return 0; 468 469 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 470 } 471 472 return 0; 473 } 474 475 //----------------------------------------------------------------------------// 476 // Module map file parser 477 //----------------------------------------------------------------------------// 478 479 namespace clang { 480 /// \brief A token in a module map file. 481 struct MMToken { 482 enum TokenKind { 483 Comma, 484 EndOfFile, 485 HeaderKeyword, 486 Identifier, 487 ExplicitKeyword, 488 ExportKeyword, 489 FrameworkKeyword, 490 ModuleKeyword, 491 Period, 492 UmbrellaKeyword, 493 RequiresKeyword, 494 Star, 495 StringLiteral, 496 LBrace, 497 RBrace, 498 LSquare, 499 RSquare 500 } Kind; 501 502 unsigned Location; 503 unsigned StringLength; 504 const char *StringData; 505 506 void clear() { 507 Kind = EndOfFile; 508 Location = 0; 509 StringLength = 0; 510 StringData = 0; 511 } 512 513 bool is(TokenKind K) const { return Kind == K; } 514 515 SourceLocation getLocation() const { 516 return SourceLocation::getFromRawEncoding(Location); 517 } 518 519 StringRef getString() const { 520 return StringRef(StringData, StringLength); 521 } 522 }; 523 524 class ModuleMapParser { 525 Lexer &L; 526 SourceManager &SourceMgr; 527 DiagnosticsEngine &Diags; 528 ModuleMap ⤅ 529 530 /// \brief The directory that this module map resides in. 531 const DirectoryEntry *Directory; 532 533 /// \brief The directory containing Clang-supplied headers. 534 const DirectoryEntry *BuiltinIncludeDir; 535 536 /// \brief Whether an error occurred. 537 bool HadError; 538 539 /// \brief Default target information, used only for string literal 540 /// parsing. 541 OwningPtr<TargetInfo> Target; 542 543 /// \brief Stores string data for the various string literals referenced 544 /// during parsing. 545 llvm::BumpPtrAllocator StringData; 546 547 /// \brief The current token. 548 MMToken Tok; 549 550 /// \brief The active module. 551 Module *ActiveModule; 552 553 /// \brief Consume the current token and return its location. 554 SourceLocation consumeToken(); 555 556 /// \brief Skip tokens until we reach the a token with the given kind 557 /// (or the end of the file). 558 void skipUntil(MMToken::TokenKind K); 559 560 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 561 ModuleId; 562 bool parseModuleId(ModuleId &Id); 563 void parseModuleDecl(); 564 void parseRequiresDecl(); 565 void parseHeaderDecl(SourceLocation UmbrellaLoc); 566 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 567 void parseExportDecl(); 568 void parseInferredSubmoduleDecl(bool Explicit); 569 570 const DirectoryEntry *getOverriddenHeaderSearchDir(); 571 572 public: 573 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 574 DiagnosticsEngine &Diags, 575 ModuleMap &Map, 576 const DirectoryEntry *Directory, 577 const DirectoryEntry *BuiltinIncludeDir) 578 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 579 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 580 HadError(false), ActiveModule(0) 581 { 582 TargetOptions TargetOpts; 583 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 584 Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts)); 585 586 Tok.clear(); 587 consumeToken(); 588 } 589 590 bool parseModuleMapFile(); 591 }; 592 } 593 594 SourceLocation ModuleMapParser::consumeToken() { 595 retry: 596 SourceLocation Result = Tok.getLocation(); 597 Tok.clear(); 598 599 Token LToken; 600 L.LexFromRawLexer(LToken); 601 Tok.Location = LToken.getLocation().getRawEncoding(); 602 switch (LToken.getKind()) { 603 case tok::raw_identifier: 604 Tok.StringData = LToken.getRawIdentifierData(); 605 Tok.StringLength = LToken.getLength(); 606 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 607 .Case("header", MMToken::HeaderKeyword) 608 .Case("explicit", MMToken::ExplicitKeyword) 609 .Case("export", MMToken::ExportKeyword) 610 .Case("framework", MMToken::FrameworkKeyword) 611 .Case("module", MMToken::ModuleKeyword) 612 .Case("requires", MMToken::RequiresKeyword) 613 .Case("umbrella", MMToken::UmbrellaKeyword) 614 .Default(MMToken::Identifier); 615 break; 616 617 case tok::comma: 618 Tok.Kind = MMToken::Comma; 619 break; 620 621 case tok::eof: 622 Tok.Kind = MMToken::EndOfFile; 623 break; 624 625 case tok::l_brace: 626 Tok.Kind = MMToken::LBrace; 627 break; 628 629 case tok::l_square: 630 Tok.Kind = MMToken::LSquare; 631 break; 632 633 case tok::period: 634 Tok.Kind = MMToken::Period; 635 break; 636 637 case tok::r_brace: 638 Tok.Kind = MMToken::RBrace; 639 break; 640 641 case tok::r_square: 642 Tok.Kind = MMToken::RSquare; 643 break; 644 645 case tok::star: 646 Tok.Kind = MMToken::Star; 647 break; 648 649 case tok::string_literal: { 650 if (LToken.hasUDSuffix()) { 651 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 652 HadError = true; 653 goto retry; 654 } 655 656 // Parse the string literal. 657 LangOptions LangOpts; 658 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 659 if (StringLiteral.hadError) 660 goto retry; 661 662 // Copy the string literal into our string data allocator. 663 unsigned Length = StringLiteral.GetStringLength(); 664 char *Saved = StringData.Allocate<char>(Length + 1); 665 memcpy(Saved, StringLiteral.GetString().data(), Length); 666 Saved[Length] = 0; 667 668 // Form the token. 669 Tok.Kind = MMToken::StringLiteral; 670 Tok.StringData = Saved; 671 Tok.StringLength = Length; 672 break; 673 } 674 675 case tok::comment: 676 goto retry; 677 678 default: 679 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 680 HadError = true; 681 goto retry; 682 } 683 684 return Result; 685 } 686 687 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 688 unsigned braceDepth = 0; 689 unsigned squareDepth = 0; 690 do { 691 switch (Tok.Kind) { 692 case MMToken::EndOfFile: 693 return; 694 695 case MMToken::LBrace: 696 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 697 return; 698 699 ++braceDepth; 700 break; 701 702 case MMToken::LSquare: 703 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 704 return; 705 706 ++squareDepth; 707 break; 708 709 case MMToken::RBrace: 710 if (braceDepth > 0) 711 --braceDepth; 712 else if (Tok.is(K)) 713 return; 714 break; 715 716 case MMToken::RSquare: 717 if (squareDepth > 0) 718 --squareDepth; 719 else if (Tok.is(K)) 720 return; 721 break; 722 723 default: 724 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 725 return; 726 break; 727 } 728 729 consumeToken(); 730 } while (true); 731 } 732 733 /// \brief Parse a module-id. 734 /// 735 /// module-id: 736 /// identifier 737 /// identifier '.' module-id 738 /// 739 /// \returns true if an error occurred, false otherwise. 740 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 741 Id.clear(); 742 do { 743 if (Tok.is(MMToken::Identifier)) { 744 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 745 consumeToken(); 746 } else { 747 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 748 return true; 749 } 750 751 if (!Tok.is(MMToken::Period)) 752 break; 753 754 consumeToken(); 755 } while (true); 756 757 return false; 758 } 759 760 namespace { 761 /// \brief Enumerates the known attributes. 762 enum AttributeKind { 763 /// \brief An unknown attribute. 764 AT_unknown, 765 /// \brief The 'system' attribute. 766 AT_system 767 }; 768 } 769 770 /// \brief Parse a module declaration. 771 /// 772 /// module-declaration: 773 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 774 /// { module-member* } 775 /// 776 /// attributes: 777 /// attribute attributes 778 /// attribute 779 /// 780 /// attribute: 781 /// [ identifier ] 782 /// 783 /// module-member: 784 /// requires-declaration 785 /// header-declaration 786 /// submodule-declaration 787 /// export-declaration 788 /// 789 /// submodule-declaration: 790 /// module-declaration 791 /// inferred-submodule-declaration 792 void ModuleMapParser::parseModuleDecl() { 793 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 794 Tok.is(MMToken::FrameworkKeyword)); 795 // Parse 'explicit' or 'framework' keyword, if present. 796 SourceLocation ExplicitLoc; 797 bool Explicit = false; 798 bool Framework = false; 799 800 // Parse 'explicit' keyword, if present. 801 if (Tok.is(MMToken::ExplicitKeyword)) { 802 ExplicitLoc = consumeToken(); 803 Explicit = true; 804 } 805 806 // Parse 'framework' keyword, if present. 807 if (Tok.is(MMToken::FrameworkKeyword)) { 808 consumeToken(); 809 Framework = true; 810 } 811 812 // Parse 'module' keyword. 813 if (!Tok.is(MMToken::ModuleKeyword)) { 814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 815 consumeToken(); 816 HadError = true; 817 return; 818 } 819 consumeToken(); // 'module' keyword 820 821 // If we have a wildcard for the module name, this is an inferred submodule. 822 // Parse it. 823 if (Tok.is(MMToken::Star)) 824 return parseInferredSubmoduleDecl(Explicit); 825 826 // Parse the module name. 827 ModuleId Id; 828 if (parseModuleId(Id)) { 829 HadError = true; 830 return; 831 } 832 833 if (ActiveModule) { 834 if (Id.size() > 1) { 835 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 836 << SourceRange(Id.front().second, Id.back().second); 837 838 HadError = true; 839 return; 840 } 841 } else if (Id.size() == 1 && Explicit) { 842 // Top-level modules can't be explicit. 843 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 844 Explicit = false; 845 ExplicitLoc = SourceLocation(); 846 HadError = true; 847 } 848 849 Module *PreviousActiveModule = ActiveModule; 850 if (Id.size() > 1) { 851 // This module map defines a submodule. Go find the module of which it 852 // is a submodule. 853 ActiveModule = 0; 854 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 855 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 856 ActiveModule = Next; 857 continue; 858 } 859 860 if (ActiveModule) { 861 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 862 << Id[I].first << ActiveModule->getTopLevelModule(); 863 } else { 864 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 865 } 866 HadError = true; 867 return; 868 } 869 } 870 871 StringRef ModuleName = Id.back().first; 872 SourceLocation ModuleNameLoc = Id.back().second; 873 874 // Parse the optional attribute list. 875 bool IsSystem = false; 876 while (Tok.is(MMToken::LSquare)) { 877 // Consume the '['. 878 SourceLocation LSquareLoc = consumeToken(); 879 880 // Check whether we have an attribute name here. 881 if (!Tok.is(MMToken::Identifier)) { 882 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 883 skipUntil(MMToken::RSquare); 884 if (Tok.is(MMToken::RSquare)) 885 consumeToken(); 886 continue; 887 } 888 889 // Decode the attribute name. 890 AttributeKind Attribute 891 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 892 .Case("system", AT_system) 893 .Default(AT_unknown); 894 switch (Attribute) { 895 case AT_unknown: 896 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 897 << Tok.getString(); 898 break; 899 900 case AT_system: 901 IsSystem = true; 902 break; 903 } 904 consumeToken(); 905 906 // Consume the ']'. 907 if (!Tok.is(MMToken::RSquare)) { 908 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 909 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 910 skipUntil(MMToken::RSquare); 911 } 912 913 if (Tok.is(MMToken::RSquare)) 914 consumeToken(); 915 } 916 917 // Parse the opening brace. 918 if (!Tok.is(MMToken::LBrace)) { 919 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 920 << ModuleName; 921 HadError = true; 922 return; 923 } 924 SourceLocation LBraceLoc = consumeToken(); 925 926 // Determine whether this (sub)module has already been defined. 927 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 928 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 929 // Skip the module definition. 930 skipUntil(MMToken::RBrace); 931 if (Tok.is(MMToken::RBrace)) 932 consumeToken(); 933 else { 934 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 935 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 936 HadError = true; 937 } 938 return; 939 } 940 941 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 942 << ModuleName; 943 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 944 945 // Skip the module definition. 946 skipUntil(MMToken::RBrace); 947 if (Tok.is(MMToken::RBrace)) 948 consumeToken(); 949 950 HadError = true; 951 return; 952 } 953 954 // Start defining this module. 955 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 956 Explicit).first; 957 ActiveModule->DefinitionLoc = ModuleNameLoc; 958 if (IsSystem) 959 ActiveModule->IsSystem = true; 960 961 bool Done = false; 962 do { 963 switch (Tok.Kind) { 964 case MMToken::EndOfFile: 965 case MMToken::RBrace: 966 Done = true; 967 break; 968 969 case MMToken::ExplicitKeyword: 970 case MMToken::FrameworkKeyword: 971 case MMToken::ModuleKeyword: 972 parseModuleDecl(); 973 break; 974 975 case MMToken::ExportKeyword: 976 parseExportDecl(); 977 break; 978 979 case MMToken::RequiresKeyword: 980 parseRequiresDecl(); 981 break; 982 983 case MMToken::UmbrellaKeyword: { 984 SourceLocation UmbrellaLoc = consumeToken(); 985 if (Tok.is(MMToken::HeaderKeyword)) 986 parseHeaderDecl(UmbrellaLoc); 987 else 988 parseUmbrellaDirDecl(UmbrellaLoc); 989 break; 990 } 991 992 case MMToken::HeaderKeyword: 993 parseHeaderDecl(SourceLocation()); 994 break; 995 996 default: 997 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 998 consumeToken(); 999 break; 1000 } 1001 } while (!Done); 1002 1003 if (Tok.is(MMToken::RBrace)) 1004 consumeToken(); 1005 else { 1006 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1007 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1008 HadError = true; 1009 } 1010 1011 // We're done parsing this module. Pop back to the previous module. 1012 ActiveModule = PreviousActiveModule; 1013 } 1014 1015 /// \brief Parse a requires declaration. 1016 /// 1017 /// requires-declaration: 1018 /// 'requires' feature-list 1019 /// 1020 /// feature-list: 1021 /// identifier ',' feature-list 1022 /// identifier 1023 void ModuleMapParser::parseRequiresDecl() { 1024 assert(Tok.is(MMToken::RequiresKeyword)); 1025 1026 // Parse 'requires' keyword. 1027 consumeToken(); 1028 1029 // Parse the feature-list. 1030 do { 1031 if (!Tok.is(MMToken::Identifier)) { 1032 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1033 HadError = true; 1034 return; 1035 } 1036 1037 // Consume the feature name. 1038 std::string Feature = Tok.getString(); 1039 consumeToken(); 1040 1041 // Add this feature. 1042 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 1043 1044 if (!Tok.is(MMToken::Comma)) 1045 break; 1046 1047 // Consume the comma. 1048 consumeToken(); 1049 } while (true); 1050 } 1051 1052 /// \brief Append to \p Paths the set of paths needed to get to the 1053 /// subframework in which the given module lives. 1054 static void appendSubframeworkPaths(Module *Mod, 1055 llvm::SmallVectorImpl<char> &Path) { 1056 // Collect the framework names from the given module to the top-level module. 1057 llvm::SmallVector<StringRef, 2> Paths; 1058 for (; Mod; Mod = Mod->Parent) { 1059 if (Mod->IsFramework) 1060 Paths.push_back(Mod->Name); 1061 } 1062 1063 if (Paths.empty()) 1064 return; 1065 1066 // Add Frameworks/Name.framework for each subframework. 1067 for (unsigned I = Paths.size() - 1; I != 0; --I) { 1068 llvm::sys::path::append(Path, "Frameworks"); 1069 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 1070 } 1071 } 1072 1073 /// \brief Determine whether the given file name is the name of a builtin 1074 /// header, supplied by Clang to replace, override, or augment existing system 1075 /// headers. 1076 static bool isBuiltinHeader(StringRef FileName) { 1077 return llvm::StringSwitch<bool>(FileName) 1078 .Case("float.h", true) 1079 .Case("iso646.h", true) 1080 .Case("limits.h", true) 1081 .Case("stdalign.h", true) 1082 .Case("stdarg.h", true) 1083 .Case("stdbool.h", true) 1084 .Case("stddef.h", true) 1085 .Case("stdint.h", true) 1086 .Case("tgmath.h", true) 1087 .Case("unwind.h", true) 1088 .Default(false); 1089 } 1090 1091 /// \brief Parse a header declaration. 1092 /// 1093 /// header-declaration: 1094 /// 'umbrella'[opt] 'header' string-literal 1095 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) { 1096 assert(Tok.is(MMToken::HeaderKeyword)); 1097 consumeToken(); 1098 1099 bool Umbrella = UmbrellaLoc.isValid(); 1100 1101 // Parse the header name. 1102 if (!Tok.is(MMToken::StringLiteral)) { 1103 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1104 << "header"; 1105 HadError = true; 1106 return; 1107 } 1108 std::string FileName = Tok.getString(); 1109 SourceLocation FileNameLoc = consumeToken(); 1110 1111 // Check whether we already have an umbrella. 1112 if (Umbrella && ActiveModule->Umbrella) { 1113 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1114 << ActiveModule->getFullModuleName(); 1115 HadError = true; 1116 return; 1117 } 1118 1119 // Look for this file. 1120 const FileEntry *File = 0; 1121 const FileEntry *BuiltinFile = 0; 1122 SmallString<128> PathName; 1123 if (llvm::sys::path::is_absolute(FileName)) { 1124 PathName = FileName; 1125 File = SourceMgr.getFileManager().getFile(PathName); 1126 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1127 PathName = Dir->getName(); 1128 llvm::sys::path::append(PathName, FileName); 1129 File = SourceMgr.getFileManager().getFile(PathName); 1130 } else { 1131 // Search for the header file within the search directory. 1132 PathName = Directory->getName(); 1133 unsigned PathLength = PathName.size(); 1134 1135 if (ActiveModule->isPartOfFramework()) { 1136 appendSubframeworkPaths(ActiveModule, PathName); 1137 1138 // Check whether this file is in the public headers. 1139 llvm::sys::path::append(PathName, "Headers"); 1140 llvm::sys::path::append(PathName, FileName); 1141 File = SourceMgr.getFileManager().getFile(PathName); 1142 1143 if (!File) { 1144 // Check whether this file is in the private headers. 1145 PathName.resize(PathLength); 1146 llvm::sys::path::append(PathName, "PrivateHeaders"); 1147 llvm::sys::path::append(PathName, FileName); 1148 File = SourceMgr.getFileManager().getFile(PathName); 1149 } 1150 } else { 1151 // Lookup for normal headers. 1152 llvm::sys::path::append(PathName, FileName); 1153 File = SourceMgr.getFileManager().getFile(PathName); 1154 1155 // If this is a system module with a top-level header, this header 1156 // may have a counterpart (or replacement) in the set of headers 1157 // supplied by Clang. Find that builtin header. 1158 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir && 1159 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) { 1160 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1161 llvm::sys::path::append(BuiltinPathName, FileName); 1162 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1163 1164 // If Clang supplies this header but the underlying system does not, 1165 // just silently swap in our builtin version. Otherwise, we'll end 1166 // up adding both (later). 1167 if (!File && BuiltinFile) { 1168 File = BuiltinFile; 1169 BuiltinFile = 0; 1170 } 1171 } 1172 } 1173 } 1174 1175 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1176 // Come up with a lazy way to do this. 1177 if (File) { 1178 if (const Module *OwningModule = Map.Headers[File]) { 1179 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1180 << FileName << OwningModule->getFullModuleName(); 1181 HadError = true; 1182 } else if (Umbrella) { 1183 const DirectoryEntry *UmbrellaDir = File->getDir(); 1184 if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 1185 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1186 << OwningModule->getFullModuleName(); 1187 HadError = true; 1188 } else { 1189 // Record this umbrella header. 1190 Map.setUmbrellaHeader(ActiveModule, File); 1191 } 1192 } else { 1193 // Record this header. 1194 Map.addHeader(ActiveModule, File); 1195 1196 // If there is a builtin counterpart to this file, add it now. 1197 if (BuiltinFile) 1198 Map.addHeader(ActiveModule, BuiltinFile); 1199 } 1200 } else { 1201 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1202 << Umbrella << FileName; 1203 HadError = true; 1204 } 1205 } 1206 1207 /// \brief Parse an umbrella directory declaration. 1208 /// 1209 /// umbrella-dir-declaration: 1210 /// umbrella string-literal 1211 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1212 // Parse the directory name. 1213 if (!Tok.is(MMToken::StringLiteral)) { 1214 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1215 << "umbrella"; 1216 HadError = true; 1217 return; 1218 } 1219 1220 std::string DirName = Tok.getString(); 1221 SourceLocation DirNameLoc = consumeToken(); 1222 1223 // Check whether we already have an umbrella. 1224 if (ActiveModule->Umbrella) { 1225 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1226 << ActiveModule->getFullModuleName(); 1227 HadError = true; 1228 return; 1229 } 1230 1231 // Look for this file. 1232 const DirectoryEntry *Dir = 0; 1233 if (llvm::sys::path::is_absolute(DirName)) 1234 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1235 else { 1236 SmallString<128> PathName; 1237 PathName = Directory->getName(); 1238 llvm::sys::path::append(PathName, DirName); 1239 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1240 } 1241 1242 if (!Dir) { 1243 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1244 << DirName; 1245 HadError = true; 1246 return; 1247 } 1248 1249 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1250 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1251 << OwningModule->getFullModuleName(); 1252 HadError = true; 1253 return; 1254 } 1255 1256 // Record this umbrella directory. 1257 Map.setUmbrellaDir(ActiveModule, Dir); 1258 } 1259 1260 /// \brief Parse a module export declaration. 1261 /// 1262 /// export-declaration: 1263 /// 'export' wildcard-module-id 1264 /// 1265 /// wildcard-module-id: 1266 /// identifier 1267 /// '*' 1268 /// identifier '.' wildcard-module-id 1269 void ModuleMapParser::parseExportDecl() { 1270 assert(Tok.is(MMToken::ExportKeyword)); 1271 SourceLocation ExportLoc = consumeToken(); 1272 1273 // Parse the module-id with an optional wildcard at the end. 1274 ModuleId ParsedModuleId; 1275 bool Wildcard = false; 1276 do { 1277 if (Tok.is(MMToken::Identifier)) { 1278 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1279 Tok.getLocation())); 1280 consumeToken(); 1281 1282 if (Tok.is(MMToken::Period)) { 1283 consumeToken(); 1284 continue; 1285 } 1286 1287 break; 1288 } 1289 1290 if(Tok.is(MMToken::Star)) { 1291 Wildcard = true; 1292 consumeToken(); 1293 break; 1294 } 1295 1296 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1297 HadError = true; 1298 return; 1299 } while (true); 1300 1301 Module::UnresolvedExportDecl Unresolved = { 1302 ExportLoc, ParsedModuleId, Wildcard 1303 }; 1304 ActiveModule->UnresolvedExports.push_back(Unresolved); 1305 } 1306 1307 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 1308 assert(Tok.is(MMToken::Star)); 1309 SourceLocation StarLoc = consumeToken(); 1310 bool Failed = false; 1311 1312 // Inferred modules must be submodules. 1313 if (!ActiveModule) { 1314 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1315 Failed = true; 1316 } 1317 1318 // Inferred modules must have umbrella directories. 1319 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1320 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1321 Failed = true; 1322 } 1323 1324 // Check for redefinition of an inferred module. 1325 if (!Failed && ActiveModule->InferSubmodules) { 1326 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1327 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1328 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1329 diag::note_mmap_prev_definition); 1330 Failed = true; 1331 } 1332 1333 // If there were any problems with this inferred submodule, skip its body. 1334 if (Failed) { 1335 if (Tok.is(MMToken::LBrace)) { 1336 consumeToken(); 1337 skipUntil(MMToken::RBrace); 1338 if (Tok.is(MMToken::RBrace)) 1339 consumeToken(); 1340 } 1341 HadError = true; 1342 return; 1343 } 1344 1345 // Note that we have an inferred submodule. 1346 ActiveModule->InferSubmodules = true; 1347 ActiveModule->InferredSubmoduleLoc = StarLoc; 1348 ActiveModule->InferExplicitSubmodules = Explicit; 1349 1350 // Parse the opening brace. 1351 if (!Tok.is(MMToken::LBrace)) { 1352 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1353 HadError = true; 1354 return; 1355 } 1356 SourceLocation LBraceLoc = consumeToken(); 1357 1358 // Parse the body of the inferred submodule. 1359 bool Done = false; 1360 do { 1361 switch (Tok.Kind) { 1362 case MMToken::EndOfFile: 1363 case MMToken::RBrace: 1364 Done = true; 1365 break; 1366 1367 case MMToken::ExportKeyword: { 1368 consumeToken(); 1369 if (Tok.is(MMToken::Star)) 1370 ActiveModule->InferExportWildcard = true; 1371 else 1372 Diags.Report(Tok.getLocation(), 1373 diag::err_mmap_expected_export_wildcard); 1374 consumeToken(); 1375 break; 1376 } 1377 1378 case MMToken::ExplicitKeyword: 1379 case MMToken::ModuleKeyword: 1380 case MMToken::HeaderKeyword: 1381 case MMToken::UmbrellaKeyword: 1382 default: 1383 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 1384 consumeToken(); 1385 break; 1386 } 1387 } while (!Done); 1388 1389 if (Tok.is(MMToken::RBrace)) 1390 consumeToken(); 1391 else { 1392 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1393 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1394 HadError = true; 1395 } 1396 } 1397 1398 /// \brief If there is a specific header search directory due the presence 1399 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1400 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1401 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1402 // If we have an umbrella directory, use that. 1403 if (Mod->hasUmbrellaDir()) 1404 return Mod->getUmbrellaDir(); 1405 1406 // If we have a framework directory, stop looking. 1407 if (Mod->IsFramework) 1408 return 0; 1409 } 1410 1411 return 0; 1412 } 1413 1414 /// \brief Parse a module map file. 1415 /// 1416 /// module-map-file: 1417 /// module-declaration* 1418 bool ModuleMapParser::parseModuleMapFile() { 1419 do { 1420 switch (Tok.Kind) { 1421 case MMToken::EndOfFile: 1422 return HadError; 1423 1424 case MMToken::ExplicitKeyword: 1425 case MMToken::ModuleKeyword: 1426 case MMToken::FrameworkKeyword: 1427 parseModuleDecl(); 1428 break; 1429 1430 case MMToken::Comma: 1431 case MMToken::ExportKeyword: 1432 case MMToken::HeaderKeyword: 1433 case MMToken::Identifier: 1434 case MMToken::LBrace: 1435 case MMToken::LSquare: 1436 case MMToken::Period: 1437 case MMToken::RBrace: 1438 case MMToken::RSquare: 1439 case MMToken::RequiresKeyword: 1440 case MMToken::Star: 1441 case MMToken::StringLiteral: 1442 case MMToken::UmbrellaKeyword: 1443 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1444 HadError = true; 1445 consumeToken(); 1446 break; 1447 } 1448 } while (true); 1449 } 1450 1451 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1452 assert(Target != 0 && "Missing target information"); 1453 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1454 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1455 if (!Buffer) 1456 return true; 1457 1458 // Parse this module map file. 1459 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1460 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1461 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir(), 1462 BuiltinIncludeDir); 1463 bool Result = Parser.parseModuleMapFile(); 1464 Diags->getClient()->EndSourceFile(); 1465 1466 return Result; 1467 } 1468