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