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