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