diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-02-21 15:22:55 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-02-21 17:08:14 +0100 |
| commit | 92a45f5582ed8ea4eb439ea2eada31e228d8fe6b (patch) | |
| tree | e5f36ba47d8e3ba7272f2eaf505154a71b529343 | |
| parent | d85d4f55f7f7cf35dfbf39979a72062f4181f9ed (diff) | |
| download | rust-92a45f5582ed8ea4eb439ea2eada31e228d8fe6b.tar.gz rust-92a45f5582ed8ea4eb439ea2eada31e228d8fe6b.zip | |
Move trans::type_of code into its own file
Slowly shrinking base.rs
| -rw-r--r-- | src/comp/middle/trans/alt.rs | 2 | ||||
| -rw-r--r-- | src/comp/middle/trans/base.rs | 252 | ||||
| -rw-r--r-- | src/comp/middle/trans/closure.rs | 2 | ||||
| -rw-r--r-- | src/comp/middle/trans/common.rs | 13 | ||||
| -rw-r--r-- | src/comp/middle/trans/impl.rs | 1 | ||||
| -rw-r--r-- | src/comp/middle/trans/native.rs | 3 | ||||
| -rw-r--r-- | src/comp/middle/trans/shape.rs | 12 | ||||
| -rw-r--r-- | src/comp/middle/trans/tvec.rs | 10 | ||||
| -rw-r--r-- | src/comp/middle/trans/type_of.rs | 145 | ||||
| -rw-r--r-- | src/comp/middle/trans/uniq.rs | 2 | ||||
| -rw-r--r-- | src/comp/rustc.rc | 1 |
11 files changed, 223 insertions, 220 deletions
diff --git a/src/comp/middle/trans/alt.rs b/src/comp/middle/trans/alt.rs index 19966559dcc..2057296d197 100644 --- a/src/comp/middle/trans/alt.rs +++ b/src/comp/middle/trans/alt.rs @@ -686,7 +686,7 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef, ast::pat_ident(_,inner) { if make_copy || ccx.copy_map.contains_key(pat.id) { let ty = node_id_type(bcx, pat.id); - let llty = type_of(ccx, ty); + let llty = type_of::type_of(ccx, ty); let alloc = alloca(bcx, llty); bcx = copy_val(bcx, INIT, alloc, load_if_immediate(bcx, val, ty), ty); diff --git a/src/comp/middle/trans/base.rs b/src/comp/middle/trans/base.rs index b426e193efb..eb25415357a 100644 --- a/src/comp/middle/trans/base.rs +++ b/src/comp/middle/trans/base.rs @@ -44,157 +44,80 @@ import util::ppaux::{ty_to_str, ty_to_short_str}; import common::*; import build::*; import shape::*; +import type_of::*; +import type_of::type_of; // Issue #1873 import ast_map::{path, path_mod, path_name}; -fn type_of_explicit_args(cx: crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { - vec::map(inputs) {|arg| - let arg_ty = arg.ty; - let llty = type_of(cx, arg_ty); - alt ty::resolved_mode(cx.tcx, arg.mode) { - ast::by_val { llty } - _ { T_ptr(llty) } - } - } -} +// Destinations +// These are passed around by the code generating functions to track the +// destination of a computation's value. -// NB: must keep 4 fns in sync: -// -// - type_of_fn -// - create_llargs_for_fn_args. -// - new_fn_ctxt -// - trans_args -fn type_of_fn(cx: crate_ctxt, inputs: [ty::arg], - output: ty::t, params: [ty::param_bounds]) -> TypeRef { - let atys: [TypeRef] = []; +enum dest { + by_val(@mutable ValueRef), + save_in(ValueRef), + ignore, +} - // Arg 0: Output pointer. - atys += [T_ptr(type_of(cx, output))]; +fn empty_dest_cell() -> @mutable ValueRef { + ret @mutable llvm::LLVMGetUndef(T_nil()); +} - // Arg 1: Environment - atys += [T_opaque_box_ptr(cx)]; +fn dup_for_join(dest: dest) -> dest { + alt dest { + by_val(_) { by_val(empty_dest_cell()) } + _ { dest } + } +} - // Args >2: ty params, if not acquired via capture... - for bounds in params { - atys += [T_ptr(cx.tydesc_type)]; - for bound in *bounds { - alt bound { - ty::bound_iface(_) { atys += [T_ptr(T_dict())]; } +fn join_returns(parent_cx: block, in_cxs: [block], + in_ds: [dest], out_dest: dest) -> block { + let out = sub_block(parent_cx, "join"); + let reachable = false, i = 0u, phi = none; + for cx in in_cxs { + if !cx.unreachable { + Br(cx, out.llbb); + reachable = true; + alt in_ds[i] { + by_val(cell) { + if option::is_none(phi) { + phi = some(EmptyPhi(out, val_ty(*cell))); + } + AddIncomingToPhi(option::get(phi), *cell, cx.llbb); + } _ {} } } + i += 1u; } - // ... then explicit args. - atys += type_of_explicit_args(cx, inputs); - ret T_fn(atys, llvm::LLVMVoidType()); -} - -// Given a function type and a count of ty params, construct an llvm type -fn type_of_fn_from_ty(cx: crate_ctxt, fty: ty::t, - param_bounds: [ty::param_bounds]) -> TypeRef { - type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty), param_bounds) -} - -fn type_of(cx: crate_ctxt, t: ty::t) -> TypeRef { - assert !ty::type_has_vars(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_str { T_ptr(T_vec(cx, T_i8())) } - ty::ty_enum(did, _) { type_of_enum(cx, did, t) } - ty::ty_box(mt) { - let mt_ty = mt.ty; - 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) { - let mt_ty = mt.ty; - T_ptr(type_of(cx, mt_ty)) } - ty::ty_vec(mt) { - let mt_ty = mt.ty; - if ty::type_has_dynamic_size(cx.tcx, mt_ty) { - T_ptr(cx.opaque_vec_type) - } else { - T_ptr(T_vec(cx, type_of(cx, mt_ty))) } - } - ty::ty_ptr(mt) { - let mt_ty = mt.ty; - T_ptr(type_of(cx, mt_ty)) } - ty::ty_rec(fields) { - let tys: [TypeRef] = []; - for f: ty::field in fields { - 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, tps) { - let sub1 = ty::substitute_type_params(cx.tcx, tps, sub); - ret T_struct([T_i8(), type_of(cx, sub1)]); - } - ty::ty_param(_, _) { T_typaram(cx.tn) } - ty::ty_send_type | ty::ty_type { T_ptr(cx.tydesc_type) } - ty::ty_tup(elts) { - let tys = []; - for elt in elts { - tys += [type_of(cx, elt)]; + if !reachable { + Unreachable(out); + } else { + alt out_dest { + by_val(cell) { *cell = option::get(phi); } + _ {} } - T_struct(tys) - } - ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) } - ty::ty_constr(subt,_) { type_of(cx, subt) } - - _ { fail "type_of not implemented for this kind of type"; } - }; - cx.lltypes.insert(t, llty); - ret llty; -} - -fn type_of_enum(cx: crate_ctxt, did: ast::def_id, t: ty::t) - -> TypeRef { - let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u; - if check type_has_static_size(cx, t) { - let size = 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) } - } - else { - if degen { T_struct([T_enum_variant(cx)]) } - else { T_opaque_enum(cx) } } + ret out; } -fn type_of_ty_param_bounds_and_ty - (ccx: crate_ctxt, tpt: ty::ty_param_bounds_and_ty) -> TypeRef { - let t = tpt.ty; - alt ty::get(t).struct { - ty::ty_fn(_) { - ret type_of_fn_from_ty(ccx, t, *tpt.bounds); - } - _ { - // fall through - } +// Used to put an immediate value in a dest. +fn store_in_dest(bcx: block, val: ValueRef, dest: dest) -> block { + alt dest { + ignore {} + by_val(cell) { *cell = val; } + save_in(addr) { Store(bcx, val, addr); } } - type_of(ccx, t) + ret bcx; } -fn type_of_or_i8(ccx: crate_ctxt, typ: ty::t) -> TypeRef { - if check type_has_static_size(ccx, typ) { - type_of(ccx, typ) - } else { T_i8() } +fn get_dest_addr(dest: dest) -> ValueRef { + alt dest { + save_in(a) { a } + _ { fail "get_dest_addr: not a save_in"; } + } } - // Name sanitation. LLVM will happily accept identifiers with weird names, but // gas doesn't! fn sanitize(s: str) -> str { @@ -1886,8 +1809,6 @@ fn trans_lazy_binop(bcx: block, op: lazy_binop_ty, a: @ast::expr, ret store_in_dest(join, phi, dest); } - - fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr, rhs: @ast::expr, dest: dest, ex: @ast::expr) -> block { // User-defined operators @@ -1921,71 +1842,6 @@ fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr, } } -enum dest { - by_val(@mutable ValueRef), - save_in(ValueRef), - ignore, -} - -fn empty_dest_cell() -> @mutable ValueRef { - ret @mutable llvm::LLVMGetUndef(T_nil()); -} - -fn dup_for_join(dest: dest) -> dest { - alt dest { - by_val(_) { by_val(empty_dest_cell()) } - _ { dest } - } -} - -fn join_returns(parent_cx: block, in_cxs: [block], - in_ds: [dest], out_dest: dest) -> block { - let out = sub_block(parent_cx, "join"); - let reachable = false, i = 0u, phi = none; - for cx in in_cxs { - if !cx.unreachable { - Br(cx, out.llbb); - reachable = true; - alt in_ds[i] { - by_val(cell) { - if option::is_none(phi) { - phi = some(EmptyPhi(out, val_ty(*cell))); - } - AddIncomingToPhi(option::get(phi), *cell, cx.llbb); - } - _ {} - } - } - i += 1u; - } - if !reachable { - Unreachable(out); - } else { - alt out_dest { - by_val(cell) { *cell = option::get(phi); } - _ {} - } - } - ret out; -} - -// Used to put an immediate value in a dest. -fn store_in_dest(bcx: block, val: ValueRef, dest: dest) -> block { - alt dest { - ignore {} - by_val(cell) { *cell = val; } - save_in(addr) { Store(bcx, val, addr); } - } - ret bcx; -} - -fn get_dest_addr(dest: dest) -> ValueRef { - alt dest { - save_in(a) { a } - _ { fail "get_dest_addr: not a save_in"; } - } -} - fn trans_if(cx: block, cond: @ast::expr, thn: ast::blk, els: option<@ast::expr>, dest: dest) -> block { diff --git a/src/comp/middle/trans/closure.rs b/src/comp/middle/trans/closure.rs index 4e915bc9b54..cde07aeedc4 100644 --- a/src/comp/middle/trans/closure.rs +++ b/src/comp/middle/trans/closure.rs @@ -6,6 +6,8 @@ import lib::llvm::{ValueRef, TypeRef}; import common::*; import build::*; import base::*; +import type_of::*; +import type_of::type_of; // Issue #1873 import middle::freevars::{get_freevars, freevar_info}; import back::abi; import syntax::codemap::span; diff --git a/src/comp/middle/trans/common.rs b/src/comp/middle/trans/common.rs index c6b5f4f9c17..a5d83906749 100644 --- a/src/comp/middle/trans/common.rs +++ b/src/comp/middle/trans/common.rs @@ -20,9 +20,6 @@ import lib::llvm::{True, False, Bool}; import metadata::csearch; import ast_map::path; -// FIXME: These should probably be pulled in here too. -import base::{type_of_fn, drop_ty}; - type namegen = fn@(str) -> str; fn new_namegen() -> namegen { let i = @mutable 0; @@ -231,7 +228,7 @@ fn scope_clean_changed(info: scope_info) { fn add_clean(cx: block, val: ValueRef, ty: ty::t) { if !ty::type_needs_drop(cx.tcx(), ty) { ret; } in_scope_cx(cx) {|info| - info.cleanups += [clean(bind drop_ty(_, val, ty))]; + info.cleanups += [clean(bind base::drop_ty(_, val, ty))]; scope_clean_changed(info); } } @@ -242,7 +239,7 @@ fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) { if ty::type_is_immediate(ty) { ret base::drop_ty_immediate(bcx, val, ty); } else { - ret drop_ty(bcx, val, ty); + ret base::drop_ty(bcx, val, ty); } } in_scope_cx(cx) {|info| @@ -253,7 +250,7 @@ fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) { fn add_clean_temp_mem(cx: block, val: ValueRef, ty: ty::t) { if !ty::type_needs_drop(cx.tcx(), ty) { ret; } in_scope_cx(cx) {|info| - info.cleanups += [clean_temp(val, bind drop_ty(_, val, ty))]; + info.cleanups += [clean_temp(val, bind base::drop_ty(_, val, ty))]; scope_clean_changed(info); } } @@ -301,8 +298,8 @@ fn get_res_dtor(ccx: crate_ctxt, did: ast::def_id, inner_t: ty::t) let param_bounds = ty::lookup_item_type(ccx.tcx, did).bounds; let nil_res = ty::mk_nil(ccx.tcx); let fn_mode = ast::expl(ast::by_ref); - let f_t = type_of_fn(ccx, [{mode: fn_mode, ty: inner_t}], - nil_res, *param_bounds); + let f_t = type_of::type_of_fn(ccx, [{mode: fn_mode, ty: inner_t}], + nil_res, *param_bounds); ret base::get_extern_const(ccx.externs, ccx.llmod, csearch::get_symbol(ccx.sess.cstore, did), f_t); diff --git a/src/comp/middle/trans/impl.rs b/src/comp/middle/trans/impl.rs index 9cb686c5def..45c9499f197 100644 --- a/src/comp/middle/trans/impl.rs +++ b/src/comp/middle/trans/impl.rs @@ -1,6 +1,7 @@ import ctypes::c_uint; import base::*; import common::*; +import type_of::*; import build::*; import driver::session::session; import syntax::{ast, ast_util}; diff --git a/src/comp/middle/trans/native.rs b/src/comp/middle/trans/native.rs index e2ab63302b7..22791047ef9 100644 --- a/src/comp/middle/trans/native.rs +++ b/src/comp/middle/trans/native.rs @@ -8,6 +8,7 @@ import back::link; import common::*; import build::*; import base::*; +import type_of::*; export link_name, trans_native_mod, register_crust_fn, trans_crust_fn; @@ -31,7 +32,7 @@ fn c_arg_and_ret_lltys(ccx: crate_ctxt, alt ty::get(ty::node_id_to_type(ccx.tcx, id)).struct { ty::ty_fn({inputs: arg_tys, output: ret_ty, _}) { let llargtys = type_of_explicit_args(ccx, arg_tys); - let llretty = type_of(ccx, ret_ty); + let llretty = type_of::type_of(ccx, ret_ty); (llargtys, llretty, ret_ty) } _ { ccx.sess.bug("c_arg_and_ret_lltys called on non-function type"); } diff --git a/src/comp/middle/trans/shape.rs b/src/comp/middle/trans/shape.rs index 8bdb6d63a4f..2805778e927 100644 --- a/src/comp/middle/trans/shape.rs +++ b/src/comp/middle/trans/shape.rs @@ -118,7 +118,7 @@ fn largest_variants(ccx: crate_ctxt, tag_id: ast::def_id) -> [uint] { // when in fact it has minimum size sizeof(int). bounded = false; } else { - let llty = base::type_of(ccx, elem_t); + let llty = type_of::type_of(ccx, elem_t); min_size += llsize_of_real(ccx, llty); min_align += llalign_of_real(ccx, llty); } @@ -188,7 +188,7 @@ fn compute_static_enum_size(ccx: crate_ctxt, largest_variants: [uint], // We increment a "virtual data pointer" to compute the size. let lltys = []; for typ: ty::t in variants[vid].args { - lltys += [base::type_of(ccx, typ)]; + lltys += [type_of::type_of(ccx, typ)]; } let llty = trans::common::T_struct(lltys); @@ -590,7 +590,7 @@ type tag_metrics = { fn size_of(bcx: block, t: ty::t) -> result { let ccx = bcx.ccx(); if check type_has_static_size(ccx, t) { - rslt(bcx, llsize_of(ccx, base::type_of(ccx, t))) + rslt(bcx, llsize_of(ccx, type_of::type_of(ccx, t))) } else { let { bcx, sz, align: _ } = dynamic_metrics(bcx, t); rslt(bcx, sz) @@ -600,7 +600,7 @@ fn size_of(bcx: block, t: ty::t) -> result { fn align_of(bcx: block, t: ty::t) -> result { let ccx = bcx.ccx(); if check type_has_static_size(ccx, t) { - rslt(bcx, llalign_of(ccx, base::type_of(ccx, t))) + rslt(bcx, llalign_of(ccx, type_of::type_of(ccx, t))) } else { let { bcx, sz: _, align } = dynamic_metrics(bcx, t); rslt(bcx, align) @@ -610,7 +610,7 @@ fn align_of(bcx: block, t: ty::t) -> result { fn metrics(bcx: block, t: ty::t) -> metrics { let ccx = bcx.ccx(); if check type_has_static_size(ccx, t) { - let llty = base::type_of(ccx, t); + let llty = type_of::type_of(ccx, t); { bcx: bcx, sz: llsize_of(ccx, llty), align: llalign_of(ccx, llty) } } else { dynamic_metrics(bcx, t) @@ -657,7 +657,7 @@ fn static_size_of_enum(cx: crate_ctxt, t: ty::t) -> uint { tup_ty = ty::substitute_type_params(cx.tcx, subtys, tup_ty); // Here we possibly do a recursive call. let this_size = - llsize_of_real(cx, base::type_of(cx, tup_ty)); + llsize_of_real(cx, type_of::type_of(cx, tup_ty)); if max_size < this_size { max_size = this_size; } } cx.enum_sizes.insert(t, max_size); diff --git a/src/comp/middle/trans/tvec.rs b/src/comp/middle/trans/tvec.rs index a48b5403d1e..ab9412263d2 100644 --- a/src/comp/middle/trans/tvec.rs +++ b/src/comp/middle/trans/tvec.rs @@ -2,7 +2,7 @@ import syntax::ast; import driver::session::session; import lib::llvm::{ValueRef, TypeRef}; import back::abi; -import base::{call_memmove, trans_shared_malloc, type_of_or_i8, +import base::{call_memmove, trans_shared_malloc, INIT, copy_val, load_if_immediate, get_tydesc, sub_block, do_spill_noroot, dest}; @@ -46,7 +46,7 @@ type alloc_result = fn alloc(bcx: block, vec_ty: ty::t, elts: uint) -> alloc_result { let ccx = bcx.ccx(); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); - let llunitty = type_of_or_i8(ccx, unit_ty); + let llunitty = type_of::type_of_or_i8(ccx, unit_ty); let llvecty = T_vec(ccx, llunitty); let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty); @@ -156,7 +156,7 @@ fn trans_append(cx: block, vec_ty: ty::t, lhsptr: ValueRef, }; let {bcx: bcx, val: unit_sz} = size_of(cx, unit_ty); - let llunitty = type_of_or_i8(ccx, unit_ty); + let llunitty = type_of::type_of_or_i8(ccx, unit_ty); let lhs = Load(bcx, lhsptr); let self_append = ICmp(bcx, lib::llvm::IntEQ, lhs, rhs); @@ -226,7 +226,7 @@ fn trans_add(bcx: block, vec_ty: ty::t, lhs: ValueRef, _ { false } }; let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); - let llunitty = type_of_or_i8(ccx, unit_ty); + let llunitty = type_of::type_of_or_i8(ccx, unit_ty); let {bcx: bcx, val: llunitsz} = size_of(bcx, unit_ty); let lhs_fill = get_fill(bcx, lhs); @@ -268,7 +268,7 @@ fn iter_vec_raw(bcx: block, vptr: ValueRef, vec_ty: ty::t, fill: ValueRef, f: iter_vec_block) -> block { let ccx = bcx.ccx(); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); - let llunitty = type_of_or_i8(ccx, unit_ty); + let llunitty = type_of::type_of_or_i8(ccx, unit_ty); let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty); let vptr = PointerCast(bcx, vptr, T_ptr(T_vec(ccx, llunitty))); let data_ptr = get_dataptr(bcx, vptr, llunitty); diff --git a/src/comp/middle/trans/type_of.rs b/src/comp/middle/trans/type_of.rs new file mode 100644 index 00000000000..f7095be55ff --- /dev/null +++ b/src/comp/middle/trans/type_of.rs @@ -0,0 +1,145 @@ +import common::*; +import lib::llvm::{TypeRef}; +import syntax::ast; +import lib::llvm::llvm; + +fn type_of_explicit_args(cx: crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { + vec::map(inputs) {|arg| + let arg_ty = arg.ty; + let llty = type_of(cx, arg_ty); + alt ty::resolved_mode(cx.tcx, arg.mode) { + ast::by_val { llty } + _ { T_ptr(llty) } + } + } +} + +fn type_of_fn(cx: crate_ctxt, inputs: [ty::arg], + output: ty::t, params: [ty::param_bounds]) -> TypeRef { + let atys: [TypeRef] = []; + + // Arg 0: Output pointer. + atys += [T_ptr(type_of(cx, output))]; + + // Arg 1: Environment + atys += [T_opaque_box_ptr(cx)]; + + // Args >2: ty params, if not acquired via capture... + for bounds in params { + atys += [T_ptr(cx.tydesc_type)]; + for bound in *bounds { + alt bound { + ty::bound_iface(_) { atys += [T_ptr(T_dict())]; } + _ {} + } + } + } + // ... then explicit args. + atys += type_of_explicit_args(cx, inputs); + ret T_fn(atys, llvm::LLVMVoidType()); +} + +// Given a function type and a count of ty params, construct an llvm type +fn type_of_fn_from_ty(cx: crate_ctxt, fty: ty::t, + param_bounds: [ty::param_bounds]) -> TypeRef { + type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty), param_bounds) +} + +fn type_of(cx: crate_ctxt, t: ty::t) -> TypeRef { + assert !ty::type_has_vars(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_str { T_ptr(T_vec(cx, T_i8())) } + ty::ty_enum(did, _) { type_of_enum(cx, did, t) } + ty::ty_box(mt) { + let mt_ty = mt.ty; + 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) { + let mt_ty = mt.ty; + T_ptr(type_of(cx, mt_ty)) } + ty::ty_vec(mt) { + let mt_ty = mt.ty; + if ty::type_has_dynamic_size(cx.tcx, mt_ty) { + T_ptr(cx.opaque_vec_type) + } else { + T_ptr(T_vec(cx, type_of(cx, mt_ty))) } + } + ty::ty_ptr(mt) { + let mt_ty = mt.ty; + T_ptr(type_of(cx, mt_ty)) } + ty::ty_rec(fields) { + let tys: [TypeRef] = []; + for f: ty::field in fields { + 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, tps) { + let sub1 = ty::substitute_type_params(cx.tcx, tps, sub); + ret T_struct([T_i8(), type_of(cx, sub1)]); + } + ty::ty_param(_, _) { T_typaram(cx.tn) } + ty::ty_send_type | ty::ty_type { T_ptr(cx.tydesc_type) } + ty::ty_tup(elts) { + let tys = []; + for elt in elts { + 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) } + + _ { fail "type_of not implemented for this kind of type"; } + }; + cx.lltypes.insert(t, llty); + ret llty; +} + +fn type_of_enum(cx: crate_ctxt, did: ast::def_id, t: ty::t) + -> TypeRef { + let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u; + if check type_has_static_size(cx, t) { + 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) } + } + else { + if degen { T_struct([T_enum_variant(cx)]) } + else { T_opaque_enum(cx) } + } +} + +fn type_of_ty_param_bounds_and_ty + (ccx: crate_ctxt, tpt: ty::ty_param_bounds_and_ty) -> TypeRef { + let t = tpt.ty; + alt ty::get(t).struct { + ty::ty_fn(_) { + ret type_of_fn_from_ty(ccx, t, *tpt.bounds); + } + _ { + // fall through + } + } + type_of(ccx, t) +} + +fn type_of_or_i8(ccx: crate_ctxt, typ: ty::t) -> TypeRef { + if check type_has_static_size(ccx, typ) { + type_of(ccx, typ) + } else { T_i8() } +} diff --git a/src/comp/middle/trans/uniq.rs b/src/comp/middle/trans/uniq.rs index b2ff6577762..d6d32510858 100644 --- a/src/comp/middle/trans/uniq.rs +++ b/src/comp/middle/trans/uniq.rs @@ -24,7 +24,7 @@ fn alloc_uniq(cx: block, uniq_ty: ty::t) -> result { bcx = r.bcx; let llsz = r.val; - let llptrty = T_ptr(type_of(bcx.ccx(), contents_ty)); + let llptrty = T_ptr(type_of::type_of(bcx.ccx(), contents_ty)); r = trans_shared_malloc(bcx, llptrty, llsz); bcx = r.bcx; diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index 9c16479c13b..0b8ce111f1f 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -16,6 +16,7 @@ use std (name = "std", mod middle { mod trans { mod common; + mod type_of; mod build; mod base; mod alt; |
