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 Unresolved = std::move(Mod->UnresolvedDirectUses); 1402 Mod->UnresolvedDirectUses.clear(); 1403 for (auto &UDU : Unresolved) { 1404 Module *DirectUse = resolveModuleId(UDU, Mod, Complain); 1405 if (DirectUse) 1406 Mod->DirectUses.push_back(DirectUse); 1407 else 1408 Mod->UnresolvedDirectUses.push_back(UDU); 1409 } 1410 return !Mod->UnresolvedDirectUses.empty(); 1411 } 1412 1413 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 1414 auto Unresolved = std::move(Mod->UnresolvedConflicts); 1415 Mod->UnresolvedConflicts.clear(); 1416 for (auto &UC : Unresolved) { 1417 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) { 1418 Module::Conflict Conflict; 1419 Conflict.Other = OtherMod; 1420 Conflict.Message = UC.Message; 1421 Mod->Conflicts.push_back(Conflict); 1422 } else 1423 Mod->UnresolvedConflicts.push_back(UC); 1424 } 1425 return !Mod->UnresolvedConflicts.empty(); 1426 } 1427 1428 //----------------------------------------------------------------------------// 1429 // Module map file parser 1430 //----------------------------------------------------------------------------// 1431 1432 namespace clang { 1433 1434 /// A token in a module map file. 1435 struct MMToken { 1436 enum TokenKind { 1437 Comma, 1438 ConfigMacros, 1439 Conflict, 1440 EndOfFile, 1441 HeaderKeyword, 1442 Identifier, 1443 Exclaim, 1444 ExcludeKeyword, 1445 ExplicitKeyword, 1446 ExportKeyword, 1447 ExportAsKeyword, 1448 ExternKeyword, 1449 FrameworkKeyword, 1450 LinkKeyword, 1451 ModuleKeyword, 1452 Period, 1453 PrivateKeyword, 1454 UmbrellaKeyword, 1455 UseKeyword, 1456 RequiresKeyword, 1457 Star, 1458 StringLiteral, 1459 IntegerLiteral, 1460 TextualKeyword, 1461 LBrace, 1462 RBrace, 1463 LSquare, 1464 RSquare 1465 } Kind; 1466 1467 SourceLocation::UIntTy Location; 1468 unsigned StringLength; 1469 union { 1470 // If Kind != IntegerLiteral. 1471 const char *StringData; 1472 1473 // If Kind == IntegerLiteral. 1474 uint64_t IntegerValue; 1475 }; 1476 1477 void clear() { 1478 Kind = EndOfFile; 1479 Location = 0; 1480 StringLength = 0; 1481 StringData = nullptr; 1482 } 1483 1484 bool is(TokenKind K) const { return Kind == K; } 1485 1486 SourceLocation getLocation() const { 1487 return SourceLocation::getFromRawEncoding(Location); 1488 } 1489 1490 uint64_t getInteger() const { 1491 return Kind == IntegerLiteral ? IntegerValue : 0; 1492 } 1493 1494 StringRef getString() const { 1495 return Kind == IntegerLiteral ? StringRef() 1496 : StringRef(StringData, StringLength); 1497 } 1498 }; 1499 1500 class ModuleMapParser { 1501 Lexer &L; 1502 SourceManager &SourceMgr; 1503 1504 /// Default target information, used only for string literal 1505 /// parsing. 1506 const TargetInfo *Target; 1507 1508 DiagnosticsEngine &Diags; 1509 ModuleMap ⤅ 1510 1511 /// The current module map file. 1512 FileEntryRef ModuleMapFile; 1513 1514 /// Source location of most recent parsed module declaration 1515 SourceLocation CurrModuleDeclLoc; 1516 1517 /// The directory that file names in this module map file should 1518 /// be resolved relative to. 1519 DirectoryEntryRef Directory; 1520 1521 /// Whether this module map is in a system header directory. 1522 bool IsSystem; 1523 1524 /// Whether an error occurred. 1525 bool HadError = false; 1526 1527 /// Stores string data for the various string literals referenced 1528 /// during parsing. 1529 llvm::BumpPtrAllocator StringData; 1530 1531 /// The current token. 1532 MMToken Tok; 1533 1534 /// The active module. 1535 Module *ActiveModule = nullptr; 1536 1537 /// Whether a module uses the 'requires excluded' hack to mark its 1538 /// contents as 'textual'. 1539 /// 1540 /// On older Darwin SDK versions, 'requires excluded' is used to mark the 1541 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as 1542 /// non-modular headers. For backwards compatibility, we continue to 1543 /// support this idiom for just these modules, and map the headers to 1544 /// 'textual' to match the original intent. 1545 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack; 1546 1547 /// Consume the current token and return its location. 1548 SourceLocation consumeToken(); 1549 1550 /// Skip tokens until we reach the a token with the given kind 1551 /// (or the end of the file). 1552 void skipUntil(MMToken::TokenKind K); 1553 1554 bool parseModuleId(ModuleId &Id); 1555 void parseModuleDecl(); 1556 void parseExternModuleDecl(); 1557 void parseRequiresDecl(); 1558 void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc); 1559 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1560 void parseExportDecl(); 1561 void parseExportAsDecl(); 1562 void parseUseDecl(); 1563 void parseLinkDecl(); 1564 void parseConfigMacros(); 1565 void parseConflict(); 1566 void parseInferredModuleDecl(bool Framework, bool Explicit); 1567 1568 /// Private modules are canonicalized as Foo_Private. Clang provides extra 1569 /// module map search logic to find the appropriate private module when PCH 1570 /// is used with implicit module maps. Warn when private modules are written 1571 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1572 void diagnosePrivateModules(SourceLocation ExplicitLoc, 1573 SourceLocation FrameworkLoc); 1574 1575 using Attributes = ModuleMap::Attributes; 1576 1577 bool parseOptionalAttributes(Attributes &Attrs); 1578 1579 public: 1580 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1581 const TargetInfo *Target, DiagnosticsEngine &Diags, 1582 ModuleMap &Map, FileEntryRef ModuleMapFile, 1583 DirectoryEntryRef Directory, bool IsSystem) 1584 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1585 ModuleMapFile(ModuleMapFile), Directory(Directory), 1586 IsSystem(IsSystem) { 1587 Tok.clear(); 1588 consumeToken(); 1589 } 1590 1591 bool parseModuleMapFile(); 1592 1593 bool terminatedByDirective() { return false; } 1594 SourceLocation getLocation() { return Tok.getLocation(); } 1595 }; 1596 1597 } // namespace clang 1598 1599 SourceLocation ModuleMapParser::consumeToken() { 1600 SourceLocation Result = Tok.getLocation(); 1601 1602 retry: 1603 Tok.clear(); 1604 Token LToken; 1605 L.LexFromRawLexer(LToken); 1606 Tok.Location = LToken.getLocation().getRawEncoding(); 1607 switch (LToken.getKind()) { 1608 case tok::raw_identifier: { 1609 StringRef RI = LToken.getRawIdentifier(); 1610 Tok.StringData = RI.data(); 1611 Tok.StringLength = RI.size(); 1612 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1613 .Case("config_macros", MMToken::ConfigMacros) 1614 .Case("conflict", MMToken::Conflict) 1615 .Case("exclude", MMToken::ExcludeKeyword) 1616 .Case("explicit", MMToken::ExplicitKeyword) 1617 .Case("export", MMToken::ExportKeyword) 1618 .Case("export_as", MMToken::ExportAsKeyword) 1619 .Case("extern", MMToken::ExternKeyword) 1620 .Case("framework", MMToken::FrameworkKeyword) 1621 .Case("header", MMToken::HeaderKeyword) 1622 .Case("link", MMToken::LinkKeyword) 1623 .Case("module", MMToken::ModuleKeyword) 1624 .Case("private", MMToken::PrivateKeyword) 1625 .Case("requires", MMToken::RequiresKeyword) 1626 .Case("textual", MMToken::TextualKeyword) 1627 .Case("umbrella", MMToken::UmbrellaKeyword) 1628 .Case("use", MMToken::UseKeyword) 1629 .Default(MMToken::Identifier); 1630 break; 1631 } 1632 1633 case tok::comma: 1634 Tok.Kind = MMToken::Comma; 1635 break; 1636 1637 case tok::eof: 1638 Tok.Kind = MMToken::EndOfFile; 1639 break; 1640 1641 case tok::l_brace: 1642 Tok.Kind = MMToken::LBrace; 1643 break; 1644 1645 case tok::l_square: 1646 Tok.Kind = MMToken::LSquare; 1647 break; 1648 1649 case tok::period: 1650 Tok.Kind = MMToken::Period; 1651 break; 1652 1653 case tok::r_brace: 1654 Tok.Kind = MMToken::RBrace; 1655 break; 1656 1657 case tok::r_square: 1658 Tok.Kind = MMToken::RSquare; 1659 break; 1660 1661 case tok::star: 1662 Tok.Kind = MMToken::Star; 1663 break; 1664 1665 case tok::exclaim: 1666 Tok.Kind = MMToken::Exclaim; 1667 break; 1668 1669 case tok::string_literal: { 1670 if (LToken.hasUDSuffix()) { 1671 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1672 HadError = true; 1673 goto retry; 1674 } 1675 1676 // Parse the string literal. 1677 LangOptions LangOpts; 1678 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1679 if (StringLiteral.hadError) 1680 goto retry; 1681 1682 // Copy the string literal into our string data allocator. 1683 unsigned Length = StringLiteral.GetStringLength(); 1684 char *Saved = StringData.Allocate<char>(Length + 1); 1685 memcpy(Saved, StringLiteral.GetString().data(), Length); 1686 Saved[Length] = 0; 1687 1688 // Form the token. 1689 Tok.Kind = MMToken::StringLiteral; 1690 Tok.StringData = Saved; 1691 Tok.StringLength = Length; 1692 break; 1693 } 1694 1695 case tok::numeric_constant: { 1696 // We don't support any suffixes or other complications. 1697 SmallString<32> SpellingBuffer; 1698 SpellingBuffer.resize(LToken.getLength() + 1); 1699 const char *Start = SpellingBuffer.data(); 1700 unsigned Length = 1701 Lexer::getSpelling(LToken, Start, SourceMgr, Map.LangOpts); 1702 uint64_t Value; 1703 if (StringRef(Start, Length).getAsInteger(0, Value)) { 1704 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1705 HadError = true; 1706 goto retry; 1707 } 1708 1709 Tok.Kind = MMToken::IntegerLiteral; 1710 Tok.IntegerValue = Value; 1711 break; 1712 } 1713 1714 case tok::comment: 1715 goto retry; 1716 1717 case tok::hash: 1718 // A module map can be terminated prematurely by 1719 // #pragma clang module contents 1720 // When building the module, we'll treat the rest of the file as the 1721 // contents of the module. 1722 { 1723 auto NextIsIdent = [&](StringRef Str) -> bool { 1724 L.LexFromRawLexer(LToken); 1725 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && 1726 LToken.getRawIdentifier() == Str; 1727 }; 1728 if (NextIsIdent("pragma") && NextIsIdent("clang") && 1729 NextIsIdent("module") && NextIsIdent("contents")) { 1730 Tok.Kind = MMToken::EndOfFile; 1731 break; 1732 } 1733 } 1734 [[fallthrough]]; 1735 1736 default: 1737 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1738 HadError = true; 1739 goto retry; 1740 } 1741 1742 return Result; 1743 } 1744 1745 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1746 unsigned braceDepth = 0; 1747 unsigned squareDepth = 0; 1748 do { 1749 switch (Tok.Kind) { 1750 case MMToken::EndOfFile: 1751 return; 1752 1753 case MMToken::LBrace: 1754 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1755 return; 1756 1757 ++braceDepth; 1758 break; 1759 1760 case MMToken::LSquare: 1761 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1762 return; 1763 1764 ++squareDepth; 1765 break; 1766 1767 case MMToken::RBrace: 1768 if (braceDepth > 0) 1769 --braceDepth; 1770 else if (Tok.is(K)) 1771 return; 1772 break; 1773 1774 case MMToken::RSquare: 1775 if (squareDepth > 0) 1776 --squareDepth; 1777 else if (Tok.is(K)) 1778 return; 1779 break; 1780 1781 default: 1782 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1783 return; 1784 break; 1785 } 1786 1787 consumeToken(); 1788 } while (true); 1789 } 1790 1791 /// Parse a module-id. 1792 /// 1793 /// module-id: 1794 /// identifier 1795 /// identifier '.' module-id 1796 /// 1797 /// \returns true if an error occurred, false otherwise. 1798 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1799 Id.clear(); 1800 do { 1801 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1802 Id.push_back( 1803 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 1804 consumeToken(); 1805 } else { 1806 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1807 return true; 1808 } 1809 1810 if (!Tok.is(MMToken::Period)) 1811 break; 1812 1813 consumeToken(); 1814 } while (true); 1815 1816 return false; 1817 } 1818 1819 namespace { 1820 1821 /// Enumerates the known attributes. 1822 enum AttributeKind { 1823 /// An unknown attribute. 1824 AT_unknown, 1825 1826 /// The 'system' attribute. 1827 AT_system, 1828 1829 /// The 'extern_c' attribute. 1830 AT_extern_c, 1831 1832 /// The 'exhaustive' attribute. 1833 AT_exhaustive, 1834 1835 /// The 'no_undeclared_includes' attribute. 1836 AT_no_undeclared_includes 1837 }; 1838 1839 } // namespace 1840 1841 /// Private modules are canonicalized as Foo_Private. Clang provides extra 1842 /// module map search logic to find the appropriate private module when PCH 1843 /// is used with implicit module maps. Warn when private modules are written 1844 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1845 void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc, 1846 SourceLocation FrameworkLoc) { 1847 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical, 1848 const Module *M, SourceRange ReplLoc) { 1849 auto D = Diags.Report(ActiveModule->DefinitionLoc, 1850 diag::note_mmap_rename_top_level_private_module); 1851 D << BadName << M->Name; 1852 D << FixItHint::CreateReplacement(ReplLoc, Canonical); 1853 }; 1854 1855 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1856 auto const *M = E->getValue(); 1857 if (M->Directory != ActiveModule->Directory) 1858 continue; 1859 1860 SmallString<128> FullName(ActiveModule->getFullModuleName()); 1861 if (!FullName.startswith(M->Name) && !FullName.endswith("Private")) 1862 continue; 1863 SmallString<128> FixedPrivModDecl; 1864 SmallString<128> Canonical(M->Name); 1865 Canonical.append("_Private"); 1866 1867 // Foo.Private -> Foo_Private 1868 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent && 1869 M->Name == ActiveModule->Parent->Name) { 1870 Diags.Report(ActiveModule->DefinitionLoc, 1871 diag::warn_mmap_mismatched_private_submodule) 1872 << FullName; 1873 1874 SourceLocation FixItInitBegin = CurrModuleDeclLoc; 1875 if (FrameworkLoc.isValid()) 1876 FixItInitBegin = FrameworkLoc; 1877 if (ExplicitLoc.isValid()) 1878 FixItInitBegin = ExplicitLoc; 1879 1880 if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework) 1881 FixedPrivModDecl.append("framework "); 1882 FixedPrivModDecl.append("module "); 1883 FixedPrivModDecl.append(Canonical); 1884 1885 GenNoteAndFixIt(FullName, FixedPrivModDecl, M, 1886 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc)); 1887 continue; 1888 } 1889 1890 // FooPrivate and whatnots -> Foo_Private 1891 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name && 1892 ActiveModule->Name != Canonical) { 1893 Diags.Report(ActiveModule->DefinitionLoc, 1894 diag::warn_mmap_mismatched_private_module_name) 1895 << ActiveModule->Name; 1896 GenNoteAndFixIt(ActiveModule->Name, Canonical, M, 1897 SourceRange(ActiveModule->DefinitionLoc)); 1898 } 1899 } 1900 } 1901 1902 /// Parse a module declaration. 1903 /// 1904 /// module-declaration: 1905 /// 'extern' 'module' module-id string-literal 1906 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1907 /// { module-member* } 1908 /// 1909 /// module-member: 1910 /// requires-declaration 1911 /// header-declaration 1912 /// submodule-declaration 1913 /// export-declaration 1914 /// export-as-declaration 1915 /// link-declaration 1916 /// 1917 /// submodule-declaration: 1918 /// module-declaration 1919 /// inferred-submodule-declaration 1920 void ModuleMapParser::parseModuleDecl() { 1921 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1922 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1923 if (Tok.is(MMToken::ExternKeyword)) { 1924 parseExternModuleDecl(); 1925 return; 1926 } 1927 1928 // Parse 'explicit' or 'framework' keyword, if present. 1929 SourceLocation ExplicitLoc; 1930 SourceLocation FrameworkLoc; 1931 bool Explicit = false; 1932 bool Framework = false; 1933 1934 // Parse 'explicit' keyword, if present. 1935 if (Tok.is(MMToken::ExplicitKeyword)) { 1936 ExplicitLoc = consumeToken(); 1937 Explicit = true; 1938 } 1939 1940 // Parse 'framework' keyword, if present. 1941 if (Tok.is(MMToken::FrameworkKeyword)) { 1942 FrameworkLoc = consumeToken(); 1943 Framework = true; 1944 } 1945 1946 // Parse 'module' keyword. 1947 if (!Tok.is(MMToken::ModuleKeyword)) { 1948 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1949 consumeToken(); 1950 HadError = true; 1951 return; 1952 } 1953 CurrModuleDeclLoc = consumeToken(); // 'module' keyword 1954 1955 // If we have a wildcard for the module name, this is an inferred submodule. 1956 // Parse it. 1957 if (Tok.is(MMToken::Star)) 1958 return parseInferredModuleDecl(Framework, Explicit); 1959 1960 // Parse the module name. 1961 ModuleId Id; 1962 if (parseModuleId(Id)) { 1963 HadError = true; 1964 return; 1965 } 1966 1967 if (ActiveModule) { 1968 if (Id.size() > 1) { 1969 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1970 << SourceRange(Id.front().second, Id.back().second); 1971 1972 HadError = true; 1973 return; 1974 } 1975 } else if (Id.size() == 1 && Explicit) { 1976 // Top-level modules can't be explicit. 1977 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1978 Explicit = false; 1979 ExplicitLoc = SourceLocation(); 1980 HadError = true; 1981 } 1982 1983 Module *PreviousActiveModule = ActiveModule; 1984 if (Id.size() > 1) { 1985 // This module map defines a submodule. Go find the module of which it 1986 // is a submodule. 1987 ActiveModule = nullptr; 1988 const Module *TopLevelModule = nullptr; 1989 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1990 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1991 if (I == 0) 1992 TopLevelModule = Next; 1993 ActiveModule = Next; 1994 continue; 1995 } 1996 1997 Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module) 1998 << Id[I].first << (ActiveModule != nullptr) 1999 << (ActiveModule 2000 ? ActiveModule->getTopLevelModule()->getFullModuleName() 2001 : ""); 2002 HadError = true; 2003 } 2004 2005 if (TopLevelModule && 2006 ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 2007 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 2008 "submodule defined in same file as 'module *' that allowed its " 2009 "top-level module"); 2010 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 2011 } 2012 } 2013 2014 StringRef ModuleName = Id.back().first; 2015 SourceLocation ModuleNameLoc = Id.back().second; 2016 2017 // Parse the optional attribute list. 2018 Attributes Attrs; 2019 if (parseOptionalAttributes(Attrs)) 2020 return; 2021 2022 // Parse the opening brace. 2023 if (!Tok.is(MMToken::LBrace)) { 2024 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 2025 << ModuleName; 2026 HadError = true; 2027 return; 2028 } 2029 SourceLocation LBraceLoc = consumeToken(); 2030 2031 // Determine whether this (sub)module has already been defined. 2032 Module *ShadowingModule = nullptr; 2033 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 2034 // We might see a (re)definition of a module that we already have a 2035 // definition for in four cases: 2036 // - If we loaded one definition from an AST file and we've just found a 2037 // corresponding definition in a module map file, or 2038 bool LoadedFromASTFile = Existing->IsFromModuleFile; 2039 // - If we previously inferred this module from different module map file. 2040 bool Inferred = Existing->IsInferred; 2041 // - If we're building a framework that vends a module map, we might've 2042 // previously seen the one in intermediate products and now the system 2043 // one. 2044 // FIXME: If we're parsing module map file that looks like this: 2045 // framework module FW { ... } 2046 // module FW.Sub { ... } 2047 // We can't check the framework qualifier, since it's not attached to 2048 // the definition of Sub. Checking that qualifier on \c Existing is 2049 // not correct either, since we might've previously seen: 2050 // module FW { ... } 2051 // module FW.Sub { ... } 2052 // We should enforce consistency of redefinitions so that we can rely 2053 // that \c Existing is part of a framework iff the redefinition of FW 2054 // we have just skipped had it too. Once we do that, stop checking 2055 // the local framework qualifier and only rely on \c Existing. 2056 bool PartOfFramework = Framework || Existing->isPartOfFramework(); 2057 // - If we're building a (preprocessed) module and we've just loaded the 2058 // module map file from which it was created. 2059 bool ParsedAsMainInput = 2060 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 2061 Map.LangOpts.CurrentModule == ModuleName && 2062 SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 2063 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 2064 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) { 2065 ActiveModule = PreviousActiveModule; 2066 // Skip the module definition. 2067 skipUntil(MMToken::RBrace); 2068 if (Tok.is(MMToken::RBrace)) 2069 consumeToken(); 2070 else { 2071 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2072 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2073 HadError = true; 2074 } 2075 return; 2076 } 2077 2078 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) { 2079 ShadowingModule = Existing; 2080 } else { 2081 // This is not a shawdowed module decl, it is an illegal redefinition. 2082 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 2083 << ModuleName; 2084 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 2085 2086 // Skip the module definition. 2087 skipUntil(MMToken::RBrace); 2088 if (Tok.is(MMToken::RBrace)) 2089 consumeToken(); 2090 2091 HadError = true; 2092 return; 2093 } 2094 } 2095 2096 // Start defining this module. 2097 if (ShadowingModule) { 2098 ActiveModule = 2099 Map.createShadowedModule(ModuleName, Framework, ShadowingModule); 2100 } else { 2101 ActiveModule = 2102 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit) 2103 .first; 2104 } 2105 2106 ActiveModule->DefinitionLoc = ModuleNameLoc; 2107 if (Attrs.IsSystem || IsSystem) 2108 ActiveModule->IsSystem = true; 2109 if (Attrs.IsExternC) 2110 ActiveModule->IsExternC = true; 2111 if (Attrs.NoUndeclaredIncludes) 2112 ActiveModule->NoUndeclaredIncludes = true; 2113 ActiveModule->Directory = Directory; 2114 2115 StringRef MapFileName(ModuleMapFile.getName()); 2116 if (MapFileName.endswith("module.private.modulemap") || 2117 MapFileName.endswith("module_private.map")) { 2118 ActiveModule->ModuleMapIsPrivate = true; 2119 } 2120 2121 // Private modules named as FooPrivate, Foo.Private or similar are likely a 2122 // user error; provide warnings, notes and fixits to direct users to use 2123 // Foo_Private instead. 2124 SourceLocation StartLoc = 2125 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); 2126 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && 2127 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule, 2128 StartLoc) && 2129 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name, 2130 StartLoc) && 2131 ActiveModule->ModuleMapIsPrivate) 2132 diagnosePrivateModules(ExplicitLoc, FrameworkLoc); 2133 2134 bool Done = false; 2135 do { 2136 switch (Tok.Kind) { 2137 case MMToken::EndOfFile: 2138 case MMToken::RBrace: 2139 Done = true; 2140 break; 2141 2142 case MMToken::ConfigMacros: 2143 parseConfigMacros(); 2144 break; 2145 2146 case MMToken::Conflict: 2147 parseConflict(); 2148 break; 2149 2150 case MMToken::ExplicitKeyword: 2151 case MMToken::ExternKeyword: 2152 case MMToken::FrameworkKeyword: 2153 case MMToken::ModuleKeyword: 2154 parseModuleDecl(); 2155 break; 2156 2157 case MMToken::ExportKeyword: 2158 parseExportDecl(); 2159 break; 2160 2161 case MMToken::ExportAsKeyword: 2162 parseExportAsDecl(); 2163 break; 2164 2165 case MMToken::UseKeyword: 2166 parseUseDecl(); 2167 break; 2168 2169 case MMToken::RequiresKeyword: 2170 parseRequiresDecl(); 2171 break; 2172 2173 case MMToken::TextualKeyword: 2174 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 2175 break; 2176 2177 case MMToken::UmbrellaKeyword: { 2178 SourceLocation UmbrellaLoc = consumeToken(); 2179 if (Tok.is(MMToken::HeaderKeyword)) 2180 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 2181 else 2182 parseUmbrellaDirDecl(UmbrellaLoc); 2183 break; 2184 } 2185 2186 case MMToken::ExcludeKeyword: 2187 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 2188 break; 2189 2190 case MMToken::PrivateKeyword: 2191 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 2192 break; 2193 2194 case MMToken::HeaderKeyword: 2195 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 2196 break; 2197 2198 case MMToken::LinkKeyword: 2199 parseLinkDecl(); 2200 break; 2201 2202 default: 2203 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 2204 consumeToken(); 2205 break; 2206 } 2207 } while (!Done); 2208 2209 if (Tok.is(MMToken::RBrace)) 2210 consumeToken(); 2211 else { 2212 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2213 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2214 HadError = true; 2215 } 2216 2217 // If the active module is a top-level framework, and there are no link 2218 // libraries, automatically link against the framework. 2219 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 2220 ActiveModule->LinkLibraries.empty()) 2221 inferFrameworkLink(ActiveModule); 2222 2223 // If the module meets all requirements but is still unavailable, mark the 2224 // whole tree as unavailable to prevent it from building. 2225 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable && 2226 ActiveModule->Parent) { 2227 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false); 2228 ActiveModule->getTopLevelModule()->MissingHeaders.append( 2229 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 2230 } 2231 2232 // We're done parsing this module. Pop back to the previous module. 2233 ActiveModule = PreviousActiveModule; 2234 } 2235 2236 /// Parse an extern module declaration. 2237 /// 2238 /// extern module-declaration: 2239 /// 'extern' 'module' module-id string-literal 2240 void ModuleMapParser::parseExternModuleDecl() { 2241 assert(Tok.is(MMToken::ExternKeyword)); 2242 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 2243 2244 // Parse 'module' keyword. 2245 if (!Tok.is(MMToken::ModuleKeyword)) { 2246 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2247 consumeToken(); 2248 HadError = true; 2249 return; 2250 } 2251 consumeToken(); // 'module' keyword 2252 2253 // Parse the module name. 2254 ModuleId Id; 2255 if (parseModuleId(Id)) { 2256 HadError = true; 2257 return; 2258 } 2259 2260 // Parse the referenced module map file name. 2261 if (!Tok.is(MMToken::StringLiteral)) { 2262 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 2263 HadError = true; 2264 return; 2265 } 2266 std::string FileName = std::string(Tok.getString()); 2267 consumeToken(); // filename 2268 2269 StringRef FileNameRef = FileName; 2270 SmallString<128> ModuleMapFileName; 2271 if (llvm::sys::path::is_relative(FileNameRef)) { 2272 ModuleMapFileName += Directory.getName(); 2273 llvm::sys::path::append(ModuleMapFileName, FileName); 2274 FileNameRef = ModuleMapFileName; 2275 } 2276 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) 2277 Map.parseModuleMapFile( 2278 *File, IsSystem, 2279 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 2280 ? Directory 2281 : File->getDir(), 2282 FileID(), nullptr, ExternLoc); 2283 } 2284 2285 /// Whether to add the requirement \p Feature to the module \p M. 2286 /// 2287 /// This preserves backwards compatibility for two hacks in the Darwin system 2288 /// module map files: 2289 /// 2290 /// 1. The use of 'requires excluded' to make headers non-modular, which 2291 /// should really be mapped to 'textual' now that we have this feature. We 2292 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 2293 /// true. Later, this bit will be used to map all the headers inside this 2294 /// module to 'textual'. 2295 /// 2296 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 2297 /// 2298 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 2299 /// was never correct and causes issues now that we check it, so drop it. 2300 static bool shouldAddRequirement(Module *M, StringRef Feature, 2301 bool &IsRequiresExcludedHack) { 2302 if (Feature == "excluded" && 2303 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 2304 M->fullModuleNameIs({"Tcl", "Private"}))) { 2305 IsRequiresExcludedHack = true; 2306 return false; 2307 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 2308 return false; 2309 } 2310 2311 return true; 2312 } 2313 2314 /// Parse a requires declaration. 2315 /// 2316 /// requires-declaration: 2317 /// 'requires' feature-list 2318 /// 2319 /// feature-list: 2320 /// feature ',' feature-list 2321 /// feature 2322 /// 2323 /// feature: 2324 /// '!'[opt] identifier 2325 void ModuleMapParser::parseRequiresDecl() { 2326 assert(Tok.is(MMToken::RequiresKeyword)); 2327 2328 // Parse 'requires' keyword. 2329 consumeToken(); 2330 2331 // Parse the feature-list. 2332 do { 2333 bool RequiredState = true; 2334 if (Tok.is(MMToken::Exclaim)) { 2335 RequiredState = false; 2336 consumeToken(); 2337 } 2338 2339 if (!Tok.is(MMToken::Identifier)) { 2340 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 2341 HadError = true; 2342 return; 2343 } 2344 2345 // Consume the feature name. 2346 std::string Feature = std::string(Tok.getString()); 2347 consumeToken(); 2348 2349 bool IsRequiresExcludedHack = false; 2350 bool ShouldAddRequirement = 2351 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2352 2353 if (IsRequiresExcludedHack) 2354 UsesRequiresExcludedHack.insert(ActiveModule); 2355 2356 if (ShouldAddRequirement) { 2357 // Add this feature. 2358 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2359 *Map.Target); 2360 } 2361 2362 if (!Tok.is(MMToken::Comma)) 2363 break; 2364 2365 // Consume the comma. 2366 consumeToken(); 2367 } while (true); 2368 } 2369 2370 /// Parse a header declaration. 2371 /// 2372 /// header-declaration: 2373 /// 'textual'[opt] 'header' string-literal 2374 /// 'private' 'textual'[opt] 'header' string-literal 2375 /// 'exclude' 'header' string-literal 2376 /// 'umbrella' 'header' string-literal 2377 /// 2378 /// FIXME: Support 'private textual header'. 2379 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2380 SourceLocation LeadingLoc) { 2381 // We've already consumed the first token. 2382 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2383 2384 if (LeadingToken == MMToken::PrivateKeyword) { 2385 Role = ModuleMap::PrivateHeader; 2386 // 'private' may optionally be followed by 'textual'. 2387 if (Tok.is(MMToken::TextualKeyword)) { 2388 LeadingToken = Tok.Kind; 2389 consumeToken(); 2390 } 2391 } else if (LeadingToken == MMToken::ExcludeKeyword) { 2392 Role = ModuleMap::ExcludedHeader; 2393 } 2394 2395 if (LeadingToken == MMToken::TextualKeyword) 2396 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2397 2398 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2399 // Mark this header 'textual' (see doc comment for 2400 // Module::UsesRequiresExcludedHack). 2401 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2402 } 2403 2404 if (LeadingToken != MMToken::HeaderKeyword) { 2405 if (!Tok.is(MMToken::HeaderKeyword)) { 2406 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2407 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2408 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2409 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2410 return; 2411 } 2412 consumeToken(); 2413 } 2414 2415 // Parse the header name. 2416 if (!Tok.is(MMToken::StringLiteral)) { 2417 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2418 << "header"; 2419 HadError = true; 2420 return; 2421 } 2422 Module::UnresolvedHeaderDirective Header; 2423 Header.FileName = std::string(Tok.getString()); 2424 Header.FileNameLoc = consumeToken(); 2425 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2426 Header.Kind = Map.headerRoleToKind(Role); 2427 2428 // Check whether we already have an umbrella. 2429 if (Header.IsUmbrella && 2430 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) { 2431 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2432 << ActiveModule->getFullModuleName(); 2433 HadError = true; 2434 return; 2435 } 2436 2437 // If we were given stat information, parse it so we can skip looking for 2438 // the file. 2439 if (Tok.is(MMToken::LBrace)) { 2440 SourceLocation LBraceLoc = consumeToken(); 2441 2442 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2443 enum Attribute { Size, ModTime, Unknown }; 2444 StringRef Str = Tok.getString(); 2445 SourceLocation Loc = consumeToken(); 2446 switch (llvm::StringSwitch<Attribute>(Str) 2447 .Case("size", Size) 2448 .Case("mtime", ModTime) 2449 .Default(Unknown)) { 2450 case Size: 2451 if (Header.Size) 2452 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2453 if (!Tok.is(MMToken::IntegerLiteral)) { 2454 Diags.Report(Tok.getLocation(), 2455 diag::err_mmap_invalid_header_attribute_value) << Str; 2456 skipUntil(MMToken::RBrace); 2457 break; 2458 } 2459 Header.Size = Tok.getInteger(); 2460 consumeToken(); 2461 break; 2462 2463 case ModTime: 2464 if (Header.ModTime) 2465 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2466 if (!Tok.is(MMToken::IntegerLiteral)) { 2467 Diags.Report(Tok.getLocation(), 2468 diag::err_mmap_invalid_header_attribute_value) << Str; 2469 skipUntil(MMToken::RBrace); 2470 break; 2471 } 2472 Header.ModTime = Tok.getInteger(); 2473 consumeToken(); 2474 break; 2475 2476 case Unknown: 2477 Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2478 skipUntil(MMToken::RBrace); 2479 break; 2480 } 2481 } 2482 2483 if (Tok.is(MMToken::RBrace)) 2484 consumeToken(); 2485 else { 2486 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2487 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2488 HadError = true; 2489 } 2490 } 2491 2492 bool NeedsFramework = false; 2493 // Don't add the top level headers to the builtin modules if the builtin headers 2494 // belong to the system modules. 2495 if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name)) 2496 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework); 2497 2498 if (NeedsFramework) 2499 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword) 2500 << ActiveModule->getFullModuleName() 2501 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module"); 2502 } 2503 2504 static int compareModuleHeaders(const Module::Header *A, 2505 const Module::Header *B) { 2506 return A->NameAsWritten.compare(B->NameAsWritten); 2507 } 2508 2509 /// Parse an umbrella directory declaration. 2510 /// 2511 /// umbrella-dir-declaration: 2512 /// umbrella string-literal 2513 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2514 // Parse the directory name. 2515 if (!Tok.is(MMToken::StringLiteral)) { 2516 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2517 << "umbrella"; 2518 HadError = true; 2519 return; 2520 } 2521 2522 std::string DirName = std::string(Tok.getString()); 2523 std::string DirNameAsWritten = DirName; 2524 SourceLocation DirNameLoc = consumeToken(); 2525 2526 // Check whether we already have an umbrella. 2527 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) { 2528 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2529 << ActiveModule->getFullModuleName(); 2530 HadError = true; 2531 return; 2532 } 2533 2534 // Look for this file. 2535 OptionalDirectoryEntryRef Dir; 2536 if (llvm::sys::path::is_absolute(DirName)) { 2537 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName); 2538 } else { 2539 SmallString<128> PathName; 2540 PathName = Directory.getName(); 2541 llvm::sys::path::append(PathName, DirName); 2542 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName); 2543 } 2544 2545 if (!Dir) { 2546 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2547 << DirName; 2548 return; 2549 } 2550 2551 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2552 // Mark this header 'textual' (see doc comment for 2553 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2554 // directory is relatively expensive, in practice this only applies to the 2555 // uncommonly used Tcl module on Darwin platforms. 2556 std::error_code EC; 2557 SmallVector<Module::Header, 6> Headers; 2558 llvm::vfs::FileSystem &FS = 2559 SourceMgr.getFileManager().getVirtualFileSystem(); 2560 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2561 I != E && !EC; I.increment(EC)) { 2562 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) { 2563 Module::Header Header = {"", std::string(I->path()), *FE}; 2564 Headers.push_back(std::move(Header)); 2565 } 2566 } 2567 2568 // Sort header paths so that the pcm doesn't depend on iteration order. 2569 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2570 2571 for (auto &Header : Headers) 2572 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2573 return; 2574 } 2575 2576 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) { 2577 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2578 << OwningModule->getFullModuleName(); 2579 HadError = true; 2580 return; 2581 } 2582 2583 // Record this umbrella directory. 2584 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName); 2585 } 2586 2587 /// Parse a module export declaration. 2588 /// 2589 /// export-declaration: 2590 /// 'export' wildcard-module-id 2591 /// 2592 /// wildcard-module-id: 2593 /// identifier 2594 /// '*' 2595 /// identifier '.' wildcard-module-id 2596 void ModuleMapParser::parseExportDecl() { 2597 assert(Tok.is(MMToken::ExportKeyword)); 2598 SourceLocation ExportLoc = consumeToken(); 2599 2600 // Parse the module-id with an optional wildcard at the end. 2601 ModuleId ParsedModuleId; 2602 bool Wildcard = false; 2603 do { 2604 // FIXME: Support string-literal module names here. 2605 if (Tok.is(MMToken::Identifier)) { 2606 ParsedModuleId.push_back( 2607 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 2608 consumeToken(); 2609 2610 if (Tok.is(MMToken::Period)) { 2611 consumeToken(); 2612 continue; 2613 } 2614 2615 break; 2616 } 2617 2618 if(Tok.is(MMToken::Star)) { 2619 Wildcard = true; 2620 consumeToken(); 2621 break; 2622 } 2623 2624 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2625 HadError = true; 2626 return; 2627 } while (true); 2628 2629 Module::UnresolvedExportDecl Unresolved = { 2630 ExportLoc, ParsedModuleId, Wildcard 2631 }; 2632 ActiveModule->UnresolvedExports.push_back(Unresolved); 2633 } 2634 2635 /// Parse a module export_as declaration. 2636 /// 2637 /// export-as-declaration: 2638 /// 'export_as' identifier 2639 void ModuleMapParser::parseExportAsDecl() { 2640 assert(Tok.is(MMToken::ExportAsKeyword)); 2641 consumeToken(); 2642 2643 if (!Tok.is(MMToken::Identifier)) { 2644 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2645 HadError = true; 2646 return; 2647 } 2648 2649 if (ActiveModule->Parent) { 2650 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); 2651 consumeToken(); 2652 return; 2653 } 2654 2655 if (!ActiveModule->ExportAsModule.empty()) { 2656 if (ActiveModule->ExportAsModule == Tok.getString()) { 2657 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) 2658 << ActiveModule->Name << Tok.getString(); 2659 } else { 2660 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) 2661 << ActiveModule->Name << ActiveModule->ExportAsModule 2662 << Tok.getString(); 2663 } 2664 } 2665 2666 ActiveModule->ExportAsModule = std::string(Tok.getString()); 2667 Map.addLinkAsDependency(ActiveModule); 2668 2669 consumeToken(); 2670 } 2671 2672 /// Parse a module use declaration. 2673 /// 2674 /// use-declaration: 2675 /// 'use' wildcard-module-id 2676 void ModuleMapParser::parseUseDecl() { 2677 assert(Tok.is(MMToken::UseKeyword)); 2678 auto KWLoc = consumeToken(); 2679 // Parse the module-id. 2680 ModuleId ParsedModuleId; 2681 parseModuleId(ParsedModuleId); 2682 2683 if (ActiveModule->Parent) 2684 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2685 else 2686 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2687 } 2688 2689 /// Parse a link declaration. 2690 /// 2691 /// module-declaration: 2692 /// 'link' 'framework'[opt] string-literal 2693 void ModuleMapParser::parseLinkDecl() { 2694 assert(Tok.is(MMToken::LinkKeyword)); 2695 SourceLocation LinkLoc = consumeToken(); 2696 2697 // Parse the optional 'framework' keyword. 2698 bool IsFramework = false; 2699 if (Tok.is(MMToken::FrameworkKeyword)) { 2700 consumeToken(); 2701 IsFramework = true; 2702 } 2703 2704 // Parse the library name 2705 if (!Tok.is(MMToken::StringLiteral)) { 2706 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2707 << IsFramework << SourceRange(LinkLoc); 2708 HadError = true; 2709 return; 2710 } 2711 2712 std::string LibraryName = std::string(Tok.getString()); 2713 consumeToken(); 2714 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2715 IsFramework)); 2716 } 2717 2718 /// Parse a configuration macro declaration. 2719 /// 2720 /// module-declaration: 2721 /// 'config_macros' attributes[opt] config-macro-list? 2722 /// 2723 /// config-macro-list: 2724 /// identifier (',' identifier)? 2725 void ModuleMapParser::parseConfigMacros() { 2726 assert(Tok.is(MMToken::ConfigMacros)); 2727 SourceLocation ConfigMacrosLoc = consumeToken(); 2728 2729 // Only top-level modules can have configuration macros. 2730 if (ActiveModule->Parent) { 2731 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2732 } 2733 2734 // Parse the optional attributes. 2735 Attributes Attrs; 2736 if (parseOptionalAttributes(Attrs)) 2737 return; 2738 2739 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2740 ActiveModule->ConfigMacrosExhaustive = true; 2741 } 2742 2743 // If we don't have an identifier, we're done. 2744 // FIXME: Support macros with the same name as a keyword here. 2745 if (!Tok.is(MMToken::Identifier)) 2746 return; 2747 2748 // Consume the first identifier. 2749 if (!ActiveModule->Parent) { 2750 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2751 } 2752 consumeToken(); 2753 2754 do { 2755 // If there's a comma, consume it. 2756 if (!Tok.is(MMToken::Comma)) 2757 break; 2758 consumeToken(); 2759 2760 // We expect to see a macro name here. 2761 // FIXME: Support macros with the same name as a keyword here. 2762 if (!Tok.is(MMToken::Identifier)) { 2763 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2764 break; 2765 } 2766 2767 // Consume the macro name. 2768 if (!ActiveModule->Parent) { 2769 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2770 } 2771 consumeToken(); 2772 } while (true); 2773 } 2774 2775 /// Format a module-id into a string. 2776 static std::string formatModuleId(const ModuleId &Id) { 2777 std::string result; 2778 { 2779 llvm::raw_string_ostream OS(result); 2780 2781 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2782 if (I) 2783 OS << "."; 2784 OS << Id[I].first; 2785 } 2786 } 2787 2788 return result; 2789 } 2790 2791 /// Parse a conflict declaration. 2792 /// 2793 /// module-declaration: 2794 /// 'conflict' module-id ',' string-literal 2795 void ModuleMapParser::parseConflict() { 2796 assert(Tok.is(MMToken::Conflict)); 2797 SourceLocation ConflictLoc = consumeToken(); 2798 Module::UnresolvedConflict Conflict; 2799 2800 // Parse the module-id. 2801 if (parseModuleId(Conflict.Id)) 2802 return; 2803 2804 // Parse the ','. 2805 if (!Tok.is(MMToken::Comma)) { 2806 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2807 << SourceRange(ConflictLoc); 2808 return; 2809 } 2810 consumeToken(); 2811 2812 // Parse the message. 2813 if (!Tok.is(MMToken::StringLiteral)) { 2814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2815 << formatModuleId(Conflict.Id); 2816 return; 2817 } 2818 Conflict.Message = Tok.getString().str(); 2819 consumeToken(); 2820 2821 // Add this unresolved conflict. 2822 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2823 } 2824 2825 /// Parse an inferred module declaration (wildcard modules). 2826 /// 2827 /// module-declaration: 2828 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2829 /// { inferred-module-member* } 2830 /// 2831 /// inferred-module-member: 2832 /// 'export' '*' 2833 /// 'exclude' identifier 2834 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2835 assert(Tok.is(MMToken::Star)); 2836 SourceLocation StarLoc = consumeToken(); 2837 bool Failed = false; 2838 2839 // Inferred modules must be submodules. 2840 if (!ActiveModule && !Framework) { 2841 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2842 Failed = true; 2843 } 2844 2845 if (ActiveModule) { 2846 // Inferred modules must have umbrella directories. 2847 if (!Failed && ActiveModule->IsAvailable && 2848 !ActiveModule->getEffectiveUmbrellaDir()) { 2849 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2850 Failed = true; 2851 } 2852 2853 // Check for redefinition of an inferred module. 2854 if (!Failed && ActiveModule->InferSubmodules) { 2855 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2856 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2857 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2858 diag::note_mmap_prev_definition); 2859 Failed = true; 2860 } 2861 2862 // Check for the 'framework' keyword, which is not permitted here. 2863 if (Framework) { 2864 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2865 Framework = false; 2866 } 2867 } else if (Explicit) { 2868 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2869 Explicit = false; 2870 } 2871 2872 // If there were any problems with this inferred submodule, skip its body. 2873 if (Failed) { 2874 if (Tok.is(MMToken::LBrace)) { 2875 consumeToken(); 2876 skipUntil(MMToken::RBrace); 2877 if (Tok.is(MMToken::RBrace)) 2878 consumeToken(); 2879 } 2880 HadError = true; 2881 return; 2882 } 2883 2884 // Parse optional attributes. 2885 Attributes Attrs; 2886 if (parseOptionalAttributes(Attrs)) 2887 return; 2888 2889 if (ActiveModule) { 2890 // Note that we have an inferred submodule. 2891 ActiveModule->InferSubmodules = true; 2892 ActiveModule->InferredSubmoduleLoc = StarLoc; 2893 ActiveModule->InferExplicitSubmodules = Explicit; 2894 } else { 2895 // We'll be inferring framework modules for this directory. 2896 Map.InferredDirectories[Directory].InferModules = true; 2897 Map.InferredDirectories[Directory].Attrs = Attrs; 2898 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2899 // FIXME: Handle the 'framework' keyword. 2900 } 2901 2902 // Parse the opening brace. 2903 if (!Tok.is(MMToken::LBrace)) { 2904 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2905 HadError = true; 2906 return; 2907 } 2908 SourceLocation LBraceLoc = consumeToken(); 2909 2910 // Parse the body of the inferred submodule. 2911 bool Done = false; 2912 do { 2913 switch (Tok.Kind) { 2914 case MMToken::EndOfFile: 2915 case MMToken::RBrace: 2916 Done = true; 2917 break; 2918 2919 case MMToken::ExcludeKeyword: 2920 if (ActiveModule) { 2921 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2922 << (ActiveModule != nullptr); 2923 consumeToken(); 2924 break; 2925 } 2926 2927 consumeToken(); 2928 // FIXME: Support string-literal module names here. 2929 if (!Tok.is(MMToken::Identifier)) { 2930 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2931 break; 2932 } 2933 2934 Map.InferredDirectories[Directory].ExcludedModules.push_back( 2935 std::string(Tok.getString())); 2936 consumeToken(); 2937 break; 2938 2939 case MMToken::ExportKeyword: 2940 if (!ActiveModule) { 2941 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2942 << (ActiveModule != nullptr); 2943 consumeToken(); 2944 break; 2945 } 2946 2947 consumeToken(); 2948 if (Tok.is(MMToken::Star)) 2949 ActiveModule->InferExportWildcard = true; 2950 else 2951 Diags.Report(Tok.getLocation(), 2952 diag::err_mmap_expected_export_wildcard); 2953 consumeToken(); 2954 break; 2955 2956 case MMToken::ExplicitKeyword: 2957 case MMToken::ModuleKeyword: 2958 case MMToken::HeaderKeyword: 2959 case MMToken::PrivateKeyword: 2960 case MMToken::UmbrellaKeyword: 2961 default: 2962 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2963 << (ActiveModule != nullptr); 2964 consumeToken(); 2965 break; 2966 } 2967 } while (!Done); 2968 2969 if (Tok.is(MMToken::RBrace)) 2970 consumeToken(); 2971 else { 2972 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2973 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2974 HadError = true; 2975 } 2976 } 2977 2978 /// Parse optional attributes. 2979 /// 2980 /// attributes: 2981 /// attribute attributes 2982 /// attribute 2983 /// 2984 /// attribute: 2985 /// [ identifier ] 2986 /// 2987 /// \param Attrs Will be filled in with the parsed attributes. 2988 /// 2989 /// \returns true if an error occurred, false otherwise. 2990 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2991 bool HadError = false; 2992 2993 while (Tok.is(MMToken::LSquare)) { 2994 // Consume the '['. 2995 SourceLocation LSquareLoc = consumeToken(); 2996 2997 // Check whether we have an attribute name here. 2998 if (!Tok.is(MMToken::Identifier)) { 2999 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 3000 skipUntil(MMToken::RSquare); 3001 if (Tok.is(MMToken::RSquare)) 3002 consumeToken(); 3003 HadError = true; 3004 } 3005 3006 // Decode the attribute name. 3007 AttributeKind Attribute 3008 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 3009 .Case("exhaustive", AT_exhaustive) 3010 .Case("extern_c", AT_extern_c) 3011 .Case("no_undeclared_includes", AT_no_undeclared_includes) 3012 .Case("system", AT_system) 3013 .Default(AT_unknown); 3014 switch (Attribute) { 3015 case AT_unknown: 3016 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 3017 << Tok.getString(); 3018 break; 3019 3020 case AT_system: 3021 Attrs.IsSystem = true; 3022 break; 3023 3024 case AT_extern_c: 3025 Attrs.IsExternC = true; 3026 break; 3027 3028 case AT_exhaustive: 3029 Attrs.IsExhaustive = true; 3030 break; 3031 3032 case AT_no_undeclared_includes: 3033 Attrs.NoUndeclaredIncludes = true; 3034 break; 3035 } 3036 consumeToken(); 3037 3038 // Consume the ']'. 3039 if (!Tok.is(MMToken::RSquare)) { 3040 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 3041 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 3042 skipUntil(MMToken::RSquare); 3043 HadError = true; 3044 } 3045 3046 if (Tok.is(MMToken::RSquare)) 3047 consumeToken(); 3048 } 3049 3050 return HadError; 3051 } 3052 3053 /// Parse a module map file. 3054 /// 3055 /// module-map-file: 3056 /// module-declaration* 3057 bool ModuleMapParser::parseModuleMapFile() { 3058 do { 3059 switch (Tok.Kind) { 3060 case MMToken::EndOfFile: 3061 return HadError; 3062 3063 case MMToken::ExplicitKeyword: 3064 case MMToken::ExternKeyword: 3065 case MMToken::ModuleKeyword: 3066 case MMToken::FrameworkKeyword: 3067 parseModuleDecl(); 3068 break; 3069 3070 case MMToken::Comma: 3071 case MMToken::ConfigMacros: 3072 case MMToken::Conflict: 3073 case MMToken::Exclaim: 3074 case MMToken::ExcludeKeyword: 3075 case MMToken::ExportKeyword: 3076 case MMToken::ExportAsKeyword: 3077 case MMToken::HeaderKeyword: 3078 case MMToken::Identifier: 3079 case MMToken::LBrace: 3080 case MMToken::LinkKeyword: 3081 case MMToken::LSquare: 3082 case MMToken::Period: 3083 case MMToken::PrivateKeyword: 3084 case MMToken::RBrace: 3085 case MMToken::RSquare: 3086 case MMToken::RequiresKeyword: 3087 case MMToken::Star: 3088 case MMToken::StringLiteral: 3089 case MMToken::IntegerLiteral: 3090 case MMToken::TextualKeyword: 3091 case MMToken::UmbrellaKeyword: 3092 case MMToken::UseKeyword: 3093 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 3094 HadError = true; 3095 consumeToken(); 3096 break; 3097 } 3098 } while (true); 3099 } 3100 3101 bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem, 3102 DirectoryEntryRef Dir, FileID ID, 3103 unsigned *Offset, 3104 SourceLocation ExternModuleLoc) { 3105 assert(Target && "Missing target information"); 3106 llvm::DenseMap<const FileEntry *, bool>::iterator Known 3107 = ParsedModuleMap.find(File); 3108 if (Known != ParsedModuleMap.end()) 3109 return Known->second; 3110 3111 // If the module map file wasn't already entered, do so now. 3112 if (ID.isInvalid()) { 3113 auto FileCharacter = 3114 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 3115 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 3116 } 3117 3118 assert(Target && "Missing target information"); 3119 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID); 3120 if (!Buffer) 3121 return ParsedModuleMap[File] = true; 3122 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 3123 "invalid buffer offset"); 3124 3125 // Parse this module map file. 3126 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 3127 Buffer->getBufferStart(), 3128 Buffer->getBufferStart() + (Offset ? *Offset : 0), 3129 Buffer->getBufferEnd()); 3130 SourceLocation Start = L.getSourceLocation(); 3131 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 3132 IsSystem); 3133 bool Result = Parser.parseModuleMapFile(); 3134 ParsedModuleMap[File] = Result; 3135 3136 if (Offset) { 3137 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 3138 assert(Loc.first == ID && "stopped in a different file?"); 3139 *Offset = Loc.second; 3140 } 3141 3142 // Notify callbacks that we parsed it. 3143 for (const auto &Cb : Callbacks) 3144 Cb->moduleMapFileRead(Start, File, IsSystem); 3145 3146 return Result; 3147 } 3148