1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ModuleMap implementation, which describes the layout 11 // of a module as it relates to headers. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "clang/Lex/ModuleMap.h" 15 #include "clang/Basic/Diagnostic.h" 16 #include "clang/Basic/DiagnosticOptions.h" 17 #include "clang/Basic/FileManager.h" 18 #include "clang/Basic/TargetInfo.h" 19 #include "clang/Basic/TargetOptions.h" 20 #include "clang/Lex/LexDiagnostic.h" 21 #include "clang/Lex/Lexer.h" 22 #include "clang/Lex/LiteralSupport.h" 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/Support/Allocator.h" 26 #include "llvm/Support/FileSystem.h" 27 #include "llvm/Support/Host.h" 28 #include "llvm/Support/PathV2.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <stdlib.h> 31 using namespace clang; 32 33 Module::ExportDecl 34 ModuleMap::resolveExport(Module *Mod, 35 const Module::UnresolvedExportDecl &Unresolved, 36 bool Complain) { 37 // We may have just a wildcard. 38 if (Unresolved.Id.empty()) { 39 assert(Unresolved.Wildcard && "Invalid unresolved export"); 40 return Module::ExportDecl(0, true); 41 } 42 43 // Find the starting module. 44 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 45 if (!Context) { 46 if (Complain) 47 Diags->Report(Unresolved.Id[0].second, 48 diag::err_mmap_missing_module_unqualified) 49 << Unresolved.Id[0].first << Mod->getFullModuleName(); 50 51 return Module::ExportDecl(); 52 } 53 54 // Dig into the module path. 55 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 56 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 57 Context); 58 if (!Sub) { 59 if (Complain) 60 Diags->Report(Unresolved.Id[I].second, 61 diag::err_mmap_missing_module_qualified) 62 << Unresolved.Id[I].first << Context->getFullModuleName() 63 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 64 65 return Module::ExportDecl(); 66 } 67 68 Context = Sub; 69 } 70 71 return Module::ExportDecl(Context, Unresolved.Wildcard); 72 } 73 74 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, 75 const LangOptions &LangOpts, const TargetInfo *Target) 76 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0) 77 { 78 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 79 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( 80 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions)); 81 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 82 SourceMgr = new SourceManager(*Diags, FileMgr); 83 } 84 85 ModuleMap::~ModuleMap() { 86 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 87 IEnd = Modules.end(); 88 I != IEnd; ++I) { 89 delete I->getValue(); 90 } 91 92 delete SourceMgr; 93 } 94 95 void ModuleMap::setTarget(const TargetInfo &Target) { 96 assert((!this->Target || this->Target == &Target) && 97 "Improper target override"); 98 this->Target = &Target; 99 } 100 101 /// \brief "Sanitize" a filename so that it can be used as an identifier. 102 static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 103 SmallVectorImpl<char> &Buffer) { 104 if (Name.empty()) 105 return Name; 106 107 // Check whether the filename is already an identifier; this is the common 108 // case. 109 bool isIdentifier = true; 110 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 111 if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0)) 112 continue; 113 114 isIdentifier = false; 115 break; 116 } 117 118 if (!isIdentifier) { 119 // If we don't already have something with the form of an identifier, 120 // create a buffer with the sanitized name. 121 Buffer.clear(); 122 if (isdigit(Name[0])) 123 Buffer.push_back('_'); 124 Buffer.reserve(Buffer.size() + Name.size()); 125 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 126 if (isalnum(Name[I]) || isspace(Name[I])) 127 Buffer.push_back(Name[I]); 128 else 129 Buffer.push_back('_'); 130 } 131 132 Name = StringRef(Buffer.data(), Buffer.size()); 133 } 134 135 while (llvm::StringSwitch<bool>(Name) 136 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 137 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 138 #include "clang/Basic/TokenKinds.def" 139 .Default(false)) { 140 if (Name.data() != Buffer.data()) 141 Buffer.append(Name.begin(), Name.end()); 142 Buffer.push_back('_'); 143 Name = StringRef(Buffer.data(), Buffer.size()); 144 } 145 146 return Name; 147 } 148 149 Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 150 HeadersMap::iterator Known = Headers.find(File); 151 if (Known != Headers.end()) { 152 // If a header is not available, don't report that it maps to anything. 153 if (!Known->second.isAvailable()) 154 return 0; 155 156 return Known->second.getModule(); 157 } 158 159 const DirectoryEntry *Dir = File->getDir(); 160 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 161 #ifdef LLVM_ON_UNIX 162 // Note: as an egregious but useful hack we use the real path here, because 163 // frameworks moving from top-level frameworks to embedded frameworks tend 164 // to be symlinked from the top-level location to the embedded location, 165 // and we need to resolve lookups as if we had found the embedded location. 166 char RealDirName[PATH_MAX]; 167 StringRef DirName; 168 if (realpath(Dir->getName(), RealDirName)) 169 DirName = RealDirName; 170 else 171 DirName = Dir->getName(); 172 #else 173 StringRef DirName = Dir->getName(); 174 #endif 175 176 // Keep walking up the directory hierarchy, looking for a directory with 177 // an umbrella header. 178 do { 179 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 180 = UmbrellaDirs.find(Dir); 181 if (KnownDir != UmbrellaDirs.end()) { 182 Module *Result = KnownDir->second; 183 184 // Search up the module stack until we find a module with an umbrella 185 // directory. 186 Module *UmbrellaModule = Result; 187 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 188 UmbrellaModule = UmbrellaModule->Parent; 189 190 if (UmbrellaModule->InferSubmodules) { 191 // Infer submodules for each of the directories we found between 192 // the directory of the umbrella header and the directory where 193 // the actual header is located. 194 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 195 196 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 197 // Find or create the module that corresponds to this directory name. 198 SmallString<32> NameBuf; 199 StringRef Name = sanitizeFilenameAsIdentifier( 200 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 201 NameBuf); 202 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 203 Explicit).first; 204 205 // Associate the module and the directory. 206 UmbrellaDirs[SkippedDirs[I-1]] = Result; 207 208 // If inferred submodules export everything they import, add a 209 // wildcard to the set of exports. 210 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 211 Result->Exports.push_back(Module::ExportDecl(0, true)); 212 } 213 214 // Infer a submodule with the same name as this header file. 215 SmallString<32> NameBuf; 216 StringRef Name = sanitizeFilenameAsIdentifier( 217 llvm::sys::path::stem(File->getName()), NameBuf); 218 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 219 Explicit).first; 220 Result->TopHeaders.insert(File); 221 222 // If inferred submodules export everything they import, add a 223 // wildcard to the set of exports. 224 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 225 Result->Exports.push_back(Module::ExportDecl(0, true)); 226 } else { 227 // Record each of the directories we stepped through as being part of 228 // the module we found, since the umbrella header covers them all. 229 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 230 UmbrellaDirs[SkippedDirs[I]] = Result; 231 } 232 233 Headers[File] = KnownHeader(Result, /*Excluded=*/false); 234 235 // If a header corresponds to an unavailable module, don't report 236 // that it maps to anything. 237 if (!Result->isAvailable()) 238 return 0; 239 240 return Result; 241 } 242 243 SkippedDirs.push_back(Dir); 244 245 // Retrieve our parent path. 246 DirName = llvm::sys::path::parent_path(DirName); 247 if (DirName.empty()) 248 break; 249 250 // Resolve the parent path to a directory entry. 251 Dir = SourceMgr->getFileManager().getDirectory(DirName); 252 } while (Dir); 253 254 return 0; 255 } 256 257 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) { 258 HeadersMap::iterator Known = Headers.find(Header); 259 if (Known != Headers.end()) 260 return !Known->second.isAvailable(); 261 262 const DirectoryEntry *Dir = Header->getDir(); 263 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 264 StringRef DirName = Dir->getName(); 265 266 // Keep walking up the directory hierarchy, looking for a directory with 267 // an umbrella header. 268 do { 269 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 270 = UmbrellaDirs.find(Dir); 271 if (KnownDir != UmbrellaDirs.end()) { 272 Module *Found = KnownDir->second; 273 if (!Found->isAvailable()) 274 return true; 275 276 // Search up the module stack until we find a module with an umbrella 277 // directory. 278 Module *UmbrellaModule = Found; 279 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 280 UmbrellaModule = UmbrellaModule->Parent; 281 282 if (UmbrellaModule->InferSubmodules) { 283 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 284 // Find or create the module that corresponds to this directory name. 285 SmallString<32> NameBuf; 286 StringRef Name = sanitizeFilenameAsIdentifier( 287 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 288 NameBuf); 289 Found = lookupModuleQualified(Name, Found); 290 if (!Found) 291 return false; 292 if (!Found->isAvailable()) 293 return true; 294 } 295 296 // Infer a submodule with the same name as this header file. 297 SmallString<32> NameBuf; 298 StringRef Name = sanitizeFilenameAsIdentifier( 299 llvm::sys::path::stem(Header->getName()), 300 NameBuf); 301 Found = lookupModuleQualified(Name, Found); 302 if (!Found) 303 return false; 304 } 305 306 return !Found->isAvailable(); 307 } 308 309 SkippedDirs.push_back(Dir); 310 311 // Retrieve our parent path. 312 DirName = llvm::sys::path::parent_path(DirName); 313 if (DirName.empty()) 314 break; 315 316 // Resolve the parent path to a directory entry. 317 Dir = SourceMgr->getFileManager().getDirectory(DirName); 318 } while (Dir); 319 320 return false; 321 } 322 323 Module *ModuleMap::findModule(StringRef Name) { 324 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 325 if (Known != Modules.end()) 326 return Known->getValue(); 327 328 return 0; 329 } 330 331 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 332 for(; Context; Context = Context->Parent) { 333 if (Module *Sub = lookupModuleQualified(Name, Context)) 334 return Sub; 335 } 336 337 return findModule(Name); 338 } 339 340 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 341 if (!Context) 342 return findModule(Name); 343 344 return Context->findSubmodule(Name); 345 } 346 347 std::pair<Module *, bool> 348 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 349 bool IsExplicit) { 350 // Try to find an existing module with this name. 351 if (Module *Sub = lookupModuleQualified(Name, Parent)) 352 return std::make_pair(Sub, false); 353 354 // Create a new module with this name. 355 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 356 IsExplicit); 357 if (!Parent) 358 Modules[Name] = Result; 359 return std::make_pair(Result, true); 360 } 361 362 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 363 StringRef Name, bool &IsSystem) { 364 // Check whether we have already looked into the parent directory 365 // for a module map. 366 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator 367 inferred = InferredDirectories.find(ParentDir); 368 if (inferred == InferredDirectories.end()) 369 return false; 370 371 if (!inferred->second.InferModules) 372 return false; 373 374 // We're allowed to infer for this directory, but make sure it's okay 375 // to infer this particular module. 376 bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 377 inferred->second.ExcludedModules.end(), 378 Name) == inferred->second.ExcludedModules.end(); 379 380 if (canInfer && inferred->second.InferSystemModules) 381 IsSystem = true; 382 383 return canInfer; 384 } 385 386 Module * 387 ModuleMap::inferFrameworkModule(StringRef ModuleName, 388 const DirectoryEntry *FrameworkDir, 389 bool IsSystem, 390 Module *Parent) { 391 // Check whether we've already found this module. 392 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 393 return Mod; 394 395 FileManager &FileMgr = SourceMgr->getFileManager(); 396 397 // If the framework has a parent path from which we're allowed to infer 398 // a framework module, do so. 399 if (!Parent) { 400 // Determine whether we're allowed to infer a module map. 401 StringRef FrameworkDirName = FrameworkDir->getName(); 402 #ifdef LLVM_ON_UNIX 403 // Note: as an egregious but useful hack we use the real path here, because 404 // we might be looking at an embedded framework that symlinks out to a 405 // top-level framework, and we need to infer as if we were naming the 406 // top-level framework. 407 char RealFrameworkDirName[PATH_MAX]; 408 if (realpath(FrameworkDir->getName(), RealFrameworkDirName)) 409 FrameworkDirName = RealFrameworkDirName; 410 #endif 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>::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 #ifdef LLVM_ON_UNIX 509 char RealSubframeworkDirName[PATH_MAX]; 510 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) { 511 StringRef SubframeworkDirName = RealSubframeworkDirName; 512 513 bool FoundParent = false; 514 do { 515 // Get the parent directory name. 516 SubframeworkDirName 517 = llvm::sys::path::parent_path(SubframeworkDirName); 518 if (SubframeworkDirName.empty()) 519 break; 520 521 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 522 FoundParent = true; 523 break; 524 } 525 } while (true); 526 527 if (!FoundParent) 528 continue; 529 } 530 #endif 531 532 // FIXME: Do we want to warn about subframeworks without umbrella headers? 533 SmallString<32> NameBuf; 534 inferFrameworkModule(sanitizeFilenameAsIdentifier( 535 llvm::sys::path::stem(Dir->path()), NameBuf), 536 SubframeworkDir, IsSystem, Result); 537 } 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) { 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 // We're done parsing this module. Pop back to the previous module. 1151 ActiveModule = PreviousActiveModule; 1152 } 1153 1154 /// \brief Parse a requires declaration. 1155 /// 1156 /// requires-declaration: 1157 /// 'requires' feature-list 1158 /// 1159 /// feature-list: 1160 /// identifier ',' feature-list 1161 /// identifier 1162 void ModuleMapParser::parseRequiresDecl() { 1163 assert(Tok.is(MMToken::RequiresKeyword)); 1164 1165 // Parse 'requires' keyword. 1166 consumeToken(); 1167 1168 // Parse the feature-list. 1169 do { 1170 if (!Tok.is(MMToken::Identifier)) { 1171 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1172 HadError = true; 1173 return; 1174 } 1175 1176 // Consume the feature name. 1177 std::string Feature = Tok.getString(); 1178 consumeToken(); 1179 1180 // Add this feature. 1181 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 1182 1183 if (!Tok.is(MMToken::Comma)) 1184 break; 1185 1186 // Consume the comma. 1187 consumeToken(); 1188 } while (true); 1189 } 1190 1191 /// \brief Append to \p Paths the set of paths needed to get to the 1192 /// subframework in which the given module lives. 1193 static void appendSubframeworkPaths(Module *Mod, 1194 SmallVectorImpl<char> &Path) { 1195 // Collect the framework names from the given module to the top-level module. 1196 SmallVector<StringRef, 2> Paths; 1197 for (; Mod; Mod = Mod->Parent) { 1198 if (Mod->IsFramework) 1199 Paths.push_back(Mod->Name); 1200 } 1201 1202 if (Paths.empty()) 1203 return; 1204 1205 // Add Frameworks/Name.framework for each subframework. 1206 for (unsigned I = Paths.size() - 1; I != 0; --I) { 1207 llvm::sys::path::append(Path, "Frameworks"); 1208 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 1209 } 1210 } 1211 1212 /// \brief Determine whether the given file name is the name of a builtin 1213 /// header, supplied by Clang to replace, override, or augment existing system 1214 /// headers. 1215 static bool isBuiltinHeader(StringRef FileName) { 1216 return llvm::StringSwitch<bool>(FileName) 1217 .Case("float.h", true) 1218 .Case("iso646.h", true) 1219 .Case("limits.h", true) 1220 .Case("stdalign.h", true) 1221 .Case("stdarg.h", true) 1222 .Case("stdbool.h", true) 1223 .Case("stddef.h", true) 1224 .Case("stdint.h", true) 1225 .Case("tgmath.h", true) 1226 .Case("unwind.h", true) 1227 .Default(false); 1228 } 1229 1230 /// \brief Parse a header declaration. 1231 /// 1232 /// header-declaration: 1233 /// 'umbrella'[opt] 'header' string-literal 1234 /// 'exclude'[opt] 'header' string-literal 1235 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc, 1236 SourceLocation ExcludeLoc) { 1237 assert(Tok.is(MMToken::HeaderKeyword)); 1238 consumeToken(); 1239 1240 bool Umbrella = UmbrellaLoc.isValid(); 1241 bool Exclude = ExcludeLoc.isValid(); 1242 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'"); 1243 // Parse the header name. 1244 if (!Tok.is(MMToken::StringLiteral)) { 1245 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1246 << "header"; 1247 HadError = true; 1248 return; 1249 } 1250 std::string FileName = Tok.getString(); 1251 SourceLocation FileNameLoc = consumeToken(); 1252 1253 // Check whether we already have an umbrella. 1254 if (Umbrella && ActiveModule->Umbrella) { 1255 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1256 << ActiveModule->getFullModuleName(); 1257 HadError = true; 1258 return; 1259 } 1260 1261 // Look for this file. 1262 const FileEntry *File = 0; 1263 const FileEntry *BuiltinFile = 0; 1264 SmallString<128> PathName; 1265 if (llvm::sys::path::is_absolute(FileName)) { 1266 PathName = FileName; 1267 File = SourceMgr.getFileManager().getFile(PathName); 1268 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1269 PathName = Dir->getName(); 1270 llvm::sys::path::append(PathName, FileName); 1271 File = SourceMgr.getFileManager().getFile(PathName); 1272 } else { 1273 // Search for the header file within the search directory. 1274 PathName = Directory->getName(); 1275 unsigned PathLength = PathName.size(); 1276 1277 if (ActiveModule->isPartOfFramework()) { 1278 appendSubframeworkPaths(ActiveModule, PathName); 1279 1280 // Check whether this file is in the public headers. 1281 llvm::sys::path::append(PathName, "Headers"); 1282 llvm::sys::path::append(PathName, FileName); 1283 File = SourceMgr.getFileManager().getFile(PathName); 1284 1285 if (!File) { 1286 // Check whether this file is in the private headers. 1287 PathName.resize(PathLength); 1288 llvm::sys::path::append(PathName, "PrivateHeaders"); 1289 llvm::sys::path::append(PathName, FileName); 1290 File = SourceMgr.getFileManager().getFile(PathName); 1291 } 1292 } else { 1293 // Lookup for normal headers. 1294 llvm::sys::path::append(PathName, FileName); 1295 File = SourceMgr.getFileManager().getFile(PathName); 1296 1297 // If this is a system module with a top-level header, this header 1298 // may have a counterpart (or replacement) in the set of headers 1299 // supplied by Clang. Find that builtin header. 1300 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir && 1301 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) { 1302 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1303 llvm::sys::path::append(BuiltinPathName, FileName); 1304 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1305 1306 // If Clang supplies this header but the underlying system does not, 1307 // just silently swap in our builtin version. Otherwise, we'll end 1308 // up adding both (later). 1309 if (!File && BuiltinFile) { 1310 File = BuiltinFile; 1311 BuiltinFile = 0; 1312 } 1313 } 1314 } 1315 } 1316 1317 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1318 // Come up with a lazy way to do this. 1319 if (File) { 1320 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) { 1321 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 1322 << FileName << OwningModule.getModule()->getFullModuleName(); 1323 HadError = true; 1324 } else if (Umbrella) { 1325 const DirectoryEntry *UmbrellaDir = File->getDir(); 1326 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1327 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1328 << UmbrellaModule->getFullModuleName(); 1329 HadError = true; 1330 } else { 1331 // Record this umbrella header. 1332 Map.setUmbrellaHeader(ActiveModule, File); 1333 } 1334 } else { 1335 // Record this header. 1336 Map.addHeader(ActiveModule, File, Exclude); 1337 1338 // If there is a builtin counterpart to this file, add it now. 1339 if (BuiltinFile) 1340 Map.addHeader(ActiveModule, BuiltinFile, Exclude); 1341 } 1342 } else if (!Exclude) { 1343 // Ignore excluded header files. They're optional anyway. 1344 1345 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1346 << Umbrella << FileName; 1347 HadError = true; 1348 } 1349 } 1350 1351 /// \brief Parse an umbrella directory declaration. 1352 /// 1353 /// umbrella-dir-declaration: 1354 /// umbrella string-literal 1355 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1356 // Parse the directory name. 1357 if (!Tok.is(MMToken::StringLiteral)) { 1358 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1359 << "umbrella"; 1360 HadError = true; 1361 return; 1362 } 1363 1364 std::string DirName = Tok.getString(); 1365 SourceLocation DirNameLoc = consumeToken(); 1366 1367 // Check whether we already have an umbrella. 1368 if (ActiveModule->Umbrella) { 1369 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1370 << ActiveModule->getFullModuleName(); 1371 HadError = true; 1372 return; 1373 } 1374 1375 // Look for this file. 1376 const DirectoryEntry *Dir = 0; 1377 if (llvm::sys::path::is_absolute(DirName)) 1378 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1379 else { 1380 SmallString<128> PathName; 1381 PathName = Directory->getName(); 1382 llvm::sys::path::append(PathName, DirName); 1383 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1384 } 1385 1386 if (!Dir) { 1387 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1388 << DirName; 1389 HadError = true; 1390 return; 1391 } 1392 1393 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1394 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1395 << OwningModule->getFullModuleName(); 1396 HadError = true; 1397 return; 1398 } 1399 1400 // Record this umbrella directory. 1401 Map.setUmbrellaDir(ActiveModule, Dir); 1402 } 1403 1404 /// \brief Parse a module export declaration. 1405 /// 1406 /// export-declaration: 1407 /// 'export' wildcard-module-id 1408 /// 1409 /// wildcard-module-id: 1410 /// identifier 1411 /// '*' 1412 /// identifier '.' wildcard-module-id 1413 void ModuleMapParser::parseExportDecl() { 1414 assert(Tok.is(MMToken::ExportKeyword)); 1415 SourceLocation ExportLoc = consumeToken(); 1416 1417 // Parse the module-id with an optional wildcard at the end. 1418 ModuleId ParsedModuleId; 1419 bool Wildcard = false; 1420 do { 1421 if (Tok.is(MMToken::Identifier)) { 1422 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1423 Tok.getLocation())); 1424 consumeToken(); 1425 1426 if (Tok.is(MMToken::Period)) { 1427 consumeToken(); 1428 continue; 1429 } 1430 1431 break; 1432 } 1433 1434 if(Tok.is(MMToken::Star)) { 1435 Wildcard = true; 1436 consumeToken(); 1437 break; 1438 } 1439 1440 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 1441 HadError = true; 1442 return; 1443 } while (true); 1444 1445 Module::UnresolvedExportDecl Unresolved = { 1446 ExportLoc, ParsedModuleId, Wildcard 1447 }; 1448 ActiveModule->UnresolvedExports.push_back(Unresolved); 1449 } 1450 1451 /// \brief Parse a link declaration. 1452 /// 1453 /// module-declaration: 1454 /// 'link' 'framework'[opt] string-literal 1455 void ModuleMapParser::parseLinkDecl() { 1456 assert(Tok.is(MMToken::LinkKeyword)); 1457 SourceLocation LinkLoc = consumeToken(); 1458 1459 // Parse the optional 'framework' keyword. 1460 bool IsFramework = false; 1461 if (Tok.is(MMToken::FrameworkKeyword)) { 1462 consumeToken(); 1463 IsFramework = true; 1464 } 1465 1466 // Parse the library name 1467 if (!Tok.is(MMToken::StringLiteral)) { 1468 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1469 << IsFramework << SourceRange(LinkLoc); 1470 HadError = true; 1471 return; 1472 } 1473 1474 std::string LibraryName = Tok.getString(); 1475 consumeToken(); 1476 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1477 IsFramework)); 1478 } 1479 1480 /// \brief Parse an inferred module declaration (wildcard modules). 1481 /// 1482 /// module-declaration: 1483 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 1484 /// { inferred-module-member* } 1485 /// 1486 /// inferred-module-member: 1487 /// 'export' '*' 1488 /// 'exclude' identifier 1489 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 1490 assert(Tok.is(MMToken::Star)); 1491 SourceLocation StarLoc = consumeToken(); 1492 bool Failed = false; 1493 1494 // Inferred modules must be submodules. 1495 if (!ActiveModule && !Framework) { 1496 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1497 Failed = true; 1498 } 1499 1500 if (ActiveModule) { 1501 // Inferred modules must have umbrella directories. 1502 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1503 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1504 Failed = true; 1505 } 1506 1507 // Check for redefinition of an inferred module. 1508 if (!Failed && ActiveModule->InferSubmodules) { 1509 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1510 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1511 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1512 diag::note_mmap_prev_definition); 1513 Failed = true; 1514 } 1515 1516 // Check for the 'framework' keyword, which is not permitted here. 1517 if (Framework) { 1518 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 1519 Framework = false; 1520 } 1521 } else if (Explicit) { 1522 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 1523 Explicit = false; 1524 } 1525 1526 // If there were any problems with this inferred submodule, skip its body. 1527 if (Failed) { 1528 if (Tok.is(MMToken::LBrace)) { 1529 consumeToken(); 1530 skipUntil(MMToken::RBrace); 1531 if (Tok.is(MMToken::RBrace)) 1532 consumeToken(); 1533 } 1534 HadError = true; 1535 return; 1536 } 1537 1538 // Parse optional attributes. 1539 Attributes Attrs; 1540 parseOptionalAttributes(Attrs); 1541 1542 if (ActiveModule) { 1543 // Note that we have an inferred submodule. 1544 ActiveModule->InferSubmodules = true; 1545 ActiveModule->InferredSubmoduleLoc = StarLoc; 1546 ActiveModule->InferExplicitSubmodules = Explicit; 1547 } else { 1548 // We'll be inferring framework modules for this directory. 1549 Map.InferredDirectories[Directory].InferModules = true; 1550 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 1551 } 1552 1553 // Parse the opening brace. 1554 if (!Tok.is(MMToken::LBrace)) { 1555 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1556 HadError = true; 1557 return; 1558 } 1559 SourceLocation LBraceLoc = consumeToken(); 1560 1561 // Parse the body of the inferred submodule. 1562 bool Done = false; 1563 do { 1564 switch (Tok.Kind) { 1565 case MMToken::EndOfFile: 1566 case MMToken::RBrace: 1567 Done = true; 1568 break; 1569 1570 case MMToken::ExcludeKeyword: { 1571 if (ActiveModule) { 1572 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1573 << (ActiveModule != 0); 1574 consumeToken(); 1575 break; 1576 } 1577 1578 consumeToken(); 1579 if (!Tok.is(MMToken::Identifier)) { 1580 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 1581 break; 1582 } 1583 1584 Map.InferredDirectories[Directory].ExcludedModules 1585 .push_back(Tok.getString()); 1586 consumeToken(); 1587 break; 1588 } 1589 1590 case MMToken::ExportKeyword: 1591 if (!ActiveModule) { 1592 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1593 << (ActiveModule != 0); 1594 consumeToken(); 1595 break; 1596 } 1597 1598 consumeToken(); 1599 if (Tok.is(MMToken::Star)) 1600 ActiveModule->InferExportWildcard = true; 1601 else 1602 Diags.Report(Tok.getLocation(), 1603 diag::err_mmap_expected_export_wildcard); 1604 consumeToken(); 1605 break; 1606 1607 case MMToken::ExplicitKeyword: 1608 case MMToken::ModuleKeyword: 1609 case MMToken::HeaderKeyword: 1610 case MMToken::UmbrellaKeyword: 1611 default: 1612 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1613 << (ActiveModule != 0); 1614 consumeToken(); 1615 break; 1616 } 1617 } while (!Done); 1618 1619 if (Tok.is(MMToken::RBrace)) 1620 consumeToken(); 1621 else { 1622 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1623 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1624 HadError = true; 1625 } 1626 } 1627 1628 /// \brief Parse optional attributes. 1629 /// 1630 /// attributes: 1631 /// attribute attributes 1632 /// attribute 1633 /// 1634 /// attribute: 1635 /// [ identifier ] 1636 /// 1637 /// \param Attrs Will be filled in with the parsed attributes. 1638 /// 1639 /// \returns true if an error occurred, false otherwise. 1640 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 1641 bool HadError = false; 1642 1643 while (Tok.is(MMToken::LSquare)) { 1644 // Consume the '['. 1645 SourceLocation LSquareLoc = consumeToken(); 1646 1647 // Check whether we have an attribute name here. 1648 if (!Tok.is(MMToken::Identifier)) { 1649 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 1650 skipUntil(MMToken::RSquare); 1651 if (Tok.is(MMToken::RSquare)) 1652 consumeToken(); 1653 HadError = true; 1654 } 1655 1656 // Decode the attribute name. 1657 AttributeKind Attribute 1658 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 1659 .Case("system", AT_system) 1660 .Default(AT_unknown); 1661 switch (Attribute) { 1662 case AT_unknown: 1663 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 1664 << Tok.getString(); 1665 break; 1666 1667 case AT_system: 1668 Attrs.IsSystem = true; 1669 break; 1670 } 1671 consumeToken(); 1672 1673 // Consume the ']'. 1674 if (!Tok.is(MMToken::RSquare)) { 1675 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 1676 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 1677 skipUntil(MMToken::RSquare); 1678 HadError = true; 1679 } 1680 1681 if (Tok.is(MMToken::RSquare)) 1682 consumeToken(); 1683 } 1684 1685 return HadError; 1686 } 1687 1688 /// \brief If there is a specific header search directory due the presence 1689 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 1690 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 1691 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 1692 // If we have an umbrella directory, use that. 1693 if (Mod->hasUmbrellaDir()) 1694 return Mod->getUmbrellaDir(); 1695 1696 // If we have a framework directory, stop looking. 1697 if (Mod->IsFramework) 1698 return 0; 1699 } 1700 1701 return 0; 1702 } 1703 1704 /// \brief Parse a module map file. 1705 /// 1706 /// module-map-file: 1707 /// module-declaration* 1708 bool ModuleMapParser::parseModuleMapFile() { 1709 do { 1710 switch (Tok.Kind) { 1711 case MMToken::EndOfFile: 1712 return HadError; 1713 1714 case MMToken::ExplicitKeyword: 1715 case MMToken::ModuleKeyword: 1716 case MMToken::FrameworkKeyword: 1717 parseModuleDecl(); 1718 break; 1719 1720 case MMToken::Comma: 1721 case MMToken::ExcludeKeyword: 1722 case MMToken::ExportKeyword: 1723 case MMToken::HeaderKeyword: 1724 case MMToken::Identifier: 1725 case MMToken::LBrace: 1726 case MMToken::LinkKeyword: 1727 case MMToken::LSquare: 1728 case MMToken::Period: 1729 case MMToken::RBrace: 1730 case MMToken::RSquare: 1731 case MMToken::RequiresKeyword: 1732 case MMToken::Star: 1733 case MMToken::StringLiteral: 1734 case MMToken::UmbrellaKeyword: 1735 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1736 HadError = true; 1737 consumeToken(); 1738 break; 1739 } 1740 } while (true); 1741 } 1742 1743 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1744 llvm::DenseMap<const FileEntry *, bool>::iterator Known 1745 = ParsedModuleMap.find(File); 1746 if (Known != ParsedModuleMap.end()) 1747 return Known->second; 1748 1749 assert(Target != 0 && "Missing target information"); 1750 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1751 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1752 if (!Buffer) 1753 return ParsedModuleMap[File] = true; 1754 1755 // Parse this module map file. 1756 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 1757 Diags->getClient()->BeginSourceFile(MMapLangOpts); 1758 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(), 1759 BuiltinIncludeDir); 1760 bool Result = Parser.parseModuleMapFile(); 1761 Diags->getClient()->EndSourceFile(); 1762 ParsedModuleMap[File] = Result; 1763 return Result; 1764 } 1765