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