提交 b0217297 编写于 作者: T Tim Chevalier

Make trans give correct types to monomorphic dtors

Irritatingly, class dtors have a different type from resource
dtors (because class dtors have a self argument), and the monomorphic
case wasn't reflecting that. Fixed.
上级 00171165
......@@ -754,7 +754,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id,
// We have to cast v0
let classptr = GEPi(bcx, v0, [0u, 1u]);
// Find and call the actual destructor
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, substs.tps);
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, some(class_did),
substs.tps);
// The second argument is the "self" argument for drop
let params = lib::llvm::fn_ty_param_tys
(llvm::LLVMGetElementType
......@@ -829,7 +830,11 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
build_return(bcx);
}
fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
// Parent ID is an option because resources don't
// have one. We can make this a def_id when
// resources get removed.
opt_id: option<ast::def_id>, substs: [ty::t])
-> ValueRef {
let _icx = ccx.insn_ctxt("trans_res_dtor");
if (substs.len() > 0u) {
......@@ -841,14 +846,27 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
} else if did.crate == ast::local_crate {
get_item_val(ccx, did.node)
} else {
let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
proto: ast::proto_bare,
inputs: [{mode: ast::expl(ast::by_ref),
alt opt_id {
some(parent_id) {
let tcx = ccx.tcx;
let name = csearch::get_symbol(ccx.sess.cstore, did);
let class_ty = ty::subst_tps(tcx, substs,
ty::lookup_item_type(tcx, parent_id).ty);
let llty = type_of_dtor(ccx, class_ty);
get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv,
llty)
}
none {
let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
proto: ast::proto_bare,
inputs: [{mode: ast::expl(ast::by_ref),
ty: ty::mk_nil_ptr(ccx.tcx)}],
output: ty::mk_nil(ccx.tcx),
ret_style: ast::return_val,
constraints: []});
trans_external_path(ccx, did, fty)
trans_external_path(ccx, did, fty)
}
}
}
}
......@@ -862,7 +880,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) {|bcx|
let valptr = GEPi(bcx, rs, [0u, 1u]);
// Find and call the actual destructor.
let dtor_addr = get_res_dtor(ccx, did, tps);
let dtor_addr = get_res_dtor(ccx, did, none, tps);
let args = [bcx.fcx.llretptr, null_env_ptr(bcx)];
// Kludge to work around the fact that we know the precise type of the
// value here, but the dtor expects a type that might have opaque
......
......@@ -21,12 +21,14 @@
import ty_ctxt = middle::ty::ctxt;
type nominal_id = @{did: ast::def_id, tps: [ty::t]};
type nominal_id = @{did: ast::def_id, parent_id: option<ast::def_id>,
tps: [ty::t]};
fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id,
parent_id: option<ast::def_id>,
tps: [ty::t]) -> nominal_id {
let tps_norm = tps.map { |t| ty::normalize_ty(tcx, t) };
@{did: did, tps: tps_norm}
@{did: did, parent_id: parent_id, tps: tps_norm}
}
fn hash_nominal_id(&&ri: nominal_id) -> uint {
......@@ -233,7 +235,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
tk_enum { [s_variant_enum_t(ccx.tcx)] }
tk_newtype | tk_complex {
let mut s = [shape_enum], id;
let nom_id = mk_nominal_id(ccx.tcx, did, substs.tps);
let nom_id = mk_nominal_id(ccx.tcx, did, none, substs.tps);
alt ccx.shape_cx.tag_id_to_index.find(nom_id) {
none {
id = ccx.shape_cx.next_tag_id;
......@@ -335,7 +337,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
else { [shape_struct] };
let mut sub = [];
option::iter(m_dtor_did) {|dtor_did|
let ri = @{did: dtor_did, tps: tps};
let ri = @{did: dtor_did, parent_id: some(did), tps: tps};
let id = interner::intern(ccx.shape_cx.resources, ri);
add_u16(s, id as u16);
......@@ -362,7 +364,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
for substs.tps.each() {|t| assert !ty::type_has_params(t); }
let subt = ty::subst(ccx.tcx, substs, raw_subt);
let tps = substs.tps;
let ri = @{did: did, tps: tps};
let ri = @{did: did, parent_id: none, tps: tps};
let id = interner::intern(ccx.shape_cx.resources, ri);
let mut s = [shape_res];
......@@ -597,7 +599,8 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef {
for uint::range(0u, len) {|i|
let ri = interner::get(ccx.shape_cx.resources, i);
for ri.tps.each() {|s| assert !ty::type_has_params(s); }
dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.tps)];
dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.parent_id,
ri.tps)];
}
ret mk_global(ccx, "resource_shapes", C_struct(dtors), true);
}
......
......@@ -8,6 +8,7 @@
import ty::*;
export type_of;
export type_of_dtor;
export type_of_explicit_args;
export type_of_fn_from_ty;
export type_of_fn;
......@@ -251,3 +252,9 @@ fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str {
);
}
fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef {
T_fn([T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))),
T_ptr(type_of(ccx, self_ty))],
llvm::LLVMVoidType())
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册