@@ -944,47 +944,62 @@ SubclassScope SILDeclRef::getSubclassScope() const {
944
944
if (!hasDecl ())
945
945
return SubclassScope::NotApplicable;
946
946
947
+ auto *decl = getDecl ();
948
+
949
+ if (!isa<AbstractFunctionDecl>(decl))
950
+ return SubclassScope::NotApplicable;
951
+
947
952
// If this declaration is a function which goes into a vtable, then it's
948
953
// symbol must be as visible as its class, because derived classes have to put
949
954
// all less visible methods of the base class into their vtables.
950
955
951
- if (auto *CD = dyn_cast<ConstructorDecl>(getDecl ()))
952
- if (!CD->isRequired ())
956
+ if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
957
+ // Initializing entry points do not appear in the vtable.
958
+ if (kind == SILDeclRef::Kind::Initializer)
953
959
return SubclassScope::NotApplicable;
954
-
955
- auto *FD = dyn_cast<FuncDecl>(getDecl ());
956
- if (!FD)
960
+ // Non-required convenience inits do not apper in the vtable.
961
+ if (!CD->isRequired () && !CD->isDesignatedInit ())
962
+ return SubclassScope::NotApplicable;
963
+ } else if (isa<DestructorDecl>(decl)) {
964
+ // Detructors do not appear in the vtable.
957
965
return SubclassScope::NotApplicable;
966
+ } else {
967
+ assert (isa<FuncDecl>(decl));
968
+ }
958
969
959
- DeclContext *context = FD ->getDeclContext ();
970
+ DeclContext *context = decl ->getDeclContext ();
960
971
961
- // Methods from extensions don't go into vtables (yet) .
972
+ // Methods from extensions don't go in the vtable .
962
973
if (isa<ExtensionDecl>(context))
963
974
return SubclassScope::NotApplicable;
964
975
965
976
// Various forms of thunks don't either.
966
977
if (isThunk () || isForeign)
967
978
return SubclassScope::NotApplicable;
968
979
969
- // Default arg generators are not visible .
980
+ // Default arg generators don't go in the vtable .
970
981
if (isDefaultArgGenerator ())
971
982
return SubclassScope::NotApplicable;
972
983
984
+ // Only non-final methods in non-final classes go in the vtable.
973
985
auto *classType = context->getSelfClassDecl ();
974
986
if (!classType || classType->isFinal ())
975
987
return SubclassScope::NotApplicable;
976
988
977
- if (FD ->isFinal ())
989
+ if (decl ->isFinal ())
978
990
return SubclassScope::NotApplicable;
979
991
980
- assert (FD ->getEffectiveAccess () <= classType->getEffectiveAccess () &&
992
+ assert (decl ->getEffectiveAccess () <= classType->getEffectiveAccess () &&
981
993
" class must be as visible as its members" );
982
994
983
995
// FIXME: This is too narrow. Any class with resilient metadata should
984
996
// probably have this, at least for method overrides that don't add new
985
997
// vtable entries.
986
- if (classType->isResilient ())
998
+ if (classType->isResilient ()) {
999
+ if (isa<ConstructorDecl>(decl))
1000
+ return SubclassScope::NotApplicable;
987
1001
return SubclassScope::Resilient;
1002
+ }
988
1003
989
1004
switch (classType->getEffectiveAccess ()) {
990
1005
case AccessLevel::Private:
0 commit comments