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