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