From 7e3411b23eb3724da5461dc6d6f97d14b3b0a52f Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 15 Nov 2007 02:58:25 +0000 Subject: [PATCH] - Implement ivar rewrite (patch by Fariborz). - RewriteMessageExpr()...make implicit casts explicit with synthesizing call (removing warnings when calling objc_msgSend()). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44156 91177308-0d34-0410-b5e6-96231b3b80d8 --- Driver/RewriteTest.cpp | 32 ++++++++++++++++++++++---------- Sema/SemaExpr.cpp | 8 ++++++-- include/clang/AST/Expr.h | 11 ++++++++--- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 0f6c9741cd..4c7bd9c9d9 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -103,6 +103,7 @@ namespace { // Expression Rewriting. Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); + Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV); Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); @@ -565,6 +566,19 @@ void RewriteTest::RewriteInterfaceDecl(ObjcInterfaceDecl *ClassDecl) { Rewrite.ReplaceText(ClassDecl->getAtEndLoc(), 0, "// ", 3); } +Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { + ObjcIvarDecl *D = IV->getDecl(); + if (IV->isFreeIvar()) { + Expr *Replacement = new MemberExpr(IV->getBase(), true, D, + IV->getLocation()); + Rewrite.ReplaceStmt(IV, Replacement); + delete IV; + return Replacement; + } + else + return IV; +} + //===----------------------------------------------------------------------===// // Function Body / Expression rewriting //===----------------------------------------------------------------------===// @@ -582,6 +596,9 @@ Stmt *RewriteTest::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { // Handle specific things. if (ObjCEncodeExpr *AtEncode = dyn_cast(S)) return RewriteAtEncode(AtEncode); + + if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast(S)) + return RewriteObjCIvarRefExpr(IvarRefExpr); if (ObjCSelectorExpr *AtSelector = dyn_cast(S)) return RewriteAtSelector(AtSelector); @@ -1063,14 +1080,11 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) { // Now push any user supplied arguments. for (unsigned i = 0; i < Exp->getNumArgs(); i++) { Expr *userExpr = Exp->getArg(i); -#if 0 - // Make sure we cast "self" to "id". - if (DeclRefExpr *DRE = dyn_cast(userExpr)) { - if (!strcmp(DRE->getDecl()->getName(), "self")) - userExpr = new CastExpr(Context->getObjcIdType(), userExpr, - SourceLocation()); - } -#endif + // Make all implicit casts explicit...ICE comes in handy:-) + if (ImplicitCastExpr *ICE = dyn_cast(userExpr)) { + // Reuse the ICE type, it is exactly what the doctor ordered. + userExpr = new CastExpr(ICE->getType(), userExpr, SourceLocation()); + } MsgExprs.push_back(userExpr); // We've transferred the ownership to MsgExprs. Null out the argument in // the original expression, since we will delete it below. @@ -1088,8 +1102,6 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) { // Push any user argument types. for (int i = 0; i < mDecl->getNumParams(); i++) { QualType t = mDecl->getParamDecl(i)->getType(); - if (t == Context->getObjcClassType()) - t = Context->getObjcIdType(); // Convert "Class"->"id" ArgTypes.push_back(t); } returnType = mDecl->getResultType(); diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index e87ad6a398..42961df167 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -85,8 +85,12 @@ Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc, if (CurMethodDecl) { ObjcInterfaceDecl *IFace = CurMethodDecl->getClassInterface(); ObjcInterfaceDecl *clsDeclared; - if (ObjcIvarDecl *IV = IFace->lookupInstanceVariable(&II, clsDeclared)) - return new ObjCIvarRefExpr(IV, IV->getType(), Loc); + if (ObjcIvarDecl *IV = IFace->lookupInstanceVariable(&II, clsDeclared)) { + IdentifierInfo &II = Context.Idents.get("self"); + ExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); + return new ObjCIvarRefExpr(IV, IV->getType(), Loc, + static_cast(SelfExpr.Val), true, true); + } } // If this name wasn't predeclared and if this is not a function call, // diagnose the problem. diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7dead68a57..66dac91e21 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1256,18 +1256,23 @@ class ObjCIvarRefExpr : public Expr { class ObjcIvarDecl *D; SourceLocation Loc; Expr *Base; - bool IsArrow; // True if this is "X->F", false if this is "X.F". + bool IsArrow:1; // True if this is "X->F", false if this is "X.F". + bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). public: ObjCIvarRefExpr(ObjcIvarDecl *d, QualType t, SourceLocation l, Expr *base=0, - bool arrow = false) : - Expr(ObjCIvarRefExprClass, t), D(d), Loc(l), Base(base), IsArrow(arrow) {} + bool arrow = false, bool freeIvar = false) : + Expr(ObjCIvarRefExprClass, t), D(d), Loc(l), Base(base), IsArrow(arrow), + IsFreeIvar(freeIvar) {} ObjcIvarDecl *getDecl() { return D; } const ObjcIvarDecl *getDecl() const { return D; } virtual SourceRange getSourceRange() const { return SourceRange(Loc); } Expr *const getBase() const { return Base; } const bool isArrow() const { return IsArrow; } + const bool isFreeIvar() const { return IsFreeIvar; } + + SourceLocation getLocation() const { return Loc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; -- 2.40.0