From: Fariborz Jahanian Date: Thu, 20 Aug 2009 20:54:15 +0000 (+0000) Subject: ir-gen patch to destruct array members. WIP. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f800f6c09ed4a71bcb593d6962e0fda2c2845a70;p=clang ir-gen patch to destruct array members. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79565 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 2ec7c47341..72aa9fc090 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -412,6 +412,12 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, EmitBlock(AfterFor, true); } +void +CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, + const ArrayType *Array, + llvm::Value *This) { +} + void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, @@ -1314,12 +1320,8 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { QualType FieldType = getContext().getCanonicalType((*Field)->getType()); const ConstantArrayType *Array = getContext().getAsConstantArrayType(FieldType); - if (Array) { - FieldType = Array->getElementType(); - while (const ConstantArrayType *AT = - getContext().getAsConstantArrayType(FieldType)) - FieldType = AT->getElementType(); - } + if (Array) + FieldType = getContext().getBaseElementType(FieldType); if (!FieldType->getAs() || Field->isAnonymousStructOrUnion()) continue; const RecordType *ClassRec = FieldType->getAs(); @@ -1374,16 +1376,27 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { if (DD->isMemberToDestroy(BaseOrMember)) { FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember); QualType FieldType = getContext().getCanonicalType((FD)->getType()); - assert(!getContext().getAsArrayType(FieldType) - && "FIXME. Field arrays destruction unsupported"); + const ConstantArrayType *Array = + getContext().getAsConstantArrayType(FieldType); + if (Array) + FieldType = getContext().getBaseElementType(FieldType); const RecordType *RT = FieldType->getAs(); CXXRecordDecl *FieldClassDecl = cast(RT->getDecl()); if (FieldClassDecl->hasTrivialDestructor()) continue; llvm::Value *LoadOfThis = LoadCXXThis(); LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0); - EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), - Dtor_Complete, LHS.getAddress()); + if (Array) { + const llvm::Type *BasePtr = ConvertType(FieldType); + BasePtr = llvm::PointerType::getUnqual(BasePtr); + llvm::Value *BaseAddrPtr = + Builder.CreateBitCast(LHS.getAddress(), BasePtr); + EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), + Array, BaseAddrPtr); + } + else + EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), + Dtor_Complete, LHS.getAddress()); } else { const RecordType *RT = DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs(); @@ -1407,7 +1420,8 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { FieldEnd = ClassDecl->field_end(); Field != FieldEnd; ++Field) { QualType FieldType = getContext().getCanonicalType((*Field)->getType()); - // FIXME. Assert on arrays for now. + if (getContext().getAsConstantArrayType(FieldType)) + FieldType = getContext().getBaseElementType(FieldType); if (const RecordType *RT = FieldType->getAs()) { CXXRecordDecl *FieldClassDecl = cast(RT->getDecl()); if (FieldClassDecl->hasTrivialDestructor()) @@ -1419,12 +1433,25 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { for (int i = DestructedFields.size() -1; i >= 0; --i) { FieldDecl *Field = DestructedFields[i]; QualType FieldType = Field->getType(); + const ConstantArrayType *Array = + getContext().getAsConstantArrayType(FieldType); + if (Array) + FieldType = getContext().getBaseElementType(FieldType); const RecordType *RT = FieldType->getAs(); CXXRecordDecl *FieldClassDecl = cast(RT->getDecl()); llvm::Value *LoadOfThis = LoadCXXThis(); LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0); - EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), - Dtor_Complete, LHS.getAddress()); + if (Array) { + const llvm::Type *BasePtr = ConvertType(FieldType); + BasePtr = llvm::PointerType::getUnqual(BasePtr); + llvm::Value *BaseAddrPtr = + Builder.CreateBitCast(LHS.getAddress(), BasePtr); + EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), + Array, BaseAddrPtr); + } + else + EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), + Dtor_Complete, LHS.getAddress()); } llvm::SmallVector DestructedBases; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index b4cbc965d5..71614c451c 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -587,6 +587,10 @@ public: const ArrayType *Array, llvm::Value *This); + void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, + const ArrayType *Array, + llvm::Value *This); + void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, llvm::Value *This);