]> granicus.if.org Git - clang/commitdiff
Objective-C [qoi]. Provide fix-it hint when sending
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 19 Aug 2014 23:39:17 +0000 (23:39 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 19 Aug 2014 23:39:17 +0000 (23:39 +0000)
class method to an object receiver. rdar://16263395

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216038 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaExprObjC.cpp
test/FixIt/fixit-class-method-messaging.m [new file with mode: 0644]

index 532e4d5bb84eb329d80c6f4730be1cbd4727be71..5d427aada7b8d6a2e61195cff9c635a75fa628e4 100644 (file)
@@ -591,6 +591,8 @@ def note_class_declared : Note<
   "class is declared here">;
 def note_receiver_class_declared : Note<
   "receiver is instance of class declared here">;
+def note_receiver_expr_here : Note<
+  "receiver expression is here">;
 def note_receiver_is_id : Note<
   "receiver is treated with 'id' type for purpose of method lookup">;
 def note_suppressed_class_declare : Note<
index eb53a93c6a28b15f362e5cecf96f8b08006196f4..a9f043d5bfdb987f5e15b2e73109f03ebd99e53c 100644 (file)
@@ -8045,6 +8045,7 @@ public:
                                  ObjCMethodDecl *Method, bool isClassMessage,
                                  bool isSuperMessage,
                                  SourceLocation lbrac, SourceLocation rbrac,
+                                 SourceRange RecRange,
                                  QualType &ReturnType, ExprValueKind &VK);
 
   /// \brief Determine the result of a message send expression based on
index 39598b5a19aab4f4c74b152cc9821f1c944668c7..582e1834d480335df2e81375ba3f19873822b1f5 100644 (file)
@@ -1325,6 +1325,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
                                      ObjCMethodDecl *Method,
                                      bool isClassMessage, bool isSuperMessage,
                                      SourceLocation lbrac, SourceLocation rbrac,
+                                     SourceRange RecRange,
                                      QualType &ReturnType, ExprValueKind &VK) {
   SourceLocation SelLoc;
   if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
@@ -1379,9 +1380,15 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
                                                 SelectorLocs.back());
       // Find the class to which we are sending this message.
       if (ReceiverType->isObjCObjectPointerType()) {
-        if (ObjCInterfaceDecl *Class =
-              ReceiverType->getAs<ObjCObjectPointerType>()->getInterfaceDecl())
-          Diag(Class->getLocation(), diag::note_receiver_class_declared);
+        if (ObjCInterfaceDecl *ThisClass =
+            ReceiverType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()) {
+          Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
+          if (!RecRange.isInvalid())
+            if (ThisClass->lookupClassMethod(Sel))
+              Diag(RecRange.getBegin(),diag::note_receiver_expr_here)
+                << FixItHint::CreateReplacement(RecRange,
+                                                ThisClass->getNameAsString());
+        }
       }
     }
 
@@ -2214,7 +2221,8 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
   if (CheckMessageArgumentTypes(ReceiverType, MultiExprArg(Args, NumArgs),
                                 Sel, SelectorLocs,
                                 Method, true,
-                                SuperLoc.isValid(), LBracLoc, RBracLoc, 
+                                SuperLoc.isValid(), LBracLoc, RBracLoc,
+                                SourceRange(),
                                 ReturnType, VK))
     return ExprError();
 
@@ -2619,7 +2627,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
   if (CheckMessageArgumentTypes(ReceiverType, MultiExprArg(Args, NumArgs),
                                 Sel, SelectorLocs, Method,
                                 ClassMessage, SuperLoc.isValid(), 
-                                LBracLoc, RBracLoc, ReturnType, VK))
+                                LBracLoc, RBracLoc, RecRange, ReturnType, VK))
     return ExprError();
 
   if (Method && !Method->getReturnType()->isVoidType() &&
diff --git a/test/FixIt/fixit-class-method-messaging.m b/test/FixIt/fixit-class-method-messaging.m
new file mode 100644 (file)
index 0000000..e2592d0
--- /dev/null
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// rdar://16263395
+
+@interface NSObject @end
+
+@interface I : NSObject // expected-note 3 {{receiver is instance of class declared here}}
++ (id) ClassMeth;
+- (I*) MethInstPI;
+@end
+
+I* pi;
+
+I* foobar();
+
+@implementation I
+- (id) PrivInstMeth {
+  [ foobar() ClassMeth]; // expected-warning {{instance method '-ClassMeth' not found (return type defaults to 'id')}} \
+                        // expected-note {{receiver expression is here}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:5-[[@LINE-2]]:13}:"I
+  [[self MethInstPI] ClassMeth]; // expected-warning {{instance method '-ClassMeth' not found (return type defaults to 'id')}} \
+                                // expected-note {{receiver expression is here}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:4-[[@LINE-2]]:21}:"I
+  return [pi ClassMeth]; // expected-warning {{instance method '-ClassMeth' not found (return type defaults to 'id')}} \
+                         // expected-note {{receiver expression is here}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"I
+}
++ (id) ClassMeth { return 0; }
+- (I*) MethInstPI { return 0; }
+@end