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