diff options
author | Steve Naroff <snaroff@apple.com> | 2009-02-23 02:25:40 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-02-23 02:25:40 +0000 |
commit | 77170dcb1439e4efddfdd9a3538f7d6be61a2247 (patch) | |
tree | 072fc015f2b24e215e677015093a7c6f9403f2cd /clang/lib/Sema/SemaExprObjC.cpp | |
parent | 5fa0d070a5ab13a3f9c8ba1e429880c7c8cab6f0 (diff) | |
download | bcm5719-llvm-77170dcb1439e4efddfdd9a3538f7d6be61a2247.tar.gz bcm5719-llvm-77170dcb1439e4efddfdd9a3538f7d6be61a2247.zip |
Sema::ActOnInstanceMessage(): Tighen up the lookup rules for handling messages to 'Class'. Also improve "super" handling.
llvm-svn: 65300
Diffstat (limited to 'clang/lib/Sema/SemaExprObjC.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index a593549235e..d6bec762764 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/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 <Func> *)super class_func0]; +// [(id <Func>)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<ObjCSuperExpr>(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<ObjCSuperExpr>(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)); |