@@ -406,13 +406,8 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
406
406
build_return ( bcx) ;
407
407
}
408
408
409
- pub fn trans_struct_drop ( bcx : block ,
410
- t : ty:: t ,
411
- v0 : ValueRef ,
412
- dtor_did : ast:: def_id ,
413
- class_did : ast:: def_id ,
414
- substs : & ty:: substs )
415
- -> block {
409
+ pub fn trans_struct_drop_flag ( bcx : block , t : ty:: t , v0 : ValueRef , dtor_did : ast:: def_id ,
410
+ class_did : ast:: def_id , substs : & ty:: substs ) -> block {
416
411
let repr = adt:: represent_type ( bcx. ccx ( ) , t) ;
417
412
let drop_flag = adt:: trans_drop_flag_ptr ( bcx, repr, v0) ;
418
413
do with_cond( bcx, IsNotNull ( bcx, Load ( bcx, drop_flag) ) ) |cx| {
@@ -454,6 +449,49 @@ pub fn trans_struct_drop(bcx: block,
454
449
}
455
450
}
456
451
452
+ pub fn trans_struct_drop ( mut bcx : block , t : ty:: t , v0 : ValueRef , dtor_did : ast:: def_id ,
453
+ class_did : ast:: def_id , substs : & ty:: substs ) -> block {
454
+ let repr = adt:: represent_type ( bcx. ccx ( ) , t) ;
455
+
456
+ // Find and call the actual destructor
457
+ let dtor_addr = get_res_dtor ( bcx. ccx ( ) , dtor_did,
458
+ class_did, /*bad*/ copy substs. tps ) ;
459
+
460
+ // The second argument is the "self" argument for drop
461
+ let params = unsafe {
462
+ let ty = Type :: from_ref ( llvm:: LLVMTypeOf ( dtor_addr) ) ;
463
+ ty. element_type ( ) . func_params ( )
464
+ } ;
465
+
466
+ // Class dtors have no explicit args, so the params should
467
+ // just consist of the environment (self)
468
+ assert_eq ! ( params. len( ) , 1 ) ;
469
+
470
+ // Take a reference to the class (because it's using the Drop trait),
471
+ // do so now.
472
+ let llval = alloca ( bcx, val_ty ( v0) ) ;
473
+ Store ( bcx, v0, llval) ;
474
+
475
+ let self_arg = PointerCast ( bcx, llval, params[ 0 ] ) ;
476
+ let args = ~[ self_arg] ;
477
+
478
+ Call ( bcx, dtor_addr, args) ;
479
+
480
+ // Drop the fields
481
+ let field_tys = ty:: struct_fields ( bcx. tcx ( ) , class_did, substs) ;
482
+ for field_tys . iter( ) . enumerate( ) . advance |( i, fld) | {
483
+ let llfld_a = adt : : trans_field_ptr( bcx, repr, v0, 0 , i) ;
484
+ bcx = drop_ty( bcx, llfld_a, fld. mt. ty) ;
485
+ }
486
+
487
+ // Zero out the struct
488
+ unsafe {
489
+ let ty = Type :: from_ref( llvm:: LLVMTypeOf ( v0) ) ;
490
+ memzero( bcx, v0, ty) ;
491
+ }
492
+
493
+ bcx
494
+ }
457
495
458
496
pub fn make_drop_glue( bcx: block, v0: ValueRef , t: ty:: t) {
459
497
// NB: v0 is an *alias* of type t here, not a direct value.
@@ -474,7 +512,10 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
474
512
ty:: ty_struct( did, ref substs) => {
475
513
let tcx = bcx. tcx( ) ;
476
514
match ty:: ty_dtor( tcx, did) {
477
- ty:: TraitDtor ( dtor) => {
515
+ ty:: TraitDtor ( dtor, true ) => {
516
+ trans_struct_drop_flag( bcx, t, v0, dtor, did, substs)
517
+ }
518
+ ty:: TraitDtor ( dtor, false ) => {
478
519
trans_struct_drop( bcx, t, v0, dtor, did, substs)
479
520
}
480
521
ty:: NoDtor => {
0 commit comments