summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-08-20 20:54:15 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-08-20 20:54:15 +0000
commit9c83720d17e5a6699a7f3d86a80e6f7bfd9f9166 (patch)
treef3da72e6b86647ee646e5f5b47243321ddc86741 /clang/lib
parente7e865cf0bc6a0376348b19462625e7d29062e54 (diff)
downloadbcm5719-llvm-9c83720d17e5a6699a7f3d86a80e6f7bfd9f9166.tar.gz
bcm5719-llvm-9c83720d17e5a6699a7f3d86a80e6f7bfd9f9166.zip
ir-gen patch to destruct array members. WIP.
llvm-svn: 79565
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp53
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h4
2 files changed, 44 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 2ec7c473414..72aa9fc090e 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -413,6 +413,12 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
}
void
+CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+ const ArrayType *Array,
+ llvm::Value *This) {
+}
+
+void
CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
CXXCtorType Type,
llvm::Value *This,
@@ -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<RecordType>() || Field->isAnonymousStructOrUnion())
continue;
const RecordType *ClassRec = FieldType->getAs<RecordType>();
@@ -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<RecordType>();
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(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<RecordType>();
@@ -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<RecordType>()) {
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(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<RecordType>();
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(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<CXXRecordDecl*, 4> DestructedBases;
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index b4cbc965d54..71614c451ce 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/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);
OpenPOWER on IntegriCloud