[cfe-commits] r95341 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-cast-ivar-access.mm
Fariborz Jahanian
fjahanian at apple.com
Thu Feb 4 17:35:01 PST 2010
Author: fjahanian
Date: Thu Feb 4 19:35:00 2010
New Revision: 95341
URL: http://llvm.org/viewvc/llvm-project?rev=95341&view=rev
Log:
Fix a nested ivar reference rewriting bug.
(Fixes radar 7607605).
Modified:
cfe/trunk/lib/Frontend/RewriteObjC.cpp
cfe/trunk/test/Rewriter/rewrite-cast-ivar-access.mm
Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=95341&r1=95340&r2=95341&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Thu Feb 4 19:35:00 2010
@@ -278,7 +278,9 @@
ParentMap *PropParentMap; // created lazily.
Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
- Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart);
+ Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart,
+ bool &replaced);
+ Stmt *RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced);
Stmt *RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr);
Stmt *RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
SourceRange SrcRange);
@@ -1209,7 +1211,8 @@
}
Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
- SourceLocation OrigStart) {
+ SourceLocation OrigStart,
+ bool &replaced) {
ObjCIvarDecl *D = IV->getDecl();
const Expr *BaseExpr = IV->getBase();
if (CurMethodDef) {
@@ -1238,21 +1241,16 @@
ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
IV->getBase()->getLocEnd(),
castExpr);
+ replaced = true;
if (IV->isFreeIvar() &&
CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
IV->getLocation(),
D->getType());
- ReplaceStmt(IV, ME);
// delete IV; leak for now, see RewritePropertySetter() usage for more info.
return ME;
}
- // Get the old text, only to get its size.
- std::string SStr;
- llvm::raw_string_ostream S(SStr);
- IV->getBase()->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
// Get the new text
- ReplaceStmt(IV->getBase(), PE, S.str().size());
// 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].
@@ -1287,7 +1285,7 @@
// Don't forget the parens to enforce the proper binding.
ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
IV->getBase()->getLocEnd(), castExpr);
- ReplaceStmt(IV->getBase(), PE);
+ replaced = true;
// 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].
@@ -1298,6 +1296,24 @@
return IV;
}
+Stmt *RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced) {
+ for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+ CI != E; ++CI) {
+ if (*CI) {
+ Stmt *newStmt = RewriteObjCNestedIvarRefExpr(*CI, replaced);
+ if (newStmt)
+ *CI = newStmt;
+ }
+ }
+ if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+ SourceRange OrigStmtRange = S->getSourceRange();
+ Stmt *newStmt = RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin(),
+ replaced);
+ return newStmt;
+ }
+ return S;
+}
+
/// SynthCountByEnumWithState - To print:
/// ((unsigned int (*)
/// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
@@ -4869,7 +4885,21 @@
for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
CI != E; ++CI)
if (*CI) {
- Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(*CI);
+ Stmt *newStmt;
+ Stmt *S = (*CI);
+ if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+ Expr *OldBase = IvarRefExpr->getBase();
+ bool replaced = false;
+ newStmt = RewriteObjCNestedIvarRefExpr(S, replaced);
+ if (replaced) {
+ if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt))
+ ReplaceStmt(OldBase, IRE->getBase());
+ else
+ ReplaceStmt(S, newStmt);
+ }
+ }
+ else
+ newStmt = RewriteFunctionBodyOrGlobalInitializer(S);
if (newStmt)
*CI = newStmt;
}
@@ -4891,9 +4921,6 @@
if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
return RewriteAtEncode(AtEncode);
- if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S))
- return RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin());
-
if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(S)) {
BinaryOperator *BinOp = PropSetters[PropRefExpr];
if (BinOp) {
Modified: cfe/trunk/test/Rewriter/rewrite-cast-ivar-access.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-cast-ivar-access.mm?rev=95341&r1=95340&r2=95341&view=diff
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-cast-ivar-access.mm (original)
+++ cfe/trunk/test/Rewriter/rewrite-cast-ivar-access.mm Thu Feb 4 19:35:00 2010
@@ -25,6 +25,29 @@
objc_assign_strongCast((id)value);
}
+// radar 7607605
+ at interface RealClass {
+ @public
+ int f;
+}
+ at end
+
+ at implementation RealClass
+ at end
+
+ at interface Foo {
+ id reserved;
+}
+ at end
+
+ at implementation Foo
+- (void)bar {
+ ((RealClass*)reserved)->f = 99;
+}
+ at end
+
// CHECK-LP: ((struct G_IMPL *)arg)->ivar
// CHECK-LP: objc_assign_strongCast((id)value)
+
+// CHECK-LP: ((struct RealClass_IMPL *)((RealClass *)((struct Foo_IMPL *)self)->reserved))->f
More information about the cfe-commits
mailing list