@@ -2634,6 +2634,41 @@ class Verifier : public ASTWalker {
26342634 abort ();
26352635 }
26362636
2637+ // Tracking for those Objective-C requirements that have witnesses.
2638+ llvm::SmallDenseSet<std::pair<ObjCSelector, char >> hasObjCWitnessMap;
2639+ bool populatedObjCWitnesses = false ;
2640+ auto populateObjCWitnesses = [&] {
2641+ if (populatedObjCWitnesses)
2642+ return ;
2643+
2644+ populatedObjCWitnesses = true ;
2645+ for (auto req : proto->getMembers ()) {
2646+ if (auto reqFunc = dyn_cast<AbstractFunctionDecl>(req)) {
2647+ if (normal->hasWitness (reqFunc)) {
2648+ hasObjCWitnessMap.insert (
2649+ {reqFunc->getObjCSelector (), reqFunc->isInstanceMember ()});
2650+ }
2651+ }
2652+ }
2653+ };
2654+
2655+ // Check whether there is a witness with the same selector and kind as
2656+ // this requirement.
2657+ auto hasObjCWitness = [&](ValueDecl *req) {
2658+ if (!proto->isObjC ())
2659+ return false ;
2660+
2661+ auto func = dyn_cast<AbstractFunctionDecl>(req);
2662+ if (!func)
2663+ return false ;
2664+
2665+ populateObjCWitnesses ();
2666+
2667+ std::pair<ObjCSelector, char > key (
2668+ func->getObjCSelector (), func->isInstanceMember ());
2669+ return hasObjCWitnessMap.count (key) > 0 ;
2670+ };
2671+
26372672 // Check that a normal protocol conformance is complete.
26382673 for (auto member : proto->getMembers ()) {
26392674 if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
@@ -2663,7 +2698,6 @@ class Verifier : public ASTWalker {
26632698 if (isa<AccessorDecl>(member))
26642699 continue ;
26652700
2666-
26672701 if (auto req = dyn_cast<ValueDecl>(member)) {
26682702 if (!normal->hasWitness (req)) {
26692703 if ((req->getAttrs ().isUnavailable (Ctx) ||
@@ -2672,6 +2706,10 @@ class Verifier : public ASTWalker {
26722706 continue ;
26732707 }
26742708
2709+ // Check if *any* witness matches the Objective-C selector.
2710+ if (hasObjCWitness (req))
2711+ continue ;
2712+
26752713 dumpRef (decl);
26762714 Out << " is missing witness for "
26772715 << conformance->getProtocol ()->getName ().str ()
0 commit comments