Revert "rustc: Use LLVM named structs for enum types"
This reverts commit 6e909e387d
.
This commit is contained in:
parent
b88ecec08c
commit
5a0c564817
@ -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);
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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); }
|
||||
|
Loading…
Reference in New Issue
Block a user