} else {
v
};
- Call(bcx, glue, [ptr], []);
+ Call(bcx, glue, [ptr], None);
}
bcx
}
let llfn = Load(bcx, GEPi(bcx, tydesc, [0u, abi::tydesc_field_visit_glue]));
let llrawptr = PointerCast(bcx, v, Type::i8p(bcx.ccx()));
- Call(bcx, llfn, [llrawptr], []);
+ Call(bcx, llfn, [llrawptr], None);
}
fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
bcx
}
-fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
+fn trans_struct_drop_flag<'a>(mut bcx: &'a Block<'a>,
t: ty::t,
v0: ValueRef,
dtor_did: ast::DefId,
substs: &subst::Substs)
-> &'a Block<'a> {
let repr = adt::represent_type(bcx.ccx(), t);
- let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0);
- with_cond(bcx, load_ty(bcx, drop_flag, ty::mk_bool()), |cx| {
+ let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, v0));
+ with_cond(bcx, load_ty(bcx, drop_flag.val, ty::mk_bool()), |cx| {
trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
})
}
ty.element_type().func_params()
};
- // Class dtors have no explicit args, so the params should
- // just consist of the environment (self)
- assert_eq!(params.len(), 1);
-
- // Be sure to put all of the fields into a scope so we can use an invoke
- // instruction to call the user destructor but still call the field
- // destructors if the user destructor fails.
- let field_scope = bcx.fcx.push_custom_cleanup_scope();
-
- let self_arg = PointerCast(bcx, v0, *params.get(0));
- let args = vec!(self_arg);
-
- // Add all the fields as a value which needs to be cleaned at the end of
- // this scope.
- let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs);
- for (i, fld) in field_tys.iter().enumerate() {
- let llfld_a = adt::trans_field_ptr(bcx, &*repr, v0, 0, i);
- bcx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
- llfld_a,
- fld.mt.ty);
- }
+ adt::fold_variants(bcx, &*repr, v0, |variant_cx, st, value| {
+ // Be sure to put all of the fields into a scope so we can use an invoke
+ // instruction to call the user destructor but still call the field
+ // destructors if the user destructor fails.
+ let field_scope = variant_cx.fcx.push_custom_cleanup_scope();
+
+ // Class dtors have no explicit args, so the params should
+ // just consist of the environment (self).
+ assert_eq!(params.len(), 1);
+ let self_arg = PointerCast(variant_cx, value, *params.get(0));
+ let args = vec!(self_arg);
+
+ // Add all the fields as a value which needs to be cleaned at the end of
+ // this scope.
+ for (i, ty) in st.fields.iter().enumerate() {
+ let llfld_a = adt::struct_field_ptr(variant_cx, &*st, value, i, false);
+ variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
+ llfld_a, *ty);
+ }
- let dtor_ty = ty::mk_ctor_fn(bcx.tcx(), ast::DUMMY_NODE_ID,
- [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil());
- let (_, bcx) = invoke(bcx, dtor_addr, args, dtor_ty, None);
+ let dtor_ty = ty::mk_ctor_fn(variant_cx.tcx(), ast::DUMMY_NODE_ID,
+ [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil());
+ let (_, variant_cx) = invoke(variant_cx, dtor_addr, args, dtor_ty, None);
- bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, field_scope)
+ variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
+ variant_cx
+ })
}
fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'a> {
Call(bcx,
dtor,
[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
- []);
+ None);
bcx
})
}
}
}
}
- ty::ty_struct(did, ref substs) => {
+ ty::ty_struct(did, ref substs) | ty::ty_enum(did, ref substs) => {
let tcx = bcx.tcx();
match ty::ty_dtor(tcx, did) {
ty::TraitDtor(dtor, true) => {
let dtor_ptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
let dtor = Load(bcx, dtor_ptr);
let cdata = GEPi(bcx, env, [0u, abi::box_field_body]);
- Call(bcx, dtor, [PointerCast(bcx, cdata, Type::i8p(bcx.ccx()))], []);
+ Call(bcx, dtor, [PointerCast(bcx, cdata, Type::i8p(bcx.ccx()))], None);
// Free the environment itself
// FIXME: #13994: pass align and size here
let arena = TypedArena::new();
let empty_param_substs = param_substs::empty();
let fcx = new_fn_ctxt(ccx, llfn, -1, false, ty::mk_nil(),
- &empty_param_substs, None, &arena);
+ &empty_param_substs, None, &arena, TranslateItems);
let bcx = init_function(&fcx, false, ty::mk_nil());