1 //===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the ModuleMap implementation, which describes the layout
10 // of a module as it relates to headers.
12 //===----------------------------------------------------------------------===//
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"
51 #include <system_error>
54 using namespace clang
;
56 void ModuleMapCallbacks::anchor() {}
58 void ModuleMap::resolveLinkAsDependencies(Module
*Mod
) {
59 auto PendingLinkAs
= PendingLinkAsModule
.find(Mod
->Name
);
60 if (PendingLinkAs
!= PendingLinkAsModule
.end()) {
61 for (auto &Name
: PendingLinkAs
->second
) {
62 auto *M
= findModule(Name
.getKey());
64 M
->UseExportAsModuleLinkName
= true;
69 void ModuleMap::addLinkAsDependency(Module
*Mod
) {
70 if (findModule(Mod
->ExportAsModule
))
71 Mod
->UseExportAsModuleLinkName
= true;
73 PendingLinkAsModule
[Mod
->ExportAsModule
].insert(Mod
->Name
);
76 Module::HeaderKind
ModuleMap::headerRoleToKind(ModuleHeaderRole Role
) {
79 return Module::HK_Normal
;
81 return Module::HK_Private
;
83 return Module::HK_Textual
;
84 case PrivateHeader
| TextualHeader
:
85 return Module::HK_PrivateTextual
;
87 return Module::HK_Excluded
;
89 llvm_unreachable("unknown header role");
92 ModuleMap::ModuleHeaderRole
93 ModuleMap::headerKindToRole(Module::HeaderKind Kind
) {
95 case Module::HK_Normal
:
97 case Module::HK_Private
:
99 case Module::HK_Textual
:
100 return TextualHeader
;
101 case Module::HK_PrivateTextual
:
102 return ModuleHeaderRole(PrivateHeader
| TextualHeader
);
103 case Module::HK_Excluded
:
104 return ExcludedHeader
;
106 llvm_unreachable("unknown header kind");
109 bool ModuleMap::isModular(ModuleHeaderRole Role
) {
110 return !(Role
& (ModuleMap::TextualHeader
| ModuleMap::ExcludedHeader
));
114 ModuleMap::resolveExport(Module
*Mod
,
115 const Module::UnresolvedExportDecl
&Unresolved
,
116 bool Complain
) const {
117 // We may have just a wildcard.
118 if (Unresolved
.Id
.empty()) {
119 assert(Unresolved
.Wildcard
&& "Invalid unresolved export");
120 return Module::ExportDecl(nullptr, true);
123 // Resolve the module-id.
124 Module
*Context
= resolveModuleId(Unresolved
.Id
, Mod
, Complain
);
128 return Module::ExportDecl(Context
, Unresolved
.Wildcard
);
131 Module
*ModuleMap::resolveModuleId(const ModuleId
&Id
, Module
*Mod
,
132 bool Complain
) const {
133 // Find the starting module.
134 Module
*Context
= lookupModuleUnqualified(Id
[0].first
, Mod
);
137 Diags
.Report(Id
[0].second
, diag::err_mmap_missing_module_unqualified
)
138 << Id
[0].first
<< Mod
->getFullModuleName();
143 // Dig into the module path.
144 for (unsigned I
= 1, N
= Id
.size(); I
!= N
; ++I
) {
145 Module
*Sub
= lookupModuleQualified(Id
[I
].first
, Context
);
148 Diags
.Report(Id
[I
].second
, diag::err_mmap_missing_module_qualified
)
149 << Id
[I
].first
<< Context
->getFullModuleName()
150 << SourceRange(Id
[0].second
, Id
[I
-1].second
);
161 /// Append to \p Paths the set of paths needed to get to the
162 /// subframework in which the given module lives.
163 static void appendSubframeworkPaths(Module
*Mod
,
164 SmallVectorImpl
<char> &Path
) {
165 // Collect the framework names from the given module to the top-level module.
166 SmallVector
<StringRef
, 2> Paths
;
167 for (; Mod
; Mod
= Mod
->Parent
) {
168 if (Mod
->IsFramework
)
169 Paths
.push_back(Mod
->Name
);
175 // Add Frameworks/Name.framework for each subframework.
176 for (StringRef Framework
: llvm::drop_begin(llvm::reverse(Paths
)))
177 llvm::sys::path::append(Path
, "Frameworks", Framework
+ ".framework");
180 OptionalFileEntryRef
ModuleMap::findHeader(
181 Module
*M
, const Module::UnresolvedHeaderDirective
&Header
,
182 SmallVectorImpl
<char> &RelativePathName
, bool &NeedsFramework
) {
183 // Search for the header file within the module's home directory.
184 auto Directory
= M
->Directory
;
185 SmallString
<128> FullPathName(Directory
->getName());
187 auto GetFile
= [&](StringRef Filename
) -> OptionalFileEntryRef
{
189 expectedToOptional(SourceMgr
.getFileManager().getFileRef(Filename
));
190 if (!File
|| (Header
.Size
&& File
->getSize() != *Header
.Size
) ||
191 (Header
.ModTime
&& File
->getModificationTime() != *Header
.ModTime
))
196 auto GetFrameworkFile
= [&]() -> OptionalFileEntryRef
{
197 unsigned FullPathLength
= FullPathName
.size();
198 appendSubframeworkPaths(M
, RelativePathName
);
199 unsigned RelativePathLength
= RelativePathName
.size();
201 // Check whether this file is in the public headers.
202 llvm::sys::path::append(RelativePathName
, "Headers", Header
.FileName
);
203 llvm::sys::path::append(FullPathName
, RelativePathName
);
204 if (auto File
= GetFile(FullPathName
))
207 // Check whether this file is in the private headers.
208 // Ideally, private modules in the form 'FrameworkName.Private' should
209 // be defined as 'module FrameworkName.Private', and not as
210 // 'framework module FrameworkName.Private', since a 'Private.Framework'
211 // does not usually exist. However, since both are currently widely used
212 // for private modules, make sure we find the right path in both cases.
213 if (M
->IsFramework
&& M
->Name
== "Private")
214 RelativePathName
.clear();
216 RelativePathName
.resize(RelativePathLength
);
217 FullPathName
.resize(FullPathLength
);
218 llvm::sys::path::append(RelativePathName
, "PrivateHeaders",
220 llvm::sys::path::append(FullPathName
, RelativePathName
);
221 return GetFile(FullPathName
);
224 if (llvm::sys::path::is_absolute(Header
.FileName
)) {
225 RelativePathName
.clear();
226 RelativePathName
.append(Header
.FileName
.begin(), Header
.FileName
.end());
227 return GetFile(Header
.FileName
);
230 if (M
->isPartOfFramework())
231 return GetFrameworkFile();
233 // Lookup for normal headers.
234 llvm::sys::path::append(RelativePathName
, Header
.FileName
);
235 llvm::sys::path::append(FullPathName
, RelativePathName
);
236 auto NormalHdrFile
= GetFile(FullPathName
);
238 if (!NormalHdrFile
&& Directory
->getName().endswith(".framework")) {
239 // The lack of 'framework' keyword in a module declaration it's a simple
240 // mistake we can diagnose when the header exists within the proper
241 // framework style path.
242 FullPathName
.assign(Directory
->getName());
243 RelativePathName
.clear();
244 if (GetFrameworkFile()) {
245 Diags
.Report(Header
.FileNameLoc
,
246 diag::warn_mmap_incomplete_framework_module_declaration
)
247 << Header
.FileName
<< M
->getFullModuleName();
248 NeedsFramework
= true;
253 return NormalHdrFile
;
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
259 static bool isBuiltinHeaderName(StringRef FileName
) {
260 return llvm::StringSwitch
<bool>(FileName
)
261 .Case("float.h", true)
262 .Case("iso646.h", true)
263 .Case("limits.h", true)
264 .Case("stdalign.h", true)
265 .Case("stdarg.h", true)
266 .Case("stdatomic.h", true)
267 .Case("stdbool.h", true)
268 .Case("stddef.h", true)
269 .Case("stdint.h", true)
270 .Case("tgmath.h", true)
271 .Case("unwind.h", true)
275 /// Determine whether the given module name is the name of a builtin
276 /// module that is cyclic with a system module on some platforms.
277 static bool isBuiltInModuleName(StringRef ModuleName
) {
278 return llvm::StringSwitch
<bool>(ModuleName
)
279 .Case("_Builtin_float", true)
280 .Case("_Builtin_inttypes", true)
281 .Case("_Builtin_iso646", true)
282 .Case("_Builtin_limits", true)
283 .Case("_Builtin_stdalign", true)
284 .Case("_Builtin_stdarg", true)
285 .Case("_Builtin_stdatomic", true)
286 .Case("_Builtin_stdbool", true)
287 .Case("_Builtin_stddef", true)
288 .Case("_Builtin_stdint", true)
289 .Case("_Builtin_stdnoreturn", true)
290 .Case("_Builtin_tgmath", true)
291 .Case("_Builtin_unwind", true)
295 void ModuleMap::resolveHeader(Module
*Mod
,
296 const Module::UnresolvedHeaderDirective
&Header
,
297 bool &NeedsFramework
) {
298 SmallString
<128> RelativePathName
;
299 if (OptionalFileEntryRef File
=
300 findHeader(Mod
, Header
, RelativePathName
, NeedsFramework
)) {
301 if (Header
.IsUmbrella
) {
302 const DirectoryEntry
*UmbrellaDir
= &File
->getDir().getDirEntry();
303 if (Module
*UmbrellaMod
= UmbrellaDirs
[UmbrellaDir
])
304 Diags
.Report(Header
.FileNameLoc
, diag::err_mmap_umbrella_clash
)
305 << UmbrellaMod
->getFullModuleName();
307 // Record this umbrella header.
308 setUmbrellaHeaderAsWritten(Mod
, *File
, Header
.FileName
,
309 RelativePathName
.str());
311 Module::Header H
= {Header
.FileName
, std::string(RelativePathName
.str()),
313 addHeader(Mod
, H
, headerKindToRole(Header
.Kind
));
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.
321 // If we find a module that has a missing header, we mark this module as
322 // unavailable and store the header directive for displaying diagnostics.
323 Mod
->MissingHeaders
.push_back(Header
);
324 // A missing header with stat information doesn't make the module
325 // unavailable; this keeps our behavior consistent as headers are lazily
326 // resolved. (Such a module still can't be built though, except from
327 // preprocessed source.)
328 if (!Header
.Size
&& !Header
.ModTime
)
329 Mod
->markUnavailable(/*Unimportable=*/false);
333 bool ModuleMap::resolveAsBuiltinHeader(
334 Module
*Mod
, const Module::UnresolvedHeaderDirective
&Header
) {
335 if (Header
.Kind
== Module::HK_Excluded
||
336 llvm::sys::path::is_absolute(Header
.FileName
) ||
337 Mod
->isPartOfFramework() || !Mod
->IsSystem
|| Header
.IsUmbrella
||
338 !BuiltinIncludeDir
|| BuiltinIncludeDir
== Mod
->Directory
||
339 !LangOpts
.BuiltinHeadersInSystemModules
|| !isBuiltinHeaderName(Header
.FileName
))
342 // This is a system module with a top-level header. This header
343 // may have a counterpart (or replacement) in the set of headers
344 // supplied by Clang. Find that builtin header.
345 SmallString
<128> Path
;
346 llvm::sys::path::append(Path
, BuiltinIncludeDir
->getName(), Header
.FileName
);
347 auto File
= SourceMgr
.getFileManager().getOptionalFileRef(Path
);
351 Module::Header H
= {Header
.FileName
, Header
.FileName
, *File
};
352 auto Role
= headerKindToRole(Header
.Kind
);
353 addHeader(Mod
, H
, Role
);
357 ModuleMap::ModuleMap(SourceManager
&SourceMgr
, DiagnosticsEngine
&Diags
,
358 const LangOptions
&LangOpts
, const TargetInfo
*Target
,
359 HeaderSearch
&HeaderInfo
)
360 : SourceMgr(SourceMgr
), Diags(Diags
), LangOpts(LangOpts
), Target(Target
),
361 HeaderInfo(HeaderInfo
) {
362 MMapLangOpts
.LineComment
= true;
365 ModuleMap::~ModuleMap() {
366 for (auto &M
: Modules
)
368 for (auto *M
: ShadowModules
)
372 void ModuleMap::setTarget(const TargetInfo
&Target
) {
373 assert((!this->Target
|| this->Target
== &Target
) &&
374 "Improper target override");
375 this->Target
= &Target
;
378 /// "Sanitize" a filename so that it can be used as an identifier.
379 static StringRef
sanitizeFilenameAsIdentifier(StringRef Name
,
380 SmallVectorImpl
<char> &Buffer
) {
384 if (!isValidAsciiIdentifier(Name
)) {
385 // If we don't already have something with the form of an identifier,
386 // create a buffer with the sanitized name.
388 if (isDigit(Name
[0]))
389 Buffer
.push_back('_');
390 Buffer
.reserve(Buffer
.size() + Name
.size());
391 for (unsigned I
= 0, N
= Name
.size(); I
!= N
; ++I
) {
392 if (isAsciiIdentifierContinue(Name
[I
]))
393 Buffer
.push_back(Name
[I
]);
395 Buffer
.push_back('_');
398 Name
= StringRef(Buffer
.data(), Buffer
.size());
401 while (llvm::StringSwitch
<bool>(Name
)
402 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
403 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
404 #include "clang/Basic/TokenKinds.def"
406 if (Name
.data() != Buffer
.data())
407 Buffer
.append(Name
.begin(), Name
.end());
408 Buffer
.push_back('_');
409 Name
= StringRef(Buffer
.data(), Buffer
.size());
415 bool ModuleMap::isBuiltinHeader(FileEntryRef File
) {
416 return File
.getDir() == BuiltinIncludeDir
&& LangOpts
.BuiltinHeadersInSystemModules
&&
417 isBuiltinHeaderName(llvm::sys::path::filename(File
.getName()));
420 bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName
,
421 Module
*Module
) const {
422 return LangOpts
.BuiltinHeadersInSystemModules
&& BuiltinIncludeDir
&&
423 Module
->IsSystem
&& !Module
->isPartOfFramework() &&
424 isBuiltinHeaderName(FileName
);
427 ModuleMap::HeadersMap::iterator
ModuleMap::findKnownHeader(FileEntryRef File
) {
428 resolveHeaderDirectives(File
);
429 HeadersMap::iterator Known
= Headers
.find(File
);
430 if (HeaderInfo
.getHeaderSearchOpts().ImplicitModuleMaps
&&
431 Known
== Headers
.end() && ModuleMap::isBuiltinHeader(File
)) {
432 HeaderInfo
.loadTopLevelSystemModules();
433 return Headers
.find(File
);
438 ModuleMap::KnownHeader
ModuleMap::findHeaderInUmbrellaDirs(
439 FileEntryRef File
, SmallVectorImpl
<DirectoryEntryRef
> &IntermediateDirs
) {
440 if (UmbrellaDirs
.empty())
443 OptionalDirectoryEntryRef Dir
= File
.getDir();
445 // Note: as an egregious but useful hack we use the real path here, because
446 // frameworks moving from top-level frameworks to embedded frameworks tend
447 // to be symlinked from the top-level location to the embedded location,
448 // and we need to resolve lookups as if we had found the embedded location.
449 StringRef DirName
= SourceMgr
.getFileManager().getCanonicalName(*Dir
);
451 // Keep walking up the directory hierarchy, looking for a directory with
452 // an umbrella header.
454 auto KnownDir
= UmbrellaDirs
.find(*Dir
);
455 if (KnownDir
!= UmbrellaDirs
.end())
456 return KnownHeader(KnownDir
->second
, NormalHeader
);
458 IntermediateDirs
.push_back(*Dir
);
460 // Retrieve our parent path.
461 DirName
= llvm::sys::path::parent_path(DirName
);
465 // Resolve the parent path to a directory entry.
466 Dir
= SourceMgr
.getFileManager().getOptionalDirectoryRef(DirName
);
471 static bool violatesPrivateInclude(Module
*RequestingModule
,
472 const FileEntry
*IncFileEnt
,
473 ModuleMap::KnownHeader Header
) {
475 if (Header
.getRole() & ModuleMap::PrivateHeader
) {
476 // Check for consistency between the module header role
477 // as obtained from the lookup and as obtained from the module.
478 // This check is not cheap, so enable it only for debugging.
479 bool IsPrivate
= false;
480 SmallVectorImpl
<Module::Header
> *HeaderList
[] = {
481 &Header
.getModule()->Headers
[Module::HK_Private
],
482 &Header
.getModule()->Headers
[Module::HK_PrivateTextual
]};
483 for (auto *Hs
: HeaderList
)
484 IsPrivate
|= llvm::any_of(
485 *Hs
, [&](const Module::Header
&H
) { return H
.Entry
== IncFileEnt
; });
486 assert(IsPrivate
&& "inconsistent headers and roles");
489 return !Header
.isAccessibleFrom(RequestingModule
);
492 static Module
*getTopLevelOrNull(Module
*M
) {
493 return M
? M
->getTopLevelModule() : nullptr;
496 void ModuleMap::diagnoseHeaderInclusion(Module
*RequestingModule
,
497 bool RequestingModuleIsModuleInterface
,
498 SourceLocation FilenameLoc
,
499 StringRef Filename
, FileEntryRef File
) {
500 // No errors for indirect modules. This may be a bit of a problem for modules
501 // with no source files.
502 if (getTopLevelOrNull(RequestingModule
) != getTopLevelOrNull(SourceModule
))
505 if (RequestingModule
) {
506 resolveUses(RequestingModule
, /*Complain=*/false);
507 resolveHeaderDirectives(RequestingModule
, /*File=*/std::nullopt
);
510 bool Excluded
= false;
511 Module
*Private
= nullptr;
512 Module
*NotUsed
= nullptr;
514 HeadersMap::iterator Known
= findKnownHeader(File
);
515 if (Known
!= Headers
.end()) {
516 for (const KnownHeader
&Header
: Known
->second
) {
517 // Excluded headers don't really belong to a module.
518 if (Header
.getRole() == ModuleMap::ExcludedHeader
) {
523 // Remember private headers for later printing of a diagnostic.
524 if (violatesPrivateInclude(RequestingModule
, File
, Header
)) {
525 Private
= Header
.getModule();
529 // If uses need to be specified explicitly, we are only allowed to return
530 // modules that are explicitly used by the requesting module.
531 if (RequestingModule
&& LangOpts
.ModulesDeclUse
&&
532 !RequestingModule
->directlyUses(Header
.getModule())) {
533 NotUsed
= Header
.getModule();
537 // We have found a module that we can happily use.
544 // We have found a header, but it is private.
546 Diags
.Report(FilenameLoc
, diag::warn_use_of_private_header_outside_module
)
551 // We have found a module, but we don't use it.
553 Diags
.Report(FilenameLoc
, diag::err_undeclared_use_of_module_indirect
)
554 << RequestingModule
->getTopLevelModule()->Name
<< Filename
559 if (Excluded
|| isHeaderInUmbrellaDirs(File
))
562 // At this point, only non-modular includes remain.
564 if (RequestingModule
&& LangOpts
.ModulesStrictDeclUse
) {
565 Diags
.Report(FilenameLoc
, diag::err_undeclared_use_of_module
)
566 << RequestingModule
->getTopLevelModule()->Name
<< Filename
;
567 } else if (RequestingModule
&& RequestingModuleIsModuleInterface
&&
568 LangOpts
.isCompilingModule()) {
569 // Do not diagnose when we are not compiling a module.
570 diag::kind DiagID
= RequestingModule
->getTopLevelModule()->IsFramework
?
571 diag::warn_non_modular_include_in_framework_module
:
572 diag::warn_non_modular_include_in_module
;
573 Diags
.Report(FilenameLoc
, DiagID
) << RequestingModule
->getFullModuleName()
578 static bool isBetterKnownHeader(const ModuleMap::KnownHeader
&New
,
579 const ModuleMap::KnownHeader
&Old
) {
580 // Prefer available modules.
581 // FIXME: Considering whether the module is available rather than merely
582 // importable is non-hermetic and can result in surprising behavior for
583 // prebuilt modules. Consider only checking for importability here.
584 if (New
.getModule()->isAvailable() && !Old
.getModule()->isAvailable())
587 // Prefer a public header over a private header.
588 if ((New
.getRole() & ModuleMap::PrivateHeader
) !=
589 (Old
.getRole() & ModuleMap::PrivateHeader
))
590 return !(New
.getRole() & ModuleMap::PrivateHeader
);
592 // Prefer a non-textual header over a textual header.
593 if ((New
.getRole() & ModuleMap::TextualHeader
) !=
594 (Old
.getRole() & ModuleMap::TextualHeader
))
595 return !(New
.getRole() & ModuleMap::TextualHeader
);
597 // Prefer a non-excluded header over an excluded header.
598 if ((New
.getRole() == ModuleMap::ExcludedHeader
) !=
599 (Old
.getRole() == ModuleMap::ExcludedHeader
))
600 return New
.getRole() != ModuleMap::ExcludedHeader
;
602 // Don't have a reason to choose between these. Just keep the first one.
606 ModuleMap::KnownHeader
ModuleMap::findModuleForHeader(FileEntryRef File
,
608 bool AllowExcluded
) {
609 auto MakeResult
= [&](ModuleMap::KnownHeader R
) -> ModuleMap::KnownHeader
{
610 if (!AllowTextual
&& R
.getRole() & ModuleMap::TextualHeader
)
615 HeadersMap::iterator Known
= findKnownHeader(File
);
616 if (Known
!= Headers
.end()) {
617 ModuleMap::KnownHeader Result
;
618 // Iterate over all modules that 'File' is part of to find the best fit.
619 for (KnownHeader
&H
: Known
->second
) {
620 // Cannot use a module if the header is excluded in it.
621 if (!AllowExcluded
&& H
.getRole() == ModuleMap::ExcludedHeader
)
623 // Prefer a header from the source module over all others.
624 if (H
.getModule()->getTopLevelModule() == SourceModule
)
625 return MakeResult(H
);
626 if (!Result
|| isBetterKnownHeader(H
, Result
))
629 return MakeResult(Result
);
632 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File
));
635 ModuleMap::KnownHeader
636 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File
) {
637 assert(!Headers
.count(File
) && "already have a module for this header");
639 SmallVector
<DirectoryEntryRef
, 2> SkippedDirs
;
640 KnownHeader H
= findHeaderInUmbrellaDirs(File
, SkippedDirs
);
642 Module
*Result
= H
.getModule();
644 // Search up the module stack until we find a module with an umbrella
646 Module
*UmbrellaModule
= Result
;
647 while (!UmbrellaModule
->getEffectiveUmbrellaDir() && UmbrellaModule
->Parent
)
648 UmbrellaModule
= UmbrellaModule
->Parent
;
650 if (UmbrellaModule
->InferSubmodules
) {
651 OptionalFileEntryRef UmbrellaModuleMap
=
652 getModuleMapFileForUniquing(UmbrellaModule
);
654 // Infer submodules for each of the directories we found between
655 // the directory of the umbrella header and the directory where
656 // the actual header is located.
657 bool Explicit
= UmbrellaModule
->InferExplicitSubmodules
;
659 for (DirectoryEntryRef SkippedDir
: llvm::reverse(SkippedDirs
)) {
660 // Find or create the module that corresponds to this directory name.
661 SmallString
<32> NameBuf
;
662 StringRef Name
= sanitizeFilenameAsIdentifier(
663 llvm::sys::path::stem(SkippedDir
.getName()), NameBuf
);
664 Result
= findOrCreateModule(Name
, Result
, /*IsFramework=*/false,
666 InferredModuleAllowedBy
[Result
] = UmbrellaModuleMap
;
667 Result
->IsInferred
= true;
669 // Associate the module and the directory.
670 UmbrellaDirs
[SkippedDir
] = Result
;
672 // If inferred submodules export everything they import, add a
673 // wildcard to the set of exports.
674 if (UmbrellaModule
->InferExportWildcard
&& Result
->Exports
.empty())
675 Result
->Exports
.push_back(Module::ExportDecl(nullptr, true));
678 // Infer a submodule with the same name as this header file.
679 SmallString
<32> NameBuf
;
680 StringRef Name
= sanitizeFilenameAsIdentifier(
681 llvm::sys::path::stem(File
.getName()), NameBuf
);
682 Result
= findOrCreateModule(Name
, Result
, /*IsFramework=*/false,
684 InferredModuleAllowedBy
[Result
] = UmbrellaModuleMap
;
685 Result
->IsInferred
= true;
686 Result
->addTopHeader(File
);
688 // If inferred submodules export everything they import, add a
689 // wildcard to the set of exports.
690 if (UmbrellaModule
->InferExportWildcard
&& Result
->Exports
.empty())
691 Result
->Exports
.push_back(Module::ExportDecl(nullptr, true));
693 // Record each of the directories we stepped through as being part of
694 // the module we found, since the umbrella header covers them all.
695 for (unsigned I
= 0, N
= SkippedDirs
.size(); I
!= N
; ++I
)
696 UmbrellaDirs
[SkippedDirs
[I
]] = Result
;
699 KnownHeader
Header(Result
, NormalHeader
);
700 Headers
[File
].push_back(Header
);
707 ArrayRef
<ModuleMap::KnownHeader
>
708 ModuleMap::findAllModulesForHeader(FileEntryRef File
) {
709 HeadersMap::iterator Known
= findKnownHeader(File
);
710 if (Known
!= Headers
.end())
711 return Known
->second
;
713 if (findOrCreateModuleForHeaderInUmbrellaDir(File
))
714 return Headers
.find(File
)->second
;
719 ArrayRef
<ModuleMap::KnownHeader
>
720 ModuleMap::findResolvedModulesForHeader(FileEntryRef File
) const {
721 // FIXME: Is this necessary?
722 resolveHeaderDirectives(File
);
723 auto It
= Headers
.find(File
);
724 if (It
== Headers
.end())
729 bool ModuleMap::isHeaderInUnavailableModule(FileEntryRef Header
) const {
730 return isHeaderUnavailableInModule(Header
, nullptr);
733 bool ModuleMap::isHeaderUnavailableInModule(
734 FileEntryRef Header
, const Module
*RequestingModule
) const {
735 resolveHeaderDirectives(Header
);
736 HeadersMap::const_iterator Known
= Headers
.find(Header
);
737 if (Known
!= Headers
.end()) {
738 for (SmallVectorImpl
<KnownHeader
>::const_iterator
739 I
= Known
->second
.begin(),
740 E
= Known
->second
.end();
743 if (I
->getRole() == ModuleMap::ExcludedHeader
)
746 if (I
->isAvailable() &&
747 (!RequestingModule
||
748 I
->getModule()->isSubModuleOf(RequestingModule
))) {
749 // When no requesting module is available, the caller is looking if a
750 // header is part a module by only looking into the module map. This is
751 // done by warn_uncovered_module_header checks; don't consider textual
752 // headers part of it in this mode, otherwise we get misleading warnings
753 // that a umbrella header is not including a textual header.
754 if (!RequestingModule
&& I
->getRole() == ModuleMap::TextualHeader
)
762 OptionalDirectoryEntryRef Dir
= Header
.getDir();
763 SmallVector
<DirectoryEntryRef
, 2> SkippedDirs
;
764 StringRef DirName
= Dir
->getName();
766 auto IsUnavailable
= [&](const Module
*M
) {
767 return !M
->isAvailable() && (!RequestingModule
||
768 M
->isSubModuleOf(RequestingModule
));
771 // Keep walking up the directory hierarchy, looking for a directory with
772 // an umbrella header.
774 auto KnownDir
= UmbrellaDirs
.find(*Dir
);
775 if (KnownDir
!= UmbrellaDirs
.end()) {
776 Module
*Found
= KnownDir
->second
;
777 if (IsUnavailable(Found
))
780 // Search up the module stack until we find a module with an umbrella
782 Module
*UmbrellaModule
= Found
;
783 while (!UmbrellaModule
->getEffectiveUmbrellaDir() &&
784 UmbrellaModule
->Parent
)
785 UmbrellaModule
= UmbrellaModule
->Parent
;
787 if (UmbrellaModule
->InferSubmodules
) {
788 for (DirectoryEntryRef SkippedDir
: llvm::reverse(SkippedDirs
)) {
789 // Find or create the module that corresponds to this directory name.
790 SmallString
<32> NameBuf
;
791 StringRef Name
= sanitizeFilenameAsIdentifier(
792 llvm::sys::path::stem(SkippedDir
.getName()), NameBuf
);
793 Found
= lookupModuleQualified(Name
, Found
);
796 if (IsUnavailable(Found
))
800 // Infer a submodule with the same name as this header file.
801 SmallString
<32> NameBuf
;
802 StringRef Name
= sanitizeFilenameAsIdentifier(
803 llvm::sys::path::stem(Header
.getName()),
805 Found
= lookupModuleQualified(Name
, Found
);
810 return IsUnavailable(Found
);
813 SkippedDirs
.push_back(*Dir
);
815 // Retrieve our parent path.
816 DirName
= llvm::sys::path::parent_path(DirName
);
820 // Resolve the parent path to a directory entry.
821 Dir
= SourceMgr
.getFileManager().getOptionalDirectoryRef(DirName
);
827 Module
*ModuleMap::findModule(StringRef Name
) const {
828 llvm::StringMap
<Module
*>::const_iterator Known
= Modules
.find(Name
);
829 if (Known
!= Modules
.end())
830 return Known
->getValue();
835 Module
*ModuleMap::lookupModuleUnqualified(StringRef Name
,
836 Module
*Context
) const {
837 for(; Context
; Context
= Context
->Parent
) {
838 if (Module
*Sub
= lookupModuleQualified(Name
, Context
))
842 return findModule(Name
);
845 Module
*ModuleMap::lookupModuleQualified(StringRef Name
, Module
*Context
) const{
847 return findModule(Name
);
849 return Context
->findSubmodule(Name
);
852 std::pair
<Module
*, bool> ModuleMap::findOrCreateModule(StringRef Name
,
856 // Try to find an existing module with this name.
857 if (Module
*Sub
= lookupModuleQualified(Name
, Parent
))
858 return std::make_pair(Sub
, false);
860 // Create a new module with this name.
861 Module
*Result
= new Module(Name
, SourceLocation(), Parent
, IsFramework
,
862 IsExplicit
, NumCreatedModules
++);
864 if (LangOpts
.CurrentModule
== Name
)
865 SourceModule
= Result
;
866 Modules
[Name
] = Result
;
867 ModuleScopeIDs
[Result
] = CurrentModuleScopeID
;
869 return std::make_pair(Result
, true);
872 Module
*ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc
,
874 auto *Result
= new Module("<global>", Loc
, Parent
, /*IsFramework*/ false,
875 /*IsExplicit*/ true, NumCreatedModules
++);
876 Result
->Kind
= Module::ExplicitGlobalModuleFragment
;
877 // If the created module isn't owned by a parent, send it to PendingSubmodules
878 // to wait for its parent.
880 PendingSubmodules
.emplace_back(Result
);
884 Module
*ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(
885 SourceLocation Loc
, bool IsExported
, Module
*Parent
) {
886 assert(Parent
&& "We should only create an implicit global module fragment "
887 "in a module purview");
888 // Note: Here the `IsExplicit` parameter refers to the semantics in clang
889 // modules. All the non-explicit submodules in clang modules will be exported
890 // too. Here we simplify the implementation by using the concept.
891 auto *Result
= new Module(IsExported
? "<exported implicit global>"
892 : "<implicit global>",
893 Loc
, Parent
, /*IsFramework*/ false,
894 /*IsExplicit*/ !IsExported
, NumCreatedModules
++);
895 Result
->Kind
= Module::ImplicitGlobalModuleFragment
;
900 ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module
*Parent
,
901 SourceLocation Loc
) {
903 new Module("<private>", Loc
, Parent
, /*IsFramework*/ false,
904 /*IsExplicit*/ true, NumCreatedModules
++);
905 Result
->Kind
= Module::PrivateModuleFragment
;
909 Module
*ModuleMap::createModuleUnitWithKind(SourceLocation Loc
, StringRef Name
,
910 Module::ModuleKind Kind
) {
912 new Module(Name
, Loc
, nullptr, /*IsFramework*/ false,
913 /*IsExplicit*/ false, NumCreatedModules
++);
916 // Reparent any current global module fragment as a submodule of this module.
917 for (auto &Submodule
: PendingSubmodules
) {
918 Submodule
->setParent(Result
);
919 Submodule
.release(); // now owned by parent
921 PendingSubmodules
.clear();
925 Module
*ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc
,
927 assert(LangOpts
.CurrentModule
== Name
&& "module name mismatch");
928 assert(!Modules
[Name
] && "redefining existing module");
931 createModuleUnitWithKind(Loc
, Name
, Module::ModuleInterfaceUnit
);
932 Modules
[Name
] = SourceModule
= Result
;
934 // Mark the main source file as being within the newly-created module so that
935 // declarations and macros are properly visibility-restricted to it.
936 auto MainFile
= SourceMgr
.getFileEntryRefForID(SourceMgr
.getMainFileID());
937 assert(MainFile
&& "no input file for module interface");
938 Headers
[*MainFile
].push_back(KnownHeader(Result
, PrivateHeader
));
943 Module
*ModuleMap::createModuleForImplementationUnit(SourceLocation Loc
,
945 assert(LangOpts
.CurrentModule
== Name
&& "module name mismatch");
946 // The interface for this implementation must exist and be loaded.
947 assert(Modules
[Name
] && Modules
[Name
]->Kind
== Module::ModuleInterfaceUnit
&&
948 "creating implementation module without an interface");
950 // Create an entry in the modules map to own the implementation unit module.
951 // User module names must not start with a period (so that this cannot clash
952 // with any legal user-defined module name).
953 StringRef IName
= ".ImplementationUnit";
954 assert(!Modules
[IName
] && "multiple implementation units?");
957 createModuleUnitWithKind(Loc
, Name
, Module::ModuleImplementationUnit
);
958 Modules
[IName
] = SourceModule
= Result
;
960 // Check that the main file is present.
961 assert(SourceMgr
.getFileEntryForID(SourceMgr
.getMainFileID()) &&
962 "no input file for module implementation");
967 Module
*ModuleMap::createHeaderUnit(SourceLocation Loc
, StringRef Name
,
969 assert(LangOpts
.CurrentModule
== Name
&& "module name mismatch");
970 assert(!Modules
[Name
] && "redefining existing module");
972 auto *Result
= new Module(Name
, Loc
, nullptr, /*IsFramework*/ false,
973 /*IsExplicit*/ false, NumCreatedModules
++);
974 Result
->Kind
= Module::ModuleHeaderUnit
;
975 Modules
[Name
] = SourceModule
= Result
;
976 addHeader(Result
, H
, NormalHeader
);
980 /// For a framework module, infer the framework against which we
982 static void inferFrameworkLink(Module
*Mod
) {
983 assert(Mod
->IsFramework
&& "Can only infer linking for framework modules");
984 assert(!Mod
->isSubFramework() &&
985 "Can only infer linking for top-level frameworks");
987 Mod
->LinkLibraries
.push_back(Module::LinkLibrary(Mod
->Name
,
988 /*IsFramework=*/true));
991 Module
*ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir
,
992 bool IsSystem
, Module
*Parent
) {
994 Attrs
.IsSystem
= IsSystem
;
995 return inferFrameworkModule(FrameworkDir
, Attrs
, Parent
);
998 Module
*ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir
,
999 Attributes Attrs
, Module
*Parent
) {
1000 // Note: as an egregious but useful hack we use the real path here, because
1001 // we might be looking at an embedded framework that symlinks out to a
1002 // top-level framework, and we need to infer as if we were naming the
1003 // top-level framework.
1004 StringRef FrameworkDirName
=
1005 SourceMgr
.getFileManager().getCanonicalName(FrameworkDir
);
1007 // In case this is a case-insensitive filesystem, use the canonical
1008 // directory name as the ModuleName, since modules are case-sensitive.
1009 // FIXME: we should be able to give a fix-it hint for the correct spelling.
1010 SmallString
<32> ModuleNameStorage
;
1011 StringRef ModuleName
= sanitizeFilenameAsIdentifier(
1012 llvm::sys::path::stem(FrameworkDirName
), ModuleNameStorage
);
1014 // Check whether we've already found this module.
1015 if (Module
*Mod
= lookupModuleQualified(ModuleName
, Parent
))
1018 FileManager
&FileMgr
= SourceMgr
.getFileManager();
1020 // If the framework has a parent path from which we're allowed to infer
1021 // a framework module, do so.
1022 OptionalFileEntryRef ModuleMapFile
;
1024 // Determine whether we're allowed to infer a module map.
1025 bool canInfer
= false;
1026 if (llvm::sys::path::has_parent_path(FrameworkDirName
)) {
1027 // Figure out the parent path.
1028 StringRef Parent
= llvm::sys::path::parent_path(FrameworkDirName
);
1029 if (auto ParentDir
= FileMgr
.getOptionalDirectoryRef(Parent
)) {
1030 // Check whether we have already looked into the parent directory
1031 // for a module map.
1032 llvm::DenseMap
<const DirectoryEntry
*, InferredDirectory
>::const_iterator
1033 inferred
= InferredDirectories
.find(*ParentDir
);
1034 if (inferred
== InferredDirectories
.end()) {
1035 // We haven't looked here before. Load a module map, if there is
1037 bool IsFrameworkDir
= Parent
.endswith(".framework");
1038 if (OptionalFileEntryRef ModMapFile
=
1039 HeaderInfo
.lookupModuleMapFile(*ParentDir
, IsFrameworkDir
)) {
1040 parseModuleMapFile(*ModMapFile
, Attrs
.IsSystem
, *ParentDir
);
1041 inferred
= InferredDirectories
.find(*ParentDir
);
1044 if (inferred
== InferredDirectories
.end())
1045 inferred
= InferredDirectories
.insert(
1046 std::make_pair(*ParentDir
, InferredDirectory())).first
;
1049 if (inferred
->second
.InferModules
) {
1050 // We're allowed to infer for this directory, but make sure it's okay
1051 // to infer this particular module.
1052 StringRef Name
= llvm::sys::path::stem(FrameworkDirName
);
1054 !llvm::is_contained(inferred
->second
.ExcludedModules
, Name
);
1056 Attrs
.IsSystem
|= inferred
->second
.Attrs
.IsSystem
;
1057 Attrs
.IsExternC
|= inferred
->second
.Attrs
.IsExternC
;
1058 Attrs
.IsExhaustive
|= inferred
->second
.Attrs
.IsExhaustive
;
1059 Attrs
.NoUndeclaredIncludes
|=
1060 inferred
->second
.Attrs
.NoUndeclaredIncludes
;
1061 ModuleMapFile
= inferred
->second
.ModuleMapFile
;
1066 // If we're not allowed to infer a framework module, don't.
1070 OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef
=
1071 getModuleMapFileForUniquing(Parent
);
1072 ModuleMapFile
= ModuleMapRef
;
1075 // Look for an umbrella header.
1076 SmallString
<128> UmbrellaName
= FrameworkDir
.getName();
1077 llvm::sys::path::append(UmbrellaName
, "Headers", ModuleName
+ ".h");
1078 auto UmbrellaHeader
= FileMgr
.getOptionalFileRef(UmbrellaName
);
1080 // FIXME: If there's no umbrella header, we could probably scan the
1081 // framework to load *everything*. But, it's not clear that this is a good
1083 if (!UmbrellaHeader
)
1086 Module
*Result
= new Module(ModuleName
, SourceLocation(), Parent
,
1087 /*IsFramework=*/true, /*IsExplicit=*/false,
1088 NumCreatedModules
++);
1089 InferredModuleAllowedBy
[Result
] = ModuleMapFile
;
1090 Result
->IsInferred
= true;
1092 if (LangOpts
.CurrentModule
== ModuleName
)
1093 SourceModule
= Result
;
1094 Modules
[ModuleName
] = Result
;
1095 ModuleScopeIDs
[Result
] = CurrentModuleScopeID
;
1098 Result
->IsSystem
|= Attrs
.IsSystem
;
1099 Result
->IsExternC
|= Attrs
.IsExternC
;
1100 Result
->ConfigMacrosExhaustive
|= Attrs
.IsExhaustive
;
1101 Result
->NoUndeclaredIncludes
|= Attrs
.NoUndeclaredIncludes
;
1102 Result
->Directory
= FrameworkDir
;
1104 // Chop off the first framework bit, as that is implied.
1105 StringRef RelativePath
= UmbrellaName
.str().substr(
1106 Result
->getTopLevelModule()->Directory
->getName().size());
1107 RelativePath
= llvm::sys::path::relative_path(RelativePath
);
1109 // umbrella header "umbrella-header-name"
1110 setUmbrellaHeaderAsWritten(Result
, *UmbrellaHeader
, ModuleName
+ ".h",
1114 Result
->Exports
.push_back(Module::ExportDecl(nullptr, true));
1116 // module * { export * }
1117 Result
->InferSubmodules
= true;
1118 Result
->InferExportWildcard
= true;
1120 // Look for subframeworks.
1122 SmallString
<128> SubframeworksDirName
= FrameworkDir
.getName();
1123 llvm::sys::path::append(SubframeworksDirName
, "Frameworks");
1124 llvm::sys::path::native(SubframeworksDirName
);
1125 llvm::vfs::FileSystem
&FS
= FileMgr
.getVirtualFileSystem();
1126 for (llvm::vfs::directory_iterator
1127 Dir
= FS
.dir_begin(SubframeworksDirName
, EC
),
1129 Dir
!= DirEnd
&& !EC
; Dir
.increment(EC
)) {
1130 if (!StringRef(Dir
->path()).endswith(".framework"))
1133 if (auto SubframeworkDir
= FileMgr
.getOptionalDirectoryRef(Dir
->path())) {
1134 // Note: as an egregious but useful hack, we use the real path here and
1135 // check whether it is actually a subdirectory of the parent directory.
1136 // This will not be the case if the 'subframework' is actually a symlink
1137 // out to a top-level framework.
1138 StringRef SubframeworkDirName
=
1139 FileMgr
.getCanonicalName(*SubframeworkDir
);
1140 bool FoundParent
= false;
1142 // Get the parent directory name.
1144 = llvm::sys::path::parent_path(SubframeworkDirName
);
1145 if (SubframeworkDirName
.empty())
1148 if (auto SubDir
= FileMgr
.getDirectory(SubframeworkDirName
)) {
1149 if (*SubDir
== FrameworkDir
) {
1159 // FIXME: Do we want to warn about subframeworks without umbrella headers?
1160 inferFrameworkModule(*SubframeworkDir
, Attrs
, Result
);
1164 // If the module is a top-level framework, automatically link against the
1166 if (!Result
->isSubFramework())
1167 inferFrameworkLink(Result
);
1172 Module
*ModuleMap::createShadowedModule(StringRef Name
, bool IsFramework
,
1173 Module
*ShadowingModule
) {
1175 // Create a new module with this name.
1177 new Module(Name
, SourceLocation(), /*Parent=*/nullptr, IsFramework
,
1178 /*IsExplicit=*/false, NumCreatedModules
++);
1179 Result
->ShadowingModule
= ShadowingModule
;
1180 Result
->markUnavailable(/*Unimportable*/true);
1181 ModuleScopeIDs
[Result
] = CurrentModuleScopeID
;
1182 ShadowModules
.push_back(Result
);
1187 void ModuleMap::setUmbrellaHeaderAsWritten(
1188 Module
*Mod
, FileEntryRef UmbrellaHeader
, const Twine
&NameAsWritten
,
1189 const Twine
&PathRelativeToRootModuleDirectory
) {
1190 Headers
[UmbrellaHeader
].push_back(KnownHeader(Mod
, NormalHeader
));
1191 Mod
->Umbrella
= UmbrellaHeader
;
1192 Mod
->UmbrellaAsWritten
= NameAsWritten
.str();
1193 Mod
->UmbrellaRelativeToRootModuleDirectory
=
1194 PathRelativeToRootModuleDirectory
.str();
1195 UmbrellaDirs
[UmbrellaHeader
.getDir()] = Mod
;
1197 // Notify callbacks that we just added a new header.
1198 for (const auto &Cb
: Callbacks
)
1199 Cb
->moduleMapAddUmbrellaHeader(UmbrellaHeader
);
1202 void ModuleMap::setUmbrellaDirAsWritten(
1203 Module
*Mod
, DirectoryEntryRef UmbrellaDir
, const Twine
&NameAsWritten
,
1204 const Twine
&PathRelativeToRootModuleDirectory
) {
1205 Mod
->Umbrella
= UmbrellaDir
;
1206 Mod
->UmbrellaAsWritten
= NameAsWritten
.str();
1207 Mod
->UmbrellaRelativeToRootModuleDirectory
=
1208 PathRelativeToRootModuleDirectory
.str();
1209 UmbrellaDirs
[UmbrellaDir
] = Mod
;
1212 void ModuleMap::addUnresolvedHeader(Module
*Mod
,
1213 Module::UnresolvedHeaderDirective Header
,
1214 bool &NeedsFramework
) {
1215 // If there is a builtin counterpart to this file, add it now so it can
1216 // wrap the system header.
1217 if (resolveAsBuiltinHeader(Mod
, Header
)) {
1218 // If we have both a builtin and system version of the file, the
1219 // builtin version may want to inject macros into the system header, so
1220 // force the system header to be treated as a textual header in this
1222 Header
.Kind
= headerRoleToKind(ModuleMap::ModuleHeaderRole(
1223 headerKindToRole(Header
.Kind
) | ModuleMap::TextualHeader
));
1224 Header
.HasBuiltinHeader
= true;
1227 // If possible, don't stat the header until we need to. This requires the
1228 // user to have provided us with some stat information about the file.
1229 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1231 if ((Header
.Size
|| Header
.ModTime
) && !Header
.IsUmbrella
&&
1232 Header
.Kind
!= Module::HK_Excluded
) {
1233 // We expect more variation in mtime than size, so if we're given both,
1234 // use the mtime as the key.
1236 LazyHeadersByModTime
[*Header
.ModTime
].push_back(Mod
);
1238 LazyHeadersBySize
[*Header
.Size
].push_back(Mod
);
1239 Mod
->UnresolvedHeaders
.push_back(Header
);
1243 // We don't have stat information or can't defer looking this file up.
1244 // Perform the lookup now.
1245 resolveHeader(Mod
, Header
, NeedsFramework
);
1248 void ModuleMap::resolveHeaderDirectives(const FileEntry
*File
) const {
1249 auto BySize
= LazyHeadersBySize
.find(File
->getSize());
1250 if (BySize
!= LazyHeadersBySize
.end()) {
1251 for (auto *M
: BySize
->second
)
1252 resolveHeaderDirectives(M
, File
);
1253 LazyHeadersBySize
.erase(BySize
);
1256 auto ByModTime
= LazyHeadersByModTime
.find(File
->getModificationTime());
1257 if (ByModTime
!= LazyHeadersByModTime
.end()) {
1258 for (auto *M
: ByModTime
->second
)
1259 resolveHeaderDirectives(M
, File
);
1260 LazyHeadersByModTime
.erase(ByModTime
);
1264 void ModuleMap::resolveHeaderDirectives(
1265 Module
*Mod
, std::optional
<const FileEntry
*> File
) const {
1266 bool NeedsFramework
= false;
1267 SmallVector
<Module::UnresolvedHeaderDirective
, 1> NewHeaders
;
1268 const auto Size
= File
? (*File
)->getSize() : 0;
1269 const auto ModTime
= File
? (*File
)->getModificationTime() : 0;
1271 for (auto &Header
: Mod
->UnresolvedHeaders
) {
1272 if (File
&& ((Header
.ModTime
&& Header
.ModTime
!= ModTime
) ||
1273 (Header
.Size
&& Header
.Size
!= Size
)))
1274 NewHeaders
.push_back(Header
);
1276 // This operation is logically const; we're just changing how we represent
1277 // the header information for this file.
1278 const_cast<ModuleMap
*>(this)->resolveHeader(Mod
, Header
, NeedsFramework
);
1280 Mod
->UnresolvedHeaders
.swap(NewHeaders
);
1283 void ModuleMap::addHeader(Module
*Mod
, Module::Header Header
,
1284 ModuleHeaderRole Role
, bool Imported
) {
1285 KnownHeader
KH(Mod
, Role
);
1287 // Only add each header to the headers list once.
1288 // FIXME: Should we diagnose if a header is listed twice in the
1289 // same module definition?
1290 auto &HeaderList
= Headers
[Header
.Entry
];
1291 if (llvm::is_contained(HeaderList
, KH
))
1294 HeaderList
.push_back(KH
);
1295 Mod
->Headers
[headerRoleToKind(Role
)].push_back(Header
);
1297 bool isCompilingModuleHeader
= Mod
->isForBuilding(LangOpts
);
1298 if (!Imported
|| isCompilingModuleHeader
) {
1299 // When we import HeaderFileInfo, the external source is expected to
1300 // set the isModuleHeader flag itself.
1301 HeaderInfo
.MarkFileModuleHeader(Header
.Entry
, Role
,
1302 isCompilingModuleHeader
);
1305 // Notify callbacks that we just added a new header.
1306 for (const auto &Cb
: Callbacks
)
1307 Cb
->moduleMapAddHeader(Header
.Entry
.getName());
1310 OptionalFileEntryRef
1311 ModuleMap::getContainingModuleMapFile(const Module
*Module
) const {
1312 if (Module
->DefinitionLoc
.isInvalid())
1313 return std::nullopt
;
1315 return SourceMgr
.getFileEntryRefForID(
1316 SourceMgr
.getFileID(Module
->DefinitionLoc
));
1319 OptionalFileEntryRef
1320 ModuleMap::getModuleMapFileForUniquing(const Module
*M
) const {
1321 if (M
->IsInferred
) {
1322 assert(InferredModuleAllowedBy
.count(M
) && "missing inferred module map");
1323 return InferredModuleAllowedBy
.find(M
)->second
;
1325 return getContainingModuleMapFile(M
);
1328 void ModuleMap::setInferredModuleAllowedBy(Module
*M
,
1329 OptionalFileEntryRef ModMap
) {
1330 assert(M
->IsInferred
&& "module not inferred");
1331 InferredModuleAllowedBy
[M
] = ModMap
;
1335 ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl
<char> &Path
) {
1336 StringRef Dir
= llvm::sys::path::parent_path({Path
.data(), Path
.size()});
1338 // Do not canonicalize within the framework; the module map parser expects
1339 // Modules/ not Versions/A/Modules.
1340 if (llvm::sys::path::filename(Dir
) == "Modules") {
1341 StringRef Parent
= llvm::sys::path::parent_path(Dir
);
1342 if (Parent
.endswith(".framework"))
1346 FileManager
&FM
= SourceMgr
.getFileManager();
1347 auto DirEntry
= FM
.getDirectoryRef(Dir
.empty() ? "." : Dir
);
1349 return llvm::errorToErrorCode(DirEntry
.takeError());
1351 // Canonicalize the directory.
1352 StringRef CanonicalDir
= FM
.getCanonicalName(*DirEntry
);
1353 if (CanonicalDir
!= Dir
)
1354 llvm::sys::path::replace_path_prefix(Path
, Dir
, CanonicalDir
);
1356 // In theory, the filename component should also be canonicalized if it
1357 // on a case-insensitive filesystem. However, the extra canonicalization is
1358 // expensive and if clang looked up the filename it will always be lowercase.
1360 // Remove ., remove redundant separators, and switch to native separators.
1361 // This is needed for separators between CanonicalDir and the filename.
1362 llvm::sys::path::remove_dots(Path
);
1364 return std::error_code();
1367 void ModuleMap::addAdditionalModuleMapFile(const Module
*M
,
1368 FileEntryRef ModuleMap
) {
1369 AdditionalModMaps
[M
].insert(ModuleMap
);
1372 LLVM_DUMP_METHOD
void ModuleMap::dump() {
1373 llvm::errs() << "Modules:";
1374 for (llvm::StringMap
<Module
*>::iterator M
= Modules
.begin(),
1375 MEnd
= Modules
.end();
1377 M
->getValue()->print(llvm::errs(), 2);
1379 llvm::errs() << "Headers:";
1380 for (HeadersMap::iterator H
= Headers
.begin(), HEnd
= Headers
.end();
1382 llvm::errs() << " \"" << H
->first
.getName() << "\" -> ";
1383 for (SmallVectorImpl
<KnownHeader
>::const_iterator I
= H
->second
.begin(),
1384 E
= H
->second
.end();
1386 if (I
!= H
->second
.begin())
1387 llvm::errs() << ",";
1388 llvm::errs() << I
->getModule()->getFullModuleName();
1390 llvm::errs() << "\n";
1394 bool ModuleMap::resolveExports(Module
*Mod
, bool Complain
) {
1395 auto Unresolved
= std::move(Mod
->UnresolvedExports
);
1396 Mod
->UnresolvedExports
.clear();
1397 for (auto &UE
: Unresolved
) {
1398 Module::ExportDecl Export
= resolveExport(Mod
, UE
, Complain
);
1399 if (Export
.getPointer() || Export
.getInt())
1400 Mod
->Exports
.push_back(Export
);
1402 Mod
->UnresolvedExports
.push_back(UE
);
1404 return !Mod
->UnresolvedExports
.empty();
1407 bool ModuleMap::resolveUses(Module
*Mod
, bool Complain
) {
1408 auto *Top
= Mod
->getTopLevelModule();
1409 auto Unresolved
= std::move(Top
->UnresolvedDirectUses
);
1410 Top
->UnresolvedDirectUses
.clear();
1411 for (auto &UDU
: Unresolved
) {
1412 Module
*DirectUse
= resolveModuleId(UDU
, Top
, Complain
);
1414 Top
->DirectUses
.push_back(DirectUse
);
1416 Top
->UnresolvedDirectUses
.push_back(UDU
);
1418 return !Top
->UnresolvedDirectUses
.empty();
1421 bool ModuleMap::resolveConflicts(Module
*Mod
, bool Complain
) {
1422 auto Unresolved
= std::move(Mod
->UnresolvedConflicts
);
1423 Mod
->UnresolvedConflicts
.clear();
1424 for (auto &UC
: Unresolved
) {
1425 if (Module
*OtherMod
= resolveModuleId(UC
.Id
, Mod
, Complain
)) {
1426 Module::Conflict Conflict
;
1427 Conflict
.Other
= OtherMod
;
1428 Conflict
.Message
= UC
.Message
;
1429 Mod
->Conflicts
.push_back(Conflict
);
1431 Mod
->UnresolvedConflicts
.push_back(UC
);
1433 return !Mod
->UnresolvedConflicts
.empty();
1436 //----------------------------------------------------------------------------//
1437 // Module map file parser
1438 //----------------------------------------------------------------------------//
1442 /// A token in a module map file.
1475 SourceLocation::UIntTy Location
;
1476 unsigned StringLength
;
1478 // If Kind != IntegerLiteral.
1479 const char *StringData
;
1481 // If Kind == IntegerLiteral.
1482 uint64_t IntegerValue
;
1489 StringData
= nullptr;
1492 bool is(TokenKind K
) const { return Kind
== K
; }
1494 SourceLocation
getLocation() const {
1495 return SourceLocation::getFromRawEncoding(Location
);
1498 uint64_t getInteger() const {
1499 return Kind
== IntegerLiteral
? IntegerValue
: 0;
1502 StringRef
getString() const {
1503 return Kind
== IntegerLiteral
? StringRef()
1504 : StringRef(StringData
, StringLength
);
1508 class ModuleMapParser
{
1510 SourceManager
&SourceMgr
;
1512 /// Default target information, used only for string literal
1514 const TargetInfo
*Target
;
1516 DiagnosticsEngine
&Diags
;
1519 /// The current module map file.
1520 FileEntryRef ModuleMapFile
;
1522 /// Source location of most recent parsed module declaration
1523 SourceLocation CurrModuleDeclLoc
;
1525 /// The directory that file names in this module map file should
1526 /// be resolved relative to.
1527 DirectoryEntryRef Directory
;
1529 /// Whether this module map is in a system header directory.
1532 /// Whether an error occurred.
1533 bool HadError
= false;
1535 /// Stores string data for the various string literals referenced
1537 llvm::BumpPtrAllocator StringData
;
1539 /// The current token.
1542 /// The active module.
1543 Module
*ActiveModule
= nullptr;
1545 /// Whether a module uses the 'requires excluded' hack to mark its
1546 /// contents as 'textual'.
1548 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1549 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1550 /// non-modular headers. For backwards compatibility, we continue to
1551 /// support this idiom for just these modules, and map the headers to
1552 /// 'textual' to match the original intent.
1553 llvm::SmallPtrSet
<Module
*, 2> UsesRequiresExcludedHack
;
1555 /// Consume the current token and return its location.
1556 SourceLocation
consumeToken();
1558 /// Skip tokens until we reach the a token with the given kind
1559 /// (or the end of the file).
1560 void skipUntil(MMToken::TokenKind K
);
1562 bool parseModuleId(ModuleId
&Id
);
1563 void parseModuleDecl();
1564 void parseExternModuleDecl();
1565 void parseRequiresDecl();
1566 void parseHeaderDecl(MMToken::TokenKind
, SourceLocation LeadingLoc
);
1567 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc
);
1568 void parseExportDecl();
1569 void parseExportAsDecl();
1570 void parseUseDecl();
1571 void parseLinkDecl();
1572 void parseConfigMacros();
1573 void parseConflict();
1574 void parseInferredModuleDecl(bool Framework
, bool Explicit
);
1576 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1577 /// module map search logic to find the appropriate private module when PCH
1578 /// is used with implicit module maps. Warn when private modules are written
1579 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1580 void diagnosePrivateModules(SourceLocation ExplicitLoc
,
1581 SourceLocation FrameworkLoc
);
1583 using Attributes
= ModuleMap::Attributes
;
1585 bool parseOptionalAttributes(Attributes
&Attrs
);
1588 explicit ModuleMapParser(Lexer
&L
, SourceManager
&SourceMgr
,
1589 const TargetInfo
*Target
, DiagnosticsEngine
&Diags
,
1590 ModuleMap
&Map
, FileEntryRef ModuleMapFile
,
1591 DirectoryEntryRef Directory
, bool IsSystem
)
1592 : L(L
), SourceMgr(SourceMgr
), Target(Target
), Diags(Diags
), Map(Map
),
1593 ModuleMapFile(ModuleMapFile
), Directory(Directory
),
1594 IsSystem(IsSystem
) {
1599 bool parseModuleMapFile();
1601 bool terminatedByDirective() { return false; }
1602 SourceLocation
getLocation() { return Tok
.getLocation(); }
1605 } // namespace clang
1607 SourceLocation
ModuleMapParser::consumeToken() {
1608 SourceLocation Result
= Tok
.getLocation();
1613 L
.LexFromRawLexer(LToken
);
1614 Tok
.Location
= LToken
.getLocation().getRawEncoding();
1615 switch (LToken
.getKind()) {
1616 case tok::raw_identifier
: {
1617 StringRef RI
= LToken
.getRawIdentifier();
1618 Tok
.StringData
= RI
.data();
1619 Tok
.StringLength
= RI
.size();
1620 Tok
.Kind
= llvm::StringSwitch
<MMToken::TokenKind
>(RI
)
1621 .Case("config_macros", MMToken::ConfigMacros
)
1622 .Case("conflict", MMToken::Conflict
)
1623 .Case("exclude", MMToken::ExcludeKeyword
)
1624 .Case("explicit", MMToken::ExplicitKeyword
)
1625 .Case("export", MMToken::ExportKeyword
)
1626 .Case("export_as", MMToken::ExportAsKeyword
)
1627 .Case("extern", MMToken::ExternKeyword
)
1628 .Case("framework", MMToken::FrameworkKeyword
)
1629 .Case("header", MMToken::HeaderKeyword
)
1630 .Case("link", MMToken::LinkKeyword
)
1631 .Case("module", MMToken::ModuleKeyword
)
1632 .Case("private", MMToken::PrivateKeyword
)
1633 .Case("requires", MMToken::RequiresKeyword
)
1634 .Case("textual", MMToken::TextualKeyword
)
1635 .Case("umbrella", MMToken::UmbrellaKeyword
)
1636 .Case("use", MMToken::UseKeyword
)
1637 .Default(MMToken::Identifier
);
1642 Tok
.Kind
= MMToken::Comma
;
1646 Tok
.Kind
= MMToken::EndOfFile
;
1650 Tok
.Kind
= MMToken::LBrace
;
1654 Tok
.Kind
= MMToken::LSquare
;
1658 Tok
.Kind
= MMToken::Period
;
1662 Tok
.Kind
= MMToken::RBrace
;
1666 Tok
.Kind
= MMToken::RSquare
;
1670 Tok
.Kind
= MMToken::Star
;
1674 Tok
.Kind
= MMToken::Exclaim
;
1677 case tok::string_literal
: {
1678 if (LToken
.hasUDSuffix()) {
1679 Diags
.Report(LToken
.getLocation(), diag::err_invalid_string_udl
);
1684 // Parse the string literal.
1685 LangOptions LangOpts
;
1686 StringLiteralParser
StringLiteral(LToken
, SourceMgr
, LangOpts
, *Target
);
1687 if (StringLiteral
.hadError
)
1690 // Copy the string literal into our string data allocator.
1691 unsigned Length
= StringLiteral
.GetStringLength();
1692 char *Saved
= StringData
.Allocate
<char>(Length
+ 1);
1693 memcpy(Saved
, StringLiteral
.GetString().data(), Length
);
1697 Tok
.Kind
= MMToken::StringLiteral
;
1698 Tok
.StringData
= Saved
;
1699 Tok
.StringLength
= Length
;
1703 case tok::numeric_constant
: {
1704 // We don't support any suffixes or other complications.
1705 SmallString
<32> SpellingBuffer
;
1706 SpellingBuffer
.resize(LToken
.getLength() + 1);
1707 const char *Start
= SpellingBuffer
.data();
1709 Lexer::getSpelling(LToken
, Start
, SourceMgr
, Map
.LangOpts
);
1711 if (StringRef(Start
, Length
).getAsInteger(0, Value
)) {
1712 Diags
.Report(Tok
.getLocation(), diag::err_mmap_unknown_token
);
1717 Tok
.Kind
= MMToken::IntegerLiteral
;
1718 Tok
.IntegerValue
= Value
;
1726 // A module map can be terminated prematurely by
1727 // #pragma clang module contents
1728 // When building the module, we'll treat the rest of the file as the
1729 // contents of the module.
1731 auto NextIsIdent
= [&](StringRef Str
) -> bool {
1732 L
.LexFromRawLexer(LToken
);
1733 return !LToken
.isAtStartOfLine() && LToken
.is(tok::raw_identifier
) &&
1734 LToken
.getRawIdentifier() == Str
;
1736 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1737 NextIsIdent("module") && NextIsIdent("contents")) {
1738 Tok
.Kind
= MMToken::EndOfFile
;
1745 Diags
.Report(Tok
.getLocation(), diag::err_mmap_unknown_token
);
1753 void ModuleMapParser::skipUntil(MMToken::TokenKind K
) {
1754 unsigned braceDepth
= 0;
1755 unsigned squareDepth
= 0;
1758 case MMToken::EndOfFile
:
1761 case MMToken::LBrace
:
1762 if (Tok
.is(K
) && braceDepth
== 0 && squareDepth
== 0)
1768 case MMToken::LSquare
:
1769 if (Tok
.is(K
) && braceDepth
== 0 && squareDepth
== 0)
1775 case MMToken::RBrace
:
1782 case MMToken::RSquare
:
1783 if (squareDepth
> 0)
1790 if (braceDepth
== 0 && squareDepth
== 0 && Tok
.is(K
))
1799 /// Parse a module-id.
1803 /// identifier '.' module-id
1805 /// \returns true if an error occurred, false otherwise.
1806 bool ModuleMapParser::parseModuleId(ModuleId
&Id
) {
1809 if (Tok
.is(MMToken::Identifier
) || Tok
.is(MMToken::StringLiteral
)) {
1811 std::make_pair(std::string(Tok
.getString()), Tok
.getLocation()));
1814 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_module_name
);
1818 if (!Tok
.is(MMToken::Period
))
1829 /// Enumerates the known attributes.
1830 enum AttributeKind
{
1831 /// An unknown attribute.
1834 /// The 'system' attribute.
1837 /// The 'extern_c' attribute.
1840 /// The 'exhaustive' attribute.
1843 /// The 'no_undeclared_includes' attribute.
1844 AT_no_undeclared_includes
1849 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1850 /// module map search logic to find the appropriate private module when PCH
1851 /// is used with implicit module maps. Warn when private modules are written
1852 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1853 void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc
,
1854 SourceLocation FrameworkLoc
) {
1855 auto GenNoteAndFixIt
= [&](StringRef BadName
, StringRef Canonical
,
1856 const Module
*M
, SourceRange ReplLoc
) {
1857 auto D
= Diags
.Report(ActiveModule
->DefinitionLoc
,
1858 diag::note_mmap_rename_top_level_private_module
);
1859 D
<< BadName
<< M
->Name
;
1860 D
<< FixItHint::CreateReplacement(ReplLoc
, Canonical
);
1863 for (auto E
= Map
.module_begin(); E
!= Map
.module_end(); ++E
) {
1864 auto const *M
= E
->getValue();
1865 if (M
->Directory
!= ActiveModule
->Directory
)
1868 SmallString
<128> FullName(ActiveModule
->getFullModuleName());
1869 if (!FullName
.startswith(M
->Name
) && !FullName
.endswith("Private"))
1871 SmallString
<128> FixedPrivModDecl
;
1872 SmallString
<128> Canonical(M
->Name
);
1873 Canonical
.append("_Private");
1875 // Foo.Private -> Foo_Private
1876 if (ActiveModule
->Parent
&& ActiveModule
->Name
== "Private" && !M
->Parent
&&
1877 M
->Name
== ActiveModule
->Parent
->Name
) {
1878 Diags
.Report(ActiveModule
->DefinitionLoc
,
1879 diag::warn_mmap_mismatched_private_submodule
)
1882 SourceLocation FixItInitBegin
= CurrModuleDeclLoc
;
1883 if (FrameworkLoc
.isValid())
1884 FixItInitBegin
= FrameworkLoc
;
1885 if (ExplicitLoc
.isValid())
1886 FixItInitBegin
= ExplicitLoc
;
1888 if (FrameworkLoc
.isValid() || ActiveModule
->Parent
->IsFramework
)
1889 FixedPrivModDecl
.append("framework ");
1890 FixedPrivModDecl
.append("module ");
1891 FixedPrivModDecl
.append(Canonical
);
1893 GenNoteAndFixIt(FullName
, FixedPrivModDecl
, M
,
1894 SourceRange(FixItInitBegin
, ActiveModule
->DefinitionLoc
));
1898 // FooPrivate and whatnots -> Foo_Private
1899 if (!ActiveModule
->Parent
&& !M
->Parent
&& M
->Name
!= ActiveModule
->Name
&&
1900 ActiveModule
->Name
!= Canonical
) {
1901 Diags
.Report(ActiveModule
->DefinitionLoc
,
1902 diag::warn_mmap_mismatched_private_module_name
)
1903 << ActiveModule
->Name
;
1904 GenNoteAndFixIt(ActiveModule
->Name
, Canonical
, M
,
1905 SourceRange(ActiveModule
->DefinitionLoc
));
1910 /// Parse a module declaration.
1912 /// module-declaration:
1913 /// 'extern' 'module' module-id string-literal
1914 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1915 /// { module-member* }
1918 /// requires-declaration
1919 /// header-declaration
1920 /// submodule-declaration
1921 /// export-declaration
1922 /// export-as-declaration
1923 /// link-declaration
1925 /// submodule-declaration:
1926 /// module-declaration
1927 /// inferred-submodule-declaration
1928 void ModuleMapParser::parseModuleDecl() {
1929 assert(Tok
.is(MMToken::ExplicitKeyword
) || Tok
.is(MMToken::ModuleKeyword
) ||
1930 Tok
.is(MMToken::FrameworkKeyword
) || Tok
.is(MMToken::ExternKeyword
));
1931 if (Tok
.is(MMToken::ExternKeyword
)) {
1932 parseExternModuleDecl();
1936 // Parse 'explicit' or 'framework' keyword, if present.
1937 SourceLocation ExplicitLoc
;
1938 SourceLocation FrameworkLoc
;
1939 bool Explicit
= false;
1940 bool Framework
= false;
1942 // Parse 'explicit' keyword, if present.
1943 if (Tok
.is(MMToken::ExplicitKeyword
)) {
1944 ExplicitLoc
= consumeToken();
1948 // Parse 'framework' keyword, if present.
1949 if (Tok
.is(MMToken::FrameworkKeyword
)) {
1950 FrameworkLoc
= consumeToken();
1954 // Parse 'module' keyword.
1955 if (!Tok
.is(MMToken::ModuleKeyword
)) {
1956 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_module
);
1961 CurrModuleDeclLoc
= consumeToken(); // 'module' keyword
1963 // If we have a wildcard for the module name, this is an inferred submodule.
1965 if (Tok
.is(MMToken::Star
))
1966 return parseInferredModuleDecl(Framework
, Explicit
);
1968 // Parse the module name.
1970 if (parseModuleId(Id
)) {
1976 if (Id
.size() > 1) {
1977 Diags
.Report(Id
.front().second
, diag::err_mmap_nested_submodule_id
)
1978 << SourceRange(Id
.front().second
, Id
.back().second
);
1983 } else if (Id
.size() == 1 && Explicit
) {
1984 // Top-level modules can't be explicit.
1985 Diags
.Report(ExplicitLoc
, diag::err_mmap_explicit_top_level
);
1987 ExplicitLoc
= SourceLocation();
1991 Module
*PreviousActiveModule
= ActiveModule
;
1992 if (Id
.size() > 1) {
1993 // This module map defines a submodule. Go find the module of which it
1995 ActiveModule
= nullptr;
1996 const Module
*TopLevelModule
= nullptr;
1997 for (unsigned I
= 0, N
= Id
.size() - 1; I
!= N
; ++I
) {
1998 if (Module
*Next
= Map
.lookupModuleQualified(Id
[I
].first
, ActiveModule
)) {
2000 TopLevelModule
= Next
;
2001 ActiveModule
= Next
;
2005 Diags
.Report(Id
[I
].second
, diag::err_mmap_missing_parent_module
)
2006 << Id
[I
].first
<< (ActiveModule
!= nullptr)
2008 ? ActiveModule
->getTopLevelModule()->getFullModuleName()
2013 if (TopLevelModule
&&
2014 ModuleMapFile
!= Map
.getContainingModuleMapFile(TopLevelModule
)) {
2015 assert(ModuleMapFile
!= Map
.getModuleMapFileForUniquing(TopLevelModule
) &&
2016 "submodule defined in same file as 'module *' that allowed its "
2017 "top-level module");
2018 Map
.addAdditionalModuleMapFile(TopLevelModule
, ModuleMapFile
);
2022 StringRef ModuleName
= Id
.back().first
;
2023 SourceLocation ModuleNameLoc
= Id
.back().second
;
2025 // Parse the optional attribute list.
2027 if (parseOptionalAttributes(Attrs
))
2030 // Parse the opening brace.
2031 if (!Tok
.is(MMToken::LBrace
)) {
2032 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_lbrace
)
2037 SourceLocation LBraceLoc
= consumeToken();
2039 // Determine whether this (sub)module has already been defined.
2040 Module
*ShadowingModule
= nullptr;
2041 if (Module
*Existing
= Map
.lookupModuleQualified(ModuleName
, ActiveModule
)) {
2042 // We might see a (re)definition of a module that we already have a
2043 // definition for in four cases:
2044 // - If we loaded one definition from an AST file and we've just found a
2045 // corresponding definition in a module map file, or
2046 bool LoadedFromASTFile
= Existing
->IsFromModuleFile
;
2047 // - If we previously inferred this module from different module map file.
2048 bool Inferred
= Existing
->IsInferred
;
2049 // - If we're building a framework that vends a module map, we might've
2050 // previously seen the one in intermediate products and now the system
2052 // FIXME: If we're parsing module map file that looks like this:
2053 // framework module FW { ... }
2054 // module FW.Sub { ... }
2055 // We can't check the framework qualifier, since it's not attached to
2056 // the definition of Sub. Checking that qualifier on \c Existing is
2057 // not correct either, since we might've previously seen:
2058 // module FW { ... }
2059 // module FW.Sub { ... }
2060 // We should enforce consistency of redefinitions so that we can rely
2061 // that \c Existing is part of a framework iff the redefinition of FW
2062 // we have just skipped had it too. Once we do that, stop checking
2063 // the local framework qualifier and only rely on \c Existing.
2064 bool PartOfFramework
= Framework
|| Existing
->isPartOfFramework();
2065 // - If we're building a (preprocessed) module and we've just loaded the
2066 // module map file from which it was created.
2067 bool ParsedAsMainInput
=
2068 Map
.LangOpts
.getCompilingModule() == LangOptions::CMK_ModuleMap
&&
2069 Map
.LangOpts
.CurrentModule
== ModuleName
&&
2070 SourceMgr
.getDecomposedLoc(ModuleNameLoc
).first
!=
2071 SourceMgr
.getDecomposedLoc(Existing
->DefinitionLoc
).first
;
2072 if (LoadedFromASTFile
|| Inferred
|| PartOfFramework
|| ParsedAsMainInput
) {
2073 ActiveModule
= PreviousActiveModule
;
2074 // Skip the module definition.
2075 skipUntil(MMToken::RBrace
);
2076 if (Tok
.is(MMToken::RBrace
))
2079 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_rbrace
);
2080 Diags
.Report(LBraceLoc
, diag::note_mmap_lbrace_match
);
2086 if (!Existing
->Parent
&& Map
.mayShadowNewModule(Existing
)) {
2087 ShadowingModule
= Existing
;
2089 // This is not a shawdowed module decl, it is an illegal redefinition.
2090 Diags
.Report(ModuleNameLoc
, diag::err_mmap_module_redefinition
)
2092 Diags
.Report(Existing
->DefinitionLoc
, diag::note_mmap_prev_definition
);
2094 // Skip the module definition.
2095 skipUntil(MMToken::RBrace
);
2096 if (Tok
.is(MMToken::RBrace
))
2104 // Start defining this module.
2105 if (ShadowingModule
) {
2107 Map
.createShadowedModule(ModuleName
, Framework
, ShadowingModule
);
2110 Map
.findOrCreateModule(ModuleName
, ActiveModule
, Framework
, Explicit
)
2114 ActiveModule
->DefinitionLoc
= ModuleNameLoc
;
2115 if (Attrs
.IsSystem
|| IsSystem
)
2116 ActiveModule
->IsSystem
= true;
2117 if (Attrs
.IsExternC
)
2118 ActiveModule
->IsExternC
= true;
2119 if (Attrs
.NoUndeclaredIncludes
)
2120 ActiveModule
->NoUndeclaredIncludes
= true;
2121 ActiveModule
->Directory
= Directory
;
2123 StringRef
MapFileName(ModuleMapFile
.getName());
2124 if (MapFileName
.endswith("module.private.modulemap") ||
2125 MapFileName
.endswith("module_private.map")) {
2126 ActiveModule
->ModuleMapIsPrivate
= true;
2129 // Private modules named as FooPrivate, Foo.Private or similar are likely a
2130 // user error; provide warnings, notes and fixits to direct users to use
2131 // Foo_Private instead.
2132 SourceLocation StartLoc
=
2133 SourceMgr
.getLocForStartOfFile(SourceMgr
.getMainFileID());
2134 if (Map
.HeaderInfo
.getHeaderSearchOpts().ImplicitModuleMaps
&&
2135 !Diags
.isIgnored(diag::warn_mmap_mismatched_private_submodule
,
2137 !Diags
.isIgnored(diag::warn_mmap_mismatched_private_module_name
,
2139 ActiveModule
->ModuleMapIsPrivate
)
2140 diagnosePrivateModules(ExplicitLoc
, FrameworkLoc
);
2145 case MMToken::EndOfFile
:
2146 case MMToken::RBrace
:
2150 case MMToken::ConfigMacros
:
2151 parseConfigMacros();
2154 case MMToken::Conflict
:
2158 case MMToken::ExplicitKeyword
:
2159 case MMToken::ExternKeyword
:
2160 case MMToken::FrameworkKeyword
:
2161 case MMToken::ModuleKeyword
:
2165 case MMToken::ExportKeyword
:
2169 case MMToken::ExportAsKeyword
:
2170 parseExportAsDecl();
2173 case MMToken::UseKeyword
:
2177 case MMToken::RequiresKeyword
:
2178 parseRequiresDecl();
2181 case MMToken::TextualKeyword
:
2182 parseHeaderDecl(MMToken::TextualKeyword
, consumeToken());
2185 case MMToken::UmbrellaKeyword
: {
2186 SourceLocation UmbrellaLoc
= consumeToken();
2187 if (Tok
.is(MMToken::HeaderKeyword
))
2188 parseHeaderDecl(MMToken::UmbrellaKeyword
, UmbrellaLoc
);
2190 parseUmbrellaDirDecl(UmbrellaLoc
);
2194 case MMToken::ExcludeKeyword
:
2195 parseHeaderDecl(MMToken::ExcludeKeyword
, consumeToken());
2198 case MMToken::PrivateKeyword
:
2199 parseHeaderDecl(MMToken::PrivateKeyword
, consumeToken());
2202 case MMToken::HeaderKeyword
:
2203 parseHeaderDecl(MMToken::HeaderKeyword
, consumeToken());
2206 case MMToken::LinkKeyword
:
2211 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_member
);
2217 if (Tok
.is(MMToken::RBrace
))
2220 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_rbrace
);
2221 Diags
.Report(LBraceLoc
, diag::note_mmap_lbrace_match
);
2225 // If the active module is a top-level framework, and there are no link
2226 // libraries, automatically link against the framework.
2227 if (ActiveModule
->IsFramework
&& !ActiveModule
->isSubFramework() &&
2228 ActiveModule
->LinkLibraries
.empty())
2229 inferFrameworkLink(ActiveModule
);
2231 // If the module meets all requirements but is still unavailable, mark the
2232 // whole tree as unavailable to prevent it from building.
2233 if (!ActiveModule
->IsAvailable
&& !ActiveModule
->IsUnimportable
&&
2234 ActiveModule
->Parent
) {
2235 ActiveModule
->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
2236 ActiveModule
->getTopLevelModule()->MissingHeaders
.append(
2237 ActiveModule
->MissingHeaders
.begin(), ActiveModule
->MissingHeaders
.end());
2240 // We're done parsing this module. Pop back to the previous module.
2241 ActiveModule
= PreviousActiveModule
;
2244 /// Parse an extern module declaration.
2246 /// extern module-declaration:
2247 /// 'extern' 'module' module-id string-literal
2248 void ModuleMapParser::parseExternModuleDecl() {
2249 assert(Tok
.is(MMToken::ExternKeyword
));
2250 SourceLocation ExternLoc
= consumeToken(); // 'extern' keyword
2252 // Parse 'module' keyword.
2253 if (!Tok
.is(MMToken::ModuleKeyword
)) {
2254 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_module
);
2259 consumeToken(); // 'module' keyword
2261 // Parse the module name.
2263 if (parseModuleId(Id
)) {
2268 // Parse the referenced module map file name.
2269 if (!Tok
.is(MMToken::StringLiteral
)) {
2270 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_mmap_file
);
2274 std::string FileName
= std::string(Tok
.getString());
2275 consumeToken(); // filename
2277 StringRef FileNameRef
= FileName
;
2278 SmallString
<128> ModuleMapFileName
;
2279 if (llvm::sys::path::is_relative(FileNameRef
)) {
2280 ModuleMapFileName
+= Directory
.getName();
2281 llvm::sys::path::append(ModuleMapFileName
, FileName
);
2282 FileNameRef
= ModuleMapFileName
;
2284 if (auto File
= SourceMgr
.getFileManager().getOptionalFileRef(FileNameRef
))
2285 Map
.parseModuleMapFile(
2287 Map
.HeaderInfo
.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2290 FileID(), nullptr, ExternLoc
);
2293 /// Whether to add the requirement \p Feature to the module \p M.
2295 /// This preserves backwards compatibility for two hacks in the Darwin system
2296 /// module map files:
2298 /// 1. The use of 'requires excluded' to make headers non-modular, which
2299 /// should really be mapped to 'textual' now that we have this feature. We
2300 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
2301 /// true. Later, this bit will be used to map all the headers inside this
2302 /// module to 'textual'.
2304 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
2306 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
2307 /// was never correct and causes issues now that we check it, so drop it.
2308 static bool shouldAddRequirement(Module
*M
, StringRef Feature
,
2309 bool &IsRequiresExcludedHack
) {
2310 if (Feature
== "excluded" &&
2311 (M
->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
2312 M
->fullModuleNameIs({"Tcl", "Private"}))) {
2313 IsRequiresExcludedHack
= true;
2315 } else if (Feature
== "cplusplus" && M
->fullModuleNameIs({"IOKit", "avc"})) {
2322 /// Parse a requires declaration.
2324 /// requires-declaration:
2325 /// 'requires' feature-list
2328 /// feature ',' feature-list
2332 /// '!'[opt] identifier
2333 void ModuleMapParser::parseRequiresDecl() {
2334 assert(Tok
.is(MMToken::RequiresKeyword
));
2336 // Parse 'requires' keyword.
2339 // Parse the feature-list.
2341 bool RequiredState
= true;
2342 if (Tok
.is(MMToken::Exclaim
)) {
2343 RequiredState
= false;
2347 if (!Tok
.is(MMToken::Identifier
)) {
2348 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_feature
);
2353 // Consume the feature name.
2354 std::string Feature
= std::string(Tok
.getString());
2357 bool IsRequiresExcludedHack
= false;
2358 bool ShouldAddRequirement
=
2359 shouldAddRequirement(ActiveModule
, Feature
, IsRequiresExcludedHack
);
2361 if (IsRequiresExcludedHack
)
2362 UsesRequiresExcludedHack
.insert(ActiveModule
);
2364 if (ShouldAddRequirement
) {
2365 // Add this feature.
2366 ActiveModule
->addRequirement(Feature
, RequiredState
, Map
.LangOpts
,
2370 if (!Tok
.is(MMToken::Comma
))
2373 // Consume the comma.
2378 /// Parse a header declaration.
2380 /// header-declaration:
2381 /// 'textual'[opt] 'header' string-literal
2382 /// 'private' 'textual'[opt] 'header' string-literal
2383 /// 'exclude' 'header' string-literal
2384 /// 'umbrella' 'header' string-literal
2386 /// FIXME: Support 'private textual header'.
2387 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken
,
2388 SourceLocation LeadingLoc
) {
2389 // We've already consumed the first token.
2390 ModuleMap::ModuleHeaderRole Role
= ModuleMap::NormalHeader
;
2392 if (LeadingToken
== MMToken::PrivateKeyword
) {
2393 Role
= ModuleMap::PrivateHeader
;
2394 // 'private' may optionally be followed by 'textual'.
2395 if (Tok
.is(MMToken::TextualKeyword
)) {
2396 LeadingToken
= Tok
.Kind
;
2399 } else if (LeadingToken
== MMToken::ExcludeKeyword
) {
2400 Role
= ModuleMap::ExcludedHeader
;
2403 if (LeadingToken
== MMToken::TextualKeyword
)
2404 Role
= ModuleMap::ModuleHeaderRole(Role
| ModuleMap::TextualHeader
);
2406 if (UsesRequiresExcludedHack
.count(ActiveModule
)) {
2407 // Mark this header 'textual' (see doc comment for
2408 // Module::UsesRequiresExcludedHack).
2409 Role
= ModuleMap::ModuleHeaderRole(Role
| ModuleMap::TextualHeader
);
2412 if (LeadingToken
!= MMToken::HeaderKeyword
) {
2413 if (!Tok
.is(MMToken::HeaderKeyword
)) {
2414 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_header
)
2415 << (LeadingToken
== MMToken::PrivateKeyword
? "private" :
2416 LeadingToken
== MMToken::ExcludeKeyword
? "exclude" :
2417 LeadingToken
== MMToken::TextualKeyword
? "textual" : "umbrella");
2423 // Parse the header name.
2424 if (!Tok
.is(MMToken::StringLiteral
)) {
2425 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_header
)
2430 Module::UnresolvedHeaderDirective Header
;
2431 Header
.FileName
= std::string(Tok
.getString());
2432 Header
.FileNameLoc
= consumeToken();
2433 Header
.IsUmbrella
= LeadingToken
== MMToken::UmbrellaKeyword
;
2434 Header
.Kind
= Map
.headerRoleToKind(Role
);
2436 // Check whether we already have an umbrella.
2437 if (Header
.IsUmbrella
&&
2438 !std::holds_alternative
<std::monostate
>(ActiveModule
->Umbrella
)) {
2439 Diags
.Report(Header
.FileNameLoc
, diag::err_mmap_umbrella_clash
)
2440 << ActiveModule
->getFullModuleName();
2445 // If we were given stat information, parse it so we can skip looking for
2447 if (Tok
.is(MMToken::LBrace
)) {
2448 SourceLocation LBraceLoc
= consumeToken();
2450 while (!Tok
.is(MMToken::RBrace
) && !Tok
.is(MMToken::EndOfFile
)) {
2451 enum Attribute
{ Size
, ModTime
, Unknown
};
2452 StringRef Str
= Tok
.getString();
2453 SourceLocation Loc
= consumeToken();
2454 switch (llvm::StringSwitch
<Attribute
>(Str
)
2456 .Case("mtime", ModTime
)
2457 .Default(Unknown
)) {
2460 Diags
.Report(Loc
, diag::err_mmap_duplicate_header_attribute
) << Str
;
2461 if (!Tok
.is(MMToken::IntegerLiteral
)) {
2462 Diags
.Report(Tok
.getLocation(),
2463 diag::err_mmap_invalid_header_attribute_value
) << Str
;
2464 skipUntil(MMToken::RBrace
);
2467 Header
.Size
= Tok
.getInteger();
2473 Diags
.Report(Loc
, diag::err_mmap_duplicate_header_attribute
) << Str
;
2474 if (!Tok
.is(MMToken::IntegerLiteral
)) {
2475 Diags
.Report(Tok
.getLocation(),
2476 diag::err_mmap_invalid_header_attribute_value
) << Str
;
2477 skipUntil(MMToken::RBrace
);
2480 Header
.ModTime
= Tok
.getInteger();
2485 Diags
.Report(Loc
, diag::err_mmap_expected_header_attribute
);
2486 skipUntil(MMToken::RBrace
);
2491 if (Tok
.is(MMToken::RBrace
))
2494 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_rbrace
);
2495 Diags
.Report(LBraceLoc
, diag::note_mmap_lbrace_match
);
2500 bool NeedsFramework
= false;
2501 // Don't add the top level headers to the builtin modules if the builtin headers
2502 // belong to the system modules.
2503 if (!Map
.LangOpts
.BuiltinHeadersInSystemModules
|| ActiveModule
->isSubModule() || !isBuiltInModuleName(ActiveModule
->Name
))
2504 Map
.addUnresolvedHeader(ActiveModule
, std::move(Header
), NeedsFramework
);
2507 Diags
.Report(CurrModuleDeclLoc
, diag::note_mmap_add_framework_keyword
)
2508 << ActiveModule
->getFullModuleName()
2509 << FixItHint::CreateReplacement(CurrModuleDeclLoc
, "framework module");
2512 static int compareModuleHeaders(const Module::Header
*A
,
2513 const Module::Header
*B
) {
2514 return A
->NameAsWritten
.compare(B
->NameAsWritten
);
2517 /// Parse an umbrella directory declaration.
2519 /// umbrella-dir-declaration:
2520 /// umbrella string-literal
2521 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc
) {
2522 // Parse the directory name.
2523 if (!Tok
.is(MMToken::StringLiteral
)) {
2524 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_header
)
2530 std::string DirName
= std::string(Tok
.getString());
2531 std::string DirNameAsWritten
= DirName
;
2532 SourceLocation DirNameLoc
= consumeToken();
2534 // Check whether we already have an umbrella.
2535 if (!std::holds_alternative
<std::monostate
>(ActiveModule
->Umbrella
)) {
2536 Diags
.Report(DirNameLoc
, diag::err_mmap_umbrella_clash
)
2537 << ActiveModule
->getFullModuleName();
2542 // Look for this file.
2543 OptionalDirectoryEntryRef Dir
;
2544 if (llvm::sys::path::is_absolute(DirName
)) {
2545 Dir
= SourceMgr
.getFileManager().getOptionalDirectoryRef(DirName
);
2547 SmallString
<128> PathName
;
2548 PathName
= Directory
.getName();
2549 llvm::sys::path::append(PathName
, DirName
);
2550 Dir
= SourceMgr
.getFileManager().getOptionalDirectoryRef(PathName
);
2554 Diags
.Report(DirNameLoc
, diag::warn_mmap_umbrella_dir_not_found
)
2559 if (UsesRequiresExcludedHack
.count(ActiveModule
)) {
2560 // Mark this header 'textual' (see doc comment for
2561 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2562 // directory is relatively expensive, in practice this only applies to the
2563 // uncommonly used Tcl module on Darwin platforms.
2565 SmallVector
<Module::Header
, 6> Headers
;
2566 llvm::vfs::FileSystem
&FS
=
2567 SourceMgr
.getFileManager().getVirtualFileSystem();
2568 for (llvm::vfs::recursive_directory_iterator
I(FS
, Dir
->getName(), EC
), E
;
2569 I
!= E
&& !EC
; I
.increment(EC
)) {
2570 if (auto FE
= SourceMgr
.getFileManager().getOptionalFileRef(I
->path())) {
2571 Module::Header Header
= {"", std::string(I
->path()), *FE
};
2572 Headers
.push_back(std::move(Header
));
2576 // Sort header paths so that the pcm doesn't depend on iteration order.
2577 llvm::array_pod_sort(Headers
.begin(), Headers
.end(), compareModuleHeaders
);
2579 for (auto &Header
: Headers
)
2580 Map
.addHeader(ActiveModule
, std::move(Header
), ModuleMap::TextualHeader
);
2584 if (Module
*OwningModule
= Map
.UmbrellaDirs
[*Dir
]) {
2585 Diags
.Report(UmbrellaLoc
, diag::err_mmap_umbrella_clash
)
2586 << OwningModule
->getFullModuleName();
2591 // Record this umbrella directory.
2592 Map
.setUmbrellaDirAsWritten(ActiveModule
, *Dir
, DirNameAsWritten
, DirName
);
2595 /// Parse a module export declaration.
2597 /// export-declaration:
2598 /// 'export' wildcard-module-id
2600 /// wildcard-module-id:
2603 /// identifier '.' wildcard-module-id
2604 void ModuleMapParser::parseExportDecl() {
2605 assert(Tok
.is(MMToken::ExportKeyword
));
2606 SourceLocation ExportLoc
= consumeToken();
2608 // Parse the module-id with an optional wildcard at the end.
2609 ModuleId ParsedModuleId
;
2610 bool Wildcard
= false;
2612 // FIXME: Support string-literal module names here.
2613 if (Tok
.is(MMToken::Identifier
)) {
2614 ParsedModuleId
.push_back(
2615 std::make_pair(std::string(Tok
.getString()), Tok
.getLocation()));
2618 if (Tok
.is(MMToken::Period
)) {
2626 if(Tok
.is(MMToken::Star
)) {
2632 Diags
.Report(Tok
.getLocation(), diag::err_mmap_module_id
);
2637 Module::UnresolvedExportDecl Unresolved
= {
2638 ExportLoc
, ParsedModuleId
, Wildcard
2640 ActiveModule
->UnresolvedExports
.push_back(Unresolved
);
2643 /// Parse a module export_as declaration.
2645 /// export-as-declaration:
2646 /// 'export_as' identifier
2647 void ModuleMapParser::parseExportAsDecl() {
2648 assert(Tok
.is(MMToken::ExportAsKeyword
));
2651 if (!Tok
.is(MMToken::Identifier
)) {
2652 Diags
.Report(Tok
.getLocation(), diag::err_mmap_module_id
);
2657 if (ActiveModule
->Parent
) {
2658 Diags
.Report(Tok
.getLocation(), diag::err_mmap_submodule_export_as
);
2663 if (!ActiveModule
->ExportAsModule
.empty()) {
2664 if (ActiveModule
->ExportAsModule
== Tok
.getString()) {
2665 Diags
.Report(Tok
.getLocation(), diag::warn_mmap_redundant_export_as
)
2666 << ActiveModule
->Name
<< Tok
.getString();
2668 Diags
.Report(Tok
.getLocation(), diag::err_mmap_conflicting_export_as
)
2669 << ActiveModule
->Name
<< ActiveModule
->ExportAsModule
2674 ActiveModule
->ExportAsModule
= std::string(Tok
.getString());
2675 Map
.addLinkAsDependency(ActiveModule
);
2680 /// Parse a module use declaration.
2682 /// use-declaration:
2683 /// 'use' wildcard-module-id
2684 void ModuleMapParser::parseUseDecl() {
2685 assert(Tok
.is(MMToken::UseKeyword
));
2686 auto KWLoc
= consumeToken();
2687 // Parse the module-id.
2688 ModuleId ParsedModuleId
;
2689 parseModuleId(ParsedModuleId
);
2691 if (ActiveModule
->Parent
)
2692 Diags
.Report(KWLoc
, diag::err_mmap_use_decl_submodule
);
2694 ActiveModule
->UnresolvedDirectUses
.push_back(ParsedModuleId
);
2697 /// Parse a link declaration.
2699 /// module-declaration:
2700 /// 'link' 'framework'[opt] string-literal
2701 void ModuleMapParser::parseLinkDecl() {
2702 assert(Tok
.is(MMToken::LinkKeyword
));
2703 SourceLocation LinkLoc
= consumeToken();
2705 // Parse the optional 'framework' keyword.
2706 bool IsFramework
= false;
2707 if (Tok
.is(MMToken::FrameworkKeyword
)) {
2712 // Parse the library name
2713 if (!Tok
.is(MMToken::StringLiteral
)) {
2714 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_library_name
)
2715 << IsFramework
<< SourceRange(LinkLoc
);
2720 std::string LibraryName
= std::string(Tok
.getString());
2722 ActiveModule
->LinkLibraries
.push_back(Module::LinkLibrary(LibraryName
,
2726 /// Parse a configuration macro declaration.
2728 /// module-declaration:
2729 /// 'config_macros' attributes[opt] config-macro-list?
2731 /// config-macro-list:
2732 /// identifier (',' identifier)?
2733 void ModuleMapParser::parseConfigMacros() {
2734 assert(Tok
.is(MMToken::ConfigMacros
));
2735 SourceLocation ConfigMacrosLoc
= consumeToken();
2737 // Only top-level modules can have configuration macros.
2738 if (ActiveModule
->Parent
) {
2739 Diags
.Report(ConfigMacrosLoc
, diag::err_mmap_config_macro_submodule
);
2742 // Parse the optional attributes.
2744 if (parseOptionalAttributes(Attrs
))
2747 if (Attrs
.IsExhaustive
&& !ActiveModule
->Parent
) {
2748 ActiveModule
->ConfigMacrosExhaustive
= true;
2751 // If we don't have an identifier, we're done.
2752 // FIXME: Support macros with the same name as a keyword here.
2753 if (!Tok
.is(MMToken::Identifier
))
2756 // Consume the first identifier.
2757 if (!ActiveModule
->Parent
) {
2758 ActiveModule
->ConfigMacros
.push_back(Tok
.getString().str());
2763 // If there's a comma, consume it.
2764 if (!Tok
.is(MMToken::Comma
))
2768 // We expect to see a macro name here.
2769 // FIXME: Support macros with the same name as a keyword here.
2770 if (!Tok
.is(MMToken::Identifier
)) {
2771 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_config_macro
);
2775 // Consume the macro name.
2776 if (!ActiveModule
->Parent
) {
2777 ActiveModule
->ConfigMacros
.push_back(Tok
.getString().str());
2783 /// Format a module-id into a string.
2784 static std::string
formatModuleId(const ModuleId
&Id
) {
2787 llvm::raw_string_ostream
OS(result
);
2789 for (unsigned I
= 0, N
= Id
.size(); I
!= N
; ++I
) {
2799 /// Parse a conflict declaration.
2801 /// module-declaration:
2802 /// 'conflict' module-id ',' string-literal
2803 void ModuleMapParser::parseConflict() {
2804 assert(Tok
.is(MMToken::Conflict
));
2805 SourceLocation ConflictLoc
= consumeToken();
2806 Module::UnresolvedConflict Conflict
;
2808 // Parse the module-id.
2809 if (parseModuleId(Conflict
.Id
))
2813 if (!Tok
.is(MMToken::Comma
)) {
2814 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_conflicts_comma
)
2815 << SourceRange(ConflictLoc
);
2820 // Parse the message.
2821 if (!Tok
.is(MMToken::StringLiteral
)) {
2822 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_conflicts_message
)
2823 << formatModuleId(Conflict
.Id
);
2826 Conflict
.Message
= Tok
.getString().str();
2829 // Add this unresolved conflict.
2830 ActiveModule
->UnresolvedConflicts
.push_back(Conflict
);
2833 /// Parse an inferred module declaration (wildcard modules).
2835 /// module-declaration:
2836 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2837 /// { inferred-module-member* }
2839 /// inferred-module-member:
2841 /// 'exclude' identifier
2842 void ModuleMapParser::parseInferredModuleDecl(bool Framework
, bool Explicit
) {
2843 assert(Tok
.is(MMToken::Star
));
2844 SourceLocation StarLoc
= consumeToken();
2845 bool Failed
= false;
2847 // Inferred modules must be submodules.
2848 if (!ActiveModule
&& !Framework
) {
2849 Diags
.Report(StarLoc
, diag::err_mmap_top_level_inferred_submodule
);
2854 // Inferred modules must have umbrella directories.
2855 if (!Failed
&& ActiveModule
->IsAvailable
&&
2856 !ActiveModule
->getEffectiveUmbrellaDir()) {
2857 Diags
.Report(StarLoc
, diag::err_mmap_inferred_no_umbrella
);
2861 // Check for redefinition of an inferred module.
2862 if (!Failed
&& ActiveModule
->InferSubmodules
) {
2863 Diags
.Report(StarLoc
, diag::err_mmap_inferred_redef
);
2864 if (ActiveModule
->InferredSubmoduleLoc
.isValid())
2865 Diags
.Report(ActiveModule
->InferredSubmoduleLoc
,
2866 diag::note_mmap_prev_definition
);
2870 // Check for the 'framework' keyword, which is not permitted here.
2872 Diags
.Report(StarLoc
, diag::err_mmap_inferred_framework_submodule
);
2875 } else if (Explicit
) {
2876 Diags
.Report(StarLoc
, diag::err_mmap_explicit_inferred_framework
);
2880 // If there were any problems with this inferred submodule, skip its body.
2882 if (Tok
.is(MMToken::LBrace
)) {
2884 skipUntil(MMToken::RBrace
);
2885 if (Tok
.is(MMToken::RBrace
))
2892 // Parse optional attributes.
2894 if (parseOptionalAttributes(Attrs
))
2898 // Note that we have an inferred submodule.
2899 ActiveModule
->InferSubmodules
= true;
2900 ActiveModule
->InferredSubmoduleLoc
= StarLoc
;
2901 ActiveModule
->InferExplicitSubmodules
= Explicit
;
2903 // We'll be inferring framework modules for this directory.
2904 Map
.InferredDirectories
[Directory
].InferModules
= true;
2905 Map
.InferredDirectories
[Directory
].Attrs
= Attrs
;
2906 Map
.InferredDirectories
[Directory
].ModuleMapFile
= ModuleMapFile
;
2907 // FIXME: Handle the 'framework' keyword.
2910 // Parse the opening brace.
2911 if (!Tok
.is(MMToken::LBrace
)) {
2912 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_lbrace_wildcard
);
2916 SourceLocation LBraceLoc
= consumeToken();
2918 // Parse the body of the inferred submodule.
2922 case MMToken::EndOfFile
:
2923 case MMToken::RBrace
:
2927 case MMToken::ExcludeKeyword
:
2929 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_inferred_member
)
2930 << (ActiveModule
!= nullptr);
2936 // FIXME: Support string-literal module names here.
2937 if (!Tok
.is(MMToken::Identifier
)) {
2938 Diags
.Report(Tok
.getLocation(), diag::err_mmap_missing_exclude_name
);
2942 Map
.InferredDirectories
[Directory
].ExcludedModules
.push_back(
2943 std::string(Tok
.getString()));
2947 case MMToken::ExportKeyword
:
2948 if (!ActiveModule
) {
2949 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_inferred_member
)
2950 << (ActiveModule
!= nullptr);
2956 if (Tok
.is(MMToken::Star
))
2957 ActiveModule
->InferExportWildcard
= true;
2959 Diags
.Report(Tok
.getLocation(),
2960 diag::err_mmap_expected_export_wildcard
);
2964 case MMToken::ExplicitKeyword
:
2965 case MMToken::ModuleKeyword
:
2966 case MMToken::HeaderKeyword
:
2967 case MMToken::PrivateKeyword
:
2968 case MMToken::UmbrellaKeyword
:
2970 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_inferred_member
)
2971 << (ActiveModule
!= nullptr);
2977 if (Tok
.is(MMToken::RBrace
))
2980 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_rbrace
);
2981 Diags
.Report(LBraceLoc
, diag::note_mmap_lbrace_match
);
2986 /// Parse optional attributes.
2989 /// attribute attributes
2995 /// \param Attrs Will be filled in with the parsed attributes.
2997 /// \returns true if an error occurred, false otherwise.
2998 bool ModuleMapParser::parseOptionalAttributes(Attributes
&Attrs
) {
2999 bool HadError
= false;
3001 while (Tok
.is(MMToken::LSquare
)) {
3003 SourceLocation LSquareLoc
= consumeToken();
3005 // Check whether we have an attribute name here.
3006 if (!Tok
.is(MMToken::Identifier
)) {
3007 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_attribute
);
3008 skipUntil(MMToken::RSquare
);
3009 if (Tok
.is(MMToken::RSquare
))
3014 // Decode the attribute name.
3015 AttributeKind Attribute
3016 = llvm::StringSwitch
<AttributeKind
>(Tok
.getString())
3017 .Case("exhaustive", AT_exhaustive
)
3018 .Case("extern_c", AT_extern_c
)
3019 .Case("no_undeclared_includes", AT_no_undeclared_includes
)
3020 .Case("system", AT_system
)
3021 .Default(AT_unknown
);
3022 switch (Attribute
) {
3024 Diags
.Report(Tok
.getLocation(), diag::warn_mmap_unknown_attribute
)
3029 Attrs
.IsSystem
= true;
3033 Attrs
.IsExternC
= true;
3037 Attrs
.IsExhaustive
= true;
3040 case AT_no_undeclared_includes
:
3041 Attrs
.NoUndeclaredIncludes
= true;
3047 if (!Tok
.is(MMToken::RSquare
)) {
3048 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_rsquare
);
3049 Diags
.Report(LSquareLoc
, diag::note_mmap_lsquare_match
);
3050 skipUntil(MMToken::RSquare
);
3054 if (Tok
.is(MMToken::RSquare
))
3061 /// Parse a module map file.
3063 /// module-map-file:
3064 /// module-declaration*
3065 bool ModuleMapParser::parseModuleMapFile() {
3068 case MMToken::EndOfFile
:
3071 case MMToken::ExplicitKeyword
:
3072 case MMToken::ExternKeyword
:
3073 case MMToken::ModuleKeyword
:
3074 case MMToken::FrameworkKeyword
:
3078 case MMToken::Comma
:
3079 case MMToken::ConfigMacros
:
3080 case MMToken::Conflict
:
3081 case MMToken::Exclaim
:
3082 case MMToken::ExcludeKeyword
:
3083 case MMToken::ExportKeyword
:
3084 case MMToken::ExportAsKeyword
:
3085 case MMToken::HeaderKeyword
:
3086 case MMToken::Identifier
:
3087 case MMToken::LBrace
:
3088 case MMToken::LinkKeyword
:
3089 case MMToken::LSquare
:
3090 case MMToken::Period
:
3091 case MMToken::PrivateKeyword
:
3092 case MMToken::RBrace
:
3093 case MMToken::RSquare
:
3094 case MMToken::RequiresKeyword
:
3096 case MMToken::StringLiteral
:
3097 case MMToken::IntegerLiteral
:
3098 case MMToken::TextualKeyword
:
3099 case MMToken::UmbrellaKeyword
:
3100 case MMToken::UseKeyword
:
3101 Diags
.Report(Tok
.getLocation(), diag::err_mmap_expected_module
);
3109 bool ModuleMap::parseModuleMapFile(FileEntryRef File
, bool IsSystem
,
3110 DirectoryEntryRef Dir
, FileID ID
,
3112 SourceLocation ExternModuleLoc
) {
3113 assert(Target
&& "Missing target information");
3114 llvm::DenseMap
<const FileEntry
*, bool>::iterator Known
3115 = ParsedModuleMap
.find(File
);
3116 if (Known
!= ParsedModuleMap
.end())
3117 return Known
->second
;
3119 // If the module map file wasn't already entered, do so now.
3120 if (ID
.isInvalid()) {
3121 auto FileCharacter
=
3122 IsSystem
? SrcMgr::C_System_ModuleMap
: SrcMgr::C_User_ModuleMap
;
3123 ID
= SourceMgr
.createFileID(File
, ExternModuleLoc
, FileCharacter
);
3126 assert(Target
&& "Missing target information");
3127 std::optional
<llvm::MemoryBufferRef
> Buffer
= SourceMgr
.getBufferOrNone(ID
);
3129 return ParsedModuleMap
[File
] = true;
3130 assert((!Offset
|| *Offset
<= Buffer
->getBufferSize()) &&
3131 "invalid buffer offset");
3133 // Parse this module map file.
3134 Lexer
L(SourceMgr
.getLocForStartOfFile(ID
), MMapLangOpts
,
3135 Buffer
->getBufferStart(),
3136 Buffer
->getBufferStart() + (Offset
? *Offset
: 0),
3137 Buffer
->getBufferEnd());
3138 SourceLocation Start
= L
.getSourceLocation();
3139 ModuleMapParser
Parser(L
, SourceMgr
, Target
, Diags
, *this, File
, Dir
,
3141 bool Result
= Parser
.parseModuleMapFile();
3142 ParsedModuleMap
[File
] = Result
;
3145 auto Loc
= SourceMgr
.getDecomposedLoc(Parser
.getLocation());
3146 assert(Loc
.first
== ID
&& "stopped in a different file?");
3147 *Offset
= Loc
.second
;
3150 // Notify callbacks that we parsed it.
3151 for (const auto &Cb
: Callbacks
)
3152 Cb
->moduleMapFileRead(Start
, File
, IsSystem
);