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