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