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.str()), 312 *File}; 313 addHeader(Mod, H, headerKindToRole(Header.Kind)); 314 } 315 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) { 316 // There's a builtin header but no corresponding on-disk header. Assume 317 // this was supposed to modularize the builtin header alone. 318 } else if (Header.Kind == Module::HK_Excluded) { 319 // Ignore missing excluded header files. They're optional anyway. 320 } else { 321 // If we find a module that has a missing header, we mark this module as 322 // unavailable and store the header directive for displaying diagnostics. 323 Mod->MissingHeaders.push_back(Header); 324 // A missing header with stat information doesn't make the module 325 // unavailable; this keeps our behavior consistent as headers are lazily 326 // resolved. (Such a module still can't be built though, except from 327 // preprocessed source.) 328 if (!Header.Size && !Header.ModTime) 329 Mod->markUnavailable(/*Unimportable=*/false); 330 } 331 } 332 333 bool ModuleMap::resolveAsBuiltinHeader( 334 Module *Mod, const Module::UnresolvedHeaderDirective &Header) { 335 if (Header.Kind == Module::HK_Excluded || 336 llvm::sys::path::is_absolute(Header.FileName) || 337 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella || 338 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory || 339 !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName)) 340 return false; 341 342 // This is a system module with a top-level header. This header 343 // may have a counterpart (or replacement) in the set of headers 344 // supplied by Clang. Find that builtin header. 345 SmallString<128> Path; 346 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName); 347 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path); 348 if (!File) 349 return false; 350 351 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 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 988 /*IsFramework=*/true)); 989 } 990 991 Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir, 992 bool IsSystem, Module *Parent) { 993 Attributes Attrs; 994 Attrs.IsSystem = IsSystem; 995 return inferFrameworkModule(FrameworkDir, Attrs, Parent); 996 } 997 998 Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir, 999 Attributes Attrs, Module *Parent) { 1000 // Note: as an egregious but useful hack we use the real path here, because 1001 // we might be looking at an embedded framework that symlinks out to a 1002 // top-level framework, and we need to infer as if we were naming the 1003 // top-level framework. 1004 StringRef FrameworkDirName = 1005 SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 1006 1007 // In case this is a case-insensitive filesystem, use the canonical 1008 // directory name as the ModuleName, since modules are case-sensitive. 1009 // FIXME: we should be able to give a fix-it hint for the correct spelling. 1010 SmallString<32> ModuleNameStorage; 1011 StringRef ModuleName = sanitizeFilenameAsIdentifier( 1012 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage); 1013 1014 // Check whether we've already found this module. 1015 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 1016 return Mod; 1017 1018 FileManager &FileMgr = SourceMgr.getFileManager(); 1019 1020 // If the framework has a parent path from which we're allowed to infer 1021 // a framework module, do so. 1022 OptionalFileEntryRef ModuleMapFile; 1023 if (!Parent) { 1024 // Determine whether we're allowed to infer a module map. 1025 bool canInfer = false; 1026 if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 1027 // Figure out the parent path. 1028 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 1029 if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) { 1030 // Check whether we have already looked into the parent directory 1031 // for a module map. 1032 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 1033 inferred = InferredDirectories.find(*ParentDir); 1034 if (inferred == InferredDirectories.end()) { 1035 // We haven't looked here before. Load a module map, if there is 1036 // one. 1037 bool IsFrameworkDir = Parent.ends_with(".framework"); 1038 if (OptionalFileEntryRef ModMapFile = 1039 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) { 1040 parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir); 1041 inferred = InferredDirectories.find(*ParentDir); 1042 } 1043 1044 if (inferred == InferredDirectories.end()) 1045 inferred = InferredDirectories.insert( 1046 std::make_pair(*ParentDir, InferredDirectory())).first; 1047 } 1048 1049 if (inferred->second.InferModules) { 1050 // We're allowed to infer for this directory, but make sure it's okay 1051 // to infer this particular module. 1052 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 1053 canInfer = 1054 !llvm::is_contained(inferred->second.ExcludedModules, Name); 1055 1056 Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 1057 Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 1058 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 1059 Attrs.NoUndeclaredIncludes |= 1060 inferred->second.Attrs.NoUndeclaredIncludes; 1061 ModuleMapFile = inferred->second.ModuleMapFile; 1062 } 1063 } 1064 } 1065 1066 // If we're not allowed to infer a framework module, don't. 1067 if (!canInfer) 1068 return nullptr; 1069 } else { 1070 ModuleMapFile = getModuleMapFileForUniquing(Parent); 1071 } 1072 1073 // Look for an umbrella header. 1074 SmallString<128> UmbrellaName = FrameworkDir.getName(); 1075 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 1076 auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName); 1077 1078 // FIXME: If there's no umbrella header, we could probably scan the 1079 // framework to load *everything*. But, it's not clear that this is a good 1080 // idea. 1081 if (!UmbrellaHeader) 1082 return nullptr; 1083 1084 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 1085 /*IsFramework=*/true, /*IsExplicit=*/false, 1086 NumCreatedModules++); 1087 InferredModuleAllowedBy[Result] = ModuleMapFile; 1088 Result->IsInferred = true; 1089 if (!Parent) { 1090 if (LangOpts.CurrentModule == ModuleName) 1091 SourceModule = Result; 1092 Modules[ModuleName] = Result; 1093 ModuleScopeIDs[Result] = CurrentModuleScopeID; 1094 } 1095 1096 Result->IsSystem |= Attrs.IsSystem; 1097 Result->IsExternC |= Attrs.IsExternC; 1098 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; 1099 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes; 1100 Result->Directory = FrameworkDir; 1101 1102 // Chop off the first framework bit, as that is implied. 1103 StringRef RelativePath = UmbrellaName.str().substr( 1104 Result->getTopLevelModule()->Directory->getName().size()); 1105 RelativePath = llvm::sys::path::relative_path(RelativePath); 1106 1107 // umbrella header "umbrella-header-name" 1108 setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h", 1109 RelativePath); 1110 1111 // export * 1112 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 1113 1114 // module * { export * } 1115 Result->InferSubmodules = true; 1116 Result->InferExportWildcard = true; 1117 1118 // Look for subframeworks. 1119 std::error_code EC; 1120 SmallString<128> SubframeworksDirName = FrameworkDir.getName(); 1121 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 1122 llvm::sys::path::native(SubframeworksDirName); 1123 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); 1124 for (llvm::vfs::directory_iterator 1125 Dir = FS.dir_begin(SubframeworksDirName, EC), 1126 DirEnd; 1127 Dir != DirEnd && !EC; Dir.increment(EC)) { 1128 if (!StringRef(Dir->path()).ends_with(".framework")) 1129 continue; 1130 1131 if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) { 1132 // Note: as an egregious but useful hack, we use the real path here and 1133 // check whether it is actually a subdirectory of the parent directory. 1134 // This will not be the case if the 'subframework' is actually a symlink 1135 // out to a top-level framework. 1136 StringRef SubframeworkDirName = 1137 FileMgr.getCanonicalName(*SubframeworkDir); 1138 bool FoundParent = false; 1139 do { 1140 // Get the parent directory name. 1141 SubframeworkDirName 1142 = llvm::sys::path::parent_path(SubframeworkDirName); 1143 if (SubframeworkDirName.empty()) 1144 break; 1145 1146 if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) { 1147 if (*SubDir == FrameworkDir) { 1148 FoundParent = true; 1149 break; 1150 } 1151 } 1152 } while (true); 1153 1154 if (!FoundParent) 1155 continue; 1156 1157 // FIXME: Do we want to warn about subframeworks without umbrella headers? 1158 inferFrameworkModule(*SubframeworkDir, Attrs, Result); 1159 } 1160 } 1161 1162 // If the module is a top-level framework, automatically link against the 1163 // framework. 1164 if (!Result->isSubFramework()) 1165 inferFrameworkLink(Result); 1166 1167 return Result; 1168 } 1169 1170 Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework, 1171 Module *ShadowingModule) { 1172 1173 // Create a new module with this name. 1174 Module *Result = 1175 new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework, 1176 /*IsExplicit=*/false, NumCreatedModules++); 1177 Result->ShadowingModule = ShadowingModule; 1178 Result->markUnavailable(/*Unimportable*/true); 1179 ModuleScopeIDs[Result] = CurrentModuleScopeID; 1180 ShadowModules.push_back(Result); 1181 1182 return Result; 1183 } 1184 1185 void ModuleMap::setUmbrellaHeaderAsWritten( 1186 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, 1187 const Twine &PathRelativeToRootModuleDirectory) { 1188 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 1189 Mod->Umbrella = UmbrellaHeader; 1190 Mod->UmbrellaAsWritten = NameAsWritten.str(); 1191 Mod->UmbrellaRelativeToRootModuleDirectory = 1192 PathRelativeToRootModuleDirectory.str(); 1193 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod; 1194 1195 // Notify callbacks that we just added a new header. 1196 for (const auto &Cb : Callbacks) 1197 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader); 1198 } 1199 1200 void ModuleMap::setUmbrellaDirAsWritten( 1201 Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, 1202 const Twine &PathRelativeToRootModuleDirectory) { 1203 Mod->Umbrella = UmbrellaDir; 1204 Mod->UmbrellaAsWritten = NameAsWritten.str(); 1205 Mod->UmbrellaRelativeToRootModuleDirectory = 1206 PathRelativeToRootModuleDirectory.str(); 1207 UmbrellaDirs[UmbrellaDir] = Mod; 1208 } 1209 1210 void ModuleMap::addUnresolvedHeader(Module *Mod, 1211 Module::UnresolvedHeaderDirective Header, 1212 bool &NeedsFramework) { 1213 // If there is a builtin counterpart to this file, add it now so it can 1214 // wrap the system header. 1215 if (resolveAsBuiltinHeader(Mod, Header)) { 1216 // If we have both a builtin and system version of the file, the 1217 // builtin version may want to inject macros into the system header, so 1218 // force the system header to be treated as a textual header in this 1219 // case. 1220 Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole( 1221 headerKindToRole(Header.Kind) | ModuleMap::TextualHeader)); 1222 Header.HasBuiltinHeader = true; 1223 } 1224 1225 // If possible, don't stat the header until we need to. This requires the 1226 // user to have provided us with some stat information about the file. 1227 // FIXME: Add support for lazily stat'ing umbrella headers and excluded 1228 // headers. 1229 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella && 1230 Header.Kind != Module::HK_Excluded) { 1231 // We expect more variation in mtime than size, so if we're given both, 1232 // use the mtime as the key. 1233 if (Header.ModTime) 1234 LazyHeadersByModTime[*Header.ModTime].push_back(Mod); 1235 else 1236 LazyHeadersBySize[*Header.Size].push_back(Mod); 1237 Mod->UnresolvedHeaders.push_back(Header); 1238 return; 1239 } 1240 1241 // We don't have stat information or can't defer looking this file up. 1242 // Perform the lookup now. 1243 resolveHeader(Mod, Header, NeedsFramework); 1244 } 1245 1246 void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const { 1247 auto BySize = LazyHeadersBySize.find(File->getSize()); 1248 if (BySize != LazyHeadersBySize.end()) { 1249 for (auto *M : BySize->second) 1250 resolveHeaderDirectives(M, File); 1251 LazyHeadersBySize.erase(BySize); 1252 } 1253 1254 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime()); 1255 if (ByModTime != LazyHeadersByModTime.end()) { 1256 for (auto *M : ByModTime->second) 1257 resolveHeaderDirectives(M, File); 1258 LazyHeadersByModTime.erase(ByModTime); 1259 } 1260 } 1261 1262 void ModuleMap::resolveHeaderDirectives( 1263 Module *Mod, std::optional<const FileEntry *> File) const { 1264 bool NeedsFramework = false; 1265 SmallVector<Module::UnresolvedHeaderDirective, 1> NewHeaders; 1266 const auto Size = File ? (*File)->getSize() : 0; 1267 const auto ModTime = File ? (*File)->getModificationTime() : 0; 1268 1269 for (auto &Header : Mod->UnresolvedHeaders) { 1270 if (File && ((Header.ModTime && Header.ModTime != ModTime) || 1271 (Header.Size && Header.Size != Size))) 1272 NewHeaders.push_back(Header); 1273 else 1274 // This operation is logically const; we're just changing how we represent 1275 // the header information for this file. 1276 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework); 1277 } 1278 Mod->UnresolvedHeaders.swap(NewHeaders); 1279 } 1280 1281 void ModuleMap::addHeader(Module *Mod, Module::Header Header, 1282 ModuleHeaderRole Role, bool Imported) { 1283 KnownHeader KH(Mod, Role); 1284 1285 // Only add each header to the headers list once. 1286 // FIXME: Should we diagnose if a header is listed twice in the 1287 // same module definition? 1288 auto &HeaderList = Headers[Header.Entry]; 1289 if (llvm::is_contained(HeaderList, KH)) 1290 return; 1291 1292 HeaderList.push_back(KH); 1293 Mod->Headers[headerRoleToKind(Role)].push_back(Header); 1294 1295 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts); 1296 if (!Imported || isCompilingModuleHeader) { 1297 // When we import HeaderFileInfo, the external source is expected to 1298 // set the isModuleHeader flag itself. 1299 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 1300 isCompilingModuleHeader); 1301 } 1302 1303 // Notify callbacks that we just added a new header. 1304 for (const auto &Cb : Callbacks) 1305 Cb->moduleMapAddHeader(Header.Entry.getName()); 1306 } 1307 1308 OptionalFileEntryRef 1309 ModuleMap::getContainingModuleMapFile(const Module *Module) const { 1310 if (Module->DefinitionLoc.isInvalid()) 1311 return std::nullopt; 1312 1313 return SourceMgr.getFileEntryRefForID( 1314 SourceMgr.getFileID(Module->DefinitionLoc)); 1315 } 1316 1317 OptionalFileEntryRef 1318 ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 1319 if (M->IsInferred) { 1320 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 1321 return InferredModuleAllowedBy.find(M)->second; 1322 } 1323 return getContainingModuleMapFile(M); 1324 } 1325 1326 void ModuleMap::setInferredModuleAllowedBy(Module *M, 1327 OptionalFileEntryRef ModMap) { 1328 assert(M->IsInferred && "module not inferred"); 1329 InferredModuleAllowedBy[M] = ModMap; 1330 } 1331 1332 std::error_code 1333 ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) { 1334 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()}); 1335 1336 // Do not canonicalize within the framework; the module map parser expects 1337 // Modules/ not Versions/A/Modules. 1338 if (llvm::sys::path::filename(Dir) == "Modules") { 1339 StringRef Parent = llvm::sys::path::parent_path(Dir); 1340 if (Parent.ends_with(".framework")) 1341 Dir = Parent; 1342 } 1343 1344 FileManager &FM = SourceMgr.getFileManager(); 1345 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir); 1346 if (!DirEntry) 1347 return llvm::errorToErrorCode(DirEntry.takeError()); 1348 1349 // Canonicalize the directory. 1350 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry); 1351 if (CanonicalDir != Dir) 1352 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir); 1353 1354 // In theory, the filename component should also be canonicalized if it 1355 // on a case-insensitive filesystem. However, the extra canonicalization is 1356 // expensive and if clang looked up the filename it will always be lowercase. 1357 1358 // Remove ., remove redundant separators, and switch to native separators. 1359 // This is needed for separators between CanonicalDir and the filename. 1360 llvm::sys::path::remove_dots(Path); 1361 1362 return std::error_code(); 1363 } 1364 1365 void ModuleMap::addAdditionalModuleMapFile(const Module *M, 1366 FileEntryRef ModuleMap) { 1367 AdditionalModMaps[M].insert(ModuleMap); 1368 } 1369 1370 LLVM_DUMP_METHOD void ModuleMap::dump() { 1371 llvm::errs() << "Modules:"; 1372 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 1373 MEnd = Modules.end(); 1374 M != MEnd; ++M) 1375 M->getValue()->print(llvm::errs(), 2); 1376 1377 llvm::errs() << "Headers:"; 1378 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 1379 H != HEnd; ++H) { 1380 llvm::errs() << " \"" << H->first.getName() << "\" -> "; 1381 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 1382 E = H->second.end(); 1383 I != E; ++I) { 1384 if (I != H->second.begin()) 1385 llvm::errs() << ","; 1386 llvm::errs() << I->getModule()->getFullModuleName(); 1387 } 1388 llvm::errs() << "\n"; 1389 } 1390 } 1391 1392 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 1393 auto Unresolved = std::move(Mod->UnresolvedExports); 1394 Mod->UnresolvedExports.clear(); 1395 for (auto &UE : Unresolved) { 1396 Module::ExportDecl Export = resolveExport(Mod, UE, Complain); 1397 if (Export.getPointer() || Export.getInt()) 1398 Mod->Exports.push_back(Export); 1399 else 1400 Mod->UnresolvedExports.push_back(UE); 1401 } 1402 return !Mod->UnresolvedExports.empty(); 1403 } 1404 1405 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 1406 auto *Top = Mod->getTopLevelModule(); 1407 auto Unresolved = std::move(Top->UnresolvedDirectUses); 1408 Top->UnresolvedDirectUses.clear(); 1409 for (auto &UDU : Unresolved) { 1410 Module *DirectUse = resolveModuleId(UDU, Top, Complain); 1411 if (DirectUse) 1412 Top->DirectUses.push_back(DirectUse); 1413 else 1414 Top->UnresolvedDirectUses.push_back(UDU); 1415 } 1416 return !Top->UnresolvedDirectUses.empty(); 1417 } 1418 1419 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 1420 auto Unresolved = std::move(Mod->UnresolvedConflicts); 1421 Mod->UnresolvedConflicts.clear(); 1422 for (auto &UC : Unresolved) { 1423 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) { 1424 Module::Conflict Conflict; 1425 Conflict.Other = OtherMod; 1426 Conflict.Message = UC.Message; 1427 Mod->Conflicts.push_back(Conflict); 1428 } else 1429 Mod->UnresolvedConflicts.push_back(UC); 1430 } 1431 return !Mod->UnresolvedConflicts.empty(); 1432 } 1433 1434 //----------------------------------------------------------------------------// 1435 // Module map file parser 1436 //----------------------------------------------------------------------------// 1437 1438 namespace clang { 1439 1440 /// A token in a module map file. 1441 struct MMToken { 1442 enum TokenKind { 1443 Comma, 1444 ConfigMacros, 1445 Conflict, 1446 EndOfFile, 1447 HeaderKeyword, 1448 Identifier, 1449 Exclaim, 1450 ExcludeKeyword, 1451 ExplicitKeyword, 1452 ExportKeyword, 1453 ExportAsKeyword, 1454 ExternKeyword, 1455 FrameworkKeyword, 1456 LinkKeyword, 1457 ModuleKeyword, 1458 Period, 1459 PrivateKeyword, 1460 UmbrellaKeyword, 1461 UseKeyword, 1462 RequiresKeyword, 1463 Star, 1464 StringLiteral, 1465 IntegerLiteral, 1466 TextualKeyword, 1467 LBrace, 1468 RBrace, 1469 LSquare, 1470 RSquare 1471 } Kind; 1472 1473 SourceLocation::UIntTy Location; 1474 unsigned StringLength; 1475 union { 1476 // If Kind != IntegerLiteral. 1477 const char *StringData; 1478 1479 // If Kind == IntegerLiteral. 1480 uint64_t IntegerValue; 1481 }; 1482 1483 void clear() { 1484 Kind = EndOfFile; 1485 Location = 0; 1486 StringLength = 0; 1487 StringData = nullptr; 1488 } 1489 1490 bool is(TokenKind K) const { return Kind == K; } 1491 1492 SourceLocation getLocation() const { 1493 return SourceLocation::getFromRawEncoding(Location); 1494 } 1495 1496 uint64_t getInteger() const { 1497 return Kind == IntegerLiteral ? IntegerValue : 0; 1498 } 1499 1500 StringRef getString() const { 1501 return Kind == IntegerLiteral ? StringRef() 1502 : StringRef(StringData, StringLength); 1503 } 1504 }; 1505 1506 class ModuleMapParser { 1507 Lexer &L; 1508 SourceManager &SourceMgr; 1509 1510 /// Default target information, used only for string literal 1511 /// parsing. 1512 const TargetInfo *Target; 1513 1514 DiagnosticsEngine &Diags; 1515 ModuleMap ⤅ 1516 1517 /// The current module map file. 1518 FileEntryRef ModuleMapFile; 1519 1520 /// Source location of most recent parsed module declaration 1521 SourceLocation CurrModuleDeclLoc; 1522 1523 /// The directory that file names in this module map file should 1524 /// be resolved relative to. 1525 DirectoryEntryRef Directory; 1526 1527 /// Whether this module map is in a system header directory. 1528 bool IsSystem; 1529 1530 /// Whether an error occurred. 1531 bool HadError = false; 1532 1533 /// Stores string data for the various string literals referenced 1534 /// during parsing. 1535 llvm::BumpPtrAllocator StringData; 1536 1537 /// The current token. 1538 MMToken Tok; 1539 1540 /// The active module. 1541 Module *ActiveModule = nullptr; 1542 1543 /// Whether a module uses the 'requires excluded' hack to mark its 1544 /// contents as 'textual'. 1545 /// 1546 /// On older Darwin SDK versions, 'requires excluded' is used to mark the 1547 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as 1548 /// non-modular headers. For backwards compatibility, we continue to 1549 /// support this idiom for just these modules, and map the headers to 1550 /// 'textual' to match the original intent. 1551 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack; 1552 1553 /// Consume the current token and return its location. 1554 SourceLocation consumeToken(); 1555 1556 /// Skip tokens until we reach the a token with the given kind 1557 /// (or the end of the file). 1558 void skipUntil(MMToken::TokenKind K); 1559 1560 bool parseModuleId(ModuleId &Id); 1561 void parseModuleDecl(); 1562 void parseExternModuleDecl(); 1563 void parseRequiresDecl(); 1564 void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc); 1565 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1566 void parseExportDecl(); 1567 void parseExportAsDecl(); 1568 void parseUseDecl(); 1569 void parseLinkDecl(); 1570 void parseConfigMacros(); 1571 void parseConflict(); 1572 void parseInferredModuleDecl(bool Framework, bool Explicit); 1573 1574 /// Private modules are canonicalized as Foo_Private. Clang provides extra 1575 /// module map search logic to find the appropriate private module when PCH 1576 /// is used with implicit module maps. Warn when private modules are written 1577 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1578 void diagnosePrivateModules(SourceLocation ExplicitLoc, 1579 SourceLocation FrameworkLoc); 1580 1581 using Attributes = ModuleMap::Attributes; 1582 1583 bool parseOptionalAttributes(Attributes &Attrs); 1584 1585 public: 1586 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1587 const TargetInfo *Target, DiagnosticsEngine &Diags, 1588 ModuleMap &Map, FileEntryRef ModuleMapFile, 1589 DirectoryEntryRef Directory, bool IsSystem) 1590 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1591 ModuleMapFile(ModuleMapFile), Directory(Directory), 1592 IsSystem(IsSystem) { 1593 Tok.clear(); 1594 consumeToken(); 1595 } 1596 1597 bool parseModuleMapFile(); 1598 1599 bool terminatedByDirective() { return false; } 1600 SourceLocation getLocation() { return Tok.getLocation(); } 1601 }; 1602 1603 } // namespace clang 1604 1605 SourceLocation ModuleMapParser::consumeToken() { 1606 SourceLocation Result = Tok.getLocation(); 1607 1608 retry: 1609 Tok.clear(); 1610 Token LToken; 1611 L.LexFromRawLexer(LToken); 1612 Tok.Location = LToken.getLocation().getRawEncoding(); 1613 switch (LToken.getKind()) { 1614 case tok::raw_identifier: { 1615 StringRef RI = LToken.getRawIdentifier(); 1616 Tok.StringData = RI.data(); 1617 Tok.StringLength = RI.size(); 1618 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1619 .Case("config_macros", MMToken::ConfigMacros) 1620 .Case("conflict", MMToken::Conflict) 1621 .Case("exclude", MMToken::ExcludeKeyword) 1622 .Case("explicit", MMToken::ExplicitKeyword) 1623 .Case("export", MMToken::ExportKeyword) 1624 .Case("export_as", MMToken::ExportAsKeyword) 1625 .Case("extern", MMToken::ExternKeyword) 1626 .Case("framework", MMToken::FrameworkKeyword) 1627 .Case("header", MMToken::HeaderKeyword) 1628 .Case("link", MMToken::LinkKeyword) 1629 .Case("module", MMToken::ModuleKeyword) 1630 .Case("private", MMToken::PrivateKeyword) 1631 .Case("requires", MMToken::RequiresKeyword) 1632 .Case("textual", MMToken::TextualKeyword) 1633 .Case("umbrella", MMToken::UmbrellaKeyword) 1634 .Case("use", MMToken::UseKeyword) 1635 .Default(MMToken::Identifier); 1636 break; 1637 } 1638 1639 case tok::comma: 1640 Tok.Kind = MMToken::Comma; 1641 break; 1642 1643 case tok::eof: 1644 Tok.Kind = MMToken::EndOfFile; 1645 break; 1646 1647 case tok::l_brace: 1648 Tok.Kind = MMToken::LBrace; 1649 break; 1650 1651 case tok::l_square: 1652 Tok.Kind = MMToken::LSquare; 1653 break; 1654 1655 case tok::period: 1656 Tok.Kind = MMToken::Period; 1657 break; 1658 1659 case tok::r_brace: 1660 Tok.Kind = MMToken::RBrace; 1661 break; 1662 1663 case tok::r_square: 1664 Tok.Kind = MMToken::RSquare; 1665 break; 1666 1667 case tok::star: 1668 Tok.Kind = MMToken::Star; 1669 break; 1670 1671 case tok::exclaim: 1672 Tok.Kind = MMToken::Exclaim; 1673 break; 1674 1675 case tok::string_literal: { 1676 if (LToken.hasUDSuffix()) { 1677 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1678 HadError = true; 1679 goto retry; 1680 } 1681 1682 // Parse the string literal. 1683 LangOptions LangOpts; 1684 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1685 if (StringLiteral.hadError) 1686 goto retry; 1687 1688 // Copy the string literal into our string data allocator. 1689 unsigned Length = StringLiteral.GetStringLength(); 1690 char *Saved = StringData.Allocate<char>(Length + 1); 1691 memcpy(Saved, StringLiteral.GetString().data(), Length); 1692 Saved[Length] = 0; 1693 1694 // Form the token. 1695 Tok.Kind = MMToken::StringLiteral; 1696 Tok.StringData = Saved; 1697 Tok.StringLength = Length; 1698 break; 1699 } 1700 1701 case tok::numeric_constant: { 1702 // We don't support any suffixes or other complications. 1703 SmallString<32> SpellingBuffer; 1704 SpellingBuffer.resize(LToken.getLength() + 1); 1705 const char *Start = SpellingBuffer.data(); 1706 unsigned Length = 1707 Lexer::getSpelling(LToken, Start, SourceMgr, Map.LangOpts); 1708 uint64_t Value; 1709 if (StringRef(Start, Length).getAsInteger(0, Value)) { 1710 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1711 HadError = true; 1712 goto retry; 1713 } 1714 1715 Tok.Kind = MMToken::IntegerLiteral; 1716 Tok.IntegerValue = Value; 1717 break; 1718 } 1719 1720 case tok::comment: 1721 goto retry; 1722 1723 case tok::hash: 1724 // A module map can be terminated prematurely by 1725 // #pragma clang module contents 1726 // When building the module, we'll treat the rest of the file as the 1727 // contents of the module. 1728 { 1729 auto NextIsIdent = [&](StringRef Str) -> bool { 1730 L.LexFromRawLexer(LToken); 1731 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && 1732 LToken.getRawIdentifier() == Str; 1733 }; 1734 if (NextIsIdent("pragma") && NextIsIdent("clang") && 1735 NextIsIdent("module") && NextIsIdent("contents")) { 1736 Tok.Kind = MMToken::EndOfFile; 1737 break; 1738 } 1739 } 1740 [[fallthrough]]; 1741 1742 default: 1743 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1744 HadError = true; 1745 goto retry; 1746 } 1747 1748 return Result; 1749 } 1750 1751 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1752 unsigned braceDepth = 0; 1753 unsigned squareDepth = 0; 1754 do { 1755 switch (Tok.Kind) { 1756 case MMToken::EndOfFile: 1757 return; 1758 1759 case MMToken::LBrace: 1760 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1761 return; 1762 1763 ++braceDepth; 1764 break; 1765 1766 case MMToken::LSquare: 1767 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1768 return; 1769 1770 ++squareDepth; 1771 break; 1772 1773 case MMToken::RBrace: 1774 if (braceDepth > 0) 1775 --braceDepth; 1776 else if (Tok.is(K)) 1777 return; 1778 break; 1779 1780 case MMToken::RSquare: 1781 if (squareDepth > 0) 1782 --squareDepth; 1783 else if (Tok.is(K)) 1784 return; 1785 break; 1786 1787 default: 1788 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1789 return; 1790 break; 1791 } 1792 1793 consumeToken(); 1794 } while (true); 1795 } 1796 1797 /// Parse a module-id. 1798 /// 1799 /// module-id: 1800 /// identifier 1801 /// identifier '.' module-id 1802 /// 1803 /// \returns true if an error occurred, false otherwise. 1804 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1805 Id.clear(); 1806 do { 1807 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1808 Id.push_back( 1809 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 1810 consumeToken(); 1811 } else { 1812 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1813 return true; 1814 } 1815 1816 if (!Tok.is(MMToken::Period)) 1817 break; 1818 1819 consumeToken(); 1820 } while (true); 1821 1822 return false; 1823 } 1824 1825 namespace { 1826 1827 /// Enumerates the known attributes. 1828 enum AttributeKind { 1829 /// An unknown attribute. 1830 AT_unknown, 1831 1832 /// The 'system' attribute. 1833 AT_system, 1834 1835 /// The 'extern_c' attribute. 1836 AT_extern_c, 1837 1838 /// The 'exhaustive' attribute. 1839 AT_exhaustive, 1840 1841 /// The 'no_undeclared_includes' attribute. 1842 AT_no_undeclared_includes 1843 }; 1844 1845 } // namespace 1846 1847 /// Private modules are canonicalized as Foo_Private. Clang provides extra 1848 /// module map search logic to find the appropriate private module when PCH 1849 /// is used with implicit module maps. Warn when private modules are written 1850 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1851 void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc, 1852 SourceLocation FrameworkLoc) { 1853 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical, 1854 const Module *M, SourceRange ReplLoc) { 1855 auto D = Diags.Report(ActiveModule->DefinitionLoc, 1856 diag::note_mmap_rename_top_level_private_module); 1857 D << BadName << M->Name; 1858 D << FixItHint::CreateReplacement(ReplLoc, Canonical); 1859 }; 1860 1861 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1862 auto const *M = E->getValue(); 1863 if (M->Directory != ActiveModule->Directory) 1864 continue; 1865 1866 SmallString<128> FullName(ActiveModule->getFullModuleName()); 1867 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private")) 1868 continue; 1869 SmallString<128> FixedPrivModDecl; 1870 SmallString<128> Canonical(M->Name); 1871 Canonical.append("_Private"); 1872 1873 // Foo.Private -> Foo_Private 1874 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent && 1875 M->Name == ActiveModule->Parent->Name) { 1876 Diags.Report(ActiveModule->DefinitionLoc, 1877 diag::warn_mmap_mismatched_private_submodule) 1878 << FullName; 1879 1880 SourceLocation FixItInitBegin = CurrModuleDeclLoc; 1881 if (FrameworkLoc.isValid()) 1882 FixItInitBegin = FrameworkLoc; 1883 if (ExplicitLoc.isValid()) 1884 FixItInitBegin = ExplicitLoc; 1885 1886 if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework) 1887 FixedPrivModDecl.append("framework "); 1888 FixedPrivModDecl.append("module "); 1889 FixedPrivModDecl.append(Canonical); 1890 1891 GenNoteAndFixIt(FullName, FixedPrivModDecl, M, 1892 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc)); 1893 continue; 1894 } 1895 1896 // FooPrivate and whatnots -> Foo_Private 1897 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name && 1898 ActiveModule->Name != Canonical) { 1899 Diags.Report(ActiveModule->DefinitionLoc, 1900 diag::warn_mmap_mismatched_private_module_name) 1901 << ActiveModule->Name; 1902 GenNoteAndFixIt(ActiveModule->Name, Canonical, M, 1903 SourceRange(ActiveModule->DefinitionLoc)); 1904 } 1905 } 1906 } 1907 1908 /// Parse a module declaration. 1909 /// 1910 /// module-declaration: 1911 /// 'extern' 'module' module-id string-literal 1912 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1913 /// { module-member* } 1914 /// 1915 /// module-member: 1916 /// requires-declaration 1917 /// header-declaration 1918 /// submodule-declaration 1919 /// export-declaration 1920 /// export-as-declaration 1921 /// link-declaration 1922 /// 1923 /// submodule-declaration: 1924 /// module-declaration 1925 /// inferred-submodule-declaration 1926 void ModuleMapParser::parseModuleDecl() { 1927 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1928 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1929 if (Tok.is(MMToken::ExternKeyword)) { 1930 parseExternModuleDecl(); 1931 return; 1932 } 1933 1934 // Parse 'explicit' or 'framework' keyword, if present. 1935 SourceLocation ExplicitLoc; 1936 SourceLocation FrameworkLoc; 1937 bool Explicit = false; 1938 bool Framework = false; 1939 1940 // Parse 'explicit' keyword, if present. 1941 if (Tok.is(MMToken::ExplicitKeyword)) { 1942 ExplicitLoc = consumeToken(); 1943 Explicit = true; 1944 } 1945 1946 // Parse 'framework' keyword, if present. 1947 if (Tok.is(MMToken::FrameworkKeyword)) { 1948 FrameworkLoc = consumeToken(); 1949 Framework = true; 1950 } 1951 1952 // Parse 'module' keyword. 1953 if (!Tok.is(MMToken::ModuleKeyword)) { 1954 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1955 consumeToken(); 1956 HadError = true; 1957 return; 1958 } 1959 CurrModuleDeclLoc = consumeToken(); // 'module' keyword 1960 1961 // If we have a wildcard for the module name, this is an inferred submodule. 1962 // Parse it. 1963 if (Tok.is(MMToken::Star)) 1964 return parseInferredModuleDecl(Framework, Explicit); 1965 1966 // Parse the module name. 1967 ModuleId Id; 1968 if (parseModuleId(Id)) { 1969 HadError = true; 1970 return; 1971 } 1972 1973 if (ActiveModule) { 1974 if (Id.size() > 1) { 1975 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1976 << SourceRange(Id.front().second, Id.back().second); 1977 1978 HadError = true; 1979 return; 1980 } 1981 } else if (Id.size() == 1 && Explicit) { 1982 // Top-level modules can't be explicit. 1983 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1984 Explicit = false; 1985 ExplicitLoc = SourceLocation(); 1986 HadError = true; 1987 } 1988 1989 Module *PreviousActiveModule = ActiveModule; 1990 if (Id.size() > 1) { 1991 // This module map defines a submodule. Go find the module of which it 1992 // is a submodule. 1993 ActiveModule = nullptr; 1994 const Module *TopLevelModule = nullptr; 1995 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1996 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1997 if (I == 0) 1998 TopLevelModule = Next; 1999 ActiveModule = Next; 2000 continue; 2001 } 2002 2003 Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module) 2004 << Id[I].first << (ActiveModule != nullptr) 2005 << (ActiveModule 2006 ? ActiveModule->getTopLevelModule()->getFullModuleName() 2007 : ""); 2008 HadError = true; 2009 } 2010 2011 if (TopLevelModule && 2012 ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 2013 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 2014 "submodule defined in same file as 'module *' that allowed its " 2015 "top-level module"); 2016 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 2017 } 2018 } 2019 2020 StringRef ModuleName = Id.back().first; 2021 SourceLocation ModuleNameLoc = Id.back().second; 2022 2023 // Parse the optional attribute list. 2024 Attributes Attrs; 2025 if (parseOptionalAttributes(Attrs)) 2026 return; 2027 2028 // Parse the opening brace. 2029 if (!Tok.is(MMToken::LBrace)) { 2030 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 2031 << ModuleName; 2032 HadError = true; 2033 return; 2034 } 2035 SourceLocation LBraceLoc = consumeToken(); 2036 2037 // Determine whether this (sub)module has already been defined. 2038 Module *ShadowingModule = nullptr; 2039 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 2040 // We might see a (re)definition of a module that we already have a 2041 // definition for in four cases: 2042 // - If we loaded one definition from an AST file and we've just found a 2043 // corresponding definition in a module map file, or 2044 bool LoadedFromASTFile = Existing->IsFromModuleFile; 2045 // - If we previously inferred this module from different module map file. 2046 bool Inferred = Existing->IsInferred; 2047 // - If we're building a framework that vends a module map, we might've 2048 // previously seen the one in intermediate products and now the system 2049 // one. 2050 // FIXME: If we're parsing module map file that looks like this: 2051 // framework module FW { ... } 2052 // module FW.Sub { ... } 2053 // We can't check the framework qualifier, since it's not attached to 2054 // the definition of Sub. Checking that qualifier on \c Existing is 2055 // not correct either, since we might've previously seen: 2056 // module FW { ... } 2057 // module FW.Sub { ... } 2058 // We should enforce consistency of redefinitions so that we can rely 2059 // that \c Existing is part of a framework iff the redefinition of FW 2060 // we have just skipped had it too. Once we do that, stop checking 2061 // the local framework qualifier and only rely on \c Existing. 2062 bool PartOfFramework = Framework || Existing->isPartOfFramework(); 2063 // - If we're building a (preprocessed) module and we've just loaded the 2064 // module map file from which it was created. 2065 bool ParsedAsMainInput = 2066 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 2067 Map.LangOpts.CurrentModule == ModuleName && 2068 SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 2069 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 2070 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) { 2071 ActiveModule = PreviousActiveModule; 2072 // Skip the module definition. 2073 skipUntil(MMToken::RBrace); 2074 if (Tok.is(MMToken::RBrace)) 2075 consumeToken(); 2076 else { 2077 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2078 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2079 HadError = true; 2080 } 2081 return; 2082 } 2083 2084 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) { 2085 ShadowingModule = Existing; 2086 } else { 2087 // This is not a shawdowed module decl, it is an illegal redefinition. 2088 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 2089 << ModuleName; 2090 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 2091 2092 // Skip the module definition. 2093 skipUntil(MMToken::RBrace); 2094 if (Tok.is(MMToken::RBrace)) 2095 consumeToken(); 2096 2097 HadError = true; 2098 return; 2099 } 2100 } 2101 2102 // Start defining this module. 2103 if (ShadowingModule) { 2104 ActiveModule = 2105 Map.createShadowedModule(ModuleName, Framework, ShadowingModule); 2106 } else { 2107 ActiveModule = 2108 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit) 2109 .first; 2110 } 2111 2112 ActiveModule->DefinitionLoc = ModuleNameLoc; 2113 if (Attrs.IsSystem || IsSystem) 2114 ActiveModule->IsSystem = true; 2115 if (Attrs.IsExternC) 2116 ActiveModule->IsExternC = true; 2117 if (Attrs.NoUndeclaredIncludes) 2118 ActiveModule->NoUndeclaredIncludes = true; 2119 ActiveModule->Directory = Directory; 2120 2121 StringRef MapFileName(ModuleMapFile.getName()); 2122 if (MapFileName.ends_with("module.private.modulemap") || 2123 MapFileName.ends_with("module_private.map")) { 2124 ActiveModule->ModuleMapIsPrivate = true; 2125 } 2126 2127 // Private modules named as FooPrivate, Foo.Private or similar are likely a 2128 // user error; provide warnings, notes and fixits to direct users to use 2129 // Foo_Private instead. 2130 SourceLocation StartLoc = 2131 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); 2132 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && 2133 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule, 2134 StartLoc) && 2135 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name, 2136 StartLoc) && 2137 ActiveModule->ModuleMapIsPrivate) 2138 diagnosePrivateModules(ExplicitLoc, FrameworkLoc); 2139 2140 bool Done = false; 2141 do { 2142 switch (Tok.Kind) { 2143 case MMToken::EndOfFile: 2144 case MMToken::RBrace: 2145 Done = true; 2146 break; 2147 2148 case MMToken::ConfigMacros: 2149 parseConfigMacros(); 2150 break; 2151 2152 case MMToken::Conflict: 2153 parseConflict(); 2154 break; 2155 2156 case MMToken::ExplicitKeyword: 2157 case MMToken::ExternKeyword: 2158 case MMToken::FrameworkKeyword: 2159 case MMToken::ModuleKeyword: 2160 parseModuleDecl(); 2161 break; 2162 2163 case MMToken::ExportKeyword: 2164 parseExportDecl(); 2165 break; 2166 2167 case MMToken::ExportAsKeyword: 2168 parseExportAsDecl(); 2169 break; 2170 2171 case MMToken::UseKeyword: 2172 parseUseDecl(); 2173 break; 2174 2175 case MMToken::RequiresKeyword: 2176 parseRequiresDecl(); 2177 break; 2178 2179 case MMToken::TextualKeyword: 2180 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 2181 break; 2182 2183 case MMToken::UmbrellaKeyword: { 2184 SourceLocation UmbrellaLoc = consumeToken(); 2185 if (Tok.is(MMToken::HeaderKeyword)) 2186 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 2187 else 2188 parseUmbrellaDirDecl(UmbrellaLoc); 2189 break; 2190 } 2191 2192 case MMToken::ExcludeKeyword: 2193 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 2194 break; 2195 2196 case MMToken::PrivateKeyword: 2197 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 2198 break; 2199 2200 case MMToken::HeaderKeyword: 2201 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 2202 break; 2203 2204 case MMToken::LinkKeyword: 2205 parseLinkDecl(); 2206 break; 2207 2208 default: 2209 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 2210 consumeToken(); 2211 break; 2212 } 2213 } while (!Done); 2214 2215 if (Tok.is(MMToken::RBrace)) 2216 consumeToken(); 2217 else { 2218 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2219 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2220 HadError = true; 2221 } 2222 2223 // If the active module is a top-level framework, and there are no link 2224 // libraries, automatically link against the framework. 2225 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 2226 ActiveModule->LinkLibraries.empty()) 2227 inferFrameworkLink(ActiveModule); 2228 2229 // If the module meets all requirements but is still unavailable, mark the 2230 // whole tree as unavailable to prevent it from building. 2231 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable && 2232 ActiveModule->Parent) { 2233 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false); 2234 ActiveModule->getTopLevelModule()->MissingHeaders.append( 2235 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 2236 } 2237 2238 // We're done parsing this module. Pop back to the previous module. 2239 ActiveModule = PreviousActiveModule; 2240 } 2241 2242 /// Parse an extern module declaration. 2243 /// 2244 /// extern module-declaration: 2245 /// 'extern' 'module' module-id string-literal 2246 void ModuleMapParser::parseExternModuleDecl() { 2247 assert(Tok.is(MMToken::ExternKeyword)); 2248 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 2249 2250 // Parse 'module' keyword. 2251 if (!Tok.is(MMToken::ModuleKeyword)) { 2252 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2253 consumeToken(); 2254 HadError = true; 2255 return; 2256 } 2257 consumeToken(); // 'module' keyword 2258 2259 // Parse the module name. 2260 ModuleId Id; 2261 if (parseModuleId(Id)) { 2262 HadError = true; 2263 return; 2264 } 2265 2266 // Parse the referenced module map file name. 2267 if (!Tok.is(MMToken::StringLiteral)) { 2268 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 2269 HadError = true; 2270 return; 2271 } 2272 std::string FileName = std::string(Tok.getString()); 2273 consumeToken(); // filename 2274 2275 StringRef FileNameRef = FileName; 2276 SmallString<128> ModuleMapFileName; 2277 if (llvm::sys::path::is_relative(FileNameRef)) { 2278 ModuleMapFileName += Directory.getName(); 2279 llvm::sys::path::append(ModuleMapFileName, FileName); 2280 FileNameRef = ModuleMapFileName; 2281 } 2282 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) 2283 Map.parseModuleMapFile( 2284 *File, IsSystem, 2285 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 2286 ? Directory 2287 : File->getDir(), 2288 FileID(), nullptr, ExternLoc); 2289 } 2290 2291 /// Whether to add the requirement \p Feature to the module \p M. 2292 /// 2293 /// This preserves backwards compatibility for two hacks in the Darwin system 2294 /// module map files: 2295 /// 2296 /// 1. The use of 'requires excluded' to make headers non-modular, which 2297 /// should really be mapped to 'textual' now that we have this feature. We 2298 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 2299 /// true. Later, this bit will be used to map all the headers inside this 2300 /// module to 'textual'. 2301 /// 2302 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 2303 /// 2304 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 2305 /// was never correct and causes issues now that we check it, so drop it. 2306 static bool shouldAddRequirement(Module *M, StringRef Feature, 2307 bool &IsRequiresExcludedHack) { 2308 if (Feature == "excluded" && 2309 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 2310 M->fullModuleNameIs({"Tcl", "Private"}))) { 2311 IsRequiresExcludedHack = true; 2312 return false; 2313 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 2314 return false; 2315 } 2316 2317 return true; 2318 } 2319 2320 /// Parse a requires declaration. 2321 /// 2322 /// requires-declaration: 2323 /// 'requires' feature-list 2324 /// 2325 /// feature-list: 2326 /// feature ',' feature-list 2327 /// feature 2328 /// 2329 /// feature: 2330 /// '!'[opt] identifier 2331 void ModuleMapParser::parseRequiresDecl() { 2332 assert(Tok.is(MMToken::RequiresKeyword)); 2333 2334 // Parse 'requires' keyword. 2335 consumeToken(); 2336 2337 // Parse the feature-list. 2338 do { 2339 bool RequiredState = true; 2340 if (Tok.is(MMToken::Exclaim)) { 2341 RequiredState = false; 2342 consumeToken(); 2343 } 2344 2345 if (!Tok.is(MMToken::Identifier)) { 2346 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 2347 HadError = true; 2348 return; 2349 } 2350 2351 // Consume the feature name. 2352 std::string Feature = std::string(Tok.getString()); 2353 consumeToken(); 2354 2355 bool IsRequiresExcludedHack = false; 2356 bool ShouldAddRequirement = 2357 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2358 2359 if (IsRequiresExcludedHack) 2360 UsesRequiresExcludedHack.insert(ActiveModule); 2361 2362 if (ShouldAddRequirement) { 2363 // Add this feature. 2364 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2365 *Map.Target); 2366 } 2367 2368 if (!Tok.is(MMToken::Comma)) 2369 break; 2370 2371 // Consume the comma. 2372 consumeToken(); 2373 } while (true); 2374 } 2375 2376 /// Parse a header declaration. 2377 /// 2378 /// header-declaration: 2379 /// 'textual'[opt] 'header' string-literal 2380 /// 'private' 'textual'[opt] 'header' string-literal 2381 /// 'exclude' 'header' string-literal 2382 /// 'umbrella' 'header' string-literal 2383 /// 2384 /// FIXME: Support 'private textual header'. 2385 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2386 SourceLocation LeadingLoc) { 2387 // We've already consumed the first token. 2388 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2389 2390 if (LeadingToken == MMToken::PrivateKeyword) { 2391 Role = ModuleMap::PrivateHeader; 2392 // 'private' may optionally be followed by 'textual'. 2393 if (Tok.is(MMToken::TextualKeyword)) { 2394 LeadingToken = Tok.Kind; 2395 consumeToken(); 2396 } 2397 } else if (LeadingToken == MMToken::ExcludeKeyword) { 2398 Role = ModuleMap::ExcludedHeader; 2399 } 2400 2401 if (LeadingToken == MMToken::TextualKeyword) 2402 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2403 2404 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2405 // Mark this header 'textual' (see doc comment for 2406 // Module::UsesRequiresExcludedHack). 2407 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2408 } 2409 2410 if (LeadingToken != MMToken::HeaderKeyword) { 2411 if (!Tok.is(MMToken::HeaderKeyword)) { 2412 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2413 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2414 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2415 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2416 return; 2417 } 2418 consumeToken(); 2419 } 2420 2421 // Parse the header name. 2422 if (!Tok.is(MMToken::StringLiteral)) { 2423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2424 << "header"; 2425 HadError = true; 2426 return; 2427 } 2428 Module::UnresolvedHeaderDirective Header; 2429 Header.FileName = std::string(Tok.getString()); 2430 Header.FileNameLoc = consumeToken(); 2431 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2432 Header.Kind = Map.headerRoleToKind(Role); 2433 2434 // Check whether we already have an umbrella. 2435 if (Header.IsUmbrella && 2436 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) { 2437 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2438 << ActiveModule->getFullModuleName(); 2439 HadError = true; 2440 return; 2441 } 2442 2443 // If we were given stat information, parse it so we can skip looking for 2444 // the file. 2445 if (Tok.is(MMToken::LBrace)) { 2446 SourceLocation LBraceLoc = consumeToken(); 2447 2448 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2449 enum Attribute { Size, ModTime, Unknown }; 2450 StringRef Str = Tok.getString(); 2451 SourceLocation Loc = consumeToken(); 2452 switch (llvm::StringSwitch<Attribute>(Str) 2453 .Case("size", Size) 2454 .Case("mtime", ModTime) 2455 .Default(Unknown)) { 2456 case Size: 2457 if (Header.Size) 2458 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2459 if (!Tok.is(MMToken::IntegerLiteral)) { 2460 Diags.Report(Tok.getLocation(), 2461 diag::err_mmap_invalid_header_attribute_value) << Str; 2462 skipUntil(MMToken::RBrace); 2463 break; 2464 } 2465 Header.Size = Tok.getInteger(); 2466 consumeToken(); 2467 break; 2468 2469 case ModTime: 2470 if (Header.ModTime) 2471 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2472 if (!Tok.is(MMToken::IntegerLiteral)) { 2473 Diags.Report(Tok.getLocation(), 2474 diag::err_mmap_invalid_header_attribute_value) << Str; 2475 skipUntil(MMToken::RBrace); 2476 break; 2477 } 2478 Header.ModTime = Tok.getInteger(); 2479 consumeToken(); 2480 break; 2481 2482 case Unknown: 2483 Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2484 skipUntil(MMToken::RBrace); 2485 break; 2486 } 2487 } 2488 2489 if (Tok.is(MMToken::RBrace)) 2490 consumeToken(); 2491 else { 2492 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2493 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2494 HadError = true; 2495 } 2496 } 2497 2498 bool NeedsFramework = false; 2499 // Don't add the top level headers to the builtin modules if the builtin headers 2500 // belong to the system modules. 2501 if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name)) 2502 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework); 2503 2504 if (NeedsFramework) 2505 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword) 2506 << ActiveModule->getFullModuleName() 2507 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module"); 2508 } 2509 2510 static bool compareModuleHeaders(const Module::Header &A, 2511 const Module::Header &B) { 2512 return A.NameAsWritten < B.NameAsWritten; 2513 } 2514 2515 /// Parse an umbrella directory declaration. 2516 /// 2517 /// umbrella-dir-declaration: 2518 /// umbrella string-literal 2519 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2520 // Parse the directory name. 2521 if (!Tok.is(MMToken::StringLiteral)) { 2522 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2523 << "umbrella"; 2524 HadError = true; 2525 return; 2526 } 2527 2528 std::string DirName = std::string(Tok.getString()); 2529 std::string DirNameAsWritten = DirName; 2530 SourceLocation DirNameLoc = consumeToken(); 2531 2532 // Check whether we already have an umbrella. 2533 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) { 2534 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2535 << ActiveModule->getFullModuleName(); 2536 HadError = true; 2537 return; 2538 } 2539 2540 // Look for this file. 2541 OptionalDirectoryEntryRef Dir; 2542 if (llvm::sys::path::is_absolute(DirName)) { 2543 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName); 2544 } else { 2545 SmallString<128> PathName; 2546 PathName = Directory.getName(); 2547 llvm::sys::path::append(PathName, DirName); 2548 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName); 2549 } 2550 2551 if (!Dir) { 2552 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2553 << DirName; 2554 return; 2555 } 2556 2557 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2558 // Mark this header 'textual' (see doc comment for 2559 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2560 // directory is relatively expensive, in practice this only applies to the 2561 // uncommonly used Tcl module on Darwin platforms. 2562 std::error_code EC; 2563 SmallVector<Module::Header, 6> Headers; 2564 llvm::vfs::FileSystem &FS = 2565 SourceMgr.getFileManager().getVirtualFileSystem(); 2566 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2567 I != E && !EC; I.increment(EC)) { 2568 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) { 2569 Module::Header Header = {"", std::string(I->path()), *FE}; 2570 Headers.push_back(std::move(Header)); 2571 } 2572 } 2573 2574 // Sort header paths so that the pcm doesn't depend on iteration order. 2575 std::stable_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2576 2577 for (auto &Header : Headers) 2578 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2579 return; 2580 } 2581 2582 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) { 2583 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2584 << OwningModule->getFullModuleName(); 2585 HadError = true; 2586 return; 2587 } 2588 2589 // Record this umbrella directory. 2590 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName); 2591 } 2592 2593 /// Parse a module export declaration. 2594 /// 2595 /// export-declaration: 2596 /// 'export' wildcard-module-id 2597 /// 2598 /// wildcard-module-id: 2599 /// identifier 2600 /// '*' 2601 /// identifier '.' wildcard-module-id 2602 void ModuleMapParser::parseExportDecl() { 2603 assert(Tok.is(MMToken::ExportKeyword)); 2604 SourceLocation ExportLoc = consumeToken(); 2605 2606 // Parse the module-id with an optional wildcard at the end. 2607 ModuleId ParsedModuleId; 2608 bool Wildcard = false; 2609 do { 2610 // FIXME: Support string-literal module names here. 2611 if (Tok.is(MMToken::Identifier)) { 2612 ParsedModuleId.push_back( 2613 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 2614 consumeToken(); 2615 2616 if (Tok.is(MMToken::Period)) { 2617 consumeToken(); 2618 continue; 2619 } 2620 2621 break; 2622 } 2623 2624 if(Tok.is(MMToken::Star)) { 2625 Wildcard = true; 2626 consumeToken(); 2627 break; 2628 } 2629 2630 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2631 HadError = true; 2632 return; 2633 } while (true); 2634 2635 Module::UnresolvedExportDecl Unresolved = { 2636 ExportLoc, ParsedModuleId, Wildcard 2637 }; 2638 ActiveModule->UnresolvedExports.push_back(Unresolved); 2639 } 2640 2641 /// Parse a module export_as declaration. 2642 /// 2643 /// export-as-declaration: 2644 /// 'export_as' identifier 2645 void ModuleMapParser::parseExportAsDecl() { 2646 assert(Tok.is(MMToken::ExportAsKeyword)); 2647 consumeToken(); 2648 2649 if (!Tok.is(MMToken::Identifier)) { 2650 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2651 HadError = true; 2652 return; 2653 } 2654 2655 if (ActiveModule->Parent) { 2656 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); 2657 consumeToken(); 2658 return; 2659 } 2660 2661 if (!ActiveModule->ExportAsModule.empty()) { 2662 if (ActiveModule->ExportAsModule == Tok.getString()) { 2663 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) 2664 << ActiveModule->Name << Tok.getString(); 2665 } else { 2666 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) 2667 << ActiveModule->Name << ActiveModule->ExportAsModule 2668 << Tok.getString(); 2669 } 2670 } 2671 2672 ActiveModule->ExportAsModule = std::string(Tok.getString()); 2673 Map.addLinkAsDependency(ActiveModule); 2674 2675 consumeToken(); 2676 } 2677 2678 /// Parse a module use declaration. 2679 /// 2680 /// use-declaration: 2681 /// 'use' wildcard-module-id 2682 void ModuleMapParser::parseUseDecl() { 2683 assert(Tok.is(MMToken::UseKeyword)); 2684 auto KWLoc = consumeToken(); 2685 // Parse the module-id. 2686 ModuleId ParsedModuleId; 2687 parseModuleId(ParsedModuleId); 2688 2689 if (ActiveModule->Parent) 2690 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2691 else 2692 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2693 } 2694 2695 /// Parse a link declaration. 2696 /// 2697 /// module-declaration: 2698 /// 'link' 'framework'[opt] string-literal 2699 void ModuleMapParser::parseLinkDecl() { 2700 assert(Tok.is(MMToken::LinkKeyword)); 2701 SourceLocation LinkLoc = consumeToken(); 2702 2703 // Parse the optional 'framework' keyword. 2704 bool IsFramework = false; 2705 if (Tok.is(MMToken::FrameworkKeyword)) { 2706 consumeToken(); 2707 IsFramework = true; 2708 } 2709 2710 // Parse the library name 2711 if (!Tok.is(MMToken::StringLiteral)) { 2712 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2713 << IsFramework << SourceRange(LinkLoc); 2714 HadError = true; 2715 return; 2716 } 2717 2718 std::string LibraryName = std::string(Tok.getString()); 2719 consumeToken(); 2720 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2721 IsFramework)); 2722 } 2723 2724 /// Parse a configuration macro declaration. 2725 /// 2726 /// module-declaration: 2727 /// 'config_macros' attributes[opt] config-macro-list? 2728 /// 2729 /// config-macro-list: 2730 /// identifier (',' identifier)? 2731 void ModuleMapParser::parseConfigMacros() { 2732 assert(Tok.is(MMToken::ConfigMacros)); 2733 SourceLocation ConfigMacrosLoc = consumeToken(); 2734 2735 // Only top-level modules can have configuration macros. 2736 if (ActiveModule->Parent) { 2737 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2738 } 2739 2740 // Parse the optional attributes. 2741 Attributes Attrs; 2742 if (parseOptionalAttributes(Attrs)) 2743 return; 2744 2745 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2746 ActiveModule->ConfigMacrosExhaustive = true; 2747 } 2748 2749 // If we don't have an identifier, we're done. 2750 // FIXME: Support macros with the same name as a keyword here. 2751 if (!Tok.is(MMToken::Identifier)) 2752 return; 2753 2754 // Consume the first identifier. 2755 if (!ActiveModule->Parent) { 2756 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2757 } 2758 consumeToken(); 2759 2760 do { 2761 // If there's a comma, consume it. 2762 if (!Tok.is(MMToken::Comma)) 2763 break; 2764 consumeToken(); 2765 2766 // We expect to see a macro name here. 2767 // FIXME: Support macros with the same name as a keyword here. 2768 if (!Tok.is(MMToken::Identifier)) { 2769 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2770 break; 2771 } 2772 2773 // Consume the macro name. 2774 if (!ActiveModule->Parent) { 2775 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2776 } 2777 consumeToken(); 2778 } while (true); 2779 } 2780 2781 /// Format a module-id into a string. 2782 static std::string formatModuleId(const ModuleId &Id) { 2783 std::string result; 2784 { 2785 llvm::raw_string_ostream OS(result); 2786 2787 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2788 if (I) 2789 OS << "."; 2790 OS << Id[I].first; 2791 } 2792 } 2793 2794 return result; 2795 } 2796 2797 /// Parse a conflict declaration. 2798 /// 2799 /// module-declaration: 2800 /// 'conflict' module-id ',' string-literal 2801 void ModuleMapParser::parseConflict() { 2802 assert(Tok.is(MMToken::Conflict)); 2803 SourceLocation ConflictLoc = consumeToken(); 2804 Module::UnresolvedConflict Conflict; 2805 2806 // Parse the module-id. 2807 if (parseModuleId(Conflict.Id)) 2808 return; 2809 2810 // Parse the ','. 2811 if (!Tok.is(MMToken::Comma)) { 2812 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2813 << SourceRange(ConflictLoc); 2814 return; 2815 } 2816 consumeToken(); 2817 2818 // Parse the message. 2819 if (!Tok.is(MMToken::StringLiteral)) { 2820 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2821 << formatModuleId(Conflict.Id); 2822 return; 2823 } 2824 Conflict.Message = Tok.getString().str(); 2825 consumeToken(); 2826 2827 // Add this unresolved conflict. 2828 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2829 } 2830 2831 /// Parse an inferred module declaration (wildcard modules). 2832 /// 2833 /// module-declaration: 2834 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2835 /// { inferred-module-member* } 2836 /// 2837 /// inferred-module-member: 2838 /// 'export' '*' 2839 /// 'exclude' identifier 2840 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2841 assert(Tok.is(MMToken::Star)); 2842 SourceLocation StarLoc = consumeToken(); 2843 bool Failed = false; 2844 2845 // Inferred modules must be submodules. 2846 if (!ActiveModule && !Framework) { 2847 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2848 Failed = true; 2849 } 2850 2851 if (ActiveModule) { 2852 // Inferred modules must have umbrella directories. 2853 if (!Failed && ActiveModule->IsAvailable && 2854 !ActiveModule->getEffectiveUmbrellaDir()) { 2855 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2856 Failed = true; 2857 } 2858 2859 // Check for redefinition of an inferred module. 2860 if (!Failed && ActiveModule->InferSubmodules) { 2861 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2862 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2863 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2864 diag::note_mmap_prev_definition); 2865 Failed = true; 2866 } 2867 2868 // Check for the 'framework' keyword, which is not permitted here. 2869 if (Framework) { 2870 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2871 Framework = false; 2872 } 2873 } else if (Explicit) { 2874 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2875 Explicit = false; 2876 } 2877 2878 // If there were any problems with this inferred submodule, skip its body. 2879 if (Failed) { 2880 if (Tok.is(MMToken::LBrace)) { 2881 consumeToken(); 2882 skipUntil(MMToken::RBrace); 2883 if (Tok.is(MMToken::RBrace)) 2884 consumeToken(); 2885 } 2886 HadError = true; 2887 return; 2888 } 2889 2890 // Parse optional attributes. 2891 Attributes Attrs; 2892 if (parseOptionalAttributes(Attrs)) 2893 return; 2894 2895 if (ActiveModule) { 2896 // Note that we have an inferred submodule. 2897 ActiveModule->InferSubmodules = true; 2898 ActiveModule->InferredSubmoduleLoc = StarLoc; 2899 ActiveModule->InferExplicitSubmodules = Explicit; 2900 } else { 2901 // We'll be inferring framework modules for this directory. 2902 Map.InferredDirectories[Directory].InferModules = true; 2903 Map.InferredDirectories[Directory].Attrs = Attrs; 2904 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2905 // FIXME: Handle the 'framework' keyword. 2906 } 2907 2908 // Parse the opening brace. 2909 if (!Tok.is(MMToken::LBrace)) { 2910 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2911 HadError = true; 2912 return; 2913 } 2914 SourceLocation LBraceLoc = consumeToken(); 2915 2916 // Parse the body of the inferred submodule. 2917 bool Done = false; 2918 do { 2919 switch (Tok.Kind) { 2920 case MMToken::EndOfFile: 2921 case MMToken::RBrace: 2922 Done = true; 2923 break; 2924 2925 case MMToken::ExcludeKeyword: 2926 if (ActiveModule) { 2927 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2928 << (ActiveModule != nullptr); 2929 consumeToken(); 2930 break; 2931 } 2932 2933 consumeToken(); 2934 // FIXME: Support string-literal module names here. 2935 if (!Tok.is(MMToken::Identifier)) { 2936 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2937 break; 2938 } 2939 2940 Map.InferredDirectories[Directory].ExcludedModules.push_back( 2941 std::string(Tok.getString())); 2942 consumeToken(); 2943 break; 2944 2945 case MMToken::ExportKeyword: 2946 if (!ActiveModule) { 2947 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2948 << (ActiveModule != nullptr); 2949 consumeToken(); 2950 break; 2951 } 2952 2953 consumeToken(); 2954 if (Tok.is(MMToken::Star)) 2955 ActiveModule->InferExportWildcard = true; 2956 else 2957 Diags.Report(Tok.getLocation(), 2958 diag::err_mmap_expected_export_wildcard); 2959 consumeToken(); 2960 break; 2961 2962 case MMToken::ExplicitKeyword: 2963 case MMToken::ModuleKeyword: 2964 case MMToken::HeaderKeyword: 2965 case MMToken::PrivateKeyword: 2966 case MMToken::UmbrellaKeyword: 2967 default: 2968 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2969 << (ActiveModule != nullptr); 2970 consumeToken(); 2971 break; 2972 } 2973 } while (!Done); 2974 2975 if (Tok.is(MMToken::RBrace)) 2976 consumeToken(); 2977 else { 2978 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2979 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2980 HadError = true; 2981 } 2982 } 2983 2984 /// Parse optional attributes. 2985 /// 2986 /// attributes: 2987 /// attribute attributes 2988 /// attribute 2989 /// 2990 /// attribute: 2991 /// [ identifier ] 2992 /// 2993 /// \param Attrs Will be filled in with the parsed attributes. 2994 /// 2995 /// \returns true if an error occurred, false otherwise. 2996 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2997 bool HadError = false; 2998 2999 while (Tok.is(MMToken::LSquare)) { 3000 // Consume the '['. 3001 SourceLocation LSquareLoc = consumeToken(); 3002 3003 // Check whether we have an attribute name here. 3004 if (!Tok.is(MMToken::Identifier)) { 3005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 3006 skipUntil(MMToken::RSquare); 3007 if (Tok.is(MMToken::RSquare)) 3008 consumeToken(); 3009 HadError = true; 3010 } 3011 3012 // Decode the attribute name. 3013 AttributeKind Attribute 3014 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 3015 .Case("exhaustive", AT_exhaustive) 3016 .Case("extern_c", AT_extern_c) 3017 .Case("no_undeclared_includes", AT_no_undeclared_includes) 3018 .Case("system", AT_system) 3019 .Default(AT_unknown); 3020 switch (Attribute) { 3021 case AT_unknown: 3022 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 3023 << Tok.getString(); 3024 break; 3025 3026 case AT_system: 3027 Attrs.IsSystem = true; 3028 break; 3029 3030 case AT_extern_c: 3031 Attrs.IsExternC = true; 3032 break; 3033 3034 case AT_exhaustive: 3035 Attrs.IsExhaustive = true; 3036 break; 3037 3038 case AT_no_undeclared_includes: 3039 Attrs.NoUndeclaredIncludes = true; 3040 break; 3041 } 3042 consumeToken(); 3043 3044 // Consume the ']'. 3045 if (!Tok.is(MMToken::RSquare)) { 3046 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 3047 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 3048 skipUntil(MMToken::RSquare); 3049 HadError = true; 3050 } 3051 3052 if (Tok.is(MMToken::RSquare)) 3053 consumeToken(); 3054 } 3055 3056 return HadError; 3057 } 3058 3059 /// Parse a module map file. 3060 /// 3061 /// module-map-file: 3062 /// module-declaration* 3063 bool ModuleMapParser::parseModuleMapFile() { 3064 do { 3065 switch (Tok.Kind) { 3066 case MMToken::EndOfFile: 3067 return HadError; 3068 3069 case MMToken::ExplicitKeyword: 3070 case MMToken::ExternKeyword: 3071 case MMToken::ModuleKeyword: 3072 case MMToken::FrameworkKeyword: 3073 parseModuleDecl(); 3074 break; 3075 3076 case MMToken::Comma: 3077 case MMToken::ConfigMacros: 3078 case MMToken::Conflict: 3079 case MMToken::Exclaim: 3080 case MMToken::ExcludeKeyword: 3081 case MMToken::ExportKeyword: 3082 case MMToken::ExportAsKeyword: 3083 case MMToken::HeaderKeyword: 3084 case MMToken::Identifier: 3085 case MMToken::LBrace: 3086 case MMToken::LinkKeyword: 3087 case MMToken::LSquare: 3088 case MMToken::Period: 3089 case MMToken::PrivateKeyword: 3090 case MMToken::RBrace: 3091 case MMToken::RSquare: 3092 case MMToken::RequiresKeyword: 3093 case MMToken::Star: 3094 case MMToken::StringLiteral: 3095 case MMToken::IntegerLiteral: 3096 case MMToken::TextualKeyword: 3097 case MMToken::UmbrellaKeyword: 3098 case MMToken::UseKeyword: 3099 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 3100 HadError = true; 3101 consumeToken(); 3102 break; 3103 } 3104 } while (true); 3105 } 3106 3107 bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem, 3108 DirectoryEntryRef Dir, FileID ID, 3109 unsigned *Offset, 3110 SourceLocation ExternModuleLoc) { 3111 assert(Target && "Missing target information"); 3112 llvm::DenseMap<const FileEntry *, bool>::iterator Known 3113 = ParsedModuleMap.find(File); 3114 if (Known != ParsedModuleMap.end()) 3115 return Known->second; 3116 3117 // If the module map file wasn't already entered, do so now. 3118 if (ID.isInvalid()) { 3119 auto FileCharacter = 3120 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 3121 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 3122 } 3123 3124 assert(Target && "Missing target information"); 3125 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID); 3126 if (!Buffer) 3127 return ParsedModuleMap[File] = true; 3128 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 3129 "invalid buffer offset"); 3130 3131 // Parse this module map file. 3132 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 3133 Buffer->getBufferStart(), 3134 Buffer->getBufferStart() + (Offset ? *Offset : 0), 3135 Buffer->getBufferEnd()); 3136 SourceLocation Start = L.getSourceLocation(); 3137 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 3138 IsSystem); 3139 bool Result = Parser.parseModuleMapFile(); 3140 ParsedModuleMap[File] = Result; 3141 3142 if (Offset) { 3143 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 3144 assert(Loc.first == ID && "stopped in a different file?"); 3145 *Offset = Loc.second; 3146 } 3147 3148 // Notify callbacks that we parsed it. 3149 for (const auto &Cb : Callbacks) 3150 Cb->moduleMapFileRead(Start, File, IsSystem); 3151 3152 return Result; 3153 } 3154