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/CharInfo.h" 16 #include "clang/Basic/Diagnostic.h" 17 #include "clang/Basic/DiagnosticOptions.h" 18 #include "clang/Basic/FileManager.h" 19 #include "clang/Basic/TargetInfo.h" 20 #include "clang/Basic/TargetOptions.h" 21 #include "clang/Lex/HeaderSearch.h" 22 #include "clang/Lex/LexDiagnostic.h" 23 #include "clang/Lex/Lexer.h" 24 #include "clang/Lex/LiteralSupport.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/StringSwitch.h" 27 #include "llvm/Support/Allocator.h" 28 #include "llvm/Support/FileSystem.h" 29 #include "llvm/Support/Host.h" 30 #include "llvm/Support/Path.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include <stdlib.h> 33 #if defined(LLVM_ON_UNIX) 34 #include <limits.h> 35 #endif 36 using namespace clang; 37 38 Module::ExportDecl 39 ModuleMap::resolveExport(Module *Mod, 40 const Module::UnresolvedExportDecl &Unresolved, 41 bool Complain) const { 42 // We may have just a wildcard. 43 if (Unresolved.Id.empty()) { 44 assert(Unresolved.Wildcard && "Invalid unresolved export"); 45 return Module::ExportDecl(nullptr, true); 46 } 47 48 // Resolve the module-id. 49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 50 if (!Context) 51 return Module::ExportDecl(); 52 53 return Module::ExportDecl(Context, Unresolved.Wildcard); 54 } 55 56 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 57 bool Complain) const { 58 // Find the starting module. 59 Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 60 if (!Context) { 61 if (Complain) 62 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 63 << Id[0].first << Mod->getFullModuleName(); 64 65 return nullptr; 66 } 67 68 // Dig into the module path. 69 for (unsigned I = 1, N = Id.size(); I != N; ++I) { 70 Module *Sub = lookupModuleQualified(Id[I].first, Context); 71 if (!Sub) { 72 if (Complain) 73 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 74 << Id[I].first << Context->getFullModuleName() 75 << SourceRange(Id[0].second, Id[I-1].second); 76 77 return nullptr; 78 } 79 80 Context = Sub; 81 } 82 83 return Context; 84 } 85 86 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 87 const LangOptions &LangOpts, const TargetInfo *Target, 88 HeaderSearch &HeaderInfo) 89 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 90 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), 91 CompilingModule(nullptr), SourceModule(nullptr) {} 92 93 ModuleMap::~ModuleMap() { 94 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 95 IEnd = Modules.end(); 96 I != IEnd; ++I) { 97 delete I->getValue(); 98 } 99 } 100 101 void ModuleMap::setTarget(const TargetInfo &Target) { 102 assert((!this->Target || this->Target == &Target) && 103 "Improper target override"); 104 this->Target = &Target; 105 } 106 107 /// \brief "Sanitize" a filename so that it can be used as an identifier. 108 static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 109 SmallVectorImpl<char> &Buffer) { 110 if (Name.empty()) 111 return Name; 112 113 if (!isValidIdentifier(Name)) { 114 // If we don't already have something with the form of an identifier, 115 // create a buffer with the sanitized name. 116 Buffer.clear(); 117 if (isDigit(Name[0])) 118 Buffer.push_back('_'); 119 Buffer.reserve(Buffer.size() + Name.size()); 120 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 121 if (isIdentifierBody(Name[I])) 122 Buffer.push_back(Name[I]); 123 else 124 Buffer.push_back('_'); 125 } 126 127 Name = StringRef(Buffer.data(), Buffer.size()); 128 } 129 130 while (llvm::StringSwitch<bool>(Name) 131 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 132 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 133 #include "clang/Basic/TokenKinds.def" 134 .Default(false)) { 135 if (Name.data() != Buffer.data()) 136 Buffer.append(Name.begin(), Name.end()); 137 Buffer.push_back('_'); 138 Name = StringRef(Buffer.data(), Buffer.size()); 139 } 140 141 return Name; 142 } 143 144 /// \brief Determine whether the given file name is the name of a builtin 145 /// header, supplied by Clang to replace, override, or augment existing system 146 /// headers. 147 static bool isBuiltinHeader(StringRef FileName) { 148 return llvm::StringSwitch<bool>(FileName) 149 .Case("float.h", true) 150 .Case("iso646.h", true) 151 .Case("limits.h", true) 152 .Case("stdalign.h", true) 153 .Case("stdarg.h", true) 154 .Case("stdbool.h", true) 155 .Case("stddef.h", true) 156 .Case("stdint.h", true) 157 .Case("tgmath.h", true) 158 .Case("unwind.h", true) 159 .Default(false); 160 } 161 162 ModuleMap::HeadersMap::iterator 163 ModuleMap::findKnownHeader(const FileEntry *File) { 164 HeadersMap::iterator Known = Headers.find(File); 165 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir && 166 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 167 HeaderInfo.loadTopLevelSystemModules(); 168 return Headers.find(File); 169 } 170 return Known; 171 } 172 173 ModuleMap::KnownHeader 174 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, 175 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { 176 const DirectoryEntry *Dir = File->getDir(); 177 assert(Dir && "file in no directory"); 178 179 // Note: as an egregious but useful hack we use the real path here, because 180 // frameworks moving from top-level frameworks to embedded frameworks tend 181 // to be symlinked from the top-level location to the embedded location, 182 // and we need to resolve lookups as if we had found the embedded location. 183 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 184 185 // Keep walking up the directory hierarchy, looking for a directory with 186 // an umbrella header. 187 do { 188 auto KnownDir = UmbrellaDirs.find(Dir); 189 if (KnownDir != UmbrellaDirs.end()) 190 return KnownHeader(KnownDir->second, NormalHeader); 191 192 IntermediateDirs.push_back(Dir); 193 194 // Retrieve our parent path. 195 DirName = llvm::sys::path::parent_path(DirName); 196 if (DirName.empty()) 197 break; 198 199 // Resolve the parent path to a directory entry. 200 Dir = SourceMgr.getFileManager().getDirectory(DirName); 201 } while (Dir); 202 return KnownHeader(); 203 } 204 205 // Returns true if RequestingModule directly uses RequestedModule. 206 static bool directlyUses(const Module *RequestingModule, 207 const Module *RequestedModule) { 208 return std::find(RequestingModule->DirectUses.begin(), 209 RequestingModule->DirectUses.end(), 210 RequestedModule) != RequestingModule->DirectUses.end(); 211 } 212 213 static bool violatesPrivateInclude(Module *RequestingModule, 214 const FileEntry *IncFileEnt, 215 ModuleMap::ModuleHeaderRole Role, 216 Module *RequestedModule) { 217 bool IsPrivateRole = Role & ModuleMap::PrivateHeader; 218 #ifndef NDEBUG 219 // Check for consistency between the module header role 220 // as obtained from the lookup and as obtained from the module. 221 // This check is not cheap, so enable it only for debugging. 222 bool IsPrivate = false; 223 auto HeaderList = {&RequestedModule->PrivateHeaders, 224 &RequestedModule->PrivateTextualHeaders}; 225 for (auto *Hdrs : HeaderList) 226 IsPrivate |= 227 std::find(Hdrs->begin(), Hdrs->end(), IncFileEnt) != Hdrs->end(); 228 assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles"); 229 #endif 230 return IsPrivateRole && 231 RequestedModule->getTopLevelModule() != RequestingModule; 232 } 233 234 static Module *getTopLevelOrNull(Module *M) { 235 return M ? M->getTopLevelModule() : nullptr; 236 } 237 238 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 239 SourceLocation FilenameLoc, 240 StringRef Filename, 241 const FileEntry *File) { 242 // No errors for indirect modules. This may be a bit of a problem for modules 243 // with no source files. 244 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) 245 return; 246 247 if (RequestingModule) 248 resolveUses(RequestingModule, /*Complain=*/false); 249 250 bool Excluded = false; 251 Module *Private = nullptr; 252 Module *NotUsed = nullptr; 253 254 HeadersMap::iterator Known = findKnownHeader(File); 255 if (Known != Headers.end()) { 256 for (const KnownHeader &Header : Known->second) { 257 // If 'File' is part of 'RequestingModule' we can definitely include it. 258 if (Header.getModule() == RequestingModule) 259 return; 260 261 // Remember private headers for later printing of a diagnostic. 262 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(), 263 Header.getModule())) { 264 Private = Header.getModule(); 265 continue; 266 } 267 268 // If uses need to be specified explicitly, we are only allowed to return 269 // modules that are explicitly used by the requesting module. 270 if (RequestingModule && LangOpts.ModulesDeclUse && 271 !directlyUses(RequestingModule, Header.getModule())) { 272 NotUsed = Header.getModule(); 273 continue; 274 } 275 276 // We have found a module that we can happily use. 277 return; 278 } 279 280 Excluded = true; 281 } 282 283 // We have found a header, but it is private. 284 if (Private) { 285 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module) 286 << Filename; 287 return; 288 } 289 290 // We have found a module, but we don't use it. 291 if (NotUsed) { 292 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) 293 << RequestingModule->getFullModuleName() << Filename; 294 return; 295 } 296 297 if (Excluded || isHeaderInUmbrellaDirs(File)) 298 return; 299 300 // At this point, only non-modular includes remain. 301 302 if (LangOpts.ModulesStrictDeclUse) { 303 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) 304 << RequestingModule->getFullModuleName() << Filename; 305 } else if (RequestingModule) { 306 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? 307 diag::warn_non_modular_include_in_framework_module : 308 diag::warn_non_modular_include_in_module; 309 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName(); 310 } 311 } 312 313 ModuleMap::KnownHeader 314 ModuleMap::findModuleForHeader(const FileEntry *File, 315 Module *RequestingModule, 316 bool IncludeTextualHeaders) { 317 HeadersMap::iterator Known = findKnownHeader(File); 318 319 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { 320 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader)) 321 return ModuleMap::KnownHeader(); 322 return R; 323 }; 324 325 if (Known != Headers.end()) { 326 ModuleMap::KnownHeader Result; 327 328 // Iterate over all modules that 'File' is part of to find the best fit. 329 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 330 E = Known->second.end(); 331 I != E; ++I) { 332 // Cannot use a module if it is unavailable. 333 if (!I->getModule()->isAvailable()) 334 continue; 335 336 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the 337 // module we are looking for. 338 if (I->getModule() == RequestingModule) 339 return MakeResult(*I); 340 341 // If uses need to be specified explicitly, we are only allowed to return 342 // modules that are explicitly used by the requesting module. 343 if (RequestingModule && LangOpts.ModulesDeclUse && 344 !directlyUses(RequestingModule, I->getModule())) 345 continue; 346 347 // Prefer a public header over a private header. 348 if (!Result || (Result.getRole() & ModuleMap::PrivateHeader)) 349 Result = *I; 350 } 351 return MakeResult(Result); 352 } 353 354 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 355 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); 356 if (H) { 357 Module *Result = H.getModule(); 358 359 // Search up the module stack until we find a module with an umbrella 360 // directory. 361 Module *UmbrellaModule = Result; 362 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 363 UmbrellaModule = UmbrellaModule->Parent; 364 365 if (UmbrellaModule->InferSubmodules) { 366 const FileEntry *UmbrellaModuleMap = 367 getModuleMapFileForUniquing(UmbrellaModule); 368 369 // Infer submodules for each of the directories we found between 370 // the directory of the umbrella header and the directory where 371 // the actual header is located. 372 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 373 374 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 375 // Find or create the module that corresponds to this directory name. 376 SmallString<32> NameBuf; 377 StringRef Name = sanitizeFilenameAsIdentifier( 378 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf); 379 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 380 Explicit).first; 381 InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 382 Result->IsInferred = true; 383 384 // Associate the module and the directory. 385 UmbrellaDirs[SkippedDirs[I-1]] = Result; 386 387 // If inferred submodules export everything they import, add a 388 // wildcard to the set of exports. 389 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 390 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 391 } 392 393 // Infer a submodule with the same name as this header file. 394 SmallString<32> NameBuf; 395 StringRef Name = sanitizeFilenameAsIdentifier( 396 llvm::sys::path::stem(File->getName()), NameBuf); 397 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 398 Explicit).first; 399 InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 400 Result->IsInferred = true; 401 Result->addTopHeader(File); 402 403 // If inferred submodules export everything they import, add a 404 // wildcard to the set of exports. 405 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 406 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 407 } else { 408 // Record each of the directories we stepped through as being part of 409 // the module we found, since the umbrella header covers them all. 410 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 411 UmbrellaDirs[SkippedDirs[I]] = Result; 412 } 413 414 Headers[File].push_back(KnownHeader(Result, NormalHeader)); 415 416 // If a header corresponds to an unavailable module, don't report 417 // that it maps to anything. 418 if (!Result->isAvailable()) 419 return KnownHeader(); 420 421 return MakeResult(Headers[File].back()); 422 } 423 424 return KnownHeader(); 425 } 426 427 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 428 return isHeaderUnavailableInModule(Header, nullptr); 429 } 430 431 bool 432 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, 433 const Module *RequestingModule) const { 434 HeadersMap::const_iterator Known = Headers.find(Header); 435 if (Known != Headers.end()) { 436 for (SmallVectorImpl<KnownHeader>::const_iterator 437 I = Known->second.begin(), 438 E = Known->second.end(); 439 I != E; ++I) { 440 if (I->isAvailable() && (!RequestingModule || 441 I->getModule()->isSubModuleOf(RequestingModule))) 442 return false; 443 } 444 return true; 445 } 446 447 const DirectoryEntry *Dir = Header->getDir(); 448 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 449 StringRef DirName = Dir->getName(); 450 451 auto IsUnavailable = [&](const Module *M) { 452 return !M->isAvailable() && (!RequestingModule || 453 M->isSubModuleOf(RequestingModule)); 454 }; 455 456 // Keep walking up the directory hierarchy, looking for a directory with 457 // an umbrella header. 458 do { 459 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 460 = UmbrellaDirs.find(Dir); 461 if (KnownDir != UmbrellaDirs.end()) { 462 Module *Found = KnownDir->second; 463 if (IsUnavailable(Found)) 464 return true; 465 466 // Search up the module stack until we find a module with an umbrella 467 // directory. 468 Module *UmbrellaModule = Found; 469 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 470 UmbrellaModule = UmbrellaModule->Parent; 471 472 if (UmbrellaModule->InferSubmodules) { 473 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 474 // Find or create the module that corresponds to this directory name. 475 SmallString<32> NameBuf; 476 StringRef Name = sanitizeFilenameAsIdentifier( 477 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 478 NameBuf); 479 Found = lookupModuleQualified(Name, Found); 480 if (!Found) 481 return false; 482 if (IsUnavailable(Found)) 483 return true; 484 } 485 486 // Infer a submodule with the same name as this header file. 487 SmallString<32> NameBuf; 488 StringRef Name = sanitizeFilenameAsIdentifier( 489 llvm::sys::path::stem(Header->getName()), 490 NameBuf); 491 Found = lookupModuleQualified(Name, Found); 492 if (!Found) 493 return false; 494 } 495 496 return IsUnavailable(Found); 497 } 498 499 SkippedDirs.push_back(Dir); 500 501 // Retrieve our parent path. 502 DirName = llvm::sys::path::parent_path(DirName); 503 if (DirName.empty()) 504 break; 505 506 // Resolve the parent path to a directory entry. 507 Dir = SourceMgr.getFileManager().getDirectory(DirName); 508 } while (Dir); 509 510 return false; 511 } 512 513 Module *ModuleMap::findModule(StringRef Name) const { 514 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 515 if (Known != Modules.end()) 516 return Known->getValue(); 517 518 return nullptr; 519 } 520 521 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, 522 Module *Context) const { 523 for(; Context; Context = Context->Parent) { 524 if (Module *Sub = lookupModuleQualified(Name, Context)) 525 return Sub; 526 } 527 528 return findModule(Name); 529 } 530 531 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 532 if (!Context) 533 return findModule(Name); 534 535 return Context->findSubmodule(Name); 536 } 537 538 std::pair<Module *, bool> 539 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 540 bool IsExplicit) { 541 // Try to find an existing module with this name. 542 if (Module *Sub = lookupModuleQualified(Name, Parent)) 543 return std::make_pair(Sub, false); 544 545 // Create a new module with this name. 546 Module *Result = new Module(Name, SourceLocation(), Parent, 547 IsFramework, IsExplicit); 548 if (LangOpts.CurrentModule == Name) { 549 SourceModule = Result; 550 SourceModuleName = Name; 551 } 552 if (!Parent) { 553 Modules[Name] = Result; 554 if (!LangOpts.CurrentModule.empty() && !CompilingModule && 555 Name == LangOpts.CurrentModule) { 556 CompilingModule = Result; 557 } 558 } 559 return std::make_pair(Result, true); 560 } 561 562 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 563 StringRef Name, bool &IsSystem) const { 564 // Check whether we have already looked into the parent directory 565 // for a module map. 566 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 567 inferred = InferredDirectories.find(ParentDir); 568 if (inferred == InferredDirectories.end()) 569 return false; 570 571 if (!inferred->second.InferModules) 572 return false; 573 574 // We're allowed to infer for this directory, but make sure it's okay 575 // to infer this particular module. 576 bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 577 inferred->second.ExcludedModules.end(), 578 Name) == inferred->second.ExcludedModules.end(); 579 580 if (canInfer && inferred->second.InferSystemModules) 581 IsSystem = true; 582 583 return canInfer; 584 } 585 586 /// \brief For a framework module, infer the framework against which we 587 /// should link. 588 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 589 FileManager &FileMgr) { 590 assert(Mod->IsFramework && "Can only infer linking for framework modules"); 591 assert(!Mod->isSubFramework() && 592 "Can only infer linking for top-level frameworks"); 593 594 SmallString<128> LibName; 595 LibName += FrameworkDir->getName(); 596 llvm::sys::path::append(LibName, Mod->Name); 597 if (FileMgr.getFile(LibName)) { 598 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 599 /*IsFramework=*/true)); 600 } 601 } 602 603 Module * 604 ModuleMap::inferFrameworkModule(StringRef ModuleName, 605 const DirectoryEntry *FrameworkDir, 606 bool IsSystem, 607 Module *Parent) { 608 // Check whether we've already found this module. 609 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 610 return Mod; 611 612 FileManager &FileMgr = SourceMgr.getFileManager(); 613 614 // If the framework has a parent path from which we're allowed to infer 615 // a framework module, do so. 616 const FileEntry *ModuleMapFile = nullptr; 617 if (!Parent) { 618 // Determine whether we're allowed to infer a module map. 619 620 // Note: as an egregious but useful hack we use the real path here, because 621 // we might be looking at an embedded framework that symlinks out to a 622 // top-level framework, and we need to infer as if we were naming the 623 // top-level framework. 624 StringRef FrameworkDirName 625 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 626 627 // In case this is a case-insensitive filesystem, make sure the canonical 628 // directory name matches ModuleName exactly. Modules are case-sensitive. 629 // FIXME: we should be able to give a fix-it hint for the correct spelling. 630 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName) 631 return nullptr; 632 633 bool canInfer = false; 634 if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 635 // Figure out the parent path. 636 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 637 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 638 // Check whether we have already looked into the parent directory 639 // for a module map. 640 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 641 inferred = InferredDirectories.find(ParentDir); 642 if (inferred == InferredDirectories.end()) { 643 // We haven't looked here before. Load a module map, if there is 644 // one. 645 bool IsFrameworkDir = Parent.endswith(".framework"); 646 if (const FileEntry *ModMapFile = 647 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { 648 parseModuleMapFile(ModMapFile, IsSystem); 649 inferred = InferredDirectories.find(ParentDir); 650 } 651 652 if (inferred == InferredDirectories.end()) 653 inferred = InferredDirectories.insert( 654 std::make_pair(ParentDir, InferredDirectory())).first; 655 } 656 657 if (inferred->second.InferModules) { 658 // We're allowed to infer for this directory, but make sure it's okay 659 // to infer this particular module. 660 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 661 canInfer = std::find(inferred->second.ExcludedModules.begin(), 662 inferred->second.ExcludedModules.end(), 663 Name) == inferred->second.ExcludedModules.end(); 664 665 if (inferred->second.InferSystemModules) 666 IsSystem = true; 667 ModuleMapFile = inferred->second.ModuleMapFile; 668 } 669 } 670 } 671 672 // If we're not allowed to infer a framework module, don't. 673 if (!canInfer) 674 return nullptr; 675 } else 676 ModuleMapFile = getModuleMapFileForUniquing(Parent); 677 678 679 // Look for an umbrella header. 680 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 681 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 682 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 683 684 // FIXME: If there's no umbrella header, we could probably scan the 685 // framework to load *everything*. But, it's not clear that this is a good 686 // idea. 687 if (!UmbrellaHeader) 688 return nullptr; 689 690 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 691 /*IsFramework=*/true, /*IsExplicit=*/false); 692 InferredModuleAllowedBy[Result] = ModuleMapFile; 693 Result->IsInferred = true; 694 if (LangOpts.CurrentModule == ModuleName) { 695 SourceModule = Result; 696 SourceModuleName = ModuleName; 697 } 698 if (IsSystem) 699 Result->IsSystem = IsSystem; 700 701 if (!Parent) 702 Modules[ModuleName] = Result; 703 704 // umbrella header "umbrella-header-name" 705 Result->Umbrella = UmbrellaHeader; 706 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); 707 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 708 709 // export * 710 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 711 712 // module * { export * } 713 Result->InferSubmodules = true; 714 Result->InferExportWildcard = true; 715 716 // Look for subframeworks. 717 std::error_code EC; 718 SmallString<128> SubframeworksDirName 719 = StringRef(FrameworkDir->getName()); 720 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 721 llvm::sys::path::native(SubframeworksDirName); 722 for (llvm::sys::fs::directory_iterator 723 Dir(SubframeworksDirName.str(), EC), DirEnd; 724 Dir != DirEnd && !EC; Dir.increment(EC)) { 725 if (!StringRef(Dir->path()).endswith(".framework")) 726 continue; 727 728 if (const DirectoryEntry *SubframeworkDir 729 = FileMgr.getDirectory(Dir->path())) { 730 // Note: as an egregious but useful hack, we use the real path here and 731 // check whether it is actually a subdirectory of the parent directory. 732 // This will not be the case if the 'subframework' is actually a symlink 733 // out to a top-level framework. 734 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 735 bool FoundParent = false; 736 do { 737 // Get the parent directory name. 738 SubframeworkDirName 739 = llvm::sys::path::parent_path(SubframeworkDirName); 740 if (SubframeworkDirName.empty()) 741 break; 742 743 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 744 FoundParent = true; 745 break; 746 } 747 } while (true); 748 749 if (!FoundParent) 750 continue; 751 752 // FIXME: Do we want to warn about subframeworks without umbrella headers? 753 SmallString<32> NameBuf; 754 inferFrameworkModule(sanitizeFilenameAsIdentifier( 755 llvm::sys::path::stem(Dir->path()), NameBuf), 756 SubframeworkDir, IsSystem, Result); 757 } 758 } 759 760 // If the module is a top-level framework, automatically link against the 761 // framework. 762 if (!Result->isSubFramework()) { 763 inferFrameworkLink(Result, FrameworkDir, FileMgr); 764 } 765 766 return Result; 767 } 768 769 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 770 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 771 Mod->Umbrella = UmbrellaHeader; 772 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 773 } 774 775 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 776 Mod->Umbrella = UmbrellaDir; 777 UmbrellaDirs[UmbrellaDir] = Mod; 778 } 779 780 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 781 ModuleHeaderRole Role) { 782 switch ((int)Role) { 783 default: 784 llvm_unreachable("unknown header role"); 785 case NormalHeader: 786 Mod->NormalHeaders.push_back(Header); 787 break; 788 case PrivateHeader: 789 Mod->PrivateHeaders.push_back(Header); 790 break; 791 case TextualHeader: 792 Mod->TextualHeaders.push_back(Header); 793 break; 794 case PrivateHeader | TextualHeader: 795 Mod->PrivateTextualHeaders.push_back(Header); 796 break; 797 } 798 799 if (!(Role & TextualHeader)) { 800 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 801 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); 802 } 803 Headers[Header].push_back(KnownHeader(Mod, Role)); 804 } 805 806 void ModuleMap::excludeHeader(Module *Mod, const FileEntry *Header) { 807 Mod->ExcludedHeaders.push_back(Header); 808 809 // Add this as a known header so we won't implicitly add it to any 810 // umbrella directory module. 811 // FIXME: Should we only exclude it from umbrella modules within the 812 // specified module? 813 (void) Headers[Header]; 814 } 815 816 const FileEntry * 817 ModuleMap::getContainingModuleMapFile(const Module *Module) const { 818 if (Module->DefinitionLoc.isInvalid()) 819 return nullptr; 820 821 return SourceMgr.getFileEntryForID( 822 SourceMgr.getFileID(Module->DefinitionLoc)); 823 } 824 825 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 826 if (M->IsInferred) { 827 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 828 return InferredModuleAllowedBy.find(M)->second; 829 } 830 return getContainingModuleMapFile(M); 831 } 832 833 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 834 assert(M->IsInferred && "module not inferred"); 835 InferredModuleAllowedBy[M] = ModMap; 836 } 837 838 void ModuleMap::dump() { 839 llvm::errs() << "Modules:"; 840 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 841 MEnd = Modules.end(); 842 M != MEnd; ++M) 843 M->getValue()->print(llvm::errs(), 2); 844 845 llvm::errs() << "Headers:"; 846 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 847 H != HEnd; ++H) { 848 llvm::errs() << " \"" << H->first->getName() << "\" -> "; 849 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 850 E = H->second.end(); 851 I != E; ++I) { 852 if (I != H->second.begin()) 853 llvm::errs() << ","; 854 llvm::errs() << I->getModule()->getFullModuleName(); 855 } 856 llvm::errs() << "\n"; 857 } 858 } 859 860 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 861 bool HadError = false; 862 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 863 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 864 Complain); 865 if (Export.getPointer() || Export.getInt()) 866 Mod->Exports.push_back(Export); 867 else 868 HadError = true; 869 } 870 Mod->UnresolvedExports.clear(); 871 return HadError; 872 } 873 874 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 875 bool HadError = false; 876 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 877 Module *DirectUse = 878 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 879 if (DirectUse) 880 Mod->DirectUses.push_back(DirectUse); 881 else 882 HadError = true; 883 } 884 Mod->UnresolvedDirectUses.clear(); 885 return HadError; 886 } 887 888 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 889 bool HadError = false; 890 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 891 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 892 Mod, Complain); 893 if (!OtherMod) { 894 HadError = true; 895 continue; 896 } 897 898 Module::Conflict Conflict; 899 Conflict.Other = OtherMod; 900 Conflict.Message = Mod->UnresolvedConflicts[I].Message; 901 Mod->Conflicts.push_back(Conflict); 902 } 903 Mod->UnresolvedConflicts.clear(); 904 return HadError; 905 } 906 907 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 908 if (Loc.isInvalid()) 909 return nullptr; 910 911 // Use the expansion location to determine which module we're in. 912 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 913 if (!ExpansionLoc.isFileID()) 914 return nullptr; 915 916 const SourceManager &SrcMgr = Loc.getManager(); 917 FileID ExpansionFileID = ExpansionLoc.getFileID(); 918 919 while (const FileEntry *ExpansionFile 920 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 921 // Find the module that owns this header (if any). 922 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 923 return Mod; 924 925 // No module owns this header, so look up the inclusion chain to see if 926 // any included header has an associated module. 927 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 928 if (IncludeLoc.isInvalid()) 929 return nullptr; 930 931 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 932 } 933 934 return nullptr; 935 } 936 937 //----------------------------------------------------------------------------// 938 // Module map file parser 939 //----------------------------------------------------------------------------// 940 941 namespace clang { 942 /// \brief A token in a module map file. 943 struct MMToken { 944 enum TokenKind { 945 Comma, 946 ConfigMacros, 947 Conflict, 948 EndOfFile, 949 HeaderKeyword, 950 Identifier, 951 Exclaim, 952 ExcludeKeyword, 953 ExplicitKeyword, 954 ExportKeyword, 955 ExternKeyword, 956 FrameworkKeyword, 957 LinkKeyword, 958 ModuleKeyword, 959 Period, 960 PrivateKeyword, 961 UmbrellaKeyword, 962 UseKeyword, 963 RequiresKeyword, 964 Star, 965 StringLiteral, 966 TextualKeyword, 967 LBrace, 968 RBrace, 969 LSquare, 970 RSquare 971 } Kind; 972 973 unsigned Location; 974 unsigned StringLength; 975 const char *StringData; 976 977 void clear() { 978 Kind = EndOfFile; 979 Location = 0; 980 StringLength = 0; 981 StringData = nullptr; 982 } 983 984 bool is(TokenKind K) const { return Kind == K; } 985 986 SourceLocation getLocation() const { 987 return SourceLocation::getFromRawEncoding(Location); 988 } 989 990 StringRef getString() const { 991 return StringRef(StringData, StringLength); 992 } 993 }; 994 995 /// \brief The set of attributes that can be attached to a module. 996 struct Attributes { 997 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { } 998 999 /// \brief Whether this is a system module. 1000 unsigned IsSystem : 1; 1001 1002 /// \brief Whether this is an extern "C" module. 1003 unsigned IsExternC : 1; 1004 1005 /// \brief Whether this is an exhaustive set of configuration macros. 1006 unsigned IsExhaustive : 1; 1007 }; 1008 1009 1010 class ModuleMapParser { 1011 Lexer &L; 1012 SourceManager &SourceMgr; 1013 1014 /// \brief Default target information, used only for string literal 1015 /// parsing. 1016 const TargetInfo *Target; 1017 1018 DiagnosticsEngine &Diags; 1019 ModuleMap ⤅ 1020 1021 /// \brief The current module map file. 1022 const FileEntry *ModuleMapFile; 1023 1024 /// \brief The directory that this module map resides in. 1025 const DirectoryEntry *Directory; 1026 1027 /// \brief The directory containing Clang-supplied headers. 1028 const DirectoryEntry *BuiltinIncludeDir; 1029 1030 /// \brief Whether this module map is in a system header directory. 1031 bool IsSystem; 1032 1033 /// \brief Whether an error occurred. 1034 bool HadError; 1035 1036 /// \brief Stores string data for the various string literals referenced 1037 /// during parsing. 1038 llvm::BumpPtrAllocator StringData; 1039 1040 /// \brief The current token. 1041 MMToken Tok; 1042 1043 /// \brief The active module. 1044 Module *ActiveModule; 1045 1046 /// \brief Consume the current token and return its location. 1047 SourceLocation consumeToken(); 1048 1049 /// \brief Skip tokens until we reach the a token with the given kind 1050 /// (or the end of the file). 1051 void skipUntil(MMToken::TokenKind K); 1052 1053 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1054 bool parseModuleId(ModuleId &Id); 1055 void parseModuleDecl(); 1056 void parseExternModuleDecl(); 1057 void parseRequiresDecl(); 1058 void parseHeaderDecl(clang::MMToken::TokenKind, 1059 SourceLocation LeadingLoc); 1060 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1061 void parseExportDecl(); 1062 void parseUseDecl(); 1063 void parseLinkDecl(); 1064 void parseConfigMacros(); 1065 void parseConflict(); 1066 void parseInferredModuleDecl(bool Framework, bool Explicit); 1067 bool parseOptionalAttributes(Attributes &Attrs); 1068 1069 public: 1070 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1071 const TargetInfo *Target, 1072 DiagnosticsEngine &Diags, 1073 ModuleMap &Map, 1074 const FileEntry *ModuleMapFile, 1075 const DirectoryEntry *Directory, 1076 const DirectoryEntry *BuiltinIncludeDir, 1077 bool IsSystem) 1078 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1079 ModuleMapFile(ModuleMapFile), Directory(Directory), 1080 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem), 1081 HadError(false), ActiveModule(nullptr) 1082 { 1083 Tok.clear(); 1084 consumeToken(); 1085 } 1086 1087 bool parseModuleMapFile(); 1088 }; 1089 } 1090 1091 SourceLocation ModuleMapParser::consumeToken() { 1092 retry: 1093 SourceLocation Result = Tok.getLocation(); 1094 Tok.clear(); 1095 1096 Token LToken; 1097 L.LexFromRawLexer(LToken); 1098 Tok.Location = LToken.getLocation().getRawEncoding(); 1099 switch (LToken.getKind()) { 1100 case tok::raw_identifier: { 1101 StringRef RI = LToken.getRawIdentifier(); 1102 Tok.StringData = RI.data(); 1103 Tok.StringLength = RI.size(); 1104 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1105 .Case("config_macros", MMToken::ConfigMacros) 1106 .Case("conflict", MMToken::Conflict) 1107 .Case("exclude", MMToken::ExcludeKeyword) 1108 .Case("explicit", MMToken::ExplicitKeyword) 1109 .Case("export", MMToken::ExportKeyword) 1110 .Case("extern", MMToken::ExternKeyword) 1111 .Case("framework", MMToken::FrameworkKeyword) 1112 .Case("header", MMToken::HeaderKeyword) 1113 .Case("link", MMToken::LinkKeyword) 1114 .Case("module", MMToken::ModuleKeyword) 1115 .Case("private", MMToken::PrivateKeyword) 1116 .Case("requires", MMToken::RequiresKeyword) 1117 .Case("textual", MMToken::TextualKeyword) 1118 .Case("umbrella", MMToken::UmbrellaKeyword) 1119 .Case("use", MMToken::UseKeyword) 1120 .Default(MMToken::Identifier); 1121 break; 1122 } 1123 1124 case tok::comma: 1125 Tok.Kind = MMToken::Comma; 1126 break; 1127 1128 case tok::eof: 1129 Tok.Kind = MMToken::EndOfFile; 1130 break; 1131 1132 case tok::l_brace: 1133 Tok.Kind = MMToken::LBrace; 1134 break; 1135 1136 case tok::l_square: 1137 Tok.Kind = MMToken::LSquare; 1138 break; 1139 1140 case tok::period: 1141 Tok.Kind = MMToken::Period; 1142 break; 1143 1144 case tok::r_brace: 1145 Tok.Kind = MMToken::RBrace; 1146 break; 1147 1148 case tok::r_square: 1149 Tok.Kind = MMToken::RSquare; 1150 break; 1151 1152 case tok::star: 1153 Tok.Kind = MMToken::Star; 1154 break; 1155 1156 case tok::exclaim: 1157 Tok.Kind = MMToken::Exclaim; 1158 break; 1159 1160 case tok::string_literal: { 1161 if (LToken.hasUDSuffix()) { 1162 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1163 HadError = true; 1164 goto retry; 1165 } 1166 1167 // Parse the string literal. 1168 LangOptions LangOpts; 1169 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1170 if (StringLiteral.hadError) 1171 goto retry; 1172 1173 // Copy the string literal into our string data allocator. 1174 unsigned Length = StringLiteral.GetStringLength(); 1175 char *Saved = StringData.Allocate<char>(Length + 1); 1176 memcpy(Saved, StringLiteral.GetString().data(), Length); 1177 Saved[Length] = 0; 1178 1179 // Form the token. 1180 Tok.Kind = MMToken::StringLiteral; 1181 Tok.StringData = Saved; 1182 Tok.StringLength = Length; 1183 break; 1184 } 1185 1186 case tok::comment: 1187 goto retry; 1188 1189 default: 1190 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1191 HadError = true; 1192 goto retry; 1193 } 1194 1195 return Result; 1196 } 1197 1198 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1199 unsigned braceDepth = 0; 1200 unsigned squareDepth = 0; 1201 do { 1202 switch (Tok.Kind) { 1203 case MMToken::EndOfFile: 1204 return; 1205 1206 case MMToken::LBrace: 1207 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1208 return; 1209 1210 ++braceDepth; 1211 break; 1212 1213 case MMToken::LSquare: 1214 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1215 return; 1216 1217 ++squareDepth; 1218 break; 1219 1220 case MMToken::RBrace: 1221 if (braceDepth > 0) 1222 --braceDepth; 1223 else if (Tok.is(K)) 1224 return; 1225 break; 1226 1227 case MMToken::RSquare: 1228 if (squareDepth > 0) 1229 --squareDepth; 1230 else if (Tok.is(K)) 1231 return; 1232 break; 1233 1234 default: 1235 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1236 return; 1237 break; 1238 } 1239 1240 consumeToken(); 1241 } while (true); 1242 } 1243 1244 /// \brief Parse a module-id. 1245 /// 1246 /// module-id: 1247 /// identifier 1248 /// identifier '.' module-id 1249 /// 1250 /// \returns true if an error occurred, false otherwise. 1251 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1252 Id.clear(); 1253 do { 1254 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1255 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1256 consumeToken(); 1257 } else { 1258 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1259 return true; 1260 } 1261 1262 if (!Tok.is(MMToken::Period)) 1263 break; 1264 1265 consumeToken(); 1266 } while (true); 1267 1268 return false; 1269 } 1270 1271 namespace { 1272 /// \brief Enumerates the known attributes. 1273 enum AttributeKind { 1274 /// \brief An unknown attribute. 1275 AT_unknown, 1276 /// \brief The 'system' attribute. 1277 AT_system, 1278 /// \brief The 'extern_c' attribute. 1279 AT_extern_c, 1280 /// \brief The 'exhaustive' attribute. 1281 AT_exhaustive 1282 }; 1283 } 1284 1285 /// \brief Parse a module declaration. 1286 /// 1287 /// module-declaration: 1288 /// 'extern' 'module' module-id string-literal 1289 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1290 /// { module-member* } 1291 /// 1292 /// module-member: 1293 /// requires-declaration 1294 /// header-declaration 1295 /// submodule-declaration 1296 /// export-declaration 1297 /// link-declaration 1298 /// 1299 /// submodule-declaration: 1300 /// module-declaration 1301 /// inferred-submodule-declaration 1302 void ModuleMapParser::parseModuleDecl() { 1303 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1304 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1305 if (Tok.is(MMToken::ExternKeyword)) { 1306 parseExternModuleDecl(); 1307 return; 1308 } 1309 1310 // Parse 'explicit' or 'framework' keyword, if present. 1311 SourceLocation ExplicitLoc; 1312 bool Explicit = false; 1313 bool Framework = false; 1314 1315 // Parse 'explicit' keyword, if present. 1316 if (Tok.is(MMToken::ExplicitKeyword)) { 1317 ExplicitLoc = consumeToken(); 1318 Explicit = true; 1319 } 1320 1321 // Parse 'framework' keyword, if present. 1322 if (Tok.is(MMToken::FrameworkKeyword)) { 1323 consumeToken(); 1324 Framework = true; 1325 } 1326 1327 // Parse 'module' keyword. 1328 if (!Tok.is(MMToken::ModuleKeyword)) { 1329 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1330 consumeToken(); 1331 HadError = true; 1332 return; 1333 } 1334 consumeToken(); // 'module' keyword 1335 1336 // If we have a wildcard for the module name, this is an inferred submodule. 1337 // Parse it. 1338 if (Tok.is(MMToken::Star)) 1339 return parseInferredModuleDecl(Framework, Explicit); 1340 1341 // Parse the module name. 1342 ModuleId Id; 1343 if (parseModuleId(Id)) { 1344 HadError = true; 1345 return; 1346 } 1347 1348 if (ActiveModule) { 1349 if (Id.size() > 1) { 1350 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1351 << SourceRange(Id.front().second, Id.back().second); 1352 1353 HadError = true; 1354 return; 1355 } 1356 } else if (Id.size() == 1 && Explicit) { 1357 // Top-level modules can't be explicit. 1358 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1359 Explicit = false; 1360 ExplicitLoc = SourceLocation(); 1361 HadError = true; 1362 } 1363 1364 Module *PreviousActiveModule = ActiveModule; 1365 if (Id.size() > 1) { 1366 // This module map defines a submodule. Go find the module of which it 1367 // is a submodule. 1368 ActiveModule = nullptr; 1369 const Module *TopLevelModule = nullptr; 1370 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1371 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1372 if (I == 0) 1373 TopLevelModule = Next; 1374 ActiveModule = Next; 1375 continue; 1376 } 1377 1378 if (ActiveModule) { 1379 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1380 << Id[I].first 1381 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1382 } else { 1383 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1384 } 1385 HadError = true; 1386 return; 1387 } 1388 1389 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1390 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1391 "submodule defined in same file as 'module *' that allowed its " 1392 "top-level module"); 1393 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1394 } 1395 } 1396 1397 StringRef ModuleName = Id.back().first; 1398 SourceLocation ModuleNameLoc = Id.back().second; 1399 1400 // Parse the optional attribute list. 1401 Attributes Attrs; 1402 parseOptionalAttributes(Attrs); 1403 1404 // Parse the opening brace. 1405 if (!Tok.is(MMToken::LBrace)) { 1406 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1407 << ModuleName; 1408 HadError = true; 1409 return; 1410 } 1411 SourceLocation LBraceLoc = consumeToken(); 1412 1413 // Determine whether this (sub)module has already been defined. 1414 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1415 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1416 // Skip the module definition. 1417 skipUntil(MMToken::RBrace); 1418 if (Tok.is(MMToken::RBrace)) 1419 consumeToken(); 1420 else { 1421 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1422 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1423 HadError = true; 1424 } 1425 return; 1426 } 1427 1428 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1429 << ModuleName; 1430 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1431 1432 // Skip the module definition. 1433 skipUntil(MMToken::RBrace); 1434 if (Tok.is(MMToken::RBrace)) 1435 consumeToken(); 1436 1437 HadError = true; 1438 return; 1439 } 1440 1441 // Start defining this module. 1442 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1443 Explicit).first; 1444 ActiveModule->DefinitionLoc = ModuleNameLoc; 1445 if (Attrs.IsSystem || IsSystem) 1446 ActiveModule->IsSystem = true; 1447 if (Attrs.IsExternC) 1448 ActiveModule->IsExternC = true; 1449 1450 bool Done = false; 1451 do { 1452 switch (Tok.Kind) { 1453 case MMToken::EndOfFile: 1454 case MMToken::RBrace: 1455 Done = true; 1456 break; 1457 1458 case MMToken::ConfigMacros: 1459 parseConfigMacros(); 1460 break; 1461 1462 case MMToken::Conflict: 1463 parseConflict(); 1464 break; 1465 1466 case MMToken::ExplicitKeyword: 1467 case MMToken::ExternKeyword: 1468 case MMToken::FrameworkKeyword: 1469 case MMToken::ModuleKeyword: 1470 parseModuleDecl(); 1471 break; 1472 1473 case MMToken::ExportKeyword: 1474 parseExportDecl(); 1475 break; 1476 1477 case MMToken::UseKeyword: 1478 parseUseDecl(); 1479 break; 1480 1481 case MMToken::RequiresKeyword: 1482 parseRequiresDecl(); 1483 break; 1484 1485 case MMToken::TextualKeyword: 1486 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1487 break; 1488 1489 case MMToken::UmbrellaKeyword: { 1490 SourceLocation UmbrellaLoc = consumeToken(); 1491 if (Tok.is(MMToken::HeaderKeyword)) 1492 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1493 else 1494 parseUmbrellaDirDecl(UmbrellaLoc); 1495 break; 1496 } 1497 1498 case MMToken::ExcludeKeyword: 1499 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1500 break; 1501 1502 case MMToken::PrivateKeyword: 1503 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1504 break; 1505 1506 case MMToken::HeaderKeyword: 1507 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1508 break; 1509 1510 case MMToken::LinkKeyword: 1511 parseLinkDecl(); 1512 break; 1513 1514 default: 1515 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1516 consumeToken(); 1517 break; 1518 } 1519 } while (!Done); 1520 1521 if (Tok.is(MMToken::RBrace)) 1522 consumeToken(); 1523 else { 1524 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1525 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1526 HadError = true; 1527 } 1528 1529 // If the active module is a top-level framework, and there are no link 1530 // libraries, automatically link against the framework. 1531 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1532 ActiveModule->LinkLibraries.empty()) { 1533 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1534 } 1535 1536 // If the module meets all requirements but is still unavailable, mark the 1537 // whole tree as unavailable to prevent it from building. 1538 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1539 ActiveModule->Parent) { 1540 ActiveModule->getTopLevelModule()->markUnavailable(); 1541 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1542 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1543 } 1544 1545 // We're done parsing this module. Pop back to the previous module. 1546 ActiveModule = PreviousActiveModule; 1547 } 1548 1549 /// \brief Parse an extern module declaration. 1550 /// 1551 /// extern module-declaration: 1552 /// 'extern' 'module' module-id string-literal 1553 void ModuleMapParser::parseExternModuleDecl() { 1554 assert(Tok.is(MMToken::ExternKeyword)); 1555 consumeToken(); // 'extern' keyword 1556 1557 // Parse 'module' keyword. 1558 if (!Tok.is(MMToken::ModuleKeyword)) { 1559 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1560 consumeToken(); 1561 HadError = true; 1562 return; 1563 } 1564 consumeToken(); // 'module' keyword 1565 1566 // Parse the module name. 1567 ModuleId Id; 1568 if (parseModuleId(Id)) { 1569 HadError = true; 1570 return; 1571 } 1572 1573 // Parse the referenced module map file name. 1574 if (!Tok.is(MMToken::StringLiteral)) { 1575 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1576 HadError = true; 1577 return; 1578 } 1579 std::string FileName = Tok.getString(); 1580 consumeToken(); // filename 1581 1582 StringRef FileNameRef = FileName; 1583 SmallString<128> ModuleMapFileName; 1584 if (llvm::sys::path::is_relative(FileNameRef)) { 1585 ModuleMapFileName += Directory->getName(); 1586 llvm::sys::path::append(ModuleMapFileName, FileName); 1587 FileNameRef = ModuleMapFileName.str(); 1588 } 1589 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1590 Map.parseModuleMapFile(File, /*IsSystem=*/false); 1591 } 1592 1593 /// \brief Parse a requires declaration. 1594 /// 1595 /// requires-declaration: 1596 /// 'requires' feature-list 1597 /// 1598 /// feature-list: 1599 /// feature ',' feature-list 1600 /// feature 1601 /// 1602 /// feature: 1603 /// '!'[opt] identifier 1604 void ModuleMapParser::parseRequiresDecl() { 1605 assert(Tok.is(MMToken::RequiresKeyword)); 1606 1607 // Parse 'requires' keyword. 1608 consumeToken(); 1609 1610 // Parse the feature-list. 1611 do { 1612 bool RequiredState = true; 1613 if (Tok.is(MMToken::Exclaim)) { 1614 RequiredState = false; 1615 consumeToken(); 1616 } 1617 1618 if (!Tok.is(MMToken::Identifier)) { 1619 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1620 HadError = true; 1621 return; 1622 } 1623 1624 // Consume the feature name. 1625 std::string Feature = Tok.getString(); 1626 consumeToken(); 1627 1628 // Add this feature. 1629 ActiveModule->addRequirement(Feature, RequiredState, 1630 Map.LangOpts, *Map.Target); 1631 1632 if (!Tok.is(MMToken::Comma)) 1633 break; 1634 1635 // Consume the comma. 1636 consumeToken(); 1637 } while (true); 1638 } 1639 1640 /// \brief Append to \p Paths the set of paths needed to get to the 1641 /// subframework in which the given module lives. 1642 static void appendSubframeworkPaths(Module *Mod, 1643 SmallVectorImpl<char> &Path) { 1644 // Collect the framework names from the given module to the top-level module. 1645 SmallVector<StringRef, 2> Paths; 1646 for (; Mod; Mod = Mod->Parent) { 1647 if (Mod->IsFramework) 1648 Paths.push_back(Mod->Name); 1649 } 1650 1651 if (Paths.empty()) 1652 return; 1653 1654 // Add Frameworks/Name.framework for each subframework. 1655 for (unsigned I = Paths.size() - 1; I != 0; --I) 1656 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1657 } 1658 1659 /// \brief Parse a header declaration. 1660 /// 1661 /// header-declaration: 1662 /// 'textual'[opt] 'header' string-literal 1663 /// 'private' 'textual'[opt] 'header' string-literal 1664 /// 'exclude' 'header' string-literal 1665 /// 'umbrella' 'header' string-literal 1666 /// 1667 /// FIXME: Support 'private textual header'. 1668 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1669 SourceLocation LeadingLoc) { 1670 // We've already consumed the first token. 1671 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1672 if (LeadingToken == MMToken::PrivateKeyword) { 1673 Role = ModuleMap::PrivateHeader; 1674 // 'private' may optionally be followed by 'textual'. 1675 if (Tok.is(MMToken::TextualKeyword)) { 1676 LeadingToken = Tok.Kind; 1677 consumeToken(); 1678 } 1679 } 1680 if (LeadingToken == MMToken::TextualKeyword) 1681 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1682 1683 if (LeadingToken != MMToken::HeaderKeyword) { 1684 if (!Tok.is(MMToken::HeaderKeyword)) { 1685 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1686 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 1687 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 1688 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 1689 return; 1690 } 1691 consumeToken(); 1692 } 1693 1694 // Parse the header name. 1695 if (!Tok.is(MMToken::StringLiteral)) { 1696 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1697 << "header"; 1698 HadError = true; 1699 return; 1700 } 1701 Module::HeaderDirective Header; 1702 Header.FileName = Tok.getString(); 1703 Header.FileNameLoc = consumeToken(); 1704 1705 // Check whether we already have an umbrella. 1706 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1707 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 1708 << ActiveModule->getFullModuleName(); 1709 HadError = true; 1710 return; 1711 } 1712 1713 // Look for this file. 1714 const FileEntry *File = nullptr; 1715 const FileEntry *BuiltinFile = nullptr; 1716 SmallString<128> PathName; 1717 if (llvm::sys::path::is_absolute(Header.FileName)) { 1718 PathName = Header.FileName; 1719 File = SourceMgr.getFileManager().getFile(PathName); 1720 } else { 1721 // Search for the header file within the search directory. 1722 PathName = Directory->getName(); 1723 unsigned PathLength = PathName.size(); 1724 1725 if (ActiveModule->isPartOfFramework()) { 1726 appendSubframeworkPaths(ActiveModule, PathName); 1727 1728 // Check whether this file is in the public headers. 1729 llvm::sys::path::append(PathName, "Headers", Header.FileName); 1730 File = SourceMgr.getFileManager().getFile(PathName); 1731 1732 if (!File) { 1733 // Check whether this file is in the private headers. 1734 PathName.resize(PathLength); 1735 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName); 1736 File = SourceMgr.getFileManager().getFile(PathName); 1737 } 1738 } else { 1739 // Lookup for normal headers. 1740 llvm::sys::path::append(PathName, Header.FileName); 1741 File = SourceMgr.getFileManager().getFile(PathName); 1742 1743 // If this is a system module with a top-level header, this header 1744 // may have a counterpart (or replacement) in the set of headers 1745 // supplied by Clang. Find that builtin header. 1746 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1747 BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1748 isBuiltinHeader(Header.FileName)) { 1749 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1750 llvm::sys::path::append(BuiltinPathName, Header.FileName); 1751 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1752 1753 // If Clang supplies this header but the underlying system does not, 1754 // just silently swap in our builtin version. Otherwise, we'll end 1755 // up adding both (later). 1756 if (!File && BuiltinFile) { 1757 File = BuiltinFile; 1758 BuiltinFile = nullptr; 1759 } 1760 } 1761 } 1762 } 1763 1764 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1765 // Come up with a lazy way to do this. 1766 if (File) { 1767 if (LeadingToken == MMToken::UmbrellaKeyword) { 1768 const DirectoryEntry *UmbrellaDir = File->getDir(); 1769 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1770 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 1771 << UmbrellaModule->getFullModuleName(); 1772 HadError = true; 1773 } else { 1774 // Record this umbrella header. 1775 Map.setUmbrellaHeader(ActiveModule, File); 1776 } 1777 } else if (LeadingToken == MMToken::ExcludeKeyword) { 1778 Map.excludeHeader(ActiveModule, File); 1779 } else { 1780 // If there is a builtin counterpart to this file, add it now, before 1781 // the "real" header, so we build the built-in one first when building 1782 // the module. 1783 if (BuiltinFile) 1784 Map.addHeader(ActiveModule, BuiltinFile, Role); 1785 1786 // Record this header. 1787 Map.addHeader(ActiveModule, File, Role); 1788 } 1789 } else if (LeadingToken != MMToken::ExcludeKeyword) { 1790 // Ignore excluded header files. They're optional anyway. 1791 1792 // If we find a module that has a missing header, we mark this module as 1793 // unavailable and store the header directive for displaying diagnostics. 1794 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 1795 ActiveModule->markUnavailable(); 1796 ActiveModule->MissingHeaders.push_back(Header); 1797 } 1798 } 1799 1800 /// \brief Parse an umbrella directory declaration. 1801 /// 1802 /// umbrella-dir-declaration: 1803 /// umbrella string-literal 1804 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1805 // Parse the directory name. 1806 if (!Tok.is(MMToken::StringLiteral)) { 1807 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1808 << "umbrella"; 1809 HadError = true; 1810 return; 1811 } 1812 1813 std::string DirName = Tok.getString(); 1814 SourceLocation DirNameLoc = consumeToken(); 1815 1816 // Check whether we already have an umbrella. 1817 if (ActiveModule->Umbrella) { 1818 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1819 << ActiveModule->getFullModuleName(); 1820 HadError = true; 1821 return; 1822 } 1823 1824 // Look for this file. 1825 const DirectoryEntry *Dir = nullptr; 1826 if (llvm::sys::path::is_absolute(DirName)) 1827 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1828 else { 1829 SmallString<128> PathName; 1830 PathName = Directory->getName(); 1831 llvm::sys::path::append(PathName, DirName); 1832 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1833 } 1834 1835 if (!Dir) { 1836 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1837 << DirName; 1838 HadError = true; 1839 return; 1840 } 1841 1842 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1843 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1844 << OwningModule->getFullModuleName(); 1845 HadError = true; 1846 return; 1847 } 1848 1849 // Record this umbrella directory. 1850 Map.setUmbrellaDir(ActiveModule, Dir); 1851 } 1852 1853 /// \brief Parse a module export declaration. 1854 /// 1855 /// export-declaration: 1856 /// 'export' wildcard-module-id 1857 /// 1858 /// wildcard-module-id: 1859 /// identifier 1860 /// '*' 1861 /// identifier '.' wildcard-module-id 1862 void ModuleMapParser::parseExportDecl() { 1863 assert(Tok.is(MMToken::ExportKeyword)); 1864 SourceLocation ExportLoc = consumeToken(); 1865 1866 // Parse the module-id with an optional wildcard at the end. 1867 ModuleId ParsedModuleId; 1868 bool Wildcard = false; 1869 do { 1870 // FIXME: Support string-literal module names here. 1871 if (Tok.is(MMToken::Identifier)) { 1872 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1873 Tok.getLocation())); 1874 consumeToken(); 1875 1876 if (Tok.is(MMToken::Period)) { 1877 consumeToken(); 1878 continue; 1879 } 1880 1881 break; 1882 } 1883 1884 if(Tok.is(MMToken::Star)) { 1885 Wildcard = true; 1886 consumeToken(); 1887 break; 1888 } 1889 1890 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 1891 HadError = true; 1892 return; 1893 } while (true); 1894 1895 Module::UnresolvedExportDecl Unresolved = { 1896 ExportLoc, ParsedModuleId, Wildcard 1897 }; 1898 ActiveModule->UnresolvedExports.push_back(Unresolved); 1899 } 1900 1901 /// \brief Parse a module uses declaration. 1902 /// 1903 /// uses-declaration: 1904 /// 'uses' wildcard-module-id 1905 void ModuleMapParser::parseUseDecl() { 1906 assert(Tok.is(MMToken::UseKeyword)); 1907 consumeToken(); 1908 // Parse the module-id. 1909 ModuleId ParsedModuleId; 1910 parseModuleId(ParsedModuleId); 1911 1912 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1913 } 1914 1915 /// \brief Parse a link declaration. 1916 /// 1917 /// module-declaration: 1918 /// 'link' 'framework'[opt] string-literal 1919 void ModuleMapParser::parseLinkDecl() { 1920 assert(Tok.is(MMToken::LinkKeyword)); 1921 SourceLocation LinkLoc = consumeToken(); 1922 1923 // Parse the optional 'framework' keyword. 1924 bool IsFramework = false; 1925 if (Tok.is(MMToken::FrameworkKeyword)) { 1926 consumeToken(); 1927 IsFramework = true; 1928 } 1929 1930 // Parse the library name 1931 if (!Tok.is(MMToken::StringLiteral)) { 1932 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1933 << IsFramework << SourceRange(LinkLoc); 1934 HadError = true; 1935 return; 1936 } 1937 1938 std::string LibraryName = Tok.getString(); 1939 consumeToken(); 1940 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1941 IsFramework)); 1942 } 1943 1944 /// \brief Parse a configuration macro declaration. 1945 /// 1946 /// module-declaration: 1947 /// 'config_macros' attributes[opt] config-macro-list? 1948 /// 1949 /// config-macro-list: 1950 /// identifier (',' identifier)? 1951 void ModuleMapParser::parseConfigMacros() { 1952 assert(Tok.is(MMToken::ConfigMacros)); 1953 SourceLocation ConfigMacrosLoc = consumeToken(); 1954 1955 // Only top-level modules can have configuration macros. 1956 if (ActiveModule->Parent) { 1957 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 1958 } 1959 1960 // Parse the optional attributes. 1961 Attributes Attrs; 1962 parseOptionalAttributes(Attrs); 1963 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 1964 ActiveModule->ConfigMacrosExhaustive = true; 1965 } 1966 1967 // If we don't have an identifier, we're done. 1968 // FIXME: Support macros with the same name as a keyword here. 1969 if (!Tok.is(MMToken::Identifier)) 1970 return; 1971 1972 // Consume the first identifier. 1973 if (!ActiveModule->Parent) { 1974 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1975 } 1976 consumeToken(); 1977 1978 do { 1979 // If there's a comma, consume it. 1980 if (!Tok.is(MMToken::Comma)) 1981 break; 1982 consumeToken(); 1983 1984 // We expect to see a macro name here. 1985 // FIXME: Support macros with the same name as a keyword here. 1986 if (!Tok.is(MMToken::Identifier)) { 1987 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 1988 break; 1989 } 1990 1991 // Consume the macro name. 1992 if (!ActiveModule->Parent) { 1993 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1994 } 1995 consumeToken(); 1996 } while (true); 1997 } 1998 1999 /// \brief Format a module-id into a string. 2000 static std::string formatModuleId(const ModuleId &Id) { 2001 std::string result; 2002 { 2003 llvm::raw_string_ostream OS(result); 2004 2005 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2006 if (I) 2007 OS << "."; 2008 OS << Id[I].first; 2009 } 2010 } 2011 2012 return result; 2013 } 2014 2015 /// \brief Parse a conflict declaration. 2016 /// 2017 /// module-declaration: 2018 /// 'conflict' module-id ',' string-literal 2019 void ModuleMapParser::parseConflict() { 2020 assert(Tok.is(MMToken::Conflict)); 2021 SourceLocation ConflictLoc = consumeToken(); 2022 Module::UnresolvedConflict Conflict; 2023 2024 // Parse the module-id. 2025 if (parseModuleId(Conflict.Id)) 2026 return; 2027 2028 // Parse the ','. 2029 if (!Tok.is(MMToken::Comma)) { 2030 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2031 << SourceRange(ConflictLoc); 2032 return; 2033 } 2034 consumeToken(); 2035 2036 // Parse the message. 2037 if (!Tok.is(MMToken::StringLiteral)) { 2038 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2039 << formatModuleId(Conflict.Id); 2040 return; 2041 } 2042 Conflict.Message = Tok.getString().str(); 2043 consumeToken(); 2044 2045 // Add this unresolved conflict. 2046 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2047 } 2048 2049 /// \brief Parse an inferred module declaration (wildcard modules). 2050 /// 2051 /// module-declaration: 2052 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2053 /// { inferred-module-member* } 2054 /// 2055 /// inferred-module-member: 2056 /// 'export' '*' 2057 /// 'exclude' identifier 2058 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2059 assert(Tok.is(MMToken::Star)); 2060 SourceLocation StarLoc = consumeToken(); 2061 bool Failed = false; 2062 2063 // Inferred modules must be submodules. 2064 if (!ActiveModule && !Framework) { 2065 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2066 Failed = true; 2067 } 2068 2069 if (ActiveModule) { 2070 // Inferred modules must have umbrella directories. 2071 if (!Failed && ActiveModule->IsAvailable && 2072 !ActiveModule->getUmbrellaDir()) { 2073 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2074 Failed = true; 2075 } 2076 2077 // Check for redefinition of an inferred module. 2078 if (!Failed && ActiveModule->InferSubmodules) { 2079 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2080 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2081 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2082 diag::note_mmap_prev_definition); 2083 Failed = true; 2084 } 2085 2086 // Check for the 'framework' keyword, which is not permitted here. 2087 if (Framework) { 2088 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2089 Framework = false; 2090 } 2091 } else if (Explicit) { 2092 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2093 Explicit = false; 2094 } 2095 2096 // If there were any problems with this inferred submodule, skip its body. 2097 if (Failed) { 2098 if (Tok.is(MMToken::LBrace)) { 2099 consumeToken(); 2100 skipUntil(MMToken::RBrace); 2101 if (Tok.is(MMToken::RBrace)) 2102 consumeToken(); 2103 } 2104 HadError = true; 2105 return; 2106 } 2107 2108 // Parse optional attributes. 2109 Attributes Attrs; 2110 parseOptionalAttributes(Attrs); 2111 2112 if (ActiveModule) { 2113 // Note that we have an inferred submodule. 2114 ActiveModule->InferSubmodules = true; 2115 ActiveModule->InferredSubmoduleLoc = StarLoc; 2116 ActiveModule->InferExplicitSubmodules = Explicit; 2117 } else { 2118 // We'll be inferring framework modules for this directory. 2119 Map.InferredDirectories[Directory].InferModules = true; 2120 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 2121 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2122 // FIXME: Handle the 'framework' keyword. 2123 } 2124 2125 // Parse the opening brace. 2126 if (!Tok.is(MMToken::LBrace)) { 2127 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2128 HadError = true; 2129 return; 2130 } 2131 SourceLocation LBraceLoc = consumeToken(); 2132 2133 // Parse the body of the inferred submodule. 2134 bool Done = false; 2135 do { 2136 switch (Tok.Kind) { 2137 case MMToken::EndOfFile: 2138 case MMToken::RBrace: 2139 Done = true; 2140 break; 2141 2142 case MMToken::ExcludeKeyword: { 2143 if (ActiveModule) { 2144 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2145 << (ActiveModule != nullptr); 2146 consumeToken(); 2147 break; 2148 } 2149 2150 consumeToken(); 2151 // FIXME: Support string-literal module names here. 2152 if (!Tok.is(MMToken::Identifier)) { 2153 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2154 break; 2155 } 2156 2157 Map.InferredDirectories[Directory].ExcludedModules 2158 .push_back(Tok.getString()); 2159 consumeToken(); 2160 break; 2161 } 2162 2163 case MMToken::ExportKeyword: 2164 if (!ActiveModule) { 2165 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2166 << (ActiveModule != nullptr); 2167 consumeToken(); 2168 break; 2169 } 2170 2171 consumeToken(); 2172 if (Tok.is(MMToken::Star)) 2173 ActiveModule->InferExportWildcard = true; 2174 else 2175 Diags.Report(Tok.getLocation(), 2176 diag::err_mmap_expected_export_wildcard); 2177 consumeToken(); 2178 break; 2179 2180 case MMToken::ExplicitKeyword: 2181 case MMToken::ModuleKeyword: 2182 case MMToken::HeaderKeyword: 2183 case MMToken::PrivateKeyword: 2184 case MMToken::UmbrellaKeyword: 2185 default: 2186 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2187 << (ActiveModule != nullptr); 2188 consumeToken(); 2189 break; 2190 } 2191 } while (!Done); 2192 2193 if (Tok.is(MMToken::RBrace)) 2194 consumeToken(); 2195 else { 2196 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2197 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2198 HadError = true; 2199 } 2200 } 2201 2202 /// \brief Parse optional attributes. 2203 /// 2204 /// attributes: 2205 /// attribute attributes 2206 /// attribute 2207 /// 2208 /// attribute: 2209 /// [ identifier ] 2210 /// 2211 /// \param Attrs Will be filled in with the parsed attributes. 2212 /// 2213 /// \returns true if an error occurred, false otherwise. 2214 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2215 bool HadError = false; 2216 2217 while (Tok.is(MMToken::LSquare)) { 2218 // Consume the '['. 2219 SourceLocation LSquareLoc = consumeToken(); 2220 2221 // Check whether we have an attribute name here. 2222 if (!Tok.is(MMToken::Identifier)) { 2223 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2224 skipUntil(MMToken::RSquare); 2225 if (Tok.is(MMToken::RSquare)) 2226 consumeToken(); 2227 HadError = true; 2228 } 2229 2230 // Decode the attribute name. 2231 AttributeKind Attribute 2232 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2233 .Case("exhaustive", AT_exhaustive) 2234 .Case("extern_c", AT_extern_c) 2235 .Case("system", AT_system) 2236 .Default(AT_unknown); 2237 switch (Attribute) { 2238 case AT_unknown: 2239 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2240 << Tok.getString(); 2241 break; 2242 2243 case AT_system: 2244 Attrs.IsSystem = true; 2245 break; 2246 2247 case AT_extern_c: 2248 Attrs.IsExternC = true; 2249 break; 2250 2251 case AT_exhaustive: 2252 Attrs.IsExhaustive = true; 2253 break; 2254 } 2255 consumeToken(); 2256 2257 // Consume the ']'. 2258 if (!Tok.is(MMToken::RSquare)) { 2259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2260 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2261 skipUntil(MMToken::RSquare); 2262 HadError = true; 2263 } 2264 2265 if (Tok.is(MMToken::RSquare)) 2266 consumeToken(); 2267 } 2268 2269 return HadError; 2270 } 2271 2272 /// \brief Parse a module map file. 2273 /// 2274 /// module-map-file: 2275 /// module-declaration* 2276 bool ModuleMapParser::parseModuleMapFile() { 2277 do { 2278 switch (Tok.Kind) { 2279 case MMToken::EndOfFile: 2280 return HadError; 2281 2282 case MMToken::ExplicitKeyword: 2283 case MMToken::ExternKeyword: 2284 case MMToken::ModuleKeyword: 2285 case MMToken::FrameworkKeyword: 2286 parseModuleDecl(); 2287 break; 2288 2289 case MMToken::Comma: 2290 case MMToken::ConfigMacros: 2291 case MMToken::Conflict: 2292 case MMToken::Exclaim: 2293 case MMToken::ExcludeKeyword: 2294 case MMToken::ExportKeyword: 2295 case MMToken::HeaderKeyword: 2296 case MMToken::Identifier: 2297 case MMToken::LBrace: 2298 case MMToken::LinkKeyword: 2299 case MMToken::LSquare: 2300 case MMToken::Period: 2301 case MMToken::PrivateKeyword: 2302 case MMToken::RBrace: 2303 case MMToken::RSquare: 2304 case MMToken::RequiresKeyword: 2305 case MMToken::Star: 2306 case MMToken::StringLiteral: 2307 case MMToken::TextualKeyword: 2308 case MMToken::UmbrellaKeyword: 2309 case MMToken::UseKeyword: 2310 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2311 HadError = true; 2312 consumeToken(); 2313 break; 2314 } 2315 } while (true); 2316 } 2317 2318 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { 2319 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2320 = ParsedModuleMap.find(File); 2321 if (Known != ParsedModuleMap.end()) 2322 return Known->second; 2323 2324 assert(Target && "Missing target information"); 2325 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2326 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter); 2327 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2328 if (!Buffer) 2329 return ParsedModuleMap[File] = true; 2330 2331 // Find the directory for the module. For frameworks, that may require going 2332 // up from the 'Modules' directory. 2333 const DirectoryEntry *Dir = File->getDir(); 2334 StringRef DirName(Dir->getName()); 2335 if (llvm::sys::path::filename(DirName) == "Modules") { 2336 DirName = llvm::sys::path::parent_path(DirName); 2337 if (DirName.endswith(".framework")) 2338 Dir = SourceMgr.getFileManager().getDirectory(DirName); 2339 assert(Dir && "parent must exist"); 2340 } 2341 2342 // Parse this module map file. 2343 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 2344 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2345 BuiltinIncludeDir, IsSystem); 2346 bool Result = Parser.parseModuleMapFile(); 2347 ParsedModuleMap[File] = Result; 2348 return Result; 2349 } 2350