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