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