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