1//===- Module.cpp - Describe a module -------------------------------------===//
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 Module class, which describes a module in the source
10// code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Basic/Module.h"
15#include "clang/Basic/CharInfo.h"
16#include "clang/Basic/FileManager.h"
17#include "clang/Basic/LangOptions.h"
18#include "clang/Basic/SourceLocation.h"
19#include "clang/Basic/TargetInfo.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringMap.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/Support/Compiler.h"
26#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/raw_ostream.h"
28#include <algorithm>
29#include <cassert>
30#include <functional>
31#include <string>
32#include <utility>
33#include <vector>
34
35using namespace clang;
36
37Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
38 bool IsFramework, bool IsExplicit, unsigned VisibilityID)
39 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40 VisibilityID(VisibilityID), IsUnimportable(false),
41 HasIncompatibleModuleFile(false), IsAvailable(true),
42 IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
43 IsSystem(false), IsExternC(false), IsInferred(false),
44 InferSubmodules(false), InferExplicitSubmodules(false),
45 InferExportWildcard(false), ConfigMacrosExhaustive(false),
46 NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
47 NamedModuleHasInit(true), NameVisibility(Hidden) {
48 if (Parent) {
49 IsAvailable = Parent->isAvailable();
50 IsUnimportable = Parent->isUnimportable();
51 IsSystem = Parent->IsSystem;
52 IsExternC = Parent->IsExternC;
53 NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
54 ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
55
56 Parent->SubModuleIndex[Name] = Parent->SubModules.size();
57 Parent->SubModules.push_back(x: this);
58 }
59}
60
61Module::~Module() {
62 for (auto *Submodule : SubModules) {
63 delete Submodule;
64 }
65}
66
67static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
68 StringRef Platform = Target.getPlatformName();
69 StringRef Env = Target.getTriple().getEnvironmentName();
70
71 // Attempt to match platform and environment.
72 if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
73 Env == Feature)
74 return true;
75
76 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
77 auto Pos = LHS.find(C: '-');
78 if (Pos == StringRef::npos)
79 return false;
80 SmallString<128> NewLHS = LHS.slice(Start: 0, End: Pos);
81 NewLHS += LHS.slice(Start: Pos+1, End: LHS.size());
82 return NewLHS == RHS;
83 };
84
85 SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
86 // Darwin has different but equivalent variants for simulators, example:
87 // 1. x86_64-apple-ios-simulator
88 // 2. x86_64-apple-iossimulator
89 // where both are valid examples of the same platform+environment but in the
90 // variant (2) the simulator is hardcoded as part of the platform name. Both
91 // forms above should match for "iossimulator" requirement.
92 if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with(Suffix: "simulator"))
93 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
94
95 return PlatformEnv == Feature;
96}
97
98/// Determine whether a translation unit built using the current
99/// language options has the given feature.
100static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
101 const TargetInfo &Target) {
102 bool HasFeature = llvm::StringSwitch<bool>(Feature)
103 .Case(S: "altivec", Value: LangOpts.AltiVec)
104 .Case(S: "blocks", Value: LangOpts.Blocks)
105 .Case(S: "coroutines", Value: LangOpts.Coroutines)
106 .Case(S: "cplusplus", Value: LangOpts.CPlusPlus)
107 .Case(S: "cplusplus11", Value: LangOpts.CPlusPlus11)
108 .Case(S: "cplusplus14", Value: LangOpts.CPlusPlus14)
109 .Case(S: "cplusplus17", Value: LangOpts.CPlusPlus17)
110 .Case(S: "cplusplus20", Value: LangOpts.CPlusPlus20)
111 .Case(S: "cplusplus23", Value: LangOpts.CPlusPlus23)
112 .Case(S: "cplusplus26", Value: LangOpts.CPlusPlus26)
113 .Case(S: "c99", Value: LangOpts.C99)
114 .Case(S: "c11", Value: LangOpts.C11)
115 .Case(S: "c17", Value: LangOpts.C17)
116 .Case(S: "c23", Value: LangOpts.C23)
117 .Case(S: "freestanding", Value: LangOpts.Freestanding)
118 .Case(S: "gnuinlineasm", Value: LangOpts.GNUAsm)
119 .Case(S: "objc", Value: LangOpts.ObjC)
120 .Case(S: "objc_arc", Value: LangOpts.ObjCAutoRefCount)
121 .Case(S: "opencl", Value: LangOpts.OpenCL)
122 .Case(S: "tls", Value: Target.isTLSSupported())
123 .Case(S: "zvector", Value: LangOpts.ZVector)
124 .Default(Value: Target.hasFeature(Feature) ||
125 isPlatformEnvironment(Target, Feature));
126 if (!HasFeature)
127 HasFeature = llvm::is_contained(Range: LangOpts.ModuleFeatures, Element: Feature);
128 return HasFeature;
129}
130
131bool Module::isUnimportable(const LangOptions &LangOpts,
132 const TargetInfo &Target, Requirement &Req,
133 Module *&ShadowingModule) const {
134 if (!IsUnimportable)
135 return false;
136
137 for (const Module *Current = this; Current; Current = Current->Parent) {
138 if (Current->ShadowingModule) {
139 ShadowingModule = Current->ShadowingModule;
140 return true;
141 }
142 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
143 if (hasFeature(Feature: Current->Requirements[I].first, LangOpts, Target) !=
144 Current->Requirements[I].second) {
145 Req = Current->Requirements[I];
146 return true;
147 }
148 }
149 }
150
151 llvm_unreachable("could not find a reason why module is unimportable");
152}
153
154// The -fmodule-name option tells the compiler to textually include headers in
155// the specified module, meaning Clang won't build the specified module. This
156// is useful in a number of situations, for instance, when building a library
157// that vends a module map, one might want to avoid hitting intermediate build
158// products containing the module map or avoid finding the system installed
159// modulemap for that library.
160bool Module::isForBuilding(const LangOptions &LangOpts) const {
161 StringRef TopLevelName = getTopLevelModuleName();
162 StringRef CurrentModule = LangOpts.CurrentModule;
163
164 // When building the implementation of framework Foo, we want to make sure
165 // that Foo *and* Foo_Private are textually included and no modules are built
166 // for either.
167 if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
168 CurrentModule == LangOpts.ModuleName &&
169 !CurrentModule.ends_with(Suffix: "_Private") &&
170 TopLevelName.ends_with(Suffix: "_Private"))
171 TopLevelName = TopLevelName.drop_back(N: 8);
172
173 return TopLevelName == CurrentModule;
174}
175
176bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
177 Requirement &Req,
178 UnresolvedHeaderDirective &MissingHeader,
179 Module *&ShadowingModule) const {
180 if (IsAvailable)
181 return true;
182
183 if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
184 return false;
185
186 // FIXME: All missing headers are listed on the top-level module. Should we
187 // just look there?
188 for (const Module *Current = this; Current; Current = Current->Parent) {
189 if (!Current->MissingHeaders.empty()) {
190 MissingHeader = Current->MissingHeaders.front();
191 return false;
192 }
193 }
194
195 llvm_unreachable("could not find a reason why module is unavailable");
196}
197
198bool Module::isSubModuleOf(const Module *Other) const {
199 for (auto *Parent = this; Parent; Parent = Parent->Parent) {
200 if (Parent == Other)
201 return true;
202 }
203 return false;
204}
205
206const Module *Module::getTopLevelModule() const {
207 const Module *Result = this;
208 while (Result->Parent)
209 Result = Result->Parent;
210
211 return Result;
212}
213
214static StringRef getModuleNameFromComponent(
215 const std::pair<std::string, SourceLocation> &IdComponent) {
216 return IdComponent.first;
217}
218
219static StringRef getModuleNameFromComponent(StringRef R) { return R; }
220
221template<typename InputIter>
222static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
223 bool AllowStringLiterals = true) {
224 for (InputIter It = Begin; It != End; ++It) {
225 if (It != Begin)
226 OS << ".";
227
228 StringRef Name = getModuleNameFromComponent(*It);
229 if (!AllowStringLiterals || isValidAsciiIdentifier(S: Name))
230 OS << Name;
231 else {
232 OS << '"';
233 OS.write_escaped(Str: Name);
234 OS << '"';
235 }
236 }
237}
238
239template<typename Container>
240static void printModuleId(raw_ostream &OS, const Container &C) {
241 return printModuleId(OS, C.begin(), C.end());
242}
243
244std::string Module::getFullModuleName(bool AllowStringLiterals) const {
245 SmallVector<StringRef, 2> Names;
246
247 // Build up the set of module names (from innermost to outermost).
248 for (const Module *M = this; M; M = M->Parent)
249 Names.push_back(Elt: M->Name);
250
251 std::string Result;
252
253 llvm::raw_string_ostream Out(Result);
254 printModuleId(OS&: Out, Begin: Names.rbegin(), End: Names.rend(), AllowStringLiterals);
255 Out.flush();
256
257 return Result;
258}
259
260bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
261 for (const Module *M = this; M; M = M->Parent) {
262 if (nameParts.empty() || M->Name != nameParts.back())
263 return false;
264 nameParts = nameParts.drop_back();
265 }
266 return nameParts.empty();
267}
268
269OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
270 if (const auto *Hdr = std::get_if<FileEntryRef>(ptr: &Umbrella))
271 return Hdr->getDir();
272 if (const auto *Dir = std::get_if<DirectoryEntryRef>(ptr: &Umbrella))
273 return *Dir;
274 return std::nullopt;
275}
276
277void Module::addTopHeader(FileEntryRef File) {
278 assert(File);
279 TopHeaders.insert(X: File);
280}
281
282ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
283 if (!TopHeaderNames.empty()) {
284 for (StringRef TopHeaderName : TopHeaderNames)
285 if (auto FE = FileMgr.getOptionalFileRef(Filename: TopHeaderName))
286 TopHeaders.insert(X: *FE);
287 TopHeaderNames.clear();
288 }
289
290 return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
291}
292
293bool Module::directlyUses(const Module *Requested) {
294 auto *Top = getTopLevelModule();
295
296 // A top-level module implicitly uses itself.
297 if (Requested->isSubModuleOf(Other: Top))
298 return true;
299
300 for (auto *Use : Top->DirectUses)
301 if (Requested->isSubModuleOf(Other: Use))
302 return true;
303
304 // Anyone is allowed to use our builtin stdarg.h and stddef.h and their
305 // accompanying modules.
306 if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" ||
307 Requested->getTopLevelModuleName() == "_Builtin_stddef")
308 return true;
309
310 if (NoUndeclaredIncludes)
311 UndeclaredUses.insert(X: Requested);
312
313 return false;
314}
315
316void Module::addRequirement(StringRef Feature, bool RequiredState,
317 const LangOptions &LangOpts,
318 const TargetInfo &Target) {
319 Requirements.push_back(Elt: Requirement(std::string(Feature), RequiredState));
320
321 // If this feature is currently available, we're done.
322 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
323 return;
324
325 markUnavailable(/*Unimportable*/true);
326}
327
328void Module::markUnavailable(bool Unimportable) {
329 auto needUpdate = [Unimportable](Module *M) {
330 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
331 };
332
333 if (!needUpdate(this))
334 return;
335
336 SmallVector<Module *, 2> Stack;
337 Stack.push_back(Elt: this);
338 while (!Stack.empty()) {
339 Module *Current = Stack.back();
340 Stack.pop_back();
341
342 if (!needUpdate(Current))
343 continue;
344
345 Current->IsAvailable = false;
346 Current->IsUnimportable |= Unimportable;
347 for (auto *Submodule : Current->submodules()) {
348 if (needUpdate(Submodule))
349 Stack.push_back(Elt: Submodule);
350 }
351 }
352}
353
354Module *Module::findSubmodule(StringRef Name) const {
355 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Key: Name);
356 if (Pos == SubModuleIndex.end())
357 return nullptr;
358
359 return SubModules[Pos->getValue()];
360}
361
362Module *Module::findOrInferSubmodule(StringRef Name) {
363 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Key: Name);
364 if (Pos != SubModuleIndex.end())
365 return SubModules[Pos->getValue()];
366 if (!InferSubmodules)
367 return nullptr;
368 Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
369 Result->InferExplicitSubmodules = InferExplicitSubmodules;
370 Result->InferSubmodules = InferSubmodules;
371 Result->InferExportWildcard = InferExportWildcard;
372 if (Result->InferExportWildcard)
373 Result->Exports.push_back(Elt: Module::ExportDecl(nullptr, true));
374 return Result;
375}
376
377Module *Module::getGlobalModuleFragment() const {
378 assert(isNamedModuleUnit() && "We should only query the global module "
379 "fragment from the C++20 Named modules");
380
381 for (auto *SubModule : SubModules)
382 if (SubModule->isExplicitGlobalModule())
383 return SubModule;
384
385 return nullptr;
386}
387
388Module *Module::getPrivateModuleFragment() const {
389 assert(isNamedModuleUnit() && "We should only query the private module "
390 "fragment from the C++20 Named modules");
391
392 for (auto *SubModule : SubModules)
393 if (SubModule->isPrivateModule())
394 return SubModule;
395
396 return nullptr;
397}
398
399void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
400 // All non-explicit submodules are exported.
401 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
402 E = SubModules.end();
403 I != E; ++I) {
404 Module *Mod = *I;
405 if (!Mod->IsExplicit)
406 Exported.push_back(Elt: Mod);
407 }
408
409 // Find re-exported modules by filtering the list of imported modules.
410 bool AnyWildcard = false;
411 bool UnrestrictedWildcard = false;
412 SmallVector<Module *, 4> WildcardRestrictions;
413 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
414 Module *Mod = Exports[I].getPointer();
415 if (!Exports[I].getInt()) {
416 // Export a named module directly; no wildcards involved.
417 Exported.push_back(Elt: Mod);
418
419 continue;
420 }
421
422 // Wildcard export: export all of the imported modules that match
423 // the given pattern.
424 AnyWildcard = true;
425 if (UnrestrictedWildcard)
426 continue;
427
428 if (Module *Restriction = Exports[I].getPointer())
429 WildcardRestrictions.push_back(Elt: Restriction);
430 else {
431 WildcardRestrictions.clear();
432 UnrestrictedWildcard = true;
433 }
434 }
435
436 // If there were any wildcards, push any imported modules that were
437 // re-exported by the wildcard restriction.
438 if (!AnyWildcard)
439 return;
440
441 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
442 Module *Mod = Imports[I];
443 bool Acceptable = UnrestrictedWildcard;
444 if (!Acceptable) {
445 // Check whether this module meets one of the restrictions.
446 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
447 Module *Restriction = WildcardRestrictions[R];
448 if (Mod == Restriction || Mod->isSubModuleOf(Other: Restriction)) {
449 Acceptable = true;
450 break;
451 }
452 }
453 }
454
455 if (!Acceptable)
456 continue;
457
458 Exported.push_back(Elt: Mod);
459 }
460}
461
462void Module::buildVisibleModulesCache() const {
463 assert(VisibleModulesCache.empty() && "cache does not need building");
464
465 // This module is visible to itself.
466 VisibleModulesCache.insert(V: this);
467
468 // Every imported module is visible.
469 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
470 while (!Stack.empty()) {
471 Module *CurrModule = Stack.pop_back_val();
472
473 // Every module transitively exported by an imported module is visible.
474 if (VisibleModulesCache.insert(V: CurrModule).second)
475 CurrModule->getExportedModules(Exported&: Stack);
476 }
477}
478
479void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
480 OS.indent(NumSpaces: Indent);
481 if (IsFramework)
482 OS << "framework ";
483 if (IsExplicit)
484 OS << "explicit ";
485 OS << "module ";
486 printModuleId(OS, Begin: &Name, End: &Name + 1);
487
488 if (IsSystem || IsExternC) {
489 OS.indent(NumSpaces: Indent + 2);
490 if (IsSystem)
491 OS << " [system]";
492 if (IsExternC)
493 OS << " [extern_c]";
494 }
495
496 OS << " {\n";
497
498 if (!Requirements.empty()) {
499 OS.indent(NumSpaces: Indent + 2);
500 OS << "requires ";
501 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
502 if (I)
503 OS << ", ";
504 if (!Requirements[I].second)
505 OS << "!";
506 OS << Requirements[I].first;
507 }
508 OS << "\n";
509 }
510
511 if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
512 OS.indent(NumSpaces: Indent + 2);
513 OS << "umbrella header \"";
514 OS.write_escaped(Str: H->NameAsWritten);
515 OS << "\"\n";
516 } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
517 OS.indent(NumSpaces: Indent + 2);
518 OS << "umbrella \"";
519 OS.write_escaped(Str: D->NameAsWritten);
520 OS << "\"\n";
521 }
522
523 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
524 OS.indent(NumSpaces: Indent + 2);
525 OS << "config_macros ";
526 if (ConfigMacrosExhaustive)
527 OS << "[exhaustive]";
528 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
529 if (I)
530 OS << ", ";
531 OS << ConfigMacros[I];
532 }
533 OS << "\n";
534 }
535
536 struct {
537 StringRef Prefix;
538 HeaderKind Kind;
539 } Kinds[] = {{.Prefix: "", .Kind: HK_Normal},
540 {.Prefix: "textual ", .Kind: HK_Textual},
541 {.Prefix: "private ", .Kind: HK_Private},
542 {.Prefix: "private textual ", .Kind: HK_PrivateTextual},
543 {.Prefix: "exclude ", .Kind: HK_Excluded}};
544
545 for (auto &K : Kinds) {
546 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
547 for (auto &H : Headers[K.Kind]) {
548 OS.indent(NumSpaces: Indent + 2);
549 OS << K.Prefix << "header \"";
550 OS.write_escaped(Str: H.NameAsWritten);
551 OS << "\" { size " << H.Entry.getSize()
552 << " mtime " << H.Entry.getModificationTime() << " }\n";
553 }
554 }
555 for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
556 for (auto &U : *Unresolved) {
557 OS.indent(NumSpaces: Indent + 2);
558 OS << Kinds[U.Kind].Prefix << "header \"";
559 OS.write_escaped(Str: U.FileName);
560 OS << "\"";
561 if (U.Size || U.ModTime) {
562 OS << " {";
563 if (U.Size)
564 OS << " size " << *U.Size;
565 if (U.ModTime)
566 OS << " mtime " << *U.ModTime;
567 OS << " }";
568 }
569 OS << "\n";
570 }
571 }
572
573 if (!ExportAsModule.empty()) {
574 OS.indent(NumSpaces: Indent + 2);
575 OS << "export_as" << ExportAsModule << "\n";
576 }
577
578 for (auto *Submodule : submodules())
579 // Print inferred subframework modules so that we don't need to re-infer
580 // them (requires expensive directory iteration + stat calls) when we build
581 // the module. Regular inferred submodules are OK, as we need to look at all
582 // those header files anyway.
583 if (!Submodule->IsInferred || Submodule->IsFramework)
584 Submodule->print(OS, Indent: Indent + 2, Dump);
585
586 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
587 OS.indent(NumSpaces: Indent + 2);
588 OS << "export ";
589 if (Module *Restriction = Exports[I].getPointer()) {
590 OS << Restriction->getFullModuleName(AllowStringLiterals: true);
591 if (Exports[I].getInt())
592 OS << ".*";
593 } else {
594 OS << "*";
595 }
596 OS << "\n";
597 }
598
599 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
600 OS.indent(NumSpaces: Indent + 2);
601 OS << "export ";
602 printModuleId(OS, C: UnresolvedExports[I].Id);
603 if (UnresolvedExports[I].Wildcard)
604 OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
605 OS << "\n";
606 }
607
608 if (Dump) {
609 for (Module *M : Imports) {
610 OS.indent(NumSpaces: Indent + 2);
611 llvm::errs() << "import " << M->getFullModuleName() << "\n";
612 }
613 }
614
615 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
616 OS.indent(NumSpaces: Indent + 2);
617 OS << "use ";
618 OS << DirectUses[I]->getFullModuleName(AllowStringLiterals: true);
619 OS << "\n";
620 }
621
622 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
623 OS.indent(NumSpaces: Indent + 2);
624 OS << "use ";
625 printModuleId(OS, C: UnresolvedDirectUses[I]);
626 OS << "\n";
627 }
628
629 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
630 OS.indent(NumSpaces: Indent + 2);
631 OS << "link ";
632 if (LinkLibraries[I].IsFramework)
633 OS << "framework ";
634 OS << "\"";
635 OS.write_escaped(Str: LinkLibraries[I].Library);
636 OS << "\"";
637 }
638
639 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
640 OS.indent(NumSpaces: Indent + 2);
641 OS << "conflict ";
642 printModuleId(OS, C: UnresolvedConflicts[I].Id);
643 OS << ", \"";
644 OS.write_escaped(Str: UnresolvedConflicts[I].Message);
645 OS << "\"\n";
646 }
647
648 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
649 OS.indent(NumSpaces: Indent + 2);
650 OS << "conflict ";
651 OS << Conflicts[I].Other->getFullModuleName(AllowStringLiterals: true);
652 OS << ", \"";
653 OS.write_escaped(Str: Conflicts[I].Message);
654 OS << "\"\n";
655 }
656
657 if (InferSubmodules) {
658 OS.indent(NumSpaces: Indent + 2);
659 if (InferExplicitSubmodules)
660 OS << "explicit ";
661 OS << "module * {\n";
662 if (InferExportWildcard) {
663 OS.indent(NumSpaces: Indent + 4);
664 OS << "export *\n";
665 }
666 OS.indent(NumSpaces: Indent + 2);
667 OS << "}\n";
668 }
669
670 OS.indent(NumSpaces: Indent);
671 OS << "}\n";
672}
673
674LLVM_DUMP_METHOD void Module::dump() const {
675 print(OS&: llvm::errs(), Indent: 0, Dump: true);
676}
677
678void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
679 VisibleCallback Vis, ConflictCallback Cb) {
680 // We can't import a global module fragment so the location can be invalid.
681 assert((M->isGlobalModule() || Loc.isValid()) &&
682 "setVisible expects a valid import location");
683 if (isVisible(M))
684 return;
685
686 ++Generation;
687
688 struct Visiting {
689 Module *M;
690 Visiting *ExportedBy;
691 };
692
693 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
694 // Nothing to do for a module that's already visible.
695 unsigned ID = V.M->getVisibilityID();
696 if (ImportLocs.size() <= ID)
697 ImportLocs.resize(new_size: ID + 1);
698 else if (ImportLocs[ID].isValid())
699 return;
700
701 ImportLocs[ID] = Loc;
702 Vis(V.M);
703
704 // Make any exported modules visible.
705 SmallVector<Module *, 16> Exports;
706 V.M->getExportedModules(Exported&: Exports);
707 for (Module *E : Exports) {
708 // Don't import non-importable modules.
709 if (!E->isUnimportable())
710 VisitModule({.M: E, .ExportedBy: &V});
711 }
712
713 for (auto &C : V.M->Conflicts) {
714 if (isVisible(M: C.Other)) {
715 llvm::SmallVector<Module*, 8> Path;
716 for (Visiting *I = &V; I; I = I->ExportedBy)
717 Path.push_back(Elt: I->M);
718 Cb(Path, C.Other, C.Message);
719 }
720 }
721 };
722 VisitModule({.M: M, .ExportedBy: nullptr});
723}
724
725void VisibleModuleSet::makeTransitiveImportsVisible(Module *M,
726 SourceLocation Loc,
727 VisibleCallback Vis,
728 ConflictCallback Cb) {
729 for (auto *I : M->Imports)
730 setVisible(M: I, Loc, Vis, Cb);
731}
732
733ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
734 : Signature(M.Signature), ClangModule(&M) {
735 if (M.Directory)
736 Path = M.Directory->getName();
737 if (auto File = M.getASTFile())
738 ASTFile = File->getName();
739}
740
741std::string ASTSourceDescriptor::getModuleName() const {
742 if (ClangModule)
743 return ClangModule->Name;
744 else
745 return std::string(PCHModuleName);
746}
747

source code of clang/lib/Basic/Module.cpp