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