@@ -250,19 +250,17 @@ class Callee {
250
250
// / Enum case constructor call.
251
251
EnumElement,
252
252
253
- VirtualMethod_First,
254
- // / A method call using class method dispatch.
255
- ClassMethod = VirtualMethod_First,
256
- // / A method call using super method dispatch.
257
- SuperMethod,
258
- VirtualMethod_Last = SuperMethod,
259
-
260
- GenericMethod_First,
261
- // / A method call using archetype dispatch.
262
- WitnessMethod = GenericMethod_First,
263
- // / A method call using dynamic lookup.
264
- DynamicMethod,
265
- GenericMethod_Last = DynamicMethod
253
+ // / A method call using class method dispatch.
254
+ ClassMethod,
255
+
256
+ // / A method call using super method dispatch.
257
+ SuperMethod,
258
+
259
+ // / A method call using protocol witness table dispatch.
260
+ WitnessMethod,
261
+
262
+ // / A method call using dynamic lookup.
263
+ DynamicMethod,
266
264
};
267
265
268
266
const Kind kind;
@@ -391,14 +389,11 @@ class Callee {
391
389
return Callee (Kind::SuperMethod, SGF, std::move (selfValue), c,
392
390
ci.FormalPattern , ci.FormalType , subs, l);
393
391
}
394
- static Callee forArchetype (SILGenFunction &SGF,
395
- CanType protocolSelfType,
396
- SILDeclRef c,
397
- SubstitutionList subs,
398
- SILLocation l) {
399
- auto *protocol = cast<ProtocolDecl>(c.getDecl ()->getDeclContext ());
400
- c = c.asForeign (protocol->isObjC ());
401
-
392
+ static Callee forWitnessMethod (SILGenFunction &SGF,
393
+ CanType protocolSelfType,
394
+ SILDeclRef c,
395
+ SubstitutionList subs,
396
+ SILLocation l) {
402
397
auto &ci = SGF.getConstantInfo (c);
403
398
return Callee (Kind::WitnessMethod, SGF, None, c, ci.FormalPattern ,
404
399
ci.FormalType , subs, l);
@@ -958,11 +953,13 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
958
953
}
959
954
}
960
955
961
- SILDeclRef constant = SILDeclRef (afd, kind);
956
+ SILDeclRef constant (afd, kind);
957
+ constant = constant.asForeign (afd->isObjC ());
962
958
963
959
// Prepare the callee. This can modify both selfValue and subs.
964
- Callee theCallee = Callee::forArchetype (SGF, selfValue.getSubstRValueType (),
965
- constant, subs, e);
960
+ Callee theCallee = Callee::forWitnessMethod (
961
+ SGF, selfValue.getSubstRValueType (),
962
+ constant, subs, e);
966
963
assumedPlusZeroSelf =
967
964
selfValue.isRValue () &&
968
965
selfValue.forceAndPeekRValue (SGF).peekIsPlusZeroRValueOrTrivial ();
@@ -1403,47 +1400,35 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
1403
1400
auto subs = ctorRef->getDeclRef ().getSubstitutions ();
1404
1401
ArgumentSource selfArgSource (arg, RValue (SGF, expr, selfFormalType, self));
1405
1402
1403
+ SILDeclRef constant (ctorRef->getDecl (),
1404
+ useAllocatingCtor
1405
+ ? SILDeclRef::Kind::Allocator
1406
+ : SILDeclRef::Kind::Initializer);
1407
+
1408
+ constant = constant.asForeign (requiresForeignEntryPoint (ctorRef->getDecl ()));
1409
+
1406
1410
// Determine the callee. For structs and enums, this is the allocating
1407
1411
// constructor (because there is no initializing constructor). For protocol
1408
1412
// default implementations, we also use the allocating constructor, because
1409
1413
// that's the only thing that's witnessed. For classes,
1410
1414
// this is the initializing constructor, to which we will dynamically
1411
1415
// dispatch.
1412
- if (selfArgSource.getSubstRValueType ()
1413
- ->getRValueInstanceType ()
1414
- ->is <ArchetypeType>() &&
1415
- isa<ProtocolDecl>(ctorRef->getDecl ()->getDeclContext ())) {
1416
+ if (isa<ProtocolDecl>(ctorRef->getDecl ()->getDeclContext ())) {
1416
1417
// Look up the witness for the constructor.
1417
- auto constant = SILDeclRef (ctorRef->getDecl (),
1418
- useAllocatingCtor
1419
- ? SILDeclRef::Kind::Allocator
1420
- : SILDeclRef::Kind::Initializer);
1421
- setCallee (Callee::forArchetype (SGF,
1422
- self.getType ().getSwiftRValueType (),
1423
- constant, subs, expr));
1418
+ setCallee (Callee::forWitnessMethod (
1419
+ SGF, self.getType ().getSwiftRValueType (),
1420
+ constant, subs, expr));
1424
1421
} else if (getMethodDispatch (ctorRef->getDecl ())
1425
1422
== MethodDispatch::Class) {
1426
1423
// Dynamic dispatch to the initializer.
1427
1424
Scope S (SGF, expr);
1428
1425
setCallee (Callee::forClassMethod (
1429
1426
SGF, selfArgSource.delayedBorrow (SGF),
1430
- SILDeclRef (ctorRef->getDecl (),
1431
- useAllocatingCtor ? SILDeclRef::Kind::Allocator
1432
- : SILDeclRef::Kind::Initializer)
1433
- .asForeign (requiresForeignEntryPoint (ctorRef->getDecl ())),
1434
- subs, fn));
1427
+ constant, subs, fn));
1435
1428
} else {
1436
1429
// Directly call the peer constructor.
1437
1430
setCallee (
1438
- Callee::forDirect (
1439
- SGF,
1440
- SILDeclRef (ctorRef->getDecl (),
1441
- useAllocatingCtor
1442
- ? SILDeclRef::Kind::Allocator
1443
- : SILDeclRef::Kind::Initializer)
1444
- .asForeign (requiresForeignEntryPoint (ctorRef->getDecl ())),
1445
- subs,
1446
- fn));
1431
+ Callee::forDirect (SGF, constant, subs, fn));
1447
1432
}
1448
1433
1449
1434
setSelfParam (std::move (selfArgSource), expr);
@@ -4797,9 +4782,9 @@ static RValue emitApplyAllocatingInitializer(SILGenFunction &SGF,
4797
4782
// Form the callee.
4798
4783
Optional<Callee> callee;
4799
4784
if (isa<ProtocolDecl>(ctor->getDeclContext ())) {
4800
- callee.emplace (Callee::forArchetype (SGF,
4801
- selfMetaVal.getType ().getSwiftRValueType (),
4802
- initRef, subs, loc));
4785
+ callee.emplace (Callee::forWitnessMethod (
4786
+ SGF, selfMetaVal.getType ().getSwiftRValueType (),
4787
+ initRef, subs, loc));
4803
4788
} else {
4804
4789
callee.emplace (Callee::forDirect (SGF, initRef, subs, loc));
4805
4790
}
@@ -5021,9 +5006,9 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &SGF,
5021
5006
assert (!isDirectUse && " direct use of protocol accessor?" );
5022
5007
assert (!isSuper && " super call to protocol method?" );
5023
5008
5024
- return Callee::forArchetype (SGF,
5025
- selfValue.getSubstRValueType (),
5026
- constant, subs, loc);
5009
+ return Callee::forWitnessMethod (
5010
+ SGF, selfValue.getSubstRValueType (),
5011
+ constant, subs, loc);
5027
5012
}
5028
5013
5029
5014
bool isClassDispatch = false ;
@@ -5278,6 +5263,10 @@ ArgumentSource SILGenFunction::prepareAccessorBaseArg(SILLocation loc,
5278
5263
5279
5264
static bool shouldReferenceForeignAccessor (AbstractStorageDecl *storage,
5280
5265
bool isDirectUse) {
5266
+ // Members of Objective-C protocols should be dynamically dispatched.
5267
+ if (auto *protoDecl = dyn_cast<ProtocolDecl>(storage->getDeclContext ()))
5268
+ return protoDecl->isObjC ();
5269
+
5281
5270
// C functions imported as members should be referenced as C functions.
5282
5271
if (storage->getGetter ()->isImportAsMember ())
5283
5272
return true ;
0 commit comments