Support for construct/destruct of ivar array

of c++ objects (NeXt runtime).
radar 7900343.

llvm-svn: 102546
This commit is contained in:
Fariborz Jahanian 2010-04-28 22:30:33 +00:00
parent 2288ef6c33
commit 499b902510
2 changed files with 89 additions and 7 deletions

View File

@ -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();

View File

@ -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];
}