@@ -62,22 +62,7 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
62
62
addSymbol (linkage.getName ());
63
63
}
64
64
65
- void addConformances (DeclContext *DC) {
66
- for (auto conformance : DC->getLocalConformances ()) {
67
- auto needsWTable = Lowering::TypeConverter::protocolRequiresWitnessTable (
68
- conformance->getProtocol ());
69
- if (!needsWTable)
70
- continue ;
71
-
72
- // Only normal conformances get symbols; the others get any public symbols
73
- // from their parent normal conformance.
74
- if (conformance->getKind () != ProtocolConformanceKind::Normal)
75
- continue ;
76
-
77
- addSymbol (LinkEntity::forDirectProtocolWitnessTable (conformance));
78
- addSymbol (LinkEntity::forProtocolWitnessTableAccessFunction (conformance));
79
- }
80
- }
65
+ void addConformances (DeclContext *DC);
81
66
82
67
public:
83
68
TBDGenVisitor (StringSet &symbols,
@@ -184,6 +169,81 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef, bool checkSILOnly) {
184
169
addSymbol (declRef.mangle ());
185
170
}
186
171
172
+ void TBDGenVisitor::addConformances (DeclContext *DC) {
173
+ for (auto conformance : DC->getLocalConformances ()) {
174
+ auto protocol = conformance->getProtocol ();
175
+ auto needsWTable =
176
+ Lowering::TypeConverter::protocolRequiresWitnessTable (protocol);
177
+ if (!needsWTable)
178
+ continue ;
179
+
180
+ // Only normal conformances get symbols; the others get any public symbols
181
+ // from their parent normal conformance.
182
+ auto normalConformance = dyn_cast<NormalProtocolConformance>(conformance);
183
+ if (!normalConformance)
184
+ continue ;
185
+
186
+ addSymbol (LinkEntity::forDirectProtocolWitnessTable (normalConformance));
187
+ addSymbol (
188
+ LinkEntity::forProtocolWitnessTableAccessFunction (normalConformance));
189
+
190
+ // FIXME: the logic around visibility in extensions is confusing, and
191
+ // sometimes witness thunks need to be manually made public.
192
+
193
+ auto conformanceIsSerialized = normalConformance->isSerialized ();
194
+ auto addSymbolIfNecessary = [&](ValueDecl *valueReq,
195
+ SILLinkage witnessLinkage) {
196
+ if (conformanceIsSerialized &&
197
+ fixmeWitnessHasLinkageThatNeedsToBePublic (witnessLinkage)) {
198
+ Mangle::ASTMangler Mangler;
199
+ addSymbol (Mangler.mangleWitnessThunk (normalConformance, valueReq));
200
+ }
201
+ };
202
+ normalConformance->forEachValueWitness (nullptr , [&](ValueDecl *valueReq,
203
+ Witness witness) {
204
+ if (isa<AbstractFunctionDecl>(valueReq)) {
205
+ auto witnessLinkage =
206
+ SILDeclRef (witness.getDecl ()).getLinkage (ForDefinition);
207
+ addSymbolIfNecessary (valueReq, witnessLinkage);
208
+ } else if (auto VD = dyn_cast<AbstractStorageDecl>(valueReq)) {
209
+ // A var or subscript decl needs special handling in the special
210
+ // handling: the things that end up in the witness table are the
211
+ // accessors, but the compiler only talks about the actual storage decl
212
+ // in the conformance, so we have to manually walk over the members,
213
+ // having pulled out something that will have the right linkage.
214
+ auto witnessVD = cast<AbstractStorageDecl>(witness.getDecl ());
215
+
216
+ SmallVector<Decl *, 4 > members;
217
+ VD->getAllAccessorFunctions (members);
218
+
219
+ // Grab one of the accessors, and then use that to pull out which of the
220
+ // getter or setter will have the appropriate linkage.
221
+ FuncDecl *witnessWithRelevantLinkage;
222
+ switch (cast<FuncDecl>(members[0 ])->getAccessorKind ()) {
223
+ case AccessorKind::NotAccessor:
224
+ llvm_unreachable (" must be an accessor" );
225
+ case AccessorKind::IsGetter:
226
+ case AccessorKind::IsAddressor:
227
+ witnessWithRelevantLinkage = witnessVD->getGetter ();
228
+ break ;
229
+ case AccessorKind::IsSetter:
230
+ case AccessorKind::IsWillSet:
231
+ case AccessorKind::IsDidSet:
232
+ case AccessorKind::IsMaterializeForSet:
233
+ case AccessorKind::IsMutableAddressor:
234
+ witnessWithRelevantLinkage = witnessVD->getSetter ();
235
+ break ;
236
+ }
237
+ auto witnessLinkage =
238
+ SILDeclRef (witnessWithRelevantLinkage).getLinkage (ForDefinition);
239
+ for (auto member : members) {
240
+ addSymbolIfNecessary (cast<ValueDecl>(member), witnessLinkage);
241
+ }
242
+ }
243
+ });
244
+ }
245
+ }
246
+
187
247
void TBDGenVisitor::visitValueDecl (ValueDecl *VD) {
188
248
addSymbol (SILDeclRef (VD));
189
249
visitMembers (VD);
0 commit comments