clang 23.0.0git
ModuleMap.cpp
Go to the documentation of this file.
1//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the ModuleMap implementation, which describes the layout
10// of a module as it relates to headers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/ModuleMap.h"
18#include "clang/Basic/LLVM.h"
20#include "clang/Basic/Module.h"
28#include "llvm/ADT/DenseMap.h"
29#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/SmallPtrSet.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/StringSwitch.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/Path.h"
38#include "llvm/Support/VirtualFileSystem.h"
39#include "llvm/Support/raw_ostream.h"
40#include <cassert>
41#include <cstring>
42#include <optional>
43#include <string>
44#include <system_error>
45#include <utility>
46
47using namespace clang;
48
49void ModuleMapCallbacks::anchor() {}
50
52 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
53 if (PendingLinkAs != PendingLinkAsModule.end()) {
54 for (auto &Name : PendingLinkAs->second) {
55 auto *M = findModule(Name.getKey());
56 if (M)
57 M->UseExportAsModuleLinkName = true;
58 }
59 }
60}
61
63 if (findModule(Mod->ExportAsModule))
64 Mod->UseExportAsModuleLinkName = true;
65 else
66 PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
67}
68
70 switch ((int)Role) {
71 case NormalHeader:
72 return Module::HK_Normal;
73 case PrivateHeader:
74 return Module::HK_Private;
75 case TextualHeader:
76 return Module::HK_Textual;
79 case ExcludedHeader:
81 }
82 llvm_unreachable("unknown header role");
83}
84
87 switch ((int)Kind) {
89 return NormalHeader;
91 return PrivateHeader;
93 return TextualHeader;
97 return ExcludedHeader;
98 }
99 llvm_unreachable("unknown header kind");
100}
101
105
107ModuleMap::resolveExport(Module *Mod,
109 bool Complain) const {
110 // We may have just a wildcard.
111 if (Unresolved.Id.empty()) {
112 assert(Unresolved.Wildcard && "Invalid unresolved export");
113 return Module::ExportDecl(nullptr, true);
114 }
115
116 // Resolve the module-id.
117 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
118 if (!Context)
119 return {};
120
121 return Module::ExportDecl(Context, Unresolved.Wildcard);
122}
123
124Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
125 bool Complain) const {
126 // Find the starting module.
127 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
128 if (!Context) {
129 if (Complain)
130 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
131 << Id[0].first << Mod->getFullModuleName();
132
133 return nullptr;
134 }
135
136 // Dig into the module path.
137 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
138 Module *Sub = lookupModuleQualified(Id[I].first, Context);
139 if (!Sub) {
140 if (Complain)
141 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
142 << Id[I].first << Context->getFullModuleName()
143 << SourceRange(Id[0].second, Id[I-1].second);
144
145 return nullptr;
146 }
147
148 Context = Sub;
149 }
150
151 return Context;
152}
153
154/// Append to \p Paths the set of paths needed to get to the
155/// subframework in which the given module lives.
157 SmallVectorImpl<char> &Path) {
158 // Collect the framework names from the given module to the top-level module.
160 for (; Mod; Mod = Mod->Parent) {
161 if (Mod->IsFramework)
162 Paths.push_back(Mod->Name);
163 }
164
165 if (Paths.empty())
166 return;
167
168 // Add Frameworks/Name.framework for each subframework.
169 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
170 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");
171}
172
173OptionalFileEntryRef ModuleMap::findHeader(
175 SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
176 // Search for the header file within the module's home directory.
177 auto Directory = M->Directory;
178 SmallString<128> FullPathName(Directory->getName());
179
180 auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {
181 auto File =
182 expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
183 if (!File || (Header.Size && File->getSize() != *Header.Size) ||
184 (Header.ModTime && File->getModificationTime() != *Header.ModTime))
185 return std::nullopt;
186 return *File;
187 };
188
189 auto GetFrameworkFile = [&]() -> OptionalFileEntryRef {
190 unsigned FullPathLength = FullPathName.size();
191 appendSubframeworkPaths(M, RelativePathName);
192 unsigned RelativePathLength = RelativePathName.size();
193
194 // Check whether this file is in the public headers.
195 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
196 llvm::sys::path::append(FullPathName, RelativePathName);
197 if (auto File = GetFile(FullPathName))
198 return File;
199
200 // Check whether this file is in the private headers.
201 // Ideally, private modules in the form 'FrameworkName.Private' should
202 // be defined as 'module FrameworkName.Private', and not as
203 // 'framework module FrameworkName.Private', since a 'Private.Framework'
204 // does not usually exist. However, since both are currently widely used
205 // for private modules, make sure we find the right path in both cases.
206 if (M->IsFramework && M->Name == "Private")
207 RelativePathName.clear();
208 else
209 RelativePathName.resize(RelativePathLength);
210 FullPathName.resize(FullPathLength);
211 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
212 Header.FileName);
213 llvm::sys::path::append(FullPathName, RelativePathName);
214 return GetFile(FullPathName);
215 };
216
217 if (llvm::sys::path::is_absolute(Header.FileName)) {
218 RelativePathName.clear();
219 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
220 return GetFile(Header.FileName);
221 }
222
223 if (M->isPartOfFramework())
224 return GetFrameworkFile();
225
226 // Lookup for normal headers.
227 llvm::sys::path::append(RelativePathName, Header.FileName);
228 llvm::sys::path::append(FullPathName, RelativePathName);
229 auto NormalHdrFile = GetFile(FullPathName);
230
231 if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
232 // The lack of 'framework' keyword in a module declaration it's a simple
233 // mistake we can diagnose when the header exists within the proper
234 // framework style path.
235 FullPathName.assign(Directory->getName());
236 RelativePathName.clear();
237 if (GetFrameworkFile()) {
238 Diags.Report(Header.FileNameLoc,
239 diag::warn_mmap_incomplete_framework_module_declaration)
240 << Header.FileName << M->getFullModuleName();
241 NeedsFramework = true;
242 }
243 return std::nullopt;
244 }
245
246 return NormalHdrFile;
247}
248
249/// Determine whether the given file name is the name of a builtin
250/// header, supplied by Clang to replace, override, or augment existing system
251/// headers.
252static bool isBuiltinHeaderName(StringRef FileName) {
253 return llvm::StringSwitch<bool>(FileName)
254 .Case("float.h", true)
255 .Case("iso646.h", true)
256 .Case("limits.h", true)
257 .Case("stdalign.h", true)
258 .Case("stdarg.h", true)
259 .Case("stdatomic.h", true)
260 .Case("stdbool.h", true)
261 .Case("stdckdint.h", true)
262 .Case("stdcountof.h", true)
263 .Case("stddef.h", true)
264 .Case("stdint.h", true)
265 .Case("tgmath.h", true)
266 .Case("unwind.h", true)
267 .Default(false);
268}
269
270/// Determine whether the given module name is the name of a builtin
271/// module that is cyclic with a system module on some platforms.
272static bool isBuiltInModuleName(StringRef ModuleName) {
273 return llvm::StringSwitch<bool>(ModuleName)
274 .Case("_Builtin_float", true)
275 .Case("_Builtin_inttypes", true)
276 .Case("_Builtin_iso646", true)
277 .Case("_Builtin_limits", true)
278 .Case("_Builtin_stdalign", true)
279 .Case("_Builtin_stdarg", true)
280 .Case("_Builtin_stdatomic", true)
281 .Case("_Builtin_stdbool", true)
282 .Case("_Builtin_stddef", true)
283 .Case("_Builtin_stdint", true)
284 .Case("_Builtin_stdnoreturn", true)
285 .Case("_Builtin_tgmath", true)
286 .Case("_Builtin_unwind", true)
287 .Default(false);
288}
289
290void ModuleMap::resolveHeader(Module *Mod,
292 bool &NeedsFramework) {
293 SmallString<128> RelativePathName;
295 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
296 if (Header.IsUmbrella) {
297 const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
298 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
299 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
300 << UmbrellaMod->getFullModuleName();
301 else
302 // Record this umbrella header.
304 RelativePathName.str());
305 } else {
306 Module::Header H = {Header.FileName, std::string(RelativePathName),
307 *File};
308 addHeader(Mod, H, headerKindToRole(Header.Kind));
309 }
310 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
311 // There's a builtin header but no corresponding on-disk header. Assume
312 // this was supposed to modularize the builtin header alone.
313 } else if (Header.Kind == Module::HK_Excluded) {
314 // Ignore missing excluded header files. They're optional anyway.
315 } else {
316 // If we find a module that has a missing header, we mark this module as
317 // unavailable and store the header directive for displaying diagnostics.
318 Mod->MissingHeaders.push_back(Header);
319 // A missing header with stat information doesn't make the module
320 // unavailable; this keeps our behavior consistent as headers are lazily
321 // resolved. (Such a module still can't be built though, except from
322 // preprocessed source.)
323 if (!Header.Size && !Header.ModTime)
324 Mod->markUnavailable(/*Unimportable=*/false);
325 }
326}
327
328bool ModuleMap::resolveAsBuiltinHeader(
329 Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
330 if (Header.Kind == Module::HK_Excluded ||
331 llvm::sys::path::is_absolute(Header.FileName) ||
332 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
333 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
334 !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
335 return false;
336
337 // This is a system module with a top-level header. This header
338 // may have a counterpart (or replacement) in the set of headers
339 // supplied by Clang. Find that builtin header.
340 SmallString<128> Path;
341 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
342 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
343 if (!File)
344 return false;
345
346 Module::Header H = {Header.FileName, Header.FileName, *File};
347 auto Role = headerKindToRole(Header.Kind);
348 addHeader(Mod, H, Role);
349 return true;
350}
351
353 const LangOptions &LangOpts, const TargetInfo *Target,
354 HeaderSearch &HeaderInfo)
355 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
356 HeaderInfo(HeaderInfo) {
357}
358
359ModuleMap::~ModuleMap() = default;
360
361void ModuleMap::setTarget(const TargetInfo &Target) {
362 assert((!this->Target || this->Target == &Target) &&
363 "Improper target override");
364 this->Target = &Target;
365}
366
367/// "Sanitize" a filename so that it can be used as an identifier.
368static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
369 SmallVectorImpl<char> &Buffer) {
370 if (Name.empty())
371 return Name;
372
373 if (!isValidAsciiIdentifier(Name)) {
374 // If we don't already have something with the form of an identifier,
375 // create a buffer with the sanitized name.
376 Buffer.clear();
377 if (isDigit(Name[0]))
378 Buffer.push_back('_');
379 Buffer.reserve(Buffer.size() + Name.size());
380 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
381 if (isAsciiIdentifierContinue(Name[I]))
382 Buffer.push_back(Name[I]);
383 else
384 Buffer.push_back('_');
385 }
386
387 Name = StringRef(Buffer.data(), Buffer.size());
388 }
389
390 while (llvm::StringSwitch<bool>(Name)
391#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
392#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
393#include "clang/Basic/TokenKinds.def"
394 .Default(false)) {
395 if (Name.data() != Buffer.data())
396 Buffer.append(Name.begin(), Name.end());
397 Buffer.push_back('_');
398 Name = StringRef(Buffer.data(), Buffer.size());
399 }
400
401 return Name;
402}
403
405 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
406 isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));
407}
408
410 Module *Module) const {
411 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
414}
415
416ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
418 HeadersMap::iterator Known = Headers.find(File);
419 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
420 Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {
421 HeaderInfo.loadTopLevelSystemModules();
422 return Headers.find(File);
423 }
424 return Known;
425}
426
427ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(
429 if (UmbrellaDirs.empty())
430 return {};
431
432 OptionalDirectoryEntryRef Dir = File.getDir();
433
434 // Note: as an egregious but useful hack we use the real path here, because
435 // frameworks moving from top-level frameworks to embedded frameworks tend
436 // to be symlinked from the top-level location to the embedded location,
437 // and we need to resolve lookups as if we had found the embedded location.
438 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
439
440 // Keep walking up the directory hierarchy, looking for a directory with
441 // an umbrella header.
442 do {
443 auto KnownDir = UmbrellaDirs.find(*Dir);
444 if (KnownDir != UmbrellaDirs.end())
445 return KnownHeader(KnownDir->second, NormalHeader);
446
447 IntermediateDirs.push_back(*Dir);
448
449 // Retrieve our parent path.
450 DirName = llvm::sys::path::parent_path(DirName);
451 if (DirName.empty())
452 break;
453
454 // Resolve the parent path to a directory entry.
455 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
456 } while (Dir);
457 return {};
458}
459
460static bool violatesPrivateInclude(Module *RequestingModule,
461 const FileEntry *IncFileEnt,
462 ModuleMap::KnownHeader Header) {
463#ifndef NDEBUG
464 if (Header.getRole() & ModuleMap::PrivateHeader) {
465 // Check for consistency between the module header role
466 // as obtained from the lookup and as obtained from the module.
467 // This check is not cheap, so enable it only for debugging.
468 bool IsPrivate = false;
469 ArrayRef<Module::Header> HeaderList[] = {
472 for (auto Hs : HeaderList)
473 IsPrivate |= llvm::any_of(
474 Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
475 assert(IsPrivate && "inconsistent headers and roles");
476 }
477#endif
478 return !Header.isAccessibleFrom(RequestingModule);
479}
480
482 return M ? M->getTopLevelModule() : nullptr;
483}
484
486 bool RequestingModuleIsModuleInterface,
487 SourceLocation FilenameLoc,
488 StringRef Filename, FileEntryRef File) {
489 // No errors for indirect modules. This may be a bit of a problem for modules
490 // with no source files.
491 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
492 return;
493
494 if (RequestingModule) {
495 resolveUses(RequestingModule, /*Complain=*/false);
496 resolveHeaderDirectives(RequestingModule, /*File=*/std::nullopt);
497 }
498
499 bool Excluded = false;
500 Module *Private = nullptr;
501 Module *NotUsed = nullptr;
502
503 HeadersMap::iterator Known = findKnownHeader(File);
504 if (Known != Headers.end()) {
505 for (const KnownHeader &Header : Known->second) {
506 // Excluded headers don't really belong to a module.
507 if (Header.getRole() == ModuleMap::ExcludedHeader) {
508 Excluded = true;
509 continue;
510 }
511
512 // Remember private headers for later printing of a diagnostic.
513 if (violatesPrivateInclude(RequestingModule, File, Header)) {
514 Private = Header.getModule();
515 continue;
516 }
517
518 // If uses need to be specified explicitly, we are only allowed to return
519 // modules that are explicitly used by the requesting module.
520 if (RequestingModule && LangOpts.ModulesDeclUse &&
521 !RequestingModule->directlyUses(Header.getModule())) {
522 NotUsed = Header.getModule();
523 continue;
524 }
525
526 // We have found a module that we can happily use.
527 return;
528 }
529
530 Excluded = true;
531 }
532
533 // We have found a header, but it is private.
534 if (Private) {
535 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
536 << Filename;
537 return;
538 }
539
540 // We have found a module, but we don't use it.
541 if (NotUsed) {
542 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
543 << RequestingModule->getTopLevelModule()->Name << Filename
544 << NotUsed->Name;
545 return;
546 }
547
548 if (Excluded || isHeaderInUmbrellaDirs(File))
549 return;
550
551 // At this point, only non-modular includes remain.
552
553 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
554 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
555 << RequestingModule->getTopLevelModule()->Name << Filename;
556 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
557 LangOpts.isCompilingModule()) {
558 // Do not diagnose when we are not compiling a module.
559 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
560 diag::warn_non_modular_include_in_framework_module :
561 diag::warn_non_modular_include_in_module;
562 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
563 << File.getName();
564 }
565}
566
568 const ModuleMap::KnownHeader &Old) {
569 // Prefer available modules.
570 // FIXME: Considering whether the module is available rather than merely
571 // importable is non-hermetic and can result in surprising behavior for
572 // prebuilt modules. Consider only checking for importability here.
573 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
574 return true;
575
576 // Prefer a public header over a private header.
577 if ((New.getRole() & ModuleMap::PrivateHeader) !=
579 return !(New.getRole() & ModuleMap::PrivateHeader);
580
581 // Prefer a non-textual header over a textual header.
582 if ((New.getRole() & ModuleMap::TextualHeader) !=
584 return !(New.getRole() & ModuleMap::TextualHeader);
585
586 // Prefer a non-excluded header over an excluded header.
587 if ((New.getRole() == ModuleMap::ExcludedHeader) !=
589 return New.getRole() != ModuleMap::ExcludedHeader;
590
591 // Don't have a reason to choose between these. Just keep the first one.
592 return false;
593}
594
596 bool AllowTextual,
597 bool AllowExcluded) {
598 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
599 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
600 return {};
601 return R;
602 };
603
604 HeadersMap::iterator Known = findKnownHeader(File);
605 if (Known != Headers.end()) {
607 // Iterate over all modules that 'File' is part of to find the best fit.
608 for (KnownHeader &H : Known->second) {
609 // Cannot use a module if the header is excluded in it.
610 if (!AllowExcluded && H.getRole() == ModuleMap::ExcludedHeader)
611 continue;
612 // Prefer a header from the source module over all others.
613 if (H.getModule()->getTopLevelModule() == SourceModule)
614 return MakeResult(H);
616 Result = H;
617 }
618 return MakeResult(Result);
619 }
620
621 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
622}
623
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 FileID &LocalFID = ModuleMapLocalFileID[File];
1336 if (LocalFID.isInvalid()) {
1337 auto FileCharacter =
1339 LocalFID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
1340 }
1341 ID = LocalFID;
1342 }
1343
1344 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
1345 if (!Buffer) {
1346 ParsedModuleMap[File] = nullptr;
1347 return true;
1348 }
1349
1350 Diags.Report(diag::remark_mmap_parse) << File.getName();
1351 std::optional<modulemap::ModuleMapFile> MaybeMMF =
1352 modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, nullptr);
1353
1354 if (!MaybeMMF) {
1355 ParsedModuleMap[File] = nullptr;
1356 return true;
1357 }
1358
1359 ParsedModuleMaps.push_back(
1360 std::make_unique<modulemap::ModuleMapFile>(std::move(*MaybeMMF)));
1361 const modulemap::ModuleMapFile &MMF = *ParsedModuleMaps.back();
1362 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;
1363 for (const auto &Decl : MMF.Decls) {
1364 std::visit(llvm::makeVisitor(
1365 [&](const modulemap::ModuleDecl &MD) {
1366 // Only use the first part of the name even for submodules.
1367 // This will correctly load the submodule declarations when
1368 // the module is loaded.
1369 auto &ModuleDecls =
1370 ParsedModules[StringRef(MD.Id.front().first)];
1371 ModuleDecls.push_back(std::pair(&MMF, &MD));
1372 },
1373 [&](const modulemap::ExternModuleDecl &EMD) {
1374 PendingExternalModuleMaps.push_back(&EMD);
1375 }),
1376 Decl);
1377 }
1378
1379 for (const modulemap::ExternModuleDecl *EMD : PendingExternalModuleMaps) {
1380 StringRef FileNameRef = EMD->Path;
1381 SmallString<128> ModuleMapFileName;
1382 if (llvm::sys::path::is_relative(FileNameRef)) {
1383 ModuleMapFileName += Dir.getName();
1384 llvm::sys::path::append(ModuleMapFileName, EMD->Path);
1385 FileNameRef = ModuleMapFileName;
1386 }
1387
1388 if (auto EFile =
1389 SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {
1390 parseModuleMapFile(*EFile, IsSystem, EFile->getDir(), FileID(),
1391 ExternModuleLoc);
1392 }
1393 }
1394
1395 ParsedModuleMap[File] = &MMF;
1396
1397 for (const auto &Cb : Callbacks)
1398 Cb->moduleMapFileRead(SourceLocation(), File, IsSystem);
1399
1400 return false;
1401}
1402
1405 return {};
1406
1407 return SourceMgr.getFileID(Module->DefinitionLoc);
1408}
1409
1412 return SourceMgr.getFileEntryRefForID(getContainingModuleMapFileID(Module));
1413}
1414
1416 if (M->IsInferred) {
1417 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1418 return InferredModuleAllowedBy.find(M)->second;
1419 }
1421}
1422
1425 return SourceMgr.getFileEntryRefForID(getModuleMapFileIDForUniquing(M));
1426}
1427
1429 M->IsInferred = true;
1430 InferredModuleAllowedBy[M] = ModMapFID;
1431}
1432
1433std::error_code
1435 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1436
1437 // Do not canonicalize within the framework; the module map loader expects
1438 // Modules/ not Versions/A/Modules.
1439 if (llvm::sys::path::filename(Dir) == "Modules") {
1440 StringRef Parent = llvm::sys::path::parent_path(Dir);
1441 if (Parent.ends_with(".framework"))
1442 Dir = Parent;
1443 }
1444
1445 FileManager &FM = SourceMgr.getFileManager();
1446 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1447 if (!DirEntry)
1448 return llvm::errorToErrorCode(DirEntry.takeError());
1449
1450 // Canonicalize the directory.
1451 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
1452 if (CanonicalDir != Dir)
1453 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1454
1455 // In theory, the filename component should also be canonicalized if it
1456 // on a case-insensitive filesystem. However, the extra canonicalization is
1457 // expensive and if clang looked up the filename it will always be lowercase.
1458
1459 // Remove ., remove redundant separators, and switch to native separators.
1460 // This is needed for separators between CanonicalDir and the filename.
1461 llvm::sys::path::remove_dots(Path);
1462
1463 return std::error_code();
1464}
1465
1468 AdditionalModMaps[M].insert(ModuleMap);
1469}
1470
1471LLVM_DUMP_METHOD void ModuleMap::dump() {
1472 llvm::errs() << "Modules:";
1473 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1474 MEnd = Modules.end();
1475 M != MEnd; ++M)
1476 M->getValue()->print(llvm::errs(), 2);
1477
1478 llvm::errs() << "Headers:";
1479 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1480 H != HEnd; ++H) {
1481 llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1482 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1483 E = H->second.end();
1484 I != E; ++I) {
1485 if (I != H->second.begin())
1486 llvm::errs() << ",";
1487 llvm::errs() << I->getModule()->getFullModuleName();
1488 }
1489 llvm::errs() << "\n";
1490 }
1491}
1492
1493bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
1494 auto Unresolved = std::move(Mod->UnresolvedExports);
1495 Mod->UnresolvedExports.clear();
1496 for (auto &UE : Unresolved) {
1497 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
1498 if (Export.getPointer() || Export.getInt())
1499 Mod->Exports.push_back(Export);
1500 else
1501 Mod->UnresolvedExports.push_back(UE);
1502 }
1503 return !Mod->UnresolvedExports.empty();
1504}
1505
1506bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
1507 auto *Top = Mod->getTopLevelModule();
1508 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1509 Top->UnresolvedDirectUses.clear();
1510 for (auto &UDU : Unresolved) {
1511 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1512 if (DirectUse)
1513 Top->DirectUses.push_back(DirectUse);
1514 else
1515 Top->UnresolvedDirectUses.push_back(UDU);
1516 }
1517 return !Top->UnresolvedDirectUses.empty();
1518}
1519
1520bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
1521 auto Unresolved = std::move(Mod->UnresolvedConflicts);
1522 Mod->UnresolvedConflicts.clear();
1523 for (auto &UC : Unresolved) {
1524 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1525 Module::Conflict Conflict;
1526 Conflict.Other = OtherMod;
1527 Conflict.Message = UC.Message;
1528 Mod->Conflicts.push_back(Conflict);
1529 } else
1530 Mod->UnresolvedConflicts.push_back(UC);
1531 }
1532 return !Mod->UnresolvedConflicts.empty();
1533}
1534
1535//----------------------------------------------------------------------------//
1536// Module map file loader
1537//----------------------------------------------------------------------------//
1538
1539namespace clang {
1541 SourceManager &SourceMgr;
1542
1543 DiagnosticsEngine &Diags;
1544 ModuleMap &Map;
1545
1546 /// The current module map file.
1547 FileID ModuleMapFID;
1548
1549 /// Source location of most recent loaded module declaration
1550 SourceLocation CurrModuleDeclLoc;
1551
1552 /// The directory that file names in this module map file should
1553 /// be resolved relative to.
1554 DirectoryEntryRef Directory;
1555
1556 /// Whether this module map is in a system header directory.
1557 bool IsSystem;
1558
1559 /// Whether an error occurred.
1560 bool HadError = false;
1561
1562 /// The active module.
1563 Module *ActiveModule = nullptr;
1564
1565 /// Whether a module uses the 'requires excluded' hack to mark its
1566 /// contents as 'textual'.
1567 ///
1568 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1569 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1570 /// non-modular headers. For backwards compatibility, we continue to
1571 /// support this idiom for just these modules, and map the headers to
1572 /// 'textual' to match the original intent.
1573 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1574
1575 void handleModuleDecl(const modulemap::ModuleDecl &MD);
1576 void handleExternModuleDecl(const modulemap::ExternModuleDecl &EMD);
1577 void handleRequiresDecl(const modulemap::RequiresDecl &RD);
1578 void handleHeaderDecl(const modulemap::HeaderDecl &HD);
1579 void handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD);
1580 void handleExportDecl(const modulemap::ExportDecl &ED);
1581 void handleExportAsDecl(const modulemap::ExportAsDecl &EAD);
1582 void handleUseDecl(const modulemap::UseDecl &UD);
1583 void handleLinkDecl(const modulemap::LinkDecl &LD);
1584 void handleConfigMacros(const modulemap::ConfigMacrosDecl &CMD);
1585 void handleConflict(const modulemap::ConflictDecl &CD);
1586 void handleInferredModuleDecl(const modulemap::ModuleDecl &MD);
1587
1588 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1589 /// module map search logic to find the appropriate private module when PCH
1590 /// is used with implicit module maps. Warn when private modules are written
1591 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1592 void diagnosePrivateModules(SourceLocation StartLoc);
1593
1594 using Attributes = ModuleMap::Attributes;
1595
1596public:
1598 ModuleMap &Map, FileID ModuleMapFID,
1599 DirectoryEntryRef Directory, bool IsSystem)
1600 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),
1601 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
1602
1603 bool loadModuleDecl(const modulemap::ModuleDecl &MD);
1606};
1607
1608} // namespace clang
1609
1610/// Private modules are canonicalized as Foo_Private. Clang provides extra
1611/// module map search logic to find the appropriate private module when PCH
1612/// is used with implicit module maps. Warn when private modules are written
1613/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1614void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {
1615 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1616 const Module *M, SourceRange ReplLoc) {
1617 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1618 diag::note_mmap_rename_top_level_private_module);
1619 D << BadName << M->Name;
1620 D << FixItHint::CreateReplacement(ReplLoc, Canonical);
1621 };
1622
1623 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1624 auto const *M = E->getValue();
1625 if (M->Directory != ActiveModule->Directory)
1626 continue;
1627
1628 SmallString<128> FullName(ActiveModule->getFullModuleName());
1629 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
1630 continue;
1631 SmallString<128> FixedPrivModDecl;
1632 SmallString<128> Canonical(M->Name);
1633 Canonical.append("_Private");
1634
1635 // Foo.Private -> Foo_Private
1636 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1637 M->Name == ActiveModule->Parent->Name) {
1638 Diags.Report(ActiveModule->DefinitionLoc,
1639 diag::warn_mmap_mismatched_private_submodule)
1640 << FullName;
1641
1642 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1643 if (StartLoc.isValid())
1644 FixItInitBegin = StartLoc;
1645
1646 if (ActiveModule->Parent->IsFramework)
1647 FixedPrivModDecl.append("framework ");
1648 FixedPrivModDecl.append("module ");
1649 FixedPrivModDecl.append(Canonical);
1650
1651 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1652 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1653 continue;
1654 }
1655
1656 // FooPrivate and whatnots -> Foo_Private
1657 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1658 ActiveModule->Name != Canonical) {
1659 Diags.Report(ActiveModule->DefinitionLoc,
1660 diag::warn_mmap_mismatched_private_module_name)
1661 << ActiveModule->Name;
1662 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1663 SourceRange(ActiveModule->DefinitionLoc));
1664 }
1665 }
1666}
1667
1668void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
1669 if (MD.Id.front().first == "*")
1670 return handleInferredModuleDecl(MD);
1671
1672 CurrModuleDeclLoc = MD.Location;
1673
1674 Module *PreviousActiveModule = ActiveModule;
1675 if (MD.Id.size() > 1) {
1676 // This module map defines a submodule. Go find the module of which it
1677 // is a submodule.
1678 ActiveModule = nullptr;
1679 const Module *TopLevelModule = nullptr;
1680 for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {
1681 if (Module *Next =
1682 Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {
1683 if (I == 0)
1684 TopLevelModule = Next;
1685 ActiveModule = Next;
1686 continue;
1687 }
1688
1689 Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)
1690 << MD.Id[I].first << (ActiveModule != nullptr)
1691 << (ActiveModule
1692 ? ActiveModule->getTopLevelModule()->getFullModuleName()
1693 : "");
1694 HadError = true;
1695 }
1696
1697 if (TopLevelModule &&
1698 ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
1699 assert(ModuleMapFID !=
1700 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
1701 "submodule defined in same file as 'module *' that allowed its "
1702 "top-level module");
1703 Map.addAdditionalModuleMapFile(
1704 TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
1705 }
1706 }
1707
1708 StringRef ModuleName = MD.Id.back().first;
1709 SourceLocation ModuleNameLoc = MD.Id.back().second;
1710
1711 // Determine whether this (sub)module has already been defined.
1712 Module *ShadowingModule = nullptr;
1713 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1714 // We might see a (re)definition of a module that we already have a
1715 // definition for in four cases:
1716 // - If we loaded one definition from an AST file and we've just found a
1717 // corresponding definition in a module map file, or
1718 bool LoadedFromASTFile = Existing->IsFromModuleFile;
1719 // - If we previously inferred this module from different module map file.
1720 bool Inferred = Existing->IsInferred;
1721 // - If we're building a framework that vends a module map, we might've
1722 // previously seen the one in intermediate products and now the system
1723 // one.
1724 // FIXME: If we're parsing module map file that looks like this:
1725 // framework module FW { ... }
1726 // module FW.Sub { ... }
1727 // We can't check the framework qualifier, since it's not attached to
1728 // the definition of Sub. Checking that qualifier on \c Existing is
1729 // not correct either, since we might've previously seen:
1730 // module FW { ... }
1731 // module FW.Sub { ... }
1732 // We should enforce consistency of redefinitions so that we can rely
1733 // that \c Existing is part of a framework iff the redefinition of FW
1734 // we have just skipped had it too. Once we do that, stop checking
1735 // the local framework qualifier and only rely on \c Existing.
1736 bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
1737 // - If we're building a (preprocessed) module and we've just loaded the
1738 // module map file from which it was created.
1739 bool ParsedAsMainInput =
1740 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1741 Map.LangOpts.CurrentModule == ModuleName &&
1742 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1743 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1744 // TODO: Remove this check when we can avoid loading module maps multiple
1745 // times.
1746 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;
1747 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||
1748 SameModuleDecl) {
1749 ActiveModule = PreviousActiveModule;
1750 // Skip the module definition.
1751 return;
1752 }
1753
1754 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
1755 ShadowingModule = Existing;
1756 } else {
1757 // This is not a shawdowed module decl, it is an illegal redefinition.
1758 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1759 << ModuleName;
1760 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1761 HadError = true;
1762 return;
1763 }
1764 }
1765
1766 // Start defining this module.
1767 if (ShadowingModule) {
1768 ActiveModule =
1769 Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
1770 } else {
1771 ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
1772 MD.Framework, MD.Explicit);
1773 }
1774
1775 ActiveModule->DefinitionLoc = ModuleNameLoc;
1776 if (MD.Attrs.IsSystem || IsSystem)
1777 ActiveModule->IsSystem = true;
1778 if (MD.Attrs.IsExternC)
1779 ActiveModule->IsExternC = true;
1781 ActiveModule->NoUndeclaredIncludes = true;
1782 ActiveModule->Directory = Directory;
1783
1784 StringRef MapFileName(
1785 SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
1786 if (MapFileName.ends_with("module.private.modulemap") ||
1787 MapFileName.ends_with("module_private.map")) {
1788 ActiveModule->ModuleMapIsPrivate = true;
1789 }
1790
1791 // Private modules named as FooPrivate, Foo.Private or similar are likely a
1792 // user error; provide warnings, notes and fixits to direct users to use
1793 // Foo_Private instead.
1794 SourceLocation StartLoc =
1795 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
1796 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1797 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1798 StartLoc) &&
1799 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1800 StartLoc) &&
1801 ActiveModule->ModuleMapIsPrivate)
1802 diagnosePrivateModules(MD.Location);
1803
1804 for (const modulemap::Decl &Decl : MD.Decls) {
1805 std::visit(
1806 llvm::makeVisitor(
1807 [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },
1808 [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
1809 [&](const modulemap::UmbrellaDirDecl &UDD) {
1810 handleUmbrellaDirDecl(UDD);
1811 },
1812 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
1813 [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
1814 [&](const modulemap::ExportAsDecl &EAD) {
1815 handleExportAsDecl(EAD);
1816 },
1817 [&](const modulemap::ExternModuleDecl &EMD) {
1818 handleExternModuleDecl(EMD);
1819 },
1820 [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },
1821 [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
1822 [&](const modulemap::ConfigMacrosDecl &CMD) {
1823 handleConfigMacros(CMD);
1824 },
1825 [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },
1826 [&](const modulemap::ExcludeDecl &ED) {
1827 Diags.Report(ED.Location, diag::err_mmap_expected_member);
1828 }),
1829 Decl);
1830 }
1831
1832 // If the active module is a top-level framework, and there are no link
1833 // libraries, automatically link against the framework.
1834 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1835 ActiveModule->LinkLibraries.empty())
1836 inferFrameworkLink(ActiveModule);
1837
1838 // If the module meets all requirements but is still unavailable, mark the
1839 // whole tree as unavailable to prevent it from building.
1840 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
1841 ActiveModule->Parent) {
1842 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
1843 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1844 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1845 }
1846
1847 // We're done parsing this module. Pop back to the previous module.
1848 ActiveModule = PreviousActiveModule;
1849}
1850
1851void ModuleMapLoader::handleExternModuleDecl(
1852 const modulemap::ExternModuleDecl &EMD) {
1853 StringRef FileNameRef = EMD.Path;
1854 SmallString<128> ModuleMapFileName;
1855 if (llvm::sys::path::is_relative(FileNameRef)) {
1856 ModuleMapFileName += Directory.getName();
1857 llvm::sys::path::append(ModuleMapFileName, EMD.Path);
1858 FileNameRef = ModuleMapFileName;
1859 }
1860 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
1861 Map.parseAndLoadModuleMapFile(
1862 *File, IsSystem,
1863 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1864 ? Directory
1865 : File->getDir(),
1866 FileID(), nullptr, EMD.Location);
1867}
1868
1869/// Whether to add the requirement \p Feature to the module \p M.
1870///
1871/// This preserves backwards compatibility for two hacks in the Darwin system
1872/// module map files:
1873///
1874/// 1. The use of 'requires excluded' to make headers non-modular, which
1875/// should really be mapped to 'textual' now that we have this feature. We
1876/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1877/// true. Later, this bit will be used to map all the headers inside this
1878/// module to 'textual'.
1879///
1880/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1881///
1882/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1883/// was never correct and causes issues now that we check it, so drop it.
1884static bool shouldAddRequirement(Module *M, StringRef Feature,
1885 bool &IsRequiresExcludedHack) {
1886 if (Feature == "excluded" &&
1887 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
1888 M->fullModuleNameIs({"Tcl", "Private"}))) {
1889 IsRequiresExcludedHack = true;
1890 return false;
1891 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
1892 return false;
1893 }
1894
1895 return true;
1896}
1897
1898void ModuleMapLoader::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
1899
1900 for (const modulemap::RequiresFeature &RF : RD.Features) {
1901 bool IsRequiresExcludedHack = false;
1902 bool ShouldAddRequirement =
1903 shouldAddRequirement(ActiveModule, RF.Feature, IsRequiresExcludedHack);
1904
1905 if (IsRequiresExcludedHack)
1906 UsesRequiresExcludedHack.insert(ActiveModule);
1907
1908 if (ShouldAddRequirement) {
1909 // Add this feature.
1910 ActiveModule->addRequirement(RF.Feature, RF.RequiredState, Map.LangOpts,
1911 *Map.Target);
1912 }
1913 }
1914}
1915
1916void ModuleMapLoader::handleHeaderDecl(const modulemap::HeaderDecl &HD) {
1917 // We've already consumed the first token.
1919
1920 if (HD.Private) {
1922 } else if (HD.Excluded) {
1924 }
1925
1926 if (HD.Textual)
1928
1929 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1930 // Mark this header 'textual' (see doc comment for
1931 // Module::UsesRequiresExcludedHack).
1933 }
1934
1935 Module::UnresolvedHeaderDirective Header;
1936 Header.FileName = HD.Path;
1937 Header.FileNameLoc = HD.PathLoc;
1938 Header.IsUmbrella = HD.Umbrella;
1939 Header.Kind = Map.headerRoleToKind(Role);
1940
1941 // Check whether we already have an umbrella.
1942 if (Header.IsUmbrella &&
1943 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
1944 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1945 << ActiveModule->getFullModuleName();
1946 HadError = true;
1947 return;
1948 }
1949
1950 if (HD.Size)
1951 Header.Size = HD.Size;
1952 if (HD.MTime)
1953 Header.ModTime = HD.MTime;
1954
1955 bool NeedsFramework = false;
1956 // Don't add headers to the builtin modules if the builtin headers belong to
1957 // the system modules, with the exception of __stddef_max_align_t.h which
1958 // always had its own module.
1959 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
1960 !isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||
1961 ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
1962 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
1963
1964 if (NeedsFramework)
1965 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
1966 << ActiveModule->getFullModuleName()
1967 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
1968}
1969
1971 const Module::Header &B) {
1972 return A.NameAsWritten < B.NameAsWritten;
1973}
1974
1975void ModuleMapLoader::handleUmbrellaDirDecl(
1976 const modulemap::UmbrellaDirDecl &UDD) {
1977 std::string DirName = std::string(UDD.Path);
1978 std::string DirNameAsWritten = DirName;
1979
1980 // Check whether we already have an umbrella.
1981 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
1982 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
1983 << ActiveModule->getFullModuleName();
1984 HadError = true;
1985 return;
1986 }
1987
1988 // Look for this file.
1990 if (llvm::sys::path::is_absolute(DirName)) {
1991 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
1992 } else {
1993 SmallString<128> PathName;
1994 PathName = Directory.getName();
1995 llvm::sys::path::append(PathName, DirName);
1996 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
1997 }
1998
1999 if (!Dir) {
2000 Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)
2001 << DirName;
2002 return;
2003 }
2004
2005 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2006 // Mark this header 'textual' (see doc comment for
2007 // ModuleMapLoader::UsesRequiresExcludedHack). Although iterating over the
2008 // directory is relatively expensive, in practice this only applies to the
2009 // uncommonly used Tcl module on Darwin platforms.
2010 std::error_code EC;
2011 SmallVector<Module::Header, 6> Headers;
2012 llvm::vfs::FileSystem &FS =
2013 SourceMgr.getFileManager().getVirtualFileSystem();
2014 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2015 I != E && !EC; I.increment(EC)) {
2016 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2017 Module::Header Header = {"", std::string(I->path()), *FE};
2018 Headers.push_back(std::move(Header));
2019 }
2020 }
2021
2022 // Sort header paths so that the pcm doesn't depend on iteration order.
2023 llvm::stable_sort(Headers, compareModuleHeaders);
2024
2025 for (auto &Header : Headers)
2026 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2027 return;
2028 }
2029
2030 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2031 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
2032 << OwningModule->getFullModuleName();
2033 HadError = true;
2034 return;
2035 }
2036
2037 // Record this umbrella directory.
2038 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
2039}
2040
2041void ModuleMapLoader::handleExportDecl(const modulemap::ExportDecl &ED) {
2042 Module::UnresolvedExportDecl Unresolved = {ED.Location, ED.Id, ED.Wildcard};
2043 ActiveModule->UnresolvedExports.push_back(Unresolved);
2044}
2045
2046void ModuleMapLoader::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
2047 const auto &ModName = EAD.Id.front();
2048
2049 if (!ActiveModule->ExportAsModule.empty()) {
2050 if (ActiveModule->ExportAsModule == ModName.first) {
2051 Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)
2052 << ActiveModule->Name << ModName.first;
2053 } else {
2054 Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)
2055 << ActiveModule->Name << ActiveModule->ExportAsModule
2056 << ModName.first;
2057 }
2058 }
2059
2060 ActiveModule->ExportAsModule = ModName.first;
2061 Map.addLinkAsDependency(ActiveModule);
2062}
2063
2064void ModuleMapLoader::handleUseDecl(const modulemap::UseDecl &UD) {
2065 if (ActiveModule->Parent)
2066 Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);
2067 else
2068 ActiveModule->UnresolvedDirectUses.push_back(UD.Id);
2069}
2070
2071void ModuleMapLoader::handleLinkDecl(const modulemap::LinkDecl &LD) {
2072 ActiveModule->LinkLibraries.push_back(
2073 Module::LinkLibrary(std::string{LD.Library}, LD.Framework));
2074}
2075
2076void ModuleMapLoader::handleConfigMacros(
2077 const modulemap::ConfigMacrosDecl &CMD) {
2078 if (ActiveModule->Parent) {
2079 Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);
2080 return;
2081 }
2082
2083 // TODO: Is this really the behavior we want for multiple config_macros
2084 // declarations? If any of them are exhaustive then all of them are.
2085 if (CMD.Exhaustive) {
2086 ActiveModule->ConfigMacrosExhaustive = true;
2087 }
2088 ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),
2089 CMD.Macros.begin(), CMD.Macros.end());
2090}
2091
2092void ModuleMapLoader::handleConflict(const modulemap::ConflictDecl &CD) {
2093 Module::UnresolvedConflict Conflict;
2094
2095 Conflict.Id = CD.Id;
2096 Conflict.Message = CD.Message;
2097
2098 // FIXME: when we move to C++20 we should consider using emplace_back
2099 ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));
2100}
2101
2102void ModuleMapLoader::handleInferredModuleDecl(
2103 const modulemap::ModuleDecl &MD) {
2104 SourceLocation StarLoc = MD.Id.front().second;
2105
2106 // Inferred modules must be submodules.
2107 if (!ActiveModule && !MD.Framework) {
2108 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2109 return;
2110 }
2111
2112 if (ActiveModule) {
2113 // Inferred modules must have umbrella directories.
2114 if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
2115 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2116 return;
2117 }
2118
2119 // Check for redefinition of an inferred module.
2120 if (ActiveModule->InferSubmodules) {
2121 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2122 if (ActiveModule->InferredSubmoduleLoc.isValid())
2123 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2124 diag::note_mmap_prev_definition);
2125 return;
2126 }
2127
2128 // Check for the 'framework' keyword, which is not permitted here.
2129 if (MD.Framework) {
2130 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2131 return;
2132 }
2133 } else if (MD.Explicit) {
2134 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2135 return;
2136 }
2137
2138 if (ActiveModule) {
2139 // Note that we have an inferred submodule.
2140 ActiveModule->InferSubmodules = true;
2141 ActiveModule->InferredSubmoduleLoc = StarLoc;
2142 ActiveModule->InferExplicitSubmodules = MD.Explicit;
2143 } else {
2144 // We'll be inferring framework modules for this directory.
2145 auto &InfDir = Map.InferredDirectories[Directory];
2146 InfDir.InferModules = true;
2147 InfDir.Attrs = MD.Attrs;
2148 InfDir.ModuleMapFID = ModuleMapFID;
2149 // FIXME: Handle the 'framework' keyword.
2150 }
2151
2152 for (const modulemap::Decl &Decl : MD.Decls) {
2153 std::visit(
2154 llvm::makeVisitor(
2155 [&](const auto &Other) {
2156 Diags.Report(Other.Location,
2157 diag::err_mmap_expected_inferred_member)
2158 << (ActiveModule != nullptr);
2159 },
2160 [&](const modulemap::ExcludeDecl &ED) {
2161 // Only inferred frameworks can have exclude decls
2162 if (ActiveModule) {
2163 Diags.Report(ED.Location,
2164 diag::err_mmap_expected_inferred_member)
2165 << (ActiveModule != nullptr);
2166 HadError = true;
2167 return;
2168 }
2169 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(
2170 ED.Module);
2171 },
2172 [&](const modulemap::ExportDecl &ED) {
2173 // Only inferred submodules can have export decls
2174 if (!ActiveModule) {
2175 Diags.Report(ED.Location,
2176 diag::err_mmap_expected_inferred_member)
2177 << (ActiveModule != nullptr);
2178 HadError = true;
2179 return;
2180 }
2181
2182 if (ED.Wildcard && ED.Id.size() == 0)
2183 ActiveModule->InferExportWildcard = true;
2184 else
2185 Diags.Report(ED.Id.front().second,
2186 diag::err_mmap_expected_export_wildcard);
2187 }),
2188 Decl);
2189 }
2190}
2191
2193 handleModuleDecl(MD);
2194 return HadError;
2195}
2196
2198 const modulemap::ExternModuleDecl &EMD) {
2199 handleExternModuleDecl(EMD);
2200 return HadError;
2201}
2202
2204 const modulemap::ModuleMapFile &MMF) {
2205 for (const auto &Decl : MMF.Decls) {
2206 std::visit(
2207 llvm::makeVisitor(
2208 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
2209 [&](const modulemap::ExternModuleDecl &EMD) {
2210 handleExternModuleDecl(EMD);
2211 }),
2212 Decl);
2213 }
2214 return HadError;
2215}
2216
2218 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
2219 if (Known != Modules.end())
2220 return Known->getValue();
2221
2222 auto ParsedMod = ParsedModules.find(Name);
2223 if (ParsedMod == ParsedModules.end())
2224 return nullptr;
2225
2226 Diags.Report(diag::remark_mmap_load_module) << Name;
2227
2228 for (const auto &ModuleDecl : ParsedMod->second) {
2229 const modulemap::ModuleMapFile &MMF = *ModuleDecl.first;
2230 ModuleMapLoader Loader(SourceMgr, Diags, const_cast<ModuleMap &>(*this),
2231 MMF.ID, *MMF.Dir, MMF.IsSystem);
2232 if (Loader.loadModuleDecl(*ModuleDecl.second))
2233 return nullptr;
2234 }
2235
2236 return findModule(Name);
2237}
2238
2240 DirectoryEntryRef Dir, FileID ID,
2241 unsigned *Offset,
2242 SourceLocation ExternModuleLoc) {
2243 assert(Target && "Missing target information");
2244 llvm::DenseMap<const FileEntry *, bool>::iterator Known =
2245 LoadedModuleMap.find(File);
2246 if (Known != LoadedModuleMap.end())
2247 return Known->second;
2248
2249 // If the module map file wasn't already entered, do so now.
2250 if (ID.isInvalid()) {
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 FileID &LocalFID = ModuleMapLocalFileID[File];
2256 if (LocalFID.isInvalid()) {
2257 auto FileCharacter =
2259 LocalFID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2260 }
2261 ID = LocalFID;
2262 }
2263
2264 assert(Target && "Missing target information");
2265 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
2266 if (!Buffer)
2267 return LoadedModuleMap[File] = true;
2268 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2269 "invalid buffer offset");
2270
2271 std::optional<modulemap::ModuleMapFile> MMF =
2272 modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, Offset);
2273 bool Result = false;
2274 if (MMF) {
2275 Diags.Report(diag::remark_mmap_load) << File.getName();
2276 ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem);
2277 Result = Loader.parseAndLoadModuleMapFile(*MMF);
2278 }
2279 LoadedModuleMap[File] = Result;
2280
2281 // Notify callbacks that we observed it.
2282 // FIXME: We should only report module maps that were actually used.
2283 for (const auto &Cb : Callbacks)
2284 Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);
2285
2286 return Result;
2287}
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
std::shared_ptr< TokenRole > Role
A token can have a special role that can carry extra information about the token's formatting.
FormatToken * Next
The next token in the unwrapped line.
#define ALIAS(NAME, TOK, FLAGS)
#define KEYWORD(NAME, FLAGS)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
static Module * getTopLevelOrNull(Module *M)
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives.
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition FileEntry.h:57
StringRef getName() const
The name of this FileEntry.
Definition FileEntry.h:61
DirectoryEntryRef getDir() const
Definition FileEntry.h:78
Cached information about one file (either on disk or in the virtual file system).
Definition FileEntry.h:302
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isInvalid() const
Implements support for file system lookup, file system caching, and directory search management.
Definition FileManager.h:53
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:140
unsigned ImplicitModuleMaps
Implicit module maps.
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
void loadTopLevelSystemModules()
Load all known, top-level system modules.
const HeaderSearchOptions & getHeaderSearchOpts() const
Retrieve the header-search options with which this header search was initialized.
OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework)
Try to find a module map file in the given directory, returning nullopt if none is found.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Required to construct a Module.
Definition Module.h: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:543
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:336
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:562
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