@@ -3365,45 +3365,8 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
3365
3365
return true ;
3366
3366
}
3367
3367
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).
3371
3368
template <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) {
3407
3370
assert (R);
3408
3371
// First, destroy all fields.
3409
3372
for (const Record::Field &Field : llvm::reverse (R->fields ())) {
@@ -3413,7 +3376,9 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
3413
3376
return false ;
3414
3377
if (!this ->emitGetPtrField (Field.Offset , SourceInfo{}))
3415
3378
return false ;
3416
- if (!this ->emitRecordDestruction (D))
3379
+ if (!this ->emitDestruction (D))
3380
+ return false ;
3381
+ if (!this ->emitPopPtr (SourceInfo{}))
3417
3382
return false ;
3418
3383
}
3419
3384
}
@@ -3437,13 +3402,57 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
3437
3402
for (const Record::Base &Base : llvm::reverse (R->bases ())) {
3438
3403
if (!this ->emitGetPtrBase (Base.Offset , SourceInfo{}))
3439
3404
return false ;
3440
- if (!this ->emitRecordDestruction (Base.Desc ))
3405
+ if (!this ->emitRecordDestruction (Base.R ))
3406
+ return false ;
3407
+ if (!this ->emitPopPtr (SourceInfo{}))
3441
3408
return false ;
3442
3409
}
3410
+
3443
3411
// 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
+ }
3444
3453
3445
- // Remove the instance pointer.
3446
- return this ->emitPopPtr (SourceInfo{} );
3454
+ assert (Desc-> ElemRecord );
3455
+ return this ->emitRecordDestruction (Desc-> ElemRecord );
3447
3456
}
3448
3457
3449
3458
namespace clang {
0 commit comments