brintos

brintos / llvm-project-archived public Read only

0
0
Text · 84.8 KiB · b8202ea Raw
2286 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the ModuleMap implementation, which describes the layout10// 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/ModuleMapFile.h"28#include "llvm/ADT/DenseMap.h"29#include "llvm/ADT/STLExtras.h"30#include "llvm/ADT/SmallPtrSet.h"31#include "llvm/ADT/SmallVector.h"32#include "llvm/ADT/StringMap.h"33#include "llvm/ADT/StringRef.h"34#include "llvm/ADT/StringSwitch.h"35#include "llvm/Support/Compiler.h"36#include "llvm/Support/ErrorHandling.h"37#include "llvm/Support/Path.h"38#include "llvm/Support/VirtualFileSystem.h"39#include "llvm/Support/raw_ostream.h"40#include <cassert>41#include <cstring>42#include <optional>43#include <string>44#include <system_error>45#include <utility>46 47using namespace clang;48 49void ModuleMapCallbacks::anchor() {}50 51void ModuleMap::resolveLinkAsDependencies(Module *Mod) {52  auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);53  if (PendingLinkAs != PendingLinkAsModule.end()) {54    for (auto &Name : PendingLinkAs->second) {55      auto *M = findModule(Name.getKey());56      if (M)57        M->UseExportAsModuleLinkName = true;58    }59  }60}61 62void ModuleMap::addLinkAsDependency(Module *Mod) {63  if (findModule(Mod->ExportAsModule))64    Mod->UseExportAsModuleLinkName = true;65  else66    PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);67}68 69Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {70  switch ((int)Role) {71  case NormalHeader:72    return Module::HK_Normal;73  case PrivateHeader:74    return Module::HK_Private;75  case TextualHeader:76    return Module::HK_Textual;77  case PrivateHeader | TextualHeader:78    return Module::HK_PrivateTextual;79  case ExcludedHeader:80    return Module::HK_Excluded;81  }82  llvm_unreachable("unknown header role");83}84 85ModuleMap::ModuleHeaderRole86ModuleMap::headerKindToRole(Module::HeaderKind Kind) {87  switch ((int)Kind) {88  case Module::HK_Normal:89    return NormalHeader;90  case Module::HK_Private:91    return PrivateHeader;92  case Module::HK_Textual:93    return TextualHeader;94  case Module::HK_PrivateTextual:95    return ModuleHeaderRole(PrivateHeader | TextualHeader);96  case Module::HK_Excluded:97    return ExcludedHeader;98  }99  llvm_unreachable("unknown header kind");100}101 102bool ModuleMap::isModular(ModuleHeaderRole Role) {103  return !(Role & (ModuleMap::TextualHeader | ModuleMap::ExcludedHeader));104}105 106Module::ExportDecl107ModuleMap::resolveExport(Module *Mod,108                         const Module::UnresolvedExportDecl &Unresolved,109                         bool Complain) const {110  // We may have just a wildcard.111  if (Unresolved.Id.empty()) {112    assert(Unresolved.Wildcard && "Invalid unresolved export");113    return Module::ExportDecl(nullptr, true);114  }115 116  // Resolve the module-id.117  Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);118  if (!Context)119    return {};120 121  return Module::ExportDecl(Context, Unresolved.Wildcard);122}123 124Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,125                                   bool Complain) const {126  // Find the starting module.127  Module *Context = lookupModuleUnqualified(Id[0].first, Mod);128  if (!Context) {129    if (Complain)130      Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)131      << Id[0].first << Mod->getFullModuleName();132 133    return nullptr;134  }135 136  // Dig into the module path.137  for (unsigned I = 1, N = Id.size(); I != N; ++I) {138    Module *Sub = lookupModuleQualified(Id[I].first, Context);139    if (!Sub) {140      if (Complain)141        Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)142        << Id[I].first << Context->getFullModuleName()143        << SourceRange(Id[0].second, Id[I-1].second);144 145      return nullptr;146    }147 148    Context = Sub;149  }150 151  return Context;152}153 154/// Append to \p Paths the set of paths needed to get to the155/// subframework in which the given module lives.156static void appendSubframeworkPaths(Module *Mod,157                                    SmallVectorImpl<char> &Path) {158  // Collect the framework names from the given module to the top-level module.159  SmallVector<StringRef, 2> Paths;160  for (; Mod; Mod = Mod->Parent) {161    if (Mod->IsFramework)162      Paths.push_back(Mod->Name);163  }164 165  if (Paths.empty())166    return;167 168  // Add Frameworks/Name.framework for each subframework.169  for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))170    llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");171}172 173OptionalFileEntryRef ModuleMap::findHeader(174    Module *M, const Module::UnresolvedHeaderDirective &Header,175    SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {176  // Search for the header file within the module's home directory.177  auto Directory = M->Directory;178  SmallString<128> FullPathName(Directory->getName());179 180  auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {181    auto File =182        expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));183    if (!File || (Header.Size && File->getSize() != *Header.Size) ||184        (Header.ModTime && File->getModificationTime() != *Header.ModTime))185      return std::nullopt;186    return *File;187  };188 189  auto GetFrameworkFile = [&]() -> OptionalFileEntryRef {190    unsigned FullPathLength = FullPathName.size();191    appendSubframeworkPaths(M, RelativePathName);192    unsigned RelativePathLength = RelativePathName.size();193 194    // Check whether this file is in the public headers.195    llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);196    llvm::sys::path::append(FullPathName, RelativePathName);197    if (auto File = GetFile(FullPathName))198      return File;199 200    // Check whether this file is in the private headers.201    // Ideally, private modules in the form 'FrameworkName.Private' should202    // be defined as 'module FrameworkName.Private', and not as203    // 'framework module FrameworkName.Private', since a 'Private.Framework'204    // does not usually exist. However, since both are currently widely used205    // for private modules, make sure we find the right path in both cases.206    if (M->IsFramework && M->Name == "Private")207      RelativePathName.clear();208    else209      RelativePathName.resize(RelativePathLength);210    FullPathName.resize(FullPathLength);211    llvm::sys::path::append(RelativePathName, "PrivateHeaders",212                            Header.FileName);213    llvm::sys::path::append(FullPathName, RelativePathName);214    return GetFile(FullPathName);215  };216 217  if (llvm::sys::path::is_absolute(Header.FileName)) {218    RelativePathName.clear();219    RelativePathName.append(Header.FileName.begin(), Header.FileName.end());220    return GetFile(Header.FileName);221  }222 223  if (M->isPartOfFramework())224    return GetFrameworkFile();225 226  // Lookup for normal headers.227  llvm::sys::path::append(RelativePathName, Header.FileName);228  llvm::sys::path::append(FullPathName, RelativePathName);229  auto NormalHdrFile = GetFile(FullPathName);230 231  if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {232    // The lack of 'framework' keyword in a module declaration it's a simple233    // mistake we can diagnose when the header exists within the proper234    // framework style path.235    FullPathName.assign(Directory->getName());236    RelativePathName.clear();237    if (GetFrameworkFile()) {238      Diags.Report(Header.FileNameLoc,239                   diag::warn_mmap_incomplete_framework_module_declaration)240          << Header.FileName << M->getFullModuleName();241      NeedsFramework = true;242    }243    return std::nullopt;244  }245 246  return NormalHdrFile;247}248 249/// Determine whether the given file name is the name of a builtin250/// header, supplied by Clang to replace, override, or augment existing system251/// headers.252static bool isBuiltinHeaderName(StringRef FileName) {253  return llvm::StringSwitch<bool>(FileName)254           .Case("float.h", true)255           .Case("iso646.h", true)256           .Case("limits.h", true)257           .Case("stdalign.h", true)258           .Case("stdarg.h", true)259           .Case("stdatomic.h", true)260           .Case("stdbool.h", true)261           .Case("stdckdint.h", true)262           .Case("stdcountof.h", true)263           .Case("stddef.h", true)264           .Case("stdint.h", true)265           .Case("tgmath.h", true)266           .Case("unwind.h", true)267           .Default(false);268}269 270/// Determine whether the given module name is the name of a builtin271/// module that is cyclic with a system module  on some platforms.272static bool isBuiltInModuleName(StringRef ModuleName) {273  return llvm::StringSwitch<bool>(ModuleName)274           .Case("_Builtin_float", true)275           .Case("_Builtin_inttypes", true)276           .Case("_Builtin_iso646", true)277           .Case("_Builtin_limits", true)278           .Case("_Builtin_stdalign", true)279           .Case("_Builtin_stdarg", true)280           .Case("_Builtin_stdatomic", true)281           .Case("_Builtin_stdbool", true)282           .Case("_Builtin_stddef", true)283           .Case("_Builtin_stdint", true)284           .Case("_Builtin_stdnoreturn", true)285           .Case("_Builtin_tgmath", true)286           .Case("_Builtin_unwind", true)287           .Default(false);288}289 290void ModuleMap::resolveHeader(Module *Mod,291                              const Module::UnresolvedHeaderDirective &Header,292                              bool &NeedsFramework) {293  SmallString<128> RelativePathName;294  if (OptionalFileEntryRef File =295          findHeader(Mod, Header, RelativePathName, NeedsFramework)) {296    if (Header.IsUmbrella) {297      const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();298      if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])299        Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)300          << UmbrellaMod->getFullModuleName();301      else302        // Record this umbrella header.303        setUmbrellaHeaderAsWritten(Mod, *File, Header.FileName,304                                   RelativePathName.str());305    } else {306      Module::Header H = {Header.FileName, std::string(RelativePathName),307                          *File};308      addHeader(Mod, H, headerKindToRole(Header.Kind));309    }310  } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {311    // There's a builtin header but no corresponding on-disk header. Assume312    // this was supposed to modularize the builtin header alone.313  } else if (Header.Kind == Module::HK_Excluded) {314    // Ignore missing excluded header files. They're optional anyway.315  } else {316    // If we find a module that has a missing header, we mark this module as317    // unavailable and store the header directive for displaying diagnostics.318    Mod->MissingHeaders.push_back(Header);319    // A missing header with stat information doesn't make the module320    // unavailable; this keeps our behavior consistent as headers are lazily321    // resolved. (Such a module still can't be built though, except from322    // preprocessed source.)323    if (!Header.Size && !Header.ModTime)324      Mod->markUnavailable(/*Unimportable=*/false);325  }326}327 328bool ModuleMap::resolveAsBuiltinHeader(329    Module *Mod, const Module::UnresolvedHeaderDirective &Header) {330  if (Header.Kind == Module::HK_Excluded ||331      llvm::sys::path::is_absolute(Header.FileName) ||332      Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||333      !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||334      !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))335    return false;336 337  // This is a system module with a top-level header. This header338  // may have a counterpart (or replacement) in the set of headers339  // supplied by Clang. Find that builtin header.340  SmallString<128> Path;341  llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);342  auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);343  if (!File)344    return false;345 346  Module::Header H = {Header.FileName, Header.FileName, *File};347  auto Role = headerKindToRole(Header.Kind);348  addHeader(Mod, H, Role);349  return true;350}351 352ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,353                     const LangOptions &LangOpts, const TargetInfo *Target,354                     HeaderSearch &HeaderInfo)355    : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),356      HeaderInfo(HeaderInfo) {357}358 359ModuleMap::~ModuleMap() = default;360 361void ModuleMap::setTarget(const TargetInfo &Target) {362  assert((!this->Target || this->Target == &Target) &&363         "Improper target override");364  this->Target = &Target;365}366 367/// "Sanitize" a filename so that it can be used as an identifier.368static StringRef sanitizeFilenameAsIdentifier(StringRef Name,369                                              SmallVectorImpl<char> &Buffer) {370  if (Name.empty())371    return Name;372 373  if (!isValidAsciiIdentifier(Name)) {374    // If we don't already have something with the form of an identifier,375    // create a buffer with the sanitized name.376    Buffer.clear();377    if (isDigit(Name[0]))378      Buffer.push_back('_');379    Buffer.reserve(Buffer.size() + Name.size());380    for (unsigned I = 0, N = Name.size(); I != N; ++I) {381      if (isAsciiIdentifierContinue(Name[I]))382        Buffer.push_back(Name[I]);383      else384        Buffer.push_back('_');385    }386 387    Name = StringRef(Buffer.data(), Buffer.size());388  }389 390  while (llvm::StringSwitch<bool>(Name)391#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)392#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)393#include "clang/Basic/TokenKinds.def"394           .Default(false)) {395    if (Name.data() != Buffer.data())396      Buffer.append(Name.begin(), Name.end());397    Buffer.push_back('_');398    Name = StringRef(Buffer.data(), Buffer.size());399  }400 401  return Name;402}403 404bool ModuleMap::isBuiltinHeader(FileEntryRef File) {405  return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&406         isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));407}408 409bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,410                                                        Module *Module) const {411  return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&412         Module->IsSystem && !Module->isPartOfFramework() &&413         isBuiltinHeaderName(FileName);414}415 416ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {417  resolveHeaderDirectives(File);418  HeadersMap::iterator Known = Headers.find(File);419  if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&420      Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {421    HeaderInfo.loadTopLevelSystemModules();422    return Headers.find(File);423  }424  return Known;425}426 427ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(428    FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs) {429  if (UmbrellaDirs.empty())430    return {};431 432  OptionalDirectoryEntryRef Dir = File.getDir();433 434  // Note: as an egregious but useful hack we use the real path here, because435  // frameworks moving from top-level frameworks to embedded frameworks tend436  // to be symlinked from the top-level location to the embedded location,437  // and we need to resolve lookups as if we had found the embedded location.438  StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);439 440  // Keep walking up the directory hierarchy, looking for a directory with441  // an umbrella header.442  do {443    auto KnownDir = UmbrellaDirs.find(*Dir);444    if (KnownDir != UmbrellaDirs.end())445      return KnownHeader(KnownDir->second, NormalHeader);446 447    IntermediateDirs.push_back(*Dir);448 449    // Retrieve our parent path.450    DirName = llvm::sys::path::parent_path(DirName);451    if (DirName.empty())452      break;453 454    // Resolve the parent path to a directory entry.455    Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);456  } while (Dir);457  return {};458}459 460static bool violatesPrivateInclude(Module *RequestingModule,461                                   const FileEntry *IncFileEnt,462                                   ModuleMap::KnownHeader Header) {463#ifndef NDEBUG464  if (Header.getRole() & ModuleMap::PrivateHeader) {465    // Check for consistency between the module header role466    // as obtained from the lookup and as obtained from the module.467    // This check is not cheap, so enable it only for debugging.468    bool IsPrivate = false;469    ArrayRef<Module::Header> HeaderList[] = {470        Header.getModule()->getHeaders(Module::HK_Private),471        Header.getModule()->getHeaders(Module::HK_PrivateTextual)};472    for (auto Hs : HeaderList)473      IsPrivate |= llvm::any_of(474          Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });475    assert(IsPrivate && "inconsistent headers and roles");476  }477#endif478  return !Header.isAccessibleFrom(RequestingModule);479}480 481static Module *getTopLevelOrNull(Module *M) {482  return M ? M->getTopLevelModule() : nullptr;483}484 485void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,486                                        bool RequestingModuleIsModuleInterface,487                                        SourceLocation FilenameLoc,488                                        StringRef Filename, FileEntryRef File) {489  // No errors for indirect modules. This may be a bit of a problem for modules490  // with no source files.491  if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))492    return;493 494  if (RequestingModule) {495    resolveUses(RequestingModule, /*Complain=*/false);496    resolveHeaderDirectives(RequestingModule, /*File=*/std::nullopt);497  }498 499  bool Excluded = false;500  Module *Private = nullptr;501  Module *NotUsed = nullptr;502 503  HeadersMap::iterator Known = findKnownHeader(File);504  if (Known != Headers.end()) {505    for (const KnownHeader &Header : Known->second) {506      // Excluded headers don't really belong to a module.507      if (Header.getRole() == ModuleMap::ExcludedHeader) {508        Excluded = true;509        continue;510      }511 512      // Remember private headers for later printing of a diagnostic.513      if (violatesPrivateInclude(RequestingModule, File, Header)) {514        Private = Header.getModule();515        continue;516      }517 518      // If uses need to be specified explicitly, we are only allowed to return519      // modules that are explicitly used by the requesting module.520      if (RequestingModule && LangOpts.ModulesDeclUse &&521          !RequestingModule->directlyUses(Header.getModule())) {522        NotUsed = Header.getModule();523        continue;524      }525 526      // We have found a module that we can happily use.527      return;528    }529 530    Excluded = true;531  }532 533  // We have found a header, but it is private.534  if (Private) {535    Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)536        << Filename;537    return;538  }539 540  // We have found a module, but we don't use it.541  if (NotUsed) {542    Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)543        << RequestingModule->getTopLevelModule()->Name << Filename544        << NotUsed->Name;545    return;546  }547 548  if (Excluded || isHeaderInUmbrellaDirs(File))549    return;550 551  // At this point, only non-modular includes remain.552 553  if (RequestingModule && LangOpts.ModulesStrictDeclUse) {554    Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)555        << RequestingModule->getTopLevelModule()->Name << Filename;556  } else if (RequestingModule && RequestingModuleIsModuleInterface &&557             LangOpts.isCompilingModule()) {558    // Do not diagnose when we are not compiling a module.559    diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?560        diag::warn_non_modular_include_in_framework_module :561        diag::warn_non_modular_include_in_module;562    Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()563        << File.getName();564  }565}566 567static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,568                                const ModuleMap::KnownHeader &Old) {569  // Prefer available modules.570  // FIXME: Considering whether the module is available rather than merely571  // importable is non-hermetic and can result in surprising behavior for572  // prebuilt modules. Consider only checking for importability here.573  if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())574    return true;575 576  // Prefer a public header over a private header.577  if ((New.getRole() & ModuleMap::PrivateHeader) !=578      (Old.getRole() & ModuleMap::PrivateHeader))579    return !(New.getRole() & ModuleMap::PrivateHeader);580 581  // Prefer a non-textual header over a textual header.582  if ((New.getRole() & ModuleMap::TextualHeader) !=583      (Old.getRole() & ModuleMap::TextualHeader))584    return !(New.getRole() & ModuleMap::TextualHeader);585 586  // Prefer a non-excluded header over an excluded header.587  if ((New.getRole() == ModuleMap::ExcludedHeader) !=588      (Old.getRole() == ModuleMap::ExcludedHeader))589    return New.getRole() != ModuleMap::ExcludedHeader;590 591  // Don't have a reason to choose between these. Just keep the first one.592  return false;593}594 595ModuleMap::KnownHeader ModuleMap::findModuleForHeader(FileEntryRef File,596                                                      bool AllowTextual,597                                                      bool AllowExcluded) {598  auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {599    if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)600      return {};601    return R;602  };603 604  HeadersMap::iterator Known = findKnownHeader(File);605  if (Known != Headers.end()) {606    ModuleMap::KnownHeader Result;607    // Iterate over all modules that 'File' is part of to find the best fit.608    for (KnownHeader &H : Known->second) {609      // Cannot use a module if the header is excluded in it.610      if (!AllowExcluded && H.getRole() == ModuleMap::ExcludedHeader)611        continue;612      // Prefer a header from the source module over all others.613      if (H.getModule()->getTopLevelModule() == SourceModule)614        return MakeResult(H);615      if (!Result || isBetterKnownHeader(H, Result))616        Result = H;617    }618    return MakeResult(Result);619  }620 621  return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));622}623 624ModuleMap::KnownHeader625ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {626  assert(!Headers.count(File) && "already have a module for this header");627 628  SmallVector<DirectoryEntryRef, 2> SkippedDirs;629  KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);630  if (H) {631    Module *Result = H.getModule();632 633    // Search up the module stack until we find a module with an umbrella634    // directory.635    Module *UmbrellaModule = Result;636    while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)637      UmbrellaModule = UmbrellaModule->Parent;638 639    if (UmbrellaModule->InferSubmodules) {640      FileID UmbrellaModuleMap = getModuleMapFileIDForUniquing(UmbrellaModule);641 642      // Infer submodules for each of the directories we found between643      // the directory of the umbrella header and the directory where644      // the actual header is located.645      bool Explicit = UmbrellaModule->InferExplicitSubmodules;646 647      for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {648        // Find or create the module that corresponds to this directory name.649        SmallString<32> NameBuf;650        StringRef Name = sanitizeFilenameAsIdentifier(651            llvm::sys::path::stem(SkippedDir.getName()), NameBuf);652        Result = findOrCreateModuleFirst(Name, Result, /*IsFramework=*/false,653                                         Explicit);654        setInferredModuleAllowedBy(Result, UmbrellaModuleMap);655 656        // Associate the module and the directory.657        UmbrellaDirs[SkippedDir] = Result;658 659        // If inferred submodules export everything they import, add a660        // wildcard to the set of exports.661        if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())662          Result->Exports.push_back(Module::ExportDecl(nullptr, true));663      }664 665      // Infer a submodule with the same name as this header file.666      SmallString<32> NameBuf;667      StringRef Name = sanitizeFilenameAsIdentifier(668                         llvm::sys::path::stem(File.getName()), NameBuf);669      Result = findOrCreateModuleFirst(Name, Result, /*IsFramework=*/false,670                                       Explicit);671      setInferredModuleAllowedBy(Result, UmbrellaModuleMap);672      Result->addTopHeader(File);673 674      // If inferred submodules export everything they import, add a675      // wildcard to the set of exports.676      if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())677        Result->Exports.push_back(Module::ExportDecl(nullptr, true));678    } else {679      // Record each of the directories we stepped through as being part of680      // the module we found, since the umbrella header covers them all.681      for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)682        UmbrellaDirs[SkippedDirs[I]] = Result;683    }684 685    KnownHeader Header(Result, NormalHeader);686    Headers[File].push_back(Header);687    return Header;688  }689 690  return {};691}692 693ArrayRef<ModuleMap::KnownHeader>694ModuleMap::findAllModulesForHeader(FileEntryRef File) {695  HeadersMap::iterator Known = findKnownHeader(File);696  if (Known != Headers.end())697    return Known->second;698 699  if (findOrCreateModuleForHeaderInUmbrellaDir(File))700    return Headers.find(File)->second;701 702  return {};703}704 705ArrayRef<ModuleMap::KnownHeader>706ModuleMap::findResolvedModulesForHeader(FileEntryRef File) const {707  // FIXME: Is this necessary?708  resolveHeaderDirectives(File);709  auto It = Headers.find(File);710  if (It == Headers.end())711    return {};712  return It->second;713}714 715bool ModuleMap::isHeaderInUnavailableModule(FileEntryRef Header) const {716  return isHeaderUnavailableInModule(Header, nullptr);717}718 719bool ModuleMap::isHeaderUnavailableInModule(720    FileEntryRef Header, const Module *RequestingModule) const {721  resolveHeaderDirectives(Header);722  HeadersMap::const_iterator Known = Headers.find(Header);723  if (Known != Headers.end()) {724    for (SmallVectorImpl<KnownHeader>::const_iterator725             I = Known->second.begin(),726             E = Known->second.end();727         I != E; ++I) {728 729      if (I->getRole() == ModuleMap::ExcludedHeader)730        continue;731 732      if (I->isAvailable() &&733          (!RequestingModule ||734           I->getModule()->isSubModuleOf(RequestingModule))) {735        // When no requesting module is available, the caller is looking if a736        // header is part a module by only looking into the module map. This is737        // done by warn_uncovered_module_header checks; don't consider textual738        // headers part of it in this mode, otherwise we get misleading warnings739        // that a umbrella header is not including a textual header.740        if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)741          continue;742        return false;743      }744    }745    return true;746  }747 748  OptionalDirectoryEntryRef Dir = Header.getDir();749  SmallVector<DirectoryEntryRef, 2> SkippedDirs;750  StringRef DirName = Dir->getName();751 752  auto IsUnavailable = [&](const Module *M) {753    return !M->isAvailable() && (!RequestingModule ||754                                 M->isSubModuleOf(RequestingModule));755  };756 757  // Keep walking up the directory hierarchy, looking for a directory with758  // an umbrella header.759  do {760    auto KnownDir = UmbrellaDirs.find(*Dir);761    if (KnownDir != UmbrellaDirs.end()) {762      Module *Found = KnownDir->second;763      if (IsUnavailable(Found))764        return true;765 766      // Search up the module stack until we find a module with an umbrella767      // directory.768      Module *UmbrellaModule = Found;769      while (!UmbrellaModule->getEffectiveUmbrellaDir() &&770             UmbrellaModule->Parent)771        UmbrellaModule = UmbrellaModule->Parent;772 773      if (UmbrellaModule->InferSubmodules) {774        for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {775          // Find or create the module that corresponds to this directory name.776          SmallString<32> NameBuf;777          StringRef Name = sanitizeFilenameAsIdentifier(778              llvm::sys::path::stem(SkippedDir.getName()), NameBuf);779          Found = lookupModuleQualified(Name, Found);780          if (!Found)781            return false;782          if (IsUnavailable(Found))783            return true;784        }785 786        // Infer a submodule with the same name as this header file.787        SmallString<32> NameBuf;788        StringRef Name = sanitizeFilenameAsIdentifier(789                           llvm::sys::path::stem(Header.getName()),790                           NameBuf);791        Found = lookupModuleQualified(Name, Found);792        if (!Found)793          return false;794      }795 796      return IsUnavailable(Found);797    }798 799    SkippedDirs.push_back(*Dir);800 801    // Retrieve our parent path.802    DirName = llvm::sys::path::parent_path(DirName);803    if (DirName.empty())804      break;805 806    // Resolve the parent path to a directory entry.807    Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);808  } while (Dir);809 810  return false;811}812 813Module *ModuleMap::findModule(StringRef Name) const {814  llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);815  if (Known != Modules.end())816    return Known->getValue();817 818  return nullptr;819}820 821Module *ModuleMap::findOrInferSubmodule(Module *Parent, StringRef Name) {822  if (Module *SubM = Parent->findSubmodule(Name))823    return SubM;824  if (!Parent->InferSubmodules)825    return nullptr;826  Module *Result = new (ModulesAlloc.Allocate())827      Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent, false,828             Parent->InferExplicitSubmodules, 0);829  Result->InferExplicitSubmodules = Parent->InferExplicitSubmodules;830  Result->InferSubmodules = Parent->InferSubmodules;831  Result->InferExportWildcard = Parent->InferExportWildcard;832  if (Result->InferExportWildcard)833    Result->Exports.push_back(Module::ExportDecl(nullptr, true));834  return Result;835}836 837Module *ModuleMap::lookupModuleUnqualified(StringRef Name,838                                           Module *Context) const {839  for(; Context; Context = Context->Parent) {840    if (Module *Sub = lookupModuleQualified(Name, Context))841      return Sub;842  }843 844  return findModule(Name);845}846 847Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{848  if (!Context)849    return findModule(Name);850 851  return Context->findSubmodule(Name);852}853 854std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,855                                                        Module *Parent,856                                                        bool IsFramework,857                                                        bool IsExplicit) {858  // Try to find an existing module with this name.859  if (Module *Sub = lookupModuleQualified(Name, Parent))860    return std::make_pair(Sub, false);861 862  // Create a new module with this name.863  Module *M = createModule(Name, Parent, IsFramework, IsExplicit);864  return std::make_pair(M, true);865}866 867Module *ModuleMap::createModule(StringRef Name, Module *Parent,868                                bool IsFramework, bool IsExplicit) {869  assert(lookupModuleQualified(Name, Parent) == nullptr &&870         "Creating duplicate submodule");871 872  Module *Result = new (ModulesAlloc.Allocate())873      Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent,874             IsFramework, IsExplicit, NumCreatedModules++);875  if (!Parent) {876    if (LangOpts.CurrentModule == Name)877      SourceModule = Result;878    Modules[Name] = Result;879    ModuleScopeIDs[Result] = CurrentModuleScopeID;880  }881  return Result;882}883 884Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,885                                                           Module *Parent) {886  auto *Result = new (ModulesAlloc.Allocate()) Module(887      ModuleConstructorTag{}, "<global>", Loc, Parent, /*IsFramework=*/false,888      /*IsExplicit=*/true, NumCreatedModules++);889  Result->Kind = Module::ExplicitGlobalModuleFragment;890  // If the created module isn't owned by a parent, send it to PendingSubmodules891  // to wait for its parent.892  if (!Result->Parent)893    PendingSubmodules.emplace_back(Result);894  return Result;895}896 897Module *898ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc,899                                                           Module *Parent) {900  assert(Parent && "We should only create an implicit global module fragment "901                   "in a module purview");902  // Note: Here the `IsExplicit` parameter refers to the semantics in clang903  // modules. All the non-explicit submodules in clang modules will be exported904  // too. Here we simplify the implementation by using the concept.905  auto *Result = new (ModulesAlloc.Allocate())906      Module(ModuleConstructorTag{}, "<implicit global>", Loc, Parent,907             /*IsFramework=*/false, /*IsExplicit=*/false, NumCreatedModules++);908  Result->Kind = Module::ImplicitGlobalModuleFragment;909  return Result;910}911 912Module *913ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,914                                                       SourceLocation Loc) {915  auto *Result = new (ModulesAlloc.Allocate()) Module(916      ModuleConstructorTag{}, "<private>", Loc, Parent, /*IsFramework=*/false,917      /*IsExplicit=*/true, NumCreatedModules++);918  Result->Kind = Module::PrivateModuleFragment;919  return Result;920}921 922Module *ModuleMap::createModuleUnitWithKind(SourceLocation Loc, StringRef Name,923                                            Module::ModuleKind Kind) {924  auto *Result = new (ModulesAlloc.Allocate())925      Module(ModuleConstructorTag{}, Name, Loc, nullptr, /*IsFramework=*/false,926             /*IsExplicit=*/false, NumCreatedModules++);927  Result->Kind = Kind;928 929  // Reparent any current global module fragment as a submodule of this module.930  for (auto &Submodule : PendingSubmodules)931    Submodule->setParent(Result);932  PendingSubmodules.clear();933  return Result;934}935 936Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,937                                                StringRef Name) {938  assert(LangOpts.CurrentModule == Name && "module name mismatch");939  assert(!Modules[Name] && "redefining existing module");940 941  auto *Result =942      createModuleUnitWithKind(Loc, Name, Module::ModuleInterfaceUnit);943  Modules[Name] = SourceModule = Result;944 945  // Mark the main source file as being within the newly-created module so that946  // declarations and macros are properly visibility-restricted to it.947  auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());948  assert(MainFile && "no input file for module interface");949  Headers[*MainFile].push_back(KnownHeader(Result, PrivateHeader));950 951  return Result;952}953 954Module *ModuleMap::createModuleForImplementationUnit(SourceLocation Loc,955                                                     StringRef Name) {956  assert(LangOpts.CurrentModule == Name && "module name mismatch");957  // The interface for this implementation must exist and be loaded.958  assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&959         "creating implementation module without an interface");960 961  // Create an entry in the modules map to own the implementation unit module.962  // User module names must not start with a period (so that this cannot clash963  // with any legal user-defined module name).964  StringRef IName = ".ImplementationUnit";965  assert(!Modules[IName] && "multiple implementation units?");966 967  auto *Result =968      createModuleUnitWithKind(Loc, Name, Module::ModuleImplementationUnit);969  Modules[IName] = SourceModule = Result;970 971  // Check that the main file is present.972  assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&973         "no input file for module implementation");974 975  return Result;976}977 978Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,979                                    Module::Header H) {980  assert(LangOpts.CurrentModule == Name && "module name mismatch");981  assert(!Modules[Name] && "redefining existing module");982 983  auto *Result = new (ModulesAlloc.Allocate())984      Module(ModuleConstructorTag{}, Name, Loc, nullptr, /*IsFramework=*/false,985             /*IsExplicit=*/false, NumCreatedModules++);986  Result->Kind = Module::ModuleHeaderUnit;987  Modules[Name] = SourceModule = Result;988  addHeader(Result, H, NormalHeader);989  return Result;990}991 992/// For a framework module, infer the framework against which we993/// should link.994static void inferFrameworkLink(Module *Mod) {995  assert(Mod->IsFramework && "Can only infer linking for framework modules");996  assert(!Mod->isSubFramework() &&997         "Can only infer linking for top-level frameworks");998 999  StringRef FrameworkName(Mod->Name);1000  FrameworkName.consume_back("_Private");1001  Mod->LinkLibraries.push_back(Module::LinkLibrary(FrameworkName.str(),1002                                                   /*IsFramework=*/true));1003}1004 1005Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,1006                                        bool IsSystem, Module *Parent) {1007  Attributes Attrs;1008  Attrs.IsSystem = IsSystem;1009  return inferFrameworkModule(FrameworkDir, Attrs, Parent);1010}1011 1012Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,1013                                        Attributes Attrs, Module *Parent) {1014  // Note: as an egregious but useful hack we use the real path here, because1015  // we might be looking at an embedded framework that symlinks out to a1016  // top-level framework, and we need to infer as if we were naming the1017  // top-level framework.1018  StringRef FrameworkDirName =1019      SourceMgr.getFileManager().getCanonicalName(FrameworkDir);1020 1021  // In case this is a case-insensitive filesystem, use the canonical1022  // directory name as the ModuleName, since modules are case-sensitive.1023  // FIXME: we should be able to give a fix-it hint for the correct spelling.1024  SmallString<32> ModuleNameStorage;1025  StringRef ModuleName = sanitizeFilenameAsIdentifier(1026      llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);1027 1028  // Check whether we've already found this module.1029  if (Module *Mod = lookupModuleQualified(ModuleName, Parent))1030    return Mod;1031 1032  FileManager &FileMgr = SourceMgr.getFileManager();1033 1034  // If the framework has a parent path from which we're allowed to infer1035  // a framework module, do so.1036  FileID ModuleMapFID;1037  if (!Parent) {1038    // Determine whether we're allowed to infer a module map.1039    bool canInfer = false;1040    if (llvm::sys::path::has_parent_path(FrameworkDirName)) {1041      // Figure out the parent path.1042      StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);1043      if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {1044        // Check whether we have already looked into the parent directory1045        // for a module map.1046        llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator1047          inferred = InferredDirectories.find(*ParentDir);1048        if (inferred == InferredDirectories.end()) {1049          // We haven't looked here before. Load a module map, if there is1050          // one.1051          bool IsFrameworkDir = Parent.ends_with(".framework");1052          if (OptionalFileEntryRef ModMapFile =1053                  HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {1054            // TODO: Parsing a module map should populate `InferredDirectories`1055            //       so we don't need to do a full load here.1056            parseAndLoadModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);1057            inferred = InferredDirectories.find(*ParentDir);1058          }1059 1060          if (inferred == InferredDirectories.end())1061            inferred = InferredDirectories.insert(1062                         std::make_pair(*ParentDir, InferredDirectory())).first;1063        }1064 1065        if (inferred->second.InferModules) {1066          // We're allowed to infer for this directory, but make sure it's okay1067          // to infer this particular module.1068          StringRef Name = llvm::sys::path::stem(FrameworkDirName);1069          canInfer =1070              !llvm::is_contained(inferred->second.ExcludedModules, Name);1071 1072          Attrs.IsSystem |= inferred->second.Attrs.IsSystem;1073          Attrs.IsExternC |= inferred->second.Attrs.IsExternC;1074          Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;1075          Attrs.NoUndeclaredIncludes |=1076              inferred->second.Attrs.NoUndeclaredIncludes;1077          ModuleMapFID = inferred->second.ModuleMapFID;1078        }1079      }1080    }1081 1082    // If we're not allowed to infer a framework module, don't.1083    if (!canInfer)1084      return nullptr;1085  } else {1086    ModuleMapFID = getModuleMapFileIDForUniquing(Parent);1087  }1088 1089  // Look for an umbrella header.1090  SmallString<128> UmbrellaName = FrameworkDir.getName();1091  llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");1092  auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);1093 1094  // FIXME: If there's no umbrella header, we could probably scan the1095  // framework to load *everything*. But, it's not clear that this is a good1096  // idea.1097  if (!UmbrellaHeader)1098    return nullptr;1099 1100  Module *Result = new (ModulesAlloc.Allocate())1101      Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,1102             /*IsFramework=*/true, /*IsExplicit=*/false, NumCreatedModules++);1103  setInferredModuleAllowedBy(Result, ModuleMapFID);1104  if (!Parent) {1105    if (LangOpts.CurrentModule == ModuleName)1106      SourceModule = Result;1107    Modules[ModuleName] = Result;1108    ModuleScopeIDs[Result] = CurrentModuleScopeID;1109  }1110 1111  Result->IsSystem |= Attrs.IsSystem;1112  Result->IsExternC |= Attrs.IsExternC;1113  Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;1114  Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;1115  Result->Directory = FrameworkDir;1116 1117  // Chop off the first framework bit, as that is implied.1118  StringRef RelativePath = UmbrellaName.str().substr(1119      Result->getTopLevelModule()->Directory->getName().size());1120  RelativePath = llvm::sys::path::relative_path(RelativePath);1121 1122  // umbrella header "umbrella-header-name"1123  setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h",1124                             RelativePath);1125 1126  // export *1127  Result->Exports.push_back(Module::ExportDecl(nullptr, true));1128 1129  // module * { export * }1130  Result->InferSubmodules = true;1131  Result->InferExportWildcard = true;1132 1133  // Look for subframeworks.1134  std::error_code EC;1135  SmallString<128> SubframeworksDirName = FrameworkDir.getName();1136  llvm::sys::path::append(SubframeworksDirName, "Frameworks");1137  llvm::sys::path::native(SubframeworksDirName);1138  llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();1139  for (llvm::vfs::directory_iterator1140           Dir = FS.dir_begin(SubframeworksDirName, EC),1141           DirEnd;1142       Dir != DirEnd && !EC; Dir.increment(EC)) {1143    if (!StringRef(Dir->path()).ends_with(".framework"))1144      continue;1145 1146    if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {1147      // Note: as an egregious but useful hack, we use the real path here and1148      // check whether it is actually a subdirectory of the parent directory.1149      // This will not be the case if the 'subframework' is actually a symlink1150      // out to a top-level framework.1151      StringRef SubframeworkDirName =1152          FileMgr.getCanonicalName(*SubframeworkDir);1153      bool FoundParent = false;1154      do {1155        // Get the parent directory name.1156        SubframeworkDirName1157          = llvm::sys::path::parent_path(SubframeworkDirName);1158        if (SubframeworkDirName.empty())1159          break;1160 1161        if (auto SubDir =1162                FileMgr.getOptionalDirectoryRef(SubframeworkDirName)) {1163          if (*SubDir == FrameworkDir) {1164            FoundParent = true;1165            break;1166          }1167        }1168      } while (true);1169 1170      if (!FoundParent)1171        continue;1172 1173      // FIXME: Do we want to warn about subframeworks without umbrella headers?1174      inferFrameworkModule(*SubframeworkDir, Attrs, Result);1175    }1176  }1177 1178  // If the module is a top-level framework, automatically link against the1179  // framework.1180  if (!Result->isSubFramework())1181    inferFrameworkLink(Result);1182 1183  return Result;1184}1185 1186Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,1187                                        Module *ShadowingModule) {1188 1189  // Create a new module with this name.1190  Module *Result = new (ModulesAlloc.Allocate())1191      Module(ModuleConstructorTag{}, Name, SourceLocation(), /*Parent=*/nullptr,1192             IsFramework, /*IsExplicit=*/false, NumCreatedModules++);1193  Result->ShadowingModule = ShadowingModule;1194  Result->markUnavailable(/*Unimportable*/true);1195  ModuleScopeIDs[Result] = CurrentModuleScopeID;1196  ShadowModules.push_back(Result);1197 1198  return Result;1199}1200 1201void ModuleMap::setUmbrellaHeaderAsWritten(1202    Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,1203    const Twine &PathRelativeToRootModuleDirectory) {1204  Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));1205  Mod->Umbrella = UmbrellaHeader;1206  Mod->UmbrellaAsWritten = NameAsWritten.str();1207  Mod->UmbrellaRelativeToRootModuleDirectory =1208      PathRelativeToRootModuleDirectory.str();1209  UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;1210 1211  // Notify callbacks that we just added a new header.1212  for (const auto &Cb : Callbacks)1213    Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);1214}1215 1216void ModuleMap::setUmbrellaDirAsWritten(1217    Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,1218    const Twine &PathRelativeToRootModuleDirectory) {1219  Mod->Umbrella = UmbrellaDir;1220  Mod->UmbrellaAsWritten = NameAsWritten.str();1221  Mod->UmbrellaRelativeToRootModuleDirectory =1222      PathRelativeToRootModuleDirectory.str();1223  UmbrellaDirs[UmbrellaDir] = Mod;1224}1225 1226void ModuleMap::addUnresolvedHeader(Module *Mod,1227                                    Module::UnresolvedHeaderDirective Header,1228                                    bool &NeedsFramework) {1229  // If there is a builtin counterpart to this file, add it now so it can1230  // wrap the system header.1231  if (resolveAsBuiltinHeader(Mod, Header)) {1232    // If we have both a builtin and system version of the file, the1233    // builtin version may want to inject macros into the system header, so1234    // force the system header to be treated as a textual header in this1235    // case.1236    Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(1237        headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));1238    Header.HasBuiltinHeader = true;1239  }1240 1241  // If possible, don't stat the header until we need to. This requires the1242  // user to have provided us with some stat information about the file.1243  // FIXME: Add support for lazily stat'ing umbrella headers and excluded1244  // headers.1245  if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&1246      Header.Kind != Module::HK_Excluded) {1247    // We expect more variation in mtime than size, so if we're given both,1248    // use the mtime as the key.1249    if (Header.ModTime)1250      LazyHeadersByModTime[*Header.ModTime].push_back(Mod);1251    else1252      LazyHeadersBySize[*Header.Size].push_back(Mod);1253    Mod->UnresolvedHeaders.push_back(Header);1254    return;1255  }1256 1257  // We don't have stat information or can't defer looking this file up.1258  // Perform the lookup now.1259  resolveHeader(Mod, Header, NeedsFramework);1260}1261 1262void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {1263  auto BySize = LazyHeadersBySize.find(File->getSize());1264  if (BySize != LazyHeadersBySize.end()) {1265    for (auto *M : BySize->second)1266      resolveHeaderDirectives(M, File);1267    LazyHeadersBySize.erase(BySize);1268  }1269 1270  auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());1271  if (ByModTime != LazyHeadersByModTime.end()) {1272    for (auto *M : ByModTime->second)1273      resolveHeaderDirectives(M, File);1274    LazyHeadersByModTime.erase(ByModTime);1275  }1276}1277 1278void ModuleMap::resolveHeaderDirectives(1279    Module *Mod, std::optional<const FileEntry *> File) const {1280  bool NeedsFramework = false;1281  SmallVector<Module::UnresolvedHeaderDirective, 1> NewHeaders;1282  const auto Size = File ? (*File)->getSize() : 0;1283  const auto ModTime = File ? (*File)->getModificationTime() : 0;1284 1285  for (auto &Header : Mod->UnresolvedHeaders) {1286    if (File && ((Header.ModTime && Header.ModTime != ModTime) ||1287                 (Header.Size && Header.Size != Size)))1288      NewHeaders.push_back(Header);1289    else1290      // This operation is logically const; we're just changing how we represent1291      // the header information for this file.1292      const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);1293  }1294  Mod->UnresolvedHeaders.swap(NewHeaders);1295}1296 1297void ModuleMap::addHeader(Module *Mod, Module::Header Header,1298                          ModuleHeaderRole Role, bool Imported) {1299  KnownHeader KH(Mod, Role);1300 1301  FileEntryRef HeaderEntry = Header.Entry;1302 1303  // Only add each header to the headers list once.1304  // FIXME: Should we diagnose if a header is listed twice in the1305  // same module definition?1306  auto &HeaderList = Headers[HeaderEntry];1307  if (llvm::is_contained(HeaderList, KH))1308    return;1309 1310  HeaderList.push_back(KH);1311  Mod->addHeader(headerRoleToKind(Role), std::move(Header));1312 1313  bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);1314  if (!Imported || isCompilingModuleHeader) {1315    // When we import HeaderFileInfo, the external source is expected to1316    // set the isModuleHeader flag itself.1317    HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role, isCompilingModuleHeader);1318  }1319 1320  // Notify callbacks that we just added a new header.1321  for (const auto &Cb : Callbacks)1322    Cb->moduleMapAddHeader(HeaderEntry.getName());1323}1324 1325bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,1326                                   DirectoryEntryRef Dir, FileID ID,1327                                   SourceLocation ExternModuleLoc) {1328  llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator1329      Known = ParsedModuleMap.find(File);1330  if (Known != ParsedModuleMap.end())1331    return Known->second == nullptr;1332 1333  // If the module map file wasn't already entered, do so now.1334  if (ID.isInvalid()) {1335    ID = SourceMgr.translateFile(File);1336    if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {1337      auto FileCharacter =1338          IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;1339      ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);1340    }1341  }1342 1343  std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);1344  if (!Buffer) {1345    ParsedModuleMap[File] = nullptr;1346    return true;1347  }1348 1349  Diags.Report(diag::remark_mmap_parse) << File.getName();1350  std::optional<modulemap::ModuleMapFile> MaybeMMF =1351      modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, nullptr);1352 1353  if (!MaybeMMF) {1354    ParsedModuleMap[File] = nullptr;1355    return true;1356  }1357 1358  ParsedModuleMaps.push_back(1359      std::make_unique<modulemap::ModuleMapFile>(std::move(*MaybeMMF)));1360  const modulemap::ModuleMapFile &MMF = *ParsedModuleMaps.back();1361  std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;1362  for (const auto &Decl : MMF.Decls) {1363    std::visit(llvm::makeVisitor(1364                   [&](const modulemap::ModuleDecl &MD) {1365                     // Only use the first part of the name even for submodules.1366                     // This will correctly load the submodule declarations when1367                     // the module is loaded.1368                     auto &ModuleDecls =1369                         ParsedModules[StringRef(MD.Id.front().first)];1370                     ModuleDecls.push_back(std::pair(&MMF, &MD));1371                   },1372                   [&](const modulemap::ExternModuleDecl &EMD) {1373                     PendingExternalModuleMaps.push_back(&EMD);1374                   }),1375               Decl);1376  }1377 1378  for (const modulemap::ExternModuleDecl *EMD : PendingExternalModuleMaps) {1379    StringRef FileNameRef = EMD->Path;1380    SmallString<128> ModuleMapFileName;1381    if (llvm::sys::path::is_relative(FileNameRef)) {1382      ModuleMapFileName += Dir.getName();1383      llvm::sys::path::append(ModuleMapFileName, EMD->Path);1384      FileNameRef = ModuleMapFileName;1385    }1386 1387    if (auto EFile =1388            SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {1389      parseModuleMapFile(*EFile, IsSystem, EFile->getDir(), FileID(),1390                         ExternModuleLoc);1391    }1392  }1393 1394  ParsedModuleMap[File] = &MMF;1395 1396  for (const auto &Cb : Callbacks)1397    Cb->moduleMapFileRead(SourceLocation(), File, IsSystem);1398 1399  return false;1400}1401 1402FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const {1403  if (Module->DefinitionLoc.isInvalid())1404    return {};1405 1406  return SourceMgr.getFileID(Module->DefinitionLoc);1407}1408 1409OptionalFileEntryRef1410ModuleMap::getContainingModuleMapFile(const Module *Module) const {1411  return SourceMgr.getFileEntryRefForID(getContainingModuleMapFileID(Module));1412}1413 1414FileID ModuleMap::getModuleMapFileIDForUniquing(const Module *M) const {1415  if (M->IsInferred) {1416    assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");1417    return InferredModuleAllowedBy.find(M)->second;1418  }1419  return getContainingModuleMapFileID(M);1420}1421 1422OptionalFileEntryRef1423ModuleMap::getModuleMapFileForUniquing(const Module *M) const {1424  return SourceMgr.getFileEntryRefForID(getModuleMapFileIDForUniquing(M));1425}1426 1427void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {1428  M->IsInferred = true;1429  InferredModuleAllowedBy[M] = ModMapFID;1430}1431 1432std::error_code1433ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {1434  StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});1435 1436  // Do not canonicalize within the framework; the module map loader expects1437  // Modules/ not Versions/A/Modules.1438  if (llvm::sys::path::filename(Dir) == "Modules") {1439    StringRef Parent = llvm::sys::path::parent_path(Dir);1440    if (Parent.ends_with(".framework"))1441      Dir = Parent;1442  }1443 1444  FileManager &FM = SourceMgr.getFileManager();1445  auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);1446  if (!DirEntry)1447    return llvm::errorToErrorCode(DirEntry.takeError());1448 1449  // Canonicalize the directory.1450  StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);1451  if (CanonicalDir != Dir)1452    llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);1453 1454  // In theory, the filename component should also be canonicalized if it1455  // on a case-insensitive filesystem. However, the extra canonicalization is1456  // expensive and if clang looked up the filename it will always be lowercase.1457 1458  // Remove ., remove redundant separators, and switch to native separators.1459  // This is needed for separators between CanonicalDir and the filename.1460  llvm::sys::path::remove_dots(Path);1461 1462  return std::error_code();1463}1464 1465void ModuleMap::addAdditionalModuleMapFile(const Module *M,1466                                           FileEntryRef ModuleMap) {1467  AdditionalModMaps[M].insert(ModuleMap);1468}1469 1470LLVM_DUMP_METHOD void ModuleMap::dump() {1471  llvm::errs() << "Modules:";1472  for (llvm::StringMap<Module *>::iterator M = Modules.begin(),1473                                        MEnd = Modules.end();1474       M != MEnd; ++M)1475    M->getValue()->print(llvm::errs(), 2);1476 1477  llvm::errs() << "Headers:";1478  for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();1479       H != HEnd; ++H) {1480    llvm::errs() << "  \"" << H->first.getName() << "\" -> ";1481    for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),1482                                                      E = H->second.end();1483         I != E; ++I) {1484      if (I != H->second.begin())1485        llvm::errs() << ",";1486      llvm::errs() << I->getModule()->getFullModuleName();1487    }1488    llvm::errs() << "\n";1489  }1490}1491 1492bool ModuleMap::resolveExports(Module *Mod, bool Complain) {1493  auto Unresolved = std::move(Mod->UnresolvedExports);1494  Mod->UnresolvedExports.clear();1495  for (auto &UE : Unresolved) {1496    Module::ExportDecl Export = resolveExport(Mod, UE, Complain);1497    if (Export.getPointer() || Export.getInt())1498      Mod->Exports.push_back(Export);1499    else1500      Mod->UnresolvedExports.push_back(UE);1501  }1502  return !Mod->UnresolvedExports.empty();1503}1504 1505bool ModuleMap::resolveUses(Module *Mod, bool Complain) {1506  auto *Top = Mod->getTopLevelModule();1507  auto Unresolved = std::move(Top->UnresolvedDirectUses);1508  Top->UnresolvedDirectUses.clear();1509  for (auto &UDU : Unresolved) {1510    Module *DirectUse = resolveModuleId(UDU, Top, Complain);1511    if (DirectUse)1512      Top->DirectUses.push_back(DirectUse);1513    else1514      Top->UnresolvedDirectUses.push_back(UDU);1515  }1516  return !Top->UnresolvedDirectUses.empty();1517}1518 1519bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {1520  auto Unresolved = std::move(Mod->UnresolvedConflicts);1521  Mod->UnresolvedConflicts.clear();1522  for (auto &UC : Unresolved) {1523    if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {1524      Module::Conflict Conflict;1525      Conflict.Other = OtherMod;1526      Conflict.Message = UC.Message;1527      Mod->Conflicts.push_back(Conflict);1528    } else1529      Mod->UnresolvedConflicts.push_back(UC);1530  }1531  return !Mod->UnresolvedConflicts.empty();1532}1533 1534//----------------------------------------------------------------------------//1535// Module map file loader1536//----------------------------------------------------------------------------//1537 1538namespace clang {1539class ModuleMapLoader {1540  SourceManager &SourceMgr;1541 1542  DiagnosticsEngine &Diags;1543  ModuleMap &Map;1544 1545  /// The current module map file.1546  FileID ModuleMapFID;1547 1548  /// Source location of most recent loaded module declaration1549  SourceLocation CurrModuleDeclLoc;1550 1551  /// The directory that file names in this module map file should1552  /// be resolved relative to.1553  DirectoryEntryRef Directory;1554 1555  /// Whether this module map is in a system header directory.1556  bool IsSystem;1557 1558  /// Whether an error occurred.1559  bool HadError = false;1560 1561  /// The active module.1562  Module *ActiveModule = nullptr;1563 1564  /// Whether a module uses the 'requires excluded' hack to mark its1565  /// contents as 'textual'.1566  ///1567  /// On older Darwin SDK versions, 'requires excluded' is used to mark the1568  /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as1569  /// non-modular headers.  For backwards compatibility, we continue to1570  /// support this idiom for just these modules, and map the headers to1571  /// 'textual' to match the original intent.1572  llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;1573 1574  void handleModuleDecl(const modulemap::ModuleDecl &MD);1575  void handleExternModuleDecl(const modulemap::ExternModuleDecl &EMD);1576  void handleRequiresDecl(const modulemap::RequiresDecl &RD);1577  void handleHeaderDecl(const modulemap::HeaderDecl &HD);1578  void handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD);1579  void handleExportDecl(const modulemap::ExportDecl &ED);1580  void handleExportAsDecl(const modulemap::ExportAsDecl &EAD);1581  void handleUseDecl(const modulemap::UseDecl &UD);1582  void handleLinkDecl(const modulemap::LinkDecl &LD);1583  void handleConfigMacros(const modulemap::ConfigMacrosDecl &CMD);1584  void handleConflict(const modulemap::ConflictDecl &CD);1585  void handleInferredModuleDecl(const modulemap::ModuleDecl &MD);1586 1587  /// Private modules are canonicalized as Foo_Private. Clang provides extra1588  /// module map search logic to find the appropriate private module when PCH1589  /// is used with implicit module maps. Warn when private modules are written1590  /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.1591  void diagnosePrivateModules(SourceLocation StartLoc);1592 1593  using Attributes = ModuleMap::Attributes;1594 1595public:1596  ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags,1597                  ModuleMap &Map, FileID ModuleMapFID,1598                  DirectoryEntryRef Directory, bool IsSystem)1599      : SourceMgr(SourceMgr), Diags(Diags), Map(Map),1600        ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}1601 1602  bool loadModuleDecl(const modulemap::ModuleDecl &MD);1603  bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD);1604  bool parseAndLoadModuleMapFile(const modulemap::ModuleMapFile &MMF);1605};1606 1607} // namespace clang1608 1609/// Private modules are canonicalized as Foo_Private. Clang provides extra1610/// module map search logic to find the appropriate private module when PCH1611/// is used with implicit module maps. Warn when private modules are written1612/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.1613void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {1614  auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,1615                             const Module *M, SourceRange ReplLoc) {1616    auto D = Diags.Report(ActiveModule->DefinitionLoc,1617                          diag::note_mmap_rename_top_level_private_module);1618    D << BadName << M->Name;1619    D << FixItHint::CreateReplacement(ReplLoc, Canonical);1620  };1621 1622  for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {1623    auto const *M = E->getValue();1624    if (M->Directory != ActiveModule->Directory)1625      continue;1626 1627    SmallString<128> FullName(ActiveModule->getFullModuleName());1628    if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))1629      continue;1630    SmallString<128> FixedPrivModDecl;1631    SmallString<128> Canonical(M->Name);1632    Canonical.append("_Private");1633 1634    // Foo.Private -> Foo_Private1635    if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&1636        M->Name == ActiveModule->Parent->Name) {1637      Diags.Report(ActiveModule->DefinitionLoc,1638                   diag::warn_mmap_mismatched_private_submodule)1639          << FullName;1640 1641      SourceLocation FixItInitBegin = CurrModuleDeclLoc;1642      if (StartLoc.isValid())1643        FixItInitBegin = StartLoc;1644 1645      if (ActiveModule->Parent->IsFramework)1646        FixedPrivModDecl.append("framework ");1647      FixedPrivModDecl.append("module ");1648      FixedPrivModDecl.append(Canonical);1649 1650      GenNoteAndFixIt(FullName, FixedPrivModDecl, M,1651                      SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));1652      continue;1653    }1654 1655    // FooPrivate and whatnots -> Foo_Private1656    if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&1657        ActiveModule->Name != Canonical) {1658      Diags.Report(ActiveModule->DefinitionLoc,1659                   diag::warn_mmap_mismatched_private_module_name)1660          << ActiveModule->Name;1661      GenNoteAndFixIt(ActiveModule->Name, Canonical, M,1662                      SourceRange(ActiveModule->DefinitionLoc));1663    }1664  }1665}1666 1667void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {1668  if (MD.Id.front().first == "*")1669    return handleInferredModuleDecl(MD);1670 1671  CurrModuleDeclLoc = MD.Location;1672 1673  Module *PreviousActiveModule = ActiveModule;1674  if (MD.Id.size() > 1) {1675    // This module map defines a submodule. Go find the module of which it1676    // is a submodule.1677    ActiveModule = nullptr;1678    const Module *TopLevelModule = nullptr;1679    for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {1680      if (Module *Next =1681              Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {1682        if (I == 0)1683          TopLevelModule = Next;1684        ActiveModule = Next;1685        continue;1686      }1687 1688      Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)1689          << MD.Id[I].first << (ActiveModule != nullptr)1690          << (ActiveModule1691                  ? ActiveModule->getTopLevelModule()->getFullModuleName()1692                  : "");1693      HadError = true;1694    }1695 1696    if (TopLevelModule &&1697        ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {1698      assert(ModuleMapFID !=1699                 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&1700             "submodule defined in same file as 'module *' that allowed its "1701             "top-level module");1702      Map.addAdditionalModuleMapFile(1703          TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));1704    }1705  }1706 1707  StringRef ModuleName = MD.Id.back().first;1708  SourceLocation ModuleNameLoc = MD.Id.back().second;1709 1710  // Determine whether this (sub)module has already been defined.1711  Module *ShadowingModule = nullptr;1712  if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {1713    // We might see a (re)definition of a module that we already have a1714    // definition for in four cases:1715    //  - If we loaded one definition from an AST file and we've just found a1716    //    corresponding definition in a module map file, or1717    bool LoadedFromASTFile = Existing->IsFromModuleFile;1718    //  - If we previously inferred this module from different module map file.1719    bool Inferred = Existing->IsInferred;1720    //  - If we're building a framework that vends a module map, we might've1721    //    previously seen the one in intermediate products and now the system1722    //    one.1723    // FIXME: If we're parsing module map file that looks like this:1724    //          framework module FW { ... }1725    //          module FW.Sub { ... }1726    //        We can't check the framework qualifier, since it's not attached to1727    //        the definition of Sub. Checking that qualifier on \c Existing is1728    //        not correct either, since we might've previously seen:1729    //          module FW { ... }1730    //          module FW.Sub { ... }1731    //        We should enforce consistency of redefinitions so that we can rely1732    //        that \c Existing is part of a framework iff the redefinition of FW1733    //        we have just skipped had it too. Once we do that, stop checking1734    //        the local framework qualifier and only rely on \c Existing.1735    bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();1736    //  - If we're building a (preprocessed) module and we've just loaded the1737    //    module map file from which it was created.1738    bool ParsedAsMainInput =1739        Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&1740        Map.LangOpts.CurrentModule == ModuleName &&1741        SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=1742            SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;1743    // TODO: Remove this check when we can avoid loading module maps multiple1744    //       times.1745    bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;1746    if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||1747        SameModuleDecl) {1748      ActiveModule = PreviousActiveModule;1749      // Skip the module definition.1750      return;1751    }1752 1753    if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {1754      ShadowingModule = Existing;1755    } else {1756      // This is not a shawdowed module decl, it is an illegal redefinition.1757      Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)1758          << ModuleName;1759      Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);1760      HadError = true;1761      return;1762    }1763  }1764 1765  // Start defining this module.1766  if (ShadowingModule) {1767    ActiveModule =1768        Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);1769  } else {1770    ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,1771                                               MD.Framework, MD.Explicit);1772  }1773 1774  ActiveModule->DefinitionLoc = ModuleNameLoc;1775  if (MD.Attrs.IsSystem || IsSystem)1776    ActiveModule->IsSystem = true;1777  if (MD.Attrs.IsExternC)1778    ActiveModule->IsExternC = true;1779  if (MD.Attrs.NoUndeclaredIncludes)1780    ActiveModule->NoUndeclaredIncludes = true;1781  ActiveModule->Directory = Directory;1782 1783  StringRef MapFileName(1784      SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());1785  if (MapFileName.ends_with("module.private.modulemap") ||1786      MapFileName.ends_with("module_private.map")) {1787    ActiveModule->ModuleMapIsPrivate = true;1788  }1789 1790  // Private modules named as FooPrivate, Foo.Private or similar are likely a1791  // user error; provide warnings, notes and fixits to direct users to use1792  // Foo_Private instead.1793  SourceLocation StartLoc =1794      SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());1795  if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&1796      !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,1797                       StartLoc) &&1798      !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,1799                       StartLoc) &&1800      ActiveModule->ModuleMapIsPrivate)1801    diagnosePrivateModules(MD.Location);1802 1803  for (const modulemap::Decl &Decl : MD.Decls) {1804    std::visit(1805        llvm::makeVisitor(1806            [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },1807            [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },1808            [&](const modulemap::UmbrellaDirDecl &UDD) {1809              handleUmbrellaDirDecl(UDD);1810            },1811            [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },1812            [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },1813            [&](const modulemap::ExportAsDecl &EAD) {1814              handleExportAsDecl(EAD);1815            },1816            [&](const modulemap::ExternModuleDecl &EMD) {1817              handleExternModuleDecl(EMD);1818            },1819            [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },1820            [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },1821            [&](const modulemap::ConfigMacrosDecl &CMD) {1822              handleConfigMacros(CMD);1823            },1824            [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },1825            [&](const modulemap::ExcludeDecl &ED) {1826              Diags.Report(ED.Location, diag::err_mmap_expected_member);1827            }),1828        Decl);1829  }1830 1831  // If the active module is a top-level framework, and there are no link1832  // libraries, automatically link against the framework.1833  if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&1834      ActiveModule->LinkLibraries.empty())1835    inferFrameworkLink(ActiveModule);1836 1837  // If the module meets all requirements but is still unavailable, mark the1838  // whole tree as unavailable to prevent it from building.1839  if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&1840      ActiveModule->Parent) {1841    ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);1842    ActiveModule->getTopLevelModule()->MissingHeaders.append(1843      ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());1844  }1845 1846  // We're done parsing this module. Pop back to the previous module.1847  ActiveModule = PreviousActiveModule;1848}1849 1850void ModuleMapLoader::handleExternModuleDecl(1851    const modulemap::ExternModuleDecl &EMD) {1852  StringRef FileNameRef = EMD.Path;1853  SmallString<128> ModuleMapFileName;1854  if (llvm::sys::path::is_relative(FileNameRef)) {1855    ModuleMapFileName += Directory.getName();1856    llvm::sys::path::append(ModuleMapFileName, EMD.Path);1857    FileNameRef = ModuleMapFileName;1858  }1859  if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))1860    Map.parseAndLoadModuleMapFile(1861        *File, IsSystem,1862        Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd1863            ? Directory1864            : File->getDir(),1865        FileID(), nullptr, EMD.Location);1866}1867 1868/// Whether to add the requirement \p Feature to the module \p M.1869///1870/// This preserves backwards compatibility for two hacks in the Darwin system1871/// module map files:1872///1873/// 1. The use of 'requires excluded' to make headers non-modular, which1874///    should really be mapped to 'textual' now that we have this feature.  We1875///    drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to1876///    true.  Later, this bit will be used to map all the headers inside this1877///    module to 'textual'.1878///1879///    This affects Darwin.C.excluded (for assert.h) and Tcl.Private.1880///1881/// 2. Removes a bogus cplusplus requirement from IOKit.avc.  This requirement1882///    was never correct and causes issues now that we check it, so drop it.1883static bool shouldAddRequirement(Module *M, StringRef Feature,1884                                 bool &IsRequiresExcludedHack) {1885  if (Feature == "excluded" &&1886      (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||1887       M->fullModuleNameIs({"Tcl", "Private"}))) {1888    IsRequiresExcludedHack = true;1889    return false;1890  } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {1891    return false;1892  }1893 1894  return true;1895}1896 1897void ModuleMapLoader::handleRequiresDecl(const modulemap::RequiresDecl &RD) {1898 1899  for (const modulemap::RequiresFeature &RF : RD.Features) {1900    bool IsRequiresExcludedHack = false;1901    bool ShouldAddRequirement =1902        shouldAddRequirement(ActiveModule, RF.Feature, IsRequiresExcludedHack);1903 1904    if (IsRequiresExcludedHack)1905      UsesRequiresExcludedHack.insert(ActiveModule);1906 1907    if (ShouldAddRequirement) {1908      // Add this feature.1909      ActiveModule->addRequirement(RF.Feature, RF.RequiredState, Map.LangOpts,1910                                   *Map.Target);1911    }1912  }1913}1914 1915void ModuleMapLoader::handleHeaderDecl(const modulemap::HeaderDecl &HD) {1916  // We've already consumed the first token.1917  ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;1918 1919  if (HD.Private) {1920    Role = ModuleMap::PrivateHeader;1921  } else if (HD.Excluded) {1922    Role = ModuleMap::ExcludedHeader;1923  }1924 1925  if (HD.Textual)1926    Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);1927 1928  if (UsesRequiresExcludedHack.count(ActiveModule)) {1929    // Mark this header 'textual' (see doc comment for1930    // Module::UsesRequiresExcludedHack).1931    Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);1932  }1933 1934  Module::UnresolvedHeaderDirective Header;1935  Header.FileName = HD.Path;1936  Header.FileNameLoc = HD.PathLoc;1937  Header.IsUmbrella = HD.Umbrella;1938  Header.Kind = Map.headerRoleToKind(Role);1939 1940  // Check whether we already have an umbrella.1941  if (Header.IsUmbrella &&1942      !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {1943    Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)1944      << ActiveModule->getFullModuleName();1945    HadError = true;1946    return;1947  }1948 1949  if (HD.Size)1950    Header.Size = HD.Size;1951  if (HD.MTime)1952    Header.ModTime = HD.MTime;1953 1954  bool NeedsFramework = false;1955  // Don't add headers to the builtin modules if the builtin headers belong to1956  // the system modules, with the exception of __stddef_max_align_t.h which1957  // always had its own module.1958  if (!Map.LangOpts.BuiltinHeadersInSystemModules ||1959      !isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||1960      ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))1961    Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);1962 1963  if (NeedsFramework)1964    Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)1965      << ActiveModule->getFullModuleName()1966      << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");1967}1968 1969static bool compareModuleHeaders(const Module::Header &A,1970                                 const Module::Header &B) {1971  return A.NameAsWritten < B.NameAsWritten;1972}1973 1974void ModuleMapLoader::handleUmbrellaDirDecl(1975    const modulemap::UmbrellaDirDecl &UDD) {1976  std::string DirName = std::string(UDD.Path);1977  std::string DirNameAsWritten = DirName;1978 1979  // Check whether we already have an umbrella.1980  if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {1981    Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)1982        << ActiveModule->getFullModuleName();1983    HadError = true;1984    return;1985  }1986 1987  // Look for this file.1988  OptionalDirectoryEntryRef Dir;1989  if (llvm::sys::path::is_absolute(DirName)) {1990    Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);1991  } else {1992    SmallString<128> PathName;1993    PathName = Directory.getName();1994    llvm::sys::path::append(PathName, DirName);1995    Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);1996  }1997 1998  if (!Dir) {1999    Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)2000        << DirName;2001    return;2002  }2003 2004  if (UsesRequiresExcludedHack.count(ActiveModule)) {2005    // Mark this header 'textual' (see doc comment for2006    // ModuleMapLoader::UsesRequiresExcludedHack). Although iterating over the2007    // directory is relatively expensive, in practice this only applies to the2008    // uncommonly used Tcl module on Darwin platforms.2009    std::error_code EC;2010    SmallVector<Module::Header, 6> Headers;2011    llvm::vfs::FileSystem &FS =2012        SourceMgr.getFileManager().getVirtualFileSystem();2013    for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;2014         I != E && !EC; I.increment(EC)) {2015      if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {2016        Module::Header Header = {"", std::string(I->path()), *FE};2017        Headers.push_back(std::move(Header));2018      }2019    }2020 2021    // Sort header paths so that the pcm doesn't depend on iteration order.2022    llvm::stable_sort(Headers, compareModuleHeaders);2023 2024    for (auto &Header : Headers)2025      Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);2026    return;2027  }2028 2029  if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {2030    Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)2031        << OwningModule->getFullModuleName();2032    HadError = true;2033    return;2034  }2035 2036  // Record this umbrella directory.2037  Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);2038}2039 2040void ModuleMapLoader::handleExportDecl(const modulemap::ExportDecl &ED) {2041  Module::UnresolvedExportDecl Unresolved = {ED.Location, ED.Id, ED.Wildcard};2042  ActiveModule->UnresolvedExports.push_back(Unresolved);2043}2044 2045void ModuleMapLoader::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {2046  const auto &ModName = EAD.Id.front();2047 2048  if (!ActiveModule->ExportAsModule.empty()) {2049    if (ActiveModule->ExportAsModule == ModName.first) {2050      Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)2051          << ActiveModule->Name << ModName.first;2052    } else {2053      Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)2054          << ActiveModule->Name << ActiveModule->ExportAsModule2055          << ModName.first;2056    }2057  }2058 2059  ActiveModule->ExportAsModule = ModName.first;2060  Map.addLinkAsDependency(ActiveModule);2061}2062 2063void ModuleMapLoader::handleUseDecl(const modulemap::UseDecl &UD) {2064  if (ActiveModule->Parent)2065    Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);2066  else2067    ActiveModule->UnresolvedDirectUses.push_back(UD.Id);2068}2069 2070void ModuleMapLoader::handleLinkDecl(const modulemap::LinkDecl &LD) {2071  ActiveModule->LinkLibraries.push_back(2072      Module::LinkLibrary(std::string{LD.Library}, LD.Framework));2073}2074 2075void ModuleMapLoader::handleConfigMacros(2076    const modulemap::ConfigMacrosDecl &CMD) {2077  if (ActiveModule->Parent) {2078    Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);2079    return;2080  }2081 2082  // TODO: Is this really the behavior we want for multiple config_macros2083  //       declarations? If any of them are exhaustive then all of them are.2084  if (CMD.Exhaustive) {2085    ActiveModule->ConfigMacrosExhaustive = true;2086  }2087  ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),2088                                    CMD.Macros.begin(), CMD.Macros.end());2089}2090 2091void ModuleMapLoader::handleConflict(const modulemap::ConflictDecl &CD) {2092  Module::UnresolvedConflict Conflict;2093 2094  Conflict.Id = CD.Id;2095  Conflict.Message = CD.Message;2096 2097  // FIXME: when we move to C++20 we should consider using emplace_back2098  ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));2099}2100 2101void ModuleMapLoader::handleInferredModuleDecl(2102    const modulemap::ModuleDecl &MD) {2103  SourceLocation StarLoc = MD.Id.front().second;2104 2105  // Inferred modules must be submodules.2106  if (!ActiveModule && !MD.Framework) {2107    Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);2108    return;2109  }2110 2111  if (ActiveModule) {2112    // Inferred modules must have umbrella directories.2113    if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {2114      Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);2115      return;2116    }2117 2118    // Check for redefinition of an inferred module.2119    if (ActiveModule->InferSubmodules) {2120      Diags.Report(StarLoc, diag::err_mmap_inferred_redef);2121      if (ActiveModule->InferredSubmoduleLoc.isValid())2122        Diags.Report(ActiveModule->InferredSubmoduleLoc,2123                     diag::note_mmap_prev_definition);2124      return;2125    }2126 2127    // Check for the 'framework' keyword, which is not permitted here.2128    if (MD.Framework) {2129      Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);2130      return;2131    }2132  } else if (MD.Explicit) {2133    Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);2134    return;2135  }2136 2137  if (ActiveModule) {2138    // Note that we have an inferred submodule.2139    ActiveModule->InferSubmodules = true;2140    ActiveModule->InferredSubmoduleLoc = StarLoc;2141    ActiveModule->InferExplicitSubmodules = MD.Explicit;2142  } else {2143    // We'll be inferring framework modules for this directory.2144    auto &InfDir = Map.InferredDirectories[Directory];2145    InfDir.InferModules = true;2146    InfDir.Attrs = MD.Attrs;2147    InfDir.ModuleMapFID = ModuleMapFID;2148    // FIXME: Handle the 'framework' keyword.2149  }2150 2151  for (const modulemap::Decl &Decl : MD.Decls) {2152    std::visit(2153        llvm::makeVisitor(2154            [&](const auto &Other) {2155              Diags.Report(Other.Location,2156                           diag::err_mmap_expected_inferred_member)2157                  << (ActiveModule != nullptr);2158            },2159            [&](const modulemap::ExcludeDecl &ED) {2160              // Only inferred frameworks can have exclude decls2161              if (ActiveModule) {2162                Diags.Report(ED.Location,2163                             diag::err_mmap_expected_inferred_member)2164                    << (ActiveModule != nullptr);2165                HadError = true;2166                return;2167              }2168              Map.InferredDirectories[Directory].ExcludedModules.emplace_back(2169                  ED.Module);2170            },2171            [&](const modulemap::ExportDecl &ED) {2172              // Only inferred submodules can have export decls2173              if (!ActiveModule) {2174                Diags.Report(ED.Location,2175                             diag::err_mmap_expected_inferred_member)2176                    << (ActiveModule != nullptr);2177                HadError = true;2178                return;2179              }2180 2181              if (ED.Wildcard && ED.Id.size() == 0)2182                ActiveModule->InferExportWildcard = true;2183              else2184                Diags.Report(ED.Id.front().second,2185                             diag::err_mmap_expected_export_wildcard);2186            }),2187        Decl);2188  }2189}2190 2191bool ModuleMapLoader::loadModuleDecl(const modulemap::ModuleDecl &MD) {2192  handleModuleDecl(MD);2193  return HadError;2194}2195 2196bool ModuleMapLoader::loadExternModuleDecl(2197    const modulemap::ExternModuleDecl &EMD) {2198  handleExternModuleDecl(EMD);2199  return HadError;2200}2201 2202bool ModuleMapLoader::parseAndLoadModuleMapFile(2203    const modulemap::ModuleMapFile &MMF) {2204  for (const auto &Decl : MMF.Decls) {2205    std::visit(2206        llvm::makeVisitor(2207            [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },2208            [&](const modulemap::ExternModuleDecl &EMD) {2209              handleExternModuleDecl(EMD);2210            }),2211        Decl);2212  }2213  return HadError;2214}2215 2216Module *ModuleMap::findOrLoadModule(StringRef Name) {2217  llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);2218  if (Known != Modules.end())2219    return Known->getValue();2220 2221  auto ParsedMod = ParsedModules.find(Name);2222  if (ParsedMod == ParsedModules.end())2223    return nullptr;2224 2225  Diags.Report(diag::remark_mmap_load_module) << Name;2226 2227  for (const auto &ModuleDecl : ParsedMod->second) {2228    const modulemap::ModuleMapFile &MMF = *ModuleDecl.first;2229    ModuleMapLoader Loader(SourceMgr, Diags, const_cast<ModuleMap &>(*this),2230                           MMF.ID, *MMF.Dir, MMF.IsSystem);2231    if (Loader.loadModuleDecl(*ModuleDecl.second))2232      return nullptr;2233  }2234 2235  return findModule(Name);2236}2237 2238bool ModuleMap::parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem,2239                                          DirectoryEntryRef Dir, FileID ID,2240                                          unsigned *Offset,2241                                          SourceLocation ExternModuleLoc) {2242  assert(Target && "Missing target information");2243  llvm::DenseMap<const FileEntry *, bool>::iterator Known =2244      LoadedModuleMap.find(File);2245  if (Known != LoadedModuleMap.end())2246    return Known->second;2247 2248  // If the module map file wasn't already entered, do so now.2249  if (ID.isInvalid()) {2250    ID = SourceMgr.translateFile(File);2251    // TODO: The way we compute affecting module maps requires this to be a2252    //       local FileID. This should be changed to reuse loaded FileIDs when2253    //       available, and change the way that affecting module maps are2254    //       computed to not require this.2255    if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {2256      auto FileCharacter =2257          IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;2258      ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);2259    }2260  }2261 2262  assert(Target && "Missing target information");2263  std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);2264  if (!Buffer)2265    return LoadedModuleMap[File] = true;2266  assert((!Offset || *Offset <= Buffer->getBufferSize()) &&2267         "invalid buffer offset");2268 2269  std::optional<modulemap::ModuleMapFile> MMF =2270      modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, Offset);2271  bool Result = false;2272  if (MMF) {2273    Diags.Report(diag::remark_mmap_load) << File.getName();2274    ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem);2275    Result = Loader.parseAndLoadModuleMapFile(*MMF);2276  }2277  LoadedModuleMap[File] = Result;2278 2279  // Notify callbacks that we observed it.2280  // FIXME: We should only report module maps that were actually used.2281  for (const auto &Cb : Callbacks)2282    Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);2283 2284  return Result;2285}2286