forked from OSchip/llvm-project
Support for construct/destruct of ivar array
of c++ objects (NeXt runtime). radar 7900343. llvm-svn: 102546
This commit is contained in:
parent
2288ef6c33
commit
499b902510
|
@ -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();
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
Loading…
Reference in New Issue