@@ -406,13 +406,8 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
406406 build_return ( bcx) ;
407407}
408408
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 {
416411 let repr = adt:: represent_type ( bcx. ccx ( ) , t) ;
417412 let drop_flag = adt:: trans_drop_flag_ptr ( bcx, repr, v0) ;
418413 do with_cond( bcx, IsNotNull ( bcx, Load ( bcx, drop_flag) ) ) |cx| {
@@ -454,6 +449,49 @@ pub fn trans_struct_drop(bcx: block,
454449 }
455450}
456451
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+ }
457495
458496pub fn make_drop_glue( bcx: block, v0: ValueRef , t: ty:: t) {
459497 // 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) {
474512 ty:: ty_struct( did, ref substs) => {
475513 let tcx = bcx. tcx( ) ;
476514 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 ) => {
478519 trans_struct_drop( bcx, t, v0, dtor, did, substs)
479520 }
480521 ty:: NoDtor => {
0 commit comments