aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-12 16:41:08 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-12 16:41:08 +0000
commit9928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3 (patch)
treeb3860a47a6a5f606e5057653deddc0dd84d70635 /lib/CodeGen/CGClass.cpp
parentf1588660c109610e6a79c786b83b7c9bbd6ed31e (diff)
Switch field destruction over to use the new destroyer-based API
and kill a lot of redundant code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp96
1 files changed, 28 insertions, 68 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 911dbf782f..e0b2b9f81e 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -929,47 +929,25 @@ namespace {
}
};
- struct CallArrayFieldDtor : EHScopeStack::Cleanup {
- const FieldDecl *Field;
- CallArrayFieldDtor(const FieldDecl *Field) : Field(Field) {}
-
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
- QualType FieldType = Field->getType();
- QualType BaseType = CGF.getContext().getBaseElementType(FieldType);
- const CXXRecordDecl *FieldClassDecl = BaseType->getAsCXXRecordDecl();
-
- llvm::Value *ThisPtr = CGF.LoadCXXThis();
- LValue LHS = CGF.EmitLValueForField(ThisPtr, Field,
- // FIXME: Qualifiers?
- /*CVRQualifiers=*/0);
-
- const llvm::Type *BasePtr
- = CGF.ConvertType(BaseType)->getPointerTo();
- llvm::Value *BaseAddrPtr
- = CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr);
- const ConstantArrayType *Array
- = CGF.getContext().getAsConstantArrayType(FieldType);
- CGF.EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(),
- Array, BaseAddrPtr);
- }
- };
-
- struct CallFieldDtor : EHScopeStack::Cleanup {
- const FieldDecl *Field;
- CallFieldDtor(const FieldDecl *Field) : Field(Field) {}
-
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
- const CXXRecordDecl *FieldClassDecl =
- Field->getType()->getAsCXXRecordDecl();
-
- llvm::Value *ThisPtr = CGF.LoadCXXThis();
- LValue LHS = CGF.EmitLValueForField(ThisPtr, Field,
- // FIXME: Qualifiers?
- /*CVRQualifiers=*/0);
-
- CGF.EmitCXXDestructorCall(FieldClassDecl->getDestructor(),
- Dtor_Complete, /*ForVirtualBase=*/false,
- LHS.getAddress());
+ class DestroyField : public EHScopeStack::Cleanup {
+ const FieldDecl *field;
+ CodeGenFunction::Destroyer &destroyer;
+ bool useEHCleanupForArray;
+
+ public:
+ DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
+ bool useEHCleanupForArray)
+ : field(field), destroyer(*destroyer),
+ useEHCleanupForArray(useEHCleanupForArray) {}
+
+ void Emit(CodeGenFunction &CGF, bool isForEH) {
+ // Find the address of the field.
+ llvm::Value *thisValue = CGF.LoadCXXThis();
+ LValue LV = CGF.EmitLValueForField(thisValue, field, /*CVRQualifiers=*/0);
+ assert(LV.isSimple());
+
+ CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer,
+ !isForEH && useEHCleanupForArray);
}
};
}
@@ -1043,33 +1021,15 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
llvm::SmallVector<const FieldDecl *, 16> FieldDecls;
for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
E = ClassDecl->field_end(); I != E; ++I) {
- const FieldDecl *Field = *I;
-
- QualType FieldType = getContext().getCanonicalType(Field->getType());
- const ConstantArrayType *Array =
- getContext().getAsConstantArrayType(FieldType);
- if (Array)
- FieldType = getContext().getBaseElementType(Array->getElementType());
-
- switch (FieldType.isDestructedType()) {
- case QualType::DK_none:
- continue;
-
- case QualType::DK_cxx_destructor:
- if (Array)
- EHStack.pushCleanup<CallArrayFieldDtor>(NormalAndEHCleanup, Field);
- else
- EHStack.pushCleanup<CallFieldDtor>(NormalAndEHCleanup, Field);
- break;
-
- case QualType::DK_objc_strong_lifetime:
- PushARCFieldReleaseCleanup(getARCCleanupKind(), Field);
- break;
-
- case QualType::DK_objc_weak_lifetime:
- PushARCFieldWeakReleaseCleanup(getARCCleanupKind(), Field);
- break;
- }
+ const FieldDecl *field = *I;
+ QualType type = field->getType();
+ QualType::DestructionKind dtorKind = type.isDestructedType();
+ if (!dtorKind) continue;
+
+ CleanupKind cleanupKind = getCleanupKind(dtorKind);
+ EHStack.pushCleanup<DestroyField>(cleanupKind, field,
+ getDestroyer(dtorKind),
+ cleanupKind & EHCleanup);
}
}