diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-06-10 04:38:50 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-06-10 04:38:50 +0000 |
commit | 42f963dec21ed86f33ba34dc01140f77c7174768 (patch) | |
tree | b92119e99aeaef0e1cff4e80f8e7b65c4543e3cd | |
parent | d7dad72aa5d98194dc19601a435765c94444ba3b (diff) |
Support complex properties, ivars and message expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73158 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExprComplex.cpp | 48 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenObjC/property-complex.m | 63 |
3 files changed, 107 insertions, 6 deletions
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 41fb725fdf..e1332ff290 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -77,7 +77,14 @@ public: /// and returns the result. ComplexPairTy EmitLoadOfLValue(const Expr *E) { LValue LV = CGF.EmitLValue(E); - return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); + if (LV.isSimple()) + return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); + + if (LV.isPropertyRef()) + return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal(); + + assert(LV.isKVCRef() && "Unknown LValue type!"); + return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal(); } /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load @@ -107,6 +114,18 @@ public: // l-values. ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); } + ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { + return EmitLoadOfLValue(E); + } + ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { + return EmitLoadOfLValue(E); + } + ComplexPairTy VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) { + return EmitLoadOfLValue(E); + } + ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { + return CGF.EmitObjCMessageExpr(E).getComplexVal(); + } ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); } @@ -522,15 +541,32 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { // Compute the address to store into. LValue LHS = CGF.EmitLValue(E->getLHS()); - - // Store into it. - EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified()); - // And now return the LHS + + // Store into it, if simple. + if (LHS.isSimple()) { + EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified()); + + // And now return the LHS + IgnoreReal = ignreal; + IgnoreImag = ignimag; + IgnoreRealAssign = ignreal; + IgnoreImagAssign = ignimag; + return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified()); + } + + // Otherwise we must have a property setter (no complex vector/bitfields). + if (LHS.isPropertyRef()) + CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val)); + else + CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val)); + + // There is no reload after a store through a method, but we need to restore + // the Ignore* flags. IgnoreReal = ignreal; IgnoreImag = ignimag; IgnoreRealAssign = ignreal; IgnoreImagAssign = ignimag; - return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified()); + return Val; } ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 75755ece76..bd5b05acf9 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1508,6 +1508,8 @@ CodeGen::RValue CGObjCCommonMac::EmitLegacyMessageSend( BuiltinType::Kind k = BT->getKind(); Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper) : ObjCTypes.getSendFn2(IsSuper); + } else { + Fn = ObjCTypes.getSendFn2(IsSuper); } } else diff --git a/test/CodeGenObjC/property-complex.m b/test/CodeGenObjC/property-complex.m new file mode 100644 index 0000000000..0cf520e322 --- /dev/null +++ b/test/CodeGenObjC/property-complex.m @@ -0,0 +1,63 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -S -o - %s && +// RUN: clang-cc -triple x86_64-apple-darwin9 -emit-llvm -S -o - %s + +#include <stdio.h> + +@interface I0 { +@public + _Complex float iv0; +} + +@property(assign) _Complex float p0; + +-(_Complex float) im0; +-(void) setIm0: (_Complex float) a0; +@end + +@implementation I0 +@dynamic p0; + +-(id) init { + self->iv0 = 5.0 + 2.0i; + return self; +} + +-(_Complex float) im0 { + printf("im0: %.2f + %.2fi\n", __real iv0, __imag iv0); + return iv0 + (.1 + .2i); +} +-(void) setIm0: (_Complex float) a0 { + printf("setIm0: %.2f + %.2fi\n", __real a0, __imag a0); + iv0 = a0 + (.3 + .4i); +} + +-(_Complex float) p0 { + printf("p0: %.2f + %.2fi\n", __real iv0, __imag iv0); + return iv0 + (.5 + .6i); +} +-(void) setP0: (_Complex float) a0 { + printf("setP0: %.2f + %.2fi\n", __real a0, __imag a0); + iv0 = a0 + (.7 + .8i); +} +@end + +void f0(I0 *a0) { + float l0 = __real a0.im0; + float l1 = __imag a0->iv0; + _Complex float l2 = (a0.im0 = a0.im0); + _Complex float l3 = a0->iv0; + _Complex float l4 = (a0->iv0 = a0->iv0); + _Complex float l5 = a0->iv0; + _Complex float l6 = (a0.p0 = a0.p0); + _Complex float l7 = a0->iv0; + _Complex float l8 = [a0 im0]; + printf("l0: %.2f + %.2fi\n", __real l0, __imag l0); + printf("l1: %.2f + %.2fi\n", __real l1, __imag l1); + printf("l2: %.2f + %.2fi\n", __real l2, __imag l2); + printf("l3: %.2f + %.2fi\n", __real l3, __imag l3); + printf("l4: %.2f + %.2fi\n", __real l4, __imag l4); + printf("l5: %.2f + %.2fi\n", __real l5, __imag l5); + printf("l6: %.2f + %.2fi\n", __real l6, __imag l6); + printf("l7: %.2f + %.2fi\n", __real l7, __imag l7); + printf("l8: %.2f + %.2fi\n", __real l8, __imag l8); +} |