@@ -892,47 +892,62 @@ SubclassScope SILDeclRef::getSubclassScope() const {
892
892
if (!hasDecl ())
893
893
return SubclassScope::NotApplicable;
894
894
895
+ auto *decl = getDecl ();
896
+
897
+ if (!isa<AbstractFunctionDecl>(decl))
898
+ return SubclassScope::NotApplicable;
899
+
895
900
// If this declaration is a function which goes into a vtable, then it's
896
901
// symbol must be as visible as its class, because derived classes have to put
897
902
// all less visible methods of the base class into their vtables.
898
903
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)
901
907
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.
905
913
return SubclassScope::NotApplicable;
914
+ } else {
915
+ assert (isa<FuncDecl>(decl));
916
+ }
906
917
907
- DeclContext *context = FD ->getDeclContext ();
918
+ DeclContext *context = decl ->getDeclContext ();
908
919
909
- // Methods from extensions don't go into vtables (yet) .
920
+ // Methods from extensions don't go in the vtable .
910
921
if (isa<ExtensionDecl>(context))
911
922
return SubclassScope::NotApplicable;
912
923
913
924
// Various forms of thunks don't either.
914
925
if (isThunk () || isForeign)
915
926
return SubclassScope::NotApplicable;
916
927
917
- // Default arg generators are not visible .
928
+ // Default arg generators don't go in the vtable .
918
929
if (isDefaultArgGenerator ())
919
930
return SubclassScope::NotApplicable;
920
931
932
+ // Only non-final methods in non-final classes go in the vtable.
921
933
auto *classType = context->getSelfClassDecl ();
922
934
if (!classType || classType->isFinal ())
923
935
return SubclassScope::NotApplicable;
924
936
925
- if (FD ->isFinal ())
937
+ if (decl ->isFinal ())
926
938
return SubclassScope::NotApplicable;
927
939
928
- assert (FD ->getEffectiveAccess () <= classType->getEffectiveAccess () &&
940
+ assert (decl ->getEffectiveAccess () <= classType->getEffectiveAccess () &&
929
941
" class must be as visible as its members" );
930
942
931
943
// FIXME: This is too narrow. Any class with resilient metadata should
932
944
// probably have this, at least for method overrides that don't add new
933
945
// vtable entries.
934
- if (classType->isResilient ())
946
+ if (classType->isResilient ()) {
947
+ if (isa<ConstructorDecl>(decl))
948
+ return SubclassScope::NotApplicable;
935
949
return SubclassScope::Resilient;
950
+ }
936
951
937
952
switch (classType->getEffectiveAccess ()) {
938
953
case AccessLevel::Private:
0 commit comments