diff options
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 25 | ||||
-rw-r--r-- | test/CodeGenObjCXX/ivar-objects.mm | 71 |
2 files changed, 89 insertions, 7 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 3ce1a65132..4a874e22da 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -413,10 +413,9 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, CXXBaseOrMemberInitializer *IvarInit = IvarInitializers[I]; FieldDecl *Field = IvarInit->getMember(); QualType FieldType = Field->getType(); - if (CGM.getContext().getAsConstantArrayType(FieldType)) - assert(false && "Construction objc arrays NYI"); ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); - LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0); + LValue LV = EmitLValueForIvar(TypeOfSelfObject(), + LoadObjCSelf(), Ivar, 0); EmitAggExpr(IvarInit->getInit(), LV.getAddress(), LV.isVolatileQualified(), false, true); } @@ -432,15 +431,27 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, for (size_t i = IvarInitializers.size(); i > 0; --i) { FieldDecl *Field = IvarInitializers[i - 1]->getMember(); QualType FieldType = Field->getType(); - if (CGM.getContext().getAsConstantArrayType(FieldType)) - assert(false && "Destructing objc arrays NYI"); + const ConstantArrayType *Array = + getContext().getAsConstantArrayType(FieldType); + if (Array) + FieldType = getContext().getBaseElementType(FieldType); + ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0); const RecordType *RT = FieldType->getAs<RecordType>(); CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); - EmitCXXDestructorCall(FieldClassDecl->getDestructor(CGM.getContext()), - Dtor_Complete, LV.getAddress()); + if (Array) { + const llvm::Type *BasePtr = ConvertType(FieldType); + BasePtr = llvm::PointerType::getUnqual(BasePtr); + llvm::Value *BaseAddrPtr = + Builder.CreateBitCast(LV.getAddress(), BasePtr); + EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), + Array, BaseAddrPtr); + } + else + EmitCXXDestructorCall(FieldClassDecl->getDestructor(CGM.getContext()), + Dtor_Complete, LV.getAddress()); } } FinishFunction(); diff --git a/test/CodeGenObjCXX/ivar-objects.mm b/test/CodeGenObjCXX/ivar-objects.mm new file mode 100644 index 0000000000..79c1a397e7 --- /dev/null +++ b/test/CodeGenObjCXX/ivar-objects.mm @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// CHECK: -[A .cxx_construct] +// CHECK: -[A .cxx_destruct] + +@interface NSObject +- alloc; +- init; +- (void) release; +@end + +extern "C" int printf(const char *, ...); + +int count = 17; +struct X { + X() : value(count++) { printf( "X::X()\n"); } + ~X() { printf( "X::~X()\n"); } + int value; +}; + +struct Y { + Y() : value(count++) { printf( "Y::Y()\n"); } + ~Y() { printf( "Y::~Y()\n"); } + int value; +}; + +@interface Super : NSObject { + Y yvar; + Y yvar1; + Y ya[3]; +} +- (void)finalize; +@end + +@interface A : Super { + X xvar; + X xvar1; + X xvar2; + X xa[2][2]; +} + +- (void)print; +- (void)finalize; +@end + +@implementation Super +- (void)print { + printf( "yvar.value = %d\n", yvar.value); + printf( "yvar1.value = %d\n", yvar1.value); + printf( "ya[0..2] = %d %d %d\n", ya[0].value, ya[1].value, ya[2].value); +} +- (void)finalize {} +@end + +@implementation A +- (void)print { + printf( "xvar.value = %d\n", xvar.value); + printf( "xvar1.value = %d\n", xvar1.value); + printf( "xvar2.value = %d\n", xvar2.value); + printf( "xa[0..1][0..1] = %d %d %d %d\n", + xa[0][0].value, xa[0][1].value, xa[1][0].value, xa[1][1].value); + [super print]; +} +- (void)finalize { [super finalize]; } +@end + +int main() { + A *a = [[A alloc] init]; + [a print]; + [a release]; +} + |