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