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