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