@@ -892,47 +892,62 @@ SubclassScope SILDeclRef::getSubclassScope() const {
892892 if (!hasDecl ())
893893 return SubclassScope::NotApplicable;
894894
895+ auto *decl = getDecl ();
896+
897+ if (!isa<AbstractFunctionDecl>(decl))
898+ return SubclassScope::NotApplicable;
899+
895900 // If this declaration is a function which goes into a vtable, then it's
896901 // symbol must be as visible as its class, because derived classes have to put
897902 // all less visible methods of the base class into their vtables.
898903
899- if (auto *CD = dyn_cast<ConstructorDecl>(getDecl ()))
900- if (!CD->isRequired ())
904+ if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
905+ // Initializing entry points do not appear in the vtable.
906+ if (kind == SILDeclRef::Kind::Initializer)
901907 return SubclassScope::NotApplicable;
902-
903- auto *FD = dyn_cast<FuncDecl>(getDecl ());
904- if (!FD)
908+ // Non-required convenience inits do not apper in the vtable.
909+ if (!CD->isRequired () && !CD->isDesignatedInit ())
910+ return SubclassScope::NotApplicable;
911+ } else if (isa<DestructorDecl>(decl)) {
912+ // Detructors do not appear in the vtable.
905913 return SubclassScope::NotApplicable;
914+ } else {
915+ assert (isa<FuncDecl>(decl));
916+ }
906917
907- DeclContext *context = FD ->getDeclContext ();
918+ DeclContext *context = decl ->getDeclContext ();
908919
909- // Methods from extensions don't go into vtables (yet) .
920+ // Methods from extensions don't go in the vtable .
910921 if (isa<ExtensionDecl>(context))
911922 return SubclassScope::NotApplicable;
912923
913924 // Various forms of thunks don't either.
914925 if (isThunk () || isForeign)
915926 return SubclassScope::NotApplicable;
916927
917- // Default arg generators are not visible .
928+ // Default arg generators don't go in the vtable .
918929 if (isDefaultArgGenerator ())
919930 return SubclassScope::NotApplicable;
920931
932+ // Only non-final methods in non-final classes go in the vtable.
921933 auto *classType = context->getSelfClassDecl ();
922934 if (!classType || classType->isFinal ())
923935 return SubclassScope::NotApplicable;
924936
925- if (FD ->isFinal ())
937+ if (decl ->isFinal ())
926938 return SubclassScope::NotApplicable;
927939
928- assert (FD ->getEffectiveAccess () <= classType->getEffectiveAccess () &&
940+ assert (decl ->getEffectiveAccess () <= classType->getEffectiveAccess () &&
929941 " class must be as visible as its members" );
930942
931943 // FIXME: This is too narrow. Any class with resilient metadata should
932944 // probably have this, at least for method overrides that don't add new
933945 // vtable entries.
934- if (classType->isResilient ())
946+ if (classType->isResilient ()) {
947+ if (isa<ConstructorDecl>(decl))
948+ return SubclassScope::NotApplicable;
935949 return SubclassScope::Resilient;
950+ }
936951
937952 switch (classType->getEffectiveAccess ()) {
938953 case AccessLevel::Private:
0 commit comments