Revert "rustc: Use LLVM named structs for enum types"

This reverts commit 6e909e387d.
This commit is contained in:
Brian Anderson 2012-04-24 20:47:06 -07:00
parent b88ecec08c
commit 5a0c564817
4 changed files with 94 additions and 179 deletions

View File

@ -2243,8 +2243,7 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id)-> lval_maybe_callee {
// Nullary variant.
let enum_ty = node_id_type(cx, id);
let llenumblob = alloc_ty(cx, enum_ty);
// FIXME: This pointer cast probably isn't necessary
let llenumty = type_of(ccx, enum_ty);
let llenumty = type_of_enum(ccx, tid, enum_ty);
let llenumptr = PointerCast(cx, llenumblob, T_ptr(llenumty));
let lldiscrimptr = GEPi(cx, llenumptr, [0, 0]);
let lldiscrim_gv = lookup_discriminant(ccx, vid);

View File

@ -7,11 +7,6 @@ import std::map::hashmap;
import ty::*;
export type_of;
export type_of_explicit_args;
export type_of_fn_from_ty;
export type_of_fn;
fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] {
vec::map(inputs) {|arg|
let arg_ty = arg.ty;
@ -44,149 +39,93 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef {
fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
assert !ty::type_has_vars(t);
#debug("type_of %?: %?", t, ty::get(t));
// Check the cache.
if cx.lltypes.contains_key(t) { ret cx.lltypes.get(t); }
let llty = alt ty::get(t).struct {
ty::ty_nil | ty::ty_bot { T_nil() }
ty::ty_bool { T_bool() }
ty::ty_int(t) { T_int_ty(cx, t) }
ty::ty_uint(t) { T_uint_ty(cx, t) }
ty::ty_float(t) { T_float_ty(cx, t) }
ty::ty_estr(ty::vstore_uniq) |
ty::ty_str { T_ptr(T_vec(cx, T_i8())) }
ty::ty_enum(did, _) { type_of_enum(cx, did, t) }
ty::ty_estr(ty::vstore_box) { T_ptr(T_box(cx, T_i8())) }
ty::ty_evec(mt, ty::vstore_box) |
ty::ty_box(mt) { T_ptr(T_box(cx, type_of(cx, mt.ty))) }
ty::ty_opaque_box { T_ptr(T_box(cx, T_i8())) }
ty::ty_uniq(mt) { T_ptr(type_of(cx, mt.ty)) }
ty::ty_evec(mt, ty::vstore_uniq) |
ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) }
ty::ty_ptr(mt) { T_ptr(type_of(cx, mt.ty)) }
ty::ty_rptr(_, mt) { T_ptr(type_of(cx, mt.ty)) }
// Replace any typedef'd types with their equivalent non-typedef
// type. This ensures that all LLVM nominal types that contain
// Rust types are defined as the same LLVM types. If we don't do
// this then, e.g. `option<{myfield: bool}>` would be a different
// type than `option<myrec>`.
let t_norm = ty::normalize_ty(cx.tcx, t);
let llty = if t != t_norm {
type_of(cx, t_norm)
} else {
alt ty::get(t).struct {
ty::ty_nil | ty::ty_bot { T_nil() }
ty::ty_bool { T_bool() }
ty::ty_int(t) { T_int_ty(cx, t) }
ty::ty_uint(t) { T_uint_ty(cx, t) }
ty::ty_float(t) { T_float_ty(cx, t) }
ty::ty_estr(ty::vstore_uniq) |
ty::ty_str { T_ptr(T_vec(cx, T_i8())) }
ty::ty_enum(did, _) { type_of_enum(cx, did, t) }
ty::ty_estr(ty::vstore_box) { T_ptr(T_box(cx, T_i8())) }
ty::ty_evec(mt, ty::vstore_box) |
ty::ty_box(mt) { T_ptr(T_box(cx, type_of(cx, mt.ty))) }
ty::ty_opaque_box { T_ptr(T_box(cx, T_i8())) }
ty::ty_uniq(mt) { T_ptr(type_of(cx, mt.ty)) }
ty::ty_evec(mt, ty::vstore_uniq) |
ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) }
ty::ty_ptr(mt) { T_ptr(type_of(cx, mt.ty)) }
ty::ty_rptr(_, mt) { T_ptr(type_of(cx, mt.ty)) }
ty::ty_evec(mt, ty::vstore_slice(_)) {
T_struct([T_ptr(type_of(cx, mt.ty)),
T_uint_ty(cx, ast::ty_u)])
}
ty::ty_evec(mt, ty::vstore_slice(_)) {
T_struct([T_ptr(type_of(cx, mt.ty)),
T_uint_ty(cx, ast::ty_u)])
}
ty::ty_estr(ty::vstore_slice(_)) {
T_struct([T_ptr(T_i8()),
T_uint_ty(cx, ast::ty_u)])
}
ty::ty_estr(ty::vstore_slice(_)) {
T_struct([T_ptr(T_i8()),
T_uint_ty(cx, ast::ty_u)])
}
ty::ty_estr(ty::vstore_fixed(n)) {
T_array(T_i8(), n + 1u /* +1 for trailing null */)
}
ty::ty_estr(ty::vstore_fixed(n)) {
T_array(T_i8(), n + 1u /* +1 for trailing null */)
}
ty::ty_evec(mt, ty::vstore_fixed(n)) {
T_array(type_of(cx, mt.ty), n)
}
ty::ty_evec(mt, ty::vstore_fixed(n)) {
T_array(type_of(cx, mt.ty), n)
}
ty::ty_rec(fields) {
let mut tys: [TypeRef] = [];
for vec::each(fields) {|f|
let mt_ty = f.mt.ty;
tys += [type_of(cx, mt_ty)];
}
T_struct(tys)
}
ty::ty_fn(_) { T_fn_pair(cx, type_of_fn_from_ty(cx, t)) }
ty::ty_iface(_, _) { T_opaque_iface(cx) }
ty::ty_res(_, sub, substs) {
let sub1 = ty::subst(cx.tcx, substs, sub);
ret T_struct([T_i8(), type_of(cx, sub1)]);
}
ty::ty_param(_, _) { T_typaram(cx.tn) }
ty::ty_type { T_ptr(cx.tydesc_type) }
ty::ty_tup(elts) {
let mut tys = [];
for vec::each(elts) {|elt|
tys += [type_of(cx, elt)];
}
T_struct(tys)
}
ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) }
ty::ty_constr(subt,_) { type_of(cx, subt) }
ty::ty_class(did, ts) {
// only instance vars are record fields at runtime
let fields = lookup_class_fields(cx.tcx, did);
let tys = vec::map(fields) {|f|
let t = ty::lookup_field_type(cx.tcx, did, f.id, ts);
type_of(cx, t)
};
T_struct(tys)
}
ty::ty_self(_) { cx.tcx.sess.unimpl("type_of: ty_self \
not implemented"); }
ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); }
ty::ty_rec(fields) {
let mut tys: [TypeRef] = [];
for vec::each(fields) {|f|
let mt_ty = f.mt.ty;
tys += [type_of(cx, mt_ty)];
}
T_struct(tys)
}
ty::ty_fn(_) { T_fn_pair(cx, type_of_fn_from_ty(cx, t)) }
ty::ty_iface(_, _) { T_opaque_iface(cx) }
ty::ty_res(_, sub, substs) {
let sub1 = ty::subst(cx.tcx, substs, sub);
ret T_struct([T_i8(), type_of(cx, sub1)]);
}
ty::ty_param(_, _) { T_typaram(cx.tn) }
ty::ty_type { T_ptr(cx.tydesc_type) }
ty::ty_tup(elts) {
let mut tys = [];
for vec::each(elts) {|elt|
tys += [type_of(cx, elt)];
}
T_struct(tys)
}
ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) }
ty::ty_constr(subt,_) { type_of(cx, subt) }
ty::ty_class(did, ts) {
// only instance vars are record fields at runtime
let fields = lookup_class_fields(cx.tcx, did);
let tys = vec::map(fields) {|f|
let t = ty::lookup_field_type(cx.tcx, did, f.id, ts);
type_of(cx, t)
};
T_struct(tys)
}
ty::ty_self(_) { cx.tcx.sess.unimpl("type_of: ty_self \
not implemented"); }
ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); }
};
cx.lltypes.insert(t, llty);
ret llty;
}
// This should only be called from type_of, above, because it
// creates new llvm named struct types lazily that are then
// cached by type_of
fn type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t)
-> TypeRef {
#debug("type_of_enum %?: %?", t, ty::get(t));
// Every enum type has a unique name. When we find our roots
// for GC and unwinding we will use this name to rediscover
// the Rust type
let name = llvm_type_name(cx, t);
let named_llty = common::T_named_struct(name);
let lltys = {
let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u;
let size = shape::static_size_of_enum(cx, t);
if !degen {
[T_enum_variant(cx), T_array(T_i8(), size)]
}
else if size == 0u {
[T_enum_variant(cx)]
}
else {
[T_array(T_i8(), size)]
}
};
common::set_struct_body(named_llty, lltys);
ret named_llty;
let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u;
let size = shape::static_size_of_enum(cx, t);
if !degen { T_enum(cx, size) }
else if size == 0u { T_struct([T_enum_variant(cx)]) }
else { T_array(T_i8(), size) }
}
fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str {
let (name, did, tps) = alt check ty::get(t).struct {
ty::ty_enum(did, substs) {
("enum", did, substs.tps)
}
};
ret #fmt(
"%s %s[#%d]",
name,
util::ppaux::parameterized(
cx.tcx,
ty::item_path_str(cx.tcx, did),
none,
tps),
did.crate
);
}

View File

@ -149,7 +149,6 @@ export ast_ty_to_ty_cache_entry;
export atttce_unresolved, atttce_resolved;
export mach_sty;
export ty_sort_str;
export normalize_ty;
// Data types
@ -2675,27 +2674,6 @@ fn ty_params_to_tys(tcx: ty::ctxt, tps: [ast::ty_param]) -> [t] {
ty::mk_param(tcx, i, ast_util::local_def(tps[i].id))
})
}
#[doc = "
Returns an equivalent type with all the typedefs and self regions removed
"]
fn normalize_ty(cx: ctxt, t: t) -> t {
let t = alt get(t).struct {
ty_enum(did, r) {
alt r.self_r {
some(_) {
// This enum has a self region. Get rid of it
mk_enum(cx, did, {self_r: none, tps: r.tps })
}
none { t }
}
}
_ { t }
};
let sty = fold_sty(get(t).struct) {|t| normalize_ty(cx, t) };
mk_t(cx, sty)
}
// Local Variables:
// mode: rust
// fill-column: 78;

View File

@ -128,6 +128,25 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
fn field_to_str(cx: ctxt, f: field) -> str {
ret f.ident + ": " + mt_to_str(cx, f.mt);
}
fn parameterized(cx: ctxt,
base: str,
self_r: option<ty::region>,
tps: [ty::t]) -> str {
let r_str = alt self_r {
none { "" }
some(r) {
#fmt["/%s", region_to_str(cx, r)]
}
};
if vec::len(tps) > 0u {
let strs = vec::map(tps, {|t| ty_to_str(cx, t)});
#fmt["%s%s<%s>", base, r_str, str::connect(strs, ",")]
} else {
#fmt["%s%s", base, r_str]
}
}
// if there is an id, print that instead of the structural type:
alt ty::type_def_id(typ) {
@ -214,26 +233,6 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
}
}
fn parameterized(cx: ctxt,
base: str,
self_r: option<ty::region>,
tps: [ty::t]) -> str {
let r_str = alt self_r {
none { "" }
some(r) {
#fmt["/%s", region_to_str(cx, r)]
}
};
if vec::len(tps) > 0u {
let strs = vec::map(tps, {|t| ty_to_str(cx, t)});
#fmt["%s%s<%s>", base, r_str, str::connect(strs, ",")]
} else {
#fmt["%s%s", base, r_str]
}
}
fn ty_to_short_str(cx: ctxt, typ: t) -> str {
let mut s = encoder::encoded_ty(cx, typ);
if str::len(s) >= 32u { s = str::slice(s, 0u, 32u); }