def warn_inst_method_not_found : Warning<
"instance method %objcinstance0 not found (return type defaults to 'id')">,
InGroup<MethodAccess>;
-def warn_method_not_found_with_typo : Warning<
- "%select{instance|class}0 method %1 not found (return type defaults to 'id')"
- "; did you mean %2?">, InGroup<MethodAccess>;
+def warn_instance_method_not_found_with_typo : Warning<
+ "instance method %objcinstance0 not found (return type defaults to 'id')"
+ "; did you mean %objcinstance2?">, InGroup<MethodAccess>;
+def warn_class_method_not_found_with_typo : Warning<
+ "class method %objcclass0 not found (return type defaults to 'id')"
+ "; did you mean %objcclass2?">, InGroup<MethodAccess>;
+def error_method_not_found_with_typo : Error<
+ "%select{instance|class}1 method %0 not found "
+ "; did you mean %2?">;
def error_no_super_class_message : Error<
"no @interface declaration found in class messaging of %0">;
def error_root_class_cannot_use_super : Error<
QualType ObjectType) {
unsigned NumArgs = Sel.getNumArgs();
SmallVector<const ObjCMethodDecl *, 8> Methods;
+ bool ObjectIsId = true, ObjectIsClass = true;
+ if (ObjectType.isNull())
+ ObjectIsId = ObjectIsClass = false;
+ else if (!ObjectType->isObjCObjectPointerType())
+ return 0;
+ else if (const ObjCObjectPointerType *ObjCPtr =
+ ObjectType->getAsObjCInterfacePointerType()) {
+ ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
+ ObjectIsId = ObjectIsClass = false;
+ }
+ else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType())
+ ObjectIsClass = false;
+ else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
+ ObjectIsId = false;
+ else
+ return 0;
for (GlobalMethodPool::iterator b = MethodPool.begin(),
e = MethodPool.end(); b != e; b++) {
// instance methods
for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
if (M->Method &&
- (M->Method->getSelector().getNumArgs() == NumArgs) &&
- HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
- Methods.push_back(M->Method);
+ (M->Method->getSelector().getNumArgs() == NumArgs)) {
+ if (ObjectIsId)
+ Methods.push_back(M->Method);
+ else if (!ObjectIsClass &&
+ HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
+ Methods.push_back(M->Method);
+ }
// class methods
for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
if (M->Method &&
- (M->Method->getSelector().getNumArgs() == NumArgs) &&
- HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
- Methods.push_back(M->Method);
+ (M->Method->getSelector().getNumArgs() == NumArgs)) {
+ if (ObjectIsClass)
+ Methods.push_back(M->Method);
+ else if (!ObjectIsId &&
+ HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
+ Methods.push_back(M->Method);
+ }
}
SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
DiagID = isClassMessage ? diag::warn_class_method_not_found
: diag::warn_inst_method_not_found;
if (!getLangOpts().DebuggerSupport) {
- const ObjCMethodDecl *OMD = 0;
- if (const ObjCObjectPointerType *ObjCPtr =
- ReceiverType->getAsObjCInterfacePointerType()) {
- QualType ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
- OMD = SelectorsForTypoCorrection(Sel, ObjectType);
- }
- if (OMD) {
+ const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);
+ if (OMD && !OMD->isInvalidDecl() && OMD->getSelector() != Sel) {
+ if (getLangOpts().ObjCAutoRefCount)
+ DiagID = diag::error_method_not_found_with_typo;
+ else
+ DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
+ : diag::warn_instance_method_not_found_with_typo;
Selector MatchedSel = OMD->getSelector();
SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
- Diag(SelLoc, diag::warn_method_not_found_with_typo)
- << isClassMessage << Sel << MatchedSel
+ Diag(SelLoc, DiagID)
+ << Sel<< isClassMessage << MatchedSel
<< FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
}
else
@implementation rdar7853549
- (int) bounds { return 0; }
- (void)PrivateMeth { int bounds = [self bonds]; }
+- (void)OtherPrivateMeth : (id) p { int bounds = [p bonds]; }
@end
void test18(void) {
id x;
- [x test18]; // expected-error {{no known instance method for selector 'test18'}}
+ [x test18]; // expected-error {{instance method 'test18' not found ; did you mean 'test17'?}}
}
extern struct Test19 *test19a;
@implementation Derived
+ (int) class_func1
{
- int i = (size_t)[self class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}}
+ int i = (size_t)[self class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id'); did you mean '+class_func}}
return i + (size_t)[super class_func0]; // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}}
}
+ (int) class_func2
}
- (int) instance_func1
{
- int i = (size_t)[self instance_func0]; // expected-warning {{instance method 'instance_func0' not found (return type defaults to 'id'); did you mean}}
+ int i = (size_t)[self instance_func0]; // expected-warning {{instance method '-instance_func0' not found (return type defaults to 'id'); did you mean}}
return i + (size_t)[super instance_func0]; // expected-warning {{'Object' may not respond to 'instance_func0'}}
}
- (int) instance_func2
@end
@implementation INTF
-- (void)IMeth {INTF<P> *pi; [pi Meth]; } // expected-warning {{instance method 'Meth' not found (return type defaults to 'id'); did you mean 'IMeth'?}}
+- (void)IMeth {INTF<P> *pi; [pi Meth]; } // expected-warning {{instance method '-Meth' not found (return type defaults to 'id'); did you mean '-IMeth'?}}
@end
@end
@implementation INTF
-- (void)IMeth { [(id<P>)self Meth]; } // expected-warning {{method '-Meth' not found (return type defaults to 'id')}}
+- (void)IMeth { [(id<P>)self Meth]; } // expected-warning {{instance method '-Meth' not found (return type defaults to 'id'); did you mean '-IMeth'?}}
@end