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 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 350 StringRef Name, bool &IsSystem) { 351 // Check whether we have already looked into the parent directory 352 // for a module map. 353 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator 354 inferred = InferredDirectories.find(ParentDir); 355 if (inferred == InferredDirectories.end()) 356 return false; 357 358 if (!inferred->second.InferModules) 359 return false; 360 361 // We're allowed to infer for this directory, but make sure it's okay 362 // to infer this particular module. 363 bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 364 inferred->second.ExcludedModules.end(), 365 Name) == inferred->second.ExcludedModules.end(); 366 367 if (canInfer && inferred->second.InferSystemModules) 368 IsSystem = true; 369 370 return canInfer; 371 } 372 373 Module * 374 ModuleMap::inferFrameworkModule(StringRef ModuleName, 375 const DirectoryEntry *FrameworkDir, 376 bool IsSystem, 377 Module *Parent) { 378 // Check whether we've already found this module. 379 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 380 return Mod; 381 382 FileManager &FileMgr = SourceMgr->getFileManager(); 383 384 // If the framework has a parent path from which we're allowed to infer 385 // a framework module, do so. 386 if (!Parent) { 387 bool canInfer = false; 388 if (llvm::sys::path::has_parent_path(FrameworkDir->getName())) { 389 // Figure out the parent path. 390 StringRef Parent = llvm::sys::path::parent_path(FrameworkDir->getName()); 391 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 392 // Check whether we have already looked into the parent directory 393 // for a module map. 394 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator 395 inferred = InferredDirectories.find(ParentDir); 396 if (inferred == InferredDirectories.end()) { 397 // We haven't looked here before. Load a module map, if there is 398 // one. 399 SmallString<128> ModMapPath = Parent; 400 llvm::sys::path::append(ModMapPath, "module.map"); 401 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) { 402 parseModuleMapFile(ModMapFile); 403 inferred = InferredDirectories.find(ParentDir); 404 } 405 406 if (inferred == InferredDirectories.end()) 407 inferred = InferredDirectories.insert( 408 std::make_pair(ParentDir, InferredDirectory())).first; 409 } 410 411 if (inferred->second.InferModules) { 412 // We're allowed to infer for this directory, but make sure it's okay 413 // to infer this particular module. 414 StringRef Name = llvm::sys::path::filename(FrameworkDir->getName()); 415 canInfer = std::find(inferred->second.ExcludedModules.begin(), 416 inferred->second.ExcludedModules.end(), 417 Name) == inferred->second.ExcludedModules.end(); 418 419 if (inferred->second.InferSystemModules) 420 IsSystem = true; 421 } 422 } 423 } 424 425 // If we're not allowed to infer a framework module, don't. 426 if (!canInfer) 427 return 0; 428 } 429 430 431 // Look for an umbrella header. 432 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 433 llvm::sys::path::append(UmbrellaName, "Headers"); 434 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 435 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 436 437 // FIXME: If there's no umbrella header, we could probably scan the 438 // framework to load *everything*. But, it's not clear that this is a good 439 // idea. 440 if (!UmbrellaHeader) 441 return 0; 442 443 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 444 /*IsFramework=*/true, /*IsExplicit=*/false); 445 if (IsSystem) 446 Result->IsSystem = IsSystem; 447 448 if (!Parent) 449 Modules[ModuleName] = Result; 450 451 // umbrella header "umbrella-header-name" 452 Result->Umbrella = UmbrellaHeader; 453 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false); 454 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 455 456 // export * 457 Result->Exports.push_back(Module::ExportDecl(0, true)); 458 459 // module * { export * } 460 Result->InferSubmodules = true; 461 Result->InferExportWildcard = true; 462 463 // Look for subframeworks. 464 llvm::error_code EC; 465 SmallString<128> SubframeworksDirName 466 = StringRef(FrameworkDir->getName()); 467 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 468 SmallString<128> SubframeworksDirNameNative; 469 llvm::sys::path::native(SubframeworksDirName.str(), 470 SubframeworksDirNameNative); 471 for (llvm::sys::fs::directory_iterator 472 Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 473 Dir != DirEnd && !EC; Dir.increment(EC)) { 474 if (!StringRef(Dir->path()).endswith(".framework")) 475 continue; 476 477 if (const DirectoryEntry *SubframeworkDir 478 = FileMgr.getDirectory(Dir->path())) { 479 // Note: as an egregious but useful hack, we use the real path here and 480 // check whether it is actually a subdirectory of the parent directory. 481 // This will not be the case if the 'subframework' is actually a symlink 482 // out to a top-level framework. 483 #ifdef LLVM_ON_UNIX 484 char RealSubframeworkDirName[PATH_MAX]; 485 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) { 486 StringRef SubframeworkDirName = RealSubframeworkDirName; 487 488 bool FoundParent = false; 489 do { 490 // Get the parent directory name. 491 SubframeworkDirName 492 = llvm::sys::path::parent_path(SubframeworkDirName); 493 if (SubframeworkDirName.empty()) 494 break; 495 496 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 497 FoundParent = true; 498 break; 499 } 500 } while (true); 501 502 if (!FoundParent) 503 continue; 504 } 505 #endif 506 507 // FIXME: Do we want to warn about subframeworks without umbrella headers? 508 SmallString<32> NameBuf; 509 inferFrameworkModule(sanitizeFilenameAsIdentifier( 510 llvm::sys::path::stem(Dir->path()), NameBuf), 511 SubframeworkDir, IsSystem, Result); 512 } 513 } 514 515 return Result; 516 } 517 518 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 519 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false); 520 Mod->Umbrella = UmbrellaHeader; 521 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 522 } 523 524 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 525 Mod->Umbrella = UmbrellaDir; 526 UmbrellaDirs[UmbrellaDir] = Mod; 527 } 528 529 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 530 bool Excluded) { 531 if (Excluded) 532 Mod->ExcludedHeaders.push_back(Header); 533 else 534 Mod->Headers.push_back(Header); 535 Headers[Header] = KnownHeader(Mod, Excluded); 536 } 537 538 const FileEntry * 539 ModuleMap::getContainingModuleMapFile(Module *Module) { 540 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 541 return 0; 542 543 return SourceMgr->getFileEntryForID( 544 SourceMgr->getFileID(Module->DefinitionLoc)); 545 } 546 547 void ModuleMap::dump() { 548 llvm::errs() << "Modules:"; 549 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 550 MEnd = Modules.end(); 551 M != MEnd; ++M) 552 M->getValue()->print(llvm::errs(), 2); 553 554 llvm::errs() << "Headers:"; 555 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 556 H != HEnd; ++H) { 557 llvm::errs() << " \"" << H->first->getName() << "\" -> " 558 << H->second.getModule()->getFullModuleName() << "\n"; 559 } 560 } 561 562 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 563 bool HadError = false; 564 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 565 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 566 Complain); 567 if (Export.getPointer() || Export.getInt()) 568 Mod->Exports.push_back(Export); 569 else 570 HadError = true; 571 } 572 Mod->UnresolvedExports.clear(); 573 return HadError; 574 } 575 576 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 577 if (Loc.isInvalid()) 578 return 0; 579 580 // Use the expansion location to determine which module we're in. 581 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 582 if (!ExpansionLoc.isFileID()) 583 return 0; 584 585 586 const SourceManager &SrcMgr = Loc.getManager(); 587 FileID ExpansionFileID = ExpansionLoc.getFileID(); 588 589 while (const FileEntry *ExpansionFile 590 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 591 // Find the module that owns this header (if any). 592 if (Module *Mod = findModuleForHeader(ExpansionFile)) 593 return Mod; 594 595 // No module owns this header, so look up the inclusion chain to see if 596 // any included header has an associated module. 597 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 598 if (IncludeLoc.isInvalid()) 599 return 0; 600 601 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 602 } 603 604 return 0; 605 } 606 607 //----------------------------------------------------------------------------// 608 // Module map file parser 609 //----------------------------------------------------------------------------// 610 611 namespace clang { 612 /// \brief A token in a module map file. 613 struct MMToken { 614 enum TokenKind { 615 Comma, 616 EndOfFile, 617 HeaderKeyword, 618 Identifier, 619 ExcludeKeyword, 620 ExplicitKeyword, 621 ExportKeyword, 622 FrameworkKeyword, 623 ModuleKeyword, 624 Period, 625 UmbrellaKeyword, 626 RequiresKeyword, 627 Star, 628 StringLiteral, 629 LBrace, 630 RBrace, 631 LSquare, 632 RSquare 633 } Kind; 634 635 unsigned Location; 636 unsigned StringLength; 637 const char *StringData; 638 639 void clear() { 640 Kind = EndOfFile; 641 Location = 0; 642 StringLength = 0; 643 StringData = 0; 644 } 645 646 bool is(TokenKind K) const { return Kind == K; } 647 648 SourceLocation getLocation() const { 649 return SourceLocation::getFromRawEncoding(Location); 650 } 651 652 StringRef getString() const { 653 return StringRef(StringData, StringLength); 654 } 655 }; 656 657 /// \brief The set of attributes that can be attached to a module. 658 struct Attributes { 659 Attributes() : IsSystem() { } 660 661 /// \brief Whether this is a system module. 662 unsigned IsSystem : 1; 663 }; 664 665 666 class ModuleMapParser { 667 Lexer &L; 668 SourceManager &SourceMgr; 669 670 /// \brief Default target information, used only for string literal 671 /// parsing. 672 const TargetInfo *Target; 673 674 DiagnosticsEngine &Diags; 675 ModuleMap ⤅ 676 677 /// \brief The directory that this module map resides in. 678 const DirectoryEntry *Directory; 679 680 /// \brief The directory containing Clang-supplied headers. 681 const DirectoryEntry *BuiltinIncludeDir; 682 683 /// \brief Whether an error occurred. 684 bool HadError; 685 686 /// \brief Stores string data for the various string literals referenced 687 /// during parsing. 688 llvm::BumpPtrAllocator StringData; 689 690 /// \brief The current token. 691 MMToken Tok; 692 693 /// \brief The active module. 694 Module *ActiveModule; 695 696 /// \brief Consume the current token and return its location. 697 SourceLocation consumeToken(); 698 699 /// \brief Skip tokens until we reach the a token with the given kind 700 /// (or the end of the file). 701 void skipUntil(MMToken::TokenKind K); 702 703 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 704 ModuleId; 705 bool parseModuleId(ModuleId &Id); 706 void parseModuleDecl(); 707 void parseRequiresDecl(); 708 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc); 709 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 710 void parseExportDecl(); 711 void parseInferredModuleDecl(bool Framework, bool Explicit); 712 bool parseOptionalAttributes(Attributes &Attrs); 713 714 const DirectoryEntry *getOverriddenHeaderSearchDir(); 715 716 public: 717 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 718 const TargetInfo *Target, 719 DiagnosticsEngine &Diags, 720 ModuleMap &Map, 721 const DirectoryEntry *Directory, 722 const DirectoryEntry *BuiltinIncludeDir) 723 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 724 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 725 HadError(false), ActiveModule(0) 726 { 727 Tok.clear(); 728 consumeToken(); 729 } 730 731 bool parseModuleMapFile(); 732 }; 733 } 734 735 SourceLocation ModuleMapParser::consumeToken() { 736 retry: 737 SourceLocation Result = Tok.getLocation(); 738 Tok.clear(); 739 740 Token LToken; 741 L.LexFromRawLexer(LToken); 742 Tok.Location = LToken.getLocation().getRawEncoding(); 743 switch (LToken.getKind()) { 744 case tok::raw_identifier: 745 Tok.StringData = LToken.getRawIdentifierData(); 746 Tok.StringLength = LToken.getLength(); 747 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 748 .Case("header", MMToken::HeaderKeyword) 749 .Case("exclude", MMToken::ExcludeKeyword) 750 .Case("explicit", MMToken::ExplicitKeyword) 751 .Case("export", MMToken::ExportKeyword) 752 .Case("framework", MMToken::FrameworkKeyword) 753 .Case("module", MMToken::ModuleKeyword) 754 .Case("requires", MMToken::RequiresKeyword) 755 .Case("umbrella", MMToken::UmbrellaKeyword) 756 .Default(MMToken::Identifier); 757 break; 758 759 case tok::comma: 760 Tok.Kind = MMToken::Comma; 761 break; 762 763 case tok::eof: 764 Tok.Kind = MMToken::EndOfFile; 765 break; 766 767 case tok::l_brace: 768 Tok.Kind = MMToken::LBrace; 769 break; 770 771 case tok::l_square: 772 Tok.Kind = MMToken::LSquare; 773 break; 774 775 case tok::period: 776 Tok.Kind = MMToken::Period; 777 break; 778 779 case tok::r_brace: 780 Tok.Kind = MMToken::RBrace; 781 break; 782 783 case tok::r_square: 784 Tok.Kind = MMToken::RSquare; 785 break; 786 787 case tok::star: 788 Tok.Kind = MMToken::Star; 789 break; 790 791 case tok::string_literal: { 792 if (LToken.hasUDSuffix()) { 793 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 794 HadError = true; 795 goto retry; 796 } 797 798 // Parse the string literal. 799 LangOptions LangOpts; 800 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 801 if (StringLiteral.hadError) 802 goto retry; 803 804 // Copy the string literal into our string data allocator. 805 unsigned Length = StringLiteral.GetStringLength(); 806 char *Saved = StringData.Allocate<char>(Length + 1); 807 memcpy(Saved, StringLiteral.GetString().data(), Length); 808 Saved[Length] = 0; 809 810 // Form the token. 811 Tok.Kind = MMToken::StringLiteral; 812 Tok.StringData = Saved; 813 Tok.StringLength = Length; 814 break; 815 } 816 817 case tok::comment: 818 goto retry; 819 820 default: 821 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 822 HadError = true; 823 goto retry; 824 } 825 826 return Result; 827 } 828 829 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 830 unsigned braceDepth = 0; 831 unsigned squareDepth = 0; 832 do { 833 switch (Tok.Kind) { 834 case MMToken::EndOfFile: 835 return; 836 837 case MMToken::LBrace: 838 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 839 return; 840 841 ++braceDepth; 842 break; 843 844 case MMToken::LSquare: 845 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 846 return; 847 848 ++squareDepth; 849 break; 850 851 case MMToken::RBrace: 852 if (braceDepth > 0) 853 --braceDepth; 854 else if (Tok.is(K)) 855 return; 856 break; 857 858 case MMToken::RSquare: 859 if (squareDepth > 0) 860 --squareDepth; 861 else if (Tok.is(K)) 862 return; 863 break; 864 865 default: 866 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 867 return; 868 break; 869 } 870 871 consumeToken(); 872 } while (true); 873 } 874 875 /// \brief Parse a module-id. 876 /// 877 /// module-id: 878 /// identifier 879 /// identifier '.' module-id 880 /// 881 /// \returns true if an error occurred, false otherwise. 882 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 883 Id.clear(); 884 do { 885 if (Tok.is(MMToken::Identifier)) { 886 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 887 consumeToken(); 888 } else { 889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 890 return true; 891 } 892 893 if (!Tok.is(MMToken::Period)) 894 break; 895 896 consumeToken(); 897 } while (true); 898 899 return false; 900 } 901 902 namespace { 903 /// \brief Enumerates the known attributes. 904 enum AttributeKind { 905 /// \brief An unknown attribute. 906 AT_unknown, 907 /// \brief The 'system' attribute. 908 AT_system 909 }; 910 } 911 912 /// \brief Parse a module declaration. 913 /// 914 /// module-declaration: 915 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 916 /// { module-member* } 917 /// 918 /// module-member: 919 /// requires-declaration 920 /// header-declaration 921 /// submodule-declaration 922 /// export-declaration 923 /// 924 /// submodule-declaration: 925 /// module-declaration 926 /// inferred-submodule-declaration 927 void ModuleMapParser::parseModuleDecl() { 928 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 929 Tok.is(MMToken::FrameworkKeyword)); 930 // Parse 'explicit' or 'framework' keyword, if present. 931 SourceLocation ExplicitLoc; 932 bool Explicit = false; 933 bool Framework = false; 934 935 // Parse 'explicit' keyword, if present. 936 if (Tok.is(MMToken::ExplicitKeyword)) { 937 ExplicitLoc = consumeToken(); 938 Explicit = true; 939 } 940 941 // Parse 'framework' keyword, if present. 942 if (Tok.is(MMToken::FrameworkKeyword)) { 943 consumeToken(); 944 Framework = true; 945 } 946 947 // Parse 'module' keyword. 948 if (!Tok.is(MMToken::ModuleKeyword)) { 949 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 950 consumeToken(); 951 HadError = true; 952 return; 953 } 954 consumeToken(); // 'module' keyword 955 956 // If we have a wildcard for the module name, this is an inferred submodule. 957 // Parse it. 958 if (Tok.is(MMToken::Star)) 959 return parseInferredModuleDecl(Framework, Explicit); 960 961 // Parse the module name. 962 ModuleId Id; 963 if (parseModuleId(Id)) { 964 HadError = true; 965 return; 966 } 967 968 if (ActiveModule) { 969 if (Id.size() > 1) { 970 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 971 << SourceRange(Id.front().second, Id.back().second); 972 973 HadError = true; 974 return; 975 } 976 } else if (Id.size() == 1 && Explicit) { 977 // Top-level modules can't be explicit. 978 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 979 Explicit = false; 980 ExplicitLoc = SourceLocation(); 981 HadError = true; 982 } 983 984 Module *PreviousActiveModule = ActiveModule; 985 if (Id.size() > 1) { 986 // This module map defines a submodule. Go find the module of which it 987 // is a submodule. 988 ActiveModule = 0; 989 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 990 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 991 ActiveModule = Next; 992 continue; 993 } 994 995 if (ActiveModule) { 996 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 997 << Id[I].first << ActiveModule->getTopLevelModule(); 998 } else { 999 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1000 } 1001 HadError = true; 1002 return; 1003 } 1004 } 1005 1006 StringRef ModuleName = Id.back().first; 1007 SourceLocation ModuleNameLoc = Id.back().second; 1008 1009 // Parse the optional attribute list. 1010 Attributes Attrs; 1011 parseOptionalAttributes(Attrs); 1012 1013 // Parse the opening brace. 1014 if (!Tok.is(MMToken::LBrace)) { 1015 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1016 << ModuleName; 1017 HadError = true; 1018 return; 1019 } 1020 SourceLocation LBraceLoc = consumeToken(); 1021 1022 // Determine whether this (sub)module has already been defined. 1023 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1024 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1025 // Skip the module definition. 1026 skipUntil(MMToken::RBrace); 1027 if (Tok.is(MMToken::RBrace)) 1028 consumeToken(); 1029 else { 1030 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1031 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1032 HadError = true; 1033 } 1034 return; 1035 } 1036 1037 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1038 << ModuleName; 1039 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1040 1041 // Skip the module definition. 1042 skipUntil(MMToken::RBrace); 1043 if (Tok.is(MMToken::RBrace)) 1044 consumeToken(); 1045 1046 HadError = true; 1047 return; 1048 } 1049 1050 // Start defining this module. 1051 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1052 Explicit).first; 1053 ActiveModule->DefinitionLoc = ModuleNameLoc; 1054 if (Attrs.IsSystem) 1055 ActiveModule->IsSystem = true; 1056 1057 bool Done = false; 1058 do { 1059 switch (Tok.Kind) { 1060 case MMToken::EndOfFile: 1061 case MMToken::RBrace: 1062 Done = true; 1063 break; 1064 1065 case MMToken::ExplicitKeyword: 1066 case MMToken::FrameworkKeyword: 1067 case MMToken::ModuleKeyword: 1068 parseModuleDecl(); 1069 break; 1070 1071 case MMToken::ExportKeyword: 1072 parseExportDecl(); 1073 break; 1074 1075 case MMToken::RequiresKeyword: 1076 parseRequiresDecl(); 1077 break; 1078 1079 case MMToken::UmbrellaKeyword: { 1080 SourceLocation UmbrellaLoc = consumeToken(); 1081 if (Tok.is(MMToken::HeaderKeyword)) 1082 parseHeaderDecl(UmbrellaLoc, SourceLocation()); 1083 else 1084 parseUmbrellaDirDecl(UmbrellaLoc); 1085 break; 1086 } 1087 1088 case MMToken::ExcludeKeyword: { 1089 SourceLocation ExcludeLoc = consumeToken(); 1090 if (Tok.is(MMToken::HeaderKeyword)) { 1091 parseHeaderDecl(SourceLocation(), ExcludeLoc); 1092 } else { 1093 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1094 << "exclude"; 1095 } 1096 break; 1097 } 1098 1099 case MMToken::HeaderKeyword: 1100 parseHeaderDecl(SourceLocation(), SourceLocation()); 1101 break; 1102 1103 default: 1104 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1105 consumeToken(); 1106 break; 1107 } 1108 } while (!Done); 1109 1110 if (Tok.is(MMToken::RBrace)) 1111 consumeToken(); 1112 else { 1113 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1114 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1115 HadError = true; 1116 } 1117 1118 // We're done parsing this module. Pop back to the previous module. 1119 ActiveModule = PreviousActiveModule; 1120 } 1121 1122 /// \brief Parse a requires declaration. 1123 /// 1124 /// requires-declaration: 1125 /// 'requires' feature-list 1126 /// 1127 /// feature-list: 1128 /// identifier ',' feature-list 1129 /// identifier 1130 void ModuleMapParser::parseRequiresDecl() { 1131 assert(Tok.is(MMToken::RequiresKeyword)); 1132 1133 // Parse 'requires' keyword. 1134 consumeToken(); 1135 1136 // Parse the feature-list. 1137 do { 1138 if (!Tok.is(MMToken::Identifier)) { 1139 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1140 HadError = true; 1141 return; 1142 } 1143 1144 // Consume the feature name. 1145 std::string Feature = Tok.getString(); 1146 consumeToken(); 1147 1148 // Add this feature. 1149 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 1150 1151 if (!Tok.is(MMToken::Comma)) 1152 break; 1153 1154 // Consume the comma. 1155 consumeToken(); 1156 } while (true); 1157 } 1158 1159 /// \brief Append to \p Paths the set of paths needed to get to the 1160 /// subframework in which the given module lives. 1161 static void appendSubframeworkPaths(Module *Mod, 1162 llvm::SmallVectorImpl<char> &Path) { 1163 // Collect the framework names from the given module to the top-level module. 1164 llvm::SmallVector<StringRef, 2> Paths; 1165 for (; Mod; Mod = Mod->Parent) { 1166 if (Mod->IsFramework) 1167 Paths.push_back(Mod->Name); 1168 } 1169 1170 if (Paths.empty()) 1171 return; 1172 1173 // Add Frameworks/Name.framework for each subframework. 1174 for (unsigned I = Paths.size() - 1; I != 0; --I) { 1175 llvm::sys::path::append(Path, "Frameworks"); 1176 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 1177 } 1178 } 1179 1180 /// \brief Determine whether the given file name is the name of a builtin 1181 /// header, supplied by Clang to replace, override, or augment existing system 1182 /// headers. 1183 static bool isBuiltinHeader(StringRef FileName) { 1184 return llvm::StringSwitch<bool>(FileName) 1185 .Case("float.h", true) 1186 .Case("iso646.h", true) 1187 .Case("limits.h", true) 1188 .Case("stdalign.h", true) 1189 .Case("stdarg.h", true) 1190 .Case("stdbool.h", true) 1191 .Case("stddef.h", true) 1192 .Case("stdint.h", true) 1193 .Case("tgmath.h", true) 1194 .Case("unwind.h", true) 1195 .Default(false); 1196 } 1197 1198 /// \brief Parse a header declaration. 1199 /// 1200 /// header-declaration: 1201 /// 'umbrella'[opt] 'header' string-literal 1202 /// 'exclude'[opt] 'header' string-literal 1203 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc, 1204 SourceLocation ExcludeLoc) { 1205 assert(Tok.is(MMToken::HeaderKeyword)); 1206 consumeToken(); 1207 1208 bool Umbrella = UmbrellaLoc.isValid(); 1209 bool Exclude = ExcludeLoc.isValid(); 1210 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'"); 1211 // Parse the header name. 1212 if (!Tok.is(MMToken::StringLiteral)) { 1213 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1214 << "header"; 1215 HadError = true; 1216 return; 1217 } 1218 std::string FileName = Tok.getString(); 1219 SourceLocation FileNameLoc = consumeToken(); 1220 1221 // Check whether we already have an umbrella. 1222 if (Umbrella && ActiveModule->Umbrella) { 1223 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1224 << ActiveModule->getFullModuleName(); 1225 HadError = true; 1226 return; 1227 } 1228 1229 // Look for this file. 1230 const FileEntry *File = 0; 1231 const FileEntry *BuiltinFile = 0; 1232 SmallString<128> PathName; 1233 if (llvm::sys::path::is_absolute(FileName)) { 1234 PathName = FileName; 1235 File = SourceMgr.getFileManager().getFile(PathName); 1236 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1237 PathName = Dir->getName(); 1238 llvm::sys::path::append(PathName, FileName); 1239 File = SourceMgr.getFileManager().getFile(PathName); 1240 } else { 1241 // Search for the header file within the search directory. 1242 PathName = Directory->getName(); 1243 unsigned PathLength = PathName.size(); 1244 1245 if (ActiveModule->isPartOfFramework()) { 1246 appendSubframeworkPaths(ActiveModule, PathName); 1247 1248 // Check whether this file is in the public headers. 1249 llvm::sys::path::append(PathName, "Headers"); 1250 llvm::sys::path::append(PathName, FileName); 1251 File = SourceMgr.getFileManager().getFile(PathName); 1252 1253 if (!File) { 1254 // Check whether this file is in the private headers. 1255 PathName.resize(PathLength); 1256 llvm::sys::path::append(PathName, "PrivateHeaders"); 1257 llvm::sys::path::append(PathName, FileName); 1258 File = SourceMgr.getFileManager().getFile(PathName); 1259 } 1260 } else { 1261 // Lookup for normal headers. 1262 llvm::sys::path::append(PathName, FileName); 1263 File = SourceMgr.getFileManager().getFile(PathName); 1264 1265 // If this is a system module with a top-level header, this header 1266 // may have a counterpart (or replacement) in the set of headers 1267 // supplied by Clang. Find that builtin header. 1268 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir && 1269 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) { 1270 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1271 llvm::sys::path::append(BuiltinPathName, FileName); 1272 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1273 1274 // If Clang supplies this header but the underlying system does not, 1275 // just silently swap in our builtin version. Otherwise, we'll end 1276 // up adding both (later). 1277 if (!File && BuiltinFile) { 1278 File = BuiltinFile; 1279 BuiltinFile = 0; 1280 } 1281 } 1282 } 1283 } 1284 1285 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1286 // Come up with a lazy way to do this. 1287 if (File) { 1288 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) { 1289 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1290 << FileName << OwningModule.getModule()->getFullModuleName(); 1291 HadError = true; 1292 } else if (Umbrella) { 1293 const DirectoryEntry *UmbrellaDir = File->getDir(); 1294 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1295 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1296 << UmbrellaModule->getFullModuleName(); 1297 HadError = true; 1298 } else { 1299 // Record this umbrella header. 1300 Map.setUmbrellaHeader(ActiveModule, File); 1301 } 1302 } else { 1303 // Record this header. 1304 Map.addHeader(ActiveModule, File, Exclude); 1305 1306 // If there is a builtin counterpart to this file, add it now. 1307 if (BuiltinFile) 1308 Map.addHeader(ActiveModule, BuiltinFile, Exclude); 1309 } 1310 } else { 1311 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1312 << Umbrella << FileName; 1313 HadError = true; 1314 } 1315 } 1316 1317 /// \brief Parse an umbrella directory declaration. 1318 /// 1319 /// umbrella-dir-declaration: 1320 /// umbrella string-literal 1321 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1322 // Parse the directory name. 1323 if (!Tok.is(MMToken::StringLiteral)) { 1324 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1325 << "umbrella"; 1326 HadError = true; 1327 return; 1328 } 1329 1330 std::string DirName = Tok.getString(); 1331 SourceLocation DirNameLoc = consumeToken(); 1332 1333 // Check whether we already have an umbrella. 1334 if (ActiveModule->Umbrella) { 1335 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1336 << ActiveModule->getFullModuleName(); 1337 HadError = true; 1338 return; 1339 } 1340 1341 // Look for this file. 1342 const DirectoryEntry *Dir = 0; 1343 if (llvm::sys::path::is_absolute(DirName)) 1344 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1345 else { 1346 SmallString<128> PathName; 1347 PathName = Directory->getName(); 1348 llvm::sys::path::append(PathName, DirName); 1349 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1350 } 1351 1352 if (!Dir) { 1353 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1354 << DirName; 1355 HadError = true; 1356 return; 1357 } 1358 1359 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1360 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1361 << OwningModule->getFullModuleName(); 1362 HadError = true; 1363 return; 1364 } 1365 1366 // Record this umbrella directory. 1367 Map.setUmbrellaDir(ActiveModule, Dir); 1368 } 1369 1370 /// \brief Parse a module export declaration. 1371 /// 1372 /// export-declaration: 1373 /// 'export' wildcard-module-id 1374 /// 1375 /// wildcard-module-id: 1376 /// identifier 1377 /// '*' 1378 /// identifier '.' wildcard-module-id 1379 void ModuleMapParser::parseExportDecl() { 1380 assert(Tok.is(MMToken::ExportKeyword)); 1381 SourceLocation ExportLoc = consumeToken(); 1382 1383 // Parse the module-id with an optional wildcard at the end. 1384 ModuleId ParsedModuleId; 1385 bool Wildcard = false; 1386 do { 1387 if (Tok.is(MMToken::Identifier)) { 1388 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1389 Tok.getLocation())); 1390 consumeToken(); 1391 1392 if (Tok.is(MMToken::Period)) { 1393 consumeToken(); 1394 continue; 1395 } 1396 1397 break; 1398 } 1399 1400 if(Tok.is(MMToken::Star)) { 1401 Wildcard = true; 1402 consumeToken(); 1403 break; 1404 } 1405 1406 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1407 HadError = true; 1408 return; 1409 } while (true); 1410 1411 Module::UnresolvedExportDecl Unresolved = { 1412 ExportLoc, ParsedModuleId, Wildcard 1413 }; 1414 ActiveModule->UnresolvedExports.push_back(Unresolved); 1415 } 1416 1417 /// \brief Parse an inferried module declaration (wildcard modules). 1418 /// 1419 /// module-declaration: 1420 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 1421 /// { inferred-module-member* } 1422 /// 1423 /// inferred-module-member: 1424 /// 'export' '*' 1425 /// 'exclude' identifier 1426 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 1427 assert(Tok.is(MMToken::Star)); 1428 SourceLocation StarLoc = consumeToken(); 1429 bool Failed = false; 1430 1431 // Inferred modules must be submodules. 1432 if (!ActiveModule && !Framework) { 1433 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1434 Failed = true; 1435 } 1436 1437 if (ActiveModule) { 1438 // Inferred modules must have umbrella directories. 1439 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1440 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1441 Failed = true; 1442 } 1443 1444 // Check for redefinition of an inferred module. 1445 if (!Failed && ActiveModule->InferSubmodules) { 1446 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1447 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1448 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1449 diag::note_mmap_prev_definition); 1450 Failed = true; 1451 } 1452 1453 // Check for the 'framework' keyword, which is not permitted here. 1454 if (Framework) { 1455 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 1456 Framework = false; 1457 } 1458 } else if (Explicit) { 1459 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 1460 Explicit = false; 1461 } 1462 1463 // If there were any problems with this inferred submodule, skip its body. 1464 if (Failed) { 1465 if (Tok.is(MMToken::LBrace)) { 1466 consumeToken(); 1467 skipUntil(MMToken::RBrace); 1468 if (Tok.is(MMToken::RBrace)) 1469 consumeToken(); 1470 } 1471 HadError = true; 1472 return; 1473 } 1474 1475 // Parse optional attributes. 1476 Attributes Attrs; 1477 parseOptionalAttributes(Attrs); 1478 1479 if (ActiveModule) { 1480 // Note that we have an inferred submodule. 1481 ActiveModule->InferSubmodules = true; 1482 ActiveModule->InferredSubmoduleLoc = StarLoc; 1483 ActiveModule->InferExplicitSubmodules = Explicit; 1484 } else { 1485 // We'll be inferring framework modules for this directory. 1486 Map.InferredDirectories[Directory].InferModules = true; 1487 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 1488 } 1489 1490 // Parse the opening brace. 1491 if (!Tok.is(MMToken::LBrace)) { 1492 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1493 HadError = true; 1494 return; 1495 } 1496 SourceLocation LBraceLoc = consumeToken(); 1497 1498 // Parse the body of the inferred submodule. 1499 bool Done = false; 1500 do { 1501 switch (Tok.Kind) { 1502 case MMToken::EndOfFile: 1503 case MMToken::RBrace: 1504 Done = true; 1505 break; 1506 1507 case MMToken::ExcludeKeyword: { 1508 if (ActiveModule) { 1509 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1510 << (ActiveModule != nullptr); 1511 consumeToken(); 1512 break; 1513 } 1514 1515 consumeToken(); 1516 if (!Tok.is(MMToken::Identifier)) { 1517 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 1518 break; 1519 } 1520 1521 Map.InferredDirectories[Directory].ExcludedModules 1522 .push_back(Tok.getString()); 1523 consumeToken(); 1524 break; 1525 } 1526 1527 case MMToken::ExportKeyword: 1528 if (!ActiveModule) { 1529 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1530 << (ActiveModule != nullptr); 1531 consumeToken(); 1532 break; 1533 } 1534 1535 consumeToken(); 1536 if (Tok.is(MMToken::Star)) 1537 ActiveModule->InferExportWildcard = true; 1538 else 1539 Diags.Report(Tok.getLocation(), 1540 diag::err_mmap_expected_export_wildcard); 1541 consumeToken(); 1542 break; 1543 1544 case MMToken::ExplicitKeyword: 1545 case MMToken::ModuleKeyword: 1546 case MMToken::HeaderKeyword: 1547 case MMToken::UmbrellaKeyword: 1548 default: 1549 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1550 << (ActiveModule != nullptr); 1551 consumeToken(); 1552 break; 1553 } 1554 } while (!Done); 1555 1556 if (Tok.is(MMToken::RBrace)) 1557 consumeToken(); 1558 else { 1559 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1560 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1561 HadError = true; 1562 } 1563 } 1564 1565 /// \brief Parse optional attributes. 1566 /// 1567 /// attributes: 1568 /// attribute attributes 1569 /// attribute 1570 /// 1571 /// attribute: 1572 /// [ identifier ] 1573 /// 1574 /// \param Attrs Will be filled in with the parsed attributes. 1575 /// 1576 /// \returns true if an error occurred, false otherwise. 1577 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 1578 bool HadError = false; 1579 1580 while (Tok.is(MMToken::LSquare)) { 1581 // Consume the '['. 1582 SourceLocation LSquareLoc = consumeToken(); 1583 1584 // Check whether we have an attribute name here. 1585 if (!Tok.is(MMToken::Identifier)) { 1586 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 1587 skipUntil(MMToken::RSquare); 1588 if (Tok.is(MMToken::RSquare)) 1589 consumeToken(); 1590 HadError = true; 1591 } 1592 1593 // Decode the attribute name. 1594 AttributeKind Attribute 1595 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 1596 .Case("system", AT_system) 1597 .Default(AT_unknown); 1598 switch (Attribute) { 1599 case AT_unknown: 1600 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 1601 << Tok.getString(); 1602 break; 1603 1604 case AT_system: 1605 Attrs.IsSystem = true; 1606 break; 1607 } 1608 consumeToken(); 1609 1610 // Consume the ']'. 1611 if (!Tok.is(MMToken::RSquare)) { 1612 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 1613 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 1614 skipUntil(MMToken::RSquare); 1615 HadError = true; 1616 } 1617 1618 if (Tok.is(MMToken::RSquare)) 1619 consumeToken(); 1620 } 1621 1622 return HadError; 1623 } 1624 1625 /// \brief If there is a specific header search directory due the presence 1626 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1627 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1628 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1629 // If we have an umbrella directory, use that. 1630 if (Mod->hasUmbrellaDir()) 1631 return Mod->getUmbrellaDir(); 1632 1633 // If we have a framework directory, stop looking. 1634 if (Mod->IsFramework) 1635 return 0; 1636 } 1637 1638 return 0; 1639 } 1640 1641 /// \brief Parse a module map file. 1642 /// 1643 /// module-map-file: 1644 /// module-declaration* 1645 bool ModuleMapParser::parseModuleMapFile() { 1646 do { 1647 switch (Tok.Kind) { 1648 case MMToken::EndOfFile: 1649 return HadError; 1650 1651 case MMToken::ExplicitKeyword: 1652 case MMToken::ModuleKeyword: 1653 case MMToken::FrameworkKeyword: 1654 parseModuleDecl(); 1655 break; 1656 1657 case MMToken::Comma: 1658 case MMToken::ExcludeKeyword: 1659 case MMToken::ExportKeyword: 1660 case MMToken::HeaderKeyword: 1661 case MMToken::Identifier: 1662 case MMToken::LBrace: 1663 case MMToken::LSquare: 1664 case MMToken::Period: 1665 case MMToken::RBrace: 1666 case MMToken::RSquare: 1667 case MMToken::RequiresKeyword: 1668 case MMToken::Star: 1669 case MMToken::StringLiteral: 1670 case MMToken::UmbrellaKeyword: 1671 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1672 HadError = true; 1673 consumeToken(); 1674 break; 1675 } 1676 } while (true); 1677 } 1678 1679 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1680 assert(Target != 0 && "Missing target information"); 1681 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1682 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1683 if (!Buffer) 1684 return true; 1685 1686 // Parse this module map file. 1687 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1688 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1689 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(), 1690 BuiltinIncludeDir); 1691 bool Result = Parser.parseModuleMapFile(); 1692 Diags->getClient()->EndSourceFile(); 1693 1694 return Result; 1695 } 1696