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/DiagnosticOptions.h" 20 #include "clang/Basic/FileManager.h" 21 #include "clang/Basic/TargetInfo.h" 22 #include "clang/Basic/TargetOptions.h" 23 #include "llvm/Support/Allocator.h" 24 #include "llvm/Support/FileSystem.h" 25 #include "llvm/Support/Host.h" 26 #include "llvm/Support/PathV2.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/ADT/StringSwitch.h" 30 #include <stdlib.h> 31 using namespace clang; 32 33 Module::ExportDecl 34 ModuleMap::resolveExport(Module *Mod, 35 const Module::UnresolvedExportDecl &Unresolved, 36 bool Complain) { 37 // We may have just a wildcard. 38 if (Unresolved.Id.empty()) { 39 assert(Unresolved.Wildcard && "Invalid unresolved export"); 40 return Module::ExportDecl(0, true); 41 } 42 43 // Find the starting module. 44 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 45 if (!Context) { 46 if (Complain) 47 Diags->Report(Unresolved.Id[0].second, 48 diag::err_mmap_missing_module_unqualified) 49 << Unresolved.Id[0].first << Mod->getFullModuleName(); 50 51 return Module::ExportDecl(); 52 } 53 54 // Dig into the module path. 55 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 56 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 57 Context); 58 if (!Sub) { 59 if (Complain) 60 Diags->Report(Unresolved.Id[I].second, 61 diag::err_mmap_missing_module_qualified) 62 << Unresolved.Id[I].first << Context->getFullModuleName() 63 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 64 65 return Module::ExportDecl(); 66 } 67 68 Context = Sub; 69 } 70 71 return Module::ExportDecl(Context, Unresolved.Wildcard); 72 } 73 74 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, 75 const LangOptions &LangOpts, const TargetInfo *Target) 76 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0) 77 { 78 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 79 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( 80 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions)); 81 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 82 SourceMgr = new SourceManager(*Diags, FileMgr); 83 } 84 85 ModuleMap::~ModuleMap() { 86 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 87 IEnd = Modules.end(); 88 I != IEnd; ++I) { 89 delete I->getValue(); 90 } 91 92 delete SourceMgr; 93 } 94 95 void ModuleMap::setTarget(const TargetInfo &Target) { 96 assert((!this->Target || this->Target == &Target) && 97 "Improper target override"); 98 this->Target = &Target; 99 } 100 101 /// \brief "Sanitize" a filename so that it can be used as an identifier. 102 static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 103 SmallVectorImpl<char> &Buffer) { 104 if (Name.empty()) 105 return Name; 106 107 // Check whether the filename is already an identifier; this is the common 108 // case. 109 bool isIdentifier = true; 110 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 111 if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0)) 112 continue; 113 114 isIdentifier = false; 115 break; 116 } 117 118 if (!isIdentifier) { 119 // If we don't already have something with the form of an identifier, 120 // create a buffer with the sanitized name. 121 Buffer.clear(); 122 if (isdigit(Name[0])) 123 Buffer.push_back('_'); 124 Buffer.reserve(Buffer.size() + Name.size()); 125 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 126 if (isalnum(Name[I]) || isspace(Name[I])) 127 Buffer.push_back(Name[I]); 128 else 129 Buffer.push_back('_'); 130 } 131 132 Name = StringRef(Buffer.data(), Buffer.size()); 133 } 134 135 while (llvm::StringSwitch<bool>(Name) 136 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 137 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 138 #include "clang/Basic/TokenKinds.def" 139 .Default(false)) { 140 if (Name.data() != Buffer.data()) 141 Buffer.append(Name.begin(), Name.end()); 142 Buffer.push_back('_'); 143 Name = StringRef(Buffer.data(), Buffer.size()); 144 } 145 146 return Name; 147 } 148 149 Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 150 HeadersMap::iterator Known = Headers.find(File); 151 if (Known != Headers.end()) { 152 // If a header is not available, don't report that it maps to anything. 153 if (!Known->second.isAvailable()) 154 return 0; 155 156 return Known->second.getModule(); 157 } 158 159 const DirectoryEntry *Dir = File->getDir(); 160 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 161 StringRef DirName = Dir->getName(); 162 163 // Keep walking up the directory hierarchy, looking for a directory with 164 // an umbrella header. 165 do { 166 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 167 = UmbrellaDirs.find(Dir); 168 if (KnownDir != UmbrellaDirs.end()) { 169 Module *Result = KnownDir->second; 170 171 // Search up the module stack until we find a module with an umbrella 172 // directory. 173 Module *UmbrellaModule = Result; 174 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 175 UmbrellaModule = UmbrellaModule->Parent; 176 177 if (UmbrellaModule->InferSubmodules) { 178 // Infer submodules for each of the directories we found between 179 // the directory of the umbrella header and the directory where 180 // the actual header is located. 181 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 182 183 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 184 // Find or create the module that corresponds to this directory name. 185 SmallString<32> NameBuf; 186 StringRef Name = sanitizeFilenameAsIdentifier( 187 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 188 NameBuf); 189 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 190 Explicit).first; 191 192 // Associate the module and the directory. 193 UmbrellaDirs[SkippedDirs[I-1]] = Result; 194 195 // If inferred submodules export everything they import, add a 196 // wildcard to the set of exports. 197 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 198 Result->Exports.push_back(Module::ExportDecl(0, true)); 199 } 200 201 // Infer a submodule with the same name as this header file. 202 SmallString<32> NameBuf; 203 StringRef Name = sanitizeFilenameAsIdentifier( 204 llvm::sys::path::stem(File->getName()), NameBuf); 205 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 206 Explicit).first; 207 Result->TopHeaders.insert(File); 208 209 // If inferred submodules export everything they import, add a 210 // wildcard to the set of exports. 211 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 212 Result->Exports.push_back(Module::ExportDecl(0, true)); 213 } else { 214 // Record each of the directories we stepped through as being part of 215 // the module we found, since the umbrella header covers them all. 216 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 217 UmbrellaDirs[SkippedDirs[I]] = Result; 218 } 219 220 Headers[File] = KnownHeader(Result, /*Excluded=*/false); 221 222 // If a header corresponds to an unavailable module, don't report 223 // that it maps to anything. 224 if (!Result->isAvailable()) 225 return 0; 226 227 return Result; 228 } 229 230 SkippedDirs.push_back(Dir); 231 232 // Retrieve our parent path. 233 DirName = llvm::sys::path::parent_path(DirName); 234 if (DirName.empty()) 235 break; 236 237 // Resolve the parent path to a directory entry. 238 Dir = SourceMgr->getFileManager().getDirectory(DirName); 239 } while (Dir); 240 241 return 0; 242 } 243 244 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) { 245 HeadersMap::iterator Known = Headers.find(Header); 246 if (Known != Headers.end()) 247 return !Known->second.isAvailable(); 248 249 const DirectoryEntry *Dir = Header->getDir(); 250 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 251 StringRef DirName = Dir->getName(); 252 253 // Keep walking up the directory hierarchy, looking for a directory with 254 // an umbrella header. 255 do { 256 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 257 = UmbrellaDirs.find(Dir); 258 if (KnownDir != UmbrellaDirs.end()) { 259 Module *Found = KnownDir->second; 260 if (!Found->isAvailable()) 261 return true; 262 263 // Search up the module stack until we find a module with an umbrella 264 // directory. 265 Module *UmbrellaModule = Found; 266 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 267 UmbrellaModule = UmbrellaModule->Parent; 268 269 if (UmbrellaModule->InferSubmodules) { 270 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 271 // Find or create the module that corresponds to this directory name. 272 SmallString<32> NameBuf; 273 StringRef Name = sanitizeFilenameAsIdentifier( 274 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 275 NameBuf); 276 Found = lookupModuleQualified(Name, Found); 277 if (!Found) 278 return false; 279 if (!Found->isAvailable()) 280 return true; 281 } 282 283 // Infer a submodule with the same name as this header file. 284 SmallString<32> NameBuf; 285 StringRef Name = sanitizeFilenameAsIdentifier( 286 llvm::sys::path::stem(Header->getName()), 287 NameBuf); 288 Found = lookupModuleQualified(Name, Found); 289 if (!Found) 290 return false; 291 } 292 293 return !Found->isAvailable(); 294 } 295 296 SkippedDirs.push_back(Dir); 297 298 // Retrieve our parent path. 299 DirName = llvm::sys::path::parent_path(DirName); 300 if (DirName.empty()) 301 break; 302 303 // Resolve the parent path to a directory entry. 304 Dir = SourceMgr->getFileManager().getDirectory(DirName); 305 } while (Dir); 306 307 return false; 308 } 309 310 Module *ModuleMap::findModule(StringRef Name) { 311 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 312 if (Known != Modules.end()) 313 return Known->getValue(); 314 315 return 0; 316 } 317 318 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 319 for(; Context; Context = Context->Parent) { 320 if (Module *Sub = lookupModuleQualified(Name, Context)) 321 return Sub; 322 } 323 324 return findModule(Name); 325 } 326 327 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 328 if (!Context) 329 return findModule(Name); 330 331 return Context->findSubmodule(Name); 332 } 333 334 std::pair<Module *, bool> 335 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 336 bool IsExplicit) { 337 // Try to find an existing module with this name. 338 if (Module *Sub = lookupModuleQualified(Name, Parent)) 339 return std::make_pair(Sub, false); 340 341 // Create a new module with this name. 342 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 343 IsExplicit); 344 if (!Parent) 345 Modules[Name] = Result; 346 return std::make_pair(Result, true); 347 } 348 349 Module * 350 ModuleMap::inferFrameworkModule(StringRef ModuleName, 351 const DirectoryEntry *FrameworkDir, 352 bool IsSystem, 353 Module *Parent) { 354 // Check whether we've already found this module. 355 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 356 return Mod; 357 358 FileManager &FileMgr = SourceMgr->getFileManager(); 359 360 // Look for an umbrella header. 361 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 362 llvm::sys::path::append(UmbrellaName, "Headers"); 363 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 364 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 365 366 // FIXME: If there's no umbrella header, we could probably scan the 367 // framework to load *everything*. But, it's not clear that this is a good 368 // idea. 369 if (!UmbrellaHeader) 370 return 0; 371 372 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 373 /*IsFramework=*/true, /*IsExplicit=*/false); 374 if (IsSystem) 375 Result->IsSystem = IsSystem; 376 377 if (!Parent) 378 Modules[ModuleName] = Result; 379 380 // umbrella header "umbrella-header-name" 381 Result->Umbrella = UmbrellaHeader; 382 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false); 383 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 384 385 // export * 386 Result->Exports.push_back(Module::ExportDecl(0, true)); 387 388 // module * { export * } 389 Result->InferSubmodules = true; 390 Result->InferExportWildcard = true; 391 392 // Look for subframeworks. 393 llvm::error_code EC; 394 SmallString<128> SubframeworksDirName 395 = StringRef(FrameworkDir->getName()); 396 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 397 SmallString<128> SubframeworksDirNameNative; 398 llvm::sys::path::native(SubframeworksDirName.str(), 399 SubframeworksDirNameNative); 400 for (llvm::sys::fs::directory_iterator 401 Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 402 Dir != DirEnd && !EC; Dir.increment(EC)) { 403 if (!StringRef(Dir->path()).endswith(".framework")) 404 continue; 405 406 if (const DirectoryEntry *SubframeworkDir 407 = FileMgr.getDirectory(Dir->path())) { 408 // Note: as an egregious but useful hack, we use the real path here and 409 // check whether it is actually a subdirectory of the parent directory. 410 // This will not be the case if the 'subframework' is actually a symlink 411 // out to a top-level framework. 412 #ifdef LLVM_ON_UNIX 413 char RealSubframeworkDirName[PATH_MAX]; 414 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) { 415 StringRef SubframeworkDirName = RealSubframeworkDirName; 416 417 bool FoundParent = false; 418 do { 419 // Get the parent directory name. 420 SubframeworkDirName 421 = llvm::sys::path::parent_path(SubframeworkDirName); 422 if (SubframeworkDirName.empty()) 423 break; 424 425 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 426 FoundParent = true; 427 break; 428 } 429 } while (true); 430 431 if (!FoundParent) 432 continue; 433 } 434 #endif 435 436 // FIXME: Do we want to warn about subframeworks without umbrella headers? 437 SmallString<32> NameBuf; 438 inferFrameworkModule(sanitizeFilenameAsIdentifier( 439 llvm::sys::path::stem(Dir->path()), NameBuf), 440 SubframeworkDir, IsSystem, Result); 441 } 442 } 443 444 return Result; 445 } 446 447 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 448 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false); 449 Mod->Umbrella = UmbrellaHeader; 450 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 451 } 452 453 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 454 Mod->Umbrella = UmbrellaDir; 455 UmbrellaDirs[UmbrellaDir] = Mod; 456 } 457 458 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 459 bool Excluded) { 460 if (Excluded) 461 Mod->ExcludedHeaders.push_back(Header); 462 else 463 Mod->Headers.push_back(Header); 464 Headers[Header] = KnownHeader(Mod, Excluded); 465 } 466 467 const FileEntry * 468 ModuleMap::getContainingModuleMapFile(Module *Module) { 469 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 470 return 0; 471 472 return SourceMgr->getFileEntryForID( 473 SourceMgr->getFileID(Module->DefinitionLoc)); 474 } 475 476 void ModuleMap::dump() { 477 llvm::errs() << "Modules:"; 478 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 479 MEnd = Modules.end(); 480 M != MEnd; ++M) 481 M->getValue()->print(llvm::errs(), 2); 482 483 llvm::errs() << "Headers:"; 484 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 485 H != HEnd; ++H) { 486 llvm::errs() << " \"" << H->first->getName() << "\" -> " 487 << H->second.getModule()->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 ExcludeKeyword, 549 ExplicitKeyword, 550 ExportKeyword, 551 FrameworkKeyword, 552 ModuleKeyword, 553 Period, 554 UmbrellaKeyword, 555 RequiresKeyword, 556 Star, 557 StringLiteral, 558 LBrace, 559 RBrace, 560 LSquare, 561 RSquare 562 } Kind; 563 564 unsigned Location; 565 unsigned StringLength; 566 const char *StringData; 567 568 void clear() { 569 Kind = EndOfFile; 570 Location = 0; 571 StringLength = 0; 572 StringData = 0; 573 } 574 575 bool is(TokenKind K) const { return Kind == K; } 576 577 SourceLocation getLocation() const { 578 return SourceLocation::getFromRawEncoding(Location); 579 } 580 581 StringRef getString() const { 582 return StringRef(StringData, StringLength); 583 } 584 }; 585 586 class ModuleMapParser { 587 Lexer &L; 588 SourceManager &SourceMgr; 589 590 /// \brief Default target information, used only for string literal 591 /// parsing. 592 const TargetInfo *Target; 593 594 DiagnosticsEngine &Diags; 595 ModuleMap ⤅ 596 597 /// \brief The directory that this module map resides in. 598 const DirectoryEntry *Directory; 599 600 /// \brief The directory containing Clang-supplied headers. 601 const DirectoryEntry *BuiltinIncludeDir; 602 603 /// \brief Whether an error occurred. 604 bool HadError; 605 606 /// \brief Stores string data for the various string literals referenced 607 /// during parsing. 608 llvm::BumpPtrAllocator StringData; 609 610 /// \brief The current token. 611 MMToken Tok; 612 613 /// \brief The active module. 614 Module *ActiveModule; 615 616 /// \brief Consume the current token and return its location. 617 SourceLocation consumeToken(); 618 619 /// \brief Skip tokens until we reach the a token with the given kind 620 /// (or the end of the file). 621 void skipUntil(MMToken::TokenKind K); 622 623 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 624 ModuleId; 625 bool parseModuleId(ModuleId &Id); 626 void parseModuleDecl(); 627 void parseRequiresDecl(); 628 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc); 629 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 630 void parseExportDecl(); 631 void parseInferredSubmoduleDecl(bool Explicit); 632 633 const DirectoryEntry *getOverriddenHeaderSearchDir(); 634 635 public: 636 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 637 const TargetInfo *Target, 638 DiagnosticsEngine &Diags, 639 ModuleMap &Map, 640 const DirectoryEntry *Directory, 641 const DirectoryEntry *BuiltinIncludeDir) 642 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 643 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 644 HadError(false), ActiveModule(0) 645 { 646 Tok.clear(); 647 consumeToken(); 648 } 649 650 bool parseModuleMapFile(); 651 }; 652 } 653 654 SourceLocation ModuleMapParser::consumeToken() { 655 retry: 656 SourceLocation Result = Tok.getLocation(); 657 Tok.clear(); 658 659 Token LToken; 660 L.LexFromRawLexer(LToken); 661 Tok.Location = LToken.getLocation().getRawEncoding(); 662 switch (LToken.getKind()) { 663 case tok::raw_identifier: 664 Tok.StringData = LToken.getRawIdentifierData(); 665 Tok.StringLength = LToken.getLength(); 666 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 667 .Case("header", MMToken::HeaderKeyword) 668 .Case("exclude", MMToken::ExcludeKeyword) 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, SourceLocation()); 1048 else 1049 parseUmbrellaDirDecl(UmbrellaLoc); 1050 break; 1051 } 1052 1053 case MMToken::ExcludeKeyword: { 1054 SourceLocation ExcludeLoc = consumeToken(); 1055 if (Tok.is(MMToken::HeaderKeyword)) { 1056 parseHeaderDecl(SourceLocation(), ExcludeLoc); 1057 } else { 1058 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1059 << "exclude"; 1060 } 1061 break; 1062 } 1063 1064 case MMToken::HeaderKeyword: 1065 parseHeaderDecl(SourceLocation(), SourceLocation()); 1066 break; 1067 1068 default: 1069 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1070 consumeToken(); 1071 break; 1072 } 1073 } while (!Done); 1074 1075 if (Tok.is(MMToken::RBrace)) 1076 consumeToken(); 1077 else { 1078 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1079 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1080 HadError = true; 1081 } 1082 1083 // We're done parsing this module. Pop back to the previous module. 1084 ActiveModule = PreviousActiveModule; 1085 } 1086 1087 /// \brief Parse a requires declaration. 1088 /// 1089 /// requires-declaration: 1090 /// 'requires' feature-list 1091 /// 1092 /// feature-list: 1093 /// identifier ',' feature-list 1094 /// identifier 1095 void ModuleMapParser::parseRequiresDecl() { 1096 assert(Tok.is(MMToken::RequiresKeyword)); 1097 1098 // Parse 'requires' keyword. 1099 consumeToken(); 1100 1101 // Parse the feature-list. 1102 do { 1103 if (!Tok.is(MMToken::Identifier)) { 1104 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1105 HadError = true; 1106 return; 1107 } 1108 1109 // Consume the feature name. 1110 std::string Feature = Tok.getString(); 1111 consumeToken(); 1112 1113 // Add this feature. 1114 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 1115 1116 if (!Tok.is(MMToken::Comma)) 1117 break; 1118 1119 // Consume the comma. 1120 consumeToken(); 1121 } while (true); 1122 } 1123 1124 /// \brief Append to \p Paths the set of paths needed to get to the 1125 /// subframework in which the given module lives. 1126 static void appendSubframeworkPaths(Module *Mod, 1127 llvm::SmallVectorImpl<char> &Path) { 1128 // Collect the framework names from the given module to the top-level module. 1129 llvm::SmallVector<StringRef, 2> Paths; 1130 for (; Mod; Mod = Mod->Parent) { 1131 if (Mod->IsFramework) 1132 Paths.push_back(Mod->Name); 1133 } 1134 1135 if (Paths.empty()) 1136 return; 1137 1138 // Add Frameworks/Name.framework for each subframework. 1139 for (unsigned I = Paths.size() - 1; I != 0; --I) { 1140 llvm::sys::path::append(Path, "Frameworks"); 1141 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 1142 } 1143 } 1144 1145 /// \brief Determine whether the given file name is the name of a builtin 1146 /// header, supplied by Clang to replace, override, or augment existing system 1147 /// headers. 1148 static bool isBuiltinHeader(StringRef FileName) { 1149 return llvm::StringSwitch<bool>(FileName) 1150 .Case("float.h", true) 1151 .Case("iso646.h", true) 1152 .Case("limits.h", true) 1153 .Case("stdalign.h", true) 1154 .Case("stdarg.h", true) 1155 .Case("stdbool.h", true) 1156 .Case("stddef.h", true) 1157 .Case("stdint.h", true) 1158 .Case("tgmath.h", true) 1159 .Case("unwind.h", true) 1160 .Default(false); 1161 } 1162 1163 /// \brief Parse a header declaration. 1164 /// 1165 /// header-declaration: 1166 /// 'umbrella'[opt] 'header' string-literal 1167 /// 'exclude'[opt] 'header' string-literal 1168 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc, 1169 SourceLocation ExcludeLoc) { 1170 assert(Tok.is(MMToken::HeaderKeyword)); 1171 consumeToken(); 1172 1173 bool Umbrella = UmbrellaLoc.isValid(); 1174 bool Exclude = ExcludeLoc.isValid(); 1175 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'"); 1176 // Parse the header name. 1177 if (!Tok.is(MMToken::StringLiteral)) { 1178 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1179 << "header"; 1180 HadError = true; 1181 return; 1182 } 1183 std::string FileName = Tok.getString(); 1184 SourceLocation FileNameLoc = consumeToken(); 1185 1186 // Check whether we already have an umbrella. 1187 if (Umbrella && ActiveModule->Umbrella) { 1188 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1189 << ActiveModule->getFullModuleName(); 1190 HadError = true; 1191 return; 1192 } 1193 1194 // Look for this file. 1195 const FileEntry *File = 0; 1196 const FileEntry *BuiltinFile = 0; 1197 SmallString<128> PathName; 1198 if (llvm::sys::path::is_absolute(FileName)) { 1199 PathName = FileName; 1200 File = SourceMgr.getFileManager().getFile(PathName); 1201 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1202 PathName = Dir->getName(); 1203 llvm::sys::path::append(PathName, FileName); 1204 File = SourceMgr.getFileManager().getFile(PathName); 1205 } else { 1206 // Search for the header file within the search directory. 1207 PathName = Directory->getName(); 1208 unsigned PathLength = PathName.size(); 1209 1210 if (ActiveModule->isPartOfFramework()) { 1211 appendSubframeworkPaths(ActiveModule, PathName); 1212 1213 // Check whether this file is in the public headers. 1214 llvm::sys::path::append(PathName, "Headers"); 1215 llvm::sys::path::append(PathName, FileName); 1216 File = SourceMgr.getFileManager().getFile(PathName); 1217 1218 if (!File) { 1219 // Check whether this file is in the private headers. 1220 PathName.resize(PathLength); 1221 llvm::sys::path::append(PathName, "PrivateHeaders"); 1222 llvm::sys::path::append(PathName, FileName); 1223 File = SourceMgr.getFileManager().getFile(PathName); 1224 } 1225 } else { 1226 // Lookup for normal headers. 1227 llvm::sys::path::append(PathName, FileName); 1228 File = SourceMgr.getFileManager().getFile(PathName); 1229 1230 // If this is a system module with a top-level header, this header 1231 // may have a counterpart (or replacement) in the set of headers 1232 // supplied by Clang. Find that builtin header. 1233 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir && 1234 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) { 1235 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1236 llvm::sys::path::append(BuiltinPathName, FileName); 1237 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1238 1239 // If Clang supplies this header but the underlying system does not, 1240 // just silently swap in our builtin version. Otherwise, we'll end 1241 // up adding both (later). 1242 if (!File && BuiltinFile) { 1243 File = BuiltinFile; 1244 BuiltinFile = 0; 1245 } 1246 } 1247 } 1248 } 1249 1250 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1251 // Come up with a lazy way to do this. 1252 if (File) { 1253 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) { 1254 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1255 << FileName << OwningModule.getModule()->getFullModuleName(); 1256 HadError = true; 1257 } else if (Umbrella) { 1258 const DirectoryEntry *UmbrellaDir = File->getDir(); 1259 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1260 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1261 << UmbrellaModule->getFullModuleName(); 1262 HadError = true; 1263 } else { 1264 // Record this umbrella header. 1265 Map.setUmbrellaHeader(ActiveModule, File); 1266 } 1267 } else { 1268 // Record this header. 1269 Map.addHeader(ActiveModule, File, Exclude); 1270 1271 // If there is a builtin counterpart to this file, add it now. 1272 if (BuiltinFile) 1273 Map.addHeader(ActiveModule, BuiltinFile, Exclude); 1274 } 1275 } else { 1276 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1277 << Umbrella << FileName; 1278 HadError = true; 1279 } 1280 } 1281 1282 /// \brief Parse an umbrella directory declaration. 1283 /// 1284 /// umbrella-dir-declaration: 1285 /// umbrella string-literal 1286 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1287 // Parse the directory name. 1288 if (!Tok.is(MMToken::StringLiteral)) { 1289 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1290 << "umbrella"; 1291 HadError = true; 1292 return; 1293 } 1294 1295 std::string DirName = Tok.getString(); 1296 SourceLocation DirNameLoc = consumeToken(); 1297 1298 // Check whether we already have an umbrella. 1299 if (ActiveModule->Umbrella) { 1300 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1301 << ActiveModule->getFullModuleName(); 1302 HadError = true; 1303 return; 1304 } 1305 1306 // Look for this file. 1307 const DirectoryEntry *Dir = 0; 1308 if (llvm::sys::path::is_absolute(DirName)) 1309 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1310 else { 1311 SmallString<128> PathName; 1312 PathName = Directory->getName(); 1313 llvm::sys::path::append(PathName, DirName); 1314 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1315 } 1316 1317 if (!Dir) { 1318 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1319 << DirName; 1320 HadError = true; 1321 return; 1322 } 1323 1324 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1325 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1326 << OwningModule->getFullModuleName(); 1327 HadError = true; 1328 return; 1329 } 1330 1331 // Record this umbrella directory. 1332 Map.setUmbrellaDir(ActiveModule, Dir); 1333 } 1334 1335 /// \brief Parse a module export declaration. 1336 /// 1337 /// export-declaration: 1338 /// 'export' wildcard-module-id 1339 /// 1340 /// wildcard-module-id: 1341 /// identifier 1342 /// '*' 1343 /// identifier '.' wildcard-module-id 1344 void ModuleMapParser::parseExportDecl() { 1345 assert(Tok.is(MMToken::ExportKeyword)); 1346 SourceLocation ExportLoc = consumeToken(); 1347 1348 // Parse the module-id with an optional wildcard at the end. 1349 ModuleId ParsedModuleId; 1350 bool Wildcard = false; 1351 do { 1352 if (Tok.is(MMToken::Identifier)) { 1353 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1354 Tok.getLocation())); 1355 consumeToken(); 1356 1357 if (Tok.is(MMToken::Period)) { 1358 consumeToken(); 1359 continue; 1360 } 1361 1362 break; 1363 } 1364 1365 if(Tok.is(MMToken::Star)) { 1366 Wildcard = true; 1367 consumeToken(); 1368 break; 1369 } 1370 1371 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1372 HadError = true; 1373 return; 1374 } while (true); 1375 1376 Module::UnresolvedExportDecl Unresolved = { 1377 ExportLoc, ParsedModuleId, Wildcard 1378 }; 1379 ActiveModule->UnresolvedExports.push_back(Unresolved); 1380 } 1381 1382 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 1383 assert(Tok.is(MMToken::Star)); 1384 SourceLocation StarLoc = consumeToken(); 1385 bool Failed = false; 1386 1387 // Inferred modules must be submodules. 1388 if (!ActiveModule) { 1389 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1390 Failed = true; 1391 } 1392 1393 // Inferred modules must have umbrella directories. 1394 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1395 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1396 Failed = true; 1397 } 1398 1399 // Check for redefinition of an inferred module. 1400 if (!Failed && ActiveModule->InferSubmodules) { 1401 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1402 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1403 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1404 diag::note_mmap_prev_definition); 1405 Failed = true; 1406 } 1407 1408 // If there were any problems with this inferred submodule, skip its body. 1409 if (Failed) { 1410 if (Tok.is(MMToken::LBrace)) { 1411 consumeToken(); 1412 skipUntil(MMToken::RBrace); 1413 if (Tok.is(MMToken::RBrace)) 1414 consumeToken(); 1415 } 1416 HadError = true; 1417 return; 1418 } 1419 1420 // Note that we have an inferred submodule. 1421 ActiveModule->InferSubmodules = true; 1422 ActiveModule->InferredSubmoduleLoc = StarLoc; 1423 ActiveModule->InferExplicitSubmodules = Explicit; 1424 1425 // Parse the opening brace. 1426 if (!Tok.is(MMToken::LBrace)) { 1427 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1428 HadError = true; 1429 return; 1430 } 1431 SourceLocation LBraceLoc = consumeToken(); 1432 1433 // Parse the body of the inferred submodule. 1434 bool Done = false; 1435 do { 1436 switch (Tok.Kind) { 1437 case MMToken::EndOfFile: 1438 case MMToken::RBrace: 1439 Done = true; 1440 break; 1441 1442 case MMToken::ExportKeyword: { 1443 consumeToken(); 1444 if (Tok.is(MMToken::Star)) 1445 ActiveModule->InferExportWildcard = true; 1446 else 1447 Diags.Report(Tok.getLocation(), 1448 diag::err_mmap_expected_export_wildcard); 1449 consumeToken(); 1450 break; 1451 } 1452 1453 case MMToken::ExplicitKeyword: 1454 case MMToken::ModuleKeyword: 1455 case MMToken::HeaderKeyword: 1456 case MMToken::UmbrellaKeyword: 1457 default: 1458 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 1459 consumeToken(); 1460 break; 1461 } 1462 } while (!Done); 1463 1464 if (Tok.is(MMToken::RBrace)) 1465 consumeToken(); 1466 else { 1467 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1468 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1469 HadError = true; 1470 } 1471 } 1472 1473 /// \brief If there is a specific header search directory due the presence 1474 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1475 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1476 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1477 // If we have an umbrella directory, use that. 1478 if (Mod->hasUmbrellaDir()) 1479 return Mod->getUmbrellaDir(); 1480 1481 // If we have a framework directory, stop looking. 1482 if (Mod->IsFramework) 1483 return 0; 1484 } 1485 1486 return 0; 1487 } 1488 1489 /// \brief Parse a module map file. 1490 /// 1491 /// module-map-file: 1492 /// module-declaration* 1493 bool ModuleMapParser::parseModuleMapFile() { 1494 do { 1495 switch (Tok.Kind) { 1496 case MMToken::EndOfFile: 1497 return HadError; 1498 1499 case MMToken::ExplicitKeyword: 1500 case MMToken::ModuleKeyword: 1501 case MMToken::FrameworkKeyword: 1502 parseModuleDecl(); 1503 break; 1504 1505 case MMToken::Comma: 1506 case MMToken::ExcludeKeyword: 1507 case MMToken::ExportKeyword: 1508 case MMToken::HeaderKeyword: 1509 case MMToken::Identifier: 1510 case MMToken::LBrace: 1511 case MMToken::LSquare: 1512 case MMToken::Period: 1513 case MMToken::RBrace: 1514 case MMToken::RSquare: 1515 case MMToken::RequiresKeyword: 1516 case MMToken::Star: 1517 case MMToken::StringLiteral: 1518 case MMToken::UmbrellaKeyword: 1519 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1520 HadError = true; 1521 consumeToken(); 1522 break; 1523 } 1524 } while (true); 1525 } 1526 1527 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1528 assert(Target != 0 && "Missing target information"); 1529 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1530 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1531 if (!Buffer) 1532 return true; 1533 1534 // Parse this module map file. 1535 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1536 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1537 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(), 1538 BuiltinIncludeDir); 1539 bool Result = Parser.parseModuleMapFile(); 1540 Diags->getClient()->EndSourceFile(); 1541 1542 return Result; 1543 } 1544