clang 22.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
625ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
626 assert(!Headers.count(File) && "already have a module for this header");
627
629 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
630 if (H) {
631 Module *Result = H.getModule();
632
633 // Search up the module stack until we find a module with an umbrella
634 // directory.
635 Module *UmbrellaModule = Result;
636 while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)
637 UmbrellaModule = UmbrellaModule->Parent;
638
639 if (UmbrellaModule->InferSubmodules) {
640 FileID UmbrellaModuleMap = getModuleMapFileIDForUniquing(UmbrellaModule);
641
642 // Infer submodules for each of the directories we found between
643 // the directory of the umbrella header and the directory where
644 // the actual header is located.
645 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
646
647 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
648 // Find or create the module that corresponds to this directory name.
649 SmallString<32> NameBuf;
650 StringRef Name = sanitizeFilenameAsIdentifier(
651 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
652 Result = findOrCreateModuleFirst(Name, Result, /*IsFramework=*/false,
653 Explicit);
654 setInferredModuleAllowedBy(Result, UmbrellaModuleMap);
655
656 // Associate the module and the directory.
657 UmbrellaDirs[SkippedDir] = Result;
658
659 // If inferred submodules export everything they import, add a
660 // wildcard to the set of exports.
661 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
662 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
663 }
664
665 // Infer a submodule with the same name as this header file.
666 SmallString<32> NameBuf;
667 StringRef Name = sanitizeFilenameAsIdentifier(
668 llvm::sys::path::stem(File.getName()), NameBuf);
669 Result = findOrCreateModuleFirst(Name, Result, /*IsFramework=*/false,
670 Explicit);
671 setInferredModuleAllowedBy(Result, UmbrellaModuleMap);
672 Result->addTopHeader(File);
673
674 // If inferred submodules export everything they import, add a
675 // wildcard to the set of exports.
676 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
677 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
678 } else {
679 // Record each of the directories we stepped through as being part of
680 // the module we found, since the umbrella header covers them all.
681 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
682 UmbrellaDirs[SkippedDirs[I]] = Result;
683 }
684
686 Headers[File].push_back(Header);
687 return Header;
688 }
689
690 return {};
691}
692
695 HeadersMap::iterator Known = findKnownHeader(File);
696 if (Known != Headers.end())
697 return Known->second;
698
699 if (findOrCreateModuleForHeaderInUmbrellaDir(File))
700 return Headers.find(File)->second;
701
702 return {};
703}
704
707 // FIXME: Is this necessary?
709 auto It = Headers.find(File);
710 if (It == Headers.end())
711 return {};
712 return It->second;
713}
714
716 return isHeaderUnavailableInModule(Header, nullptr);
717}
718
720 FileEntryRef Header, const Module *RequestingModule) const {
722 HeadersMap::const_iterator Known = Headers.find(Header);
723 if (Known != Headers.end()) {
725 I = Known->second.begin(),
726 E = Known->second.end();
727 I != E; ++I) {
728
729 if (I->getRole() == ModuleMap::ExcludedHeader)
730 continue;
731
732 if (I->isAvailable() &&
733 (!RequestingModule ||
734 I->getModule()->isSubModuleOf(RequestingModule))) {
735 // When no requesting module is available, the caller is looking if a
736 // header is part a module by only looking into the module map. This is
737 // done by warn_uncovered_module_header checks; don't consider textual
738 // headers part of it in this mode, otherwise we get misleading warnings
739 // that a umbrella header is not including a textual header.
740 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
741 continue;
742 return false;
743 }
744 }
745 return true;
746 }
747
748 OptionalDirectoryEntryRef Dir = Header.getDir();
750 StringRef DirName = Dir->getName();
751
752 auto IsUnavailable = [&](const Module *M) {
753 return !M->isAvailable() && (!RequestingModule ||
754 M->isSubModuleOf(RequestingModule));
755 };
756
757 // Keep walking up the directory hierarchy, looking for a directory with
758 // an umbrella header.
759 do {
760 auto KnownDir = UmbrellaDirs.find(*Dir);
761 if (KnownDir != UmbrellaDirs.end()) {
762 Module *Found = KnownDir->second;
763 if (IsUnavailable(Found))
764 return true;
765
766 // Search up the module stack until we find a module with an umbrella
767 // directory.
768 Module *UmbrellaModule = Found;
769 while (!UmbrellaModule->getEffectiveUmbrellaDir() &&
770 UmbrellaModule->Parent)
771 UmbrellaModule = UmbrellaModule->Parent;
772
773 if (UmbrellaModule->InferSubmodules) {
774 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
775 // Find or create the module that corresponds to this directory name.
776 SmallString<32> NameBuf;
777 StringRef Name = sanitizeFilenameAsIdentifier(
778 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
780 if (!Found)
781 return false;
782 if (IsUnavailable(Found))
783 return true;
784 }
785
786 // Infer a submodule with the same name as this header file.
787 SmallString<32> NameBuf;
788 StringRef Name = sanitizeFilenameAsIdentifier(
789 llvm::sys::path::stem(Header.getName()),
790 NameBuf);
792 if (!Found)
793 return false;
794 }
795
796 return IsUnavailable(Found);
797 }
798
799 SkippedDirs.push_back(*Dir);
800
801 // Retrieve our parent path.
802 DirName = llvm::sys::path::parent_path(DirName);
803 if (DirName.empty())
804 break;
805
806 // Resolve the parent path to a directory entry.
807 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
808 } while (Dir);
809
810 return false;
811}
812
813Module *ModuleMap::findModule(StringRef Name) const {
814 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
815 if (Known != Modules.end())
816 return Known->getValue();
817
818 return nullptr;
819}
820
822 if (Module *SubM = Parent->findSubmodule(Name))
823 return SubM;
824 if (!Parent->InferSubmodules)
825 return nullptr;
826 Module *Result = new (ModulesAlloc.Allocate())
827 Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent, false,
828 Parent->InferExplicitSubmodules, 0);
829 Result->InferExplicitSubmodules = Parent->InferExplicitSubmodules;
830 Result->InferSubmodules = Parent->InferSubmodules;
831 Result->InferExportWildcard = Parent->InferExportWildcard;
832 if (Result->InferExportWildcard)
833 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
834 return Result;
835}
836
838 Module *Context) const {
839 for(; Context; Context = Context->Parent) {
840 if (Module *Sub = lookupModuleQualified(Name, Context))
841 return Sub;
842 }
843
844 return findModule(Name);
845}
846
847Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
848 if (!Context)
849 return findModule(Name);
850
851 return Context->findSubmodule(Name);
852}
853
854std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
855 Module *Parent,
856 bool IsFramework,
857 bool IsExplicit) {
858 // Try to find an existing module with this name.
859 if (Module *Sub = lookupModuleQualified(Name, Parent))
860 return std::make_pair(Sub, false);
861
862 // Create a new module with this name.
863 Module *M = createModule(Name, Parent, IsFramework, IsExplicit);
864 return std::make_pair(M, true);
865}
866
867Module *ModuleMap::createModule(StringRef Name, Module *Parent,
868 bool IsFramework, bool IsExplicit) {
869 assert(lookupModuleQualified(Name, Parent) == nullptr &&
870 "Creating duplicate submodule");
871
872 Module *Result = new (ModulesAlloc.Allocate())
873 Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent,
874 IsFramework, IsExplicit, NumCreatedModules++);
875 if (!Parent) {
876 if (LangOpts.CurrentModule == Name)
877 SourceModule = Result;
878 Modules[Name] = Result;
879 ModuleScopeIDs[Result] = CurrentModuleScopeID;
880 }
881 return Result;
882}
883
885 Module *Parent) {
886 auto *Result = new (ModulesAlloc.Allocate()) Module(
887 ModuleConstructorTag{}, "<global>", Loc, Parent, /*IsFramework=*/false,
888 /*IsExplicit=*/true, NumCreatedModules++);
890 // If the created module isn't owned by a parent, send it to PendingSubmodules
891 // to wait for its parent.
892 if (!Result->Parent)
893 PendingSubmodules.emplace_back(Result);
894 return Result;
895}
896
897Module *
899 Module *Parent) {
900 assert(Parent && "We should only create an implicit global module fragment "
901 "in a module purview");
902 // Note: Here the `IsExplicit` parameter refers to the semantics in clang
903 // modules. All the non-explicit submodules in clang modules will be exported
904 // too. Here we simplify the implementation by using the concept.
905 auto *Result = new (ModulesAlloc.Allocate())
906 Module(ModuleConstructorTag{}, "<implicit global>", Loc, Parent,
907 /*IsFramework=*/false, /*IsExplicit=*/false, NumCreatedModules++);
909 return Result;
910}
911
912Module *
914 SourceLocation Loc) {
915 auto *Result = new (ModulesAlloc.Allocate()) Module(
916 ModuleConstructorTag{}, "<private>", Loc, Parent, /*IsFramework=*/false,
917 /*IsExplicit=*/true, NumCreatedModules++);
919 return Result;
920}
921
923 Module::ModuleKind Kind) {
924 auto *Result = new (ModulesAlloc.Allocate())
925 Module(ModuleConstructorTag{}, Name, Loc, nullptr, /*IsFramework=*/false,
926 /*IsExplicit=*/false, NumCreatedModules++);
927 Result->Kind = Kind;
928
929 // Reparent any current global module fragment as a submodule of this module.
930 for (auto &Submodule : PendingSubmodules)
931 Submodule->setParent(Result);
932 PendingSubmodules.clear();
933 return Result;
934}
935
937 StringRef Name) {
938 assert(LangOpts.CurrentModule == Name && "module name mismatch");
939 assert(!Modules[Name] && "redefining existing module");
940
941 auto *Result =
943 Modules[Name] = SourceModule = Result;
944
945 // Mark the main source file as being within the newly-created module so that
946 // declarations and macros are properly visibility-restricted to it.
947 auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
948 assert(MainFile && "no input file for module interface");
949 Headers[*MainFile].push_back(KnownHeader(Result, PrivateHeader));
950
951 return Result;
952}
953
955 StringRef Name) {
956 assert(LangOpts.CurrentModule == Name && "module name mismatch");
957 // The interface for this implementation must exist and be loaded.
958 assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&
959 "creating implementation module without an interface");
960
961 // Create an entry in the modules map to own the implementation unit module.
962 // User module names must not start with a period (so that this cannot clash
963 // with any legal user-defined module name).
964 StringRef IName = ".ImplementationUnit";
965 assert(!Modules[IName] && "multiple implementation units?");
966
967 auto *Result =
969 Modules[IName] = SourceModule = Result;
970
971 // Check that the main file is present.
972 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
973 "no input file for module implementation");
974
975 return Result;
976}
977
979 Module::Header H) {
980 assert(LangOpts.CurrentModule == Name && "module name mismatch");
981 assert(!Modules[Name] && "redefining existing module");
982
983 auto *Result = new (ModulesAlloc.Allocate())
984 Module(ModuleConstructorTag{}, Name, Loc, nullptr, /*IsFramework=*/false,
985 /*IsExplicit=*/false, NumCreatedModules++);
987 Modules[Name] = SourceModule = Result;
989 return Result;
990}
991
992/// For a framework module, infer the framework against which we
993/// should link.
994static void inferFrameworkLink(Module *Mod) {
995 assert(Mod->IsFramework && "Can only infer linking for framework modules");
996 assert(!Mod->isSubFramework() &&
997 "Can only infer linking for top-level frameworks");
998
999 StringRef FrameworkName(Mod->Name);
1000 FrameworkName.consume_back("_Private");
1001 Mod->LinkLibraries.push_back(Module::LinkLibrary(FrameworkName.str(),
1002 /*IsFramework=*/true));
1003}
1004
1005Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
1006 bool IsSystem, Module *Parent) {
1007 Attributes Attrs;
1008 Attrs.IsSystem = IsSystem;
1009 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
1010}
1011
1012Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
1013 Attributes Attrs, Module *Parent) {
1014 // Note: as an egregious but useful hack we use the real path here, because
1015 // we might be looking at an embedded framework that symlinks out to a
1016 // top-level framework, and we need to infer as if we were naming the
1017 // top-level framework.
1018 StringRef FrameworkDirName =
1019 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
1020
1021 // In case this is a case-insensitive filesystem, use the canonical
1022 // directory name as the ModuleName, since modules are case-sensitive.
1023 // FIXME: we should be able to give a fix-it hint for the correct spelling.
1024 SmallString<32> ModuleNameStorage;
1025 StringRef ModuleName = sanitizeFilenameAsIdentifier(
1026 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1027
1028 // Check whether we've already found this module.
1029 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
1030 return Mod;
1031
1032 FileManager &FileMgr = SourceMgr.getFileManager();
1033
1034 // If the framework has a parent path from which we're allowed to infer
1035 // a framework module, do so.
1036 FileID ModuleMapFID;
1037 if (!Parent) {
1038 // Determine whether we're allowed to infer a module map.
1039 bool canInfer = false;
1040 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1041 // Figure out the parent path.
1042 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1043 if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {
1044 // Check whether we have already looked into the parent directory
1045 // for a module map.
1046 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1047 inferred = InferredDirectories.find(*ParentDir);
1048 if (inferred == InferredDirectories.end()) {
1049 // We haven't looked here before. Load a module map, if there is
1050 // one.
1051 bool IsFrameworkDir = Parent.ends_with(".framework");
1052 if (OptionalFileEntryRef ModMapFile =
1053 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
1054 // TODO: Parsing a module map should populate `InferredDirectories`
1055 // so we don't need to do a full load here.
1056 parseAndLoadModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
1057 inferred = InferredDirectories.find(*ParentDir);
1058 }
1059
1060 if (inferred == InferredDirectories.end())
1061 inferred = InferredDirectories.insert(
1062 std::make_pair(*ParentDir, InferredDirectory())).first;
1063 }
1064
1065 if (inferred->second.InferModules) {
1066 // We're allowed to infer for this directory, but make sure it's okay
1067 // to infer this particular module.
1068 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1069 canInfer =
1070 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1071
1072 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1073 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1074 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1075 Attrs.NoUndeclaredIncludes |=
1076 inferred->second.Attrs.NoUndeclaredIncludes;
1077 ModuleMapFID = inferred->second.ModuleMapFID;
1078 }
1079 }
1080 }
1081
1082 // If we're not allowed to infer a framework module, don't.
1083 if (!canInfer)
1084 return nullptr;
1085 } else {
1086 ModuleMapFID = getModuleMapFileIDForUniquing(Parent);
1087 }
1088
1089 // Look for an umbrella header.
1090 SmallString<128> UmbrellaName = FrameworkDir.getName();
1091 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1092 auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
1093
1094 // FIXME: If there's no umbrella header, we could probably scan the
1095 // framework to load *everything*. But, it's not clear that this is a good
1096 // idea.
1097 if (!UmbrellaHeader)
1098 return nullptr;
1099
1100 Module *Result = new (ModulesAlloc.Allocate())
1101 Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,
1102 /*IsFramework=*/true, /*IsExplicit=*/false, NumCreatedModules++);
1103 setInferredModuleAllowedBy(Result, ModuleMapFID);
1104 if (!Parent) {
1105 if (LangOpts.CurrentModule == ModuleName)
1106 SourceModule = Result;
1107 Modules[ModuleName] = Result;
1108 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1109 }
1110
1111 Result->IsSystem |= Attrs.IsSystem;
1112 Result->IsExternC |= Attrs.IsExternC;
1113 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1114 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1115 Result->Directory = FrameworkDir;
1116
1117 // Chop off the first framework bit, as that is implied.
1118 StringRef RelativePath = UmbrellaName.str().substr(
1119 Result->getTopLevelModule()->Directory->getName().size());
1120 RelativePath = llvm::sys::path::relative_path(RelativePath);
1121
1122 // umbrella header "umbrella-header-name"
1123 setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h",
1124 RelativePath);
1125
1126 // export *
1127 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
1128
1129 // module * { export * }
1130 Result->InferSubmodules = true;
1131 Result->InferExportWildcard = true;
1132
1133 // Look for subframeworks.
1134 std::error_code EC;
1135 SmallString<128> SubframeworksDirName = FrameworkDir.getName();
1136 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1137 llvm::sys::path::native(SubframeworksDirName);
1138 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1139 for (llvm::vfs::directory_iterator
1140 Dir = FS.dir_begin(SubframeworksDirName, EC),
1141 DirEnd;
1142 Dir != DirEnd && !EC; Dir.increment(EC)) {
1143 if (!StringRef(Dir->path()).ends_with(".framework"))
1144 continue;
1145
1146 if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {
1147 // Note: as an egregious but useful hack, we use the real path here and
1148 // check whether it is actually a subdirectory of the parent directory.
1149 // This will not be the case if the 'subframework' is actually a symlink
1150 // out to a top-level framework.
1151 StringRef SubframeworkDirName =
1152 FileMgr.getCanonicalName(*SubframeworkDir);
1153 bool FoundParent = false;
1154 do {
1155 // Get the parent directory name.
1156 SubframeworkDirName
1157 = llvm::sys::path::parent_path(SubframeworkDirName);
1158 if (SubframeworkDirName.empty())
1159 break;
1160
1161 if (auto SubDir =
1162 FileMgr.getOptionalDirectoryRef(SubframeworkDirName)) {
1163 if (*SubDir == FrameworkDir) {
1164 FoundParent = true;
1165 break;
1166 }
1167 }
1168 } while (true);
1169
1170 if (!FoundParent)
1171 continue;
1172
1173 // FIXME: Do we want to warn about subframeworks without umbrella headers?
1174 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1175 }
1176 }
1177
1178 // If the module is a top-level framework, automatically link against the
1179 // framework.
1180 if (!Result->isSubFramework())
1182
1183 return Result;
1184}
1185
1186Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
1187 Module *ShadowingModule) {
1188
1189 // Create a new module with this name.
1190 Module *Result = new (ModulesAlloc.Allocate())
1191 Module(ModuleConstructorTag{}, Name, SourceLocation(), /*Parent=*/nullptr,
1192 IsFramework, /*IsExplicit=*/false, NumCreatedModules++);
1193 Result->ShadowingModule = ShadowingModule;
1194 Result->markUnavailable(/*Unimportable*/true);
1195 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1196 ShadowModules.push_back(Result);
1197
1198 return Result;
1199}
1200
1202 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1203 const Twine &PathRelativeToRootModuleDirectory) {
1204 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
1205 Mod->Umbrella = UmbrellaHeader;
1206 Mod->UmbrellaAsWritten = NameAsWritten.str();
1208 PathRelativeToRootModuleDirectory.str();
1209 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1210
1211 // Notify callbacks that we just added a new header.
1212 for (const auto &Cb : Callbacks)
1213 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1214}
1215
1217 Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
1218 const Twine &PathRelativeToRootModuleDirectory) {
1219 Mod->Umbrella = UmbrellaDir;
1220 Mod->UmbrellaAsWritten = NameAsWritten.str();
1222 PathRelativeToRootModuleDirectory.str();
1223 UmbrellaDirs[UmbrellaDir] = Mod;
1224}
1225
1226void ModuleMap::addUnresolvedHeader(Module *Mod,
1228 bool &NeedsFramework) {
1229 // If there is a builtin counterpart to this file, add it now so it can
1230 // wrap the system header.
1231 if (resolveAsBuiltinHeader(Mod, Header)) {
1232 // If we have both a builtin and system version of the file, the
1233 // builtin version may want to inject macros into the system header, so
1234 // force the system header to be treated as a textual header in this
1235 // case.
1238 Header.HasBuiltinHeader = true;
1239 }
1240
1241 // If possible, don't stat the header until we need to. This requires the
1242 // user to have provided us with some stat information about the file.
1243 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1244 // headers.
1245 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1246 Header.Kind != Module::HK_Excluded) {
1247 // We expect more variation in mtime than size, so if we're given both,
1248 // use the mtime as the key.
1249 if (Header.ModTime)
1250 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1251 else
1252 LazyHeadersBySize[*Header.Size].push_back(Mod);
1253 Mod->UnresolvedHeaders.push_back(Header);
1254 return;
1255 }
1256
1257 // We don't have stat information or can't defer looking this file up.
1258 // Perform the lookup now.
1259 resolveHeader(Mod, Header, NeedsFramework);
1260}
1261
1263 auto BySize = LazyHeadersBySize.find(File->getSize());
1264 if (BySize != LazyHeadersBySize.end()) {
1265 for (auto *M : BySize->second)
1267 LazyHeadersBySize.erase(BySize);
1268 }
1269
1270 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1271 if (ByModTime != LazyHeadersByModTime.end()) {
1272 for (auto *M : ByModTime->second)
1274 LazyHeadersByModTime.erase(ByModTime);
1275 }
1276}
1277
1279 Module *Mod, std::optional<const FileEntry *> File) const {
1280 bool NeedsFramework = false;
1282 const auto Size = File ? (*File)->getSize() : 0;
1283 const auto ModTime = File ? (*File)->getModificationTime() : 0;
1284
1285 for (auto &Header : Mod->UnresolvedHeaders) {
1286 if (File && ((Header.ModTime && Header.ModTime != ModTime) ||
1287 (Header.Size && Header.Size != Size)))
1288 NewHeaders.push_back(Header);
1289 else
1290 // This operation is logically const; we're just changing how we represent
1291 // the header information for this file.
1292 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1293 }
1294 Mod->UnresolvedHeaders.swap(NewHeaders);
1295}
1296
1298 ModuleHeaderRole Role, bool Imported) {
1299 KnownHeader KH(Mod, Role);
1300
1301 FileEntryRef HeaderEntry = Header.Entry;
1302
1303 // Only add each header to the headers list once.
1304 // FIXME: Should we diagnose if a header is listed twice in the
1305 // same module definition?
1306 auto &HeaderList = Headers[HeaderEntry];
1307 if (llvm::is_contained(HeaderList, KH))
1308 return;
1309
1310 HeaderList.push_back(KH);
1311 Mod->addHeader(headerRoleToKind(Role), std::move(Header));
1312
1313 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
1314 if (!Imported || isCompilingModuleHeader) {
1315 // When we import HeaderFileInfo, the external source is expected to
1316 // set the isModuleHeader flag itself.
1317 HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role, isCompilingModuleHeader);
1318 }
1319
1320 // Notify callbacks that we just added a new header.
1321 for (const auto &Cb : Callbacks)
1322 Cb->moduleMapAddHeader(HeaderEntry.getName());
1323}
1324
1326 DirectoryEntryRef Dir, FileID ID,
1327 SourceLocation ExternModuleLoc) {
1328 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator
1329 Known = ParsedModuleMap.find(File);
1330 if (Known != ParsedModuleMap.end())
1331 return Known->second == nullptr;
1332
1333 // If the module map file wasn't already entered, do so now.
1334 if (ID.isInvalid()) {
1335 ID = SourceMgr.translateFile(File);
1336 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {
1337 auto FileCharacter =
1339 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
1340 }
1341 }
1342
1343 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
1344 if (!Buffer) {
1345 ParsedModuleMap[File] = nullptr;
1346 return true;
1347 }
1348
1349 Diags.Report(diag::remark_mmap_parse) << File.getName();
1350 std::optional<modulemap::ModuleMapFile> MaybeMMF =
1351 modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, nullptr);
1352
1353 if (!MaybeMMF) {
1354 ParsedModuleMap[File] = nullptr;
1355 return true;
1356 }
1357
1358 ParsedModuleMaps.push_back(
1359 std::make_unique<modulemap::ModuleMapFile>(std::move(*MaybeMMF)));
1360 const modulemap::ModuleMapFile &MMF = *ParsedModuleMaps.back();
1361 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;
1362 for (const auto &Decl : MMF.Decls) {
1363 std::visit(llvm::makeVisitor(
1364 [&](const modulemap::ModuleDecl &MD) {
1365 // Only use the first part of the name even for submodules.
1366 // This will correctly load the submodule declarations when
1367 // the module is loaded.
1368 auto &ModuleDecls =
1369 ParsedModules[StringRef(MD.Id.front().first)];
1370 ModuleDecls.push_back(std::pair(&MMF, &MD));
1371 },
1372 [&](const modulemap::ExternModuleDecl &EMD) {
1373 PendingExternalModuleMaps.push_back(&EMD);
1374 }),
1375 Decl);
1376 }
1377
1378 for (const modulemap::ExternModuleDecl *EMD : PendingExternalModuleMaps) {
1379 StringRef FileNameRef = EMD->Path;
1380 SmallString<128> ModuleMapFileName;
1381 if (llvm::sys::path::is_relative(FileNameRef)) {
1382 ModuleMapFileName += Dir.getName();
1383 llvm::sys::path::append(ModuleMapFileName, EMD->Path);
1384 FileNameRef = ModuleMapFileName;
1385 }
1386
1387 if (auto EFile =
1388 SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {
1389 parseModuleMapFile(*EFile, IsSystem, EFile->getDir(), FileID(),
1390 ExternModuleLoc);
1391 }
1392 }
1393
1394 ParsedModuleMap[File] = &MMF;
1395
1396 for (const auto &Cb : Callbacks)
1397 Cb->moduleMapFileRead(SourceLocation(), File, IsSystem);
1398
1399 return false;
1400}
1401
1404 return {};
1405
1406 return SourceMgr.getFileID(Module->DefinitionLoc);
1407}
1408
1411 return SourceMgr.getFileEntryRefForID(getContainingModuleMapFileID(Module));
1412}
1413
1415 if (M->IsInferred) {
1416 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1417 return InferredModuleAllowedBy.find(M)->second;
1418 }
1420}
1421
1424 return SourceMgr.getFileEntryRefForID(getModuleMapFileIDForUniquing(M));
1425}
1426
1428 M->IsInferred = true;
1429 InferredModuleAllowedBy[M] = ModMapFID;
1430}
1431
1432std::error_code
1434 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1435
1436 // Do not canonicalize within the framework; the module map loader expects
1437 // Modules/ not Versions/A/Modules.
1438 if (llvm::sys::path::filename(Dir) == "Modules") {
1439 StringRef Parent = llvm::sys::path::parent_path(Dir);
1440 if (Parent.ends_with(".framework"))
1441 Dir = Parent;
1442 }
1443
1444 FileManager &FM = SourceMgr.getFileManager();
1445 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1446 if (!DirEntry)
1447 return llvm::errorToErrorCode(DirEntry.takeError());
1448
1449 // Canonicalize the directory.
1450 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
1451 if (CanonicalDir != Dir)
1452 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1453
1454 // In theory, the filename component should also be canonicalized if it
1455 // on a case-insensitive filesystem. However, the extra canonicalization is
1456 // expensive and if clang looked up the filename it will always be lowercase.
1457
1458 // Remove ., remove redundant separators, and switch to native separators.
1459 // This is needed for separators between CanonicalDir and the filename.
1460 llvm::sys::path::remove_dots(Path);
1461
1462 return std::error_code();
1463}
1464
1467 AdditionalModMaps[M].insert(ModuleMap);
1468}
1469
1470LLVM_DUMP_METHOD void ModuleMap::dump() {
1471 llvm::errs() << "Modules:";
1472 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1473 MEnd = Modules.end();
1474 M != MEnd; ++M)
1475 M->getValue()->print(llvm::errs(), 2);
1476
1477 llvm::errs() << "Headers:";
1478 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1479 H != HEnd; ++H) {
1480 llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1481 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1482 E = H->second.end();
1483 I != E; ++I) {
1484 if (I != H->second.begin())
1485 llvm::errs() << ",";
1486 llvm::errs() << I->getModule()->getFullModuleName();
1487 }
1488 llvm::errs() << "\n";
1489 }
1490}
1491
1492bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
1493 auto Unresolved = std::move(Mod->UnresolvedExports);
1494 Mod->UnresolvedExports.clear();
1495 for (auto &UE : Unresolved) {
1496 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
1497 if (Export.getPointer() || Export.getInt())
1498 Mod->Exports.push_back(Export);
1499 else
1500 Mod->UnresolvedExports.push_back(UE);
1501 }
1502 return !Mod->UnresolvedExports.empty();
1503}
1504
1505bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
1506 auto *Top = Mod->getTopLevelModule();
1507 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1508 Top->UnresolvedDirectUses.clear();
1509 for (auto &UDU : Unresolved) {
1510 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1511 if (DirectUse)
1512 Top->DirectUses.push_back(DirectUse);
1513 else
1514 Top->UnresolvedDirectUses.push_back(UDU);
1515 }
1516 return !Top->UnresolvedDirectUses.empty();
1517}
1518
1519bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
1520 auto Unresolved = std::move(Mod->UnresolvedConflicts);
1521 Mod->UnresolvedConflicts.clear();
1522 for (auto &UC : Unresolved) {
1523 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1524 Module::Conflict Conflict;
1525 Conflict.Other = OtherMod;
1526 Conflict.Message = UC.Message;
1527 Mod->Conflicts.push_back(Conflict);
1528 } else
1529 Mod->UnresolvedConflicts.push_back(UC);
1530 }
1531 return !Mod->UnresolvedConflicts.empty();
1532}
1533
1534//----------------------------------------------------------------------------//
1535// Module map file loader
1536//----------------------------------------------------------------------------//
1537
1538namespace clang {
1540 SourceManager &SourceMgr;
1541
1542 DiagnosticsEngine &Diags;
1543 ModuleMap &Map;
1544
1545 /// The current module map file.
1546 FileID ModuleMapFID;
1547
1548 /// Source location of most recent loaded module declaration
1549 SourceLocation CurrModuleDeclLoc;
1550
1551 /// The directory that file names in this module map file should
1552 /// be resolved relative to.
1553 DirectoryEntryRef Directory;
1554
1555 /// Whether this module map is in a system header directory.
1556 bool IsSystem;
1557
1558 /// Whether an error occurred.
1559 bool HadError = false;
1560
1561 /// The active module.
1562 Module *ActiveModule = nullptr;
1563
1564 /// Whether a module uses the 'requires excluded' hack to mark its
1565 /// contents as 'textual'.
1566 ///
1567 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1568 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1569 /// non-modular headers. For backwards compatibility, we continue to
1570 /// support this idiom for just these modules, and map the headers to
1571 /// 'textual' to match the original intent.
1572 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1573
1574 void handleModuleDecl(const modulemap::ModuleDecl &MD);
1575 void handleExternModuleDecl(const modulemap::ExternModuleDecl &EMD);
1576 void handleRequiresDecl(const modulemap::RequiresDecl &RD);
1577 void handleHeaderDecl(const modulemap::HeaderDecl &HD);
1578 void handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD);
1579 void handleExportDecl(const modulemap::ExportDecl &ED);
1580 void handleExportAsDecl(const modulemap::ExportAsDecl &EAD);
1581 void handleUseDecl(const modulemap::UseDecl &UD);
1582 void handleLinkDecl(const modulemap::LinkDecl &LD);
1583 void handleConfigMacros(const modulemap::ConfigMacrosDecl &CMD);
1584 void handleConflict(const modulemap::ConflictDecl &CD);
1585 void handleInferredModuleDecl(const modulemap::ModuleDecl &MD);
1586
1587 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1588 /// module map search logic to find the appropriate private module when PCH
1589 /// is used with implicit module maps. Warn when private modules are written
1590 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1591 void diagnosePrivateModules(SourceLocation StartLoc);
1592
1593 using Attributes = ModuleMap::Attributes;
1594
1595public:
1597 ModuleMap &Map, FileID ModuleMapFID,
1598 DirectoryEntryRef Directory, bool IsSystem)
1599 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),
1600 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
1601
1602 bool loadModuleDecl(const modulemap::ModuleDecl &MD);
1605};
1606
1607} // namespace clang
1608
1609/// Private modules are canonicalized as Foo_Private. Clang provides extra
1610/// module map search logic to find the appropriate private module when PCH
1611/// is used with implicit module maps. Warn when private modules are written
1612/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1613void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {
1614 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1615 const Module *M, SourceRange ReplLoc) {
1616 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1617 diag::note_mmap_rename_top_level_private_module);
1618 D << BadName << M->Name;
1619 D << FixItHint::CreateReplacement(ReplLoc, Canonical);
1620 };
1621
1622 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1623 auto const *M = E->getValue();
1624 if (M->Directory != ActiveModule->Directory)
1625 continue;
1626
1627 SmallString<128> FullName(ActiveModule->getFullModuleName());
1628 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
1629 continue;
1630 SmallString<128> FixedPrivModDecl;
1631 SmallString<128> Canonical(M->Name);
1632 Canonical.append("_Private");
1633
1634 // Foo.Private -> Foo_Private
1635 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1636 M->Name == ActiveModule->Parent->Name) {
1637 Diags.Report(ActiveModule->DefinitionLoc,
1638 diag::warn_mmap_mismatched_private_submodule)
1639 << FullName;
1640
1641 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1642 if (StartLoc.isValid())
1643 FixItInitBegin = StartLoc;
1644
1645 if (ActiveModule->Parent->IsFramework)
1646 FixedPrivModDecl.append("framework ");
1647 FixedPrivModDecl.append("module ");
1648 FixedPrivModDecl.append(Canonical);
1649
1650 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1651 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1652 continue;
1653 }
1654
1655 // FooPrivate and whatnots -> Foo_Private
1656 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1657 ActiveModule->Name != Canonical) {
1658 Diags.Report(ActiveModule->DefinitionLoc,
1659 diag::warn_mmap_mismatched_private_module_name)
1660 << ActiveModule->Name;
1661 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1662 SourceRange(ActiveModule->DefinitionLoc));
1663 }
1664 }
1665}
1666
1667void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
1668 if (MD.Id.front().first == "*")
1669 return handleInferredModuleDecl(MD);
1670
1671 CurrModuleDeclLoc = MD.Location;
1672
1673 Module *PreviousActiveModule = ActiveModule;
1674 if (MD.Id.size() > 1) {
1675 // This module map defines a submodule. Go find the module of which it
1676 // is a submodule.
1677 ActiveModule = nullptr;
1678 const Module *TopLevelModule = nullptr;
1679 for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {
1680 if (Module *Next =
1681 Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {
1682 if (I == 0)
1683 TopLevelModule = Next;
1684 ActiveModule = Next;
1685 continue;
1686 }
1687
1688 Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)
1689 << MD.Id[I].first << (ActiveModule != nullptr)
1690 << (ActiveModule
1691 ? ActiveModule->getTopLevelModule()->getFullModuleName()
1692 : "");
1693 HadError = true;
1694 }
1695
1696 if (TopLevelModule &&
1697 ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
1698 assert(ModuleMapFID !=
1699 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
1700 "submodule defined in same file as 'module *' that allowed its "
1701 "top-level module");
1702 Map.addAdditionalModuleMapFile(
1703 TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
1704 }
1705 }
1706
1707 StringRef ModuleName = MD.Id.back().first;
1708 SourceLocation ModuleNameLoc = MD.Id.back().second;
1709
1710 // Determine whether this (sub)module has already been defined.
1711 Module *ShadowingModule = nullptr;
1712 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1713 // We might see a (re)definition of a module that we already have a
1714 // definition for in four cases:
1715 // - If we loaded one definition from an AST file and we've just found a
1716 // corresponding definition in a module map file, or
1717 bool LoadedFromASTFile = Existing->IsFromModuleFile;
1718 // - If we previously inferred this module from different module map file.
1719 bool Inferred = Existing->IsInferred;
1720 // - If we're building a framework that vends a module map, we might've
1721 // previously seen the one in intermediate products and now the system
1722 // one.
1723 // FIXME: If we're parsing module map file that looks like this:
1724 // framework module FW { ... }
1725 // module FW.Sub { ... }
1726 // We can't check the framework qualifier, since it's not attached to
1727 // the definition of Sub. Checking that qualifier on \c Existing is
1728 // not correct either, since we might've previously seen:
1729 // module FW { ... }
1730 // module FW.Sub { ... }
1731 // We should enforce consistency of redefinitions so that we can rely
1732 // that \c Existing is part of a framework iff the redefinition of FW
1733 // we have just skipped had it too. Once we do that, stop checking
1734 // the local framework qualifier and only rely on \c Existing.
1735 bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
1736 // - If we're building a (preprocessed) module and we've just loaded the
1737 // module map file from which it was created.
1738 bool ParsedAsMainInput =
1739 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1740 Map.LangOpts.CurrentModule == ModuleName &&
1741 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1742 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1743 // TODO: Remove this check when we can avoid loading module maps multiple
1744 // times.
1745 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;
1746 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||
1747 SameModuleDecl) {
1748 ActiveModule = PreviousActiveModule;
1749 // Skip the module definition.
1750 return;
1751 }
1752
1753 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1754 ShadowingModule = Existing;
1755 } else {
1756 // This is not a shawdowed module decl, it is an illegal redefinition.
1757 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1758 << ModuleName;
1759 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1760 HadError = true;
1761 return;
1762 }
1763 }
1764
1765 // Start defining this module.
1766 if (ShadowingModule) {
1767 ActiveModule =
1768 Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
1769 } else {
1770 ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
1771 MD.Framework, MD.Explicit);
1772 }
1773
1774 ActiveModule->DefinitionLoc = ModuleNameLoc;
1775 if (MD.Attrs.IsSystem || IsSystem)
1776 ActiveModule->IsSystem = true;
1777 if (MD.Attrs.IsExternC)
1778 ActiveModule->IsExternC = true;
1780 ActiveModule->NoUndeclaredIncludes = true;
1781 ActiveModule->Directory = Directory;
1782
1783 StringRef MapFileName(
1784 SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
1785 if (MapFileName.ends_with("module.private.modulemap") ||
1786 MapFileName.ends_with("module_private.map")) {
1787 ActiveModule->ModuleMapIsPrivate = true;
1788 }
1789
1790 // Private modules named as FooPrivate, Foo.Private or similar are likely a
1791 // user error; provide warnings, notes and fixits to direct users to use
1792 // Foo_Private instead.
1793 SourceLocation StartLoc =
1794 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1795 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1796 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1797 StartLoc) &&
1798 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1799 StartLoc) &&
1800 ActiveModule->ModuleMapIsPrivate)
1801 diagnosePrivateModules(MD.Location);
1802
1803 for (const modulemap::Decl &Decl : MD.Decls) {
1804 std::visit(
1805 llvm::makeVisitor(
1806 [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },
1807 [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
1808 [&](const modulemap::UmbrellaDirDecl &UDD) {
1809 handleUmbrellaDirDecl(UDD);
1810 },
1811 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
1812 [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
1813 [&](const modulemap::ExportAsDecl &EAD) {
1814 handleExportAsDecl(EAD);
1815 },
1816 [&](const modulemap::ExternModuleDecl &EMD) {
1817 handleExternModuleDecl(EMD);
1818 },
1819 [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },
1820 [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
1821 [&](const modulemap::ConfigMacrosDecl &CMD) {
1822 handleConfigMacros(CMD);
1823 },
1824 [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },
1825 [&](const modulemap::ExcludeDecl &ED) {
1826 Diags.Report(ED.Location, diag::err_mmap_expected_member);
1827 }),
1828 Decl);
1829 }
1830
1831 // If the active module is a top-level framework, and there are no link
1832 // libraries, automatically link against the framework.
1833 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1834 ActiveModule->LinkLibraries.empty())
1835 inferFrameworkLink(ActiveModule);
1836
1837 // If the module meets all requirements but is still unavailable, mark the
1838 // whole tree as unavailable to prevent it from building.
1839 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
1840 ActiveModule->Parent) {
1841 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
1842 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1843 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1844 }
1845
1846 // We're done parsing this module. Pop back to the previous module.
1847 ActiveModule = PreviousActiveModule;
1848}
1849
1850void ModuleMapLoader::handleExternModuleDecl(
1851 const modulemap::ExternModuleDecl &EMD) {
1852 StringRef FileNameRef = EMD.Path;
1853 SmallString<128> ModuleMapFileName;
1854 if (llvm::sys::path::is_relative(FileNameRef)) {
1855 ModuleMapFileName += Directory.getName();
1856 llvm::sys::path::append(ModuleMapFileName, EMD.Path);
1857 FileNameRef = ModuleMapFileName;
1858 }
1859 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
1860 Map.parseAndLoadModuleMapFile(
1861 *File, IsSystem,
1862 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1863 ? Directory
1864 : File->getDir(),
1865 FileID(), nullptr, EMD.Location);
1866}
1867
1868/// Whether to add the requirement \p Feature to the module \p M.
1869///
1870/// This preserves backwards compatibility for two hacks in the Darwin system
1871/// module map files:
1872///
1873/// 1. The use of 'requires excluded' to make headers non-modular, which
1874/// should really be mapped to 'textual' now that we have this feature. We
1875/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1876/// true. Later, this bit will be used to map all the headers inside this
1877/// module to 'textual'.
1878///
1879/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1880///
1881/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1882/// was never correct and causes issues now that we check it, so drop it.
1883static bool shouldAddRequirement(Module *M, StringRef Feature,
1884 bool &IsRequiresExcludedHack) {
1885 if (Feature == "excluded" &&
1886 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
1887 M->fullModuleNameIs({"Tcl", "Private"}))) {
1888 IsRequiresExcludedHack = true;
1889 return false;
1890 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
1891 return false;
1892 }
1893
1894 return true;
1895}
1896
1897void ModuleMapLoader::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
1898
1899 for (const modulemap::RequiresFeature &RF : RD.Features) {
1900 bool IsRequiresExcludedHack = false;
1901 bool ShouldAddRequirement =
1902 shouldAddRequirement(ActiveModule, RF.Feature, IsRequiresExcludedHack);
1903
1904 if (IsRequiresExcludedHack)
1905 UsesRequiresExcludedHack.insert(ActiveModule);
1906
1907 if (ShouldAddRequirement) {
1908 // Add this feature.
1909 ActiveModule->addRequirement(RF.Feature, RF.RequiredState, Map.LangOpts,
1910 *Map.Target);
1911 }
1912 }
1913}
1914
1915void ModuleMapLoader::handleHeaderDecl(const modulemap::HeaderDecl &HD) {
1916 // We've already consumed the first token.
1918
1919 if (HD.Private) {
1921 } else if (HD.Excluded) {
1923 }
1924
1925 if (HD.Textual)
1927
1928 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1929 // Mark this header 'textual' (see doc comment for
1930 // Module::UsesRequiresExcludedHack).
1932 }
1933
1934 Module::UnresolvedHeaderDirective Header;
1935 Header.FileName = HD.Path;
1936 Header.FileNameLoc = HD.PathLoc;
1937 Header.IsUmbrella = HD.Umbrella;
1938 Header.Kind = Map.headerRoleToKind(Role);
1939
1940 // Check whether we already have an umbrella.
1941 if (Header.IsUmbrella &&
1942 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
1943 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1944 << ActiveModule->getFullModuleName();
1945 HadError = true;
1946 return;
1947 }
1948
1949 if (HD.Size)
1950 Header.Size = HD.Size;
1951 if (HD.MTime)
1952 Header.ModTime = HD.MTime;
1953
1954 bool NeedsFramework = false;
1955 // Don't add headers to the builtin modules if the builtin headers belong to
1956 // the system modules, with the exception of __stddef_max_align_t.h which
1957 // always had its own module.
1958 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
1959 !isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||
1960 ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
1961 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
1962
1963 if (NeedsFramework)
1964 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
1965 << ActiveModule->getFullModuleName()
1966 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
1967}
1968
1970 const Module::Header &B) {
1971 return A.NameAsWritten < B.NameAsWritten;
1972}
1973
1974void ModuleMapLoader::handleUmbrellaDirDecl(
1975 const modulemap::UmbrellaDirDecl &UDD) {
1976 std::string DirName = std::string(UDD.Path);
1977 std::string DirNameAsWritten = DirName;
1978
1979 // Check whether we already have an umbrella.
1980 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
1981 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
1982 << ActiveModule->getFullModuleName();
1983 HadError = true;
1984 return;
1985 }
1986
1987 // Look for this file.
1989 if (llvm::sys::path::is_absolute(DirName)) {
1990 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
1991 } else {
1992 SmallString<128> PathName;
1993 PathName = Directory.getName();
1994 llvm::sys::path::append(PathName, DirName);
1995 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
1996 }
1997
1998 if (!Dir) {
1999 Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)
2000 << DirName;
2001 return;
2002 }
2003
2004 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2005 // Mark this header 'textual' (see doc comment for
2006 // ModuleMapLoader::UsesRequiresExcludedHack). Although iterating over the
2007 // directory is relatively expensive, in practice this only applies to the
2008 // uncommonly used Tcl module on Darwin platforms.
2009 std::error_code EC;
2010 SmallVector<Module::Header, 6> Headers;
2011 llvm::vfs::FileSystem &FS =
2012 SourceMgr.getFileManager().getVirtualFileSystem();
2013 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2014 I != E && !EC; I.increment(EC)) {
2015 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2016 Module::Header Header = {"", std::string(I->path()), *FE};
2017 Headers.push_back(std::move(Header));
2018 }
2019 }
2020
2021 // Sort header paths so that the pcm doesn't depend on iteration order.
2022 llvm::stable_sort(Headers, compareModuleHeaders);
2023
2024 for (auto &Header : Headers)
2025 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2026 return;
2027 }
2028
2029 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2030 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
2031 << OwningModule->getFullModuleName();
2032 HadError = true;
2033 return;
2034 }
2035
2036 // Record this umbrella directory.
2037 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
2038}
2039
2040void ModuleMapLoader::handleExportDecl(const modulemap::ExportDecl &ED) {
2041 Module::UnresolvedExportDecl Unresolved = {ED.Location, ED.Id, ED.Wildcard};
2042 ActiveModule->UnresolvedExports.push_back(Unresolved);
2043}
2044
2045void ModuleMapLoader::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
2046 const auto &ModName = EAD.Id.front();
2047
2048 if (!ActiveModule->ExportAsModule.empty()) {
2049 if (ActiveModule->ExportAsModule == ModName.first) {
2050 Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)
2051 << ActiveModule->Name << ModName.first;
2052 } else {
2053 Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)
2054 << ActiveModule->Name << ActiveModule->ExportAsModule
2055 << ModName.first;
2056 }
2057 }
2058
2059 ActiveModule->ExportAsModule = ModName.first;
2060 Map.addLinkAsDependency(ActiveModule);
2061}
2062
2063void ModuleMapLoader::handleUseDecl(const modulemap::UseDecl &UD) {
2064 if (ActiveModule->Parent)
2065 Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);
2066 else
2067 ActiveModule->UnresolvedDirectUses.push_back(UD.Id);
2068}
2069
2070void ModuleMapLoader::handleLinkDecl(const modulemap::LinkDecl &LD) {
2071 ActiveModule->LinkLibraries.push_back(
2072 Module::LinkLibrary(std::string{LD.Library}, LD.Framework));
2073}
2074
2075void ModuleMapLoader::handleConfigMacros(
2076 const modulemap::ConfigMacrosDecl &CMD) {
2077 if (ActiveModule->Parent) {
2078 Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);
2079 return;
2080 }
2081
2082 // TODO: Is this really the behavior we want for multiple config_macros
2083 // declarations? If any of them are exhaustive then all of them are.
2084 if (CMD.Exhaustive) {
2085 ActiveModule->ConfigMacrosExhaustive = true;
2086 }
2087 ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),
2088 CMD.Macros.begin(), CMD.Macros.end());
2089}
2090
2091void ModuleMapLoader::handleConflict(const modulemap::ConflictDecl &CD) {
2092 Module::UnresolvedConflict Conflict;
2093
2094 Conflict.Id = CD.Id;
2095 Conflict.Message = CD.Message;
2096
2097 // FIXME: when we move to C++20 we should consider using emplace_back
2098 ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));
2099}
2100
2101void ModuleMapLoader::handleInferredModuleDecl(
2102 const modulemap::ModuleDecl &MD) {
2103 SourceLocation StarLoc = MD.Id.front().second;
2104
2105 // Inferred modules must be submodules.
2106 if (!ActiveModule && !MD.Framework) {
2107 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2108 return;
2109 }
2110
2111 if (ActiveModule) {
2112 // Inferred modules must have umbrella directories.
2113 if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
2114 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2115 return;
2116 }
2117
2118 // Check for redefinition of an inferred module.
2119 if (ActiveModule->InferSubmodules) {
2120 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2121 if (ActiveModule->InferredSubmoduleLoc.isValid())
2122 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2123 diag::note_mmap_prev_definition);
2124 return;
2125 }
2126
2127 // Check for the 'framework' keyword, which is not permitted here.
2128 if (MD.Framework) {
2129 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2130 return;
2131 }
2132 } else if (MD.Explicit) {
2133 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2134 return;
2135 }
2136
2137 if (ActiveModule) {
2138 // Note that we have an inferred submodule.
2139 ActiveModule->InferSubmodules = true;
2140 ActiveModule->InferredSubmoduleLoc = StarLoc;
2141 ActiveModule->InferExplicitSubmodules = MD.Explicit;
2142 } else {
2143 // We'll be inferring framework modules for this directory.
2144 auto &InfDir = Map.InferredDirectories[Directory];
2145 InfDir.InferModules = true;
2146 InfDir.Attrs = MD.Attrs;
2147 InfDir.ModuleMapFID = ModuleMapFID;
2148 // FIXME: Handle the 'framework' keyword.
2149 }
2150
2151 for (const modulemap::Decl &Decl : MD.Decls) {
2152 std::visit(
2153 llvm::makeVisitor(
2154 [&](const auto &Other) {
2155 Diags.Report(Other.Location,
2156 diag::err_mmap_expected_inferred_member)
2157 << (ActiveModule != nullptr);
2158 },
2159 [&](const modulemap::ExcludeDecl &ED) {
2160 // Only inferred frameworks can have exclude decls
2161 if (ActiveModule) {
2162 Diags.Report(ED.Location,
2163 diag::err_mmap_expected_inferred_member)
2164 << (ActiveModule != nullptr);
2165 HadError = true;
2166 return;
2167 }
2168 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(
2169 ED.Module);
2170 },
2171 [&](const modulemap::ExportDecl &ED) {
2172 // Only inferred submodules can have export decls
2173 if (!ActiveModule) {
2174 Diags.Report(ED.Location,
2175 diag::err_mmap_expected_inferred_member)
2176 << (ActiveModule != nullptr);
2177 HadError = true;
2178 return;
2179 }
2180
2181 if (ED.Wildcard && ED.Id.size() == 0)
2182 ActiveModule->InferExportWildcard = true;
2183 else
2184 Diags.Report(ED.Id.front().second,
2185 diag::err_mmap_expected_export_wildcard);
2186 }),
2187 Decl);
2188 }
2189}
2190
2192 handleModuleDecl(MD);
2193 return HadError;
2194}
2195
2197 const modulemap::ExternModuleDecl &EMD) {
2198 handleExternModuleDecl(EMD);
2199 return HadError;
2200}
2201
2203 const modulemap::ModuleMapFile &MMF) {
2204 for (const auto &Decl : MMF.Decls) {
2205 std::visit(
2206 llvm::makeVisitor(
2207 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
2208 [&](const modulemap::ExternModuleDecl &EMD) {
2209 handleExternModuleDecl(EMD);
2210 }),
2211 Decl);
2212 }
2213 return HadError;
2214}
2215
2217 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
2218 if (Known != Modules.end())
2219 return Known->getValue();
2220
2221 auto ParsedMod = ParsedModules.find(Name);
2222 if (ParsedMod == ParsedModules.end())
2223 return nullptr;
2224
2225 Diags.Report(diag::remark_mmap_load_module) << Name;
2226
2227 for (const auto &ModuleDecl : ParsedMod->second) {
2228 const modulemap::ModuleMapFile &MMF = *ModuleDecl.first;
2229 ModuleMapLoader Loader(SourceMgr, Diags, const_cast<ModuleMap &>(*this),
2230 MMF.ID, *MMF.Dir, MMF.IsSystem);
2231 if (Loader.loadModuleDecl(*ModuleDecl.second))
2232 return nullptr;
2233 }
2234
2235 return findModule(Name);
2236}
2237
2239 DirectoryEntryRef Dir, FileID ID,
2240 unsigned *Offset,
2241 SourceLocation ExternModuleLoc) {
2242 assert(Target && "Missing target information");
2243 llvm::DenseMap<const FileEntry *, bool>::iterator Known =
2244 LoadedModuleMap.find(File);
2245 if (Known != LoadedModuleMap.end())
2246 return Known->second;
2247
2248 // If the module map file wasn't already entered, do so now.
2249 if (ID.isInvalid()) {
2250 ID = SourceMgr.translateFile(File);
2251 // TODO: The way we compute affecting module maps requires this to be a
2252 // local FileID. This should be changed to reuse loaded FileIDs when
2253 // available, and change the way that affecting module maps are
2254 // computed to not require this.
2255 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {
2256 auto FileCharacter =
2258 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2259 }
2260 }
2261
2262 assert(Target && "Missing target information");
2263 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
2264 if (!Buffer)
2265 return LoadedModuleMap[File] = true;
2266 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2267 "invalid buffer offset");
2268
2269 std::optional<modulemap::ModuleMapFile> MMF =
2270 modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, Offset);
2271 bool Result = false;
2272 if (MMF) {
2273 Diags.Report(diag::remark_mmap_load) << File.getName();
2274 ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem);
2275 Result = Loader.parseAndLoadModuleMapFile(*MMF);
2276 }
2277 LoadedModuleMap[File] = Result;
2278
2279 // Notify callbacks that we observed it.
2280 // FIXME: We should only report module maps that were actually used.
2281 for (const auto &Cb : Callbacks)
2282 Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);
2283
2284 return Result;
2285}
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...
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:136
bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD)
ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)
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
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.
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
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
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.
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:539
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.
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef Dir, FileID ID=FileID(), SourceLocation ExternModuleLoc=SourceLocation())
Parse a module map without creating clang::Module instances.
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)
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:144
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition Module.h:471
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
Definition Module.cpp:155
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
Definition Module.h:205
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
Definition Module.h:406
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
Definition Module.cpp:350
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
Definition Module.cpp:287
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:463
SourceLocation DefinitionLoc
The location of the module definition.
Definition Module.h:150
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:341
Module * Parent
The parent of this module.
Definition Module.h:193
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
Definition Module.cpp:325
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:337
@ HK_PrivateTextual
Definition Module.h:282
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
Definition Module.cpp:254
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Definition Module.h:399
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition Module.h:389
std::string Name
The name of this module.
Definition Module.h:147
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Definition Module.h:635
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:520
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
Definition Module.h:489
void addHeader(HeaderKind HK, Header H)
Definition Module.h:308
std::string UmbrellaRelativeToRootModuleDirectory
Definition Module.h:214
OptionalDirectoryEntryRef Directory
The build directory of this module.
Definition Module.h:198
ArrayRef< Header > getHeaders(HeaderKind HK) const
Definition Module.h:302
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
Definition Module.h:416
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Definition Module.h:541
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
Definition Module.cpp:193
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:625
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Definition Module.h:586
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
Definition Module.h:468
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition Module.h:167
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition Module.h:185
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition Module.h:164
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition Module.h:161
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition Module.h:180
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition Module.h:177
unsigned IsFramework
Whether this is a framework module.
Definition Module.h:380
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
Definition Module.h:218
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:239
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Definition Module.h:211
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Definition Module.h:411
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition Module.h:722
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
Definition Module.cpp:263
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
Definition Module.h:524
std::vector< Conflict > Conflicts
The list of conflicts.
Definition Module.h:553
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
Definition TargetInfo.h:226
Defines the clang::TargetInfo interface.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
bool Sub(InterpState &S, CodePtr OpPC)
Definition Interp.h:329
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.
std::optional< ModuleMapFile > parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset)
Parse a module map file into an in memory representation.
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:560
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
@ Other
Other implicit parameter.
Definition Decl.h:1746
unsigned IsExternC
Whether this is an extern "C" module.
Definition Module.h:116
unsigned IsSystem
Whether this is a system module.
Definition Module.h:112
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
Definition Module.h:125
A conflict between two modules.
Definition Module.h:544
Module * Other
The module that this module conflicts with.
Definition Module.h:546
std::string Message
The message provided to the user when there is a conflict.
Definition Module.h:549
Information about a header directive as found in the module map file.
Definition Module.h:287
std::string NameAsWritten
Definition Module.h:288
FileEntryRef Entry
Definition Module.h:290
A library or framework to link against when an entity from this module is used.
Definition Module.h:503
std::string Message
The message provided to the user when there is a conflict.
Definition Module.h:536
ModuleId Id
The (unresolved) module id.
Definition Module.h:533
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
Definition Module.h:475
Stored information about a header directive that was found in the module map file but has not been re...
Definition Module.h:325
std::optional< time_t > ModTime
Definition Module.h:332
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