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