Loading clang/include/clang/Basic/DiagnosticSemaKinds.td +2 −0 Original line number Diff line number Diff line Loading @@ -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< Loading clang/include/clang/Sema/Sema.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading clang/lib/Sema/SemaExprObjC.cpp +13 −5 Original line number Diff line number Diff line Loading @@ -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()) Loading Loading @@ -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()); } } } Loading Loading @@ -2215,6 +2222,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, Sel, SelectorLocs, Method, true, SuperLoc.isValid(), LBracLoc, RBracLoc, SourceRange(), ReturnType, VK)) return ExprError(); Loading Loading @@ -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() && Loading clang/test/FixIt/fixit-class-method-messaging.m 0 → 100644 +30 −0 Original line number Diff line number Diff line // 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 Loading
clang/include/clang/Basic/DiagnosticSemaKinds.td +2 −0 Original line number Diff line number Diff line Loading @@ -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< Loading
clang/include/clang/Sema/Sema.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
clang/lib/Sema/SemaExprObjC.cpp +13 −5 Original line number Diff line number Diff line Loading @@ -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()) Loading Loading @@ -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()); } } } Loading Loading @@ -2215,6 +2222,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, Sel, SelectorLocs, Method, true, SuperLoc.isValid(), LBracLoc, RBracLoc, SourceRange(), ReturnType, VK)) return ExprError(); Loading Loading @@ -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() && Loading
clang/test/FixIt/fixit-class-method-messaging.m 0 → 100644 +30 −0 Original line number Diff line number Diff line // 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