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 (OptionalFileEntryRef ModMapFile = 1023 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) { 1024 parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir); 1025 inferred = InferredDirectories.find(*ParentDir); 1026 } 1027 1028 if (inferred == InferredDirectories.end()) 1029 inferred = InferredDirectories.insert( 1030 std::make_pair(*ParentDir, InferredDirectory())).first; 1031 } 1032 1033 if (inferred->second.InferModules) { 1034 // We're allowed to infer for this directory, but make sure it's okay 1035 // to infer this particular module. 1036 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 1037 canInfer = 1038 !llvm::is_contained(inferred->second.ExcludedModules, Name); 1039 1040 Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 1041 Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 1042 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 1043 Attrs.NoUndeclaredIncludes |= 1044 inferred->second.Attrs.NoUndeclaredIncludes; 1045 ModuleMapFile = inferred->second.ModuleMapFile; 1046 } 1047 } 1048 } 1049 1050 // If we're not allowed to infer a framework module, don't. 1051 if (!canInfer) 1052 return nullptr; 1053 } else { 1054 OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef = 1055 getModuleMapFileForUniquing(Parent); 1056 ModuleMapFile = ModuleMapRef; 1057 } 1058 1059 // Look for an umbrella header. 1060 SmallString<128> UmbrellaName = 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, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, 1190 const Twine &PathRelativeToRootModuleDirectory) { 1191 Mod->Umbrella = &UmbrellaDir.getMapEntry(); 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 OptionalDirectoryEntryRef Dir; 2519 if (llvm::sys::path::is_absolute(DirName)) { 2520 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName); 2521 } else { 2522 SmallString<128> PathName; 2523 PathName = Directory->getName(); 2524 llvm::sys::path::append(PathName, DirName); 2525 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName); 2526 } 2527 2528 if (!Dir) { 2529 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2530 << DirName; 2531 return; 2532 } 2533 2534 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2535 // Mark this header 'textual' (see doc comment for 2536 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2537 // directory is relatively expensive, in practice this only applies to the 2538 // uncommonly used Tcl module on Darwin platforms. 2539 std::error_code EC; 2540 SmallVector<Module::Header, 6> Headers; 2541 llvm::vfs::FileSystem &FS = 2542 SourceMgr.getFileManager().getVirtualFileSystem(); 2543 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2544 I != E && !EC; I.increment(EC)) { 2545 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) { 2546 Module::Header Header = {"", std::string(I->path()), FE}; 2547 Headers.push_back(std::move(Header)); 2548 } 2549 } 2550 2551 // Sort header paths so that the pcm doesn't depend on iteration order. 2552 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2553 2554 for (auto &Header : Headers) 2555 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2556 return; 2557 } 2558 2559 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) { 2560 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2561 << OwningModule->getFullModuleName(); 2562 HadError = true; 2563 return; 2564 } 2565 2566 // Record this umbrella directory. 2567 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName); 2568 } 2569 2570 /// Parse a module export declaration. 2571 /// 2572 /// export-declaration: 2573 /// 'export' wildcard-module-id 2574 /// 2575 /// wildcard-module-id: 2576 /// identifier 2577 /// '*' 2578 /// identifier '.' wildcard-module-id 2579 void ModuleMapParser::parseExportDecl() { 2580 assert(Tok.is(MMToken::ExportKeyword)); 2581 SourceLocation ExportLoc = consumeToken(); 2582 2583 // Parse the module-id with an optional wildcard at the end. 2584 ModuleId ParsedModuleId; 2585 bool Wildcard = false; 2586 do { 2587 // FIXME: Support string-literal module names here. 2588 if (Tok.is(MMToken::Identifier)) { 2589 ParsedModuleId.push_back( 2590 std::make_pair(std::string(Tok.getString()), Tok.getLocation())); 2591 consumeToken(); 2592 2593 if (Tok.is(MMToken::Period)) { 2594 consumeToken(); 2595 continue; 2596 } 2597 2598 break; 2599 } 2600 2601 if(Tok.is(MMToken::Star)) { 2602 Wildcard = true; 2603 consumeToken(); 2604 break; 2605 } 2606 2607 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2608 HadError = true; 2609 return; 2610 } while (true); 2611 2612 Module::UnresolvedExportDecl Unresolved = { 2613 ExportLoc, ParsedModuleId, Wildcard 2614 }; 2615 ActiveModule->UnresolvedExports.push_back(Unresolved); 2616 } 2617 2618 /// Parse a module export_as declaration. 2619 /// 2620 /// export-as-declaration: 2621 /// 'export_as' identifier 2622 void ModuleMapParser::parseExportAsDecl() { 2623 assert(Tok.is(MMToken::ExportAsKeyword)); 2624 consumeToken(); 2625 2626 if (!Tok.is(MMToken::Identifier)) { 2627 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2628 HadError = true; 2629 return; 2630 } 2631 2632 if (ActiveModule->Parent) { 2633 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); 2634 consumeToken(); 2635 return; 2636 } 2637 2638 if (!ActiveModule->ExportAsModule.empty()) { 2639 if (ActiveModule->ExportAsModule == Tok.getString()) { 2640 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) 2641 << ActiveModule->Name << Tok.getString(); 2642 } else { 2643 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) 2644 << ActiveModule->Name << ActiveModule->ExportAsModule 2645 << Tok.getString(); 2646 } 2647 } 2648 2649 ActiveModule->ExportAsModule = std::string(Tok.getString()); 2650 Map.addLinkAsDependency(ActiveModule); 2651 2652 consumeToken(); 2653 } 2654 2655 /// Parse a module use declaration. 2656 /// 2657 /// use-declaration: 2658 /// 'use' wildcard-module-id 2659 void ModuleMapParser::parseUseDecl() { 2660 assert(Tok.is(MMToken::UseKeyword)); 2661 auto KWLoc = consumeToken(); 2662 // Parse the module-id. 2663 ModuleId ParsedModuleId; 2664 parseModuleId(ParsedModuleId); 2665 2666 if (ActiveModule->Parent) 2667 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2668 else 2669 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2670 } 2671 2672 /// Parse a link declaration. 2673 /// 2674 /// module-declaration: 2675 /// 'link' 'framework'[opt] string-literal 2676 void ModuleMapParser::parseLinkDecl() { 2677 assert(Tok.is(MMToken::LinkKeyword)); 2678 SourceLocation LinkLoc = consumeToken(); 2679 2680 // Parse the optional 'framework' keyword. 2681 bool IsFramework = false; 2682 if (Tok.is(MMToken::FrameworkKeyword)) { 2683 consumeToken(); 2684 IsFramework = true; 2685 } 2686 2687 // Parse the library name 2688 if (!Tok.is(MMToken::StringLiteral)) { 2689 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2690 << IsFramework << SourceRange(LinkLoc); 2691 HadError = true; 2692 return; 2693 } 2694 2695 std::string LibraryName = std::string(Tok.getString()); 2696 consumeToken(); 2697 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2698 IsFramework)); 2699 } 2700 2701 /// Parse a configuration macro declaration. 2702 /// 2703 /// module-declaration: 2704 /// 'config_macros' attributes[opt] config-macro-list? 2705 /// 2706 /// config-macro-list: 2707 /// identifier (',' identifier)? 2708 void ModuleMapParser::parseConfigMacros() { 2709 assert(Tok.is(MMToken::ConfigMacros)); 2710 SourceLocation ConfigMacrosLoc = consumeToken(); 2711 2712 // Only top-level modules can have configuration macros. 2713 if (ActiveModule->Parent) { 2714 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2715 } 2716 2717 // Parse the optional attributes. 2718 Attributes Attrs; 2719 if (parseOptionalAttributes(Attrs)) 2720 return; 2721 2722 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2723 ActiveModule->ConfigMacrosExhaustive = true; 2724 } 2725 2726 // If we don't have an identifier, we're done. 2727 // FIXME: Support macros with the same name as a keyword here. 2728 if (!Tok.is(MMToken::Identifier)) 2729 return; 2730 2731 // Consume the first identifier. 2732 if (!ActiveModule->Parent) { 2733 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2734 } 2735 consumeToken(); 2736 2737 do { 2738 // If there's a comma, consume it. 2739 if (!Tok.is(MMToken::Comma)) 2740 break; 2741 consumeToken(); 2742 2743 // We expect to see a macro name here. 2744 // FIXME: Support macros with the same name as a keyword here. 2745 if (!Tok.is(MMToken::Identifier)) { 2746 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2747 break; 2748 } 2749 2750 // Consume the macro name. 2751 if (!ActiveModule->Parent) { 2752 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2753 } 2754 consumeToken(); 2755 } while (true); 2756 } 2757 2758 /// Format a module-id into a string. 2759 static std::string formatModuleId(const ModuleId &Id) { 2760 std::string result; 2761 { 2762 llvm::raw_string_ostream OS(result); 2763 2764 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2765 if (I) 2766 OS << "."; 2767 OS << Id[I].first; 2768 } 2769 } 2770 2771 return result; 2772 } 2773 2774 /// Parse a conflict declaration. 2775 /// 2776 /// module-declaration: 2777 /// 'conflict' module-id ',' string-literal 2778 void ModuleMapParser::parseConflict() { 2779 assert(Tok.is(MMToken::Conflict)); 2780 SourceLocation ConflictLoc = consumeToken(); 2781 Module::UnresolvedConflict Conflict; 2782 2783 // Parse the module-id. 2784 if (parseModuleId(Conflict.Id)) 2785 return; 2786 2787 // Parse the ','. 2788 if (!Tok.is(MMToken::Comma)) { 2789 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2790 << SourceRange(ConflictLoc); 2791 return; 2792 } 2793 consumeToken(); 2794 2795 // Parse the message. 2796 if (!Tok.is(MMToken::StringLiteral)) { 2797 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2798 << formatModuleId(Conflict.Id); 2799 return; 2800 } 2801 Conflict.Message = Tok.getString().str(); 2802 consumeToken(); 2803 2804 // Add this unresolved conflict. 2805 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2806 } 2807 2808 /// Parse an inferred module declaration (wildcard modules). 2809 /// 2810 /// module-declaration: 2811 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2812 /// { inferred-module-member* } 2813 /// 2814 /// inferred-module-member: 2815 /// 'export' '*' 2816 /// 'exclude' identifier 2817 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2818 assert(Tok.is(MMToken::Star)); 2819 SourceLocation StarLoc = consumeToken(); 2820 bool Failed = false; 2821 2822 // Inferred modules must be submodules. 2823 if (!ActiveModule && !Framework) { 2824 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2825 Failed = true; 2826 } 2827 2828 if (ActiveModule) { 2829 // Inferred modules must have umbrella directories. 2830 if (!Failed && ActiveModule->IsAvailable && 2831 !ActiveModule->getEffectiveUmbrellaDir()) { 2832 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2833 Failed = true; 2834 } 2835 2836 // Check for redefinition of an inferred module. 2837 if (!Failed && ActiveModule->InferSubmodules) { 2838 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2839 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2840 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2841 diag::note_mmap_prev_definition); 2842 Failed = true; 2843 } 2844 2845 // Check for the 'framework' keyword, which is not permitted here. 2846 if (Framework) { 2847 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2848 Framework = false; 2849 } 2850 } else if (Explicit) { 2851 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2852 Explicit = false; 2853 } 2854 2855 // If there were any problems with this inferred submodule, skip its body. 2856 if (Failed) { 2857 if (Tok.is(MMToken::LBrace)) { 2858 consumeToken(); 2859 skipUntil(MMToken::RBrace); 2860 if (Tok.is(MMToken::RBrace)) 2861 consumeToken(); 2862 } 2863 HadError = true; 2864 return; 2865 } 2866 2867 // Parse optional attributes. 2868 Attributes Attrs; 2869 if (parseOptionalAttributes(Attrs)) 2870 return; 2871 2872 if (ActiveModule) { 2873 // Note that we have an inferred submodule. 2874 ActiveModule->InferSubmodules = true; 2875 ActiveModule->InferredSubmoduleLoc = StarLoc; 2876 ActiveModule->InferExplicitSubmodules = Explicit; 2877 } else { 2878 // We'll be inferring framework modules for this directory. 2879 Map.InferredDirectories[Directory].InferModules = true; 2880 Map.InferredDirectories[Directory].Attrs = Attrs; 2881 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2882 // FIXME: Handle the 'framework' keyword. 2883 } 2884 2885 // Parse the opening brace. 2886 if (!Tok.is(MMToken::LBrace)) { 2887 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2888 HadError = true; 2889 return; 2890 } 2891 SourceLocation LBraceLoc = consumeToken(); 2892 2893 // Parse the body of the inferred submodule. 2894 bool Done = false; 2895 do { 2896 switch (Tok.Kind) { 2897 case MMToken::EndOfFile: 2898 case MMToken::RBrace: 2899 Done = true; 2900 break; 2901 2902 case MMToken::ExcludeKeyword: 2903 if (ActiveModule) { 2904 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2905 << (ActiveModule != nullptr); 2906 consumeToken(); 2907 break; 2908 } 2909 2910 consumeToken(); 2911 // FIXME: Support string-literal module names here. 2912 if (!Tok.is(MMToken::Identifier)) { 2913 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2914 break; 2915 } 2916 2917 Map.InferredDirectories[Directory].ExcludedModules.push_back( 2918 std::string(Tok.getString())); 2919 consumeToken(); 2920 break; 2921 2922 case MMToken::ExportKeyword: 2923 if (!ActiveModule) { 2924 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2925 << (ActiveModule != nullptr); 2926 consumeToken(); 2927 break; 2928 } 2929 2930 consumeToken(); 2931 if (Tok.is(MMToken::Star)) 2932 ActiveModule->InferExportWildcard = true; 2933 else 2934 Diags.Report(Tok.getLocation(), 2935 diag::err_mmap_expected_export_wildcard); 2936 consumeToken(); 2937 break; 2938 2939 case MMToken::ExplicitKeyword: 2940 case MMToken::ModuleKeyword: 2941 case MMToken::HeaderKeyword: 2942 case MMToken::PrivateKeyword: 2943 case MMToken::UmbrellaKeyword: 2944 default: 2945 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2946 << (ActiveModule != nullptr); 2947 consumeToken(); 2948 break; 2949 } 2950 } while (!Done); 2951 2952 if (Tok.is(MMToken::RBrace)) 2953 consumeToken(); 2954 else { 2955 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2956 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2957 HadError = true; 2958 } 2959 } 2960 2961 /// Parse optional attributes. 2962 /// 2963 /// attributes: 2964 /// attribute attributes 2965 /// attribute 2966 /// 2967 /// attribute: 2968 /// [ identifier ] 2969 /// 2970 /// \param Attrs Will be filled in with the parsed attributes. 2971 /// 2972 /// \returns true if an error occurred, false otherwise. 2973 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2974 bool HadError = false; 2975 2976 while (Tok.is(MMToken::LSquare)) { 2977 // Consume the '['. 2978 SourceLocation LSquareLoc = consumeToken(); 2979 2980 // Check whether we have an attribute name here. 2981 if (!Tok.is(MMToken::Identifier)) { 2982 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2983 skipUntil(MMToken::RSquare); 2984 if (Tok.is(MMToken::RSquare)) 2985 consumeToken(); 2986 HadError = true; 2987 } 2988 2989 // Decode the attribute name. 2990 AttributeKind Attribute 2991 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2992 .Case("exhaustive", AT_exhaustive) 2993 .Case("extern_c", AT_extern_c) 2994 .Case("no_undeclared_includes", AT_no_undeclared_includes) 2995 .Case("system", AT_system) 2996 .Default(AT_unknown); 2997 switch (Attribute) { 2998 case AT_unknown: 2999 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 3000 << Tok.getString(); 3001 break; 3002 3003 case AT_system: 3004 Attrs.IsSystem = true; 3005 break; 3006 3007 case AT_extern_c: 3008 Attrs.IsExternC = true; 3009 break; 3010 3011 case AT_exhaustive: 3012 Attrs.IsExhaustive = true; 3013 break; 3014 3015 case AT_no_undeclared_includes: 3016 Attrs.NoUndeclaredIncludes = true; 3017 break; 3018 } 3019 consumeToken(); 3020 3021 // Consume the ']'. 3022 if (!Tok.is(MMToken::RSquare)) { 3023 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 3024 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 3025 skipUntil(MMToken::RSquare); 3026 HadError = true; 3027 } 3028 3029 if (Tok.is(MMToken::RSquare)) 3030 consumeToken(); 3031 } 3032 3033 return HadError; 3034 } 3035 3036 /// Parse a module map file. 3037 /// 3038 /// module-map-file: 3039 /// module-declaration* 3040 bool ModuleMapParser::parseModuleMapFile() { 3041 do { 3042 switch (Tok.Kind) { 3043 case MMToken::EndOfFile: 3044 return HadError; 3045 3046 case MMToken::ExplicitKeyword: 3047 case MMToken::ExternKeyword: 3048 case MMToken::ModuleKeyword: 3049 case MMToken::FrameworkKeyword: 3050 parseModuleDecl(); 3051 break; 3052 3053 case MMToken::Comma: 3054 case MMToken::ConfigMacros: 3055 case MMToken::Conflict: 3056 case MMToken::Exclaim: 3057 case MMToken::ExcludeKeyword: 3058 case MMToken::ExportKeyword: 3059 case MMToken::ExportAsKeyword: 3060 case MMToken::HeaderKeyword: 3061 case MMToken::Identifier: 3062 case MMToken::LBrace: 3063 case MMToken::LinkKeyword: 3064 case MMToken::LSquare: 3065 case MMToken::Period: 3066 case MMToken::PrivateKeyword: 3067 case MMToken::RBrace: 3068 case MMToken::RSquare: 3069 case MMToken::RequiresKeyword: 3070 case MMToken::Star: 3071 case MMToken::StringLiteral: 3072 case MMToken::IntegerLiteral: 3073 case MMToken::TextualKeyword: 3074 case MMToken::UmbrellaKeyword: 3075 case MMToken::UseKeyword: 3076 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 3077 HadError = true; 3078 consumeToken(); 3079 break; 3080 } 3081 } while (true); 3082 } 3083 3084 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 3085 const DirectoryEntry *Dir, FileID ID, 3086 unsigned *Offset, 3087 SourceLocation ExternModuleLoc) { 3088 assert(Target && "Missing target information"); 3089 llvm::DenseMap<const FileEntry *, bool>::iterator Known 3090 = ParsedModuleMap.find(File); 3091 if (Known != ParsedModuleMap.end()) 3092 return Known->second; 3093 3094 // If the module map file wasn't already entered, do so now. 3095 if (ID.isInvalid()) { 3096 auto FileCharacter = 3097 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 3098 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 3099 } 3100 3101 assert(Target && "Missing target information"); 3102 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID); 3103 if (!Buffer) 3104 return ParsedModuleMap[File] = true; 3105 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 3106 "invalid buffer offset"); 3107 3108 // Parse this module map file. 3109 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 3110 Buffer->getBufferStart(), 3111 Buffer->getBufferStart() + (Offset ? *Offset : 0), 3112 Buffer->getBufferEnd()); 3113 SourceLocation Start = L.getSourceLocation(); 3114 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 3115 IsSystem); 3116 bool Result = Parser.parseModuleMapFile(); 3117 ParsedModuleMap[File] = Result; 3118 3119 if (Offset) { 3120 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 3121 assert(Loc.first == ID && "stopped in a different file?"); 3122 *Offset = Loc.second; 3123 } 3124 3125 // Notify callbacks that we parsed it. 3126 for (const auto &Cb : Callbacks) 3127 Cb->moduleMapFileRead(Start, *File, IsSystem); 3128 3129 return Result; 3130 } 3131