From 6c79f97037c56f39d4d1ab2bd27ed26aa9392cf1 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 24 Jul 2008 19:44:33 +0000 Subject: [PATCH] Fix Sema::ActOnClassMessage() to pass through the identifier for "super". This fixes a critical rewriter bug ( 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). llvm-svn: 53994 --- clang/Driver/RewriteObjC.cpp | 2 ++ clang/include/clang/AST/ExprObjC.h | 1 + clang/lib/Sema/SemaExprObjC.cpp | 12 +++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index e022ddaf6c12..0ee0599b892c 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/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/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index e63242e909ff..ab4992cfe08f 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 333268e8e5f6..5d168232fe0b 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -147,7 +147,10 @@ Sema::ExprResult Sema::ActOnClassMessage( Expr **ArgExprs = reinterpret_cast(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); }