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