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 DiagnosticsEngine &Diags; 589 ModuleMap ⤅ 590 591 /// \brief The directory that this module map resides in. 592 const DirectoryEntry *Directory; 593 594 /// \brief The directory containing Clang-supplied headers. 595 const DirectoryEntry *BuiltinIncludeDir; 596 597 /// \brief Whether an error occurred. 598 bool HadError; 599 600 /// \brief Default target information, used only for string literal 601 /// parsing. 602 OwningPtr<TargetInfo> Target; 603 604 /// \brief Stores string data for the various string literals referenced 605 /// during parsing. 606 llvm::BumpPtrAllocator StringData; 607 608 /// \brief The current token. 609 MMToken Tok; 610 611 /// \brief The active module. 612 Module *ActiveModule; 613 614 /// \brief Consume the current token and return its location. 615 SourceLocation consumeToken(); 616 617 /// \brief Skip tokens until we reach the a token with the given kind 618 /// (or the end of the file). 619 void skipUntil(MMToken::TokenKind K); 620 621 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 622 ModuleId; 623 bool parseModuleId(ModuleId &Id); 624 void parseModuleDecl(); 625 void parseRequiresDecl(); 626 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc); 627 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 628 void parseExportDecl(); 629 void parseInferredSubmoduleDecl(bool Explicit); 630 631 const DirectoryEntry *getOverriddenHeaderSearchDir(); 632 633 public: 634 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 635 DiagnosticsEngine &Diags, 636 ModuleMap &Map, 637 const DirectoryEntry *Directory, 638 const DirectoryEntry *BuiltinIncludeDir) 639 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 640 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 641 HadError(false), ActiveModule(0) 642 { 643 TargetOptions TargetOpts; 644 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 645 Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts)); 646 647 Tok.clear(); 648 consumeToken(); 649 } 650 651 bool parseModuleMapFile(); 652 }; 653 } 654 655 SourceLocation ModuleMapParser::consumeToken() { 656 retry: 657 SourceLocation Result = Tok.getLocation(); 658 Tok.clear(); 659 660 Token LToken; 661 L.LexFromRawLexer(LToken); 662 Tok.Location = LToken.getLocation().getRawEncoding(); 663 switch (LToken.getKind()) { 664 case tok::raw_identifier: 665 Tok.StringData = LToken.getRawIdentifierData(); 666 Tok.StringLength = LToken.getLength(); 667 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 668 .Case("header", MMToken::HeaderKeyword) 669 .Case("exclude", MMToken::ExcludeKeyword) 670 .Case("explicit", MMToken::ExplicitKeyword) 671 .Case("export", MMToken::ExportKeyword) 672 .Case("framework", MMToken::FrameworkKeyword) 673 .Case("module", MMToken::ModuleKeyword) 674 .Case("requires", MMToken::RequiresKeyword) 675 .Case("umbrella", MMToken::UmbrellaKeyword) 676 .Default(MMToken::Identifier); 677 break; 678 679 case tok::comma: 680 Tok.Kind = MMToken::Comma; 681 break; 682 683 case tok::eof: 684 Tok.Kind = MMToken::EndOfFile; 685 break; 686 687 case tok::l_brace: 688 Tok.Kind = MMToken::LBrace; 689 break; 690 691 case tok::l_square: 692 Tok.Kind = MMToken::LSquare; 693 break; 694 695 case tok::period: 696 Tok.Kind = MMToken::Period; 697 break; 698 699 case tok::r_brace: 700 Tok.Kind = MMToken::RBrace; 701 break; 702 703 case tok::r_square: 704 Tok.Kind = MMToken::RSquare; 705 break; 706 707 case tok::star: 708 Tok.Kind = MMToken::Star; 709 break; 710 711 case tok::string_literal: { 712 if (LToken.hasUDSuffix()) { 713 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 714 HadError = true; 715 goto retry; 716 } 717 718 // Parse the string literal. 719 LangOptions LangOpts; 720 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 721 if (StringLiteral.hadError) 722 goto retry; 723 724 // Copy the string literal into our string data allocator. 725 unsigned Length = StringLiteral.GetStringLength(); 726 char *Saved = StringData.Allocate<char>(Length + 1); 727 memcpy(Saved, StringLiteral.GetString().data(), Length); 728 Saved[Length] = 0; 729 730 // Form the token. 731 Tok.Kind = MMToken::StringLiteral; 732 Tok.StringData = Saved; 733 Tok.StringLength = Length; 734 break; 735 } 736 737 case tok::comment: 738 goto retry; 739 740 default: 741 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 742 HadError = true; 743 goto retry; 744 } 745 746 return Result; 747 } 748 749 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 750 unsigned braceDepth = 0; 751 unsigned squareDepth = 0; 752 do { 753 switch (Tok.Kind) { 754 case MMToken::EndOfFile: 755 return; 756 757 case MMToken::LBrace: 758 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 759 return; 760 761 ++braceDepth; 762 break; 763 764 case MMToken::LSquare: 765 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 766 return; 767 768 ++squareDepth; 769 break; 770 771 case MMToken::RBrace: 772 if (braceDepth > 0) 773 --braceDepth; 774 else if (Tok.is(K)) 775 return; 776 break; 777 778 case MMToken::RSquare: 779 if (squareDepth > 0) 780 --squareDepth; 781 else if (Tok.is(K)) 782 return; 783 break; 784 785 default: 786 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 787 return; 788 break; 789 } 790 791 consumeToken(); 792 } while (true); 793 } 794 795 /// \brief Parse a module-id. 796 /// 797 /// module-id: 798 /// identifier 799 /// identifier '.' module-id 800 /// 801 /// \returns true if an error occurred, false otherwise. 802 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 803 Id.clear(); 804 do { 805 if (Tok.is(MMToken::Identifier)) { 806 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 807 consumeToken(); 808 } else { 809 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 810 return true; 811 } 812 813 if (!Tok.is(MMToken::Period)) 814 break; 815 816 consumeToken(); 817 } while (true); 818 819 return false; 820 } 821 822 namespace { 823 /// \brief Enumerates the known attributes. 824 enum AttributeKind { 825 /// \brief An unknown attribute. 826 AT_unknown, 827 /// \brief The 'system' attribute. 828 AT_system 829 }; 830 } 831 832 /// \brief Parse a module declaration. 833 /// 834 /// module-declaration: 835 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 836 /// { module-member* } 837 /// 838 /// attributes: 839 /// attribute attributes 840 /// attribute 841 /// 842 /// attribute: 843 /// [ identifier ] 844 /// 845 /// module-member: 846 /// requires-declaration 847 /// header-declaration 848 /// submodule-declaration 849 /// export-declaration 850 /// 851 /// submodule-declaration: 852 /// module-declaration 853 /// inferred-submodule-declaration 854 void ModuleMapParser::parseModuleDecl() { 855 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 856 Tok.is(MMToken::FrameworkKeyword)); 857 // Parse 'explicit' or 'framework' keyword, if present. 858 SourceLocation ExplicitLoc; 859 bool Explicit = false; 860 bool Framework = false; 861 862 // Parse 'explicit' keyword, if present. 863 if (Tok.is(MMToken::ExplicitKeyword)) { 864 ExplicitLoc = consumeToken(); 865 Explicit = true; 866 } 867 868 // Parse 'framework' keyword, if present. 869 if (Tok.is(MMToken::FrameworkKeyword)) { 870 consumeToken(); 871 Framework = true; 872 } 873 874 // Parse 'module' keyword. 875 if (!Tok.is(MMToken::ModuleKeyword)) { 876 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 877 consumeToken(); 878 HadError = true; 879 return; 880 } 881 consumeToken(); // 'module' keyword 882 883 // If we have a wildcard for the module name, this is an inferred submodule. 884 // Parse it. 885 if (Tok.is(MMToken::Star)) 886 return parseInferredSubmoduleDecl(Explicit); 887 888 // Parse the module name. 889 ModuleId Id; 890 if (parseModuleId(Id)) { 891 HadError = true; 892 return; 893 } 894 895 if (ActiveModule) { 896 if (Id.size() > 1) { 897 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 898 << SourceRange(Id.front().second, Id.back().second); 899 900 HadError = true; 901 return; 902 } 903 } else if (Id.size() == 1 && Explicit) { 904 // Top-level modules can't be explicit. 905 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 906 Explicit = false; 907 ExplicitLoc = SourceLocation(); 908 HadError = true; 909 } 910 911 Module *PreviousActiveModule = ActiveModule; 912 if (Id.size() > 1) { 913 // This module map defines a submodule. Go find the module of which it 914 // is a submodule. 915 ActiveModule = 0; 916 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 917 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 918 ActiveModule = Next; 919 continue; 920 } 921 922 if (ActiveModule) { 923 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 924 << Id[I].first << ActiveModule->getTopLevelModule(); 925 } else { 926 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 927 } 928 HadError = true; 929 return; 930 } 931 } 932 933 StringRef ModuleName = Id.back().first; 934 SourceLocation ModuleNameLoc = Id.back().second; 935 936 // Parse the optional attribute list. 937 bool IsSystem = false; 938 while (Tok.is(MMToken::LSquare)) { 939 // Consume the '['. 940 SourceLocation LSquareLoc = consumeToken(); 941 942 // Check whether we have an attribute name here. 943 if (!Tok.is(MMToken::Identifier)) { 944 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 945 skipUntil(MMToken::RSquare); 946 if (Tok.is(MMToken::RSquare)) 947 consumeToken(); 948 continue; 949 } 950 951 // Decode the attribute name. 952 AttributeKind Attribute 953 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 954 .Case("system", AT_system) 955 .Default(AT_unknown); 956 switch (Attribute) { 957 case AT_unknown: 958 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 959 << Tok.getString(); 960 break; 961 962 case AT_system: 963 IsSystem = true; 964 break; 965 } 966 consumeToken(); 967 968 // Consume the ']'. 969 if (!Tok.is(MMToken::RSquare)) { 970 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 971 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 972 skipUntil(MMToken::RSquare); 973 } 974 975 if (Tok.is(MMToken::RSquare)) 976 consumeToken(); 977 } 978 979 // Parse the opening brace. 980 if (!Tok.is(MMToken::LBrace)) { 981 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 982 << ModuleName; 983 HadError = true; 984 return; 985 } 986 SourceLocation LBraceLoc = consumeToken(); 987 988 // Determine whether this (sub)module has already been defined. 989 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 990 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 991 // Skip the module definition. 992 skipUntil(MMToken::RBrace); 993 if (Tok.is(MMToken::RBrace)) 994 consumeToken(); 995 else { 996 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 997 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 998 HadError = true; 999 } 1000 return; 1001 } 1002 1003 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1004 << ModuleName; 1005 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1006 1007 // Skip the module definition. 1008 skipUntil(MMToken::RBrace); 1009 if (Tok.is(MMToken::RBrace)) 1010 consumeToken(); 1011 1012 HadError = true; 1013 return; 1014 } 1015 1016 // Start defining this module. 1017 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1018 Explicit).first; 1019 ActiveModule->DefinitionLoc = ModuleNameLoc; 1020 if (IsSystem) 1021 ActiveModule->IsSystem = true; 1022 1023 bool Done = false; 1024 do { 1025 switch (Tok.Kind) { 1026 case MMToken::EndOfFile: 1027 case MMToken::RBrace: 1028 Done = true; 1029 break; 1030 1031 case MMToken::ExplicitKeyword: 1032 case MMToken::FrameworkKeyword: 1033 case MMToken::ModuleKeyword: 1034 parseModuleDecl(); 1035 break; 1036 1037 case MMToken::ExportKeyword: 1038 parseExportDecl(); 1039 break; 1040 1041 case MMToken::RequiresKeyword: 1042 parseRequiresDecl(); 1043 break; 1044 1045 case MMToken::UmbrellaKeyword: { 1046 SourceLocation UmbrellaLoc = consumeToken(); 1047 if (Tok.is(MMToken::HeaderKeyword)) 1048 parseHeaderDecl(UmbrellaLoc, SourceLocation()); 1049 else 1050 parseUmbrellaDirDecl(UmbrellaLoc); 1051 break; 1052 } 1053 1054 case MMToken::ExcludeKeyword: { 1055 SourceLocation ExcludeLoc = consumeToken(); 1056 if (Tok.is(MMToken::HeaderKeyword)) { 1057 parseHeaderDecl(SourceLocation(), ExcludeLoc); 1058 } else { 1059 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1060 << "exclude"; 1061 } 1062 break; 1063 } 1064 1065 case MMToken::HeaderKeyword: 1066 parseHeaderDecl(SourceLocation(), SourceLocation()); 1067 break; 1068 1069 default: 1070 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1071 consumeToken(); 1072 break; 1073 } 1074 } while (!Done); 1075 1076 if (Tok.is(MMToken::RBrace)) 1077 consumeToken(); 1078 else { 1079 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1080 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1081 HadError = true; 1082 } 1083 1084 // We're done parsing this module. Pop back to the previous module. 1085 ActiveModule = PreviousActiveModule; 1086 } 1087 1088 /// \brief Parse a requires declaration. 1089 /// 1090 /// requires-declaration: 1091 /// 'requires' feature-list 1092 /// 1093 /// feature-list: 1094 /// identifier ',' feature-list 1095 /// identifier 1096 void ModuleMapParser::parseRequiresDecl() { 1097 assert(Tok.is(MMToken::RequiresKeyword)); 1098 1099 // Parse 'requires' keyword. 1100 consumeToken(); 1101 1102 // Parse the feature-list. 1103 do { 1104 if (!Tok.is(MMToken::Identifier)) { 1105 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1106 HadError = true; 1107 return; 1108 } 1109 1110 // Consume the feature name. 1111 std::string Feature = Tok.getString(); 1112 consumeToken(); 1113 1114 // Add this feature. 1115 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 1116 1117 if (!Tok.is(MMToken::Comma)) 1118 break; 1119 1120 // Consume the comma. 1121 consumeToken(); 1122 } while (true); 1123 } 1124 1125 /// \brief Append to \p Paths the set of paths needed to get to the 1126 /// subframework in which the given module lives. 1127 static void appendSubframeworkPaths(Module *Mod, 1128 llvm::SmallVectorImpl<char> &Path) { 1129 // Collect the framework names from the given module to the top-level module. 1130 llvm::SmallVector<StringRef, 2> Paths; 1131 for (; Mod; Mod = Mod->Parent) { 1132 if (Mod->IsFramework) 1133 Paths.push_back(Mod->Name); 1134 } 1135 1136 if (Paths.empty()) 1137 return; 1138 1139 // Add Frameworks/Name.framework for each subframework. 1140 for (unsigned I = Paths.size() - 1; I != 0; --I) { 1141 llvm::sys::path::append(Path, "Frameworks"); 1142 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 1143 } 1144 } 1145 1146 /// \brief Determine whether the given file name is the name of a builtin 1147 /// header, supplied by Clang to replace, override, or augment existing system 1148 /// headers. 1149 static bool isBuiltinHeader(StringRef FileName) { 1150 return llvm::StringSwitch<bool>(FileName) 1151 .Case("float.h", true) 1152 .Case("iso646.h", true) 1153 .Case("limits.h", true) 1154 .Case("stdalign.h", true) 1155 .Case("stdarg.h", true) 1156 .Case("stdbool.h", true) 1157 .Case("stddef.h", true) 1158 .Case("stdint.h", true) 1159 .Case("tgmath.h", true) 1160 .Case("unwind.h", true) 1161 .Default(false); 1162 } 1163 1164 /// \brief Parse a header declaration. 1165 /// 1166 /// header-declaration: 1167 /// 'umbrella'[opt] 'header' string-literal 1168 /// 'exclude'[opt] 'header' string-literal 1169 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc, 1170 SourceLocation ExcludeLoc) { 1171 assert(Tok.is(MMToken::HeaderKeyword)); 1172 consumeToken(); 1173 1174 bool Umbrella = UmbrellaLoc.isValid(); 1175 bool Exclude = ExcludeLoc.isValid(); 1176 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'"); 1177 // Parse the header name. 1178 if (!Tok.is(MMToken::StringLiteral)) { 1179 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1180 << "header"; 1181 HadError = true; 1182 return; 1183 } 1184 std::string FileName = Tok.getString(); 1185 SourceLocation FileNameLoc = consumeToken(); 1186 1187 // Check whether we already have an umbrella. 1188 if (Umbrella && ActiveModule->Umbrella) { 1189 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1190 << ActiveModule->getFullModuleName(); 1191 HadError = true; 1192 return; 1193 } 1194 1195 // Look for this file. 1196 const FileEntry *File = 0; 1197 const FileEntry *BuiltinFile = 0; 1198 SmallString<128> PathName; 1199 if (llvm::sys::path::is_absolute(FileName)) { 1200 PathName = FileName; 1201 File = SourceMgr.getFileManager().getFile(PathName); 1202 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1203 PathName = Dir->getName(); 1204 llvm::sys::path::append(PathName, FileName); 1205 File = SourceMgr.getFileManager().getFile(PathName); 1206 } else { 1207 // Search for the header file within the search directory. 1208 PathName = Directory->getName(); 1209 unsigned PathLength = PathName.size(); 1210 1211 if (ActiveModule->isPartOfFramework()) { 1212 appendSubframeworkPaths(ActiveModule, PathName); 1213 1214 // Check whether this file is in the public headers. 1215 llvm::sys::path::append(PathName, "Headers"); 1216 llvm::sys::path::append(PathName, FileName); 1217 File = SourceMgr.getFileManager().getFile(PathName); 1218 1219 if (!File) { 1220 // Check whether this file is in the private headers. 1221 PathName.resize(PathLength); 1222 llvm::sys::path::append(PathName, "PrivateHeaders"); 1223 llvm::sys::path::append(PathName, FileName); 1224 File = SourceMgr.getFileManager().getFile(PathName); 1225 } 1226 } else { 1227 // Lookup for normal headers. 1228 llvm::sys::path::append(PathName, FileName); 1229 File = SourceMgr.getFileManager().getFile(PathName); 1230 1231 // If this is a system module with a top-level header, this header 1232 // may have a counterpart (or replacement) in the set of headers 1233 // supplied by Clang. Find that builtin header. 1234 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir && 1235 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) { 1236 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1237 llvm::sys::path::append(BuiltinPathName, FileName); 1238 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1239 1240 // If Clang supplies this header but the underlying system does not, 1241 // just silently swap in our builtin version. Otherwise, we'll end 1242 // up adding both (later). 1243 if (!File && BuiltinFile) { 1244 File = BuiltinFile; 1245 BuiltinFile = 0; 1246 } 1247 } 1248 } 1249 } 1250 1251 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1252 // Come up with a lazy way to do this. 1253 if (File) { 1254 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) { 1255 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1256 << FileName << OwningModule.getModule()->getFullModuleName(); 1257 HadError = true; 1258 } else if (Umbrella) { 1259 const DirectoryEntry *UmbrellaDir = File->getDir(); 1260 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1261 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1262 << UmbrellaModule->getFullModuleName(); 1263 HadError = true; 1264 } else { 1265 // Record this umbrella header. 1266 Map.setUmbrellaHeader(ActiveModule, File); 1267 } 1268 } else { 1269 // Record this header. 1270 Map.addHeader(ActiveModule, File, Exclude); 1271 1272 // If there is a builtin counterpart to this file, add it now. 1273 if (BuiltinFile) 1274 Map.addHeader(ActiveModule, BuiltinFile, Exclude); 1275 } 1276 } else { 1277 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1278 << Umbrella << FileName; 1279 HadError = true; 1280 } 1281 } 1282 1283 /// \brief Parse an umbrella directory declaration. 1284 /// 1285 /// umbrella-dir-declaration: 1286 /// umbrella string-literal 1287 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1288 // Parse the directory name. 1289 if (!Tok.is(MMToken::StringLiteral)) { 1290 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1291 << "umbrella"; 1292 HadError = true; 1293 return; 1294 } 1295 1296 std::string DirName = Tok.getString(); 1297 SourceLocation DirNameLoc = consumeToken(); 1298 1299 // Check whether we already have an umbrella. 1300 if (ActiveModule->Umbrella) { 1301 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1302 << ActiveModule->getFullModuleName(); 1303 HadError = true; 1304 return; 1305 } 1306 1307 // Look for this file. 1308 const DirectoryEntry *Dir = 0; 1309 if (llvm::sys::path::is_absolute(DirName)) 1310 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1311 else { 1312 SmallString<128> PathName; 1313 PathName = Directory->getName(); 1314 llvm::sys::path::append(PathName, DirName); 1315 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1316 } 1317 1318 if (!Dir) { 1319 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1320 << DirName; 1321 HadError = true; 1322 return; 1323 } 1324 1325 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1326 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1327 << OwningModule->getFullModuleName(); 1328 HadError = true; 1329 return; 1330 } 1331 1332 // Record this umbrella directory. 1333 Map.setUmbrellaDir(ActiveModule, Dir); 1334 } 1335 1336 /// \brief Parse a module export declaration. 1337 /// 1338 /// export-declaration: 1339 /// 'export' wildcard-module-id 1340 /// 1341 /// wildcard-module-id: 1342 /// identifier 1343 /// '*' 1344 /// identifier '.' wildcard-module-id 1345 void ModuleMapParser::parseExportDecl() { 1346 assert(Tok.is(MMToken::ExportKeyword)); 1347 SourceLocation ExportLoc = consumeToken(); 1348 1349 // Parse the module-id with an optional wildcard at the end. 1350 ModuleId ParsedModuleId; 1351 bool Wildcard = false; 1352 do { 1353 if (Tok.is(MMToken::Identifier)) { 1354 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1355 Tok.getLocation())); 1356 consumeToken(); 1357 1358 if (Tok.is(MMToken::Period)) { 1359 consumeToken(); 1360 continue; 1361 } 1362 1363 break; 1364 } 1365 1366 if(Tok.is(MMToken::Star)) { 1367 Wildcard = true; 1368 consumeToken(); 1369 break; 1370 } 1371 1372 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1373 HadError = true; 1374 return; 1375 } while (true); 1376 1377 Module::UnresolvedExportDecl Unresolved = { 1378 ExportLoc, ParsedModuleId, Wildcard 1379 }; 1380 ActiveModule->UnresolvedExports.push_back(Unresolved); 1381 } 1382 1383 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 1384 assert(Tok.is(MMToken::Star)); 1385 SourceLocation StarLoc = consumeToken(); 1386 bool Failed = false; 1387 1388 // Inferred modules must be submodules. 1389 if (!ActiveModule) { 1390 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1391 Failed = true; 1392 } 1393 1394 // Inferred modules must have umbrella directories. 1395 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1396 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1397 Failed = true; 1398 } 1399 1400 // Check for redefinition of an inferred module. 1401 if (!Failed && ActiveModule->InferSubmodules) { 1402 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1403 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1404 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1405 diag::note_mmap_prev_definition); 1406 Failed = true; 1407 } 1408 1409 // If there were any problems with this inferred submodule, skip its body. 1410 if (Failed) { 1411 if (Tok.is(MMToken::LBrace)) { 1412 consumeToken(); 1413 skipUntil(MMToken::RBrace); 1414 if (Tok.is(MMToken::RBrace)) 1415 consumeToken(); 1416 } 1417 HadError = true; 1418 return; 1419 } 1420 1421 // Note that we have an inferred submodule. 1422 ActiveModule->InferSubmodules = true; 1423 ActiveModule->InferredSubmoduleLoc = StarLoc; 1424 ActiveModule->InferExplicitSubmodules = Explicit; 1425 1426 // Parse the opening brace. 1427 if (!Tok.is(MMToken::LBrace)) { 1428 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1429 HadError = true; 1430 return; 1431 } 1432 SourceLocation LBraceLoc = consumeToken(); 1433 1434 // Parse the body of the inferred submodule. 1435 bool Done = false; 1436 do { 1437 switch (Tok.Kind) { 1438 case MMToken::EndOfFile: 1439 case MMToken::RBrace: 1440 Done = true; 1441 break; 1442 1443 case MMToken::ExportKeyword: { 1444 consumeToken(); 1445 if (Tok.is(MMToken::Star)) 1446 ActiveModule->InferExportWildcard = true; 1447 else 1448 Diags.Report(Tok.getLocation(), 1449 diag::err_mmap_expected_export_wildcard); 1450 consumeToken(); 1451 break; 1452 } 1453 1454 case MMToken::ExplicitKeyword: 1455 case MMToken::ModuleKeyword: 1456 case MMToken::HeaderKeyword: 1457 case MMToken::UmbrellaKeyword: 1458 default: 1459 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 1460 consumeToken(); 1461 break; 1462 } 1463 } while (!Done); 1464 1465 if (Tok.is(MMToken::RBrace)) 1466 consumeToken(); 1467 else { 1468 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1469 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1470 HadError = true; 1471 } 1472 } 1473 1474 /// \brief If there is a specific header search directory due the presence 1475 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1476 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1477 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1478 // If we have an umbrella directory, use that. 1479 if (Mod->hasUmbrellaDir()) 1480 return Mod->getUmbrellaDir(); 1481 1482 // If we have a framework directory, stop looking. 1483 if (Mod->IsFramework) 1484 return 0; 1485 } 1486 1487 return 0; 1488 } 1489 1490 /// \brief Parse a module map file. 1491 /// 1492 /// module-map-file: 1493 /// module-declaration* 1494 bool ModuleMapParser::parseModuleMapFile() { 1495 do { 1496 switch (Tok.Kind) { 1497 case MMToken::EndOfFile: 1498 return HadError; 1499 1500 case MMToken::ExplicitKeyword: 1501 case MMToken::ModuleKeyword: 1502 case MMToken::FrameworkKeyword: 1503 parseModuleDecl(); 1504 break; 1505 1506 case MMToken::Comma: 1507 case MMToken::ExcludeKeyword: 1508 case MMToken::ExportKeyword: 1509 case MMToken::HeaderKeyword: 1510 case MMToken::Identifier: 1511 case MMToken::LBrace: 1512 case MMToken::LSquare: 1513 case MMToken::Period: 1514 case MMToken::RBrace: 1515 case MMToken::RSquare: 1516 case MMToken::RequiresKeyword: 1517 case MMToken::Star: 1518 case MMToken::StringLiteral: 1519 case MMToken::UmbrellaKeyword: 1520 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1521 HadError = true; 1522 consumeToken(); 1523 break; 1524 } 1525 } while (true); 1526 } 1527 1528 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1529 assert(Target != 0 && "Missing target information"); 1530 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1531 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1532 if (!Buffer) 1533 return true; 1534 1535 // Parse this module map file. 1536 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1537 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1538 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir(), 1539 BuiltinIncludeDir); 1540 bool Result = Parser.parseModuleMapFile(); 1541 Diags->getClient()->EndSourceFile(); 1542 1543 return Result; 1544 } 1545