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