diff options
author | Steve Naroff <snaroff@apple.com> | 2008-07-24 19:44:33 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2008-07-24 19:44:33 +0000 |
commit | fc93d52ada07d52de0ad4fd051b6a08e21d421ff (patch) | |
tree | 4ded457fe6093b022dd9d004e14a07345e055beb | |
parent | 17a61db7da06eec137f48bfb40369ec2a39c4fdc (diff) |
Fix Sema::ActOnClassMessage() to pass through the identifier for "super".
This fixes a critical rewriter bug (<rdar://problem/6096760> clang ObjC rewriter: 'self' not expected value in class method called with 'super').
Also added a couple FIXME's since I'm not happy with my fix to Sema. It would be nicer if the super handling for class/instance messages was the same (based on PreDefinedExpr).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53994 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Driver/RewriteObjC.cpp | 2 | ||||
-rw-r--r-- | include/clang/AST/ExprObjC.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 12 |
3 files changed, 12 insertions, 3 deletions
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp index e022ddaf6c..0ee0599b89 100644 --- a/Driver/RewriteObjC.cpp +++ b/Driver/RewriteObjC.cpp @@ -2000,6 +2000,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend(). if (clsName) { // class message. + // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle + // the 'super' idiom within a class method. if (!strcmp(clsName->getName(), "super")) { MsgSendFlavor = MsgSendSuperFunctionDecl; if (MsgSendStretFlavor) diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index e63242e909..ab4992cfe0 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -286,6 +286,7 @@ public: /// getReceiver - Returns the receiver of the message expression. /// This can be NULL if the message is for class methods. For /// class methods, use getClassName. + /// FIXME: need to handle/detect 'super' usage within a class method. Expr *getReceiver() { uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; return (x & Flags) == IsInstMeth ? (Expr*) x : 0; diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 333268e8e5..5d168232fe 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -147,7 +147,10 @@ Sema::ExprResult Sema::ActOnClassMessage( Expr **ArgExprs = reinterpret_cast<Expr **>(Args); ObjCInterfaceDecl* ClassDecl = 0; + bool isSuper = false; + if (!strcmp(receiverName->getName(), "super") && getCurMethodDecl()) { + isSuper = true; ClassDecl = getCurMethodDecl()->getClassInterface()->getSuperClass(); if (!ClassDecl) return Diag(lbrac, diag::error_no_super_class, @@ -206,11 +209,14 @@ Sema::ExprResult Sema::ActOnClassMessage( // If we have the ObjCInterfaceDecl* for the class that is receiving // the message, use that to construct the ObjCMessageExpr. Otherwise // pass on the IdentifierInfo* for the class. - if (ClassDecl) - return new ObjCMessageExpr(ClassDecl, Sel, returnType, Method, + // FIXME: need to do a better job handling 'super' usage within a class + // For now, we simply pass the "super" identifier through (which isn't + // consistent with instance methods. + if (isSuper || !ClassDecl) + return new ObjCMessageExpr(receiverName, Sel, returnType, Method, lbrac, rbrac, ArgExprs, NumArgs); else - return new ObjCMessageExpr(receiverName, Sel, returnType, Method, + return new ObjCMessageExpr(ClassDecl, Sel, returnType, Method, lbrac, rbrac, ArgExprs, NumArgs); } |