From: Steve Naroff Date: Wed, 12 Mar 2008 23:15:19 +0000 (+0000) Subject: Two fixes to RewriteTest::RewriteObjCIvarRefExpr(): X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5518e7caf365158c5a03fc34d0d05d5a4981fa05;p=clang Two fixes to RewriteTest::RewriteObjCIvarRefExpr(): - For explicit ivar refers, make sure the cast is propagated to the AST. - Don't free the base (since it is still in use). This fixes the recent regression to test/Rewriter/objc-ivar-receiver-1.m. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48309 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 8140197351..d53f23d00c 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -764,10 +764,6 @@ void RewriteTest::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { ReplaceText(ClassDecl->getAtEndLoc(), 0, "// ", 3); } -/// FIXME: Investigate the following comment... -/// This code is not right. It seems unnecessary. It breaks use of -/// ivar reference used as 'receiver' of an expression; as in: -/// [newInv->_container addObject:0]; Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { ObjCIvarDecl *D = IV->getDecl(); if (CurMethodDecl) { @@ -778,6 +774,8 @@ Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { ObjCInterfaceDecl *clsDeclared = 0; intT->getDecl()->lookupInstanceVariable(D->getIdentifier(), clsDeclared); assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); + + // Synthesize an explicit cast to gain access to the ivar. std::string RecName = clsDeclared->getIdentifier()->getName(); RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName.c_str()); @@ -794,12 +792,16 @@ Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { return ME; } else { ReplaceStmt(IV->getBase(), PE); - delete IV->getBase(); - return PE; + // Cannot delete IV->getBase(), since PE points to it. + // Replace the old base with the cast. This is important when doing + // embedded rewrites. For example, [newInv->_container addObject:0]. + IV->setBase(PE); + return IV; } } } } + // FIXME: Implement public ivar access from a function. Expr *Replacement = new MemberExpr(IV->getBase(), true, D, IV->getLocation(), D->getType()); ReplaceStmt(IV, Replacement); @@ -1975,7 +1977,6 @@ Stmt *RewriteTest::SynthMessageExpr(ObjCMessageExpr *Exp) { SourceLocation()); MsgExprs.push_back(Unop); } else { - //recExpr->dump(); // Remove all type-casts because it may contain objc-style types; e.g. // Foo *. while (CastExpr *CE = dyn_cast(recExpr)) diff --git a/test/Rewriter/objc-ivar-receiver-1.m b/test/Rewriter/objc-ivar-receiver-1.m index 5592be4213..27287dc275 100644 --- a/test/Rewriter/objc-ivar-receiver-1.m +++ b/test/Rewriter/objc-ivar-receiver-1.m @@ -17,6 +17,7 @@ + (NSInvocation *)invocationWithMethodSignature { NSInvocation *newInv; + id obj = newInv->_container; [newInv->_container addObject:0]; return 0; }