Skip to content

Commit e6d1d97

Browse files
committed
SILGen: Use the base SILDeclRef for super_method override constant info
getOverriddenVTableEntry only goes one level up in the class hierarchy, but getConstantOverrideInfo requires that the next level up not itself be an override. A little bit of refactoring: SILDeclRef::getOverriddenVTableEntry() -> SILDeclRef::getNextOverriddenVTableEntry() static findOverriddenFunction() -> SILDeclRef::getBaseOverriddenVTableEntry() rdar://problem/22749732
1 parent 3fbd00d commit e6d1d97

File tree

10 files changed

+36
-27
lines changed

10 files changed

+36
-27
lines changed

include/swift/SIL/SILDeclRef.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,11 @@ struct SILDeclRef {
341341
/// Return a SILDeclRef to the declaration whose vtable entry this declaration
342342
/// overrides. This may be different from "getOverridden" because some
343343
/// declarations do not always have vtable entries.
344-
SILDeclRef getOverriddenVTableEntry() const;
344+
SILDeclRef getNextOverriddenVTableEntry() const;
345+
346+
/// Return a SILDeclRef referring to the ultimate base class's declaration,
347+
/// which must be used with getConstantOverrideInfo.
348+
SILDeclRef getBaseOverriddenVTableEntry() const;
345349

346350
/// True if the referenced entity is some kind of thunk.
347351
bool isThunk() const;

include/swift/SIL/TypeLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ class TypeConverter {
695695
/// not override.
696696
CanSILFunctionType getConstantOverrideType(SILDeclRef constant) {
697697
// Fast path if the constant isn't overridden.
698-
if (constant.getOverriddenVTableEntry().isNull())
698+
if (constant.getNextOverriddenVTableEntry().isNull())
699699
return getConstantFunctionType(constant);
700700
SILDeclRef base = constant;
701701
while (SILDeclRef overridden = base.getOverridden())

lib/IRGen/ClassMetadataLayout.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ template <class Impl> class ClassMetadataLayout : public MetadataLayout<Impl> {
212212
unsigned uncurryLevel) {
213213
SILDeclRef declRef(fn, kind, explosionLevel, uncurryLevel);
214214
// If the method overrides something, we don't need a new entry.
215-
if (declRef.getOverriddenVTableEntry())
215+
if (declRef.getNextOverriddenVTableEntry())
216216
return;
217217

218218
// Both static and non-static functions go in the metadata.

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4279,21 +4279,6 @@ AbstractCallee irgen::getAbstractVirtualCallee(IRGenFunction &IGF,
42794279
naturalUncurry, naturalUncurry, ExtraData::None);
42804280
}
42814281

4282-
/// Find the function which will actually appear in the virtual table.
4283-
static SILDeclRef findOverriddenFunction(IRGenModule &IGM,
4284-
SILDeclRef method) {
4285-
// 'method' is the most final method in the hierarchy which we
4286-
// haven't yet found a compatible override for. 'cur' is the method
4287-
// we're currently looking at. Compatibility is transitive,
4288-
// so we can forget our original method and just keep going up.
4289-
4290-
SILDeclRef cur = method;
4291-
while ((cur = cur.getOverriddenVTableEntry())) {
4292-
method = cur;
4293-
}
4294-
return method;
4295-
}
4296-
42974282
/// Load the correct virtual function for the given class method.
42984283
llvm::Value *irgen::emitVirtualMethodValue(IRGenFunction &IGF,
42994284
llvm::Value *base,
@@ -4305,8 +4290,7 @@ llvm::Value *irgen::emitVirtualMethodValue(IRGenFunction &IGF,
43054290
= cast<AbstractFunctionDecl>(method.getDecl());
43064291

43074292
// Find the function that's actually got an entry in the metadata.
4308-
SILDeclRef overridden =
4309-
findOverriddenFunction(IGF.IGM, method);
4293+
SILDeclRef overridden = method.getBaseOverriddenVTableEntry();
43104294

43114295
// Find the metadata.
43124296
llvm::Value *metadata;

lib/SIL/SILDeclRef.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ StringRef SILDeclRef::mangle(SmallVectorImpl<char> &buffer,
512512
return stream.str();
513513
}
514514

515-
SILDeclRef SILDeclRef::getOverriddenVTableEntry() const {
515+
SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const {
516516
if (auto overridden = getOverridden()) {
517517
// If we overrode a foreign decl, a dynamic method, this is an
518518
// accessor for a property that overrides an ObjC decl, or if it is an
@@ -544,6 +544,19 @@ SILDeclRef SILDeclRef::getOverriddenVTableEntry() const {
544544
return SILDeclRef();
545545
}
546546

547+
SILDeclRef SILDeclRef::getBaseOverriddenVTableEntry() const {
548+
// 'method' is the most final method in the hierarchy which we
549+
// haven't yet found a compatible override for. 'cur' is the method
550+
// we're currently looking at. Compatibility is transitive,
551+
// so we can forget our original method and just keep going up.
552+
SILDeclRef method = *this;
553+
SILDeclRef cur = method;
554+
while ((cur = cur.getNextOverriddenVTableEntry())) {
555+
method = cur;
556+
}
557+
return method;
558+
}
559+
547560
SILLocation SILDeclRef::getAsRegularLocation() const {
548561
if (hasDecl())
549562
return RegularLocation(getDecl());

lib/SIL/SILFunctionType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1736,7 +1736,7 @@ SILConstantInfo TypeConverter::getConstantOverrideInfo(SILDeclRef derived,
17361736
if (found != ConstantOverrideTypes.end())
17371737
return found->second;
17381738

1739-
assert(base.getOverriddenVTableEntry().isNull()
1739+
assert(base.getNextOverriddenVTableEntry().isNull()
17401740
&& "base must not be an override");
17411741

17421742
auto baseInfo = getConstantInfo(base);

lib/SILAnalysis/BasicCalleeAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void CalleeCache::computeClassMethodCalleesForClass(ClassDecl *CD) {
9494
if (canCallUnknown)
9595
TheCallees.setInt(true);
9696

97-
Method = Method.getOverriddenVTableEntry();
97+
Method = Method.getNextOverriddenVTableEntry();
9898
} while (Method);
9999
}
100100
}

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ class Callee {
593593
constant = Constant.atUncurryLevel(level);
594594
constantInfo = gen.getConstantInfo(*constant);
595595

596-
if (SILDeclRef baseConstant = Constant.getOverriddenVTableEntry())
596+
if (SILDeclRef baseConstant = Constant.getBaseOverriddenVTableEntry())
597597
constantInfo = gen.SGM.Types.getConstantOverrideInfo(Constant,
598598
baseConstant);
599599
auto methodVal = gen.B.createSuperMethod(Loc,

lib/SILGen/SILGenType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ class SILGenVTable : public Lowering::ASTVisitor<SILGenVTable> {
232232
// Try to find an overridden entry.
233233
// NB: Mutates vtableEntries in-place
234234
// FIXME: O(n^2)
235-
if (auto overridden = member.getOverriddenVTableEntry()) {
235+
if (auto overridden = member.getNextOverriddenVTableEntry()) {
236236
for (SILVTable::Pair &entry : vtableEntries) {
237237
SILDeclRef ref = overridden;
238238

test/SILGen/super_method.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,25 @@ class Parent {
99
class Child : Parent {}
1010

1111
class Grandchild : Child {
12-
// CHECK: sil hidden @_TFC12super_method10Grandchild16onlyInGrandchildfT_T_
12+
// CHECK-LABEL: sil hidden @_TFC12super_method10Grandchild16onlyInGrandchildfT_T_
1313
func onlyInGrandchild() {
1414
// CHECK: super_method %0 : $Grandchild, #Parent.onlyInParent!1 : Parent -> () -> ()
1515
super.onlyInParent()
1616
// CHECK: function_ref super_method.Parent.finalOnlyInParent
1717
super.finalOnlyInParent()
1818
}
1919

20-
// CHECK: sil hidden @_TFC12super_method10Grandchild3foofT_T_
20+
// CHECK-LABEL: sil hidden @_TFC12super_method10Grandchild3foofT_T_
2121
override func foo() {
2222
// CHECK: super_method %0 : $Grandchild, #Parent.foo!1 : Parent -> () -> ()
2323
super.foo()
2424
}
2525
}
26+
27+
class GreatGrandchild : Grandchild {
28+
// CHECK-LABEL: sil hidden @_TFC12super_method15GreatGrandchild3foofT_T_ : $@convention(method) (@guaranteed GreatGrandchild) -> ()
29+
override func foo() {
30+
// CHECK: super_method {{%[0-9]+}} : $GreatGrandchild, #Grandchild.foo!1 : Grandchild -> () -> () , $@convention(method) (@guaranteed Grandchild) -> ()
31+
super.foo()
32+
}
33+
}

0 commit comments

Comments
 (0)