1 //===- ModuleMap.cpp - Describe the layout of modules ---------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the ModuleMap implementation, which describes the layout 10 // of a module as it relates to headers. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Lex/ModuleMap.h" 15 #include "clang/Basic/CharInfo.h" 16 #include "clang/Basic/Diagnostic.h" 17 #include "clang/Basic/FileManager.h" 18 #include "clang/Basic/LLVM.h" 19 #include "clang/Basic/LangOptions.h" 20 #include "clang/Basic/Module.h" 21 #include "clang/Basic/SourceLocation.h" 22 #include "clang/Basic/SourceManager.h" 23 #include "clang/Basic/TargetInfo.h" 24 #include "clang/Lex/HeaderSearch.h" 25 #include "clang/Lex/HeaderSearchOptions.h" 26 #include "clang/Lex/LexDiagnostic.h" 27 #include "clang/Lex/Lexer.h" 28 #include "clang/Lex/LiteralSupport.h" 29 #include "clang/Lex/Token.h" 30 #include "llvm/ADT/DenseMap.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/ADT/SmallPtrSet.h" 33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/ADT/SmallVector.h" 35 #include "llvm/ADT/StringMap.h" 36 #include "llvm/ADT/StringRef.h" 37 #include "llvm/ADT/StringSwitch.h" 38 #include "llvm/Support/Allocator.h" 39 #include "llvm/Support/Compiler.h" 40 #include "llvm/Support/ErrorHandling.h" 41 #include "llvm/Support/MemoryBuffer.h" 42 #include "llvm/Support/Path.h" 43 #include "llvm/Support/VirtualFileSystem.h" 44 #include "llvm/Support/raw_ostream.h" 45 #include <algorithm> 46 #include <cassert> 47 #include <cstdint> 48 #include <cstring> 49 #include <optional> 50 #include <string> 51 #include <system_error> 52 #include <utility> 53 54 using namespace clang; 55 56 void ModuleMapCallbacks::anchor() {} 57 58 void ModuleMap::resolveLinkAsDependencies(Module *Mod) { 59 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name); 60 if (PendingLinkAs != PendingLinkAsModule.end()) { 61 for (auto &Name : PendingLinkAs->second) { 62 auto *M = findModule(Name.getKey()); 63 if (M) 64 M->UseExportAsModuleLinkName = true; 65 } 66 } 67 } 68 69 void ModuleMap::addLinkAsDependency(Module *Mod) { 70 if (findModule(Mod->ExportAsModule)) 71 Mod->UseExportAsModuleLinkName = true; 72 else 73 PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name); 74 } 75 76 Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) { 77 switch ((int)Role) { 78 case NormalHeader: 79 return Module::HK_Normal; 80 case PrivateHeader: 81 return Module::HK_Private; 82 case TextualHeader: 83 return Module::HK_Textual; 84 case PrivateHeader | TextualHeader: 85 return Module::HK_PrivateTextual; 86 case ExcludedHeader: 87 return Module::HK_Excluded; 88 } 89 llvm_unreachable("unknown header role"); 90 } 91 92 ModuleMap::ModuleHeaderRole 93 ModuleMap::headerKindToRole(Module::HeaderKind Kind) { 94 switch ((int)Kind) { 95 case Module::HK_Normal: 96 return NormalHeader; 97 case Module::HK_Private: 98 return PrivateHeader; 99 case Module::HK_Textual: 100 return TextualHeader; 101 case Module::HK_PrivateTextual: 102 return ModuleHeaderRole(PrivateHeader | TextualHeader); 103 case Module::HK_Excluded: 104 return ExcludedHeader; 105 } 106 llvm_unreachable("unknown header kind"); 107 } 108 109 bool ModuleMap::isModular(ModuleHeaderRole Role) { 110 return !(Role & (ModuleMap::TextualHeader | ModuleMap::ExcludedHeader)); 111 } 112 113 Module::ExportDecl 114 ModuleMap::resolveExport(Module *Mod, 115 const Module::UnresolvedExportDecl &Unresolved, 116 bool Complain) const { 117 // We may have just a wildcard. 118 if (Unresolved.Id.empty()) { 119 assert(Unresolved.Wildcard && "Invalid unresolved export"); 120 return Module::ExportDecl(nullptr, true); 121 } 122 123 // Resolve the module-id. 124 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 125 if (!Context) 126 return {}; 127 128 return Module::ExportDecl(Context, Unresolved.Wildcard); 129 } 130 131 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 132 bool Complain) const { 133 // Find the starting module. 134 Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 135 if (!Context) { 136 if (Complain) 137 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 138 << Id[0].first << Mod->getFullModuleName(); 139 140 return nullptr; 141 } 142 143 // Dig into the module path. 144 for (unsigned I = 1, N = Id.size(); I != N; ++I) { 145 Module *Sub = lookupModuleQualified(Id[I].first, Context); 146 if (!Sub) { 147 if (Complain) 148 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 149 << Id[I].first << Context->getFullModuleName() 150 << SourceRange(Id[0].second, Id[I-1].second); 151 152 return nullptr; 153 } 154 155 Context = Sub; 156 } 157 158 return Context; 159 } 160 161 /// Append to \p Paths the set of paths needed to get to the 162 /// subframework in which the given module lives. 163 static void appendSubframeworkPaths(Module *Mod, 164 SmallVectorImpl<char> &Path) { 165 // Collect the framework names from the given module to the top-level module. 166 SmallVector<StringRef, 2> Paths; 167 for (; Mod; Mod = Mod->Parent) { 168 if (Mod->IsFramework) 169 Paths.push_back(Mod->Name); 170 } 171 172 if (Paths.empty()) 173 return; 174 175 // Add Frameworks/Name.framework for each subframework. 176 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths))) 177 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework"); 178 } 179 180 OptionalFileEntryRef ModuleMap::findHeader( 181 Module *M, const Module::UnresolvedHeaderDirective &Header, 182 SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) { 183 // Search for the header file within the module's home directory. 184 auto *Directory = M->Directory; 185 SmallString<128> FullPathName(Directory->getName()); 186 187 auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef { 188 auto File = 189 expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename)); 190 if (!File || (Header.Size && File->getSize() != *Header.Size) || 191 (Header.ModTime && File->getModificationTime() != *Header.ModTime)) 192 return std::nullopt; 193 return *File; 194 }; 195 196 auto GetFrameworkFile = [&]() -> OptionalFileEntryRef { 197 unsigned FullPathLength = FullPathName.size(); 198 appendSubframeworkPaths(M, RelativePathName); 199 unsigned RelativePathLength = RelativePathName.size(); 200 201 // Check whether this file is in the public headers. 202 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); 203 llvm::sys::path::append(FullPathName, RelativePathName); 204 if (auto File = GetFile(FullPathName)) 205 return File; 206 207 // Check whether this file is in the private headers. 208 // Ideally, private modules in the form 'FrameworkName.Private' should 209 // be defined as 'module FrameworkName.Private', and not as 210 // 'framework module FrameworkName.Private', since a 'Private.Framework' 211 // does not usually exist. However, since both are currently widely used 212 // for private modules, make sure we find the right path in both cases. 213 if (M->IsFramework && M->Name == "Private") 214 RelativePathName.clear(); 215 else 216 RelativePathName.resize(RelativePathLength); 217 FullPathName.resize(FullPathLength); 218 llvm::sys::path::append(RelativePathName, "PrivateHeaders", 219 Header.FileName); 220 llvm::sys::path::append(FullPathName, RelativePathName); 221 return GetFile(FullPathName); 222 }; 223 224 if (llvm::sys::path::is_absolute(Header.FileName)) { 225 RelativePathName.clear(); 226 RelativePathName.append(Header.FileName.begin(), Header.FileName.end()); 227 return GetFile(Header.FileName); 228 } 229 230 if (M->isPartOfFramework()) 231 return GetFrameworkFile(); 232 233 // Lookup for normal headers. 234 llvm::sys::path::append(RelativePathName, Header.FileName); 235 llvm::sys::path::append(FullPathName, RelativePathName); 236 auto NormalHdrFile = GetFile(FullPathName); 237 238 if (!NormalHdrFile && Directory->getName().endswith(".framework")) { 239 // The lack of 'framework' keyword in a module declaration it's a simple 240 // mistake we can diagnose when the header exists within the proper 241 // framework style path. 242 FullPathName.assign(Directory->getName()); 243 RelativePathName.clear(); 244 if (GetFrameworkFile()) { 245 Diags.Report(Header.FileNameLoc, 246 diag::warn_mmap_incomplete_framework_module_declaration) 247 << Header.FileName << M->getFullModuleName(); 248 NeedsFramework = true; 249 } 250 return std::nullopt; 251 } 252 253 return NormalHdrFile; 254 } 255 256 void ModuleMap::resolveHeader(Module *Mod, 257 const Module::UnresolvedHeaderDirective &Header, 258 bool &NeedsFramework) { 259 SmallString<128> RelativePathName; 260 if (OptionalFileEntryRef File = 261 findHeader(Mod, Header, RelativePathName, NeedsFramework)) { 262 if (Header.IsUmbrella) { 263 const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry(); 264 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir]) 265 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 266 << UmbrellaMod->getFullModuleName(); 267 else 268 // Record this umbrella header. 269 setUmbrellaHeader(Mod, *File, Header.FileName, RelativePathName.str()); 270 } else { 271 Module::Header H = {Header.FileName, std::string(RelativePathName.str()), 272 *File}; 273 addHeader(Mod, H, headerKindToRole(Header.Kind)); 274 } 275 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) { 276 // There's a builtin header but no corresponding on-disk header. Assume 277 // this was supposed to modularize the builtin header alone. 278 } else if (Header.Kind == Module::HK_Excluded) { 279 // Ignore missing excluded header files. They're optional anyway. 280 } else { 281 // If we find a module that has a missing header, we mark this module as 282 // unavailable and store the header directive for displaying diagnostics. 283 Mod->MissingHeaders.push_back(Header); 284 // A missing header with stat information doesn't make the module 285 // unavailable; this keeps our behavior consistent as headers are lazily 286 // resolved. (Such a module still can't be built though, except from 287 // preprocessed source.) 288 if (!Header.Size && !Header.ModTime) 289 Mod->markUnavailable(/*Unimportable=*/false); 290 } 291 } 292 293 bool ModuleMap::resolveAsBuiltinHeader( 294 Module *Mod, const Module::UnresolvedHeaderDirective &Header) { 295 if (Header.Kind == Module::HK_Excluded || 296 llvm::sys::path::is_absolute(Header.FileName) || 297 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella || 298 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory || 299 !isBuiltinHeader(Header.FileName)) 300 return false; 301 302 // This is a system module with a top-level header. This header 303 // may have a counterpart (or replacement) in the set of headers 304 // supplied by Clang. Find that builtin header. 305 SmallString<128> Path; 306 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName); 307 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path); 308 if (!File) 309 return false; 310 311 auto Role = headerKindToRole(Header.Kind); 312 Module::Header H = {Header.FileName, std::string(Path.str()), *File}; 313 addHeader(Mod, H, Role); 314 return true; 315 } 316 317 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 318 const LangOptions &LangOpts, const TargetInfo *Target, 319 HeaderSearch &HeaderInfo) 320 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 321 HeaderInfo(HeaderInfo) { 322 MMapLangOpts.LineComment = true; 323 } 324 325 ModuleMap::~ModuleMap() { 326 for (auto &M : Modules) 327 delete M.getValue(); 328 for (auto *M : ShadowModules) 329 delete M; 330 } 331 332 void ModuleMap::setTarget(const TargetInfo &Target) { 333 assert((!this->Target || this->Target == &Target) && 334 "Improper target override"); 335 this->Target = &Target; 336 } 337 338 /// "Sanitize" a filename so that it can be used as an identifier. 339 static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 340 SmallVectorImpl<char> &Buffer) { 341 if (Name.empty()) 342 return Name; 343 344 if (!isValidAsciiIdentifier(Name)) { 345 // If we don't already have something with the form of an identifier, 346 // create a buffer with the sanitized name. 347 Buffer.clear(); 348 if (isDigit(Name[0])) 349 Buffer.push_back('_'); 350 Buffer.reserve(Buffer.size() + Name.size()); 351 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 352 if (isAsciiIdentifierContinue(Name[I])) 353 Buffer.push_back(Name[I]); 354 else 355 Buffer.push_back('_'); 356 } 357 358 Name = StringRef(Buffer.data(), Buffer.size()); 359 } 360 361 while (llvm::StringSwitch<bool>(Name) 362 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 363 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 364 #include "clang/Basic/TokenKinds.def" 365 .Default(false)) { 366 if (Name.data() != Buffer.data()) 367 Buffer.append(Name.begin(), Name.end()); 368 Buffer.push_back('_'); 369 Name = StringRef(Buffer.data(), Buffer.size()); 370 } 371 372 return Name; 373 } 374 375 /// Determine whether the given file name is the name of a builtin 376 /// header, supplied by Clang to replace, override, or augment existing system 377 /// headers. 378 bool ModuleMap::isBuiltinHeader(StringRef FileName) { 379 return llvm::StringSwitch<bool>(FileName) 380 .Case("float.h", true) 381 .Case("iso646.h", true) 382 .Case("limits.h", true) 383 .Case("stdalign.h", true) 384 .Case("stdarg.h", true) 385 .Case("stdatomic.h", true) 386 .Case("stdbool.h", true) 387 .Case("stddef.h", true) 388 .Case("stdint.h", true) 389 .Case("tgmath.h", true) 390 .Case("unwind.h", true) 391 .Default(false); 392 } 393 394 bool ModuleMap::isBuiltinHeader(const FileEntry *File) { 395 return File->getDir() == BuiltinIncludeDir && 396 ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName())); 397 } 398 399 ModuleMap::HeadersMap::iterator 400 ModuleMap::findKnownHeader(const FileEntry *File) { 401 resolveHeaderDirectives(File); 402 HeadersMap::iterator Known = Headers.find(File); 403 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && 404 Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) { 405 HeaderInfo.loadTopLevelSystemModules(); 406 return Headers.find(File); 407 } 408 return Known; 409 } 410 411 ModuleMap::KnownHeader 412 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, 413 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { 414 if (UmbrellaDirs.empty()) 415 return {}; 416 417 const DirectoryEntry *Dir = File->getDir(); 418 assert(Dir && "file in no directory"); 419 420 // Note: as an egregious but useful hack we use the real path here, because 421 // frameworks moving from top-level frameworks to embedded frameworks tend 422 // to be symlinked from the top-level location to the embedded location, 423 // and we need to resolve lookups as if we had found the embedded location. 424 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 425 426 // Keep walking up the directory hierarchy, looking for a directory with 427 // an umbrella header. 428 do { 429 auto KnownDir = UmbrellaDirs.find(Dir); 430 if (KnownDir != UmbrellaDirs.end()) 431 return KnownHeader(KnownDir->second, NormalHeader); 432 433 IntermediateDirs.push_back(Dir); 434 435 // Retrieve our parent path. 436 DirName = llvm::sys::path::parent_path(DirName); 437 if (DirName.empty()) 438 break; 439 440 // Resolve the parent path to a directory entry. 441 if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName)) 442 Dir = *DirEntry; 443 else 444 Dir = nullptr; 445 } while (Dir); 446 return {}; 447 } 448 449 static bool violatesPrivateInclude(Module *RequestingModule, 450 const FileEntry *IncFileEnt, 451 ModuleMap::KnownHeader Header) { 452 #ifndef NDEBUG 453 if (Header.getRole() & ModuleMap::PrivateHeader) { 454 // Check for consistency between the module header role 455 // as obtained from the lookup and as obtained from the module. 456 // This check is not cheap, so enable it only for debugging. 457 bool IsPrivate = false; 458 SmallVectorImpl<Module::Header> *HeaderList[] = { 459 &Header.getModule()->Headers[Module::HK_Private], 460 &Header.getModule()->Headers[Module::HK_PrivateTextual]}; 461 for (auto *Hs : HeaderList) 462 IsPrivate |= llvm::any_of( 463 *Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; }); 464 assert(IsPrivate && "inconsistent headers and roles"); 465 } 466 #endif 467 return !Header.isAccessibleFrom(RequestingModule); 468 } 469 470 static Module *getTopLevelOrNull(Module *M) { 471 return M ? M->getTopLevelModule() : nullptr; 472 } 473 474 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 475 bool RequestingModuleIsModuleInterface, 476 SourceLocation FilenameLoc, 477 StringRef Filename, FileEntryRef File) { 478 // No errors for indirect modules. This may be a bit of a problem for modules 479 // with no source files. 480 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) 481 return; 482 483 if (RequestingModule) { 484 resolveUses(RequestingModule, /*Complain=*/false); 485 resolveHeaderDirectives(RequestingModule, /*File=*/std::nullopt); 486 } 487 488 bool Excluded = false; 489 Module *Private = nullptr; 490 Module *NotUsed = nullptr; 491 492 HeadersMap::iterator Known = findKnownHeader(File); 493 if (Known != Headers.end()) { 494 for (const KnownHeader &Header : Known->second) { 495 // Excluded headers don't really belong to a module. 496 if (Header.getRole() == ModuleMap::ExcludedHeader) { 497 Excluded = true; 498 continue; 499 } 500 501 // Remember private headers for later printing of a diagnostic. 502 if (violatesPrivateInclude(RequestingModule, File, Header)) { 503 Private = Header.getModule(); 504 continue; 505 } 506 507 // If uses need to be specified explicitly, we are only allowed to return 508 // modules that are explicitly used by the requesting module. 509 if (RequestingModule && LangOpts.ModulesDeclUse && 510 !RequestingModule->directlyUses(Header.getModule())) { 511 NotUsed = Header.getModule(); 512 continue; 513 } 514 515 // We have found a module that we can happily use. 516 return; 517 } 518 519 Excluded = true; 520 } 521 522 // We have found a header, but it is private. 523 if (Private) { 524 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module) 525 << Filename; 526 return; 527 } 528 529 // We have found a module, but we don't use it. 530 if (NotUsed) { 531 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 532 << RequestingModule->getTopLevelModule()->Name << Filename; 533 return; 534 } 535 536 if (Excluded || isHeaderInUmbrellaDirs(File)) 537 return; 538 539 // At this point, only non-modular includes remain. 540 541 if (RequestingModule && LangOpts.ModulesStrictDeclUse) { 542 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 543 << RequestingModule->getTopLevelModule()->Name << Filename; 544 } else if (RequestingModule && RequestingModuleIsModuleInterface && 545 LangOpts.isCompilingModule()) { 546 // Do not diagnose when we are not compiling a module. 547 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? 548 diag::warn_non_modular_include_in_framework_module : 549 diag::warn_non_modular_include_in_module; 550 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName() 551 << File.getName(); 552 } 553 } 554 555 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, 556 const ModuleMap::KnownHeader &Old) { 557 // Prefer available modules. 558 // FIXME: Considering whether the module is available rather than merely 559 // importable is non-hermetic and can result in surprising behavior for 560 // prebuilt modules. Consider only checking for importability here. 561 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable()) 562 return true; 563 564 // Prefer a public header over a private header. 565 if ((New.getRole() & ModuleMap::PrivateHeader) != 566 (Old.getRole() & ModuleMap::PrivateHeader)) 567 return !(New.getRole() & ModuleMap::PrivateHeader); 568 569 // Prefer a non-textual header over a textual header. 570 if ((New.getRole() & ModuleMap::TextualHeader) != 571 (Old.getRole() & ModuleMap::TextualHeader)) 572 return !(New.getRole() & ModuleMap::TextualHeader); 573 574 // Prefer a non-excluded header over an excluded header. 575 if ((New.getRole() == ModuleMap::ExcludedHeader) != 576 (Old.getRole() == ModuleMap::ExcludedHeader)) 577 return New.getRole() != ModuleMap::ExcludedHeader; 578 579 // Don't have a reason to choose between these. Just keep the first one. 580 return false; 581 } 582 583 ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, 584 bool AllowTextual, 585 bool AllowExcluded) { 586 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { 587 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader) 588 return {}; 589 return R; 590 }; 591 592 HeadersMap::iterator Known = findKnownHeader(File); 593 if (Known != Headers.end()) { 594 ModuleMap::KnownHeader Result; 595 // Iterate over all modules that 'File' is part of to find the best fit. 596 for (KnownHeader &H : Known->second) { 597 // Cannot use a module if the header is excluded in it. 598 if (!AllowExcluded && H.getRole() == ModuleMap::ExcludedHeader) 599 continue; 600 // Prefer a header from the source module over all others. 601 if (H.getModule()->getTopLevelModule() == SourceModule) 602 return MakeResult(H); 603 if (!Result || isBetterKnownHeader(H, Result)) 604 Result = H; 605 } 606 return MakeResult(Result); 607 } 608 609 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File)); 610 } 611 612 ModuleMap::KnownHeader 613 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) { 614 assert(!Headers.count(File) && "already have a module for this header"); 615 616 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 617 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); 618 if (H) { 619 Module *Result = H.getModule(); 620 621 // Search up the module stack until we find a module with an umbrella 622 // directory. 623 Module *UmbrellaModule = Result; 624 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 625 UmbrellaModule = UmbrellaModule->Parent; 626 627 if (UmbrellaModule->InferSubmodules) { 628 OptionalFileEntryRefDegradesToFileEntryPtr UmbrellaModuleMap = 629 getModuleMapFileForUniquing(UmbrellaModule); 630 631 // Infer submodules for each of the directories we found between 632 // the directory of the umbrella header and the directory where 633 // the actual header is located. 634 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 635 636 for (const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) { 637 // Find or create the module that corresponds to this directory name. 638 SmallString<32> NameBuf; 639 StringRef Name = sanitizeFilenameAsIdentifier( 640 llvm::sys::path::stem(SkippedDir->getName()), NameBuf); 641 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 642 Explicit).first; 643 InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 644 Result->IsInferred = true; 645 646 // Associate the module and the directory. 647 UmbrellaDirs[SkippedDir] = Result; 648 649 // If inferred submodules export everything they import, add a 650 // wildcard to the set of exports. 651 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 652 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 653 } 654 655 // Infer a submodule with the same name as this header file. 656 SmallString<32> NameBuf; 657 StringRef Name = sanitizeFilenameAsIdentifier( 658 llvm::sys::path::stem(File->getName()), NameBuf); 659 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 660 Explicit).first; 661 InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 662 Result->IsInferred = true; 663 Result->addTopHeader(File); 664 665 // If inferred submodules export everything they import, add a 666 // wildcard to the set of exports. 667 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 668 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 669 } else { 670 // Record each of the directories we stepped through as being part of 671 // the module we found, since the umbrella header covers them all. 672 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 673 UmbrellaDirs[SkippedDirs[I]] = Result; 674 } 675 676 KnownHeader Header(Result, NormalHeader); 677 Headers[File].push_back(Header); 678 return Header; 679 } 680 681 return {}; 682 } 683 684 ArrayRef<ModuleMap::KnownHeader> 685 ModuleMap::findAllModulesForHeader(const FileEntry *File) { 686 HeadersMap::iterator Known = findKnownHeader(File); 687 if (Known != Headers.end()) 688 return Known->second; 689 690 if (findOrCreateModuleForHeaderInUmbrellaDir(File)) 691 return Headers.find(File)->second; 692 693 return std::nullopt; 694 } 695 696 ArrayRef<ModuleMap::KnownHeader> 697 ModuleMap::findResolvedModulesForHeader(const FileEntry *File) const { 698 // FIXME: Is this necessary? 699 resolveHeaderDirectives(File); 700 auto It = Headers.find(File); 701 if (It == Headers.end()) 702 return std::nullopt; 703 return It->second; 704 } 705 706 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 707 return isHeaderUnavailableInModule(Header, nullptr); 708 } 709 710 bool 711 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, 712 const Module *RequestingModule) const { 713 resolveHeaderDirectives(Header); 714 HeadersMap::const_iterator Known = Headers.find(Header); 715 if (Known != Headers.end()) { 716 for (SmallVectorImpl<KnownHeader>::const_iterator 717 I = Known->second.begin(), 718 E = Known->second.end(); 719 I != E; ++I) { 720 721 if (I->getRole() == ModuleMap::ExcludedHeader) 722 continue; 723 724 if (I->isAvailable() && 725 (!RequestingModule || 726 I->getModule()->isSubModuleOf(RequestingModule))) { 727 // When no requesting module is available, the caller is looking if a 728 // header is part a module by only looking into the module map. This is 729 // done by warn_uncovered_module_header checks; don't consider textual 730 // headers part of it in this mode, otherwise we get misleading warnings 731 // that a umbrella header is not including a textual header. 732 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader) 733 continue; 734 return false; 735 } 736 } 737 return true; 738 } 739 740 const DirectoryEntry *Dir = Header->getDir(); 741 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 742 StringRef DirName = Dir->getName(); 743 744 auto IsUnavailable = [&](const Module *M) { 745 return !M->isAvailable() && (!RequestingModule || 746 M->isSubModuleOf(RequestingModule)); 747 }; 748 749 // Keep walking up the directory hierarchy, looking for a directory with 750 // an umbrella header. 751 do { 752 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 753 = UmbrellaDirs.find(Dir); 754 if (KnownDir != UmbrellaDirs.end()) { 755 Module *Found = KnownDir->second; 756 if (IsUnavailable(Found)) 757 return true; 758 759 // Search up the module stack until we find a module with an umbrella 760 // directory. 761 Module *UmbrellaModule = Found; 762 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 763 UmbrellaModule = UmbrellaModule->Parent; 764 765 if (UmbrellaModule->InferSubmodules) { 766 for (const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) { 767 // Find or create the module that corresponds to this directory name. 768 SmallString<32> NameBuf; 769 StringRef Name = sanitizeFilenameAsIdentifier( 770 llvm::sys::path::stem(SkippedDir->getName()), NameBuf); 771 Found = lookupModuleQualified(Name, Found); 772 if (!Found) 773 return false; 774 if (IsUnavailable(Found)) 775 return true; 776 } 777 778 // Infer a submodule with the same name as this header file. 779 SmallString<32> NameBuf; 780 StringRef Name = sanitizeFilenameAsIdentifier( 781 llvm::sys::path::stem(Header->getName()), 782 NameBuf); 783 Found = lookupModuleQualified(Name, Found); 784 if (!Found) 785 return false; 786 } 787 788 return IsUnavailable(Found); 789 } 790 791 SkippedDirs.push_back(Dir); 792 793 // Retrieve our parent path. 794 DirName = llvm::sys::path::parent_path(DirName); 795 if (DirName.empty()) 796 break; 797 798 // Resolve the parent path to a directory entry. 799 if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName)) 800 Dir = *DirEntry; 801 else 802 Dir = nullptr; 803 } while (Dir); 804 805 return false; 806 } 807 808 Module *ModuleMap::findModule(StringRef Name) const { 809 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 810 if (Known != Modules.end()) 811 return Known->getValue(); 812 813 return nullptr; 814 } 815 816 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, 817 Module *Context) const { 818 for(; Context; Context = Context->Parent) { 819 if (Module *Sub = lookupModuleQualified(Name, Context)) 820 return Sub; 821 } 822 823 return findModule(Name); 824 } 825 826 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 827 if (!Context) 828 return findModule(Name); 829 830 return Context->findSubmodule(Name); 831 } 832 833 std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name, 834 Module *Parent, 835 bool IsFramework, 836 bool IsExplicit) { 837 // Try to find an existing module with this name. 838 if (Module *Sub = lookupModuleQualified(Name, Parent)) 839 return std::make_pair(Sub, false); 840 841 // Create a new module with this name. 842 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 843 IsExplicit, NumCreatedModules++); 844 if (!Parent) { 845 if (LangOpts.CurrentModule == Name) 846 SourceModule = Result; 847 Modules[Name] = Result; 848 ModuleScopeIDs[Result] = CurrentModuleScopeID; 849 } 850 return std::make_pair(Result, true); 851 } 852 853 Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, 854 Module *Parent) { 855 auto *Result = new Module("<global>", Loc, Parent, /*IsFramework*/ false, 856 /*IsExplicit*/ true, NumCreatedModules++); 857 Result->Kind = Module::GlobalModuleFragment; 858 // If the created module isn't owned by a parent, send it to PendingSubmodules 859 // to wait for its parent. 860 if (!Result->Parent) 861 PendingSubmodules.emplace_back(Result); 862 return Result; 863 } 864 865 Module * 866 ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent, 867 SourceLocation Loc) { 868 auto *Result = 869 new Module("<private>", Loc, Parent, /*IsFramework*/ false, 870 /*IsExplicit*/ true, NumCreatedModules++); 871 Result->Kind = Module::PrivateModuleFragment; 872 return Result; 873 } 874 875 Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, 876 StringRef Name) { 877 assert(LangOpts.CurrentModule == Name && "module name mismatch"); 878 assert(!Modules[Name] && "redefining existing module"); 879 880 auto *Result = 881 new Module(Name, Loc, nullptr, /*IsFramework*/ false, 882 /*IsExplicit*/ false, NumCreatedModules++); 883 Result->Kind = Module::ModuleInterfaceUnit; 884 Modules[Name] = SourceModule = Result; 885 886 // Reparent the current global module fragment as a submodule of this module. 887 for (auto &Submodule : PendingSubmodules) { 888 Submodule->setParent(Result); 889 Submodule.release(); // now owned by parent 890 } 891 PendingSubmodules.clear(); 892 893 // Mark the main source file as being within the newly-created module so that 894 // declarations and macros are properly visibility-restricted to it. 895 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); 896 assert(MainFile && "no input file for module interface"); 897 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader)); 898 899 return Result; 900 } 901 902 Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name, 903 Module::Header H) { 904 assert(LangOpts.CurrentModule == Name && "module name mismatch"); 905 assert(!Modules[Name] && "redefining existing module"); 906 907 auto *Result = new Module(Name, Loc, nullptr, /*IsFramework*/ false, 908 /*IsExplicit*/ false, NumCreatedModules++); 909 Result->Kind = Module::ModuleHeaderUnit; 910 Modules[Name] = SourceModule = Result; 911 addHeader(Result, H, NormalHeader); 912 return Result; 913 } 914 915 /// For a framework module, infer the framework against which we 916 /// should link. 917 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 918 FileManager &FileMgr) { 919 assert(Mod->IsFramework && "Can only infer linking for framework modules"); 920 assert(!Mod->isSubFramework() && 921 "Can only infer linking for top-level frameworks"); 922 923 SmallString<128> LibName; 924 LibName += FrameworkDir->getName(); 925 llvm::sys::path::append(LibName, Mod->Name); 926 927 // The library name of a framework has more than one possible extension since 928 // the introduction of the text-based dynamic library format. We need to check 929 // for both before we give up. 930 for (const char *extension : {"", ".tbd"}) { 931 llvm::sys::path::replace_extension(LibName, extension); 932 if (FileMgr.getFile(LibName)) { 933 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 934 /*IsFramework=*/true)); 935 return; 936 } 937 } 938 } 939 940 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, 941 bool IsSystem, Module *Parent) { 942 Attributes Attrs; 943 Attrs.IsSystem = IsSystem; 944 return inferFrameworkModule(FrameworkDir, Attrs, Parent); 945 } 946 947 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, 948 Attributes Attrs, Module *Parent) { 949 // Note: as an egregious but useful hack we use the real path here, because 950 // we might be looking at an embedded framework that symlinks out to a 951 // top-level framework, and we need to infer as if we were naming the 952 // top-level framework. 953 StringRef FrameworkDirName = 954 SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 955 956 // In case this is a case-insensitive filesystem, use the canonical 957 // directory name as the ModuleName, since modules are case-sensitive. 958 // FIXME: we should be able to give a fix-it hint for the correct spelling. 959 SmallString<32> ModuleNameStorage; 960 StringRef ModuleName = sanitizeFilenameAsIdentifier( 961 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage); 962 963 // Check whether we've already found this module. 964 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 965 return Mod; 966 967 FileManager &FileMgr = SourceMgr.getFileManager(); 968 969 // If the framework has a parent path from which we're allowed to infer 970 // a framework module, do so. 971 const FileEntry *ModuleMapFile = nullptr; 972 if (!Parent) { 973 // Determine whether we're allowed to infer a module map. 974 bool canInfer = false; 975 if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 976 // Figure out the parent path. 977 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 978 if (auto ParentDir = FileMgr.getDirectory(Parent)) { 979 // Check whether we have already looked into the parent directory 980 // for a module map. 981 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 982 inferred = InferredDirectories.find(*ParentDir); 983 if (inferred == InferredDirectories.end()) { 984 // We haven't looked here before. Load a module map, if there is 985 // one. 986 bool IsFrameworkDir = Parent.endswith(".framework"); 987 if (const FileEntry *ModMapFile = 988 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) { 989 parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir); 990 inferred = InferredDirectories.find(*ParentDir); 991 } 992 993 if (inferred == InferredDirectories.end()) 994 inferred = InferredDirectories.insert( 995 std::make_pair(*ParentDir, InferredDirectory())).first; 996 } 997 998 if (inferred->second.InferModules) { 999 // We're allowed to infer for this directory, but make sure it's okay 1000 // to infer this particular module. 1001 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 1002 canInfer = 1003 !llvm::is_contained(inferred->second.ExcludedModules, Name); 1004 1005 Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 1006 Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 1007 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 1008 Attrs.NoUndeclaredIncludes |= 1009 inferred->second.Attrs.NoUndeclaredIncludes; 1010 ModuleMapFile = inferred->second.ModuleMapFile; 1011 } 1012 } 1013 } 1014 1015 // If we're not allowed to infer a framework module, don't. 1016 if (!canInfer) 1017 return nullptr; 1018 } else { 1019 OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef = 1020 getModuleMapFileForUniquing(Parent); 1021 ModuleMapFile = ModuleMapRef; 1022 } 1023 1024 // Look for an umbrella header. 1025 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 1026 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 1027 auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName); 1028 1029 // FIXME: If there's no umbrella header, we could probably scan the 1030 // framework to load *everything*. But, it's not clear that this is a good 1031 // idea. 1032 if (!UmbrellaHeader) 1033 return nullptr; 1034 1035 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 1036 /*IsFramework=*/true, /*IsExplicit=*/false, 1037 NumCreatedModules++); 1038 InferredModuleAllowedBy[Result] = ModuleMapFile; 1039 Result->IsInferred = true; 1040 if (!Parent) { 1041 if (LangOpts.CurrentModule == ModuleName) 1042 SourceModule = Result; 1043 Modules[ModuleName] = Result; 1044 ModuleScopeIDs[Result] = CurrentModuleScopeID; 1045 } 1046 1047 Result->IsSystem |= Attrs.IsSystem; 1048 Result->IsExternC |= Attrs.IsExternC; 1049 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; 1050 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes; 1051 Result->Directory = FrameworkDir; 1052 1053 // Chop off the first framework bit, as that is implied. 1054 StringRef RelativePath = UmbrellaName.str().substr( 1055 Result->getTopLevelModule()->Directory->getName().size()); 1056 RelativePath = llvm::sys::path::relative_path(RelativePath); 1057 1058 // umbrella header "umbrella-header-name" 1059 setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath); 1060 1061 // export * 1062 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 1063 1064 // module * { export * } 1065 Result->InferSubmodules = true; 1066 Result->InferExportWildcard = true; 1067 1068 // Look for subframeworks. 1069 std::error_code EC; 1070 SmallString<128> SubframeworksDirName 1071 = StringRef(FrameworkDir->getName()); 1072 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 1073 llvm::sys::path::native(SubframeworksDirName); 1074 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); 1075 for (llvm::vfs::directory_iterator 1076 Dir = FS.dir_begin(SubframeworksDirName, EC), 1077 DirEnd; 1078 Dir != DirEnd && !EC; Dir.increment(EC)) { 1079 if (!StringRef(Dir->path()).endswith(".framework")) 1080 continue; 1081 1082 if (auto SubframeworkDir = 1083 FileMgr.getDirectory(Dir->path())) { 1084 // Note: as an egregious but useful hack, we use the real path here and 1085 // check whether it is actually a subdirectory of the parent directory. 1086 // This will not be the case if the 'subframework' is actually a symlink 1087 // out to a top-level framework. 1088 StringRef SubframeworkDirName = 1089 FileMgr.getCanonicalName(*SubframeworkDir); 1090 bool FoundParent = false; 1091 do { 1092 // Get the parent directory name. 1093 SubframeworkDirName 1094 = llvm::sys::path::parent_path(SubframeworkDirName); 1095 if (SubframeworkDirName.empty()) 1096 break; 1097 1098 if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) { 1099 if (*SubDir == FrameworkDir) { 1100 FoundParent = true; 1101 break; 1102 } 1103 } 1104 } while (true); 1105 1106 if (!FoundParent) 1107 continue; 1108 1109 // FIXME: Do we want to warn about subframeworks without umbrella headers? 1110 inferFrameworkModule(*SubframeworkDir, Attrs, Result); 1111 } 1112 } 1113 1114 // If the module is a top-level framework, automatically link against the 1115 // framework. 1116 if (!Result->isSubFramework()) { 1117 inferFrameworkLink(Result, FrameworkDir, FileMgr); 1118 } 1119 1120 return Result; 1121 } 1122 1123 Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework, 1124 Module *ShadowingModule) { 1125 1126 // Create a new module with this name. 1127 Module *Result = 1128 new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework, 1129 /*IsExplicit=*/false, NumCreatedModules++); 1130 Result->ShadowingModule = ShadowingModule; 1131 Result->markUnavailable(/*Unimportable*/true); 1132 ModuleScopeIDs[Result] = CurrentModuleScopeID; 1133 ShadowModules.push_back(Result); 1134 1135 return Result; 1136 } 1137 1138 void ModuleMap::setUmbrellaHeader( 1139 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, 1140 const Twine &PathRelativeToRootModuleDirectory) { 1141 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 1142 Mod->Umbrella = &UmbrellaHeader.getMapEntry(); 1143 Mod->UmbrellaAsWritten = NameAsWritten.str(); 1144 Mod->UmbrellaRelativeToRootModuleDirectory = 1145 PathRelativeToRootModuleDirectory.str(); 1146 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod; 1147 1148 // Notify callbacks that we just added a new header. 1149 for (const auto &Cb : Callbacks) 1150 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader); 1151 } 1152 1153 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, 1154 const Twine &NameAsWritten, 1155 const Twine &PathRelativeToRootModuleDirectory) { 1156 Mod->Umbrella = UmbrellaDir; 1157 Mod->UmbrellaAsWritten = NameAsWritten.str(); 1158 Mod->UmbrellaRelativeToRootModuleDirectory = 1159 PathRelativeToRootModuleDirectory.str(); 1160 UmbrellaDirs[UmbrellaDir] = Mod; 1161 } 1162 1163 void ModuleMap::addUnresolvedHeader(Module *Mod, 1164 Module::UnresolvedHeaderDirective Header, 1165 bool &NeedsFramework) { 1166 // If there is a builtin counterpart to this file, add it now so it can 1167 // wrap the system header. 1168 if (resolveAsBuiltinHeader(Mod, Header)) { 1169 // If we have both a builtin and system version of the file, the 1170 // builtin version may want to inject macros into the system header, so 1171 // force the system header to be treated as a textual header in this 1172 // case. 1173 Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole( 1174 headerKindToRole(Header.Kind) | ModuleMap::TextualHeader)); 1175 Header.HasBuiltinHeader = true; 1176 } 1177 1178 // If possible, don't stat the header until we need to. This requires the 1179 // user to have provided us with some stat information about the file. 1180 // FIXME: Add support for lazily stat'ing umbrella headers and excluded 1181 // headers. 1182 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella && 1183 Header.Kind != Module::HK_Excluded) { 1184 // We expect more variation in mtime than size, so if we're given both, 1185 // use the mtime as the key. 1186 if (Header.ModTime) 1187 LazyHeadersByModTime[*Header.ModTime].push_back(Mod); 1188 else 1189 LazyHeadersBySize[*Header.Size].push_back(Mod); 1190 Mod->UnresolvedHeaders.push_back(Header); 1191 return; 1192 } 1193 1194 // We don't have stat information or can't defer looking this file up. 1195 // Perform the lookup now. 1196 resolveHeader(Mod, Header, NeedsFramework); 1197 } 1198 1199 void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const { 1200 auto BySize = LazyHeadersBySize.find(File->getSize()); 1201 if (BySize != LazyHeadersBySize.end()) { 1202 for (auto *M : BySize->second) 1203 resolveHeaderDirectives(M, File); 1204 LazyHeadersBySize.erase(BySize); 1205 } 1206 1207 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime()); 1208 if (ByModTime != LazyHeadersByModTime.end()) { 1209 for (auto *M : ByModTime->second) 1210 resolveHeaderDirectives(M, File); 1211 LazyHeadersByModTime.erase(ByModTime); 1212 } 1213 } 1214 1215 void ModuleMap::resolveHeaderDirectives( 1216 Module *Mod, std::optional<const FileEntry *> File) const { 1217 bool NeedsFramework = false; 1218 SmallVector<Module::UnresolvedHeaderDirective, 1> NewHeaders; 1219 const auto Size = File ? (*File)->getSize() : 0; 1220 const auto ModTime = File ? (*File)->getModificationTime() : 0; 1221 1222 for (auto &Header : Mod->UnresolvedHeaders) { 1223 if (File && ((Header.ModTime && Header.ModTime != ModTime) || 1224 (Header.Size && Header.Size != Size))) 1225 NewHeaders.push_back(Header); 1226 else 1227 // This operation is logically const; we're just changing how we represent 1228 // the header information for this file. 1229 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework); 1230 } 1231 Mod->UnresolvedHeaders.swap(NewHeaders); 1232 } 1233 1234 void ModuleMap::addHeader(Module *Mod, Module::Header Header, 1235 ModuleHeaderRole Role, bool Imported) { 1236 KnownHeader KH(Mod, Role); 1237 1238 // Only add each header to the headers list once. 1239 // FIXME: Should we diagnose if a header is listed twice in the 1240 // same module definition? 1241 auto &HeaderList = Headers[Header.Entry]; 1242 if (llvm::is_contained(HeaderList, KH)) 1243 return; 1244 1245 HeaderList.push_back(KH); 1246 Mod->Headers[headerRoleToKind(Role)].push_back(Header); 1247 1248 bool isCompilingModuleHeader = 1249 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule; 1250 if (!Imported || isCompilingModuleHeader) { 1251 // When we import HeaderFileInfo, the external source is expected to 1252 // set the isModuleHeader flag itself. 1253 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 1254 isCompilingModuleHeader); 1255 } 1256 1257 // Notify callbacks that we just added a new header. 1258 for (const auto &Cb : Callbacks) 1259 Cb->moduleMapAddHeader(Header.Entry->getName()); 1260 } 1261 1262 OptionalFileEntryRef 1263 ModuleMap::getContainingModuleMapFile(const Module *Module) const { 1264 if (Module->DefinitionLoc.isInvalid()) 1265 return std::nullopt; 1266 1267 return SourceMgr.getFileEntryRefForID( 1268 SourceMgr.getFileID(Module->DefinitionLoc)); 1269 } 1270 1271 OptionalFileEntryRef 1272 ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 1273 if (M->IsInferred) { 1274 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 1275 // FIXME: Update InferredModuleAllowedBy to use FileEntryRef. 1276 return InferredModuleAllowedBy.find(M)->second->getLastRef(); 1277 } 1278 return getContainingModuleMapFile(M); 1279 } 1280 1281 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 1282 assert(M->IsInferred && "module not inferred"); 1283 InferredModuleAllowedBy[M] = ModMap; 1284 } 1285 1286 std::error_code 1287 ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) { 1288 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()}); 1289 1290 // Do not canonicalize within the framework; the module map parser expects 1291 // Modules/ not Versions/A/Modules. 1292 if (llvm::sys::path::filename(Dir) == "Modules") { 1293 StringRef Parent = llvm::sys::path::parent_path(Dir); 1294 if (Parent.endswith(".framework")) 1295 Dir = Parent; 1296 } 1297 1298 FileManager &FM = SourceMgr.getFileManager(); 1299 auto DirEntry = FM.getDirectory(Dir.empty() ? "." : Dir); 1300 if (!DirEntry) 1301 return DirEntry.getError(); 1302 1303 // Canonicalize the directory. 1304 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry); 1305 if (CanonicalDir != Dir) { 1306 auto CanonicalDirEntry = FM.getDirectory(CanonicalDir); 1307 // Only use the canonicalized path if it resolves to the same entry as the 1308 // original. This is not true if there's a VFS overlay on top of a FS where 1309 // the directory is a symlink. The overlay would not remap the target path 1310 // of the symlink to the same directory entry in that case. 1311 if (CanonicalDirEntry && *CanonicalDirEntry == *DirEntry) { 1312 bool Done = llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir); 1313 (void)Done; 1314 assert(Done && "Path should always start with Dir"); 1315 } 1316 } 1317 1318 // In theory, the filename component should also be canonicalized if it 1319 // on a case-insensitive filesystem. However, the extra canonicalization is 1320 // expensive and if clang looked up the filename it will always be lowercase. 1321 1322 // Remove ., remove redundant separators, and switch to native separators. 1323 // This is needed for separators between CanonicalDir and the filename. 1324 llvm::sys::path::remove_dots(Path); 1325 1326 return std::error_code(); 1327 } 1328 1329 void ModuleMap::addAdditionalModuleMapFile(const Module *M, 1330 const FileEntry *ModuleMap) { 1331 AdditionalModMaps[M].insert(ModuleMap); 1332 } 1333 1334 LLVM_DUMP_METHOD void ModuleMap::dump() { 1335 llvm::errs() << "Modules:"; 1336 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 1337 MEnd = Modules.end(); 1338 M != MEnd; ++M) 1339 M->getValue()->print(llvm::errs(), 2); 1340 1341 llvm::errs() << "Headers:"; 1342 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 1343 H != HEnd; ++H) { 1344 llvm::errs() << " \"" << H->first->getName() << "\" -> "; 1345 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 1346 E = H->second.end(); 1347 I != E; ++I) { 1348 if (I != H->second.begin()) 1349 llvm::errs() << ","; 1350 llvm::errs() << I->getModule()->getFullModuleName(); 1351 } 1352 llvm::errs() << "\n"; 1353 } 1354 } 1355 1356 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 1357 auto Unresolved = std::move(Mod->UnresolvedExports); 1358 Mod->UnresolvedExports.clear(); 1359 for (auto &UE : Unresolved) { 1360 Module::ExportDecl Export = resolveExport(Mod, UE, Complain); 1361 if (Export.getPointer() || Export.getInt()) 1362 Mod->Exports.push_back(Export); 1363 else 1364 Mod->UnresolvedExports.push_back(UE); 1365 } 1366 return !Mod->UnresolvedExports.empty(); 1367 } 1368 1369 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 1370 auto Unresolved = std::move(Mod->UnresolvedDirectUses); 1371 Mod->UnresolvedDirectUses.clear(); 1372 for (auto &UDU : Unresolved) { 1373 Module *DirectUse = resolveModuleId(UDU, Mod, Complain); 1374 if (DirectUse) 1375 Mod->DirectUses.push_back(DirectUse); 1376 else 1377 Mod->UnresolvedDirectUses.push_back(UDU); 1378 } 1379 return !Mod->UnresolvedDirectUses.empty(); 1380 } 1381 1382 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 1383 auto Unresolved = std::move(Mod->UnresolvedConflicts); 1384 Mod->UnresolvedConflicts.clear(); 1385 for (auto &UC : Unresolved) { 1386 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) { 1387 Module::Conflict Conflict; 1388 Conflict.Other = OtherMod; 1389 Conflict.Message = UC.Message; 1390 Mod->Conflicts.push_back(Conflict); 1391 } else 1392 Mod->UnresolvedConflicts.push_back(UC); 1393 } 1394 return !Mod->UnresolvedConflicts.empty(); 1395 } 1396 1397 //----------------------------------------------------------------------------// 1398 // Module map file parser 1399 //----------------------------------------------------------------------------// 1400 1401 namespace clang { 1402 1403 /// A token in a module map file. 1404 struct MMToken { 1405 enum TokenKind { 1406 Comma, 1407 ConfigMacros, 1408 Conflict, 1409 EndOfFile, 1410 HeaderKeyword, 1411 Identifier, 1412 Exclaim, 1413 ExcludeKeyword, 1414 ExplicitKeyword, 1415 ExportKeyword, 1416 ExportAsKeyword, 1417 ExternKeyword, 1418 FrameworkKeyword, 1419 LinkKeyword, 1420 ModuleKeyword, 1421 Period, 1422 PrivateKeyword, 1423 UmbrellaKeyword, 1424 UseKeyword, 1425 RequiresKeyword, 1426 Star, 1427 StringLiteral, 1428 IntegerLiteral, 1429 TextualKeyword, 1430 LBrace, 1431 RBrace, 1432 LSquare, 1433 RSquare 1434 } Kind; 1435 1436 SourceLocation::UIntTy Location; 1437 unsigned StringLength; 1438 union { 1439 // If Kind != IntegerLiteral. 1440 const char *StringData; 1441 1442 // If Kind == IntegerLiteral. 1443 uint64_t IntegerValue; 1444 }; 1445 1446 void clear() { 1447 Kind = EndOfFile; 1448 Location = 0; 1449 StringLength = 0; 1450 StringData = nullptr; 1451 } 1452 1453 bool is(TokenKind K) const { return Kind == K; } 1454 1455 SourceLocation getLocation() const { 1456 return SourceLocation::getFromRawEncoding(Location); 1457 } 1458 1459 uint64_t getInteger() const { 1460 return Kind == IntegerLiteral ? IntegerValue : 0; 1461 } 1462 1463 StringRef getString() const { 1464 return Kind == IntegerLiteral ? StringRef() 1465 : StringRef(StringData, StringLength); 1466 } 1467 }; 1468 1469 class ModuleMapParser { 1470 Lexer &L; 1471 SourceManager &SourceMgr; 1472 1473 /// Default target information, used only for string literal 1474 /// parsing. 1475 const TargetInfo *Target; 1476 1477 DiagnosticsEngine &Diags; 1478 ModuleMap ⤅ 1479 1480 /// The current module map file. 1481 const FileEntry *ModuleMapFile; 1482 1483 /// Source location of most recent parsed module declaration 1484 SourceLocation CurrModuleDeclLoc; 1485 1486 /// The directory that file names in this module map file should 1487 /// be resolved relative to. 1488 const DirectoryEntry *Directory; 1489 1490 /// Whether this module map is in a system header directory. 1491 bool IsSystem; 1492 1493 /// Whether an error occurred. 1494 bool HadError = false; 1495 1496 /// Stores string data for the various string literals referenced 1497 /// during parsing. 1498 llvm::BumpPtrAllocator StringData; 1499 1500 /// The current token. 1501 MMToken Tok; 1502 1503 /// The active module. 1504 Module *ActiveModule = nullptr; 1505 1506 /// Whether a module uses the 'requires excluded' hack to mark its 1507 /// contents as 'textual'. 1508 /// 1509 /// On older Darwin SDK versions, 'requires excluded' is used to mark the 1510 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as 1511 /// non-modular headers. For backwards compatibility, we continue to 1512 /// support this idiom for just these modules, and map the headers to 1513 /// 'textual' to match the original intent. 1514 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack; 1515 1516 /// Consume the current token and return its location. 1517 SourceLocation consumeToken(); 1518 1519 /// Skip tokens until we reach the a token with the given kind 1520 /// (or the end of the file). 1521 void skipUntil(MMToken::TokenKind K); 1522 1523 using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; 1524 1525 bool parseModuleId(ModuleId &Id); 1526 void parseModuleDecl(); 1527 void parseExternModuleDecl(); 1528 void parseRequiresDecl(); 1529 void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc); 1530 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1531 void parseExportDecl(); 1532 void parseExportAsDecl(); 1533 void parseUseDecl(); 1534 void parseLinkDecl(); 1535 void parseConfigMacros(); 1536 void parseConflict(); 1537 void parseInferredModuleDecl(bool Framework, bool Explicit); 1538 1539 /// Private modules are canonicalized as Foo_Private. Clang provides extra 1540 /// module map search logic to find the appropriate private module when PCH 1541 /// is used with implicit module maps. Warn when private modules are written 1542 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1543 void diagnosePrivateModules(SourceLocation ExplicitLoc, 1544 SourceLocation FrameworkLoc); 1545 1546 using Attributes = ModuleMap::Attributes; 1547 1548 bool parseOptionalAttributes(Attributes &Attrs); 1549 1550 public: 1551 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1552 const TargetInfo *Target, DiagnosticsEngine &Diags, 1553 ModuleMap &Map, const FileEntry *ModuleMapFile, 1554 const DirectoryEntry *Directory, bool IsSystem) 1555 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1556 ModuleMapFile(ModuleMapFile), Directory(Directory), 1557 IsSystem(IsSystem) { 1558 Tok.clear(); 1559 consumeToken(); 1560 } 1561 1562 bool parseModuleMapFile(); 1563 1564 bool terminatedByDirective() { return false; } 1565 SourceLocation getLocation() { return Tok.getLocation(); } 1566 }; 1567 1568 } // namespace clang 1569 1570 SourceLocation ModuleMapParser::consumeToken() { 1571 SourceLocation Result = Tok.getLocation(); 1572 1573 retry: 1574 Tok.clear(); 1575 Token LToken; 1576 L.LexFromRawLexer(LToken); 1577 Tok.Location = LToken.getLocation().getRawEncoding(); 1578 switch (LToken.getKind()) { 1579 case tok::raw_identifier: { 1580 StringRef RI = LToken.getRawIdentifier(); 1581 Tok.StringData = RI.data(); 1582 Tok.StringLength = RI.size(); 1583 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1584 .Case("config_macros", MMToken::ConfigMacros) 1585 .Case("conflict", MMToken::Conflict) 1586 .Case("exclude", MMToken::ExcludeKeyword) 1587 .Case("explicit", MMToken::ExplicitKeyword) 1588 .Case("export", MMToken::ExportKeyword) 1589 .Case("export_as", MMToken::ExportAsKeyword) 1590 .Case("extern", MMToken::ExternKeyword) 1591 .Case("framework", MMToken::FrameworkKeyword) 1592 .Case("header", MMToken::HeaderKeyword) 1593 .Case("link", MMToken::LinkKeyword) 1594 .Case("module", MMToken::ModuleKeyword) 1595 .Case("private", MMToken::PrivateKeyword) 1596 .Case("requires", MMToken::RequiresKeyword) 1597 .Case("textual", MMToken::TextualKeyword) 1598 .Case("umbrella", MMToken::UmbrellaKeyword) 1599 .Case("use", MMToken::UseKeyword) 1600 .Default(MMToken::Identifier); 1601 break; 1602 } 1603 1604 case tok::comma: 1605 Tok.Kind = MMToken::Comma; 1606 break; 1607 1608 case tok::eof: 1609 Tok.Kind = MMToken::EndOfFile; 1610 break; 1611 1612 case tok::l_brace: 1613 Tok.Kind = MMToken::LBrace; 1614 break; 1615 1616 case tok::l_square: 1617 Tok.Kind = MMToken::LSquare; 1618 break; 1619 1620 case tok::period: 1621 Tok.Kind = MMToken::Period; 1622 break; 1623 1624 case tok::r_brace: 1625 Tok.Kind = MMToken::RBrace; 1626 break; 1627 1628 case tok::r_square: 1629 Tok.Kind = MMToken::RSquare; 1630 break; 1631 1632 case tok::star: 1633 Tok.Kind = MMToken::Star; 1634 break; 1635 1636 case tok::exclaim: 1637 Tok.Kind = MMToken::Exclaim; 1638 break; 1639 1640 case tok::string_literal: { 1641 if (LToken.hasUDSuffix()) { 1642 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1643 HadError = true; 1644 goto retry; 1645 } 1646 1647 // Parse the string literal. 1648 LangOptions LangOpts; 1649 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1650 if (StringLiteral.hadError) 1651 goto retry; 1652 1653 // Copy the string literal into our string data allocator. 1654 unsigned Length = StringLiteral.GetStringLength(); 1655 char *Saved = StringData.Allocate<char>(Length + 1); 1656 memcpy(Saved, StringLiteral.GetString().data(), Length); 1657 Saved[Length] = 0; 1658 1659 // Form the token. 1660 Tok.Kind = MMToken::StringLiteral; 1661 Tok.StringData = Saved; 1662 Tok.StringLength = Length; 1663 break; 1664 } 1665 1666 case tok::numeric_constant: { 1667 // We don't support any suffixes or other complications. 1668 SmallString<32> SpellingBuffer; 1669 SpellingBuffer.resize(LToken.getLength() + 1); 1670 const char *Start = SpellingBuffer.data(); 1671 unsigned Length = 1672 Lexer::getSpelling(LToken, Start, SourceMgr, Map.LangOpts); 1673 uint64_t Value; 1674 if (StringRef(Start, Length).getAsInteger(0, Value)) { 1675 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1676 HadError = true; 1677 goto retry; 1678 } 1679 1680 Tok.Kind = MMToken::IntegerLiteral; 1681 Tok.IntegerValue = Value; 1682 break; 1683 } 1684 1685 case tok::comment: 1686 goto retry; 1687 1688 case tok::hash: 1689 // A module map can be terminated prematurely by 1690 // #pragma clang module contents 1691 // When building the module, we'll treat the rest of the file as the 1692 // contents of the module. 1693 { 1694 auto NextIsIdent = [&](StringRef Str) -> bool { 1695 L.LexFromRawLexer(LToken); 1696 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && 1697 LToken.getRawIdentifier() == Str; 1698 }; 1699 if (NextIsIdent("pragma") && NextIsIdent("clang") && 1700 NextIsIdent("module") && NextIsIdent("contents")) { 1701 Tok.Kind = MMToken::EndOfFile; 1702 break; 1703 } 1704 } 1705 [[fallthrough]]; 1706 1707 default: 1708 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1709 HadError = true; 1710 goto retry; 1711 } 1712 1713 return Result; 1714 } 1715 1716 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1717 unsigned braceDepth = 0; 1718 unsigned squareDepth = 0; 1719 do { 1720 switch (Tok.Kind) { 1721 case MMToken::EndOfFile: 1722 return; 1723 1724 case MMToken::LBrace: 1725 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1726 return; 1727 1728 ++braceDepth; 1729 break; 1730 1731 case MMToken::LSquare: 1732 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1733 return; 1734 1735 ++squareDepth; 1736 break; 1737 1738 case MMToken::RBrace: 1739 if (braceDepth > 0) 1740 --braceDepth; 1741 else if (Tok.is(K)) 1742 return; 1743 break; 1744 1745 case MMToken::RSquare: 1746 if (squareDepth > 0) 1747 --squareDepth; 1748 else if (Tok.is(K)) 1749 return; 1750 break; 1751 1752 default: 1753 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1754 return; 1755 break; 1756 } 1757 1758 consumeToken(); 1759 } while (true); 1760 } 1761 1762 /// Parse a module-id. 1763 /// 1764 /// module-id: 1765 /// identifier 1766 /// identifier '.' module-id 1767 /// 1768 /// \returns true if an error occurred, false otherwise. 1769 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1770 Id.clear(); 1771 do { 1772 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1773 Id.push_back( 1774 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 1775 consumeToken(); 1776 } else { 1777 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1778 return true; 1779 } 1780 1781 if (!Tok.is(MMToken::Period)) 1782 break; 1783 1784 consumeToken(); 1785 } while (true); 1786 1787 return false; 1788 } 1789 1790 namespace { 1791 1792 /// Enumerates the known attributes. 1793 enum AttributeKind { 1794 /// An unknown attribute. 1795 AT_unknown, 1796 1797 /// The 'system' attribute. 1798 AT_system, 1799 1800 /// The 'extern_c' attribute. 1801 AT_extern_c, 1802 1803 /// The 'exhaustive' attribute. 1804 AT_exhaustive, 1805 1806 /// The 'no_undeclared_includes' attribute. 1807 AT_no_undeclared_includes 1808 }; 1809 1810 } // namespace 1811 1812 /// Private modules are canonicalized as Foo_Private. Clang provides extra 1813 /// module map search logic to find the appropriate private module when PCH 1814 /// is used with implicit module maps. Warn when private modules are written 1815 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1816 void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc, 1817 SourceLocation FrameworkLoc) { 1818 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical, 1819 const Module *M, SourceRange ReplLoc) { 1820 auto D = Diags.Report(ActiveModule->DefinitionLoc, 1821 diag::note_mmap_rename_top_level_private_module); 1822 D << BadName << M->Name; 1823 D << FixItHint::CreateReplacement(ReplLoc, Canonical); 1824 }; 1825 1826 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1827 auto const *M = E->getValue(); 1828 if (M->Directory != ActiveModule->Directory) 1829 continue; 1830 1831 SmallString<128> FullName(ActiveModule->getFullModuleName()); 1832 if (!FullName.startswith(M->Name) && !FullName.endswith("Private")) 1833 continue; 1834 SmallString<128> FixedPrivModDecl; 1835 SmallString<128> Canonical(M->Name); 1836 Canonical.append("_Private"); 1837 1838 // Foo.Private -> Foo_Private 1839 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent && 1840 M->Name == ActiveModule->Parent->Name) { 1841 Diags.Report(ActiveModule->DefinitionLoc, 1842 diag::warn_mmap_mismatched_private_submodule) 1843 << FullName; 1844 1845 SourceLocation FixItInitBegin = CurrModuleDeclLoc; 1846 if (FrameworkLoc.isValid()) 1847 FixItInitBegin = FrameworkLoc; 1848 if (ExplicitLoc.isValid()) 1849 FixItInitBegin = ExplicitLoc; 1850 1851 if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework) 1852 FixedPrivModDecl.append("framework "); 1853 FixedPrivModDecl.append("module "); 1854 FixedPrivModDecl.append(Canonical); 1855 1856 GenNoteAndFixIt(FullName, FixedPrivModDecl, M, 1857 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc)); 1858 continue; 1859 } 1860 1861 // FooPrivate and whatnots -> Foo_Private 1862 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name && 1863 ActiveModule->Name != Canonical) { 1864 Diags.Report(ActiveModule->DefinitionLoc, 1865 diag::warn_mmap_mismatched_private_module_name) 1866 << ActiveModule->Name; 1867 GenNoteAndFixIt(ActiveModule->Name, Canonical, M, 1868 SourceRange(ActiveModule->DefinitionLoc)); 1869 } 1870 } 1871 } 1872 1873 /// Parse a module declaration. 1874 /// 1875 /// module-declaration: 1876 /// 'extern' 'module' module-id string-literal 1877 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1878 /// { module-member* } 1879 /// 1880 /// module-member: 1881 /// requires-declaration 1882 /// header-declaration 1883 /// submodule-declaration 1884 /// export-declaration 1885 /// export-as-declaration 1886 /// link-declaration 1887 /// 1888 /// submodule-declaration: 1889 /// module-declaration 1890 /// inferred-submodule-declaration 1891 void ModuleMapParser::parseModuleDecl() { 1892 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1893 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1894 if (Tok.is(MMToken::ExternKeyword)) { 1895 parseExternModuleDecl(); 1896 return; 1897 } 1898 1899 // Parse 'explicit' or 'framework' keyword, if present. 1900 SourceLocation ExplicitLoc; 1901 SourceLocation FrameworkLoc; 1902 bool Explicit = false; 1903 bool Framework = false; 1904 1905 // Parse 'explicit' keyword, if present. 1906 if (Tok.is(MMToken::ExplicitKeyword)) { 1907 ExplicitLoc = consumeToken(); 1908 Explicit = true; 1909 } 1910 1911 // Parse 'framework' keyword, if present. 1912 if (Tok.is(MMToken::FrameworkKeyword)) { 1913 FrameworkLoc = consumeToken(); 1914 Framework = true; 1915 } 1916 1917 // Parse 'module' keyword. 1918 if (!Tok.is(MMToken::ModuleKeyword)) { 1919 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1920 consumeToken(); 1921 HadError = true; 1922 return; 1923 } 1924 CurrModuleDeclLoc = consumeToken(); // 'module' keyword 1925 1926 // If we have a wildcard for the module name, this is an inferred submodule. 1927 // Parse it. 1928 if (Tok.is(MMToken::Star)) 1929 return parseInferredModuleDecl(Framework, Explicit); 1930 1931 // Parse the module name. 1932 ModuleId Id; 1933 if (parseModuleId(Id)) { 1934 HadError = true; 1935 return; 1936 } 1937 1938 if (ActiveModule) { 1939 if (Id.size() > 1) { 1940 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1941 << SourceRange(Id.front().second, Id.back().second); 1942 1943 HadError = true; 1944 return; 1945 } 1946 } else if (Id.size() == 1 && Explicit) { 1947 // Top-level modules can't be explicit. 1948 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1949 Explicit = false; 1950 ExplicitLoc = SourceLocation(); 1951 HadError = true; 1952 } 1953 1954 Module *PreviousActiveModule = ActiveModule; 1955 if (Id.size() > 1) { 1956 // This module map defines a submodule. Go find the module of which it 1957 // is a submodule. 1958 ActiveModule = nullptr; 1959 const Module *TopLevelModule = nullptr; 1960 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1961 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1962 if (I == 0) 1963 TopLevelModule = Next; 1964 ActiveModule = Next; 1965 continue; 1966 } 1967 1968 Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module) 1969 << Id[I].first << (ActiveModule != nullptr) 1970 << (ActiveModule 1971 ? ActiveModule->getTopLevelModule()->getFullModuleName() 1972 : ""); 1973 HadError = true; 1974 } 1975 1976 if (TopLevelModule && 1977 ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1978 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1979 "submodule defined in same file as 'module *' that allowed its " 1980 "top-level module"); 1981 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1982 } 1983 } 1984 1985 StringRef ModuleName = Id.back().first; 1986 SourceLocation ModuleNameLoc = Id.back().second; 1987 1988 // Parse the optional attribute list. 1989 Attributes Attrs; 1990 if (parseOptionalAttributes(Attrs)) 1991 return; 1992 1993 // Parse the opening brace. 1994 if (!Tok.is(MMToken::LBrace)) { 1995 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1996 << ModuleName; 1997 HadError = true; 1998 return; 1999 } 2000 SourceLocation LBraceLoc = consumeToken(); 2001 2002 // Determine whether this (sub)module has already been defined. 2003 Module *ShadowingModule = nullptr; 2004 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 2005 // We might see a (re)definition of a module that we already have a 2006 // definition for in two cases: 2007 // - If we loaded one definition from an AST file and we've just found a 2008 // corresponding definition in a module map file, or 2009 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid(); 2010 // - If we're building a (preprocessed) module and we've just loaded the 2011 // module map file from which it was created. 2012 bool ParsedAsMainInput = 2013 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 2014 Map.LangOpts.CurrentModule == ModuleName && 2015 SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 2016 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 2017 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) { 2018 // Skip the module definition. 2019 skipUntil(MMToken::RBrace); 2020 if (Tok.is(MMToken::RBrace)) 2021 consumeToken(); 2022 else { 2023 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2024 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2025 HadError = true; 2026 } 2027 return; 2028 } 2029 2030 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) { 2031 ShadowingModule = Existing; 2032 } else { 2033 // This is not a shawdowed module decl, it is an illegal redefinition. 2034 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 2035 << ModuleName; 2036 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 2037 2038 // Skip the module definition. 2039 skipUntil(MMToken::RBrace); 2040 if (Tok.is(MMToken::RBrace)) 2041 consumeToken(); 2042 2043 HadError = true; 2044 return; 2045 } 2046 } 2047 2048 // Start defining this module. 2049 if (ShadowingModule) { 2050 ActiveModule = 2051 Map.createShadowedModule(ModuleName, Framework, ShadowingModule); 2052 } else { 2053 ActiveModule = 2054 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit) 2055 .first; 2056 } 2057 2058 ActiveModule->DefinitionLoc = ModuleNameLoc; 2059 if (Attrs.IsSystem || IsSystem) 2060 ActiveModule->IsSystem = true; 2061 if (Attrs.IsExternC) 2062 ActiveModule->IsExternC = true; 2063 if (Attrs.NoUndeclaredIncludes) 2064 ActiveModule->NoUndeclaredIncludes = true; 2065 ActiveModule->Directory = Directory; 2066 2067 StringRef MapFileName(ModuleMapFile->getName()); 2068 if (MapFileName.endswith("module.private.modulemap") || 2069 MapFileName.endswith("module_private.map")) { 2070 ActiveModule->ModuleMapIsPrivate = true; 2071 } 2072 2073 // Private modules named as FooPrivate, Foo.Private or similar are likely a 2074 // user error; provide warnings, notes and fixits to direct users to use 2075 // Foo_Private instead. 2076 SourceLocation StartLoc = 2077 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); 2078 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && 2079 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule, 2080 StartLoc) && 2081 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name, 2082 StartLoc) && 2083 ActiveModule->ModuleMapIsPrivate) 2084 diagnosePrivateModules(ExplicitLoc, FrameworkLoc); 2085 2086 bool Done = false; 2087 do { 2088 switch (Tok.Kind) { 2089 case MMToken::EndOfFile: 2090 case MMToken::RBrace: 2091 Done = true; 2092 break; 2093 2094 case MMToken::ConfigMacros: 2095 parseConfigMacros(); 2096 break; 2097 2098 case MMToken::Conflict: 2099 parseConflict(); 2100 break; 2101 2102 case MMToken::ExplicitKeyword: 2103 case MMToken::ExternKeyword: 2104 case MMToken::FrameworkKeyword: 2105 case MMToken::ModuleKeyword: 2106 parseModuleDecl(); 2107 break; 2108 2109 case MMToken::ExportKeyword: 2110 parseExportDecl(); 2111 break; 2112 2113 case MMToken::ExportAsKeyword: 2114 parseExportAsDecl(); 2115 break; 2116 2117 case MMToken::UseKeyword: 2118 parseUseDecl(); 2119 break; 2120 2121 case MMToken::RequiresKeyword: 2122 parseRequiresDecl(); 2123 break; 2124 2125 case MMToken::TextualKeyword: 2126 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 2127 break; 2128 2129 case MMToken::UmbrellaKeyword: { 2130 SourceLocation UmbrellaLoc = consumeToken(); 2131 if (Tok.is(MMToken::HeaderKeyword)) 2132 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 2133 else 2134 parseUmbrellaDirDecl(UmbrellaLoc); 2135 break; 2136 } 2137 2138 case MMToken::ExcludeKeyword: 2139 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 2140 break; 2141 2142 case MMToken::PrivateKeyword: 2143 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 2144 break; 2145 2146 case MMToken::HeaderKeyword: 2147 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 2148 break; 2149 2150 case MMToken::LinkKeyword: 2151 parseLinkDecl(); 2152 break; 2153 2154 default: 2155 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 2156 consumeToken(); 2157 break; 2158 } 2159 } while (!Done); 2160 2161 if (Tok.is(MMToken::RBrace)) 2162 consumeToken(); 2163 else { 2164 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2165 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2166 HadError = true; 2167 } 2168 2169 // If the active module is a top-level framework, and there are no link 2170 // libraries, automatically link against the framework. 2171 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 2172 ActiveModule->LinkLibraries.empty()) { 2173 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 2174 } 2175 2176 // If the module meets all requirements but is still unavailable, mark the 2177 // whole tree as unavailable to prevent it from building. 2178 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable && 2179 ActiveModule->Parent) { 2180 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false); 2181 ActiveModule->getTopLevelModule()->MissingHeaders.append( 2182 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 2183 } 2184 2185 // We're done parsing this module. Pop back to the previous module. 2186 ActiveModule = PreviousActiveModule; 2187 } 2188 2189 /// Parse an extern module declaration. 2190 /// 2191 /// extern module-declaration: 2192 /// 'extern' 'module' module-id string-literal 2193 void ModuleMapParser::parseExternModuleDecl() { 2194 assert(Tok.is(MMToken::ExternKeyword)); 2195 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 2196 2197 // Parse 'module' keyword. 2198 if (!Tok.is(MMToken::ModuleKeyword)) { 2199 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2200 consumeToken(); 2201 HadError = true; 2202 return; 2203 } 2204 consumeToken(); // 'module' keyword 2205 2206 // Parse the module name. 2207 ModuleId Id; 2208 if (parseModuleId(Id)) { 2209 HadError = true; 2210 return; 2211 } 2212 2213 // Parse the referenced module map file name. 2214 if (!Tok.is(MMToken::StringLiteral)) { 2215 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 2216 HadError = true; 2217 return; 2218 } 2219 std::string FileName = std::string(Tok.getString()); 2220 consumeToken(); // filename 2221 2222 StringRef FileNameRef = FileName; 2223 SmallString<128> ModuleMapFileName; 2224 if (llvm::sys::path::is_relative(FileNameRef)) { 2225 ModuleMapFileName += Directory->getName(); 2226 llvm::sys::path::append(ModuleMapFileName, FileName); 2227 FileNameRef = ModuleMapFileName; 2228 } 2229 if (auto File = SourceMgr.getFileManager().getFile(FileNameRef)) 2230 Map.parseModuleMapFile( 2231 *File, IsSystem, 2232 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 2233 ? Directory 2234 : (*File)->getDir(), 2235 FileID(), nullptr, ExternLoc); 2236 } 2237 2238 /// Whether to add the requirement \p Feature to the module \p M. 2239 /// 2240 /// This preserves backwards compatibility for two hacks in the Darwin system 2241 /// module map files: 2242 /// 2243 /// 1. The use of 'requires excluded' to make headers non-modular, which 2244 /// should really be mapped to 'textual' now that we have this feature. We 2245 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 2246 /// true. Later, this bit will be used to map all the headers inside this 2247 /// module to 'textual'. 2248 /// 2249 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 2250 /// 2251 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 2252 /// was never correct and causes issues now that we check it, so drop it. 2253 static bool shouldAddRequirement(Module *M, StringRef Feature, 2254 bool &IsRequiresExcludedHack) { 2255 if (Feature == "excluded" && 2256 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 2257 M->fullModuleNameIs({"Tcl", "Private"}))) { 2258 IsRequiresExcludedHack = true; 2259 return false; 2260 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 2261 return false; 2262 } 2263 2264 return true; 2265 } 2266 2267 /// Parse a requires declaration. 2268 /// 2269 /// requires-declaration: 2270 /// 'requires' feature-list 2271 /// 2272 /// feature-list: 2273 /// feature ',' feature-list 2274 /// feature 2275 /// 2276 /// feature: 2277 /// '!'[opt] identifier 2278 void ModuleMapParser::parseRequiresDecl() { 2279 assert(Tok.is(MMToken::RequiresKeyword)); 2280 2281 // Parse 'requires' keyword. 2282 consumeToken(); 2283 2284 // Parse the feature-list. 2285 do { 2286 bool RequiredState = true; 2287 if (Tok.is(MMToken::Exclaim)) { 2288 RequiredState = false; 2289 consumeToken(); 2290 } 2291 2292 if (!Tok.is(MMToken::Identifier)) { 2293 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 2294 HadError = true; 2295 return; 2296 } 2297 2298 // Consume the feature name. 2299 std::string Feature = std::string(Tok.getString()); 2300 consumeToken(); 2301 2302 bool IsRequiresExcludedHack = false; 2303 bool ShouldAddRequirement = 2304 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2305 2306 if (IsRequiresExcludedHack) 2307 UsesRequiresExcludedHack.insert(ActiveModule); 2308 2309 if (ShouldAddRequirement) { 2310 // Add this feature. 2311 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2312 *Map.Target); 2313 } 2314 2315 if (!Tok.is(MMToken::Comma)) 2316 break; 2317 2318 // Consume the comma. 2319 consumeToken(); 2320 } while (true); 2321 } 2322 2323 /// Parse a header declaration. 2324 /// 2325 /// header-declaration: 2326 /// 'textual'[opt] 'header' string-literal 2327 /// 'private' 'textual'[opt] 'header' string-literal 2328 /// 'exclude' 'header' string-literal 2329 /// 'umbrella' 'header' string-literal 2330 /// 2331 /// FIXME: Support 'private textual header'. 2332 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2333 SourceLocation LeadingLoc) { 2334 // We've already consumed the first token. 2335 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2336 2337 if (LeadingToken == MMToken::PrivateKeyword) { 2338 Role = ModuleMap::PrivateHeader; 2339 // 'private' may optionally be followed by 'textual'. 2340 if (Tok.is(MMToken::TextualKeyword)) { 2341 LeadingToken = Tok.Kind; 2342 consumeToken(); 2343 } 2344 } else if (LeadingToken == MMToken::ExcludeKeyword) { 2345 Role = ModuleMap::ExcludedHeader; 2346 } 2347 2348 if (LeadingToken == MMToken::TextualKeyword) 2349 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2350 2351 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2352 // Mark this header 'textual' (see doc comment for 2353 // Module::UsesRequiresExcludedHack). 2354 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2355 } 2356 2357 if (LeadingToken != MMToken::HeaderKeyword) { 2358 if (!Tok.is(MMToken::HeaderKeyword)) { 2359 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2360 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2361 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2362 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2363 return; 2364 } 2365 consumeToken(); 2366 } 2367 2368 // Parse the header name. 2369 if (!Tok.is(MMToken::StringLiteral)) { 2370 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2371 << "header"; 2372 HadError = true; 2373 return; 2374 } 2375 Module::UnresolvedHeaderDirective Header; 2376 Header.FileName = std::string(Tok.getString()); 2377 Header.FileNameLoc = consumeToken(); 2378 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2379 Header.Kind = Map.headerRoleToKind(Role); 2380 2381 // Check whether we already have an umbrella. 2382 if (Header.IsUmbrella && ActiveModule->Umbrella) { 2383 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2384 << ActiveModule->getFullModuleName(); 2385 HadError = true; 2386 return; 2387 } 2388 2389 // If we were given stat information, parse it so we can skip looking for 2390 // the file. 2391 if (Tok.is(MMToken::LBrace)) { 2392 SourceLocation LBraceLoc = consumeToken(); 2393 2394 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2395 enum Attribute { Size, ModTime, Unknown }; 2396 StringRef Str = Tok.getString(); 2397 SourceLocation Loc = consumeToken(); 2398 switch (llvm::StringSwitch<Attribute>(Str) 2399 .Case("size", Size) 2400 .Case("mtime", ModTime) 2401 .Default(Unknown)) { 2402 case Size: 2403 if (Header.Size) 2404 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2405 if (!Tok.is(MMToken::IntegerLiteral)) { 2406 Diags.Report(Tok.getLocation(), 2407 diag::err_mmap_invalid_header_attribute_value) << Str; 2408 skipUntil(MMToken::RBrace); 2409 break; 2410 } 2411 Header.Size = Tok.getInteger(); 2412 consumeToken(); 2413 break; 2414 2415 case ModTime: 2416 if (Header.ModTime) 2417 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2418 if (!Tok.is(MMToken::IntegerLiteral)) { 2419 Diags.Report(Tok.getLocation(), 2420 diag::err_mmap_invalid_header_attribute_value) << Str; 2421 skipUntil(MMToken::RBrace); 2422 break; 2423 } 2424 Header.ModTime = Tok.getInteger(); 2425 consumeToken(); 2426 break; 2427 2428 case Unknown: 2429 Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2430 skipUntil(MMToken::RBrace); 2431 break; 2432 } 2433 } 2434 2435 if (Tok.is(MMToken::RBrace)) 2436 consumeToken(); 2437 else { 2438 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2439 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2440 HadError = true; 2441 } 2442 } 2443 2444 bool NeedsFramework = false; 2445 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework); 2446 2447 if (NeedsFramework && ActiveModule) 2448 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword) 2449 << ActiveModule->getFullModuleName() 2450 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module"); 2451 } 2452 2453 static int compareModuleHeaders(const Module::Header *A, 2454 const Module::Header *B) { 2455 return A->NameAsWritten.compare(B->NameAsWritten); 2456 } 2457 2458 /// Parse an umbrella directory declaration. 2459 /// 2460 /// umbrella-dir-declaration: 2461 /// umbrella string-literal 2462 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2463 // Parse the directory name. 2464 if (!Tok.is(MMToken::StringLiteral)) { 2465 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2466 << "umbrella"; 2467 HadError = true; 2468 return; 2469 } 2470 2471 std::string DirName = std::string(Tok.getString()); 2472 std::string DirNameAsWritten = DirName; 2473 SourceLocation DirNameLoc = consumeToken(); 2474 2475 // Check whether we already have an umbrella. 2476 if (ActiveModule->Umbrella) { 2477 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2478 << ActiveModule->getFullModuleName(); 2479 HadError = true; 2480 return; 2481 } 2482 2483 // Look for this file. 2484 const DirectoryEntry *Dir = nullptr; 2485 if (llvm::sys::path::is_absolute(DirName)) { 2486 if (auto D = SourceMgr.getFileManager().getDirectory(DirName)) 2487 Dir = *D; 2488 } else { 2489 SmallString<128> PathName; 2490 PathName = Directory->getName(); 2491 llvm::sys::path::append(PathName, DirName); 2492 if (auto D = SourceMgr.getFileManager().getDirectory(PathName)) 2493 Dir = *D; 2494 } 2495 2496 if (!Dir) { 2497 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2498 << DirName; 2499 return; 2500 } 2501 2502 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2503 // Mark this header 'textual' (see doc comment for 2504 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2505 // directory is relatively expensive, in practice this only applies to the 2506 // uncommonly used Tcl module on Darwin platforms. 2507 std::error_code EC; 2508 SmallVector<Module::Header, 6> Headers; 2509 llvm::vfs::FileSystem &FS = 2510 SourceMgr.getFileManager().getVirtualFileSystem(); 2511 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2512 I != E && !EC; I.increment(EC)) { 2513 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) { 2514 Module::Header Header = {"", std::string(I->path()), FE}; 2515 Headers.push_back(std::move(Header)); 2516 } 2517 } 2518 2519 // Sort header paths so that the pcm doesn't depend on iteration order. 2520 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2521 2522 for (auto &Header : Headers) 2523 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2524 return; 2525 } 2526 2527 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 2528 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2529 << OwningModule->getFullModuleName(); 2530 HadError = true; 2531 return; 2532 } 2533 2534 // Record this umbrella directory. 2535 Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName); 2536 } 2537 2538 /// Parse a module export declaration. 2539 /// 2540 /// export-declaration: 2541 /// 'export' wildcard-module-id 2542 /// 2543 /// wildcard-module-id: 2544 /// identifier 2545 /// '*' 2546 /// identifier '.' wildcard-module-id 2547 void ModuleMapParser::parseExportDecl() { 2548 assert(Tok.is(MMToken::ExportKeyword)); 2549 SourceLocation ExportLoc = consumeToken(); 2550 2551 // Parse the module-id with an optional wildcard at the end. 2552 ModuleId ParsedModuleId; 2553 bool Wildcard = false; 2554 do { 2555 // FIXME: Support string-literal module names here. 2556 if (Tok.is(MMToken::Identifier)) { 2557 ParsedModuleId.push_back( 2558 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 2559 consumeToken(); 2560 2561 if (Tok.is(MMToken::Period)) { 2562 consumeToken(); 2563 continue; 2564 } 2565 2566 break; 2567 } 2568 2569 if(Tok.is(MMToken::Star)) { 2570 Wildcard = true; 2571 consumeToken(); 2572 break; 2573 } 2574 2575 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2576 HadError = true; 2577 return; 2578 } while (true); 2579 2580 Module::UnresolvedExportDecl Unresolved = { 2581 ExportLoc, ParsedModuleId, Wildcard 2582 }; 2583 ActiveModule->UnresolvedExports.push_back(Unresolved); 2584 } 2585 2586 /// Parse a module export_as declaration. 2587 /// 2588 /// export-as-declaration: 2589 /// 'export_as' identifier 2590 void ModuleMapParser::parseExportAsDecl() { 2591 assert(Tok.is(MMToken::ExportAsKeyword)); 2592 consumeToken(); 2593 2594 if (!Tok.is(MMToken::Identifier)) { 2595 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2596 HadError = true; 2597 return; 2598 } 2599 2600 if (ActiveModule->Parent) { 2601 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); 2602 consumeToken(); 2603 return; 2604 } 2605 2606 if (!ActiveModule->ExportAsModule.empty()) { 2607 if (ActiveModule->ExportAsModule == Tok.getString()) { 2608 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) 2609 << ActiveModule->Name << Tok.getString(); 2610 } else { 2611 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) 2612 << ActiveModule->Name << ActiveModule->ExportAsModule 2613 << Tok.getString(); 2614 } 2615 } 2616 2617 ActiveModule->ExportAsModule = std::string(Tok.getString()); 2618 Map.addLinkAsDependency(ActiveModule); 2619 2620 consumeToken(); 2621 } 2622 2623 /// Parse a module use declaration. 2624 /// 2625 /// use-declaration: 2626 /// 'use' wildcard-module-id 2627 void ModuleMapParser::parseUseDecl() { 2628 assert(Tok.is(MMToken::UseKeyword)); 2629 auto KWLoc = consumeToken(); 2630 // Parse the module-id. 2631 ModuleId ParsedModuleId; 2632 parseModuleId(ParsedModuleId); 2633 2634 if (ActiveModule->Parent) 2635 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2636 else 2637 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2638 } 2639 2640 /// Parse a link declaration. 2641 /// 2642 /// module-declaration: 2643 /// 'link' 'framework'[opt] string-literal 2644 void ModuleMapParser::parseLinkDecl() { 2645 assert(Tok.is(MMToken::LinkKeyword)); 2646 SourceLocation LinkLoc = consumeToken(); 2647 2648 // Parse the optional 'framework' keyword. 2649 bool IsFramework = false; 2650 if (Tok.is(MMToken::FrameworkKeyword)) { 2651 consumeToken(); 2652 IsFramework = true; 2653 } 2654 2655 // Parse the library name 2656 if (!Tok.is(MMToken::StringLiteral)) { 2657 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2658 << IsFramework << SourceRange(LinkLoc); 2659 HadError = true; 2660 return; 2661 } 2662 2663 std::string LibraryName = std::string(Tok.getString()); 2664 consumeToken(); 2665 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2666 IsFramework)); 2667 } 2668 2669 /// Parse a configuration macro declaration. 2670 /// 2671 /// module-declaration: 2672 /// 'config_macros' attributes[opt] config-macro-list? 2673 /// 2674 /// config-macro-list: 2675 /// identifier (',' identifier)? 2676 void ModuleMapParser::parseConfigMacros() { 2677 assert(Tok.is(MMToken::ConfigMacros)); 2678 SourceLocation ConfigMacrosLoc = consumeToken(); 2679 2680 // Only top-level modules can have configuration macros. 2681 if (ActiveModule->Parent) { 2682 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2683 } 2684 2685 // Parse the optional attributes. 2686 Attributes Attrs; 2687 if (parseOptionalAttributes(Attrs)) 2688 return; 2689 2690 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2691 ActiveModule->ConfigMacrosExhaustive = true; 2692 } 2693 2694 // If we don't have an identifier, we're done. 2695 // FIXME: Support macros with the same name as a keyword here. 2696 if (!Tok.is(MMToken::Identifier)) 2697 return; 2698 2699 // Consume the first identifier. 2700 if (!ActiveModule->Parent) { 2701 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2702 } 2703 consumeToken(); 2704 2705 do { 2706 // If there's a comma, consume it. 2707 if (!Tok.is(MMToken::Comma)) 2708 break; 2709 consumeToken(); 2710 2711 // We expect to see a macro name here. 2712 // FIXME: Support macros with the same name as a keyword here. 2713 if (!Tok.is(MMToken::Identifier)) { 2714 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2715 break; 2716 } 2717 2718 // Consume the macro name. 2719 if (!ActiveModule->Parent) { 2720 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2721 } 2722 consumeToken(); 2723 } while (true); 2724 } 2725 2726 /// Format a module-id into a string. 2727 static std::string formatModuleId(const ModuleId &Id) { 2728 std::string result; 2729 { 2730 llvm::raw_string_ostream OS(result); 2731 2732 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2733 if (I) 2734 OS << "."; 2735 OS << Id[I].first; 2736 } 2737 } 2738 2739 return result; 2740 } 2741 2742 /// Parse a conflict declaration. 2743 /// 2744 /// module-declaration: 2745 /// 'conflict' module-id ',' string-literal 2746 void ModuleMapParser::parseConflict() { 2747 assert(Tok.is(MMToken::Conflict)); 2748 SourceLocation ConflictLoc = consumeToken(); 2749 Module::UnresolvedConflict Conflict; 2750 2751 // Parse the module-id. 2752 if (parseModuleId(Conflict.Id)) 2753 return; 2754 2755 // Parse the ','. 2756 if (!Tok.is(MMToken::Comma)) { 2757 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2758 << SourceRange(ConflictLoc); 2759 return; 2760 } 2761 consumeToken(); 2762 2763 // Parse the message. 2764 if (!Tok.is(MMToken::StringLiteral)) { 2765 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2766 << formatModuleId(Conflict.Id); 2767 return; 2768 } 2769 Conflict.Message = Tok.getString().str(); 2770 consumeToken(); 2771 2772 // Add this unresolved conflict. 2773 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2774 } 2775 2776 /// Parse an inferred module declaration (wildcard modules). 2777 /// 2778 /// module-declaration: 2779 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2780 /// { inferred-module-member* } 2781 /// 2782 /// inferred-module-member: 2783 /// 'export' '*' 2784 /// 'exclude' identifier 2785 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2786 assert(Tok.is(MMToken::Star)); 2787 SourceLocation StarLoc = consumeToken(); 2788 bool Failed = false; 2789 2790 // Inferred modules must be submodules. 2791 if (!ActiveModule && !Framework) { 2792 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2793 Failed = true; 2794 } 2795 2796 if (ActiveModule) { 2797 // Inferred modules must have umbrella directories. 2798 if (!Failed && ActiveModule->IsAvailable && 2799 !ActiveModule->getUmbrellaDir()) { 2800 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2801 Failed = true; 2802 } 2803 2804 // Check for redefinition of an inferred module. 2805 if (!Failed && ActiveModule->InferSubmodules) { 2806 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2807 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2808 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2809 diag::note_mmap_prev_definition); 2810 Failed = true; 2811 } 2812 2813 // Check for the 'framework' keyword, which is not permitted here. 2814 if (Framework) { 2815 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2816 Framework = false; 2817 } 2818 } else if (Explicit) { 2819 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2820 Explicit = false; 2821 } 2822 2823 // If there were any problems with this inferred submodule, skip its body. 2824 if (Failed) { 2825 if (Tok.is(MMToken::LBrace)) { 2826 consumeToken(); 2827 skipUntil(MMToken::RBrace); 2828 if (Tok.is(MMToken::RBrace)) 2829 consumeToken(); 2830 } 2831 HadError = true; 2832 return; 2833 } 2834 2835 // Parse optional attributes. 2836 Attributes Attrs; 2837 if (parseOptionalAttributes(Attrs)) 2838 return; 2839 2840 if (ActiveModule) { 2841 // Note that we have an inferred submodule. 2842 ActiveModule->InferSubmodules = true; 2843 ActiveModule->InferredSubmoduleLoc = StarLoc; 2844 ActiveModule->InferExplicitSubmodules = Explicit; 2845 } else { 2846 // We'll be inferring framework modules for this directory. 2847 Map.InferredDirectories[Directory].InferModules = true; 2848 Map.InferredDirectories[Directory].Attrs = Attrs; 2849 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2850 // FIXME: Handle the 'framework' keyword. 2851 } 2852 2853 // Parse the opening brace. 2854 if (!Tok.is(MMToken::LBrace)) { 2855 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2856 HadError = true; 2857 return; 2858 } 2859 SourceLocation LBraceLoc = consumeToken(); 2860 2861 // Parse the body of the inferred submodule. 2862 bool Done = false; 2863 do { 2864 switch (Tok.Kind) { 2865 case MMToken::EndOfFile: 2866 case MMToken::RBrace: 2867 Done = true; 2868 break; 2869 2870 case MMToken::ExcludeKeyword: 2871 if (ActiveModule) { 2872 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2873 << (ActiveModule != nullptr); 2874 consumeToken(); 2875 break; 2876 } 2877 2878 consumeToken(); 2879 // FIXME: Support string-literal module names here. 2880 if (!Tok.is(MMToken::Identifier)) { 2881 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2882 break; 2883 } 2884 2885 Map.InferredDirectories[Directory].ExcludedModules.push_back( 2886 std::string(Tok.getString())); 2887 consumeToken(); 2888 break; 2889 2890 case MMToken::ExportKeyword: 2891 if (!ActiveModule) { 2892 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2893 << (ActiveModule != nullptr); 2894 consumeToken(); 2895 break; 2896 } 2897 2898 consumeToken(); 2899 if (Tok.is(MMToken::Star)) 2900 ActiveModule->InferExportWildcard = true; 2901 else 2902 Diags.Report(Tok.getLocation(), 2903 diag::err_mmap_expected_export_wildcard); 2904 consumeToken(); 2905 break; 2906 2907 case MMToken::ExplicitKeyword: 2908 case MMToken::ModuleKeyword: 2909 case MMToken::HeaderKeyword: 2910 case MMToken::PrivateKeyword: 2911 case MMToken::UmbrellaKeyword: 2912 default: 2913 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2914 << (ActiveModule != nullptr); 2915 consumeToken(); 2916 break; 2917 } 2918 } while (!Done); 2919 2920 if (Tok.is(MMToken::RBrace)) 2921 consumeToken(); 2922 else { 2923 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2924 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2925 HadError = true; 2926 } 2927 } 2928 2929 /// Parse optional attributes. 2930 /// 2931 /// attributes: 2932 /// attribute attributes 2933 /// attribute 2934 /// 2935 /// attribute: 2936 /// [ identifier ] 2937 /// 2938 /// \param Attrs Will be filled in with the parsed attributes. 2939 /// 2940 /// \returns true if an error occurred, false otherwise. 2941 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2942 bool HadError = false; 2943 2944 while (Tok.is(MMToken::LSquare)) { 2945 // Consume the '['. 2946 SourceLocation LSquareLoc = consumeToken(); 2947 2948 // Check whether we have an attribute name here. 2949 if (!Tok.is(MMToken::Identifier)) { 2950 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2951 skipUntil(MMToken::RSquare); 2952 if (Tok.is(MMToken::RSquare)) 2953 consumeToken(); 2954 HadError = true; 2955 } 2956 2957 // Decode the attribute name. 2958 AttributeKind Attribute 2959 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2960 .Case("exhaustive", AT_exhaustive) 2961 .Case("extern_c", AT_extern_c) 2962 .Case("no_undeclared_includes", AT_no_undeclared_includes) 2963 .Case("system", AT_system) 2964 .Default(AT_unknown); 2965 switch (Attribute) { 2966 case AT_unknown: 2967 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2968 << Tok.getString(); 2969 break; 2970 2971 case AT_system: 2972 Attrs.IsSystem = true; 2973 break; 2974 2975 case AT_extern_c: 2976 Attrs.IsExternC = true; 2977 break; 2978 2979 case AT_exhaustive: 2980 Attrs.IsExhaustive = true; 2981 break; 2982 2983 case AT_no_undeclared_includes: 2984 Attrs.NoUndeclaredIncludes = true; 2985 break; 2986 } 2987 consumeToken(); 2988 2989 // Consume the ']'. 2990 if (!Tok.is(MMToken::RSquare)) { 2991 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2992 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2993 skipUntil(MMToken::RSquare); 2994 HadError = true; 2995 } 2996 2997 if (Tok.is(MMToken::RSquare)) 2998 consumeToken(); 2999 } 3000 3001 return HadError; 3002 } 3003 3004 /// Parse a module map file. 3005 /// 3006 /// module-map-file: 3007 /// module-declaration* 3008 bool ModuleMapParser::parseModuleMapFile() { 3009 do { 3010 switch (Tok.Kind) { 3011 case MMToken::EndOfFile: 3012 return HadError; 3013 3014 case MMToken::ExplicitKeyword: 3015 case MMToken::ExternKeyword: 3016 case MMToken::ModuleKeyword: 3017 case MMToken::FrameworkKeyword: 3018 parseModuleDecl(); 3019 break; 3020 3021 case MMToken::Comma: 3022 case MMToken::ConfigMacros: 3023 case MMToken::Conflict: 3024 case MMToken::Exclaim: 3025 case MMToken::ExcludeKeyword: 3026 case MMToken::ExportKeyword: 3027 case MMToken::ExportAsKeyword: 3028 case MMToken::HeaderKeyword: 3029 case MMToken::Identifier: 3030 case MMToken::LBrace: 3031 case MMToken::LinkKeyword: 3032 case MMToken::LSquare: 3033 case MMToken::Period: 3034 case MMToken::PrivateKeyword: 3035 case MMToken::RBrace: 3036 case MMToken::RSquare: 3037 case MMToken::RequiresKeyword: 3038 case MMToken::Star: 3039 case MMToken::StringLiteral: 3040 case MMToken::IntegerLiteral: 3041 case MMToken::TextualKeyword: 3042 case MMToken::UmbrellaKeyword: 3043 case MMToken::UseKeyword: 3044 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 3045 HadError = true; 3046 consumeToken(); 3047 break; 3048 } 3049 } while (true); 3050 } 3051 3052 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 3053 const DirectoryEntry *Dir, FileID ID, 3054 unsigned *Offset, 3055 SourceLocation ExternModuleLoc) { 3056 assert(Target && "Missing target information"); 3057 llvm::DenseMap<const FileEntry *, bool>::iterator Known 3058 = ParsedModuleMap.find(File); 3059 if (Known != ParsedModuleMap.end()) 3060 return Known->second; 3061 3062 // If the module map file wasn't already entered, do so now. 3063 if (ID.isInvalid()) { 3064 auto FileCharacter = 3065 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 3066 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 3067 } 3068 3069 assert(Target && "Missing target information"); 3070 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID); 3071 if (!Buffer) 3072 return ParsedModuleMap[File] = true; 3073 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 3074 "invalid buffer offset"); 3075 3076 // Parse this module map file. 3077 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 3078 Buffer->getBufferStart(), 3079 Buffer->getBufferStart() + (Offset ? *Offset : 0), 3080 Buffer->getBufferEnd()); 3081 SourceLocation Start = L.getSourceLocation(); 3082 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 3083 IsSystem); 3084 bool Result = Parser.parseModuleMapFile(); 3085 ParsedModuleMap[File] = Result; 3086 3087 if (Offset) { 3088 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 3089 assert(Loc.first == ID && "stopped in a different file?"); 3090 *Offset = Loc.second; 3091 } 3092 3093 // Notify callbacks that we parsed it. 3094 for (const auto &Cb : Callbacks) 3095 Cb->moduleMapFileRead(Start, *File, IsSystem); 3096 3097 return Result; 3098 } 3099