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