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