Emit diagnostics for methods not found.

llvm-svn: 43037
This commit is contained in:
Steve Naroff 2007-10-16 20:39:36 +00:00
parent 4187801f85
commit 55f52da24c
4 changed files with 45 additions and 10 deletions

View File

@ -1930,11 +1930,17 @@ Sema::ExprResult Sema::ActOnClassMessage(
ObjcInterfaceDecl* ClassDecl = getObjCInterfaceDecl(receiverName);
ObjcMethodDecl *Method = ClassDecl->lookupClassMethod(Sel);
assert(Method && "missing method declaration");
QualType retType = Method->getMethodType();
QualType returnType;
if (!Method) {
Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(),
SourceRange(lbrac, rbrac));
returnType = GetObjcIdType();
} else {
returnType = Method->getMethodType();
}
// Expr *RExpr = global reference to the class symbol...
Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
return new ObjCMessageExpr(receiverName, Sel, retType, lbrac, rbrac,
return new ObjCMessageExpr(receiverName, Sel, returnType, lbrac, rbrac,
ArgExprs);
}
@ -1953,9 +1959,13 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
if (receiverType == GetObjcIdType()) {
ObjcMethodDecl *Method = InstanceMethodPool[Sel].Method;
// FIXME: emit a diagnostic. For now, I want a hard error...
assert(Method && "missing method declaration");
returnType = Method->getMethodType();
if (!Method) {
Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
SourceRange(lbrac, rbrac));
returnType = GetObjcIdType();
} else {
returnType = Method->getMethodType();
}
} else {
// FIXME (snaroff): checking in this code from Patrick. Needs to be
// revisited. how do we get the ClassDecl from the receiver expression?
@ -1968,10 +1978,17 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
"bad receiver type");
ObjcInterfaceDecl* ClassDecl = static_cast<ObjcInterfaceType*>(
receiverType.getTypePtr())->getDecl();
// FIXME: consider using InstanceMethodPool, since it will be faster
// than the following method (which can do *many* linear searches). The
// idea is to add class info to InstanceMethodPool...
ObjcMethodDecl *Method = ClassDecl->lookupInstanceMethod(Sel);
// FIXME: emit a diagnostic. For now, I want a hard error...
assert(Method && "missing method declaration");
returnType = Method->getMethodType();
if (!Method) {
Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
SourceRange(lbrac, rbrac));
returnType = GetObjcIdType();
} else {
returnType = Method->getMethodType();
}
}
Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
return new ObjCMessageExpr(RExpr, Sel, returnType, lbrac, rbrac, ArgExprs);

View File

@ -157,12 +157,14 @@ public:
// CURRENTLY UNUSED (10/15/07). ObjCStringLiteral now uses the hook below.
QualType getCFConstantStringType();
// This setter/getter represents the actual ObjC type for an NSConstantString.
// This setter/getter represents the ObjC type for an NSConstantString.
void setObjcConstantStringInterface(ObjcInterfaceDecl *Decl);
QualType getObjcConstantStringInterface() const {
return ObjcConstantStringType;
}
// This setter/getter repreents the ObjC 'id' type. It is setup lazily, by
// Sema.
void setObjcIdType(TypedefDecl *Decl);
QualType getObjcIdType() const { return ObjcIdType; }

View File

@ -454,6 +454,8 @@ DIAG(err_conflicting_aliasing_type, ERROR,
"conflicting types for alias %0'")
DIAG(err_statically_allocated_object, ERROR,
"statically allocated Objective-c object '%0'")
DIAG(warn_method_not_found, WARNING,
"method '%0%1' not found (return type defaults to 'id')")
//===----------------------------------------------------------------------===//
// Semantic Analysis

View File

@ -0,0 +1,14 @@
// RUN: clang -fsyntax-only -verify %s
typedef struct objc_object *id;
@interface Foo
@end
void test() {
Foo *fooObj;
id obj;
[[Foo alloc] init]; // expected-warning {{method '+alloc' not found (return type defaults to 'id')}} expected-warning {{method '-init' not found (return type defaults to 'id')}}
[fooObj notdefined]; // expected-warning {{method '-notdefined' not found (return type defaults to 'id')}}
[obj whatever:1 :2 :3]; // expected-warning {{method '-whatever:::' not found (return type defaults to 'id'))}}
}