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