Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Basic/Module.cpp
35232 views
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
35
using namespace clang;
36
37
Module::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(this);
58
}
59
}
60
61
Module::~Module() {
62
for (auto *Submodule : SubModules) {
63
delete Submodule;
64
}
65
}
66
67
static 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('-');
78
if (Pos == StringRef::npos)
79
return false;
80
SmallString<128> NewLHS = LHS.slice(0, Pos);
81
NewLHS += LHS.slice(Pos+1, 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("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.
100
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
101
const TargetInfo &Target) {
102
bool HasFeature = llvm::StringSwitch<bool>(Feature)
103
.Case("altivec", LangOpts.AltiVec)
104
.Case("blocks", LangOpts.Blocks)
105
.Case("coroutines", LangOpts.Coroutines)
106
.Case("cplusplus", LangOpts.CPlusPlus)
107
.Case("cplusplus11", LangOpts.CPlusPlus11)
108
.Case("cplusplus14", LangOpts.CPlusPlus14)
109
.Case("cplusplus17", LangOpts.CPlusPlus17)
110
.Case("cplusplus20", LangOpts.CPlusPlus20)
111
.Case("cplusplus23", LangOpts.CPlusPlus23)
112
.Case("cplusplus26", LangOpts.CPlusPlus26)
113
.Case("c99", LangOpts.C99)
114
.Case("c11", LangOpts.C11)
115
.Case("c17", LangOpts.C17)
116
.Case("c23", LangOpts.C23)
117
.Case("freestanding", LangOpts.Freestanding)
118
.Case("gnuinlineasm", LangOpts.GNUAsm)
119
.Case("objc", LangOpts.ObjC)
120
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
121
.Case("opencl", LangOpts.OpenCL)
122
.Case("tls", Target.isTLSSupported())
123
.Case("zvector", LangOpts.ZVector)
124
.Default(Target.hasFeature(Feature) ||
125
isPlatformEnvironment(Target, Feature));
126
if (!HasFeature)
127
HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
128
return HasFeature;
129
}
130
131
bool 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(Current->Requirements[I].FeatureName, LangOpts, Target) !=
144
Current->Requirements[I].RequiredState) {
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.
160
bool 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("_Private") &&
170
TopLevelName.ends_with("_Private"))
171
TopLevelName = TopLevelName.drop_back(8);
172
173
return TopLevelName == CurrentModule;
174
}
175
176
bool 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
198
bool 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
206
const Module *Module::getTopLevelModule() const {
207
const Module *Result = this;
208
while (Result->Parent)
209
Result = Result->Parent;
210
211
return Result;
212
}
213
214
static StringRef getModuleNameFromComponent(
215
const std::pair<std::string, SourceLocation> &IdComponent) {
216
return IdComponent.first;
217
}
218
219
static StringRef getModuleNameFromComponent(StringRef R) { return R; }
220
221
template<typename InputIter>
222
static 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(Name))
230
OS << Name;
231
else {
232
OS << '"';
233
OS.write_escaped(Name);
234
OS << '"';
235
}
236
}
237
}
238
239
template<typename Container>
240
static void printModuleId(raw_ostream &OS, const Container &C) {
241
return printModuleId(OS, C.begin(), C.end());
242
}
243
244
std::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(M->Name);
250
251
std::string Result;
252
253
llvm::raw_string_ostream Out(Result);
254
printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
255
Out.flush();
256
257
return Result;
258
}
259
260
bool 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
269
OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
270
if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
271
return Hdr->getDir();
272
if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
273
return *Dir;
274
return std::nullopt;
275
}
276
277
void Module::addTopHeader(FileEntryRef File) {
278
assert(File);
279
TopHeaders.insert(File);
280
}
281
282
ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
283
if (!TopHeaderNames.empty()) {
284
for (StringRef TopHeaderName : TopHeaderNames)
285
if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
286
TopHeaders.insert(*FE);
287
TopHeaderNames.clear();
288
}
289
290
return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
291
}
292
293
bool Module::directlyUses(const Module *Requested) {
294
auto *Top = getTopLevelModule();
295
296
// A top-level module implicitly uses itself.
297
if (Requested->isSubModuleOf(Top))
298
return true;
299
300
for (auto *Use : Top->DirectUses)
301
if (Requested->isSubModuleOf(Use))
302
return true;
303
304
// Anyone is allowed to use our builtin stddef.h and its accompanying modules.
305
if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
306
Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
307
return true;
308
// Darwin is allowed is to use our builtin 'ptrauth.h' and its accompanying
309
// module.
310
if (!Requested->Parent && Requested->Name == "ptrauth")
311
return true;
312
313
if (NoUndeclaredIncludes)
314
UndeclaredUses.insert(Requested);
315
316
return false;
317
}
318
319
void Module::addRequirement(StringRef Feature, bool RequiredState,
320
const LangOptions &LangOpts,
321
const TargetInfo &Target) {
322
Requirements.push_back(Requirement{std::string(Feature), RequiredState});
323
324
// If this feature is currently available, we're done.
325
if (hasFeature(Feature, LangOpts, Target) == RequiredState)
326
return;
327
328
markUnavailable(/*Unimportable*/true);
329
}
330
331
void Module::markUnavailable(bool Unimportable) {
332
auto needUpdate = [Unimportable](Module *M) {
333
return M->IsAvailable || (!M->IsUnimportable && Unimportable);
334
};
335
336
if (!needUpdate(this))
337
return;
338
339
SmallVector<Module *, 2> Stack;
340
Stack.push_back(this);
341
while (!Stack.empty()) {
342
Module *Current = Stack.back();
343
Stack.pop_back();
344
345
if (!needUpdate(Current))
346
continue;
347
348
Current->IsAvailable = false;
349
Current->IsUnimportable |= Unimportable;
350
for (auto *Submodule : Current->submodules()) {
351
if (needUpdate(Submodule))
352
Stack.push_back(Submodule);
353
}
354
}
355
}
356
357
Module *Module::findSubmodule(StringRef Name) const {
358
llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
359
if (Pos == SubModuleIndex.end())
360
return nullptr;
361
362
return SubModules[Pos->getValue()];
363
}
364
365
Module *Module::findOrInferSubmodule(StringRef Name) {
366
llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
367
if (Pos != SubModuleIndex.end())
368
return SubModules[Pos->getValue()];
369
if (!InferSubmodules)
370
return nullptr;
371
Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
372
Result->InferExplicitSubmodules = InferExplicitSubmodules;
373
Result->InferSubmodules = InferSubmodules;
374
Result->InferExportWildcard = InferExportWildcard;
375
if (Result->InferExportWildcard)
376
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
377
return Result;
378
}
379
380
Module *Module::getGlobalModuleFragment() const {
381
assert(isNamedModuleUnit() && "We should only query the global module "
382
"fragment from the C++20 Named modules");
383
384
for (auto *SubModule : SubModules)
385
if (SubModule->isExplicitGlobalModule())
386
return SubModule;
387
388
return nullptr;
389
}
390
391
Module *Module::getPrivateModuleFragment() const {
392
assert(isNamedModuleUnit() && "We should only query the private module "
393
"fragment from the C++20 Named modules");
394
395
for (auto *SubModule : SubModules)
396
if (SubModule->isPrivateModule())
397
return SubModule;
398
399
return nullptr;
400
}
401
402
void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
403
// All non-explicit submodules are exported.
404
for (std::vector<Module *>::const_iterator I = SubModules.begin(),
405
E = SubModules.end();
406
I != E; ++I) {
407
Module *Mod = *I;
408
if (!Mod->IsExplicit)
409
Exported.push_back(Mod);
410
}
411
412
// Find re-exported modules by filtering the list of imported modules.
413
bool AnyWildcard = false;
414
bool UnrestrictedWildcard = false;
415
SmallVector<Module *, 4> WildcardRestrictions;
416
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
417
Module *Mod = Exports[I].getPointer();
418
if (!Exports[I].getInt()) {
419
// Export a named module directly; no wildcards involved.
420
Exported.push_back(Mod);
421
422
continue;
423
}
424
425
// Wildcard export: export all of the imported modules that match
426
// the given pattern.
427
AnyWildcard = true;
428
if (UnrestrictedWildcard)
429
continue;
430
431
if (Module *Restriction = Exports[I].getPointer())
432
WildcardRestrictions.push_back(Restriction);
433
else {
434
WildcardRestrictions.clear();
435
UnrestrictedWildcard = true;
436
}
437
}
438
439
// If there were any wildcards, push any imported modules that were
440
// re-exported by the wildcard restriction.
441
if (!AnyWildcard)
442
return;
443
444
for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
445
Module *Mod = Imports[I];
446
bool Acceptable = UnrestrictedWildcard;
447
if (!Acceptable) {
448
// Check whether this module meets one of the restrictions.
449
for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
450
Module *Restriction = WildcardRestrictions[R];
451
if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
452
Acceptable = true;
453
break;
454
}
455
}
456
}
457
458
if (!Acceptable)
459
continue;
460
461
Exported.push_back(Mod);
462
}
463
}
464
465
void Module::buildVisibleModulesCache() const {
466
assert(VisibleModulesCache.empty() && "cache does not need building");
467
468
// This module is visible to itself.
469
VisibleModulesCache.insert(this);
470
471
// Every imported module is visible.
472
SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
473
while (!Stack.empty()) {
474
Module *CurrModule = Stack.pop_back_val();
475
476
// Every module transitively exported by an imported module is visible.
477
if (VisibleModulesCache.insert(CurrModule).second)
478
CurrModule->getExportedModules(Stack);
479
}
480
}
481
482
void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
483
OS.indent(Indent);
484
if (IsFramework)
485
OS << "framework ";
486
if (IsExplicit)
487
OS << "explicit ";
488
OS << "module ";
489
printModuleId(OS, &Name, &Name + 1);
490
491
if (IsSystem || IsExternC) {
492
OS.indent(Indent + 2);
493
if (IsSystem)
494
OS << " [system]";
495
if (IsExternC)
496
OS << " [extern_c]";
497
}
498
499
OS << " {\n";
500
501
if (!Requirements.empty()) {
502
OS.indent(Indent + 2);
503
OS << "requires ";
504
for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
505
if (I)
506
OS << ", ";
507
if (!Requirements[I].RequiredState)
508
OS << "!";
509
OS << Requirements[I].FeatureName;
510
}
511
OS << "\n";
512
}
513
514
if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
515
OS.indent(Indent + 2);
516
OS << "umbrella header \"";
517
OS.write_escaped(H->NameAsWritten);
518
OS << "\"\n";
519
} else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
520
OS.indent(Indent + 2);
521
OS << "umbrella \"";
522
OS.write_escaped(D->NameAsWritten);
523
OS << "\"\n";
524
}
525
526
if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
527
OS.indent(Indent + 2);
528
OS << "config_macros ";
529
if (ConfigMacrosExhaustive)
530
OS << "[exhaustive]";
531
for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
532
if (I)
533
OS << ", ";
534
OS << ConfigMacros[I];
535
}
536
OS << "\n";
537
}
538
539
struct {
540
StringRef Prefix;
541
HeaderKind Kind;
542
} Kinds[] = {{"", HK_Normal},
543
{"textual ", HK_Textual},
544
{"private ", HK_Private},
545
{"private textual ", HK_PrivateTextual},
546
{"exclude ", HK_Excluded}};
547
548
for (auto &K : Kinds) {
549
assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
550
for (auto &H : Headers[K.Kind]) {
551
OS.indent(Indent + 2);
552
OS << K.Prefix << "header \"";
553
OS.write_escaped(H.NameAsWritten);
554
OS << "\" { size " << H.Entry.getSize()
555
<< " mtime " << H.Entry.getModificationTime() << " }\n";
556
}
557
}
558
for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
559
for (auto &U : *Unresolved) {
560
OS.indent(Indent + 2);
561
OS << Kinds[U.Kind].Prefix << "header \"";
562
OS.write_escaped(U.FileName);
563
OS << "\"";
564
if (U.Size || U.ModTime) {
565
OS << " {";
566
if (U.Size)
567
OS << " size " << *U.Size;
568
if (U.ModTime)
569
OS << " mtime " << *U.ModTime;
570
OS << " }";
571
}
572
OS << "\n";
573
}
574
}
575
576
if (!ExportAsModule.empty()) {
577
OS.indent(Indent + 2);
578
OS << "export_as" << ExportAsModule << "\n";
579
}
580
581
for (auto *Submodule : submodules())
582
// Print inferred subframework modules so that we don't need to re-infer
583
// them (requires expensive directory iteration + stat calls) when we build
584
// the module. Regular inferred submodules are OK, as we need to look at all
585
// those header files anyway.
586
if (!Submodule->IsInferred || Submodule->IsFramework)
587
Submodule->print(OS, Indent + 2, Dump);
588
589
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
590
OS.indent(Indent + 2);
591
OS << "export ";
592
if (Module *Restriction = Exports[I].getPointer()) {
593
OS << Restriction->getFullModuleName(true);
594
if (Exports[I].getInt())
595
OS << ".*";
596
} else {
597
OS << "*";
598
}
599
OS << "\n";
600
}
601
602
for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
603
OS.indent(Indent + 2);
604
OS << "export ";
605
printModuleId(OS, UnresolvedExports[I].Id);
606
if (UnresolvedExports[I].Wildcard)
607
OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
608
OS << "\n";
609
}
610
611
if (Dump) {
612
for (Module *M : Imports) {
613
OS.indent(Indent + 2);
614
llvm::errs() << "import " << M->getFullModuleName() << "\n";
615
}
616
}
617
618
for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
619
OS.indent(Indent + 2);
620
OS << "use ";
621
OS << DirectUses[I]->getFullModuleName(true);
622
OS << "\n";
623
}
624
625
for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
626
OS.indent(Indent + 2);
627
OS << "use ";
628
printModuleId(OS, UnresolvedDirectUses[I]);
629
OS << "\n";
630
}
631
632
for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
633
OS.indent(Indent + 2);
634
OS << "link ";
635
if (LinkLibraries[I].IsFramework)
636
OS << "framework ";
637
OS << "\"";
638
OS.write_escaped(LinkLibraries[I].Library);
639
OS << "\"";
640
}
641
642
for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
643
OS.indent(Indent + 2);
644
OS << "conflict ";
645
printModuleId(OS, UnresolvedConflicts[I].Id);
646
OS << ", \"";
647
OS.write_escaped(UnresolvedConflicts[I].Message);
648
OS << "\"\n";
649
}
650
651
for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
652
OS.indent(Indent + 2);
653
OS << "conflict ";
654
OS << Conflicts[I].Other->getFullModuleName(true);
655
OS << ", \"";
656
OS.write_escaped(Conflicts[I].Message);
657
OS << "\"\n";
658
}
659
660
if (InferSubmodules) {
661
OS.indent(Indent + 2);
662
if (InferExplicitSubmodules)
663
OS << "explicit ";
664
OS << "module * {\n";
665
if (InferExportWildcard) {
666
OS.indent(Indent + 4);
667
OS << "export *\n";
668
}
669
OS.indent(Indent + 2);
670
OS << "}\n";
671
}
672
673
OS.indent(Indent);
674
OS << "}\n";
675
}
676
677
LLVM_DUMP_METHOD void Module::dump() const {
678
print(llvm::errs(), 0, true);
679
}
680
681
void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
682
VisibleCallback Vis, ConflictCallback Cb) {
683
// We can't import a global module fragment so the location can be invalid.
684
assert((M->isGlobalModule() || Loc.isValid()) &&
685
"setVisible expects a valid import location");
686
if (isVisible(M))
687
return;
688
689
++Generation;
690
691
struct Visiting {
692
Module *M;
693
Visiting *ExportedBy;
694
};
695
696
std::function<void(Visiting)> VisitModule = [&](Visiting V) {
697
// Nothing to do for a module that's already visible.
698
unsigned ID = V.M->getVisibilityID();
699
if (ImportLocs.size() <= ID)
700
ImportLocs.resize(ID + 1);
701
else if (ImportLocs[ID].isValid())
702
return;
703
704
ImportLocs[ID] = Loc;
705
Vis(V.M);
706
707
// Make any exported modules visible.
708
SmallVector<Module *, 16> Exports;
709
V.M->getExportedModules(Exports);
710
for (Module *E : Exports) {
711
// Don't import non-importable modules.
712
if (!E->isUnimportable())
713
VisitModule({E, &V});
714
}
715
716
for (auto &C : V.M->Conflicts) {
717
if (isVisible(C.Other)) {
718
llvm::SmallVector<Module*, 8> Path;
719
for (Visiting *I = &V; I; I = I->ExportedBy)
720
Path.push_back(I->M);
721
Cb(Path, C.Other, C.Message);
722
}
723
}
724
};
725
VisitModule({M, nullptr});
726
}
727
728