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