From: Steve Naroff Date: Mon, 23 Feb 2009 02:25:40 +0000 (+0000) Subject: Sema::ActOnInstanceMessage(): Tighen up the lookup rules for handling messages to... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d526c2f2ef28643c15589135b59eb4a8d9f9414c;p=clang Sema::ActOnInstanceMessage(): Tighen up the lookup rules for handling messages to 'Class'. Also improve "super" handling. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65300 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index a593549235..d6bec76276 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -309,6 +309,22 @@ Sema::ExprResult Sema::ActOnClassMessage( lbrac, rbrac, ArgExprs, NumArgs); } +// This routine makes sure we handle the following: +// +// [(Object *)super class_func0]; +// [(id )super class_func0]; +// +static bool isSuperExpr(Stmt *S) { + for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); + CI != E; ++CI) { + if (*CI) + return isSuperExpr(*CI); + } + if (isa(S)) + return true; + return false; +} + // ActOnInstanceMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). @@ -327,7 +343,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, Context.getCanonicalType(RExpr->getType()).getUnqualifiedType(); // Handle messages to 'super'. - if (isa(RExpr)) { + if (isSuperExpr(RExpr)) { ObjCMethodDecl *Method = 0; if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { // If we have an interface in scope, check 'super' methods. @@ -364,17 +380,23 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) { ObjCMethodDecl *Method = 0; if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { - // If we have an implementation in scope, check "private" methods. - if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) - if (ObjCImplementationDecl *ImpDecl = - ObjCImplementations[ClassDecl->getIdentifier()]) - Method = ImpDecl->getClassMethod(Sel); - + if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { + // First check the public methods in the class interface. + Method = ClassDecl->lookupClassMethod(Sel); + + if (!Method) { + // If we have an implementation in scope, check "private" methods. + if (ObjCImplementationDecl *ImpDecl = + ObjCImplementations[ClassDecl->getIdentifier()]) + Method = ImpDecl->getClassMethod(Sel); + } + } if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) return true; - } - if (!Method) + } else { + // We're not in a method context, look for any factory method named 'Sel'. Method = FactoryMethodPool[Sel].Method; + } if (!Method) Method = LookupInstanceMethodInGlobalPool( Sel, SourceRange(lbrac,rbrac));