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/HeaderSearch.h" 22 #include "clang/Lex/LexDiagnostic.h" 23 #include "clang/Lex/Lexer.h" 24 #include "clang/Lex/LiteralSupport.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/StringSwitch.h" 27 #include "llvm/Support/Allocator.h" 28 #include "llvm/Support/FileSystem.h" 29 #include "llvm/Support/Host.h" 30 #include "llvm/Support/Path.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include <stdlib.h> 33 #if defined(LLVM_ON_UNIX) 34 #include <limits.h> 35 #endif 36 using namespace clang; 37 38 Module::ExportDecl 39 ModuleMap::resolveExport(Module *Mod, 40 const Module::UnresolvedExportDecl &Unresolved, 41 bool Complain) const { 42 // We may have just a wildcard. 43 if (Unresolved.Id.empty()) { 44 assert(Unresolved.Wildcard && "Invalid unresolved export"); 45 return Module::ExportDecl(0, true); 46 } 47 48 // Resolve the module-id. 49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 50 if (!Context) 51 return Module::ExportDecl(); 52 53 return Module::ExportDecl(Context, Unresolved.Wildcard); 54 } 55 56 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 57 bool Complain) const { 58 // Find the starting module. 59 Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 60 if (!Context) { 61 if (Complain) 62 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 63 << Id[0].first << Mod->getFullModuleName(); 64 65 return 0; 66 } 67 68 // Dig into the module path. 69 for (unsigned I = 1, N = Id.size(); I != N; ++I) { 70 Module *Sub = lookupModuleQualified(Id[I].first, Context); 71 if (!Sub) { 72 if (Complain) 73 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 74 << Id[I].first << Context->getFullModuleName() 75 << SourceRange(Id[0].second, Id[I-1].second); 76 77 return 0; 78 } 79 80 Context = Sub; 81 } 82 83 return Context; 84 } 85 86 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 87 const LangOptions &LangOpts, const TargetInfo *Target, 88 HeaderSearch &HeaderInfo) 89 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 90 HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0), 91 SourceModule(0) {} 92 93 ModuleMap::~ModuleMap() { 94 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 95 IEnd = Modules.end(); 96 I != IEnd; ++I) { 97 delete I->getValue(); 98 } 99 } 100 101 void ModuleMap::setTarget(const TargetInfo &Target) { 102 assert((!this->Target || this->Target == &Target) && 103 "Improper target override"); 104 this->Target = &Target; 105 } 106 107 /// \brief "Sanitize" a filename so that it can be used as an identifier. 108 static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 109 SmallVectorImpl<char> &Buffer) { 110 if (Name.empty()) 111 return Name; 112 113 if (!isValidIdentifier(Name)) { 114 // If we don't already have something with the form of an identifier, 115 // create a buffer with the sanitized name. 116 Buffer.clear(); 117 if (isDigit(Name[0])) 118 Buffer.push_back('_'); 119 Buffer.reserve(Buffer.size() + Name.size()); 120 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 121 if (isIdentifierBody(Name[I])) 122 Buffer.push_back(Name[I]); 123 else 124 Buffer.push_back('_'); 125 } 126 127 Name = StringRef(Buffer.data(), Buffer.size()); 128 } 129 130 while (llvm::StringSwitch<bool>(Name) 131 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 132 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 133 #include "clang/Basic/TokenKinds.def" 134 .Default(false)) { 135 if (Name.data() != Buffer.data()) 136 Buffer.append(Name.begin(), Name.end()); 137 Buffer.push_back('_'); 138 Name = StringRef(Buffer.data(), Buffer.size()); 139 } 140 141 return Name; 142 } 143 144 /// \brief Determine whether the given file name is the name of a builtin 145 /// header, supplied by Clang to replace, override, or augment existing system 146 /// headers. 147 static bool isBuiltinHeader(StringRef FileName) { 148 return llvm::StringSwitch<bool>(FileName) 149 .Case("float.h", true) 150 .Case("iso646.h", true) 151 .Case("limits.h", true) 152 .Case("stdalign.h", true) 153 .Case("stdarg.h", true) 154 .Case("stdbool.h", true) 155 .Case("stddef.h", true) 156 .Case("stdint.h", true) 157 .Case("tgmath.h", true) 158 .Case("unwind.h", true) 159 .Default(false); 160 } 161 162 ModuleMap::HeadersMap::iterator 163 ModuleMap::findKnownHeader(const FileEntry *File) { 164 HeadersMap::iterator Known = Headers.find(File); 165 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir && 166 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 167 HeaderInfo.loadTopLevelSystemModules(); 168 return Headers.find(File); 169 } 170 return Known; 171 } 172 173 // Returns 'true' if 'RequestingModule directly uses 'RequestedModule'. 174 static bool directlyUses(const Module *RequestingModule, 175 const Module *RequestedModule) { 176 return std::find(RequestingModule->DirectUses.begin(), 177 RequestingModule->DirectUses.end(), 178 RequestedModule) != RequestingModule->DirectUses.end(); 179 } 180 181 static bool violatesPrivateInclude(Module *RequestingModule, 182 const FileEntry *IncFileEnt, 183 ModuleMap::ModuleHeaderRole Role, 184 Module *RequestedModule) { 185 #ifndef NDEBUG 186 // Check for consistency between the module header role 187 // as obtained from the lookup and as obtained from the module. 188 // This check is not cheap, so enable it only for debugging. 189 SmallVectorImpl<const FileEntry *> &PvtHdrs 190 = RequestedModule->PrivateHeaders; 191 SmallVectorImpl<const FileEntry *>::iterator Look 192 = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt); 193 bool IsPrivate = Look != PvtHdrs.end(); 194 assert((IsPrivate && Role == ModuleMap::PrivateHeader) 195 || (!IsPrivate && Role != ModuleMap::PrivateHeader)); 196 #endif 197 return Role == ModuleMap::PrivateHeader && 198 RequestedModule->getTopLevelModule() != RequestingModule; 199 } 200 201 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 202 SourceLocation FilenameLoc, 203 StringRef Filename, 204 const FileEntry *File) { 205 // No errors for indirect modules. This may be a bit of a problem for modules 206 // with no source files. 207 if (RequestingModule != SourceModule) 208 return; 209 210 if (RequestingModule) 211 resolveUses(RequestingModule, /*Complain=*/false); 212 213 HeadersMap::iterator Known = findKnownHeader(File); 214 if (Known == Headers.end()) 215 return; 216 217 Module *Private = NULL; 218 Module *NotUsed = NULL; 219 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 220 E = Known->second.end(); 221 I != E; ++I) { 222 // Excluded headers don't really belong to a module. 223 if (I->getRole() == ModuleMap::ExcludedHeader) 224 continue; 225 226 // If 'File' is part of 'RequestingModule' we can definitely include it. 227 if (I->getModule() == RequestingModule) 228 return; 229 230 // Remember private headers for later printing of a diagnostic. 231 if (violatesPrivateInclude(RequestingModule, File, I->getRole(), 232 I->getModule())) { 233 Private = I->getModule(); 234 continue; 235 } 236 237 // If uses need to be specified explicitly, we are only allowed to return 238 // modules that are explicitly used by the requesting module. 239 if (RequestingModule && LangOpts.ModulesDeclUse && 240 !directlyUses(RequestingModule, I->getModule())) { 241 NotUsed = I->getModule(); 242 continue; 243 } 244 245 // We have found a module that we can happily use. 246 return; 247 } 248 249 // We have found a header, but it is private. 250 if (Private != NULL) { 251 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module) 252 << Filename; 253 return; 254 } 255 256 // We have found a module, but we don't use it. 257 if (NotUsed != NULL) { 258 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) 259 << RequestingModule->getFullModuleName() << Filename; 260 return; 261 } 262 263 // Headers for which we have not found a module are fine to include. 264 } 265 266 ModuleMap::KnownHeader 267 ModuleMap::findModuleForHeader(const FileEntry *File, 268 Module *RequestingModule) { 269 HeadersMap::iterator Known = findKnownHeader(File); 270 271 if (Known != Headers.end()) { 272 ModuleMap::KnownHeader Result = KnownHeader(); 273 274 // Iterate over all modules that 'File' is part of to find the best fit. 275 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 276 E = Known->second.end(); 277 I != E; ++I) { 278 // Cannot use a module if the header is excluded in it. 279 if (I->getRole() == ModuleMap::ExcludedHeader) 280 continue; 281 282 // Cannot use a module if it is unavailable. 283 if (!I->getModule()->isAvailable()) 284 continue; 285 286 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the 287 // module we are looking for. 288 if (I->getModule() == RequestingModule) 289 return *I; 290 291 // If uses need to be specified explicitly, we are only allowed to return 292 // modules that are explicitly used by the requesting module. 293 if (RequestingModule && LangOpts.ModulesDeclUse && 294 !directlyUses(RequestingModule, I->getModule())) 295 continue; 296 297 Result = *I; 298 // If 'File' is a public header of this module, this is as good as we 299 // are going to get. 300 // FIXME: If we have a RequestingModule, we should prefer the header from 301 // that module. 302 if (I->getRole() == ModuleMap::NormalHeader) 303 break; 304 } 305 return Result; 306 } 307 308 const DirectoryEntry *Dir = File->getDir(); 309 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 310 311 // Note: as an egregious but useful hack we use the real path here, because 312 // frameworks moving from top-level frameworks to embedded frameworks tend 313 // to be symlinked from the top-level location to the embedded location, 314 // and we need to resolve lookups as if we had found the embedded location. 315 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 316 317 // Keep walking up the directory hierarchy, looking for a directory with 318 // an umbrella header. 319 do { 320 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 321 = UmbrellaDirs.find(Dir); 322 if (KnownDir != UmbrellaDirs.end()) { 323 Module *Result = KnownDir->second; 324 325 // Search up the module stack until we find a module with an umbrella 326 // directory. 327 Module *UmbrellaModule = Result; 328 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 329 UmbrellaModule = UmbrellaModule->Parent; 330 331 if (UmbrellaModule->InferSubmodules) { 332 // Infer submodules for each of the directories we found between 333 // the directory of the umbrella header and the directory where 334 // the actual header is located. 335 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 336 337 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 338 // Find or create the module that corresponds to this directory name. 339 SmallString<32> NameBuf; 340 StringRef Name = sanitizeFilenameAsIdentifier( 341 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 342 NameBuf); 343 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 344 Explicit).first; 345 346 // Associate the module and the directory. 347 UmbrellaDirs[SkippedDirs[I-1]] = Result; 348 349 // If inferred submodules export everything they import, add a 350 // wildcard to the set of exports. 351 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 352 Result->Exports.push_back(Module::ExportDecl(0, true)); 353 } 354 355 // Infer a submodule with the same name as this header file. 356 SmallString<32> NameBuf; 357 StringRef Name = sanitizeFilenameAsIdentifier( 358 llvm::sys::path::stem(File->getName()), NameBuf); 359 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 360 Explicit).first; 361 Result->addTopHeader(File); 362 363 // If inferred submodules export everything they import, add a 364 // wildcard to the set of exports. 365 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 366 Result->Exports.push_back(Module::ExportDecl(0, true)); 367 } else { 368 // Record each of the directories we stepped through as being part of 369 // the module we found, since the umbrella header covers them all. 370 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 371 UmbrellaDirs[SkippedDirs[I]] = Result; 372 } 373 374 Headers[File].push_back(KnownHeader(Result, NormalHeader)); 375 376 // If a header corresponds to an unavailable module, don't report 377 // that it maps to anything. 378 if (!Result->isAvailable()) 379 return KnownHeader(); 380 381 return Headers[File].back(); 382 } 383 384 SkippedDirs.push_back(Dir); 385 386 // Retrieve our parent path. 387 DirName = llvm::sys::path::parent_path(DirName); 388 if (DirName.empty()) 389 break; 390 391 // Resolve the parent path to a directory entry. 392 Dir = SourceMgr.getFileManager().getDirectory(DirName); 393 } while (Dir); 394 395 return KnownHeader(); 396 } 397 398 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 399 HeadersMap::const_iterator Known = Headers.find(Header); 400 if (Known != Headers.end()) { 401 for (SmallVectorImpl<KnownHeader>::const_iterator 402 I = Known->second.begin(), 403 E = Known->second.end(); 404 I != E; ++I) { 405 if (I->isAvailable()) 406 return false; 407 } 408 return true; 409 } 410 411 const DirectoryEntry *Dir = Header->getDir(); 412 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 413 StringRef DirName = Dir->getName(); 414 415 // Keep walking up the directory hierarchy, looking for a directory with 416 // an umbrella header. 417 do { 418 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 419 = UmbrellaDirs.find(Dir); 420 if (KnownDir != UmbrellaDirs.end()) { 421 Module *Found = KnownDir->second; 422 if (!Found->isAvailable()) 423 return true; 424 425 // Search up the module stack until we find a module with an umbrella 426 // directory. 427 Module *UmbrellaModule = Found; 428 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 429 UmbrellaModule = UmbrellaModule->Parent; 430 431 if (UmbrellaModule->InferSubmodules) { 432 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 433 // Find or create the module that corresponds to this directory name. 434 SmallString<32> NameBuf; 435 StringRef Name = sanitizeFilenameAsIdentifier( 436 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 437 NameBuf); 438 Found = lookupModuleQualified(Name, Found); 439 if (!Found) 440 return false; 441 if (!Found->isAvailable()) 442 return true; 443 } 444 445 // Infer a submodule with the same name as this header file. 446 SmallString<32> NameBuf; 447 StringRef Name = sanitizeFilenameAsIdentifier( 448 llvm::sys::path::stem(Header->getName()), 449 NameBuf); 450 Found = lookupModuleQualified(Name, Found); 451 if (!Found) 452 return false; 453 } 454 455 return !Found->isAvailable(); 456 } 457 458 SkippedDirs.push_back(Dir); 459 460 // Retrieve our parent path. 461 DirName = llvm::sys::path::parent_path(DirName); 462 if (DirName.empty()) 463 break; 464 465 // Resolve the parent path to a directory entry. 466 Dir = SourceMgr.getFileManager().getDirectory(DirName); 467 } while (Dir); 468 469 return false; 470 } 471 472 Module *ModuleMap::findModule(StringRef Name) const { 473 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 474 if (Known != Modules.end()) 475 return Known->getValue(); 476 477 return 0; 478 } 479 480 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, 481 Module *Context) const { 482 for(; Context; Context = Context->Parent) { 483 if (Module *Sub = lookupModuleQualified(Name, Context)) 484 return Sub; 485 } 486 487 return findModule(Name); 488 } 489 490 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 491 if (!Context) 492 return findModule(Name); 493 494 return Context->findSubmodule(Name); 495 } 496 497 std::pair<Module *, bool> 498 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 499 bool IsExplicit) { 500 // Try to find an existing module with this name. 501 if (Module *Sub = lookupModuleQualified(Name, Parent)) 502 return std::make_pair(Sub, false); 503 504 // Create a new module with this name. 505 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 506 IsExplicit); 507 if (LangOpts.CurrentModule == Name) { 508 SourceModule = Result; 509 SourceModuleName = Name; 510 } 511 if (!Parent) { 512 Modules[Name] = Result; 513 if (!LangOpts.CurrentModule.empty() && !CompilingModule && 514 Name == LangOpts.CurrentModule) { 515 CompilingModule = Result; 516 } 517 } 518 return std::make_pair(Result, true); 519 } 520 521 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 522 StringRef Name, bool &IsSystem) const { 523 // Check whether we have already looked into the parent directory 524 // for a module map. 525 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 526 inferred = InferredDirectories.find(ParentDir); 527 if (inferred == InferredDirectories.end()) 528 return false; 529 530 if (!inferred->second.InferModules) 531 return false; 532 533 // We're allowed to infer for this directory, but make sure it's okay 534 // to infer this particular module. 535 bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 536 inferred->second.ExcludedModules.end(), 537 Name) == inferred->second.ExcludedModules.end(); 538 539 if (canInfer && inferred->second.InferSystemModules) 540 IsSystem = true; 541 542 return canInfer; 543 } 544 545 /// \brief For a framework module, infer the framework against which we 546 /// should link. 547 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 548 FileManager &FileMgr) { 549 assert(Mod->IsFramework && "Can only infer linking for framework modules"); 550 assert(!Mod->isSubFramework() && 551 "Can only infer linking for top-level frameworks"); 552 553 SmallString<128> LibName; 554 LibName += FrameworkDir->getName(); 555 llvm::sys::path::append(LibName, Mod->Name); 556 if (FileMgr.getFile(LibName)) { 557 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 558 /*IsFramework=*/true)); 559 } 560 } 561 562 Module * 563 ModuleMap::inferFrameworkModule(StringRef ModuleName, 564 const DirectoryEntry *FrameworkDir, 565 bool IsSystem, 566 Module *Parent) { 567 // Check whether we've already found this module. 568 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 569 return Mod; 570 571 FileManager &FileMgr = SourceMgr.getFileManager(); 572 573 // If the framework has a parent path from which we're allowed to infer 574 // a framework module, do so. 575 if (!Parent) { 576 // Determine whether we're allowed to infer a module map. 577 578 // Note: as an egregious but useful hack we use the real path here, because 579 // we might be looking at an embedded framework that symlinks out to a 580 // top-level framework, and we need to infer as if we were naming the 581 // top-level framework. 582 StringRef FrameworkDirName 583 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 584 585 bool canInfer = false; 586 if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 587 // Figure out the parent path. 588 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 589 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 590 // Check whether we have already looked into the parent directory 591 // for a module map. 592 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 593 inferred = InferredDirectories.find(ParentDir); 594 if (inferred == InferredDirectories.end()) { 595 // We haven't looked here before. Load a module map, if there is 596 // one. 597 bool IsFrameworkDir = Parent.endswith(".framework"); 598 if (const FileEntry *ModMapFile = 599 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { 600 parseModuleMapFile(ModMapFile, IsSystem); 601 inferred = InferredDirectories.find(ParentDir); 602 } 603 604 if (inferred == InferredDirectories.end()) 605 inferred = InferredDirectories.insert( 606 std::make_pair(ParentDir, InferredDirectory())).first; 607 } 608 609 if (inferred->second.InferModules) { 610 // We're allowed to infer for this directory, but make sure it's okay 611 // to infer this particular module. 612 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 613 canInfer = std::find(inferred->second.ExcludedModules.begin(), 614 inferred->second.ExcludedModules.end(), 615 Name) == inferred->second.ExcludedModules.end(); 616 617 if (inferred->second.InferSystemModules) 618 IsSystem = true; 619 } 620 } 621 } 622 623 // If we're not allowed to infer a framework module, don't. 624 if (!canInfer) 625 return 0; 626 } 627 628 629 // Look for an umbrella header. 630 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 631 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 632 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 633 634 // FIXME: If there's no umbrella header, we could probably scan the 635 // framework to load *everything*. But, it's not clear that this is a good 636 // idea. 637 if (!UmbrellaHeader) 638 return 0; 639 640 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 641 /*IsFramework=*/true, /*IsExplicit=*/false); 642 if (LangOpts.CurrentModule == ModuleName) { 643 SourceModule = Result; 644 SourceModuleName = ModuleName; 645 } 646 if (IsSystem) 647 Result->IsSystem = IsSystem; 648 649 if (!Parent) 650 Modules[ModuleName] = Result; 651 652 // umbrella header "umbrella-header-name" 653 Result->Umbrella = UmbrellaHeader; 654 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); 655 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 656 657 // export * 658 Result->Exports.push_back(Module::ExportDecl(0, true)); 659 660 // module * { export * } 661 Result->InferSubmodules = true; 662 Result->InferExportWildcard = true; 663 664 // Look for subframeworks. 665 llvm::error_code EC; 666 SmallString<128> SubframeworksDirName 667 = StringRef(FrameworkDir->getName()); 668 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 669 llvm::sys::path::native(SubframeworksDirName); 670 for (llvm::sys::fs::directory_iterator 671 Dir(SubframeworksDirName.str(), EC), DirEnd; 672 Dir != DirEnd && !EC; Dir.increment(EC)) { 673 if (!StringRef(Dir->path()).endswith(".framework")) 674 continue; 675 676 if (const DirectoryEntry *SubframeworkDir 677 = FileMgr.getDirectory(Dir->path())) { 678 // Note: as an egregious but useful hack, we use the real path here and 679 // check whether it is actually a subdirectory of the parent directory. 680 // This will not be the case if the 'subframework' is actually a symlink 681 // out to a top-level framework. 682 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 683 bool FoundParent = false; 684 do { 685 // Get the parent directory name. 686 SubframeworkDirName 687 = llvm::sys::path::parent_path(SubframeworkDirName); 688 if (SubframeworkDirName.empty()) 689 break; 690 691 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 692 FoundParent = true; 693 break; 694 } 695 } while (true); 696 697 if (!FoundParent) 698 continue; 699 700 // FIXME: Do we want to warn about subframeworks without umbrella headers? 701 SmallString<32> NameBuf; 702 inferFrameworkModule(sanitizeFilenameAsIdentifier( 703 llvm::sys::path::stem(Dir->path()), NameBuf), 704 SubframeworkDir, IsSystem, Result); 705 } 706 } 707 708 // If the module is a top-level framework, automatically link against the 709 // framework. 710 if (!Result->isSubFramework()) { 711 inferFrameworkLink(Result, FrameworkDir, FileMgr); 712 } 713 714 return Result; 715 } 716 717 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 718 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 719 Mod->Umbrella = UmbrellaHeader; 720 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 721 } 722 723 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 724 Mod->Umbrella = UmbrellaDir; 725 UmbrellaDirs[UmbrellaDir] = Mod; 726 } 727 728 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 729 ModuleHeaderRole Role) { 730 if (Role == ExcludedHeader) { 731 Mod->ExcludedHeaders.push_back(Header); 732 } else { 733 if (Role == PrivateHeader) 734 Mod->PrivateHeaders.push_back(Header); 735 else 736 Mod->NormalHeaders.push_back(Header); 737 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 738 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); 739 } 740 Headers[Header].push_back(KnownHeader(Mod, Role)); 741 } 742 743 const FileEntry * 744 ModuleMap::getContainingModuleMapFile(Module *Module) const { 745 if (Module->DefinitionLoc.isInvalid()) 746 return 0; 747 748 return SourceMgr.getFileEntryForID( 749 SourceMgr.getFileID(Module->DefinitionLoc)); 750 } 751 752 void ModuleMap::dump() { 753 llvm::errs() << "Modules:"; 754 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 755 MEnd = Modules.end(); 756 M != MEnd; ++M) 757 M->getValue()->print(llvm::errs(), 2); 758 759 llvm::errs() << "Headers:"; 760 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 761 H != HEnd; ++H) { 762 llvm::errs() << " \"" << H->first->getName() << "\" -> "; 763 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 764 E = H->second.end(); 765 I != E; ++I) { 766 if (I != H->second.begin()) 767 llvm::errs() << ","; 768 llvm::errs() << I->getModule()->getFullModuleName(); 769 } 770 llvm::errs() << "\n"; 771 } 772 } 773 774 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 775 bool HadError = false; 776 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 777 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 778 Complain); 779 if (Export.getPointer() || Export.getInt()) 780 Mod->Exports.push_back(Export); 781 else 782 HadError = true; 783 } 784 Mod->UnresolvedExports.clear(); 785 return HadError; 786 } 787 788 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 789 bool HadError = false; 790 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 791 Module *DirectUse = 792 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 793 if (DirectUse) 794 Mod->DirectUses.push_back(DirectUse); 795 else 796 HadError = true; 797 } 798 Mod->UnresolvedDirectUses.clear(); 799 return HadError; 800 } 801 802 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 803 bool HadError = false; 804 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 805 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 806 Mod, Complain); 807 if (!OtherMod) { 808 HadError = true; 809 continue; 810 } 811 812 Module::Conflict Conflict; 813 Conflict.Other = OtherMod; 814 Conflict.Message = Mod->UnresolvedConflicts[I].Message; 815 Mod->Conflicts.push_back(Conflict); 816 } 817 Mod->UnresolvedConflicts.clear(); 818 return HadError; 819 } 820 821 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 822 if (Loc.isInvalid()) 823 return 0; 824 825 // Use the expansion location to determine which module we're in. 826 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 827 if (!ExpansionLoc.isFileID()) 828 return 0; 829 830 831 const SourceManager &SrcMgr = Loc.getManager(); 832 FileID ExpansionFileID = ExpansionLoc.getFileID(); 833 834 while (const FileEntry *ExpansionFile 835 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 836 // Find the module that owns this header (if any). 837 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 838 return Mod; 839 840 // No module owns this header, so look up the inclusion chain to see if 841 // any included header has an associated module. 842 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 843 if (IncludeLoc.isInvalid()) 844 return 0; 845 846 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 847 } 848 849 return 0; 850 } 851 852 //----------------------------------------------------------------------------// 853 // Module map file parser 854 //----------------------------------------------------------------------------// 855 856 namespace clang { 857 /// \brief A token in a module map file. 858 struct MMToken { 859 enum TokenKind { 860 Comma, 861 ConfigMacros, 862 Conflict, 863 EndOfFile, 864 HeaderKeyword, 865 Identifier, 866 Exclaim, 867 ExcludeKeyword, 868 ExplicitKeyword, 869 ExportKeyword, 870 ExternKeyword, 871 FrameworkKeyword, 872 LinkKeyword, 873 ModuleKeyword, 874 Period, 875 PrivateKeyword, 876 UmbrellaKeyword, 877 UseKeyword, 878 RequiresKeyword, 879 Star, 880 StringLiteral, 881 LBrace, 882 RBrace, 883 LSquare, 884 RSquare 885 } Kind; 886 887 unsigned Location; 888 unsigned StringLength; 889 const char *StringData; 890 891 void clear() { 892 Kind = EndOfFile; 893 Location = 0; 894 StringLength = 0; 895 StringData = 0; 896 } 897 898 bool is(TokenKind K) const { return Kind == K; } 899 900 SourceLocation getLocation() const { 901 return SourceLocation::getFromRawEncoding(Location); 902 } 903 904 StringRef getString() const { 905 return StringRef(StringData, StringLength); 906 } 907 }; 908 909 /// \brief The set of attributes that can be attached to a module. 910 struct Attributes { 911 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { } 912 913 /// \brief Whether this is a system module. 914 unsigned IsSystem : 1; 915 916 /// \brief Whether this is an extern "C" module. 917 unsigned IsExternC : 1; 918 919 /// \brief Whether this is an exhaustive set of configuration macros. 920 unsigned IsExhaustive : 1; 921 }; 922 923 924 class ModuleMapParser { 925 Lexer &L; 926 SourceManager &SourceMgr; 927 928 /// \brief Default target information, used only for string literal 929 /// parsing. 930 const TargetInfo *Target; 931 932 DiagnosticsEngine &Diags; 933 ModuleMap ⤅ 934 935 /// \brief The directory that this module map resides in. 936 const DirectoryEntry *Directory; 937 938 /// \brief The directory containing Clang-supplied headers. 939 const DirectoryEntry *BuiltinIncludeDir; 940 941 /// \brief Whether this module map is in a system header directory. 942 bool IsSystem; 943 944 /// \brief Whether an error occurred. 945 bool HadError; 946 947 /// \brief Stores string data for the various string literals referenced 948 /// during parsing. 949 llvm::BumpPtrAllocator StringData; 950 951 /// \brief The current token. 952 MMToken Tok; 953 954 /// \brief The active module. 955 Module *ActiveModule; 956 957 /// \brief Consume the current token and return its location. 958 SourceLocation consumeToken(); 959 960 /// \brief Skip tokens until we reach the a token with the given kind 961 /// (or the end of the file). 962 void skipUntil(MMToken::TokenKind K); 963 964 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 965 bool parseModuleId(ModuleId &Id); 966 void parseModuleDecl(); 967 void parseExternModuleDecl(); 968 void parseRequiresDecl(); 969 void parseHeaderDecl(clang::MMToken::TokenKind, 970 SourceLocation LeadingLoc); 971 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 972 void parseExportDecl(); 973 void parseUseDecl(); 974 void parseLinkDecl(); 975 void parseConfigMacros(); 976 void parseConflict(); 977 void parseInferredModuleDecl(bool Framework, bool Explicit); 978 bool parseOptionalAttributes(Attributes &Attrs); 979 980 const DirectoryEntry *getOverriddenHeaderSearchDir(); 981 982 public: 983 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 984 const TargetInfo *Target, 985 DiagnosticsEngine &Diags, 986 ModuleMap &Map, 987 const DirectoryEntry *Directory, 988 const DirectoryEntry *BuiltinIncludeDir, 989 bool IsSystem) 990 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 991 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 992 IsSystem(IsSystem), HadError(false), ActiveModule(0) 993 { 994 Tok.clear(); 995 consumeToken(); 996 } 997 998 bool parseModuleMapFile(); 999 }; 1000 } 1001 1002 SourceLocation ModuleMapParser::consumeToken() { 1003 retry: 1004 SourceLocation Result = Tok.getLocation(); 1005 Tok.clear(); 1006 1007 Token LToken; 1008 L.LexFromRawLexer(LToken); 1009 Tok.Location = LToken.getLocation().getRawEncoding(); 1010 switch (LToken.getKind()) { 1011 case tok::raw_identifier: 1012 Tok.StringData = LToken.getRawIdentifierData(); 1013 Tok.StringLength = LToken.getLength(); 1014 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 1015 .Case("config_macros", MMToken::ConfigMacros) 1016 .Case("conflict", MMToken::Conflict) 1017 .Case("exclude", MMToken::ExcludeKeyword) 1018 .Case("explicit", MMToken::ExplicitKeyword) 1019 .Case("export", MMToken::ExportKeyword) 1020 .Case("extern", MMToken::ExternKeyword) 1021 .Case("framework", MMToken::FrameworkKeyword) 1022 .Case("header", MMToken::HeaderKeyword) 1023 .Case("link", MMToken::LinkKeyword) 1024 .Case("module", MMToken::ModuleKeyword) 1025 .Case("private", MMToken::PrivateKeyword) 1026 .Case("requires", MMToken::RequiresKeyword) 1027 .Case("umbrella", MMToken::UmbrellaKeyword) 1028 .Case("use", MMToken::UseKeyword) 1029 .Default(MMToken::Identifier); 1030 break; 1031 1032 case tok::comma: 1033 Tok.Kind = MMToken::Comma; 1034 break; 1035 1036 case tok::eof: 1037 Tok.Kind = MMToken::EndOfFile; 1038 break; 1039 1040 case tok::l_brace: 1041 Tok.Kind = MMToken::LBrace; 1042 break; 1043 1044 case tok::l_square: 1045 Tok.Kind = MMToken::LSquare; 1046 break; 1047 1048 case tok::period: 1049 Tok.Kind = MMToken::Period; 1050 break; 1051 1052 case tok::r_brace: 1053 Tok.Kind = MMToken::RBrace; 1054 break; 1055 1056 case tok::r_square: 1057 Tok.Kind = MMToken::RSquare; 1058 break; 1059 1060 case tok::star: 1061 Tok.Kind = MMToken::Star; 1062 break; 1063 1064 case tok::exclaim: 1065 Tok.Kind = MMToken::Exclaim; 1066 break; 1067 1068 case tok::string_literal: { 1069 if (LToken.hasUDSuffix()) { 1070 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1071 HadError = true; 1072 goto retry; 1073 } 1074 1075 // Parse the string literal. 1076 LangOptions LangOpts; 1077 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 1078 if (StringLiteral.hadError) 1079 goto retry; 1080 1081 // Copy the string literal into our string data allocator. 1082 unsigned Length = StringLiteral.GetStringLength(); 1083 char *Saved = StringData.Allocate<char>(Length + 1); 1084 memcpy(Saved, StringLiteral.GetString().data(), Length); 1085 Saved[Length] = 0; 1086 1087 // Form the token. 1088 Tok.Kind = MMToken::StringLiteral; 1089 Tok.StringData = Saved; 1090 Tok.StringLength = Length; 1091 break; 1092 } 1093 1094 case tok::comment: 1095 goto retry; 1096 1097 default: 1098 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1099 HadError = true; 1100 goto retry; 1101 } 1102 1103 return Result; 1104 } 1105 1106 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1107 unsigned braceDepth = 0; 1108 unsigned squareDepth = 0; 1109 do { 1110 switch (Tok.Kind) { 1111 case MMToken::EndOfFile: 1112 return; 1113 1114 case MMToken::LBrace: 1115 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1116 return; 1117 1118 ++braceDepth; 1119 break; 1120 1121 case MMToken::LSquare: 1122 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1123 return; 1124 1125 ++squareDepth; 1126 break; 1127 1128 case MMToken::RBrace: 1129 if (braceDepth > 0) 1130 --braceDepth; 1131 else if (Tok.is(K)) 1132 return; 1133 break; 1134 1135 case MMToken::RSquare: 1136 if (squareDepth > 0) 1137 --squareDepth; 1138 else if (Tok.is(K)) 1139 return; 1140 break; 1141 1142 default: 1143 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1144 return; 1145 break; 1146 } 1147 1148 consumeToken(); 1149 } while (true); 1150 } 1151 1152 /// \brief Parse a module-id. 1153 /// 1154 /// module-id: 1155 /// identifier 1156 /// identifier '.' module-id 1157 /// 1158 /// \returns true if an error occurred, false otherwise. 1159 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1160 Id.clear(); 1161 do { 1162 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1163 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1164 consumeToken(); 1165 } else { 1166 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1167 return true; 1168 } 1169 1170 if (!Tok.is(MMToken::Period)) 1171 break; 1172 1173 consumeToken(); 1174 } while (true); 1175 1176 return false; 1177 } 1178 1179 namespace { 1180 /// \brief Enumerates the known attributes. 1181 enum AttributeKind { 1182 /// \brief An unknown attribute. 1183 AT_unknown, 1184 /// \brief The 'system' attribute. 1185 AT_system, 1186 /// \brief The 'extern_c' attribute. 1187 AT_extern_c, 1188 /// \brief The 'exhaustive' attribute. 1189 AT_exhaustive 1190 }; 1191 } 1192 1193 /// \brief Parse a module declaration. 1194 /// 1195 /// module-declaration: 1196 /// 'extern' 'module' module-id string-literal 1197 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1198 /// { module-member* } 1199 /// 1200 /// module-member: 1201 /// requires-declaration 1202 /// header-declaration 1203 /// submodule-declaration 1204 /// export-declaration 1205 /// link-declaration 1206 /// 1207 /// submodule-declaration: 1208 /// module-declaration 1209 /// inferred-submodule-declaration 1210 void ModuleMapParser::parseModuleDecl() { 1211 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1212 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1213 if (Tok.is(MMToken::ExternKeyword)) { 1214 parseExternModuleDecl(); 1215 return; 1216 } 1217 1218 // Parse 'explicit' or 'framework' keyword, if present. 1219 SourceLocation ExplicitLoc; 1220 bool Explicit = false; 1221 bool Framework = false; 1222 1223 // Parse 'explicit' keyword, if present. 1224 if (Tok.is(MMToken::ExplicitKeyword)) { 1225 ExplicitLoc = consumeToken(); 1226 Explicit = true; 1227 } 1228 1229 // Parse 'framework' keyword, if present. 1230 if (Tok.is(MMToken::FrameworkKeyword)) { 1231 consumeToken(); 1232 Framework = true; 1233 } 1234 1235 // Parse 'module' keyword. 1236 if (!Tok.is(MMToken::ModuleKeyword)) { 1237 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1238 consumeToken(); 1239 HadError = true; 1240 return; 1241 } 1242 consumeToken(); // 'module' keyword 1243 1244 // If we have a wildcard for the module name, this is an inferred submodule. 1245 // Parse it. 1246 if (Tok.is(MMToken::Star)) 1247 return parseInferredModuleDecl(Framework, Explicit); 1248 1249 // Parse the module name. 1250 ModuleId Id; 1251 if (parseModuleId(Id)) { 1252 HadError = true; 1253 return; 1254 } 1255 1256 if (ActiveModule) { 1257 if (Id.size() > 1) { 1258 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1259 << SourceRange(Id.front().second, Id.back().second); 1260 1261 HadError = true; 1262 return; 1263 } 1264 } else if (Id.size() == 1 && Explicit) { 1265 // Top-level modules can't be explicit. 1266 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1267 Explicit = false; 1268 ExplicitLoc = SourceLocation(); 1269 HadError = true; 1270 } 1271 1272 Module *PreviousActiveModule = ActiveModule; 1273 if (Id.size() > 1) { 1274 // This module map defines a submodule. Go find the module of which it 1275 // is a submodule. 1276 ActiveModule = 0; 1277 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1278 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1279 ActiveModule = Next; 1280 continue; 1281 } 1282 1283 if (ActiveModule) { 1284 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1285 << Id[I].first 1286 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1287 } else { 1288 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1289 } 1290 HadError = true; 1291 return; 1292 } 1293 } 1294 1295 StringRef ModuleName = Id.back().first; 1296 SourceLocation ModuleNameLoc = Id.back().second; 1297 1298 // Parse the optional attribute list. 1299 Attributes Attrs; 1300 parseOptionalAttributes(Attrs); 1301 1302 // Parse the opening brace. 1303 if (!Tok.is(MMToken::LBrace)) { 1304 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1305 << ModuleName; 1306 HadError = true; 1307 return; 1308 } 1309 SourceLocation LBraceLoc = consumeToken(); 1310 1311 // Determine whether this (sub)module has already been defined. 1312 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1313 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1314 // Skip the module definition. 1315 skipUntil(MMToken::RBrace); 1316 if (Tok.is(MMToken::RBrace)) 1317 consumeToken(); 1318 else { 1319 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1320 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1321 HadError = true; 1322 } 1323 return; 1324 } 1325 1326 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1327 << ModuleName; 1328 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1329 1330 // Skip the module definition. 1331 skipUntil(MMToken::RBrace); 1332 if (Tok.is(MMToken::RBrace)) 1333 consumeToken(); 1334 1335 HadError = true; 1336 return; 1337 } 1338 1339 // Start defining this module. 1340 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1341 Explicit).first; 1342 ActiveModule->DefinitionLoc = ModuleNameLoc; 1343 if (Attrs.IsSystem || IsSystem) 1344 ActiveModule->IsSystem = true; 1345 if (Attrs.IsExternC) 1346 ActiveModule->IsExternC = true; 1347 1348 bool Done = false; 1349 do { 1350 switch (Tok.Kind) { 1351 case MMToken::EndOfFile: 1352 case MMToken::RBrace: 1353 Done = true; 1354 break; 1355 1356 case MMToken::ConfigMacros: 1357 parseConfigMacros(); 1358 break; 1359 1360 case MMToken::Conflict: 1361 parseConflict(); 1362 break; 1363 1364 case MMToken::ExplicitKeyword: 1365 case MMToken::ExternKeyword: 1366 case MMToken::FrameworkKeyword: 1367 case MMToken::ModuleKeyword: 1368 parseModuleDecl(); 1369 break; 1370 1371 case MMToken::ExportKeyword: 1372 parseExportDecl(); 1373 break; 1374 1375 case MMToken::UseKeyword: 1376 parseUseDecl(); 1377 break; 1378 1379 case MMToken::RequiresKeyword: 1380 parseRequiresDecl(); 1381 break; 1382 1383 case MMToken::UmbrellaKeyword: { 1384 SourceLocation UmbrellaLoc = consumeToken(); 1385 if (Tok.is(MMToken::HeaderKeyword)) 1386 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1387 else 1388 parseUmbrellaDirDecl(UmbrellaLoc); 1389 break; 1390 } 1391 1392 case MMToken::ExcludeKeyword: { 1393 SourceLocation ExcludeLoc = consumeToken(); 1394 if (Tok.is(MMToken::HeaderKeyword)) { 1395 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc); 1396 } else { 1397 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1398 << "exclude"; 1399 } 1400 break; 1401 } 1402 1403 case MMToken::PrivateKeyword: { 1404 SourceLocation PrivateLoc = consumeToken(); 1405 if (Tok.is(MMToken::HeaderKeyword)) { 1406 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc); 1407 } else { 1408 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1409 << "private"; 1410 } 1411 break; 1412 } 1413 1414 case MMToken::HeaderKeyword: 1415 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation()); 1416 break; 1417 1418 case MMToken::LinkKeyword: 1419 parseLinkDecl(); 1420 break; 1421 1422 default: 1423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1424 consumeToken(); 1425 break; 1426 } 1427 } while (!Done); 1428 1429 if (Tok.is(MMToken::RBrace)) 1430 consumeToken(); 1431 else { 1432 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1433 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1434 HadError = true; 1435 } 1436 1437 // If the active module is a top-level framework, and there are no link 1438 // libraries, automatically link against the framework. 1439 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1440 ActiveModule->LinkLibraries.empty()) { 1441 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1442 } 1443 1444 // We're done parsing this module. Pop back to the previous module. 1445 ActiveModule = PreviousActiveModule; 1446 } 1447 1448 /// \brief Parse an extern module declaration. 1449 /// 1450 /// extern module-declaration: 1451 /// 'extern' 'module' module-id string-literal 1452 void ModuleMapParser::parseExternModuleDecl() { 1453 assert(Tok.is(MMToken::ExternKeyword)); 1454 consumeToken(); // 'extern' keyword 1455 1456 // Parse 'module' keyword. 1457 if (!Tok.is(MMToken::ModuleKeyword)) { 1458 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1459 consumeToken(); 1460 HadError = true; 1461 return; 1462 } 1463 consumeToken(); // 'module' keyword 1464 1465 // Parse the module name. 1466 ModuleId Id; 1467 if (parseModuleId(Id)) { 1468 HadError = true; 1469 return; 1470 } 1471 1472 // Parse the referenced module map file name. 1473 if (!Tok.is(MMToken::StringLiteral)) { 1474 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1475 HadError = true; 1476 return; 1477 } 1478 std::string FileName = Tok.getString(); 1479 consumeToken(); // filename 1480 1481 StringRef FileNameRef = FileName; 1482 SmallString<128> ModuleMapFileName; 1483 if (llvm::sys::path::is_relative(FileNameRef)) { 1484 ModuleMapFileName += Directory->getName(); 1485 llvm::sys::path::append(ModuleMapFileName, FileName); 1486 FileNameRef = ModuleMapFileName.str(); 1487 } 1488 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1489 Map.parseModuleMapFile(File, /*IsSystem=*/false); 1490 } 1491 1492 /// \brief Parse a requires declaration. 1493 /// 1494 /// requires-declaration: 1495 /// 'requires' feature-list 1496 /// 1497 /// feature-list: 1498 /// feature ',' feature-list 1499 /// feature 1500 /// 1501 /// feature: 1502 /// '!'[opt] identifier 1503 void ModuleMapParser::parseRequiresDecl() { 1504 assert(Tok.is(MMToken::RequiresKeyword)); 1505 1506 // Parse 'requires' keyword. 1507 consumeToken(); 1508 1509 // Parse the feature-list. 1510 do { 1511 bool RequiredState = true; 1512 if (Tok.is(MMToken::Exclaim)) { 1513 RequiredState = false; 1514 consumeToken(); 1515 } 1516 1517 if (!Tok.is(MMToken::Identifier)) { 1518 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1519 HadError = true; 1520 return; 1521 } 1522 1523 // Consume the feature name. 1524 std::string Feature = Tok.getString(); 1525 consumeToken(); 1526 1527 // Add this feature. 1528 ActiveModule->addRequirement(Feature, RequiredState, 1529 Map.LangOpts, *Map.Target); 1530 1531 if (!Tok.is(MMToken::Comma)) 1532 break; 1533 1534 // Consume the comma. 1535 consumeToken(); 1536 } while (true); 1537 } 1538 1539 /// \brief Append to \p Paths the set of paths needed to get to the 1540 /// subframework in which the given module lives. 1541 static void appendSubframeworkPaths(Module *Mod, 1542 SmallVectorImpl<char> &Path) { 1543 // Collect the framework names from the given module to the top-level module. 1544 SmallVector<StringRef, 2> Paths; 1545 for (; Mod; Mod = Mod->Parent) { 1546 if (Mod->IsFramework) 1547 Paths.push_back(Mod->Name); 1548 } 1549 1550 if (Paths.empty()) 1551 return; 1552 1553 // Add Frameworks/Name.framework for each subframework. 1554 for (unsigned I = Paths.size() - 1; I != 0; --I) 1555 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1556 } 1557 1558 /// \brief Parse a header declaration. 1559 /// 1560 /// header-declaration: 1561 /// 'umbrella'[opt] 'header' string-literal 1562 /// 'exclude'[opt] 'header' string-literal 1563 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1564 SourceLocation LeadingLoc) { 1565 assert(Tok.is(MMToken::HeaderKeyword)); 1566 consumeToken(); 1567 1568 // Parse the header name. 1569 if (!Tok.is(MMToken::StringLiteral)) { 1570 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1571 << "header"; 1572 HadError = true; 1573 return; 1574 } 1575 Module::HeaderDirective Header; 1576 Header.FileName = Tok.getString(); 1577 Header.FileNameLoc = consumeToken(); 1578 1579 // Check whether we already have an umbrella. 1580 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1581 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 1582 << ActiveModule->getFullModuleName(); 1583 HadError = true; 1584 return; 1585 } 1586 1587 // Look for this file. 1588 const FileEntry *File = 0; 1589 const FileEntry *BuiltinFile = 0; 1590 SmallString<128> PathName; 1591 if (llvm::sys::path::is_absolute(Header.FileName)) { 1592 PathName = Header.FileName; 1593 File = SourceMgr.getFileManager().getFile(PathName); 1594 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1595 PathName = Dir->getName(); 1596 llvm::sys::path::append(PathName, Header.FileName); 1597 File = SourceMgr.getFileManager().getFile(PathName); 1598 } else { 1599 // Search for the header file within the search directory. 1600 PathName = Directory->getName(); 1601 unsigned PathLength = PathName.size(); 1602 1603 if (ActiveModule->isPartOfFramework()) { 1604 appendSubframeworkPaths(ActiveModule, PathName); 1605 1606 // Check whether this file is in the public headers. 1607 llvm::sys::path::append(PathName, "Headers", Header.FileName); 1608 File = SourceMgr.getFileManager().getFile(PathName); 1609 1610 if (!File) { 1611 // Check whether this file is in the private headers. 1612 PathName.resize(PathLength); 1613 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName); 1614 File = SourceMgr.getFileManager().getFile(PathName); 1615 } 1616 } else { 1617 // Lookup for normal headers. 1618 llvm::sys::path::append(PathName, Header.FileName); 1619 File = SourceMgr.getFileManager().getFile(PathName); 1620 1621 // If this is a system module with a top-level header, this header 1622 // may have a counterpart (or replacement) in the set of headers 1623 // supplied by Clang. Find that builtin header. 1624 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1625 BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1626 isBuiltinHeader(Header.FileName)) { 1627 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1628 llvm::sys::path::append(BuiltinPathName, Header.FileName); 1629 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1630 1631 // If Clang supplies this header but the underlying system does not, 1632 // just silently swap in our builtin version. Otherwise, we'll end 1633 // up adding both (later). 1634 if (!File && BuiltinFile) { 1635 File = BuiltinFile; 1636 BuiltinFile = 0; 1637 } 1638 } 1639 } 1640 } 1641 1642 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1643 // Come up with a lazy way to do this. 1644 if (File) { 1645 if (LeadingToken == MMToken::UmbrellaKeyword) { 1646 const DirectoryEntry *UmbrellaDir = File->getDir(); 1647 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1648 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 1649 << UmbrellaModule->getFullModuleName(); 1650 HadError = true; 1651 } else { 1652 // Record this umbrella header. 1653 Map.setUmbrellaHeader(ActiveModule, File); 1654 } 1655 } else { 1656 // Record this header. 1657 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1658 if (LeadingToken == MMToken::ExcludeKeyword) 1659 Role = ModuleMap::ExcludedHeader; 1660 else if (LeadingToken == MMToken::PrivateKeyword) 1661 Role = ModuleMap::PrivateHeader; 1662 else 1663 assert(LeadingToken == MMToken::HeaderKeyword); 1664 1665 Map.addHeader(ActiveModule, File, Role); 1666 1667 // If there is a builtin counterpart to this file, add it now. 1668 if (BuiltinFile) 1669 Map.addHeader(ActiveModule, BuiltinFile, Role); 1670 } 1671 } else if (LeadingToken != MMToken::ExcludeKeyword) { 1672 // Ignore excluded header files. They're optional anyway. 1673 1674 // If we find a module that has a missing header, we mark this module as 1675 // unavailable and store the header directive for displaying diagnostics. 1676 // Other submodules in the same module can still be used. 1677 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 1678 ActiveModule->IsAvailable = false; 1679 ActiveModule->MissingHeaders.push_back(Header); 1680 } 1681 } 1682 1683 /// \brief Parse an umbrella directory declaration. 1684 /// 1685 /// umbrella-dir-declaration: 1686 /// umbrella string-literal 1687 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1688 // Parse the directory name. 1689 if (!Tok.is(MMToken::StringLiteral)) { 1690 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1691 << "umbrella"; 1692 HadError = true; 1693 return; 1694 } 1695 1696 std::string DirName = Tok.getString(); 1697 SourceLocation DirNameLoc = consumeToken(); 1698 1699 // Check whether we already have an umbrella. 1700 if (ActiveModule->Umbrella) { 1701 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1702 << ActiveModule->getFullModuleName(); 1703 HadError = true; 1704 return; 1705 } 1706 1707 // Look for this file. 1708 const DirectoryEntry *Dir = 0; 1709 if (llvm::sys::path::is_absolute(DirName)) 1710 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1711 else { 1712 SmallString<128> PathName; 1713 PathName = Directory->getName(); 1714 llvm::sys::path::append(PathName, DirName); 1715 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1716 } 1717 1718 if (!Dir) { 1719 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1720 << DirName; 1721 HadError = true; 1722 return; 1723 } 1724 1725 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1726 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1727 << OwningModule->getFullModuleName(); 1728 HadError = true; 1729 return; 1730 } 1731 1732 // Record this umbrella directory. 1733 Map.setUmbrellaDir(ActiveModule, Dir); 1734 } 1735 1736 /// \brief Parse a module export declaration. 1737 /// 1738 /// export-declaration: 1739 /// 'export' wildcard-module-id 1740 /// 1741 /// wildcard-module-id: 1742 /// identifier 1743 /// '*' 1744 /// identifier '.' wildcard-module-id 1745 void ModuleMapParser::parseExportDecl() { 1746 assert(Tok.is(MMToken::ExportKeyword)); 1747 SourceLocation ExportLoc = consumeToken(); 1748 1749 // Parse the module-id with an optional wildcard at the end. 1750 ModuleId ParsedModuleId; 1751 bool Wildcard = false; 1752 do { 1753 if (Tok.is(MMToken::Identifier)) { 1754 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1755 Tok.getLocation())); 1756 consumeToken(); 1757 1758 if (Tok.is(MMToken::Period)) { 1759 consumeToken(); 1760 continue; 1761 } 1762 1763 break; 1764 } 1765 1766 if(Tok.is(MMToken::Star)) { 1767 Wildcard = true; 1768 consumeToken(); 1769 break; 1770 } 1771 1772 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 1773 HadError = true; 1774 return; 1775 } while (true); 1776 1777 Module::UnresolvedExportDecl Unresolved = { 1778 ExportLoc, ParsedModuleId, Wildcard 1779 }; 1780 ActiveModule->UnresolvedExports.push_back(Unresolved); 1781 } 1782 1783 /// \brief Parse a module uses declaration. 1784 /// 1785 /// uses-declaration: 1786 /// 'uses' wildcard-module-id 1787 void ModuleMapParser::parseUseDecl() { 1788 assert(Tok.is(MMToken::UseKeyword)); 1789 consumeToken(); 1790 // Parse the module-id. 1791 ModuleId ParsedModuleId; 1792 parseModuleId(ParsedModuleId); 1793 1794 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1795 } 1796 1797 /// \brief Parse a link declaration. 1798 /// 1799 /// module-declaration: 1800 /// 'link' 'framework'[opt] string-literal 1801 void ModuleMapParser::parseLinkDecl() { 1802 assert(Tok.is(MMToken::LinkKeyword)); 1803 SourceLocation LinkLoc = consumeToken(); 1804 1805 // Parse the optional 'framework' keyword. 1806 bool IsFramework = false; 1807 if (Tok.is(MMToken::FrameworkKeyword)) { 1808 consumeToken(); 1809 IsFramework = true; 1810 } 1811 1812 // Parse the library name 1813 if (!Tok.is(MMToken::StringLiteral)) { 1814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1815 << IsFramework << SourceRange(LinkLoc); 1816 HadError = true; 1817 return; 1818 } 1819 1820 std::string LibraryName = Tok.getString(); 1821 consumeToken(); 1822 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1823 IsFramework)); 1824 } 1825 1826 /// \brief Parse a configuration macro declaration. 1827 /// 1828 /// module-declaration: 1829 /// 'config_macros' attributes[opt] config-macro-list? 1830 /// 1831 /// config-macro-list: 1832 /// identifier (',' identifier)? 1833 void ModuleMapParser::parseConfigMacros() { 1834 assert(Tok.is(MMToken::ConfigMacros)); 1835 SourceLocation ConfigMacrosLoc = consumeToken(); 1836 1837 // Only top-level modules can have configuration macros. 1838 if (ActiveModule->Parent) { 1839 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 1840 } 1841 1842 // Parse the optional attributes. 1843 Attributes Attrs; 1844 parseOptionalAttributes(Attrs); 1845 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 1846 ActiveModule->ConfigMacrosExhaustive = true; 1847 } 1848 1849 // If we don't have an identifier, we're done. 1850 if (!Tok.is(MMToken::Identifier)) 1851 return; 1852 1853 // Consume the first identifier. 1854 if (!ActiveModule->Parent) { 1855 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1856 } 1857 consumeToken(); 1858 1859 do { 1860 // If there's a comma, consume it. 1861 if (!Tok.is(MMToken::Comma)) 1862 break; 1863 consumeToken(); 1864 1865 // We expect to see a macro name here. 1866 if (!Tok.is(MMToken::Identifier)) { 1867 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 1868 break; 1869 } 1870 1871 // Consume the macro name. 1872 if (!ActiveModule->Parent) { 1873 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1874 } 1875 consumeToken(); 1876 } while (true); 1877 } 1878 1879 /// \brief Format a module-id into a string. 1880 static std::string formatModuleId(const ModuleId &Id) { 1881 std::string result; 1882 { 1883 llvm::raw_string_ostream OS(result); 1884 1885 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 1886 if (I) 1887 OS << "."; 1888 OS << Id[I].first; 1889 } 1890 } 1891 1892 return result; 1893 } 1894 1895 /// \brief Parse a conflict declaration. 1896 /// 1897 /// module-declaration: 1898 /// 'conflict' module-id ',' string-literal 1899 void ModuleMapParser::parseConflict() { 1900 assert(Tok.is(MMToken::Conflict)); 1901 SourceLocation ConflictLoc = consumeToken(); 1902 Module::UnresolvedConflict Conflict; 1903 1904 // Parse the module-id. 1905 if (parseModuleId(Conflict.Id)) 1906 return; 1907 1908 // Parse the ','. 1909 if (!Tok.is(MMToken::Comma)) { 1910 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 1911 << SourceRange(ConflictLoc); 1912 return; 1913 } 1914 consumeToken(); 1915 1916 // Parse the message. 1917 if (!Tok.is(MMToken::StringLiteral)) { 1918 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 1919 << formatModuleId(Conflict.Id); 1920 return; 1921 } 1922 Conflict.Message = Tok.getString().str(); 1923 consumeToken(); 1924 1925 // Add this unresolved conflict. 1926 ActiveModule->UnresolvedConflicts.push_back(Conflict); 1927 } 1928 1929 /// \brief Parse an inferred module declaration (wildcard modules). 1930 /// 1931 /// module-declaration: 1932 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 1933 /// { inferred-module-member* } 1934 /// 1935 /// inferred-module-member: 1936 /// 'export' '*' 1937 /// 'exclude' identifier 1938 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 1939 assert(Tok.is(MMToken::Star)); 1940 SourceLocation StarLoc = consumeToken(); 1941 bool Failed = false; 1942 1943 // Inferred modules must be submodules. 1944 if (!ActiveModule && !Framework) { 1945 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1946 Failed = true; 1947 } 1948 1949 if (ActiveModule) { 1950 // Inferred modules must have umbrella directories. 1951 if (!Failed && !ActiveModule->getUmbrellaDir()) { 1952 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1953 Failed = true; 1954 } 1955 1956 // Check for redefinition of an inferred module. 1957 if (!Failed && ActiveModule->InferSubmodules) { 1958 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1959 if (ActiveModule->InferredSubmoduleLoc.isValid()) 1960 Diags.Report(ActiveModule->InferredSubmoduleLoc, 1961 diag::note_mmap_prev_definition); 1962 Failed = true; 1963 } 1964 1965 // Check for the 'framework' keyword, which is not permitted here. 1966 if (Framework) { 1967 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 1968 Framework = false; 1969 } 1970 } else if (Explicit) { 1971 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 1972 Explicit = false; 1973 } 1974 1975 // If there were any problems with this inferred submodule, skip its body. 1976 if (Failed) { 1977 if (Tok.is(MMToken::LBrace)) { 1978 consumeToken(); 1979 skipUntil(MMToken::RBrace); 1980 if (Tok.is(MMToken::RBrace)) 1981 consumeToken(); 1982 } 1983 HadError = true; 1984 return; 1985 } 1986 1987 // Parse optional attributes. 1988 Attributes Attrs; 1989 parseOptionalAttributes(Attrs); 1990 1991 if (ActiveModule) { 1992 // Note that we have an inferred submodule. 1993 ActiveModule->InferSubmodules = true; 1994 ActiveModule->InferredSubmoduleLoc = StarLoc; 1995 ActiveModule->InferExplicitSubmodules = Explicit; 1996 } else { 1997 // We'll be inferring framework modules for this directory. 1998 Map.InferredDirectories[Directory].InferModules = true; 1999 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 2000 // FIXME: Handle the 'framework' keyword. 2001 } 2002 2003 // Parse the opening brace. 2004 if (!Tok.is(MMToken::LBrace)) { 2005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2006 HadError = true; 2007 return; 2008 } 2009 SourceLocation LBraceLoc = consumeToken(); 2010 2011 // Parse the body of the inferred submodule. 2012 bool Done = false; 2013 do { 2014 switch (Tok.Kind) { 2015 case MMToken::EndOfFile: 2016 case MMToken::RBrace: 2017 Done = true; 2018 break; 2019 2020 case MMToken::ExcludeKeyword: { 2021 if (ActiveModule) { 2022 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2023 << (ActiveModule != 0); 2024 consumeToken(); 2025 break; 2026 } 2027 2028 consumeToken(); 2029 if (!Tok.is(MMToken::Identifier)) { 2030 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2031 break; 2032 } 2033 2034 Map.InferredDirectories[Directory].ExcludedModules 2035 .push_back(Tok.getString()); 2036 consumeToken(); 2037 break; 2038 } 2039 2040 case MMToken::ExportKeyword: 2041 if (!ActiveModule) { 2042 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2043 << (ActiveModule != 0); 2044 consumeToken(); 2045 break; 2046 } 2047 2048 consumeToken(); 2049 if (Tok.is(MMToken::Star)) 2050 ActiveModule->InferExportWildcard = true; 2051 else 2052 Diags.Report(Tok.getLocation(), 2053 diag::err_mmap_expected_export_wildcard); 2054 consumeToken(); 2055 break; 2056 2057 case MMToken::ExplicitKeyword: 2058 case MMToken::ModuleKeyword: 2059 case MMToken::HeaderKeyword: 2060 case MMToken::PrivateKeyword: 2061 case MMToken::UmbrellaKeyword: 2062 default: 2063 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2064 << (ActiveModule != 0); 2065 consumeToken(); 2066 break; 2067 } 2068 } while (!Done); 2069 2070 if (Tok.is(MMToken::RBrace)) 2071 consumeToken(); 2072 else { 2073 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2074 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2075 HadError = true; 2076 } 2077 } 2078 2079 /// \brief Parse optional attributes. 2080 /// 2081 /// attributes: 2082 /// attribute attributes 2083 /// attribute 2084 /// 2085 /// attribute: 2086 /// [ identifier ] 2087 /// 2088 /// \param Attrs Will be filled in with the parsed attributes. 2089 /// 2090 /// \returns true if an error occurred, false otherwise. 2091 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2092 bool HadError = false; 2093 2094 while (Tok.is(MMToken::LSquare)) { 2095 // Consume the '['. 2096 SourceLocation LSquareLoc = consumeToken(); 2097 2098 // Check whether we have an attribute name here. 2099 if (!Tok.is(MMToken::Identifier)) { 2100 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2101 skipUntil(MMToken::RSquare); 2102 if (Tok.is(MMToken::RSquare)) 2103 consumeToken(); 2104 HadError = true; 2105 } 2106 2107 // Decode the attribute name. 2108 AttributeKind Attribute 2109 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2110 .Case("exhaustive", AT_exhaustive) 2111 .Case("extern_c", AT_extern_c) 2112 .Case("system", AT_system) 2113 .Default(AT_unknown); 2114 switch (Attribute) { 2115 case AT_unknown: 2116 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2117 << Tok.getString(); 2118 break; 2119 2120 case AT_system: 2121 Attrs.IsSystem = true; 2122 break; 2123 2124 case AT_extern_c: 2125 Attrs.IsExternC = true; 2126 break; 2127 2128 case AT_exhaustive: 2129 Attrs.IsExhaustive = true; 2130 break; 2131 } 2132 consumeToken(); 2133 2134 // Consume the ']'. 2135 if (!Tok.is(MMToken::RSquare)) { 2136 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2137 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2138 skipUntil(MMToken::RSquare); 2139 HadError = true; 2140 } 2141 2142 if (Tok.is(MMToken::RSquare)) 2143 consumeToken(); 2144 } 2145 2146 return HadError; 2147 } 2148 2149 /// \brief If there is a specific header search directory due the presence 2150 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 2151 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 2152 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 2153 // If we have an umbrella directory, use that. 2154 if (Mod->hasUmbrellaDir()) 2155 return Mod->getUmbrellaDir(); 2156 2157 // If we have a framework directory, stop looking. 2158 if (Mod->IsFramework) 2159 return 0; 2160 } 2161 2162 return 0; 2163 } 2164 2165 /// \brief Parse a module map file. 2166 /// 2167 /// module-map-file: 2168 /// module-declaration* 2169 bool ModuleMapParser::parseModuleMapFile() { 2170 do { 2171 switch (Tok.Kind) { 2172 case MMToken::EndOfFile: 2173 return HadError; 2174 2175 case MMToken::ExplicitKeyword: 2176 case MMToken::ExternKeyword: 2177 case MMToken::ModuleKeyword: 2178 case MMToken::FrameworkKeyword: 2179 parseModuleDecl(); 2180 break; 2181 2182 case MMToken::Comma: 2183 case MMToken::ConfigMacros: 2184 case MMToken::Conflict: 2185 case MMToken::Exclaim: 2186 case MMToken::ExcludeKeyword: 2187 case MMToken::ExportKeyword: 2188 case MMToken::HeaderKeyword: 2189 case MMToken::Identifier: 2190 case MMToken::LBrace: 2191 case MMToken::LinkKeyword: 2192 case MMToken::LSquare: 2193 case MMToken::Period: 2194 case MMToken::PrivateKeyword: 2195 case MMToken::RBrace: 2196 case MMToken::RSquare: 2197 case MMToken::RequiresKeyword: 2198 case MMToken::Star: 2199 case MMToken::StringLiteral: 2200 case MMToken::UmbrellaKeyword: 2201 case MMToken::UseKeyword: 2202 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2203 HadError = true; 2204 consumeToken(); 2205 break; 2206 } 2207 } while (true); 2208 } 2209 2210 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { 2211 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2212 = ParsedModuleMap.find(File); 2213 if (Known != ParsedModuleMap.end()) 2214 return Known->second; 2215 2216 assert(Target != 0 && "Missing target information"); 2217 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2218 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter); 2219 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2220 if (!Buffer) 2221 return ParsedModuleMap[File] = true; 2222 2223 // Find the directory for the module. For frameworks, that may require going 2224 // up from the 'Modules' directory. 2225 const DirectoryEntry *Dir = File->getDir(); 2226 StringRef DirName(Dir->getName()); 2227 if (llvm::sys::path::filename(DirName) == "Modules") { 2228 DirName = llvm::sys::path::parent_path(DirName); 2229 if (DirName.endswith(".framework")) 2230 Dir = SourceMgr.getFileManager().getDirectory(DirName); 2231 assert(Dir && "parent must exist"); 2232 } 2233 2234 // Parse this module map file. 2235 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 2236 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, Dir, 2237 BuiltinIncludeDir, IsSystem); 2238 bool Result = Parser.parseModuleMapFile(); 2239 ParsedModuleMap[File] = Result; 2240 return Result; 2241 } 2242