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