================
@@ -460,29 +460,80 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
     return true;
   }
 
-  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    auto StartLoc = E->getSelectorStartLoc();
-    // Identify the selector and the method declaration
-    if (auto *Method = E->getMethodDecl()) {
-      // Report the method as a used symbol
-      report(StartLoc, Method);
+  /// Determines whether a protocol is already covered by the receiver's type,
+  /// either through adopted protocol qualifiers (e.g. `id<Proto>` or an
+  /// inheriting sub-protocol) or through class conformance on the receiver
+  /// interface (e.g. `MyClass <Proto>`).
+  bool IsProtocolCoveredByReceiver(ObjCProtocolDecl *Proto,
+                                   const ObjCObjectPointerType *ObjCPtr,
+                                   ObjCInterfaceDecl *IFace) {
+    if (ObjCPtr) {
+      ASTContext &Ctx = Proto->getASTContext();
+      for (auto *ReceiverProto : ObjCPtr->quals())
+        if (Ctx.ProtocolCompatibleWithProtocol(Proto, ReceiverProto))
+          return true;
     }
+    return IFace && IFace->ClassImplementsProtocol(Proto, true);
----------------
nico wrote:

…is checking if the protocol is implemented in a category safe? Consider:

```
% cat my_protocol.h
@protocol MyProtocol
- (void)foo;
@end
```

```
%cat my_class.h
@interface MyClass
@end
```

```
% cat my_class_category.h
@interface MyClass (Conf) <MyProtocol>
@end
```

Now `[f foo]` is skipped because it's declared on the protocol, the class 
implements the protocol (but only via category!), and `my_class_category.h` is 
skipped.

https://github.com/llvm/llvm-project/pull/216857
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to