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