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