[cfe-commits] r50781 - /cfe/trunk/Driver/RewriteObjC.cpp
Steve Naroff
snaroff at apple.com
Tue May 6 16:20:07 PDT 2008
Author: snaroff
Date: Tue May 6 18:20:07 2008
New Revision: 50781
URL: http://llvm.org/viewvc/llvm-project?rev=50781&view=rev
Log:
Fix <rdar://problem/5879237> clang objc rewriter: ivars not accessible in structure generated for class
Modified:
cfe/trunk/Driver/RewriteObjC.cpp
Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=50781&r1=50780&r2=50781&view=diff
==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Tue May 6 18:20:07 2008
@@ -850,9 +850,35 @@
}
}
} else { // we are outside a method.
- if (IV->isFreeIvar())
- assert(1 && "Cannot have a free standing ivar outside a method");
- // Explicit ivar refs do not need to be rewritten. Do nothing.
+ assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
+
+ // Explicit ivar refs need to have a cast inserted.
+ // FIXME: consider sharing some of this code with the code above.
+ if (const PointerType *pType = IV->getBase()->getType()->getAsPointerType()) {
+ ObjCInterfaceType *intT = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
+ // lookup which class implements the instance variable.
+ 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());
+ RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, TUDecl,
+ SourceLocation(), II, 0);
+ assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+ QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+ CastExpr *castExpr = new CastExpr(castT, IV->getBase(), SourceLocation());
+ // Don't forget the parens to enforce the proper binding.
+ ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), castExpr);
+ ReplaceStmt(IV->getBase(), 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;
+ }
}
return IV;
}
More information about the cfe-commits
mailing list