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