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