aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-04-28 21:28:56 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-04-28 21:28:56 +0000
commit109dfc6ca6652f60c55ed0f2631aebf323d0200d (patch)
treed61db3de42d880a2bee63603685277372a01e326 /lib/CodeGen/CGObjC.cpp
parent60909e1242f19aa8b1b87110aaa8e394f329ae96 (diff)
IRGen for initialization/destruction of
ivar class objects (NeXt runtime). (radar 7900343). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102533 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
-rw-r--r--lib/CodeGen/CGObjC.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 3c1dca01e1..3ce1a65132 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -397,6 +397,55 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
FinishFunction();
}
+void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
+ ObjCMethodDecl *MD,
+ bool ctor) {
+ llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> IvarInitializers;
+ MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
+ StartObjCMethod(MD, IMP->getClassInterface());
+ for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
+ E = IMP->init_end(); B != E; ++B) {
+ CXXBaseOrMemberInitializer *Member = (*B);
+ IvarInitializers.push_back(Member);
+ }
+ if (ctor) {
+ for (unsigned I = 0, E = IvarInitializers.size(); I != E; ++I) {
+ 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);
+ EmitAggExpr(IvarInit->getInit(), LV.getAddress(),
+ LV.isVolatileQualified(), false, true);
+ }
+ // constructor returns 'self'.
+ CodeGenTypes &Types = CGM.getTypes();
+ QualType IdTy(CGM.getContext().getObjCIdType());
+ llvm::Value *SelfAsId =
+ Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
+ EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
+ }
+ else {
+ // dtor
+ 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");
+ 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());
+ }
+ }
+ FinishFunction();
+}
+
bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
it++; it++;