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