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