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