@@ -3011,59 +3011,74 @@ class ObjCImplementationChecker {
30113011 diagnose (afd, diag::objc_implementation_member_requires_vtable, afd);
30123012 }
30133013
3014- void addRequirements (IterableDeclContext *idc) {
3015- assert (idc->getDecl ()->hasClangNode ());
3016- for (Decl *_member : idc->getMembers ()) {
3017- // Skip accessors; we'll match their storage instead.
3018- auto member = dyn_cast<ValueDecl>(_member);
3019- if (!member || isa<AccessorDecl>(member))
3020- continue ;
3014+ void addRequirement (Decl *D) {
3015+ auto VD = dyn_cast<ValueDecl>(D);
3016+ if (!VD)
3017+ return ;
30213018
3022- ASTContext &ctx = member ->getASTContext ();
3019+ ASTContext &ctx = VD ->getASTContext ();
30233020
3024- // Also skip overrides, unless they override an unavailable decl, which
3025- // makes them not formally overrides anymore.
3026- if (member ->getOverriddenDecl () &&
3027- !member ->getOverriddenDecl ()->getAttrs ().isUnavailable (ctx))
3028- continue ;
3021+ // Also skip overrides, unless they override an unavailable decl, which
3022+ // makes them not formally overrides anymore.
3023+ if (VD ->getOverriddenDecl () &&
3024+ !VD ->getOverriddenDecl ()->getAttrs ().isUnavailable (ctx))
3025+ return ;
30293026
3030- // Skip alternate Swift names for other language modes.
3031- if (member->getAttrs ().isUnavailable (ctx))
3032- continue ;
3027+ // Skip alternate Swift names for other language modes.
3028+ if (VD->getAttrs ().isUnavailable (ctx))
3029+ return ;
3030+
3031+ // Skip async versions of members. We'll match against the completion
3032+ // handler versions, hopping over to `getAsyncAlternative()` if needed.
3033+ if (hasAsync (VD))
3034+ return ;
3035+
3036+ auto inserted = unmatchedRequirements.insert (VD);
3037+ assert (inserted && " objc interface member added twice?" );
3038+ }
3039+
3040+ void addCandidate (Decl *D) {
3041+ auto VD = dyn_cast<ValueDecl>(D);
3042+ if (!VD || isa<DestructorDecl>(VD))
3043+ return ;
30333044
3034- // Skip async versions of members. We'll match against the completion
3035- // handler versions, hopping over to `getAsyncAlternative()` if needed.
3036- if (hasAsync (member))
3045+ // `getExplicitObjCName()` is O(N) and would otherwise be used repeatedly
3046+ // in `matchRequirementsAtThreshold()`, so just precompute it.
3047+ auto inserted =
3048+ unmatchedCandidates.insert ({ VD, getExplicitObjCName (VD) });
3049+ assert (inserted.second && " member implementation added twice?" );
3050+ }
3051+
3052+ void addRequirements (IterableDeclContext *idc) {
3053+ assert (idc->getDecl ()->hasClangNode ());
3054+ for (Decl *member : idc->getMembers ()) {
3055+ // Skip accessors; we'll match their storage instead.
3056+ if (isa<AccessorDecl>(member))
30373057 continue ;
30383058
3039- auto inserted = unmatchedRequirements.insert (member);
3040- assert (inserted && " objc interface member added twice?" );
3059+ addRequirement (member);
30413060 }
30423061 }
30433062
30443063 void addCandidates (ExtensionDecl *ext) {
30453064 assert (ext->isObjCImplementation ());
3046- for (Decl *_member : ext->getMembers ()) {
3065+ for (Decl *member : ext->getMembers ()) {
30473066 // Skip accessors; we'll match their storage instead.
3048- auto member = dyn_cast<ValueDecl>(_member);
3049- if (!member || isa<AccessorDecl>(member) || isa<DestructorDecl>(member))
3067+ if (isa<AccessorDecl>(member))
30503068 continue ;
30513069
3052- // Skip non-member implementations.
3053- // FIXME: Should we consider them if they were only rejected for privacy?
3054- if (!member->isObjCMemberImplementation ()) {
3055- // No member of an `@_objcImplementation` extension should need a vtable
3056- // entry.
3057- diagnoseVTableUse (member);
3058- continue ;
3070+ if (auto VD = dyn_cast<ValueDecl>(member)) {
3071+ // Skip non-member implementations.
3072+ // FIXME: Should we consider them if only rejected for access level?
3073+ if (!VD->isObjCMemberImplementation ()) {
3074+ // No member of an `@_objcImplementation` extension should need a
3075+ // vtable entry.
3076+ diagnoseVTableUse (VD);
3077+ continue ;
3078+ }
30593079 }
30603080
3061- // `getExplicitObjCName()` is O(N) and would otherwise be used repeatedly
3062- // in `matchRequirementsAtThreshold()`, so just precompute it.
3063- auto inserted =
3064- unmatchedCandidates.insert ({ member, getExplicitObjCName (member) });
3065- assert (inserted.second && " member implementation added twice?" );
3066-
3081+ addCandidate (member);
30673082 }
30683083 }
30693084
0 commit comments