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