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