Switch field destruction over to use the new destroyer-based API

and kill a lot of redundant code.

llvm-svn: 134988
This commit is contained in:
John McCall
2011-07-12 16:41:08 +00:00
parent 992a2856f5
commit 4bd0fb1f09
8 changed files with 194 additions and 402 deletions

View File

@@ -929,47 +929,25 @@ namespace {
}
};
struct CallArrayFieldDtor : EHScopeStack::Cleanup {
const FieldDecl *Field;
CallArrayFieldDtor(const FieldDecl *Field) : Field(Field) {}
class DestroyField : public EHScopeStack::Cleanup {
const FieldDecl *field;
CodeGenFunction::Destroyer &destroyer;
bool useEHCleanupForArray;
void Emit(CodeGenFunction &CGF, bool IsForEH) {
QualType FieldType = Field->getType();
QualType BaseType = CGF.getContext().getBaseElementType(FieldType);
const CXXRecordDecl *FieldClassDecl = BaseType->getAsCXXRecordDecl();
public:
DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
bool useEHCleanupForArray)
: field(field), destroyer(*destroyer),
useEHCleanupForArray(useEHCleanupForArray) {}
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());
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());
const FieldDecl *field = *I;
QualType type = field->getType();
QualType::DestructionKind dtorKind = type.isDestructedType();
if (!dtorKind) continue;
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;
}
CleanupKind cleanupKind = getCleanupKind(dtorKind);
EHStack.pushCleanup<DestroyField>(cleanupKind, field,
getDestroyer(dtorKind),
cleanupKind & EHCleanup);
}
}