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