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