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