diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 1e9910762a1..25887cc1fe8 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2153,10 +2153,16 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef { } } -fn trans_lit(cx: @block_ctxt, lit: ast::lit) -> result { +fn trans_lit(cx: @block_ctxt, lit: ast::lit, dest: dest) -> @block_ctxt { + if dest == ignore { ret cx; } alt lit.node { - ast::lit_str(s) { ret tvec::trans_str(cx, s); } - _ { ret rslt(cx, trans_crate_lit(bcx_ccx(cx), lit)); } + ast::lit_str(s) { ret tvec::trans_str(cx, s, dest); } + _ { + let cell = alt dest { by_val(c) { c } + _ { bcx_ccx(cx).sess.span_note(lit.span, "here"); fail; }}; + *cell = trans_crate_lit(bcx_ccx(cx), lit); + ret cx; + } } } @@ -4129,7 +4135,6 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field], fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result { // Fixme Fill in cx.sp alt e.node { - ast::expr_lit(lit) { ret trans_lit(cx, *lit); } ast::expr_binary(op, x, y) { ret trans_binary(cx, op, x, y); } ast::expr_fn(f) { let ccx = bcx_ccx(cx); @@ -4186,7 +4191,6 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result { } ast::expr_bind(f, args) { ret trans_bind(cx, f, args, e.id); } ast::expr_cast(val, _) { ret trans_cast(cx, val, e.id); } - ast::expr_vec(args, _) { ret tvec::trans_vec(cx, args, e.id); } ast::expr_anon_obj(anon_obj) { ret trans_anon_obj(cx, e.span, anon_obj, e.id); } @@ -4261,6 +4265,9 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) ret trans_rec(bcx, args, base, e.id, dest); } ast::expr_tup(args) { ret trans_tup(bcx, args, e.id, dest); } + ast::expr_lit(lit) { ret trans_lit(bcx, *lit, dest); } + ast::expr_vec(args, _) { ret tvec::trans_vec(bcx, args, e.id, dest); } + ast::expr_break. { assert dest == ignore; ret trans_break(e.span, bcx); @@ -5306,13 +5313,18 @@ fn trans_closure(bcx_maybe: option::t<@block_ctxt>, // translation calls that don't have a return value (trans_crate, // trans_mod, trans_item, trans_obj, et cetera) and those that do // (trans_block, trans_expr, et cetera). - let dest = if !ty::type_is_bot(cx.ccx.tcx, block_ty) && - !ty::type_is_nil(cx.ccx.tcx, block_ty) && - f.proto != ast::proto_iter && - option::is_some(f.body.node.expr) { - save_in(fcx.llretptr) - } else { ignore }; - bcx = trans_block_dps(bcx, f.body, dest); + if ty::type_is_bot(cx.ccx.tcx, block_ty) || + ty::type_is_nil(cx.ccx.tcx, block_ty) || + f.proto == ast::proto_iter || + option::is_none(f.body.node.expr) { + bcx = trans_block_dps(bcx, f.body, ignore); + } else if type_is_immediate(cx.ccx, block_ty) { + let cell = empty_dest_cell(); + bcx = trans_block_dps(bcx, f.body, by_val(cell)); + Store(bcx, *cell, fcx.llretptr); + } else { + bcx = trans_block_dps(bcx, f.body, save_in(fcx.llretptr)); + } if !bcx.unreachable { // FIXME: until LLVM has a unit type, we are moving around diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs index 9afc3f6819c..c9375115d3c 100644 --- a/src/comp/middle/trans_alt.rs +++ b/src/comp/middle/trans_alt.rs @@ -33,7 +33,19 @@ fn opt_eq(a: opt, b: opt) -> bool { } fn trans_opt(bcx: @block_ctxt, o: opt) -> result { alt o { - lit(l) { ret trans::trans_lit(bcx, *l); } + lit(l) { + alt l.node { + ast::lit_str(s) { + let {bcx, val: dst} = + trans::alloc_ty(bcx, ty::mk_str(bcx_tcx(bcx))); + bcx = trans_vec::trans_str(bcx, s, trans::save_in(dst)); + ret rslt(bcx, dst); + } + _ { + ret rslt(bcx, trans::trans_crate_lit(bcx_ccx(bcx), *l)); + } + } + } var(id, _) { ret rslt(bcx, C_int(id as int)); } } } diff --git a/src/comp/middle/trans_vec.rs b/src/comp/middle/trans_vec.rs index e47e841bd03..0536f0ab12d 100644 --- a/src/comp/middle/trans_vec.rs +++ b/src/comp/middle/trans_vec.rs @@ -8,7 +8,7 @@ import trans::{call_memmove, trans_shared_malloc, llsize_of, type_of_or_i8, llderivedtydescs_block_ctxt, lazily_emit_tydesc_glue, get_tydesc, load_inbounds, move_val_if_temp, trans_lval, node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot, - GEPi, alloc_ty}; + GEPi, alloc_ty, dest}; import trans_build::*; import trans_common::*; @@ -49,7 +49,8 @@ type alloc_result = llunitsz: ValueRef, llunitty: TypeRef}; -fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result { +fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint, dest: dest) + -> alloc_result { let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty); let llunitty = type_of_or_i8(bcx, unit_ty); let llvecty = T_vec(llunitty); @@ -60,12 +61,9 @@ fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result { let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc); let vptr = PointerCast(bcx, vptr, T_ptr(llvecty)); - let r = alloc_ty(bcx, vec_ty); - let vptrptr = r.val; - bcx = r.bcx; - + let vptrptr = alt dest { trans::save_in(a) { a } }; Store(bcx, vptr, vptrptr); - add_clean_temp(bcx, vptrptr, vec_ty); +// add_clean_temp(bcx, vptrptr, vec_ty); ret {bcx: bcx, val: vptrptr, unit_ty: unit_ty, @@ -102,18 +100,19 @@ fn make_drop_glue(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t) -> ret next_cx; } -fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id) -> - result { +// FIXME handle dest == ignore +fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id, + dest: dest) -> @block_ctxt { let vec_ty = node_id_type(bcx_ccx(bcx), id); let {bcx: bcx, - val: vptr, + val: vptrptr, llunitsz: llunitsz, unit_ty: unit_ty, llunitty: llunitty} = - alloc(bcx, vec_ty, vec::len(args)); + alloc(bcx, vec_ty, vec::len(args), dest); // Store the individual elements. - let dataptr = get_dataptr(bcx, vptr, llunitty); + let dataptr = get_dataptr(bcx, vptrptr, llunitty); let i = 0u; for e in args { let lv = trans_lval(bcx, e); @@ -125,19 +124,18 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id) -> bcx = move_val_if_temp(bcx, INIT, lleltptr, lv, unit_ty); i += 1u; } - ret rslt(bcx, vptr); + ret bcx; } -fn trans_str(bcx: @block_ctxt, s: str) -> result { +fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt { let veclen = std::str::byte_len(s) + 1u; // +1 for \0 - let {bcx: bcx, val: sptr, _} = - alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen); + let {bcx: bcx, val: sptrptr, _} = + alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen, dest); let llcstr = C_cstr(bcx_ccx(bcx), s); let bcx = - call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()), llcstr, + call_memmove(bcx, get_dataptr(bcx, sptrptr, T_i8()), llcstr, C_uint(veclen)).bcx; - - ret rslt(bcx, sptr); + ret bcx; } fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,