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