Convert type_of to use trans::adt.

This commit is contained in:
Jed Davis 2013-02-22 21:45:49 -08:00
parent c4682dcabe
commit 5e2302a56f

View File

@ -11,6 +11,7 @@
use lib::llvm::llvm;
use lib::llvm::{TypeRef};
use middle::trans::adt;
use middle::trans::base;
use middle::trans::common::*;
use middle::trans::common;
@ -143,32 +144,12 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_unboxed_vec(mt) => T_vec(cx, sizing_type_of(cx, mt.ty)),
ty::ty_tup(ref elems) => {
T_struct(elems.map(|&t| sizing_type_of(cx, t)))
ty::ty_tup(*) | ty::ty_rec(*) | ty::ty_struct(*)
| ty::ty_enum(*) => {
let repr = adt::represent_type(cx, t);
T_struct(adt::sizing_fields_of(cx, &repr))
}
ty::ty_rec(ref fields) => {
T_struct(fields.map(|f| sizing_type_of(cx, f.mt.ty)))
}
ty::ty_struct(def_id, ref substs) => {
let fields = ty::lookup_struct_fields(cx.tcx, def_id);
let lltype = T_struct(fields.map(|field| {
let field_type = ty::lookup_field_type(cx.tcx,
def_id,
field.id,
substs);
sizing_type_of(cx, field_type)
}));
if ty::ty_dtor(cx.tcx, def_id).is_present() {
T_struct(~[lltype, T_i8()])
} else {
lltype
}
}
ty::ty_enum(def_id, _) => T_struct(enum_body_types(cx, def_id, t)),
ty::ty_self | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => {
cx.tcx.sess.bug(
fmt!("fictitious type %? in sizing_type_of()",
@ -257,28 +238,13 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
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.push(type_of(cx, mt_ty));
}
// n.b.: introduce an extra layer of indirection to match
// structs
T_struct(~[T_struct(tys)])
}
ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
ty::ty_type => T_ptr(cx.tydesc_type),
ty::ty_tup(elts) => {
let mut tys = ~[];
for vec::each(elts) |elt| {
tys.push(type_of(cx, *elt));
}
T_struct(tys)
ty::ty_tup(*) | ty::ty_rec(*) => {
let repr = adt::represent_type(cx, t);
T_struct(adt::fields_of(cx, &repr))
}
ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx),
ty::ty_struct(did, ref substs) => {
@ -301,24 +267,9 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
// If this was an enum or struct, fill in the type now.
match ty::get(t).sty {
ty::ty_enum(did, _) => {
fill_type_of_enum(cx, did, t, llty);
}
ty::ty_struct(did, ref substs) => {
// Only instance vars are record fields at runtime.
let fields = ty::lookup_struct_fields(cx.tcx, did);
let mut tys = do vec::map(fields) |f| {
let t = ty::lookup_field_type(cx.tcx, did, f.id, substs);
type_of(cx, t)
};
// include a byte flag if there is a dtor so that we know when we've
// been dropped
if ty::ty_dtor(cx.tcx, did).is_present() {
common::set_struct_body(llty, ~[T_struct(tys), T_i8()]);
} else {
common::set_struct_body(llty, ~[T_struct(tys)]);
}
ty::ty_enum(*) | ty::ty_struct(*) => {
let repr = adt::represent_type(cx, t);
common::set_struct_body(llty, adt::fields_of(cx, &repr));
}
_ => ()
}
@ -326,34 +277,6 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
return llty;
}
pub fn enum_body_types(cx: @CrateContext, did: ast::def_id, t: ty::t)
-> ~[TypeRef] {
let univar = ty::enum_is_univariant(cx.tcx, did);
if !univar {
let size = machine::static_size_of_enum(cx, t);
~[T_enum_discrim(cx), T_array(T_i8(), size)]
}
else {
// Use the actual fields, so we get the alignment right.
match ty::get(t).sty {
ty::ty_enum(_, ref substs) => {
do ty::enum_variants(cx.tcx, did)[0].args.map |&field_ty| {
sizing_type_of(cx, ty::subst(cx.tcx, substs, field_ty))
}
}
_ => cx.sess.bug(~"enum is not an enum")
}
}
}
pub fn fill_type_of_enum(cx: @CrateContext,
did: ast::def_id,
t: ty::t,
llty: TypeRef) {
debug!("type_of_enum %?: %?", t, ty::get(t));
common::set_struct_body(llty, enum_body_types(cx, did, t));
}
// Want refinements! (Or case classes, I guess
pub enum named_ty { a_struct, an_enum }