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