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