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