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