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