13
13
#include " SILGen.h"
14
14
#include " swift/AST/Decl.h"
15
15
#include " swift/AST/ProtocolConformance.h"
16
+ #include " swift/ClangImporter/ClangModule.h"
16
17
#include " swift/SIL/SILInstruction.h"
17
18
#include " swift/SIL/SILVisitor.h"
18
19
@@ -25,11 +26,28 @@ void SILGenModule::useConformance(ProtocolConformanceRef conformanceRef) {
25
26
return ;
26
27
27
28
auto conformance = conformanceRef.getConcrete ();
29
+
30
+ // Always look through inherited conformances.
31
+ if (auto *inherited = dyn_cast<InheritedProtocolConformance>(conformance))
32
+ conformance = inherited->getInheritedConformance ();
33
+
34
+ // Get the normal conformance. If we don't have one, this is a self
35
+ // conformance, which we can ignore.
28
36
auto normal = dyn_cast<NormalProtocolConformance>(
29
37
conformance->getRootConformance ());
30
38
if (normal == nullptr )
31
39
return ;
32
40
41
+ // Emit any conformances implied by conditional requirements.
42
+ if (auto *specialized = dyn_cast<SpecializedProtocolConformance>(conformance))
43
+ useConformancesFromSubstitutions (specialized->getSubstitutionMap ());
44
+
45
+ // If this conformance was not synthesized by the ClangImporter, we're not
46
+ // going to be emitting it lazily either, so we can avoid doing anything
47
+ // below.
48
+ if (!isa<ClangModuleUnit>(normal->getDeclContext ()->getModuleScopeContext ()))
49
+ return ;
50
+
33
51
// If we already emitted this witness table, we don't need to track the fact
34
52
// we need it.
35
53
if (emittedWitnessTables.count (normal))
@@ -54,21 +72,60 @@ void SILGenModule::useConformancesFromSubstitutions(
54
72
}
55
73
56
74
void SILGenModule::useConformancesFromType (CanType type) {
57
- type.findIf ([&](Type t) -> bool {
75
+ if (!usedConformancesFromTypes.insert (type.getPointer ()).second )
76
+ return ;
77
+
78
+ type.visit ([&](Type t) {
58
79
auto *decl = t->getAnyNominal ();
59
80
if (!decl)
60
- return false ;
81
+ return ;
61
82
62
83
if (isa<ProtocolDecl>(decl))
63
- return false ;
84
+ return ;
64
85
65
86
auto *genericSig = decl->getGenericSignature ();
66
87
if (!genericSig)
67
- return false ;
88
+ return ;
68
89
69
90
auto subMap = t->getContextSubstitutionMap (SwiftModule, decl);
70
91
useConformancesFromSubstitutions (subMap);
71
- return false ;
92
+ return ;
93
+ });
94
+ }
95
+
96
+ void SILGenModule::useConformancesFromObjectiveCType (CanType type) {
97
+ if (!usedConformancesFromObjectiveCTypes.insert (type.getPointer ()).second )
98
+ return ;
99
+
100
+ auto &ctx = getASTContext ();
101
+ auto objectiveCBridgeable = ctx.getProtocol (
102
+ KnownProtocolKind::ObjectiveCBridgeable);
103
+ auto bridgedStoredNSError = ctx.getProtocol (
104
+ KnownProtocolKind::BridgedStoredNSError);
105
+ if (!objectiveCBridgeable && !bridgedStoredNSError)
106
+ return ;
107
+
108
+ type.visit ([&](Type t) {
109
+ auto *decl = t->getAnyNominal ();
110
+ if (!decl)
111
+ return ;
112
+
113
+ if (!isa<ClangModuleUnit>(decl->getModuleScopeContext ()))
114
+ return ;
115
+
116
+ if (objectiveCBridgeable) {
117
+ auto subConformance = SwiftModule->lookupConformance (
118
+ t, objectiveCBridgeable);
119
+ if (subConformance)
120
+ useConformance (*subConformance);
121
+ }
122
+
123
+ if (bridgedStoredNSError) {
124
+ auto subConformance = SwiftModule->lookupConformance (
125
+ t, bridgedStoredNSError);
126
+ if (subConformance)
127
+ useConformance (*subConformance);
128
+ }
72
129
});
73
130
}
74
131
@@ -87,6 +144,7 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
87
144
88
145
void visitAllocExistentialBoxInst (AllocExistentialBoxInst *AEBI) {
89
146
SGM.useConformancesFromType (AEBI->getFormalConcreteType ());
147
+ SGM.useConformancesFromObjectiveCType (AEBI->getFormalConcreteType ());
90
148
for (auto conformance : AEBI->getConformances ())
91
149
SGM.useConformance (conformance);
92
150
}
@@ -109,10 +167,12 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
109
167
}
110
168
111
169
void visitApplyInst (ApplyInst *AI) {
170
+ SGM.useConformancesFromObjectiveCType (AI->getSubstCalleeType ());
112
171
SGM.useConformancesFromSubstitutions (AI->getSubstitutionMap ());
113
172
}
114
173
115
174
void visitBeginApplyInst (BeginApplyInst *BAI) {
175
+ SGM.useConformancesFromObjectiveCType (BAI->getSubstCalleeType ());
116
176
SGM.useConformancesFromSubstitutions (BAI->getSubstitutionMap ());
117
177
}
118
178
@@ -123,16 +183,22 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
123
183
void visitCheckedCastBranchInst (CheckedCastBranchInst *CCBI) {
124
184
SGM.useConformancesFromType (CCBI->getSourceType ());
125
185
SGM.useConformancesFromType (CCBI->getTargetType ());
186
+ SGM.useConformancesFromObjectiveCType (CCBI->getSourceType ());
187
+ SGM.useConformancesFromObjectiveCType (CCBI->getTargetType ());
126
188
}
127
189
128
190
void visitCheckedCastAddrBranchInst (CheckedCastAddrBranchInst *CCABI) {
129
191
SGM.useConformancesFromType (CCABI->getSourceType ());
130
192
SGM.useConformancesFromType (CCABI->getTargetType ());
193
+ SGM.useConformancesFromObjectiveCType (CCABI->getSourceType ());
194
+ SGM.useConformancesFromObjectiveCType (CCABI->getTargetType ());
131
195
}
132
196
133
197
void visitCheckedCastValueBranchInst (CheckedCastValueBranchInst *CCVBI) {
134
198
SGM.useConformancesFromType (CCVBI->getSourceType ());
135
199
SGM.useConformancesFromType (CCVBI->getTargetType ());
200
+ SGM.useConformancesFromObjectiveCType (CCVBI->getSourceType ());
201
+ SGM.useConformancesFromObjectiveCType (CCVBI->getTargetType ());
136
202
}
137
203
138
204
void visitCopyAddrInst (CopyAddrInst *CAI) {
@@ -177,6 +243,7 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
177
243
178
244
void visitInitExistentialAddrInst (InitExistentialAddrInst *IEAI) {
179
245
SGM.useConformancesFromType (IEAI->getFormalConcreteType ());
246
+ SGM.useConformancesFromObjectiveCType (IEAI->getFormalConcreteType ());
180
247
for (auto conformance : IEAI->getConformances ())
181
248
SGM.useConformance (conformance);
182
249
}
@@ -189,12 +256,14 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
189
256
190
257
void visitInitExistentialRefInst (InitExistentialRefInst *IERI) {
191
258
SGM.useConformancesFromType (IERI->getFormalConcreteType ());
259
+ SGM.useConformancesFromObjectiveCType (IERI->getFormalConcreteType ());
192
260
for (auto conformance : IERI->getConformances ())
193
261
SGM.useConformance (conformance);
194
262
}
195
263
196
264
void visitInitExistentialValueInst (InitExistentialValueInst *IEVI) {
197
265
SGM.useConformancesFromType (IEVI->getFormalConcreteType ());
266
+ SGM.useConformancesFromObjectiveCType (IEVI->getFormalConcreteType ());
198
267
for (auto conformance : IEVI->getConformances ())
199
268
SGM.useConformance (conformance);
200
269
}
@@ -204,6 +273,7 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
204
273
}
205
274
206
275
void visitPartialApplyInst (PartialApplyInst *PAI) {
276
+ SGM.useConformancesFromObjectiveCType (PAI->getSubstCalleeType ());
207
277
SGM.useConformancesFromSubstitutions (PAI->getSubstitutionMap ());
208
278
}
209
279
@@ -217,6 +287,7 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
217
287
}
218
288
219
289
void visitTryApplyInst (TryApplyInst *TAI) {
290
+ SGM.useConformancesFromObjectiveCType (TAI->getSubstCalleeType ());
220
291
SGM.useConformancesFromSubstitutions (TAI->getSubstitutionMap ());
221
292
}
222
293
@@ -227,14 +298,20 @@ class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitt
227
298
void visitUnconditionalCheckedCastInst (UnconditionalCheckedCastInst *UCCI) {
228
299
SGM.useConformancesFromType (UCCI->getSourceType ());
229
300
SGM.useConformancesFromType (UCCI->getTargetType ());
301
+ SGM.useConformancesFromObjectiveCType (UCCI->getSourceType ());
302
+ SGM.useConformancesFromObjectiveCType (UCCI->getTargetType ());
230
303
}
231
304
232
305
void visitUnconditionalCheckedCastAddrInst (UnconditionalCheckedCastAddrInst *UCCAI) {
233
306
SGM.useConformancesFromType (UCCAI->getSourceType ());
234
307
SGM.useConformancesFromType (UCCAI->getTargetType ());
308
+ SGM.useConformancesFromObjectiveCType (UCCAI->getSourceType ());
309
+ SGM.useConformancesFromObjectiveCType (UCCAI->getTargetType ());
235
310
}
236
311
237
- void visitUncheckedTakeEnumDataAddrInst (UncheckedTakeEnumDataAddrInst *UTEDAI) {}
312
+ void visitUncheckedTakeEnumDataAddrInst (UncheckedTakeEnumDataAddrInst *UTEDAI) {
313
+ SGM.useConformancesFromType (UTEDAI->getOperand ()->getType ().getASTType ());
314
+ }
238
315
239
316
void visitWitnessMethodInst (WitnessMethodInst *WMI) {
240
317
SGM.useConformance (WMI->getConformance ());
0 commit comments