Skip to content

Commit 514aa99

Browse files
committed
SILGen: Clean up SILGenApply a bit
1 parent e806b62 commit 514aa99

File tree

1 file changed

+44
-55
lines changed

1 file changed

+44
-55
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -250,19 +250,17 @@ class Callee {
250250
/// Enum case constructor call.
251251
EnumElement,
252252

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,
266264
};
267265

268266
const Kind kind;
@@ -391,14 +389,11 @@ class Callee {
391389
return Callee(Kind::SuperMethod, SGF, std::move(selfValue), c,
392390
ci.FormalPattern, ci.FormalType, subs, l);
393391
}
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) {
402397
auto &ci = SGF.getConstantInfo(c);
403398
return Callee(Kind::WitnessMethod, SGF, None, c, ci.FormalPattern,
404399
ci.FormalType, subs, l);
@@ -958,11 +953,13 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
958953
}
959954
}
960955

961-
SILDeclRef constant = SILDeclRef(afd, kind);
956+
SILDeclRef constant(afd, kind);
957+
constant = constant.asForeign(afd->isObjC());
962958

963959
// 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);
966963
assumedPlusZeroSelf =
967964
selfValue.isRValue() &&
968965
selfValue.forceAndPeekRValue(SGF).peekIsPlusZeroRValueOrTrivial();
@@ -1403,47 +1400,35 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
14031400
auto subs = ctorRef->getDeclRef().getSubstitutions();
14041401
ArgumentSource selfArgSource(arg, RValue(SGF, expr, selfFormalType, self));
14051402

1403+
SILDeclRef constant(ctorRef->getDecl(),
1404+
useAllocatingCtor
1405+
? SILDeclRef::Kind::Allocator
1406+
: SILDeclRef::Kind::Initializer);
1407+
1408+
constant = constant.asForeign(requiresForeignEntryPoint(ctorRef->getDecl()));
1409+
14061410
// Determine the callee. For structs and enums, this is the allocating
14071411
// constructor (because there is no initializing constructor). For protocol
14081412
// default implementations, we also use the allocating constructor, because
14091413
// that's the only thing that's witnessed. For classes,
14101414
// this is the initializing constructor, to which we will dynamically
14111415
// dispatch.
1412-
if (selfArgSource.getSubstRValueType()
1413-
->getRValueInstanceType()
1414-
->is<ArchetypeType>() &&
1415-
isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
1416+
if (isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
14161417
// 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));
14241421
} else if (getMethodDispatch(ctorRef->getDecl())
14251422
== MethodDispatch::Class) {
14261423
// Dynamic dispatch to the initializer.
14271424
Scope S(SGF, expr);
14281425
setCallee(Callee::forClassMethod(
14291426
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));
14351428
} else {
14361429
// Directly call the peer constructor.
14371430
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));
14471432
}
14481433

14491434
setSelfParam(std::move(selfArgSource), expr);
@@ -4797,9 +4782,9 @@ static RValue emitApplyAllocatingInitializer(SILGenFunction &SGF,
47974782
// Form the callee.
47984783
Optional<Callee> callee;
47994784
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));
48034788
} else {
48044789
callee.emplace(Callee::forDirect(SGF, initRef, subs, loc));
48054790
}
@@ -5021,9 +5006,9 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &SGF,
50215006
assert(!isDirectUse && "direct use of protocol accessor?");
50225007
assert(!isSuper && "super call to protocol method?");
50235008

5024-
return Callee::forArchetype(SGF,
5025-
selfValue.getSubstRValueType(),
5026-
constant, subs, loc);
5009+
return Callee::forWitnessMethod(
5010+
SGF, selfValue.getSubstRValueType(),
5011+
constant, subs, loc);
50275012
}
50285013

50295014
bool isClassDispatch = false;
@@ -5278,6 +5263,10 @@ ArgumentSource SILGenFunction::prepareAccessorBaseArg(SILLocation loc,
52785263

52795264
static bool shouldReferenceForeignAccessor(AbstractStorageDecl *storage,
52805265
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+
52815270
// C functions imported as members should be referenced as C functions.
52825271
if (storage->getGetter()->isImportAsMember())
52835272
return true;

0 commit comments

Comments
 (0)