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