@@ -3365,45 +3365,8 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
33653365 return true ;
33663366}
33673367
3368- // / When calling this, we have a pointer of the local-to-destroy
3369- // / on the stack.
3370- // / Emit destruction of record types (or arrays of record types).
33713368template <class Emitter >
3372- bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
3373- assert (Desc);
3374- assert (!Desc->isPrimitive ());
3375- assert (!Desc->isPrimitiveArray ());
3376-
3377- // Arrays.
3378- if (Desc->isArray ()) {
3379- const Descriptor *ElemDesc = Desc->ElemDesc ;
3380- assert (ElemDesc);
3381-
3382- // Don't need to do anything for these.
3383- if (ElemDesc->isPrimitiveArray ())
3384- return this ->emitPopPtr (SourceInfo{});
3385-
3386- // If this is an array of record types, check if we need
3387- // to call the element destructors at all. If not, try
3388- // to save the work.
3389- if (const Record *ElemRecord = ElemDesc->ElemRecord ) {
3390- if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor ();
3391- !Dtor || Dtor->isTrivial ())
3392- return this ->emitPopPtr (SourceInfo{});
3393- }
3394-
3395- for (ssize_t I = Desc->getNumElems () - 1 ; I >= 0 ; --I) {
3396- if (!this ->emitConstUint64 (I, SourceInfo{}))
3397- return false ;
3398- if (!this ->emitArrayElemPtrUint64 (SourceInfo{}))
3399- return false ;
3400- if (!this ->emitRecordDestruction (ElemDesc))
3401- return false ;
3402- }
3403- return this ->emitPopPtr (SourceInfo{});
3404- }
3405-
3406- const Record *R = Desc->ElemRecord ;
3369+ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) {
34073370 assert (R);
34083371 // First, destroy all fields.
34093372 for (const Record::Field &Field : llvm::reverse (R->fields ())) {
@@ -3413,7 +3376,9 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
34133376 return false ;
34143377 if (!this ->emitGetPtrField (Field.Offset , SourceInfo{}))
34153378 return false ;
3416- if (!this ->emitRecordDestruction (D))
3379+ if (!this ->emitDestruction (D))
3380+ return false ;
3381+ if (!this ->emitPopPtr (SourceInfo{}))
34173382 return false ;
34183383 }
34193384 }
@@ -3437,13 +3402,57 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
34373402 for (const Record::Base &Base : llvm::reverse (R->bases ())) {
34383403 if (!this ->emitGetPtrBase (Base.Offset , SourceInfo{}))
34393404 return false ;
3440- if (!this ->emitRecordDestruction (Base.Desc ))
3405+ if (!this ->emitRecordDestruction (Base.R ))
3406+ return false ;
3407+ if (!this ->emitPopPtr (SourceInfo{}))
34413408 return false ;
34423409 }
3410+
34433411 // FIXME: Virtual bases.
3412+ return true ;
3413+ }
3414+ // / When calling this, we have a pointer of the local-to-destroy
3415+ // / on the stack.
3416+ // / Emit destruction of record types (or arrays of record types).
3417+ template <class Emitter >
3418+ bool ByteCodeExprGen<Emitter>::emitDestruction(const Descriptor *Desc) {
3419+ assert (Desc);
3420+ assert (!Desc->isPrimitive ());
3421+ assert (!Desc->isPrimitiveArray ());
3422+
3423+ // Arrays.
3424+ if (Desc->isArray ()) {
3425+ const Descriptor *ElemDesc = Desc->ElemDesc ;
3426+ assert (ElemDesc);
3427+
3428+ // Don't need to do anything for these.
3429+ if (ElemDesc->isPrimitiveArray ())
3430+ return true ;
3431+
3432+ // If this is an array of record types, check if we need
3433+ // to call the element destructors at all. If not, try
3434+ // to save the work.
3435+ if (const Record *ElemRecord = ElemDesc->ElemRecord ) {
3436+ if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor ();
3437+ !Dtor || Dtor->isTrivial ())
3438+ return true ;
3439+ }
3440+
3441+ for (ssize_t I = Desc->getNumElems () - 1 ; I >= 0 ; --I) {
3442+ if (!this ->emitConstUint64 (I, SourceInfo{}))
3443+ return false ;
3444+ if (!this ->emitArrayElemPtrUint64 (SourceInfo{}))
3445+ return false ;
3446+ if (!this ->emitDestruction (ElemDesc))
3447+ return false ;
3448+ if (!this ->emitPopPtr (SourceInfo{}))
3449+ return false ;
3450+ }
3451+ return true ;
3452+ }
34443453
3445- // Remove the instance pointer.
3446- return this ->emitPopPtr (SourceInfo{} );
3454+ assert (Desc-> ElemRecord );
3455+ return this ->emitRecordDestruction (Desc-> ElemRecord );
34473456}
34483457
34493458namespace clang {
0 commit comments