diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-16 23:11:23 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-16 23:11:23 +0000 |
commit | dbf3cfd39dd5234f90235e263ba2ff4cc61258bd (patch) | |
tree | f10ef988934a570c07a230e78504b18c9182f152 | |
parent | dd4a3b0065b9a7e7b00073df415a798886c090f3 (diff) |
patch for generating objc'2 objc_assign_ivar. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82090 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 23 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 1 | ||||
-rw-r--r-- | test/CodeGenObjC/objc-assign-ivar.m | 47 |
3 files changed, 56 insertions, 15 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 4dc7c265bb..fa3e492416 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -492,17 +492,9 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, // load of a __strong object. llvm::Value *LvalueDst = Dst.getAddress(); llvm::Value *src = Src.getScalarVal(); -#if 0 - // FIXME: We cannot positively determine if we have an 'ivar' assignment, - // object assignment or an unknown assignment. For now, generate call to - // objc_assign_strongCast assignment which is a safe, but consevative - // assumption. if (Dst.isObjCIvar()) CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, LvalueDst); - else - CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst); -#endif - if (Dst.isGlobalObjCRef()) + else if (Dst.isGlobalObjCRef()) CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst); else CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst); @@ -703,6 +695,10 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) { !Ctx.getLangOptions().ObjCNewGCAPI) return; + if (isa<ObjCIvarRefExpr>(E)) { + LV.SetObjCIvar(LV, true); + return; + } if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) { if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) { if ((VD->isBlockVarDecl() && !VD->hasLocalStorage()) || @@ -1033,7 +1029,6 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { bool isUnion = false; - bool isIvar = false; bool isNonGC = false; Expr *BaseExpr = E->getBase(); llvm::Value *BaseValue = NULL; @@ -1057,8 +1052,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { CVRQualifiers = BaseExpr->getType().getCVRQualifiers(); } else { LValue BaseLV = EmitLValue(BaseExpr); - if (BaseLV.isObjCIvar()) - isIvar = true; if (BaseLV.isNonGC()) isNonGC = true; // FIXME: this isn't right for bitfields. @@ -1074,7 +1067,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { assert(Field && "No code generation for non-field member references"); LValue MemExpLV = EmitLValueForField(BaseValue, Field, isUnion, CVRQualifiers); - LValue::SetObjCIvar(MemExpLV, isIvar); LValue::SetObjCNonGC(MemExpLV, isNonGC); setObjCGCLValueClass(getContext(), E, MemExpLV); return MemExpLV; @@ -1425,7 +1417,10 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { CVRQualifiers = ObjectTy.getCVRQualifiers(); } - return EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(), CVRQualifiers); + LValue LV = + EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(), CVRQualifiers); + setObjCGCLValueClass(getContext(), E, LV); + return LV; } LValue diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 5f3009074a..7fd1198a88 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -129,7 +129,6 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, LValue LV = LValue::MakeAddr(V, IvarTy.getCVRQualifiers()|CVRQualifiers, CGF.CGM.getContext().getObjCGCAttrKind(IvarTy)); - LValue::SetObjCIvar(LV, true); return LV; } diff --git a/test/CodeGenObjC/objc-assign-ivar.m b/test/CodeGenObjC/objc-assign-ivar.m new file mode 100644 index 0000000000..f78b2eea6b --- /dev/null +++ b/test/CodeGenObjC/objc-assign-ivar.m @@ -0,0 +1,47 @@ +// RUN: clang-cc -fnext-runtime -fobjc-gc -fobjc-newgc-api -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_ivar' %t | count 11 && +// RUN: true + +typedef struct { + id element; + id elementArray[10]; + __strong id cfElement; + __strong id cfElementArray[10]; +} struct_with_ids_t; + + +@interface NSString @end + +@interface Foo { +@public +// assignments to any/all of these fields should generate objc_assign_ivar + __strong id dict; + __strong id dictArray[3]; + id ivar; + id array[10]; + id nsobject; + NSString *stringArray[10]; + struct_with_ids_t inner; +} +@end + +// The test cases +int IvarAssigns; +void *rhs = 0; +#define ASSIGNTEST(expr, global) expr = rhs + +void testIvars() { + Foo *foo; + ASSIGNTEST(foo->ivar, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->dict, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->dictArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->array[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->nsobject, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->stringArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.element, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.elementArray[0], IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElement, IvarAssigns); // objc_assign_ivar + ASSIGNTEST(foo->inner.cfElementArray[0], IvarAssigns); // objc_assign_ivar + +} + |