clang 24.0.0git
ModuleMap.cpp
Go to the documentation of this file.
1//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the ModuleMap implementation, which describes the layout
10// of a module as it relates to headers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/ModuleMap.h"
18#include "clang/Basic/LLVM.h"
20#include "clang/Basic/Module.h"
28#include "llvm/ADT/DenseMap.h"
29#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/SmallPtrSet.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/StringSwitch.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/Path.h"
38#include "llvm/Support/VirtualFileSystem.h"
39#include "llvm/Support/raw_ostream.h"
40#include <cassert>
41#include <cstring>
42#include <optional>
43#include <string>
44#include <system_error>
45#include <utility>
46
47using namespace clang;
48
49static constexpr llvm::StringRef kPrivateModuleSuffix = "_Private";
50
51void ModuleMapCallbacks::anchor() {}
52
54 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
55 if (PendingLinkAs != PendingLinkAsModule.end()) {
56 for (auto &Name : PendingLinkAs->second) {
57 auto *M = findModule(Name.getKey());
58 if (M)
59 M->UseExportAsModuleLinkName = true;
60 }
61 }
62}
63
65 if (findModule(Mod->ExportAsModule))
66 Mod->UseExportAsModuleLinkName = true;
67 else
68 PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
69}
70
72 switch ((int)Role) {
73 case NormalHeader:
74 return Module::HK_Normal;
75 case PrivateHeader:
76 return Module::HK_Private;
77 case TextualHeader:
78 return Module::HK_Textual;
81 case ExcludedHeader:
83 }
84 llvm_unreachable("unknown header role");
85}
86
89 switch ((int)Kind) {
91 return NormalHeader;
93 return PrivateHeader;
95 return TextualHeader;
99 return ExcludedHeader;
100 }
101 llvm_unreachable("unknown header kind");
102}
103
107
109ModuleMap::resolveExport(Module *Mod,
111 bool Complain) const {
112 // We may have just a wildcard.
113 if (Unresolved.Id.empty()) {
114 assert(Unresolved.Wildcard && "Invalid unresolved export");
115 return Module::ExportDecl(nullptr, true);
116 }
117
118 // Resolve the module-id.
119 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
120 if (!Context)
121 return {};
122
123 return Module::ExportDecl(Context, Unresolved.Wildcard);
124}
125
126Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
127 bool Complain) const {
128 // Find the starting module.
129 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
130 if (!Context) {
131 if (Complain)
132 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
133 << Id[0].first << Mod->getFullModuleName();
134
135 return nullptr;
136 }
137
138 // Dig into the module path.
139 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
140 Module *Sub = lookupModuleQualified(Id[I].first, Context);
141 if (!Sub) {
142 if (Complain)
143 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
144 << Id[I].first << Context->getFullModuleName()
145 << SourceRange(Id[0].second, Id[I-1].second);
146
147 return nullptr;
148 }
149
150 Context = Sub;
151 }
152
153 return Context;
154}
155
156/// Append to \p Paths the set of paths needed to get to the
157/// subframework in which the given module lives.
159 SmallVectorImpl<char> &Path) {
160 // Collect the framework names from the given module to the top-level module.
162 for (; Mod; Mod = Mod->Parent) {
163 if (Mod->IsFramework)
164 Paths.push_back(Mod->Name);
165 }
166
167 if (Paths.empty())
168 return;
169
170 // Add Frameworks/Name.framework for each subframework.
171 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
172 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");
173}
174
175OptionalFileEntryRef ModuleMap::findHeader(
177 SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
178 auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {
179 auto File = SourceMgr.getFileManager().getOptionalFileRef(Filename);
180 if (!File || (Header.Size && File->getSize() != *Header.Size) ||
181 (Header.ModTime && File->getModificationTime() != *Header.ModTime))
182 return std::nullopt;
183 return *File;
184 };
185
186 if (llvm::sys::path::is_absolute(Header.FileName)) {
187 RelativePathName.clear();
188 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
189 return GetFile(Header.FileName);
190 }
191
192 // Search for the header file within the module's home directory.
193 auto Directory = M->Directory;
194 if (!Directory)
195 return std::nullopt;
196 SmallString<128> FullPathName(Directory->getName());
197
198 auto GetFrameworkFile = [&]() -> OptionalFileEntryRef {
199 unsigned FullPathLength = FullPathName.size();
200 appendSubframeworkPaths(M, RelativePathName);
201 unsigned RelativePathLength = RelativePathName.size();
202
203 // Check whether this file is in the public headers.
204 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
205 llvm::sys::path::append(FullPathName, RelativePathName);
206 if (auto File = GetFile(FullPathName))
207 return File;
208
209 // Check whether this file is in the private headers.
210 // Ideally, private modules in the form 'FrameworkName.Private' should
211 // be defined as 'module FrameworkName.Private', and not as
212 // 'framework module FrameworkName.Private', since a 'Private.Framework'
213 // does not usually exist. However, since both are currently widely used
214 // for private modules, make sure we find the right path in both cases.
215 if (M->IsFramework && M->Name == "Private")
216 RelativePathName.clear();
217 else
218 RelativePathName.resize(RelativePathLength);
219 FullPathName.resize(FullPathLength);
220 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
221 Header.FileName);
222 llvm::sys::path::append(FullPathName, RelativePathName);
223 return GetFile(FullPathName);
224 };
225
226 if (M->isPartOfFramework())
227 return GetFrameworkFile();
228
229 // Lookup for normal headers.
230 llvm::sys::path::append(RelativePathName, Header.FileName);
231 llvm::sys::path::append(FullPathName, RelativePathName);
232 auto NormalHdrFile = GetFile(FullPathName);
233
234 if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
235 // The lack of 'framework' keyword in a module declaration it's a simple
236 // mistake we can diagnose when the header exists within the proper
237 // framework style path.
238 FullPathName.assign(Directory->getName());
239 RelativePathName.clear();
240 if (GetFrameworkFile()) {
241 Diags.Report(Header.FileNameLoc,
242 diag::warn_mmap_incomplete_framework_module_declaration)
243 << Header.FileName << M->getFullModuleName();
244 NeedsFramework = true;
245 }
246 return std::nullopt;
247 }
248
249 return NormalHdrFile;
250}
251
252/// Determine whether the given file name is the name of a builtin
253/// header, supplied by Clang to replace, override, or augment existing system
254/// headers.
255static bool isBuiltinHeaderName(StringRef FileName) {
256 return llvm::StringSwitch<bool>(FileName)
257 .Case("float.h", true)
258 .Case("iso646.h", true)
259 .Case("limits.h", true)
260 .Case("stdalign.h", true)
261 .Case("stdarg.h", true)
262 .Case("stdatomic.h", true)
263 .Case("stdbool.h", true)
264 .Case("stdckdint.h", true)
265 .Case("stdcountof.h", true)
266 .Case("stddef.h", true)
267 .Case("stdint.h", true)
268 .Case("tgmath.h", true)
269 .Case("unwind.h", true)
270 .Default(false);
271}
272
273/// Determine whether the given module name is the name of a builtin
274/// module that is cyclic with a system module on some platforms.
275static bool isBuiltInModuleName(StringRef ModuleName) {
276 return llvm::StringSwitch<bool>(ModuleName)
277 .Case("_Builtin_float", true)
278 .Case("_Builtin_inttypes", true)
279 .Case("_Builtin_iso646", true)
280 .Case("_Builtin_limits", true)
281 .Case("_Builtin_stdalign", true)
282 .Case("_Builtin_stdarg", true)
283 .Case("_Builtin_stdatomic", true)
284 .Case("_Builtin_stdbool", true)
285 .Case("_Builtin_stddef", true)
286 .Case("_Builtin_stdint", true)
287 .Case("_Builtin_stdnoreturn", true)
288 .Case("_Builtin_tgmath", true)
289 .Case("_Builtin_unwind", true)
290 .Default(false);
291}
292
293void ModuleMap::resolveHeader(Module *Mod,
295 bool &NeedsFramework) {
296 SmallString<128> RelativePathName;
298 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
299 if (Header.IsUmbrella) {
300 const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
301 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
302 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
303 << UmbrellaMod->getFullModuleName();
304 else
305 // Record this umbrella header.
307 RelativePathName.str(), Header.FileNameLoc);
308 } else {
309 Module::Header H = {Header.FileName, std::string(RelativePathName),
310 *File};
311 addHeader(Mod, H, headerKindToRole(Header.Kind), /*Imported=*/false,
312 Header.FileNameLoc);
313 }
314 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
315 // There's a builtin header but no corresponding on-disk header. Assume
316 // this was supposed to modularize the builtin header alone.
317 } else if (Header.Kind == Module::HK_Excluded) {
318 // Ignore missing excluded header files. They're optional anyway.
319 } else {
320 // If we find a module that has a missing header, we mark this module as
321 // unavailable and store the header directive for displaying diagnostics.
322 Mod->MissingHeaders.push_back(Header);
323 // A missing header with stat information doesn't make the module
324 // unavailable; this keeps our behavior consistent as headers are lazily
325 // resolved. (Such a module still can't be built though, except from
326 // preprocessed source.)
327 if (!Header.Size && !Header.ModTime)
328 Mod->markUnavailable(/*Unimportable=*/false);
329 }
330}
331
332bool ModuleMap::resolveAsBuiltinHeader(
333 Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
334 if (Header.Kind == Module::HK_Excluded ||
335 llvm::sys::path::is_absolute(Header.FileName) ||
336 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
337 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
338 !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
339 return false;
340
341 // This is a system module with a top-level header. This header
342 // may have a counterpart (or replacement) in the set of headers
343 // supplied by Clang. Find that builtin header.
344 SmallString<128> Path;
345 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
346 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
347 if (!File)
348 return false;
349
350 Module::Header H = {Header.FileName, Header.FileName, *File};
351 auto Role = headerKindToRole(Header.Kind);
352 addHeader(Mod, H, Role);
353 return true;
354}
355
357 const LangOptions &LangOpts, const TargetInfo *Target,
358 HeaderSearch &HeaderInfo)
359 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
360 HeaderInfo(HeaderInfo) {
361}
362
363ModuleMap::~ModuleMap() = default;
364
365void ModuleMap::setTarget(const TargetInfo &Target) {
366 assert((!this->Target || this->Target == &Target) &&
367 "Improper target override");
368 this->Target = &Target;
369}
370
371/// "Sanitize" a filename so that it can be used as an identifier.
372static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
373 SmallVectorImpl<char> &Buffer) {
374 if (Name.empty())
375 return Name;
376
377 if (!isValidAsciiIdentifier(Name)) {
378 // If we don't already have something with the form of an identifier,
379 // create a buffer with the sanitized name.
380 Buffer.clear();
381 if (isDigit(Name[0]))
382 Buffer.push_back('_');
383 Buffer.reserve(Buffer.size() + Name.size());
384 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
385 if (isAsciiIdentifierContinue(Name[I]))
386 Buffer.push_back(Name[I]);
387 else
388 Buffer.push_back('_');
389 }
390
391 Name = StringRef(Buffer.data(), Buffer.size());
392 }
393
394 while (llvm::StringSwitch<bool>(Name)
395#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
396#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
397#include "clang/Basic/TokenKinds.def"
398 .Default(false)) {
399 if (Name.data() != Buffer.data())
400 Buffer.append(Name.begin(), Name.end());
401 Buffer.push_back('_');
402 Name = StringRef(Buffer.data(), Buffer.size());
403 }
404
405 return Name;
406}
407
409 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
410 isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));
411}
412
414 Module *Module) const {
415 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
418}
419
420ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
422 HeadersMap::iterator Known = Headers.find(File);
423 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
424 Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {
425 HeaderInfo.loadTopLevelSystemModules();
426 return Headers.find(File);
427 }
428 return Known;
429}
430
431ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(
433 if (UmbrellaDirs.empty())
434 return {};
435
436 OptionalDirectoryEntryRef Dir = File.getDir();
437
438 // Note: as an egregious but useful hack we use the real path here, because
439 // frameworks moving from top-level frameworks to embedded frameworks tend
440 // to be symlinked from the top-level location to the embedded location,
441 // and we need to resolve lookups as if we had found the embedded location.
442 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
443
444 // Keep walking up the directory hierarchy, looking for a directory with
445 // an umbrella header.
446 do {
447 auto KnownDir = UmbrellaDirs.find(*Dir);
448 if (KnownDir != UmbrellaDirs.end())
449 return KnownHeader(KnownDir->second, NormalHeader);
450
451 IntermediateDirs.push_back(*Dir);
452
453 // Retrieve our parent path.
454 DirName = llvm::sys::path::parent_path(DirName);
455 if (DirName.empty())
456 break;
457
458 // Resolve the parent path to a directory entry.
459 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
460 } while (Dir);
461 return {};
462}
463
464static bool violatesPrivateInclude(Module *RequestingModule,
465 const FileEntry *IncFileEnt,
466 ModuleMap::KnownHeader Header) {
467#ifndef NDEBUG
468 if (Header.getRole() & ModuleMap::PrivateHeader) {
469 // Check for consistency between the module header role
470 // as obtained from the lookup and as obtained from the module.
471 // This check is not cheap, so enable it only for debugging.
472 bool IsPrivate = false;
473 ArrayRef<Module::Header> HeaderList[] = {
476 for (auto Hs : HeaderList)
477 IsPrivate |= llvm::any_of(
478 Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
479 assert(IsPrivate && "inconsistent headers and roles");
480 }
481#endif
482 return !Header.isAccessibleFrom(RequestingModule);
483}
484
486 return M ? M->getTopLevelModule() : nullptr;
487}
488
490 bool RequestingModuleIsModuleInterface,
491 SourceLocation FilenameLoc,
492 StringRef Filename, FileEntryRef File) {
493 if (RequestingModule) {
494 resolveUses(RequestingModule, /*Complain=*/false);
495 resolveHeaderDirectives(RequestingModule, /*File=*/std::nullopt);
496 }
497
498 HeadersMap::iterator Known = findKnownHeader(File);
499
500 diagnoseDuplicateHeaderOwnership(FilenameLoc, Filename, File, Known);
501
502 // No errors for indirect modules. This may be a bit of a problem for modules
503 // with no source files.
504 Module *TopLevelRequestingModule = getTopLevelOrNull(RequestingModule);
505 Module *TopLevelSourceModule = getTopLevelOrNull(SourceModule);
506 bool IsPublicForMainPrivateModule = false;
507 if (TopLevelRequestingModule != TopLevelSourceModule) {
508 // Suppose we have a pair of files foo.cpp / foo.h.
509 // Our build system may want to verify that foo.cpp only uses things
510 // declared in the implementation_deps of foo, while foo.h only uses things
511 // declared in interface_deps. This requires them to be two seperate
512 // modules, foo_Private and foo. This check is required to ensure that foo.h
513 // is still checked. Otherwise, foo.h would never be checked, since it will
514 // never be the top-level module.
515 if (TopLevelRequestingModule && TopLevelSourceModule &&
516 llvm::StringRef(TopLevelSourceModule->Name)
517 .ends_with(kPrivateModuleSuffix) &&
518 llvm::StringRef(TopLevelSourceModule->Name)
519 .drop_back(kPrivateModuleSuffix.size()) ==
520 TopLevelRequestingModule->Name) {
521 IsPublicForMainPrivateModule = true;
522 } else {
523 return;
524 }
525 }
526
527 bool Excluded = false;
528 bool UsedByPrivateModule = false;
529 Module *Private = nullptr;
530 Module *NotUsed = nullptr;
531
532 if (Known != Headers.end()) {
533 for (const KnownHeader &Header : Known->second) {
534 // Excluded headers don't really belong to a module.
535 if (Header.getRole() == ModuleMap::ExcludedHeader) {
536 Excluded = true;
537 continue;
538 }
539
540 // Remember private headers for later printing of a diagnostic.
541 if (violatesPrivateInclude(RequestingModule, File, Header)) {
542 Private = Header.getModule();
543 continue;
544 }
545
546 // If uses need to be specified explicitly, we are only allowed to return
547 // modules that are explicitly used by the requesting module.
548 if (RequestingModule && LangOpts.ModulesDeclUse &&
549 !RequestingModule->directlyUses(Header.getModule())) {
550 NotUsed = Header.getModule();
551 if (IsPublicForMainPrivateModule) {
552 UsedByPrivateModule = SourceModule->directlyUses(Header.getModule());
553 }
554 continue;
555 }
556
557 // We have found a module that we can happily use.
558 return;
559 }
560
561 Excluded = true;
562 }
563
564 // We have found a header, but it is private.
565 if (Private) {
566 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
567 << Filename;
568 return;
569 }
570
571 // We have found a module, but we don't use it.
572 if (NotUsed) {
573 if (UsedByPrivateModule) {
574 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_private)
575 << RequestingModule->getTopLevelModule()->Name << Filename
576 << NotUsed->Name;
577 } else {
578 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
579 << RequestingModule->getTopLevelModule()->Name << Filename
580 << NotUsed->Name;
581 }
582 return;
583 }
584
585 if (Excluded || isHeaderInUmbrellaDirs(File))
586 return;
587
588 // At this point, only non-modular includes remain.
589
590 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
591 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
592 << RequestingModule->getTopLevelModule()->Name << Filename;
593 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
594 LangOpts.isCompilingModule()) {
595 // Do not diagnose when we are not compiling a module.
596 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
597 diag::warn_non_modular_include_in_framework_module :
598 diag::warn_non_modular_include_in_module;
599 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
600 << File.getName();
601 }
602}
603
604void ModuleMap::diagnoseDuplicateHeaderOwnership(SourceLocation FilenameLoc,
605 StringRef Filename,
607 HeadersMap::iterator Known) {
608 if (Known == Headers.end())
609 return;
610
611 if (Diags.isIgnored(diag::warn_mmap_duplicate_header_ownership, FilenameLoc))
612 return;
613
614 // Only diagnose each header once.
615 if (!DiagnosedDuplicateHeaders.insert(&File.getFileEntry()).second)
616 return;
617
618 struct OwnerInfo {
619 Module *Mod;
620 SourceLocation Loc;
621 bool IsUmbrella;
622 };
623
624 // Collect distinct top-level modules that explicitly own this header with
625 // a modular (non-textual, non-excluded) role.
626 SmallVector<OwnerInfo, 2> OwningModules;
628 for (const KnownHeader &H : Known->second) {
629 if (!isModular(H.getRole()))
630 continue;
631 Module *TopLevel = H.getModule()->getTopLevelModule();
632 if (!SeenTopLevel.insert(TopLevel).second)
633 continue;
634 auto It = HeaderOwnerLocs.find({&File.getFileEntry(), H.getModule()});
635 SourceLocation OwnerLoc =
636 It != HeaderOwnerLocs.end() ? It->second : SourceLocation();
637 OwningModules.push_back({TopLevel, OwnerLoc, /*IsUmbrella=*/false});
638 }
639
640 // Need at least one explicit owner for there to be a conflict, since
641 // umbrella coverage can only add one more.
642 if (OwningModules.empty())
643 return;
644
645 // Also check umbrella directory coverage for additional owners from different
646 // top-level modules — but only if the header isn't excluded from the umbrella
647 // module. Explicit headers take precedence over umbrella dirs in module
648 // resolution, but a header owned by one module that another module's umbrella
649 // covers can still create problems.
650 SmallVector<DirectoryEntryRef, 2> IntermediateDirs;
651 if (KnownHeader UmbrellaOwner =
652 findHeaderInUmbrellaDirs(File, IntermediateDirs)) {
653 Module *TopLevel = UmbrellaOwner.getModule()->getTopLevelModule();
654 // Only add if it's a different top-level module and the header isn't
655 // excluded from the umbrella module.
656 if (SeenTopLevel.insert(TopLevel).second) {
657 // Check that the header isn't excluded in the umbrella module.
658 bool IsExcluded =
659 llvm::any_of(Known->second, [TopLevel](const KnownHeader &H) {
660 return H.getModule()->getTopLevelModule() == TopLevel &&
661 H.getRole() == ExcludedHeader;
662 });
663 if (!IsExcluded) {
664 OwningModules.push_back({TopLevel,
665 UmbrellaOwner.getModule()->UmbrellaDeclLoc,
666 /*IsUmbrella=*/true});
667 }
668 }
669 }
670
671 if (OwningModules.size() < 2)
672 return;
673
674 Diags.Report(FilenameLoc, diag::warn_mmap_duplicate_header_ownership)
675 << Filename;
676 for (const auto &Owner : OwningModules) {
677 unsigned NoteID = Owner.IsUmbrella
678 ? diag::note_mmap_header_covered_by_umbrella
679 : diag::note_mmap_header_owned_by;
680 Diags.Report(Owner.Loc, NoteID) << Owner.Mod->getFullModuleName();
681 }
682}
683
685 const ModuleMap::KnownHeader &Old) {
686 // Prefer available modules.
687 // FIXME: Considering whether the module is available rather than merely
688 // importable is non-hermetic and can result in surprising behavior for
689 // prebuilt modules. Consider only checking for importability here.
690 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
691 return true;
692
693 // Prefer a public header over a private header.
694 if ((New.getRole() & ModuleMap::PrivateHeader) !=
696 return !(New.getRole() & ModuleMap::PrivateHeader);
697
698 // Prefer a non-textual header over a textual header.
699 if ((New.getRole() & ModuleMap::TextualHeader) !=
701 return !(New.getRole() & ModuleMap::TextualHeader);
702
703 // Prefer a non-excluded header over an excluded header.
704 if ((New.getRole() == ModuleMap::ExcludedHeader) !=
706 return New.getRole() != ModuleMap::ExcludedHeader;
707
708 // Don't have a reason to choose between these. Just keep the first one.
709 return false;
710}
711
713 bool AllowTextual,
714 bool AllowExcluded) {
715 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
716 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
717 return {};
718 return R;
719 };
720
721 HeadersMap::iterator Known = findKnownHeader(File);
722 if (Known != Headers.end()) {
724 // Iterate over all modules that 'File' is part of to find the best fit.
725 for (KnownHeader &H : Known->second) {
726 // Cannot use a module if the header is excluded in it.
727 if (!AllowExcluded && H.getRole() == ModuleMap::ExcludedHeader)
728 continue;
729 // Prefer a header from the source module over all others.
730 if (H.getModule()->getTopLevelModule() == SourceModule)
731 return MakeResult(H);
733 Result = H;
734 }
735 return MakeResult(Result);
736 }
737
738 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
739}
740
742 Module *M, std::string NameAsWritten,
743 SmallVectorImpl<char> &RelativePathName) {
745 Header.FileName = std::move(NameAsWritten);
746 Header.IsUmbrella = true;
747 bool NeedsFramework;
748 return findHeader(M, Header, RelativePathName, NeedsFramework);
749}
750
752ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
753 assert(!Headers.count(File) && "already have a module for this header");
754
756 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
757 if (H) {
758 Module *Result = H.getModule();
759
760 // Search up the module stack until we find a module with an umbrella
761 // directory.
762 Module *UmbrellaModule = Result;
763 while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)
764 UmbrellaModule = UmbrellaModule->Parent;
765
766 if (UmbrellaModule->InferSubmodules) {
767 FileID UmbrellaModuleMap = getModuleMapFileIDForUniquing(UmbrellaModule);
768
769 // Infer submodules for each of the directories we found between
770 // the directory of the umbrella header and the directory where
771 // the actual header is located.
772 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
773
774 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
775 // Find or create the module that corresponds to this directory name.
776 SmallString<32> NameBuf;
777 StringRef Name = sanitizeFilenameAsIdentifier(
778 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
779 Result = findOrCreateModuleFirst(Name, Result, /*IsFramework=*/false,
780 Explicit);
781 setInferredModuleAllowedBy(Result, UmbrellaModuleMap);
782
783 // Associate the module and the directory.
784 UmbrellaDirs[SkippedDir] = Result;
785
786 // If inferred submodules export everything they import, add a
787 // wildcard to the set of exports.
788 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
789 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
790 }
791
792 // Infer a submodule with the same name as this header file.
793 SmallString<32> NameBuf;
794 StringRef Name = sanitizeFilenameAsIdentifier(
795 llvm::sys::path::stem(File.getName()), NameBuf);
796 Result = findOrCreateModuleFirst(Name, Result, /*IsFramework=*/false,
797 Explicit);
798 setInferredModuleAllowedBy(Result, UmbrellaModuleMap);
799 Result->addTopHeader(File);
800
801 // If inferred submodules export everything they import, add a
802 // wildcard to the set of exports.
803 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
804 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
805 } else {
806 // Record each of the directories we stepped through as being part of
807 // the module we found, since the umbrella header covers them all.
808 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
809 UmbrellaDirs[SkippedDirs[I]] = Result;
810 }
811
813 Headers[File].push_back(Header);
814 return Header;
815 }
816
817 return {};
818}
819
822 HeadersMap::iterator Known = findKnownHeader(File);
823 if (Known != Headers.end())
824 return Known->second;
825
826 if (findOrCreateModuleForHeaderInUmbrellaDir(File))
827 return Headers.find(File)->second;
828
829 return {};
830}
831
834 // FIXME: Is this necessary?
836 auto It = Headers.find(File);
837 if (It == Headers.end())
838 return {};
839 return It->second;
840}
841
843 return isHeaderUnavailableInModule(Header, nullptr);
844}
845
847 FileEntryRef Header, const Module *RequestingModule) const {
849 HeadersMap::const_iterator Known = Headers.find(Header);
850 if (Known != Headers.end()) {
852 I = Known->second.begin(),
853 E = Known->second.end();
854 I != E; ++I) {
855
856 if (I->getRole() == ModuleMap::ExcludedHeader)
857 continue;
858
859 if (I->isAvailable() &&
860 (!RequestingModule ||
861 I->getModule()->isSubModuleOf(RequestingModule))) {
862 // When no requesting module is available, the caller is looking if a
863 // header is part a module by only looking into the module map. This is
864 // done by warn_uncovered_module_header checks; don't consider textual
865 // headers part of it in this mode, otherwise we get misleading warnings
866 // that a umbrella header is not including a textual header.
867 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
868 continue;
869 return false;
870 }
871 }
872 return true;
873 }
874
875 OptionalDirectoryEntryRef Dir = Header.getDir();
877 StringRef DirName = Dir->getName();
878
879 auto IsUnavailable = [&](const Module *M) {
880 return !M->isAvailable() && (!RequestingModule ||
881 M->isSubModuleOf(RequestingModule));
882 };
883
884 // Keep walking up the directory hierarchy, looking for a directory with
885 // an umbrella header.
886 do {
887 auto KnownDir = UmbrellaDirs.find(*Dir);
888 if (KnownDir != UmbrellaDirs.end()) {
889 Module *Found = KnownDir->second;
890 if (IsUnavailable(Found))
891 return true;
892
893 // Search up the module stack until we find a module with an umbrella
894 // directory.
895 Module *UmbrellaModule = Found;
896 while (!UmbrellaModule->getEffectiveUmbrellaDir() &&
897 UmbrellaModule->Parent)
898 UmbrellaModule = UmbrellaModule->Parent;
899
900 if (UmbrellaModule->InferSubmodules) {
901 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
902 // Find or create the module that corresponds to this directory name.
903 SmallString<32> NameBuf;
904 StringRef Name = sanitizeFilenameAsIdentifier(
905 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
907 if (!Found)
908 return false;
909 if (IsUnavailable(Found))
910 return true;
911 }
912
913 // Infer a submodule with the same name as this header file.
914 SmallString<32> NameBuf;
915 StringRef Name = sanitizeFilenameAsIdentifier(
916 llvm::sys::path::stem(Header.getName()),
917 NameBuf);
919 if (!Found)
920 return false;
921 }
922
923 return IsUnavailable(Found);
924 }
925
926 SkippedDirs.push_back(*Dir);
927
928 // Retrieve our parent path.
929 DirName = llvm::sys::path::parent_path(DirName);
930 if (DirName.empty())
931 break;
932
933 // Resolve the parent path to a directory entry.
934 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
935 } while (Dir);
936
937 return false;
938}
939
940Module *ModuleMap::findModule(StringRef Name) const {
941 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
942 if (Known != Modules.end())
943 return Known->getValue();
944
945 return nullptr;
946}
947
949 if (Module *SubM = Parent->findSubmodule(Name))
950 return SubM;
951 if (!Parent->InferSubmodules)
952 return nullptr;
953 Module *Result = new (ModulesAlloc.Allocate())
954 Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent, false,
955 Parent->InferExplicitSubmodules, 0);
956 Result->InferExplicitSubmodules = Parent->InferExplicitSubmodules;
957 Result->InferSubmodules = Parent->InferSubmodules;
958 Result->InferExportWildcard = Parent->InferExportWildcard;
959 if (Result->InferExportWildcard)
960 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
961 return Result;
962}
963
965 Module *Context) const {
966 for(; Context; Context = Context->Parent) {
967 if (Module *Sub = lookupModuleQualified(Name, Context))
968 return Sub;
969 }
970
971 return findModule(Name);
972}
973
975 Module *Context) const {
976 if (!Context)
977 return findModule(Name);
978
979 return Context->findSubmodule(Name);
980}
981
982std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
983 Module *Parent,
984 bool IsFramework,
985 bool IsExplicit) {
986 // Try to find an existing module with this name.
987 if (ModuleRef Sub = lookupModuleQualified(Name, Parent); Sub.getExisting())
988 return std::make_pair(Sub.getExisting(), false);
989
990 // Create a new module with this name.
991 Module *M = createModule(Name, Parent, IsFramework, IsExplicit);
992 return std::make_pair(M, true);
993}
994
995Module *ModuleMap::createModule(StringRef Name, Module *Parent,
996 bool IsFramework, bool IsExplicit) {
997 assert(!lookupModuleQualified(Name, Parent).getExisting() &&
998 "Creating duplicate submodule");
999
1000 Module *Result = new (ModulesAlloc.Allocate())
1001 Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent,
1002 IsFramework, IsExplicit, NumCreatedModules++);
1003 if (!Parent) {
1004 if (LangOpts.CurrentModule == Name)
1005 SourceModule = Result;
1006 Modules[Name] = Result;
1007 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1008 }
1009 return Result;
1010}
1011
1013 Module *Parent) {
1014 auto *Result = new (ModulesAlloc.Allocate()) Module(
1015 ModuleConstructorTag{}, "<global>", Loc, Parent, /*IsFramework=*/false,
1016 /*IsExplicit=*/true, NumCreatedModules++);
1018 // If the created module isn't owned by a parent, send it to PendingSubmodules
1019 // to wait for its parent.
1020 if (!Result->Parent)
1021 PendingSubmodules.emplace_back(Result);
1022 return Result;
1023}
1024
1025Module *
1027 Module *Parent) {
1028 assert(Parent && "We should only create an implicit global module fragment "
1029 "in a module purview");
1030 // Note: Here the `IsExplicit` parameter refers to the semantics in clang
1031 // modules. All the non-explicit submodules in clang modules will be exported
1032 // too. Here we simplify the implementation by using the concept.
1033 auto *Result = new (ModulesAlloc.Allocate())
1034 Module(ModuleConstructorTag{}, "<implicit global>", Loc, Parent,
1035 /*IsFramework=*/false, /*IsExplicit=*/false, NumCreatedModules++);
1037 return Result;
1038}
1039
1040Module *
1042 SourceLocation Loc) {
1043 auto *Result = new (ModulesAlloc.Allocate()) Module(
1044 ModuleConstructorTag{}, "<private>", Loc, Parent, /*IsFramework=*/false,
1045 /*IsExplicit=*/true, NumCreatedModules++);
1047 return Result;
1048}
1049
1051 Module::ModuleKind Kind) {
1052 auto *Result = new (ModulesAlloc.Allocate())
1053 Module(ModuleConstructorTag{}, Name, Loc, nullptr, /*IsFramework=*/false,
1054 /*IsExplicit=*/false, NumCreatedModules++);
1055 Result->Kind = Kind;
1056
1057 // Reparent any current global module fragment as a submodule of this module.
1058 for (auto &Submodule : PendingSubmodules)
1059 Submodule->setParent(Result);
1060 PendingSubmodules.clear();
1061 return Result;
1062}
1063
1065 StringRef Name) {
1066 assert(LangOpts.CurrentModule == Name && "module name mismatch");
1067 assert(!Modules[Name] && "redefining existing module");
1068
1069 auto *Result =
1071 Modules[Name] = SourceModule = Result;
1072
1073 // Mark the main source file as being within the newly-created module so that
1074 // declarations and macros are properly visibility-restricted to it.
1075 auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
1076 assert(MainFile && "no input file for module interface");
1077 Headers[*MainFile].push_back(KnownHeader(Result, PrivateHeader));
1078
1079 return Result;
1080}
1081
1083 StringRef Name) {
1084 assert(LangOpts.CurrentModule == Name && "module name mismatch");
1085 // The interface for this implementation must exist and be loaded.
1086 assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&
1087 "creating implementation module without an interface");
1088
1089 // Create an entry in the modules map to own the implementation unit module.
1090 // User module names must not start with a period (so that this cannot clash
1091 // with any legal user-defined module name).
1092 StringRef IName = ".ImplementationUnit";
1093 assert(!Modules[IName] && "multiple implementation units?");
1094
1095 auto *Result =
1097 Modules[IName] = SourceModule = Result;
1098
1099 // Check that the main file is present.
1100 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
1101 "no input file for module implementation");
1102
1103 return Result;
1104}
1105
1107 Module::Header H) {
1108 assert(LangOpts.CurrentModule == Name && "module name mismatch");
1109 assert(!Modules[Name] && "redefining existing module");
1110
1111 auto *Result = new (ModulesAlloc.Allocate())
1112 Module(ModuleConstructorTag{}, Name, Loc, nullptr, /*IsFramework=*/false,
1113 /*IsExplicit=*/false, NumCreatedModules++);
1115 Modules[Name] = SourceModule = Result;
1117 return Result;
1118}
1119
1120/// For a framework module, infer the framework against which we
1121/// should link.
1122static void inferFrameworkLink(Module *Mod) {
1123 assert(Mod->IsFramework && "Can only infer linking for framework modules");
1124 assert(!Mod->isSubFramework() &&
1125 "Can only infer linking for top-level frameworks");
1126
1127 StringRef FrameworkName(Mod->Name);
1128 FrameworkName.consume_back("_Private");
1129 Mod->LinkLibraries.push_back(Module::LinkLibrary(FrameworkName.str(),
1130 /*IsFramework=*/true));
1131}
1132
1133Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
1134 bool IsSystem, Module *Parent) {
1135 Attributes Attrs;
1136 Attrs.IsSystem = IsSystem;
1137 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
1138}
1139
1140Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
1141 Attributes Attrs, Module *Parent) {
1142 // Note: as an egregious but useful hack we use the real path here, because
1143 // we might be looking at an embedded framework that symlinks out to a
1144 // top-level framework, and we need to infer as if we were naming the
1145 // top-level framework.
1146 StringRef FrameworkDirName =
1147 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
1148
1149 // In case this is a case-insensitive filesystem, use the canonical
1150 // directory name as the ModuleName, since modules are case-sensitive.
1151 // FIXME: we should be able to give a fix-it hint for the correct spelling.
1152 SmallString<32> ModuleNameStorage;
1153 StringRef ModuleName = sanitizeFilenameAsIdentifier(
1154 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1155
1156 // Check whether we've already found this module.
1157 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
1158 return Mod;
1159
1160 FileManager &FileMgr = SourceMgr.getFileManager();
1161
1162 // If the framework has a parent path from which we're allowed to infer
1163 // a framework module, do so.
1164 FileID ModuleMapFID;
1165 if (!Parent) {
1166 // Determine whether we're allowed to infer a module map.
1167 bool canInfer = false;
1168 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1169 // Figure out the parent path.
1170 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1171 if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {
1172 // Check whether we have already looked into the parent directory
1173 // for a module map.
1174 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1175 inferred = InferredDirectories.find(*ParentDir);
1176 if (inferred == InferredDirectories.end()) {
1177 // We haven't looked here before. Load a module map, if there is
1178 // one.
1179 bool IsFrameworkDir = Parent.ends_with(".framework");
1180 if (OptionalFileEntryRef ModMapFile =
1181 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
1182 // TODO: Parsing a module map should populate `InferredDirectories`
1183 // so we don't need to do a full load here.
1184 parseAndLoadModuleMapFile(*ModMapFile, Attrs.IsSystem,
1185 /*ImplicitlyDiscovered=*/true,
1186 *ParentDir);
1187 inferred = InferredDirectories.find(*ParentDir);
1188 }
1189
1190 if (inferred == InferredDirectories.end())
1191 inferred = InferredDirectories.insert(
1192 std::make_pair(*ParentDir, InferredDirectory())).first;
1193 }
1194
1195 if (inferred->second.InferModules) {
1196 // We're allowed to infer for this directory, but make sure it's okay
1197 // to infer this particular module.
1198 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1199 canInfer =
1200 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1201
1202 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1203 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1204 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1205 Attrs.NoUndeclaredIncludes |=
1206 inferred->second.Attrs.NoUndeclaredIncludes;
1207 ModuleMapFID = inferred->second.ModuleMapFID;
1208 }
1209 }
1210 }
1211
1212 // If we're not allowed to infer a framework module, don't.
1213 if (!canInfer)
1214 return nullptr;
1215 } else {
1216 ModuleMapFID = getModuleMapFileIDForUniquing(Parent);
1217 }
1218
1219 // Look for an umbrella header.
1220 SmallString<128> UmbrellaName = FrameworkDir.getName();
1221 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1222 auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
1223
1224 // FIXME: If there's no umbrella header, we could probably scan the
1225 // framework to load *everything*. But, it's not clear that this is a good
1226 // idea.
1227 if (!UmbrellaHeader)
1228 return nullptr;
1229
1230 Module *Result = new (ModulesAlloc.Allocate())
1231 Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,
1232 /*IsFramework=*/true, /*IsExplicit=*/false, NumCreatedModules++);
1233 setInferredModuleAllowedBy(Result, ModuleMapFID);
1234 if (!Parent) {
1235 if (LangOpts.CurrentModule == ModuleName)
1236 SourceModule = Result;
1237 Modules[ModuleName] = Result;
1238 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1239 }
1240
1241 Result->IsSystem |= Attrs.IsSystem;
1242 Result->IsExternC |= Attrs.IsExternC;
1243 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1244 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1245 Result->Directory = FrameworkDir;
1246
1247 // Chop off the first framework bit, as that is implied.
1248 StringRef RelativePath = UmbrellaName.str().substr(
1249 Result->getTopLevelModule()->Directory->getName().size());
1250 RelativePath = llvm::sys::path::relative_path(RelativePath);
1251
1252 // umbrella header "umbrella-header-name"
1253 setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h",
1254 RelativePath);
1255
1256 // export *
1257 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
1258
1259 // module * { export * }
1260 Result->InferSubmodules = true;
1261 Result->InferExportWildcard = true;
1262
1263 // Look for subframeworks.
1264 std::error_code EC;
1265 SmallString<128> SubframeworksDirName = FrameworkDir.getName();
1266 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1267 llvm::sys::path::native(SubframeworksDirName);
1268 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1269 for (llvm::vfs::directory_iterator
1270 Dir = FS.dir_begin(SubframeworksDirName, EC),
1271 DirEnd;
1272 Dir != DirEnd && !EC; Dir.increment(EC)) {
1273 if (!StringRef(Dir->path()).ends_with(".framework"))
1274 continue;
1275
1276 if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {
1277 // Note: as an egregious but useful hack, we use the real path here and
1278 // check whether it is actually a subdirectory of the parent directory.
1279 // This will not be the case if the 'subframework' is actually a symlink
1280 // out to a top-level framework.
1281 StringRef SubframeworkDirName =
1282 FileMgr.getCanonicalName(*SubframeworkDir);
1283 bool FoundParent = false;
1284 do {
1285 // Get the parent directory name.
1286 SubframeworkDirName
1287 = llvm::sys::path::parent_path(SubframeworkDirName);
1288 if (SubframeworkDirName.empty())
1289 break;
1290
1291 if (auto SubDir =
1292 FileMgr.getOptionalDirectoryRef(SubframeworkDirName)) {
1293 if (*SubDir == FrameworkDir) {
1294 FoundParent = true;
1295 break;
1296 }
1297 }
1298 } while (true);
1299
1300 if (!FoundParent)
1301 continue;
1302
1303 // FIXME: Do we want to warn about subframeworks without umbrella headers?
1304 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1305 }
1306 }
1307
1308 // If the module is a top-level framework, automatically link against the
1309 // framework.
1310 if (!Result->isSubFramework())
1312
1313 return Result;
1314}
1315
1316Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
1317 Module *ShadowingModule) {
1318
1319 // Create a new module with this name.
1320 Module *Result = new (ModulesAlloc.Allocate())
1321 Module(ModuleConstructorTag{}, Name, SourceLocation(), /*Parent=*/nullptr,
1322 IsFramework, /*IsExplicit=*/false, NumCreatedModules++);
1323 Result->ShadowingModule = ShadowingModule;
1324 Result->markUnavailable(/*Unimportable*/true);
1325 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1326 ShadowModules.push_back(Result);
1327
1328 return Result;
1329}
1330
1332 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1333 const Twine &PathRelativeToRootModuleDirectory, SourceLocation Loc) {
1334 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
1335 if (Loc.isValid())
1336 HeaderOwnerLocs[{&UmbrellaHeader.getFileEntry(), Mod}] = Loc;
1337 Mod->Umbrella = UmbrellaHeader;
1338 Mod->UmbrellaDeclLoc = Loc;
1339 Mod->UmbrellaAsWritten = NameAsWritten.str();
1341 PathRelativeToRootModuleDirectory.str();
1342 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1343
1344 // Notify callbacks that we just added a new header.
1345 for (const auto &Cb : Callbacks)
1346 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1347}
1348
1350 Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
1351 const Twine &PathRelativeToRootModuleDirectory, SourceLocation Loc) {
1352 Mod->Umbrella = UmbrellaDir;
1353 Mod->UmbrellaDeclLoc = Loc;
1354 Mod->UmbrellaAsWritten = NameAsWritten.str();
1356 PathRelativeToRootModuleDirectory.str();
1357 UmbrellaDirs[UmbrellaDir] = Mod;
1358}
1359
1360void ModuleMap::addUnresolvedHeader(Module *Mod,
1362 bool &NeedsFramework) {
1363 // If there is a builtin counterpart to this file, add it now so it can
1364 // wrap the system header.
1365 if (resolveAsBuiltinHeader(Mod, Header)) {
1366 // If we have both a builtin and system version of the file, the
1367 // builtin version may want to inject macros into the system header, so
1368 // force the system header to be treated as a textual header in this
1369 // case.
1372 Header.HasBuiltinHeader = true;
1373 }
1374
1375 // If possible, don't stat the header until we need to. This requires the
1376 // user to have provided us with some stat information about the file.
1377 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1378 // headers.
1379 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1380 Header.Kind != Module::HK_Excluded) {
1381 // We expect more variation in mtime than size, so if we're given both,
1382 // use the mtime as the key.
1383 if (Header.ModTime)
1384 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1385 else
1386 LazyHeadersBySize[*Header.Size].push_back(Mod);
1387 Mod->UnresolvedHeaders.push_back(Header);
1388 return;
1389 }
1390
1391 // We don't have stat information or can't defer looking this file up.
1392 // Perform the lookup now.
1393 resolveHeader(Mod, Header, NeedsFramework);
1394}
1395
1397 auto BySize = LazyHeadersBySize.find(File->getSize());
1398 if (BySize != LazyHeadersBySize.end()) {
1399 for (auto *M : BySize->second)
1401 LazyHeadersBySize.erase(BySize);
1402 }
1403
1404 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1405 if (ByModTime != LazyHeadersByModTime.end()) {
1406 for (auto *M : ByModTime->second)
1408 LazyHeadersByModTime.erase(ByModTime);
1409 }
1410}
1411
1413 Module *Mod, std::optional<const FileEntry *> File) const {
1414 bool NeedsFramework = false;
1416 const auto Size = File ? (*File)->getSize() : 0;
1417 const auto ModTime = File ? (*File)->getModificationTime() : 0;
1418
1419 for (auto &Header : Mod->UnresolvedHeaders) {
1420 if (File && ((Header.ModTime && Header.ModTime != ModTime) ||
1421 (Header.Size && Header.Size != Size)))
1422 NewHeaders.push_back(Header);
1423 else
1424 // This operation is logically const; we're just changing how we represent
1425 // the header information for this file.
1426 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1427 }
1428 Mod->UnresolvedHeaders.swap(NewHeaders);
1429}
1430
1432 ModuleHeaderRole Role, bool Imported,
1433 SourceLocation Loc) {
1434 KnownHeader KH(Mod, Role);
1435
1436 FileEntryRef HeaderEntry = Header.Entry;
1437
1438 // Only add each header to the headers list once.
1439 // FIXME: Should we diagnose if a header is listed twice in the
1440 // same module definition?
1441 auto &HeaderList = Headers[HeaderEntry];
1442 if (llvm::is_contained(HeaderList, KH))
1443 return;
1444
1445 if (Loc.isValid())
1446 HeaderOwnerLocs[{&HeaderEntry.getFileEntry(), Mod}] = Loc;
1447
1448 HeaderList.push_back(KH);
1449 Mod->addHeader(headerRoleToKind(Role), std::move(Header));
1450
1451 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
1452 if (!Imported || isCompilingModuleHeader) {
1453 // When we import HeaderFileInfo, the external source is expected to
1454 // set the isModuleHeader flag itself.
1455 HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role, isCompilingModuleHeader);
1456 }
1457
1458 // Notify callbacks that we just added a new header.
1459 for (const auto &Cb : Callbacks)
1460 Cb->moduleMapAddHeader(HeaderEntry.getName());
1461}
1462
1464 bool ImplicitlyDiscovered,
1465 DirectoryEntryRef Dir, FileID ID,
1466 SourceLocation ExternModuleLoc) {
1467 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator
1468 Known = ParsedModuleMap.find(File);
1469 if (Known != ParsedModuleMap.end())
1470 return Known->second == nullptr;
1471
1472 // If the module map file wasn't already entered, do so now.
1473 if (ID.isInvalid()) {
1474 FileID &LocalFID = ModuleMapLocalFileID[File];
1475 if (LocalFID.isInvalid()) {
1476 auto FileCharacter =
1478 LocalFID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
1479 }
1480 ID = LocalFID;
1481 }
1482
1483 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
1484 if (!Buffer) {
1485 ParsedModuleMap[File] = nullptr;
1486 return true;
1487 }
1488
1489 Diags.Report(diag::remark_mmap_parse) << File.getName();
1490 std::optional<modulemap::ModuleMapFile> MaybeMMF = modulemap::parseModuleMap(
1491 ID, Dir, SourceMgr, Diags, IsSystem, ImplicitlyDiscovered, nullptr);
1492
1493 if (!MaybeMMF) {
1494 ParsedModuleMap[File] = nullptr;
1495 return true;
1496 }
1497
1498 ParsedModuleMaps.push_back(
1499 std::make_unique<modulemap::ModuleMapFile>(std::move(*MaybeMMF)));
1500 const modulemap::ModuleMapFile &MMF = *ParsedModuleMaps.back();
1501 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;
1502 std::function<void(const modulemap::ModuleDecl &)> CollectExternDecls =
1503 [&](const modulemap::ModuleDecl &MD) {
1504 for (const auto &Decl : MD.Decls) {
1505 std::visit(llvm::makeVisitor(
1506 [&](const modulemap::ModuleDecl &SubMD) {
1507 // Skip inferred submodules (module *)
1508 if (SubMD.Id.front().first == "*")
1509 return;
1510 CollectExternDecls(SubMD);
1511 },
1512 [&](const modulemap::ExternModuleDecl &EMD) {
1513 PendingExternalModuleMaps.push_back(&EMD);
1514 },
1515 [&](const auto &) {
1516 // Ignore other decls
1517 }),
1518 Decl);
1519 }
1520 };
1521
1522 for (const auto &Decl : MMF.Decls) {
1523 std::visit(llvm::makeVisitor(
1524 [&](const modulemap::ModuleDecl &MD) {
1525 // Only use the first part of the name even for submodules.
1526 // This will correctly load the submodule declarations when
1527 // the module is loaded.
1528 auto &ModuleDecls =
1529 ParsedModules[StringRef(MD.Id.front().first)];
1530 ModuleDecls.push_back(std::pair(&MMF, &MD));
1531 CollectExternDecls(MD);
1532 },
1533 [&](const modulemap::ExternModuleDecl &EMD) {
1534 PendingExternalModuleMaps.push_back(&EMD);
1535 }),
1536 Decl);
1537 }
1538
1539 for (const modulemap::ExternModuleDecl *EMD : PendingExternalModuleMaps) {
1540 StringRef FileNameRef = EMD->Path;
1541 SmallString<128> ModuleMapFileName;
1542 if (llvm::sys::path::is_relative(FileNameRef)) {
1543 ModuleMapFileName += Dir.getName();
1544 llvm::sys::path::append(ModuleMapFileName, EMD->Path);
1545 FileNameRef = ModuleMapFileName;
1546 }
1547
1548 if (auto EFile =
1549 SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {
1550 parseModuleMapFile(*EFile, IsSystem, ImplicitlyDiscovered,
1551 EFile->getDir(), FileID(), ExternModuleLoc);
1552 }
1553 }
1554
1555 ParsedModuleMap[File] = &MMF;
1556
1557 for (const auto &Cb : Callbacks)
1558 Cb->moduleMapFileRead(SourceLocation(), File, IsSystem);
1559
1560 return false;
1561}
1562
1564 for (const auto &Entry : ParsedModules)
1565 findOrLoadModule(Entry.first());
1566}
1567
1570 return {};
1571
1572 return SourceMgr.getFileID(Module->DefinitionLoc);
1573}
1574
1577 return SourceMgr.getFileEntryRefForID(getContainingModuleMapFileID(Module));
1578}
1579
1581 if (M->IsInferred) {
1582 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1583 return InferredModuleAllowedBy.find(M)->second;
1584 }
1586}
1587
1590 return SourceMgr.getFileEntryRefForID(getModuleMapFileIDForUniquing(M));
1591}
1592
1594 M->IsInferred = true;
1595 InferredModuleAllowedBy[M] = ModMapFID;
1596}
1597
1598std::error_code
1600 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1601
1602 // Do not canonicalize within the framework; the module map loader expects
1603 // Modules/ not Versions/A/Modules.
1604 if (llvm::sys::path::filename(Dir) == "Modules") {
1605 StringRef Parent = llvm::sys::path::parent_path(Dir);
1606 if (Parent.ends_with(".framework"))
1607 Dir = Parent;
1608 }
1609
1610 FileManager &FM = SourceMgr.getFileManager();
1611 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1612 if (!DirEntry)
1613 return llvm::errorToErrorCode(DirEntry.takeError());
1614
1615 // Canonicalize the directory.
1616 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
1617 if (CanonicalDir != Dir)
1618 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1619
1620 // In theory, the filename component should also be canonicalized if it
1621 // on a case-insensitive filesystem. However, the extra canonicalization is
1622 // expensive and if clang looked up the filename it will always be lowercase.
1623
1624 // Remove ., remove redundant separators, and switch to native separators.
1625 // This is needed for separators between CanonicalDir and the filename.
1626 llvm::sys::path::remove_dots(Path);
1627
1628 return std::error_code();
1629}
1630
1633 AdditionalModMaps[M].insert(ModuleMap);
1634}
1635
1636LLVM_DUMP_METHOD void ModuleMap::dump() {
1637 llvm::errs() << "Modules:";
1638 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1639 MEnd = Modules.end();
1640 M != MEnd; ++M)
1641 M->getValue()->print(llvm::errs(), 2);
1642
1643 llvm::errs() << "Headers:";
1644 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1645 H != HEnd; ++H) {
1646 llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1647 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1648 E = H->second.end();
1649 I != E; ++I) {
1650 if (I != H->second.begin())
1651 llvm::errs() << ",";
1652 llvm::errs() << I->getModule()->getFullModuleName();
1653 }
1654 llvm::errs() << "\n";
1655 }
1656}
1657
1658bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
1659 auto Unresolved = std::move(Mod->UnresolvedExports);
1660 Mod->UnresolvedExports.clear();
1661 for (auto &UE : Unresolved) {
1662 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
1663 if (Export.first || Export.second)
1664 Mod->Exports.push_back(Export);
1665 else
1666 Mod->UnresolvedExports.push_back(UE);
1667 }
1668 return !Mod->UnresolvedExports.empty();
1669}
1670
1671bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
1672 auto *Top = Mod->getTopLevelModule();
1673 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1674 Top->UnresolvedDirectUses.clear();
1675 for (auto &UDU : Unresolved) {
1676 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1677 if (DirectUse)
1678 Top->DirectUses.push_back(DirectUse);
1679 else
1680 Top->UnresolvedDirectUses.push_back(UDU);
1681 }
1682 return !Top->UnresolvedDirectUses.empty();
1683}
1684
1685bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
1686 auto Unresolved = std::move(Mod->UnresolvedConflicts);
1687 Mod->UnresolvedConflicts.clear();
1688 for (auto &UC : Unresolved) {
1689 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1690 Module::Conflict Conflict;
1691 Conflict.Other = OtherMod;
1692 Conflict.Message = UC.Message;
1693 Mod->Conflicts.push_back(Conflict);
1694 } else
1695 Mod->UnresolvedConflicts.push_back(UC);
1696 }
1697 return !Mod->UnresolvedConflicts.empty();
1698}
1699
1700//----------------------------------------------------------------------------//
1701// Module map file loader
1702//----------------------------------------------------------------------------//
1703
1704namespace clang {
1706 SourceManager &SourceMgr;
1707
1708 DiagnosticsEngine &Diags;
1709 ModuleMap &Map;
1710
1711 /// The current module map file.
1712 FileID ModuleMapFID;
1713
1714 /// Source location of most recent loaded module declaration
1715 SourceLocation CurrModuleDeclLoc;
1716
1717 /// The directory that file names in this module map file should
1718 /// be resolved relative to.
1719 DirectoryEntryRef Directory;
1720
1721 /// Whether this module map is in a system header directory.
1722 bool IsSystem;
1723
1724 bool ImplicitlyDiscovered;
1725
1726 /// Whether an error occurred.
1727 bool HadError = false;
1728
1729 /// The active module.
1730 Module *ActiveModule = nullptr;
1731
1732 /// Whether a module uses the 'requires excluded' hack to mark its
1733 /// contents as 'textual'.
1734 ///
1735 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1736 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1737 /// non-modular headers. For backwards compatibility, we continue to
1738 /// support this idiom for just these modules, and map the headers to
1739 /// 'textual' to match the original intent.
1740 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1741
1742 void handleModuleDecl(const modulemap::ModuleDecl &MD);
1743 void handleExternModuleDecl(const modulemap::ExternModuleDecl &EMD);
1744 void handleRequiresDecl(const modulemap::RequiresDecl &RD);
1745 void handleHeaderDecl(const modulemap::HeaderDecl &HD);
1746 void handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD);
1747 void handleExportDecl(const modulemap::ExportDecl &ED);
1748 void handleExportAsDecl(const modulemap::ExportAsDecl &EAD);
1749 void handleUseDecl(const modulemap::UseDecl &UD);
1750 void handleLinkDecl(const modulemap::LinkDecl &LD);
1751 void handleConfigMacros(const modulemap::ConfigMacrosDecl &CMD);
1752 void handleConflict(const modulemap::ConflictDecl &CD);
1753 void handleInferredModuleDecl(const modulemap::ModuleDecl &MD);
1754
1755 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1756 /// module map search logic to find the appropriate private module when PCH
1757 /// is used with implicit module maps. Warn when private modules are written
1758 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1759 void diagnosePrivateModules(SourceLocation StartLoc);
1760
1761 using Attributes = ModuleMap::Attributes;
1762
1763public:
1765 ModuleMap &Map, FileID ModuleMapFID,
1766 DirectoryEntryRef Directory, bool IsSystem,
1767 bool ImplicitlyDiscovered)
1768 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),
1769 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem),
1770 ImplicitlyDiscovered(ImplicitlyDiscovered) {}
1771
1772 bool loadModuleDecl(const modulemap::ModuleDecl &MD);
1775};
1776
1777} // namespace clang
1778
1779/// Private modules are canonicalized as Foo_Private. Clang provides extra
1780/// module map search logic to find the appropriate private module when PCH
1781/// is used with implicit module maps. Warn when private modules are written
1782/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1783void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {
1784 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1785 const Module *M, SourceRange ReplLoc) {
1786 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1787 diag::note_mmap_rename_top_level_private_module);
1788 D << BadName << M->Name;
1789 D << FixItHint::CreateReplacement(ReplLoc, Canonical);
1790 };
1791
1792 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1793 auto const *M = E->getValue();
1794 if (M->Directory != ActiveModule->Directory)
1795 continue;
1796
1797 SmallString<128> FullName(ActiveModule->getFullModuleName());
1798 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
1799 continue;
1800 SmallString<128> FixedPrivModDecl;
1801 SmallString<128> Canonical(M->Name);
1802 Canonical.append("_Private");
1803
1804 // Foo.Private -> Foo_Private
1805 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1806 M->Name == ActiveModule->Parent->Name) {
1807 Diags.Report(ActiveModule->DefinitionLoc,
1808 diag::warn_mmap_mismatched_private_submodule)
1809 << FullName;
1810
1811 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1812 if (StartLoc.isValid())
1813 FixItInitBegin = StartLoc;
1814
1815 if (ActiveModule->Parent->IsFramework)
1816 FixedPrivModDecl.append("framework ");
1817 FixedPrivModDecl.append("module ");
1818 FixedPrivModDecl.append(Canonical);
1819
1820 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1821 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1822 continue;
1823 }
1824
1825 // FooPrivate and whatnots -> Foo_Private
1826 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1827 ActiveModule->Name != Canonical) {
1828 Diags.Report(ActiveModule->DefinitionLoc,
1829 diag::warn_mmap_mismatched_private_module_name)
1830 << ActiveModule->Name;
1831 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1832 SourceRange(ActiveModule->DefinitionLoc));
1833 }
1834 }
1835}
1836
1837void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
1838 if (MD.Id.front().first == "*")
1839 return handleInferredModuleDecl(MD);
1840
1841 CurrModuleDeclLoc = MD.Location;
1842
1843 Module *PreviousActiveModule = ActiveModule;
1844 if (MD.Id.size() > 1) {
1845 // This module map defines a submodule. Go find the module of which it
1846 // is a submodule.
1847 ActiveModule = nullptr;
1848 const Module *TopLevelModule = nullptr;
1849 for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {
1850 if (Module *Next =
1851 Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {
1852 if (I == 0)
1853 TopLevelModule = Next;
1854 ActiveModule = Next;
1855 continue;
1856 }
1857
1858 Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)
1859 << MD.Id[I].first << (ActiveModule != nullptr)
1860 << (ActiveModule
1861 ? ActiveModule->getTopLevelModule()->getFullModuleName()
1862 : "");
1863 HadError = true;
1864 }
1865
1866 if (TopLevelModule &&
1867 ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
1868 assert(ModuleMapFID !=
1869 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
1870 "submodule defined in same file as 'module *' that allowed its "
1871 "top-level module");
1872 Map.addAdditionalModuleMapFile(
1873 TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
1874 }
1875 }
1876
1877 StringRef ModuleName = MD.Id.back().first;
1878 SourceLocation ModuleNameLoc = MD.Id.back().second;
1879
1880 // Determine whether this (sub)module has already been defined.
1881 Module *ShadowingModule = nullptr;
1882 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1883 // We might see a (re)definition of a module that we already have a
1884 // definition for in four cases:
1885 // - If the Existing module was loaded from an AST file and we've found its
1886 // original source module map, or we cannot determine Existing's
1887 // definition location.
1888 bool LoadedFromASTFile = Existing->IsFromModuleFile;
1889 if (LoadedFromASTFile) {
1890 OptionalFileEntryRef ExistingModMapFile =
1891 Map.getContainingModuleMapFile(Existing);
1892 OptionalFileEntryRef CurrentModMapFile =
1893 SourceMgr.getFileEntryRefForID(ModuleMapFID);
1894 if ((ExistingModMapFile && CurrentModMapFile &&
1895 *ExistingModMapFile == *CurrentModMapFile) ||
1896 Existing->DefinitionLoc.isInvalid()) {
1897 // If we do not know Existing's definition location, we have
1898 // no way of checking against it, and hence we stay conservative and do
1899 // not check for duplicating module definitions.
1900 LoadedFromASTFile = true;
1901 } else
1902 LoadedFromASTFile = false;
1903 }
1904 // - If we previously inferred this module from different module map file.
1905 bool Inferred = Existing->IsInferred;
1906 // - If we're building a framework that vends a module map, we might've
1907 // previously seen the one in intermediate products and now the system
1908 // one.
1909 // FIXME: If we're parsing module map file that looks like this:
1910 // framework module FW { ... }
1911 // module FW.Sub { ... }
1912 // We can't check the framework qualifier, since it's not attached to
1913 // the definition of Sub. Checking that qualifier on \c Existing is
1914 // not correct either, since we might've previously seen:
1915 // module FW { ... }
1916 // module FW.Sub { ... }
1917 // We should enforce consistency of redefinitions so that we can rely
1918 // that \c Existing is part of a framework iff the redefinition of FW
1919 // we have just skipped had it too. Once we do that, stop checking
1920 // the local framework qualifier and only rely on \c Existing.
1921 bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
1922 // - If we're building a (preprocessed) module and we've just loaded the
1923 // module map file from which it was created.
1924 bool ParsedAsMainInput =
1925 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1926 Map.LangOpts.CurrentModule == ModuleName &&
1927 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1928 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1929 // TODO: Remove this check when we can avoid loading module maps multiple
1930 // times.
1931 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;
1932 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||
1933 SameModuleDecl) {
1934 ActiveModule = PreviousActiveModule;
1935 // Skip the module definition.
1936 return;
1937 }
1938
1939 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1940 ShadowingModule = Existing;
1941 } else {
1942 // This is not a shawdowed module decl, it is an illegal redefinition.
1943 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1944 << ModuleName;
1945 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1946 HadError = true;
1947 return;
1948 }
1949 }
1950
1951 // Start defining this module.
1952 if (ShadowingModule) {
1953 ActiveModule =
1954 Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
1955 } else {
1956 ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
1957 MD.Framework, MD.Explicit);
1958 }
1959
1960 ActiveModule->DefinitionLoc = ModuleNameLoc;
1961 if (MD.Attrs.IsSystem || IsSystem)
1962 ActiveModule->IsSystem = true;
1963 if (MD.Attrs.IsExternC)
1964 ActiveModule->IsExternC = true;
1966 ActiveModule->NoUndeclaredIncludes = true;
1967 ActiveModule->Directory = Directory;
1968
1969 StringRef MapFileName(
1970 SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
1971 if (MapFileName.ends_with("module.private.modulemap") ||
1972 MapFileName.ends_with("module_private.map")) {
1973 ActiveModule->ModuleMapIsPrivate = true;
1974 }
1975
1976 // Private modules named as FooPrivate, Foo.Private or similar are likely a
1977 // user error; provide warnings, notes and fixits to direct users to use
1978 // Foo_Private instead.
1979 SourceLocation StartLoc =
1980 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1981 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1982 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1983 StartLoc) &&
1984 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1985 StartLoc) &&
1986 ActiveModule->ModuleMapIsPrivate)
1987 diagnosePrivateModules(MD.Location);
1988
1989 for (const modulemap::Decl &Decl : MD.Decls) {
1990 std::visit(
1991 llvm::makeVisitor(
1992 [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },
1993 [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
1994 [&](const modulemap::UmbrellaDirDecl &UDD) {
1995 handleUmbrellaDirDecl(UDD);
1996 },
1997 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
1998 [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
1999 [&](const modulemap::ExportAsDecl &EAD) {
2000 handleExportAsDecl(EAD);
2001 },
2002 [&](const modulemap::ExternModuleDecl &EMD) {
2003 handleExternModuleDecl(EMD);
2004 },
2005 [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },
2006 [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
2007 [&](const modulemap::ConfigMacrosDecl &CMD) {
2008 handleConfigMacros(CMD);
2009 },
2010 [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },
2011 [&](const modulemap::ExcludeDecl &ED) {
2012 Diags.Report(ED.Location, diag::err_mmap_expected_member);
2013 }),
2014 Decl);
2015 }
2016
2017 // If the active module is a top-level framework, and there are no link
2018 // libraries, automatically link against the framework.
2019 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2020 ActiveModule->LinkLibraries.empty())
2021 inferFrameworkLink(ActiveModule);
2022
2023 // If the module meets all requirements but is still unavailable, mark the
2024 // whole tree as unavailable to prevent it from building.
2025 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
2026 ActiveModule->Parent) {
2027 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
2028 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2029 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2030 }
2031
2032 // We're done parsing this module. Pop back to the previous module.
2033 ActiveModule = PreviousActiveModule;
2034}
2035
2036void ModuleMapLoader::handleExternModuleDecl(
2037 const modulemap::ExternModuleDecl &EMD) {
2038 StringRef FileNameRef = EMD.Path;
2039 SmallString<128> ModuleMapFileName;
2040 if (llvm::sys::path::is_relative(FileNameRef)) {
2041 ModuleMapFileName += Directory.getName();
2042 llvm::sys::path::append(ModuleMapFileName, EMD.Path);
2043 // As extern module declarations are parsed recursively, relative paths
2044 // to those modules can become arbitrarily long.
2045 // If the OS name length limit is exceeded when trying to get the file ref
2046 // we can silently fail to find an extern module that exists.
2047 // To mitigate this, collapse relative paths containing '../' for when
2048 // constructing the name of each module file referenced as an extern module.
2049 llvm::sys::path::remove_dots(ModuleMapFileName, /*remove_dot_dot=*/true);
2050 FileNameRef = ModuleMapFileName;
2051 }
2052 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
2053 Map.parseAndLoadModuleMapFile(
2054 *File, IsSystem, ImplicitlyDiscovered,
2055 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2056 ? Directory
2057 : File->getDir(),
2058 FileID(), nullptr, EMD.Location);
2059}
2060
2061/// Whether to add the requirement \p Feature to the module \p M.
2062///
2063/// This preserves backwards compatibility for two hacks in the Darwin system
2064/// module map files:
2065///
2066/// 1. The use of 'requires excluded' to make headers non-modular, which
2067/// should really be mapped to 'textual' now that we have this feature. We
2068/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
2069/// true. Later, this bit will be used to map all the headers inside this
2070/// module to 'textual'.
2071///
2072/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
2073///
2074/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
2075/// was never correct and causes issues now that we check it, so drop it.
2076static bool shouldAddRequirement(Module *M, StringRef Feature,
2077 bool &IsRequiresExcludedHack) {
2078 if (Feature == "excluded" &&
2079 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
2080 M->fullModuleNameIs({"Tcl", "Private"}))) {
2081 IsRequiresExcludedHack = true;
2082 return false;
2083 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
2084 return false;
2085 }
2086
2087 return true;
2088}
2089
2090void ModuleMapLoader::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
2091
2092 for (const modulemap::RequiresFeature &RF : RD.Features) {
2093 bool IsRequiresExcludedHack = false;
2094 bool ShouldAddRequirement =
2095 shouldAddRequirement(ActiveModule, RF.Feature, IsRequiresExcludedHack);
2096
2097 if (IsRequiresExcludedHack)
2098 UsesRequiresExcludedHack.insert(ActiveModule);
2099
2100 if (ShouldAddRequirement) {
2101 // Add this feature.
2102 ActiveModule->addRequirement(RF.Feature, RF.RequiredState, Map.LangOpts,
2103 *Map.Target);
2104 }
2105 }
2106}
2107
2108void ModuleMapLoader::handleHeaderDecl(const modulemap::HeaderDecl &HD) {
2109 // We've already consumed the first token.
2111
2112 if (HD.Private) {
2114 } else if (HD.Excluded) {
2116 }
2117
2118 if (HD.Textual)
2120
2121 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2122 // Mark this header 'textual' (see doc comment for
2123 // Module::UsesRequiresExcludedHack).
2125 }
2126
2127 Module::UnresolvedHeaderDirective Header;
2128 Header.FileName = HD.Path;
2129 Header.FileNameLoc = HD.PathLoc;
2130 Header.IsUmbrella = HD.Umbrella;
2131 Header.Kind = Map.headerRoleToKind(Role);
2132
2133 // Check whether we already have an umbrella.
2134 if (Header.IsUmbrella &&
2135 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
2136 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
2137 << ActiveModule->getFullModuleName();
2138 HadError = true;
2139 return;
2140 }
2141
2142 if (ImplicitlyDiscovered) {
2143 SmallString<128> NormalizedPath(HD.Path);
2144 llvm::sys::path::remove_dots(NormalizedPath, /*remove_dot_dot=*/true);
2145 if (NormalizedPath.starts_with(".."))
2146 Diags.Report(HD.PathLoc, diag::warn_mmap_path_outside_directory);
2147 }
2148
2149 if (HD.Size)
2150 Header.Size = HD.Size;
2151 if (HD.MTime)
2152 Header.ModTime = HD.MTime;
2153
2154 bool NeedsFramework = false;
2155 // Don't add headers to the builtin modules if the builtin headers belong to
2156 // the system modules, with the exception of __stddef_max_align_t.h which
2157 // always had its own module.
2158 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
2159 !isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||
2160 ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
2161 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2162
2163 if (NeedsFramework)
2164 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2165 << ActiveModule->getFullModuleName()
2166 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
2167}
2168
2170 const Module::Header &B) {
2171 return A.NameAsWritten < B.NameAsWritten;
2172}
2173
2174void ModuleMapLoader::handleUmbrellaDirDecl(
2175 const modulemap::UmbrellaDirDecl &UDD) {
2176 std::string DirName = std::string(UDD.Path);
2177 std::string DirNameAsWritten = DirName;
2178
2179 // Check whether we already have an umbrella.
2180 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
2181 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
2182 << ActiveModule->getFullModuleName();
2183 HadError = true;
2184 return;
2185 }
2186
2187 if (ImplicitlyDiscovered) {
2188 SmallString<128> NormalizedPath(UDD.Path);
2189 llvm::sys::path::remove_dots(NormalizedPath, /*remove_dot_dot=*/true);
2190 if (NormalizedPath.starts_with(".."))
2191 Diags.Report(UDD.Location, diag::warn_mmap_path_outside_directory);
2192 }
2193
2194 // Look for this file.
2196 if (llvm::sys::path::is_absolute(DirName)) {
2197 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
2198 } else {
2199 SmallString<128> PathName;
2200 PathName = Directory.getName();
2201 llvm::sys::path::append(PathName, DirName);
2202 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
2203 }
2204
2205 if (!Dir) {
2206 Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)
2207 << DirName;
2208 return;
2209 }
2210
2211 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2212 // Mark this header 'textual' (see doc comment for
2213 // ModuleMapLoader::UsesRequiresExcludedHack). Although iterating over the
2214 // directory is relatively expensive, in practice this only applies to the
2215 // uncommonly used Tcl module on Darwin platforms.
2216 std::error_code EC;
2217 SmallVector<Module::Header, 6> Headers;
2218 llvm::vfs::FileSystem &FS =
2219 SourceMgr.getFileManager().getVirtualFileSystem();
2220 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2221 I != E && !EC; I.increment(EC)) {
2222 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2223 Module::Header Header = {"", std::string(I->path()), *FE};
2224 Headers.push_back(std::move(Header));
2225 }
2226 }
2227
2228 // Sort header paths so that the pcm doesn't depend on iteration order.
2229 llvm::stable_sort(Headers, compareModuleHeaders);
2230
2231 for (auto &Header : Headers)
2232 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2233 return;
2234 }
2235
2236 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2237 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
2238 << OwningModule->getFullModuleName();
2239 HadError = true;
2240 return;
2241 }
2242
2243 // Record this umbrella directory.
2244 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName,
2245 UDD.Location);
2246}
2247
2248void ModuleMapLoader::handleExportDecl(const modulemap::ExportDecl &ED) {
2249 Module::UnresolvedExportDecl Unresolved = {ED.Location, ED.Id, ED.Wildcard};
2250 ActiveModule->UnresolvedExports.push_back(Unresolved);
2251}
2252
2253void ModuleMapLoader::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
2254 const auto &ModName = EAD.Id.front();
2255
2256 if (!ActiveModule->ExportAsModule.empty()) {
2257 if (ActiveModule->ExportAsModule == ModName.first) {
2258 Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)
2259 << ActiveModule->Name << ModName.first;
2260 } else {
2261 Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)
2262 << ActiveModule->Name << ActiveModule->ExportAsModule
2263 << ModName.first;
2264 }
2265 }
2266
2267 ActiveModule->ExportAsModule = ModName.first;
2268 Map.addLinkAsDependency(ActiveModule);
2269}
2270
2271void ModuleMapLoader::handleUseDecl(const modulemap::UseDecl &UD) {
2272 if (ActiveModule->Parent)
2273 Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);
2274 else
2275 ActiveModule->UnresolvedDirectUses.push_back(UD.Id);
2276}
2277
2278void ModuleMapLoader::handleLinkDecl(const modulemap::LinkDecl &LD) {
2279 ActiveModule->LinkLibraries.push_back(
2280 Module::LinkLibrary(std::string{LD.Library}, LD.Framework));
2281}
2282
2283void ModuleMapLoader::handleConfigMacros(
2284 const modulemap::ConfigMacrosDecl &CMD) {
2285 if (ActiveModule->Parent) {
2286 Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);
2287 return;
2288 }
2289
2290 // TODO: Is this really the behavior we want for multiple config_macros
2291 // declarations? If any of them are exhaustive then all of them are.
2292 if (CMD.Exhaustive) {
2293 ActiveModule->ConfigMacrosExhaustive = true;
2294 }
2295 ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),
2296 CMD.Macros.begin(), CMD.Macros.end());
2297}
2298
2299void ModuleMapLoader::handleConflict(const modulemap::ConflictDecl &CD) {
2300 Module::UnresolvedConflict Conflict;
2301
2302 Conflict.Id = CD.Id;
2303 Conflict.Message = CD.Message;
2304
2305 // FIXME: when we move to C++20 we should consider using emplace_back
2306 ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));
2307}
2308
2309void ModuleMapLoader::handleInferredModuleDecl(
2310 const modulemap::ModuleDecl &MD) {
2311 SourceLocation StarLoc = MD.Id.front().second;
2312
2313 // Inferred modules must be submodules.
2314 if (!ActiveModule && !MD.Framework) {
2315 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2316 return;
2317 }
2318
2319 if (ActiveModule) {
2320 // Inferred modules must have umbrella directories.
2321 if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
2322 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2323 return;
2324 }
2325
2326 // Check for redefinition of an inferred module.
2327 if (ActiveModule->InferSubmodules) {
2328 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2329 if (ActiveModule->InferredSubmoduleLoc.isValid())
2330 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2331 diag::note_mmap_prev_definition);
2332 return;
2333 }
2334
2335 // Check for the 'framework' keyword, which is not permitted here.
2336 if (MD.Framework) {
2337 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2338 return;
2339 }
2340 } else if (MD.Explicit) {
2341 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2342 return;
2343 }
2344
2345 if (ActiveModule) {
2346 // Note that we have an inferred submodule.
2347 ActiveModule->InferSubmodules = true;
2348 ActiveModule->InferredSubmoduleLoc = StarLoc;
2349 ActiveModule->InferExplicitSubmodules = MD.Explicit;
2350 } else {
2351 // We'll be inferring framework modules for this directory.
2352 auto &InfDir = Map.InferredDirectories[Directory];
2353 InfDir.InferModules = true;
2354 InfDir.Attrs = MD.Attrs;
2355 InfDir.ModuleMapFID = ModuleMapFID;
2356 // FIXME: Handle the 'framework' keyword.
2357 }
2358
2359 for (const modulemap::Decl &Decl : MD.Decls) {
2360 std::visit(
2361 llvm::makeVisitor(
2362 [&](const auto &Other) {
2363 Diags.Report(Other.Location,
2364 diag::err_mmap_expected_inferred_member)
2365 << (ActiveModule != nullptr);
2366 },
2367 [&](const modulemap::ExcludeDecl &ED) {
2368 // Only inferred frameworks can have exclude decls
2369 if (ActiveModule) {
2370 Diags.Report(ED.Location,
2371 diag::err_mmap_expected_inferred_member)
2372 << (ActiveModule != nullptr);
2373 HadError = true;
2374 return;
2375 }
2376 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(
2377 ED.Module);
2378 },
2379 [&](const modulemap::ExportDecl &ED) {
2380 // Only inferred submodules can have export decls
2381 if (!ActiveModule) {
2382 Diags.Report(ED.Location,
2383 diag::err_mmap_expected_inferred_member)
2384 << (ActiveModule != nullptr);
2385 HadError = true;
2386 return;
2387 }
2388
2389 if (ED.Wildcard && ED.Id.size() == 0)
2390 ActiveModule->InferExportWildcard = true;
2391 else
2392 Diags.Report(ED.Id.front().second,
2393 diag::err_mmap_expected_export_wildcard);
2394 }),
2395 Decl);
2396 }
2397}
2398
2400 handleModuleDecl(MD);
2401 return HadError;
2402}
2403
2405 const modulemap::ExternModuleDecl &EMD) {
2406 handleExternModuleDecl(EMD);
2407 return HadError;
2408}
2409
2411 const modulemap::ModuleMapFile &MMF) {
2412 for (const auto &Decl : MMF.Decls) {
2413 std::visit(
2414 llvm::makeVisitor(
2415 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
2416 [&](const modulemap::ExternModuleDecl &EMD) {
2417 handleExternModuleDecl(EMD);
2418 }),
2419 Decl);
2420 }
2421 return HadError;
2422}
2423
2425 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
2426 if (Known != Modules.end())
2427 return Known->getValue();
2428
2429 auto ParsedMod = ParsedModules.find(Name);
2430 if (ParsedMod == ParsedModules.end())
2431 return nullptr;
2432
2433 Diags.Report(diag::remark_mmap_load_module) << Name;
2434
2435 for (const auto &ModuleDecl : ParsedMod->second) {
2436 const modulemap::ModuleMapFile &MMF = *ModuleDecl.first;
2437 ModuleMapLoader Loader(SourceMgr, Diags, const_cast<ModuleMap &>(*this),
2438 MMF.ID, *MMF.Dir, MMF.IsSystem,
2440 if (Loader.loadModuleDecl(*ModuleDecl.second))
2441 return nullptr;
2442 }
2443
2444 return findModule(Name);
2445}
2446
2448 bool ImplicitlyDiscovered,
2449 DirectoryEntryRef Dir, FileID ID,
2450 unsigned *Offset,
2451 SourceLocation ExternModuleLoc) {
2452 assert(Target && "Missing target information");
2453 llvm::DenseMap<const FileEntry *, bool>::iterator Known =
2454 LoadedModuleMap.find(File);
2455 if (Known != LoadedModuleMap.end())
2456 return Known->second;
2457
2458 // If the module map file wasn't already entered, do so now.
2459 if (ID.isInvalid()) {
2460 // TODO: The way we compute affecting module maps requires this to be a
2461 // local FileID. This should be changed to reuse loaded FileIDs when
2462 // available, and change the way that affecting module maps are
2463 // computed to not require this.
2464 FileID &LocalFID = ModuleMapLocalFileID[File];
2465 if (LocalFID.isInvalid()) {
2466 auto FileCharacter =
2468 LocalFID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2469 }
2470 ID = LocalFID;
2471 }
2472
2473 assert(Target && "Missing target information");
2474 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
2475 if (!Buffer)
2476 return LoadedModuleMap[File] = true;
2477 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2478 "invalid buffer offset");
2479
2480 std::optional<modulemap::ModuleMapFile> MMF = modulemap::parseModuleMap(
2481 ID, Dir, SourceMgr, Diags, IsSystem, ImplicitlyDiscovered, Offset);
2482 bool Result = false;
2483 if (MMF) {
2484 Diags.Report(diag::remark_mmap_load) << File.getName();
2485 ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem,
2486 ImplicitlyDiscovered);
2487 Result = Loader.parseAndLoadModuleMapFile(*MMF);
2488
2489 // Also record that this was parsed if it wasn't previously. This is used
2490 // for diagnostics.
2491 llvm::DenseMap<const FileEntry *,
2492 const modulemap::ModuleMapFile *>::iterator PKnown =
2493 ParsedModuleMap.find(File);
2494 if (PKnown == ParsedModuleMap.end()) {
2495 ParsedModuleMaps.push_back(
2496 std::make_unique<modulemap::ModuleMapFile>(std::move(*MMF)));
2497 ParsedModuleMap[File] = &*ParsedModuleMaps.back();
2498 }
2499 }
2500 LoadedModuleMap[File] = Result;
2501
2502 // Notify callbacks that we observed it.
2503 // FIXME: We should only report module maps that were actually used.
2504 for (const auto &Cb : Callbacks)
2505 Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);
2506
2507 return Result;
2508}
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
std::shared_ptr< TokenRole > Role
A token can have a special role that can carry extra information about the token's formatting.
FormatToken * Next
The next token in the unwrapped line.
#define ALIAS(NAME, TOK, FLAGS)
#define KEYWORD(NAME, FLAGS)
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
static Module * getTopLevelOrNull(Module *M)
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
static constexpr llvm::StringRef kPrivateModuleSuffix
Definition ModuleMap.cpp:49
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives.
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:234
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition Diagnostic.h:972
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition FileEntry.h:57
const FileEntry & getFileEntry() const
Definition FileEntry.h:70
StringRef getName() const
The name of this FileEntry.
Definition FileEntry.h:61
DirectoryEntryRef getDir() const
Definition FileEntry.h:78
Cached information about one file (either on disk or in the virtual file system).
Definition FileEntry.h:273
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isInvalid() const
Implements support for file system lookup, file system caching, and directory search management.
Definition FileManager.h:57
llvm::vfs::FileSystem & getVirtualFileSystem() const
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:142
unsigned ImplicitModuleMaps
Implicit module maps.
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
void loadTopLevelSystemModules()
Load all known, top-level system modules.
const HeaderSearchOptions & getHeaderSearchOpts() const
Retrieve the header-search options with which this header search was initialized.
OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework)
Try to find a module map file in the given directory, returning nullopt if none is found.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Required to construct a Module.
Definition Module.h:332
ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem, bool ImplicitlyDiscovered)
bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD)
bool parseAndLoadModuleMapFile(const modulemap::ModuleMapFile &MMF)
bool loadModuleDecl(const modulemap::ModuleDecl &MD)
A header that is known to reside within a given module, whether it was included or excluded.
Definition ModuleMap.h:158
bool isAccessibleFrom(Module *M) const
Whether this header is accessible from the specified module.
Definition ModuleMap.h:184
ModuleHeaderRole getRole() const
The role of this header within the module.
Definition ModuleMap.h:176
Module * getModule() const
Retrieve the module the header is stored in.
Definition ModuleMap.h:173
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
Definition ModuleMap.cpp:64
friend class ModuleMapLoader
Definition ModuleMap.h:199
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, DirectoryEntryRef Dir, FileID ID=FileID(), SourceLocation ExternModuleLoc=SourceLocation())
Parse a module map without creating clang::Module instances.
void dump()
Dump the contents of the module map, for debugging purposes.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
ModuleRef lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Definition ModuleMap.cpp:71
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory, SourceLocation Loc=SourceLocation())
Sets the umbrella header of the given module to the given header.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false, SourceLocation Loc=SourceLocation())
Adds this header to the given module.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
OptionalFileEntryRef findUmbrellaHeaderForModule(Module *M, std::string NameAsWritten, SmallVectorImpl< char > &RelativePathName)
Find the FileEntry for an umbrella header in a module as if it was written in the module map as a hea...
FileID getModuleMapFileIDForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory, SourceLocation Loc=SourceLocation())
Sets the umbrella directory of the given module to the given directory.
Module * findOrCreateModuleFirst(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Call ModuleMap::findOrCreateModule and throw away the information whether the module was found or cre...
Definition ModuleMap.h:572
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Module * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Create new submodule, assuming it does not exist.
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
~ModuleMap()
Destroy the module map.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
void setTarget(const TargetInfo &Target)
Set the target information.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
Definition ModuleMap.cpp:53
ModuleHeaderRole
Flags describing the role of a module header.
Definition ModuleMap.h:126
@ PrivateHeader
This header is included but private.
Definition ModuleMap.h:131
@ ExcludedHeader
This header is explicitly excluded from the module.
Definition ModuleMap.h:138
@ NormalHeader
This header is normally included in the module.
Definition ModuleMap.h:128
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Definition ModuleMap.h:135
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module interface unit.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
void loadAllParsedModules()
Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)
Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...
Module * findOrLoadModule(StringRef Name)
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
Definition ModuleMap.cpp:88
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Reference to a module that consists of either an existing/materialized Module object,...
Definition Module.h:275
Describes a module or submodule.
Definition Module.h:340
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition Module.h:671
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
Definition Module.cpp:156
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
Definition Module.h:401
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
Definition Module.h:606
SourceLocation UmbrellaDeclLoc
The location of the umbrella header or directory declaration.
Definition Module.h:404
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
Definition Module.cpp:288
std::pair< ModuleRef, bool > ExportDecl
Describes an exported module.
Definition Module.h:668
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
Definition Module.cpp:456
SourceLocation DefinitionLoc
The location of the module definition.
Definition Module.h:346
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Definition Module.h:541
Module * Parent
The parent of this module.
Definition Module.h:389
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
Definition Module.cpp:326
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
Definition Module.h:537
@ HK_PrivateTextual
Definition Module.h:482
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
Definition Module.cpp:255
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Definition Module.h:599
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition Module.h:589
std::string Name
The name of this module.
Definition Module.h:343
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Definition Module.h:835
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
Definition Module.h:720
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
Definition Module.h:689
void addHeader(HeaderKind HK, Header H)
Definition Module.h:508
std::string UmbrellaRelativeToRootModuleDirectory
Definition Module.h:413
OptionalDirectoryEntryRef Directory
The build directory of this module.
Definition Module.h:394
ModuleRef findSubmodule(StringRef Name) const
Find the submodule with the given name.
Definition Module.cpp:351
ArrayRef< Header > getHeaders(HeaderKind HK) const
Definition Module.h:502
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
Definition Module.h:616
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Definition Module.h:741
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
Definition Module.cpp:194
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
Definition Module.h:825
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Definition Module.h:786
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition Module.h:363
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition Module.h:381
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition Module.h:360
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition Module.h:357
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition Module.h:376
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition Module.h:373
unsigned IsFramework
Whether this is a framework module.
Definition Module.h:580
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
Definition Module.h:417
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition Module.cpp:240
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Definition Module.h:410
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Definition Module.h:611
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition Module.h:940
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
Definition Module.cpp:264
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
Definition Module.h:724
std::vector< Conflict > Conflicts
The list of conflicts.
Definition Module.h:753
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
Definition TargetInfo.h:226
Defines the clang::TargetInfo interface.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
bool Sub(InterpState &S, CodePtr OpPC)
Definition Interp.h:447
std::optional< ModuleMapFile > parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, DiagnosticsEngine &Diags, bool IsSystem, bool ImplicitlyDiscovered, unsigned *Offset)
Parse a module map file into an in memory representation.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:196
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
Definition CharInfo.h:61
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
Definition Module.h:63
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
Definition CharInfo.h:244
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
Definition Linkage.h:54
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
Definition TypeBase.h:906
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Definition CharInfo.h:114
@ Keyword
The name has been typo-corrected to a keyword.
Definition Sema.h:556
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
@ Other
Other implicit parameter.
Definition Decl.h:1775
int const char * function
Definition c++config.h:31
unsigned IsExternC
Whether this is an extern "C" module.
Definition Module.h:256
unsigned IsSystem
Whether this is a system module.
Definition Module.h:252
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
Definition Module.h:265
A conflict between two modules.
Definition Module.h:744
std::string Message
The message provided to the user when there is a conflict.
Definition Module.h:749
ModuleRef Other
The module that this module conflicts with.
Definition Module.h:746
Information about a header directive as found in the module map file.
Definition Module.h:487
std::string NameAsWritten
Definition Module.h:488
FileEntryRef Entry
Definition Module.h:490
A library or framework to link against when an entity from this module is used.
Definition Module.h:703
std::string Message
The message provided to the user when there is a conflict.
Definition Module.h:736
ModuleId Id
The (unresolved) module id.
Definition Module.h:733
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
Definition Module.h:675
Stored information about a header directive that was found in the module map file but has not been re...
Definition Module.h:525
std::optional< time_t > ModTime
Definition Module.h:532
std::vector< StringRef > Macros
std::optional< int64_t > Size
std::optional< int64_t > MTime
ModuleAttributes Attrs
Points to the first keyword in the decl.
std::vector< Decl > Decls
Represents the parsed form of a module map file.
std::vector< TopLevelDecl > Decls
FileID ID
The FileID used to parse this module map. This is always a local ID.
OptionalDirectoryEntryRef Dir
The directory in which the module map was discovered.
std::vector< RequiresFeature > Features