rollup merge of #20642: michaelwoerister/sane-source-locations-pt1
Conflicts: src/librustc_trans/trans/debuginfo.rs
This commit is contained in:
commit
f4df69a40a
@ -208,10 +208,10 @@ use trans::cleanup::{self, CleanupMethods};
|
||||
use trans::common::*;
|
||||
use trans::consts;
|
||||
use trans::datum::*;
|
||||
use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
|
||||
use trans::expr::{self, Dest};
|
||||
use trans::tvec;
|
||||
use trans::type_of;
|
||||
use trans::debuginfo;
|
||||
use middle::ty::{self, Ty};
|
||||
use session::config::FullDebugInfo;
|
||||
use util::common::indenter;
|
||||
@ -632,7 +632,7 @@ fn bind_subslice_pat(bcx: Block,
|
||||
|
||||
let slice_begin = InBoundsGEP(bcx, base, &[C_uint(bcx.ccx(), offset_left)]);
|
||||
let slice_len_offset = C_uint(bcx.ccx(), offset_left + offset_right);
|
||||
let slice_len = Sub(bcx, len, slice_len_offset);
|
||||
let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
|
||||
let slice_ty = ty::mk_slice(bcx.tcx(),
|
||||
bcx.tcx().mk_region(ty::ReStatic),
|
||||
ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
|
||||
@ -656,7 +656,7 @@ fn extract_vec_elems<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
elems.extend(range(0, before).map(|i| GEPi(bcx, base, &[i])));
|
||||
elems.extend(range(0, after).rev().map(|i| {
|
||||
InBoundsGEP(bcx, base, &[
|
||||
Sub(bcx, len, C_uint(bcx.ccx(), i + 1))
|
||||
Sub(bcx, len, C_uint(bcx.ccx(), i + 1), DebugLoc::None)
|
||||
])
|
||||
}));
|
||||
ExtractedBlock { vals: elems, bcx: bcx }
|
||||
@ -731,7 +731,7 @@ impl FailureHandler {
|
||||
Infallible =>
|
||||
panic!("attempted to panic in a non-panicking panic handler!"),
|
||||
JumpToBasicBlock(basic_block) =>
|
||||
Br(bcx, basic_block),
|
||||
Br(bcx, basic_block, DebugLoc::None),
|
||||
Unreachable =>
|
||||
build::Unreachable(bcx)
|
||||
}
|
||||
@ -889,7 +889,7 @@ fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
with_cond(bcx, Not(bcx, val), |bcx| {
|
||||
with_cond(bcx, Not(bcx, val, guard_expr.debug_loc()), |bcx| {
|
||||
// Guard does not match: remove all bindings from the lllocals table
|
||||
for (_, &binding_info) in data.bindings_map.iter() {
|
||||
call_lifetime_end(bcx, binding_info.llmatch);
|
||||
@ -966,7 +966,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
Br(bcx, data.bodycx.llbb);
|
||||
Br(bcx, data.bodycx.llbb, DebugLoc::None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1096,7 +1096,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
if !exhaustive || i + 1 < len {
|
||||
opt_cx = bcx.fcx.new_temp_block("match_case");
|
||||
match kind {
|
||||
Single => Br(bcx, opt_cx.llbb),
|
||||
Single => Br(bcx, opt_cx.llbb, DebugLoc::None),
|
||||
Switch => {
|
||||
match opt.trans(bcx) {
|
||||
SingleResult(r) => {
|
||||
@ -1131,7 +1131,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
compare_scalar_types(
|
||||
bcx, test_val, vend,
|
||||
t, ast::BiLe);
|
||||
Result::new(bcx, And(bcx, llge, llle))
|
||||
Result::new(bcx, And(bcx, llge, llle, DebugLoc::None))
|
||||
}
|
||||
LowerBound(Result { bcx, val }) => {
|
||||
compare_scalar_types(bcx, test_val, val, t, ast::BiGe)
|
||||
@ -1149,12 +1149,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
if i + 1 < len && (guarded || multi_pats || kind == CompareSliceLength) {
|
||||
branch_chk = Some(JumpToBasicBlock(bcx.llbb));
|
||||
}
|
||||
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
|
||||
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb, DebugLoc::None);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
} else if kind == Compare || kind == CompareSliceLength {
|
||||
Br(bcx, else_cx.llbb);
|
||||
Br(bcx, else_cx.llbb, DebugLoc::None);
|
||||
}
|
||||
|
||||
let mut size = 0u;
|
||||
@ -1194,7 +1194,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
// Compile the fall-through case, if any
|
||||
if !exhaustive && kind != Single {
|
||||
if kind == Compare || kind == CompareSliceLength {
|
||||
Br(bcx, else_cx.llbb);
|
||||
Br(bcx, else_cx.llbb, DebugLoc::None);
|
||||
}
|
||||
match chk {
|
||||
// If there is only one default arm left, move on to the next
|
||||
|
@ -62,6 +62,7 @@ use trans::cleanup;
|
||||
use trans::cleanup::CleanupMethods;
|
||||
use trans::common::*;
|
||||
use trans::datum;
|
||||
use trans::debuginfo::DebugLoc;
|
||||
use trans::machine;
|
||||
use trans::monomorphize;
|
||||
use trans::type_::Type;
|
||||
@ -979,7 +980,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to());
|
||||
|
||||
variant_cx = f(variant_cx, case, variant_value);
|
||||
Br(variant_cx, bcx_next.llbb);
|
||||
Br(variant_cx, bcx_next.llbb, DebugLoc::None);
|
||||
}
|
||||
|
||||
bcx_next
|
||||
|
@ -57,7 +57,7 @@ use trans::closure;
|
||||
use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral};
|
||||
use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
|
||||
use trans::common::{CrateContext, ExternMap, FunctionContext};
|
||||
use trans::common::{NodeInfo, Result};
|
||||
use trans::common::{Result};
|
||||
use trans::common::{node_id_type, return_type_is_void};
|
||||
use trans::common::{tydesc_info, type_is_immediate};
|
||||
use trans::common::{type_is_zero_size, val_ty};
|
||||
@ -66,7 +66,7 @@ use trans::consts;
|
||||
use trans::context::SharedCrateContext;
|
||||
use trans::controlflow;
|
||||
use trans::datum;
|
||||
use trans::debuginfo;
|
||||
use trans::debuginfo::{self, DebugLoc};
|
||||
use trans::expr;
|
||||
use trans::foreign;
|
||||
use trans::glue;
|
||||
@ -780,7 +780,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
|
||||
&**variant,
|
||||
substs,
|
||||
&mut f);
|
||||
Br(variant_cx, next_cx.llbb);
|
||||
Br(variant_cx, next_cx.llbb, DebugLoc::None);
|
||||
}
|
||||
cx = next_cx;
|
||||
}
|
||||
@ -945,7 +945,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
llfn: ValueRef,
|
||||
llargs: &[ValueRef],
|
||||
fn_ty: Ty<'tcx>,
|
||||
call_info: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> (ValueRef, Block<'blk, 'tcx>) {
|
||||
let _icx = push_ctxt("invoke_");
|
||||
if bcx.unreachable.get() {
|
||||
@ -971,17 +971,13 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let normal_bcx = bcx.fcx.new_temp_block("normal-return");
|
||||
let landing_pad = bcx.fcx.get_landing_pad();
|
||||
|
||||
match call_info {
|
||||
Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
|
||||
None => debuginfo::clear_source_location(bcx.fcx)
|
||||
};
|
||||
|
||||
let llresult = Invoke(bcx,
|
||||
llfn,
|
||||
&llargs[],
|
||||
normal_bcx.llbb,
|
||||
landing_pad,
|
||||
Some(attributes));
|
||||
Some(attributes),
|
||||
debug_loc);
|
||||
return (llresult, normal_bcx);
|
||||
} else {
|
||||
debug!("calling {} at {:?}", bcx.val_to_string(llfn), bcx.llbb);
|
||||
@ -989,12 +985,11 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
debug!("arg: {}", bcx.val_to_string(llarg));
|
||||
}
|
||||
|
||||
match call_info {
|
||||
Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
|
||||
None => debuginfo::clear_source_location(bcx.fcx)
|
||||
};
|
||||
|
||||
let llresult = Call(bcx, llfn, &llargs[], Some(attributes));
|
||||
let llresult = Call(bcx,
|
||||
llfn,
|
||||
&llargs[],
|
||||
Some(attributes),
|
||||
debug_loc);
|
||||
return (llresult, bcx);
|
||||
}
|
||||
}
|
||||
@ -1082,10 +1077,10 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
let fcx = bcx.fcx;
|
||||
let next_cx = fcx.new_temp_block("next");
|
||||
let cond_cx = fcx.new_temp_block("cond");
|
||||
CondBr(bcx, val, cond_cx.llbb, next_cx.llbb);
|
||||
CondBr(bcx, val, cond_cx.llbb, next_cx.llbb, DebugLoc::None);
|
||||
let after_cx = f(cond_cx);
|
||||
if !after_cx.terminated.get() {
|
||||
Br(after_cx, next_cx.llbb);
|
||||
Br(after_cx, next_cx.llbb, DebugLoc::None);
|
||||
}
|
||||
next_cx
|
||||
}
|
||||
@ -1101,7 +1096,7 @@ pub fn call_lifetime_start(cx: Block, ptr: ValueRef) {
|
||||
let llsize = C_u64(ccx, machine::llsize_of_alloc(ccx, val_ty(ptr).element_type()));
|
||||
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
|
||||
let lifetime_start = ccx.get_intrinsic(&"llvm.lifetime.start");
|
||||
Call(cx, lifetime_start, &[llsize, ptr], None);
|
||||
Call(cx, lifetime_start, &[llsize, ptr], None, DebugLoc::None);
|
||||
}
|
||||
|
||||
pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
|
||||
@ -1115,7 +1110,7 @@ pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
|
||||
let llsize = C_u64(ccx, machine::llsize_of_alloc(ccx, val_ty(ptr).element_type()));
|
||||
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
|
||||
let lifetime_end = ccx.get_intrinsic(&"llvm.lifetime.end");
|
||||
Call(cx, lifetime_end, &[llsize, ptr], None);
|
||||
Call(cx, lifetime_end, &[llsize, ptr], None, DebugLoc::None);
|
||||
}
|
||||
|
||||
pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
|
||||
@ -1132,7 +1127,7 @@ pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a
|
||||
let size = IntCast(cx, n_bytes, ccx.int_type());
|
||||
let align = C_i32(ccx, align as i32);
|
||||
let volatile = C_bool(ccx, false);
|
||||
Call(cx, memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
|
||||
Call(cx, memcpy, &[dst_ptr, src_ptr, size, align, volatile], None, DebugLoc::None);
|
||||
}
|
||||
|
||||
pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
@ -1685,13 +1680,14 @@ fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>(
|
||||
// and builds the return block.
|
||||
pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
|
||||
last_bcx: Block<'blk, 'tcx>,
|
||||
retty: ty::FnOutput<'tcx>) {
|
||||
retty: ty::FnOutput<'tcx>,
|
||||
ret_debug_loc: DebugLoc) {
|
||||
let _icx = push_ctxt("finish_fn");
|
||||
|
||||
let ret_cx = match fcx.llreturn.get() {
|
||||
Some(llreturn) => {
|
||||
if !last_bcx.terminated.get() {
|
||||
Br(last_bcx, llreturn);
|
||||
Br(last_bcx, llreturn, DebugLoc::None);
|
||||
}
|
||||
raw_block(fcx, false, llreturn)
|
||||
}
|
||||
@ -1701,7 +1697,7 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
|
||||
// This shouldn't need to recompute the return type,
|
||||
// as new_fn_ctxt did it already.
|
||||
let substd_retty = fcx.monomorphize(&retty);
|
||||
build_return_block(fcx, ret_cx, substd_retty);
|
||||
build_return_block(fcx, ret_cx, substd_retty, ret_debug_loc);
|
||||
|
||||
debuginfo::clear_source_location(fcx);
|
||||
fcx.cleanup();
|
||||
@ -1710,10 +1706,11 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
|
||||
// Builds the return block for a function.
|
||||
pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
|
||||
ret_cx: Block<'blk, 'tcx>,
|
||||
retty: ty::FnOutput<'tcx>) {
|
||||
retty: ty::FnOutput<'tcx>,
|
||||
ret_debug_location: DebugLoc) {
|
||||
if fcx.llretslotptr.get().is_none() ||
|
||||
(!fcx.needs_ret_allocas && fcx.caller_expects_out_pointer) {
|
||||
return RetVoid(ret_cx);
|
||||
return RetVoid(ret_cx, ret_debug_location);
|
||||
}
|
||||
|
||||
let retslot = if fcx.needs_ret_allocas {
|
||||
@ -1743,9 +1740,9 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
|
||||
if let ty::FnConverging(retty) = retty {
|
||||
store_ty(ret_cx, retval, get_param(fcx.llfn, 0), retty);
|
||||
}
|
||||
RetVoid(ret_cx)
|
||||
RetVoid(ret_cx, ret_debug_location)
|
||||
} else {
|
||||
Ret(ret_cx, retval)
|
||||
Ret(ret_cx, retval, ret_debug_location)
|
||||
}
|
||||
}
|
||||
// Otherwise, copy the return value to the ret slot
|
||||
@ -1753,16 +1750,16 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
|
||||
ty::FnConverging(retty) => {
|
||||
if fcx.caller_expects_out_pointer {
|
||||
memcpy_ty(ret_cx, get_param(fcx.llfn, 0), retslot, retty);
|
||||
RetVoid(ret_cx)
|
||||
RetVoid(ret_cx, ret_debug_location)
|
||||
} else {
|
||||
Ret(ret_cx, load_ty(ret_cx, retslot, retty))
|
||||
Ret(ret_cx, load_ty(ret_cx, retslot, retty), ret_debug_location)
|
||||
}
|
||||
}
|
||||
ty::FnDiverging => {
|
||||
if fcx.caller_expects_out_pointer {
|
||||
RetVoid(ret_cx)
|
||||
RetVoid(ret_cx, ret_debug_location)
|
||||
} else {
|
||||
Ret(ret_cx, C_undef(Type::nil(fcx.ccx)))
|
||||
Ret(ret_cx, C_undef(Type::nil(fcx.ccx)), ret_debug_location)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1893,7 +1890,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
match fcx.llreturn.get() {
|
||||
Some(_) => {
|
||||
Br(bcx, fcx.return_exit_block());
|
||||
Br(bcx, fcx.return_exit_block(), DebugLoc::None);
|
||||
fcx.pop_custom_cleanup_scope(arg_scope);
|
||||
}
|
||||
None => {
|
||||
@ -1912,8 +1909,11 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
let ret_debug_loc = DebugLoc::At(fn_cleanup_debug_loc.id,
|
||||
fn_cleanup_debug_loc.span);
|
||||
|
||||
// Insert the mandatory first few basic blocks before lltop.
|
||||
finish_fn(&fcx, bcx, output_type);
|
||||
finish_fn(&fcx, bcx, output_type, ret_debug_loc);
|
||||
}
|
||||
|
||||
// trans_fn: creates an LLVM function corresponding to a source language
|
||||
@ -1965,7 +1965,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
disr: ty::Disr,
|
||||
args: callee::CallArgs,
|
||||
dest: expr::Dest,
|
||||
call_info: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Result<'blk, 'tcx> {
|
||||
|
||||
let ccx = bcx.fcx.ccx;
|
||||
@ -2004,7 +2004,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
&fields[],
|
||||
None,
|
||||
expr::SaveIn(llresult),
|
||||
call_info);
|
||||
debug_loc);
|
||||
}
|
||||
_ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor")
|
||||
}
|
||||
@ -2015,7 +2015,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
let bcx = match dest {
|
||||
expr::SaveIn(_) => bcx,
|
||||
expr::Ignore => {
|
||||
glue::drop_ty(bcx, llresult, result_ty, call_info)
|
||||
glue::drop_ty(bcx, llresult, result_ty, debug_loc)
|
||||
}
|
||||
};
|
||||
|
||||
@ -2082,7 +2082,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
|
||||
adt::trans_set_discr(bcx, &*repr, dest, disr);
|
||||
}
|
||||
|
||||
finish_fn(&fcx, bcx, result_ty);
|
||||
finish_fn(&fcx, bcx, result_ty, DebugLoc::None);
|
||||
}
|
||||
|
||||
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {
|
||||
|
@ -20,6 +20,7 @@ use syntax::codemap::Span;
|
||||
|
||||
use trans::builder::Builder;
|
||||
use trans::type_::Type;
|
||||
use trans::debuginfo::DebugLoc;
|
||||
|
||||
use libc::{c_uint, c_char};
|
||||
|
||||
@ -48,41 +49,59 @@ pub fn B<'blk, 'tcx>(cx: Block<'blk, 'tcx>) -> Builder<'blk, 'tcx> {
|
||||
// for (panic/break/return statements, call to diverging functions, etc), and
|
||||
// further instructions to the block should simply be ignored.
|
||||
|
||||
pub fn RetVoid(cx: Block) {
|
||||
if cx.unreachable.get() { return; }
|
||||
pub fn RetVoid(cx: Block, debug_loc: DebugLoc) {
|
||||
if cx.unreachable.get() {
|
||||
return;
|
||||
}
|
||||
check_not_terminated(cx);
|
||||
terminate(cx, "RetVoid");
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).ret_void();
|
||||
}
|
||||
|
||||
pub fn Ret(cx: Block, v: ValueRef) {
|
||||
if cx.unreachable.get() { return; }
|
||||
pub fn Ret(cx: Block, v: ValueRef, debug_loc: DebugLoc) {
|
||||
if cx.unreachable.get() {
|
||||
return;
|
||||
}
|
||||
check_not_terminated(cx);
|
||||
terminate(cx, "Ret");
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).ret(v);
|
||||
}
|
||||
|
||||
pub fn AggregateRet(cx: Block, ret_vals: &[ValueRef]) {
|
||||
if cx.unreachable.get() { return; }
|
||||
pub fn AggregateRet(cx: Block,
|
||||
ret_vals: &[ValueRef],
|
||||
debug_loc: DebugLoc) {
|
||||
if cx.unreachable.get() {
|
||||
return;
|
||||
}
|
||||
check_not_terminated(cx);
|
||||
terminate(cx, "AggregateRet");
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).aggregate_ret(ret_vals);
|
||||
}
|
||||
|
||||
pub fn Br(cx: Block, dest: BasicBlockRef) {
|
||||
if cx.unreachable.get() { return; }
|
||||
pub fn Br(cx: Block, dest: BasicBlockRef, debug_loc: DebugLoc) {
|
||||
if cx.unreachable.get() {
|
||||
return;
|
||||
}
|
||||
check_not_terminated(cx);
|
||||
terminate(cx, "Br");
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).br(dest);
|
||||
}
|
||||
|
||||
pub fn CondBr(cx: Block,
|
||||
if_: ValueRef,
|
||||
then: BasicBlockRef,
|
||||
else_: BasicBlockRef) {
|
||||
if cx.unreachable.get() { return; }
|
||||
else_: BasicBlockRef,
|
||||
debug_loc: DebugLoc) {
|
||||
if cx.unreachable.get() {
|
||||
return;
|
||||
}
|
||||
check_not_terminated(cx);
|
||||
terminate(cx, "CondBr");
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).cond_br(if_, then, else_);
|
||||
}
|
||||
|
||||
@ -101,10 +120,16 @@ pub fn AddCase(s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn IndirectBr(cx: Block, addr: ValueRef, num_dests: uint) {
|
||||
if cx.unreachable.get() { return; }
|
||||
pub fn IndirectBr(cx: Block,
|
||||
addr: ValueRef,
|
||||
num_dests: uint,
|
||||
debug_loc: DebugLoc) {
|
||||
if cx.unreachable.get() {
|
||||
return;
|
||||
}
|
||||
check_not_terminated(cx);
|
||||
terminate(cx, "IndirectBr");
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).indirect_br(addr, num_dests);
|
||||
}
|
||||
|
||||
@ -113,7 +138,8 @@ pub fn Invoke(cx: Block,
|
||||
args: &[ValueRef],
|
||||
then: BasicBlockRef,
|
||||
catch: BasicBlockRef,
|
||||
attributes: Option<AttrBuilder>)
|
||||
attributes: Option<AttrBuilder>,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return C_null(Type::i8(cx.ccx()));
|
||||
@ -123,6 +149,7 @@ pub fn Invoke(cx: Block,
|
||||
debug!("Invoke({} with arguments ({}))",
|
||||
cx.val_to_string(fn_),
|
||||
args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().connect(", "));
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).invoke(fn_, args, then, catch, attributes)
|
||||
}
|
||||
|
||||
@ -143,176 +170,378 @@ pub fn _Undef(val: ValueRef) -> ValueRef {
|
||||
}
|
||||
|
||||
/* Arithmetic */
|
||||
pub fn Add(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn Add(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).add(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn NSWAdd(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn NSWAdd(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nswadd(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn NUWAdd(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn NUWAdd(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nuwadd(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn FAdd(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn FAdd(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).fadd(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn Sub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn Sub(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).sub(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn NSWSub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn NSWSub(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nswsub(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn NUWSub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn NUWSub(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nuwsub(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn FSub(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn FSub(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).fsub(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn Mul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn Mul(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).mul(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn NSWMul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn NSWMul(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nswmul(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn NUWMul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn NUWMul(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nuwmul(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn FMul(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn FMul(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).fmul(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn UDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn UDiv(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).udiv(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn SDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn SDiv(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).sdiv(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn ExactSDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn ExactSDiv(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).exactsdiv(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn FDiv(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn FDiv(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).fdiv(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn URem(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn URem(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).urem(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn SRem(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn SRem(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).srem(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn FRem(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn FRem(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).frem(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn Shl(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn Shl(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).shl(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn LShr(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn LShr(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).lshr(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn AShr(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn AShr(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).ashr(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn And(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn And(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).and(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn Or(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn Or(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).or(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn Xor(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
pub fn Xor(cx: Block,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).xor(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn BinOp(cx: Block, op: Opcode, lhs: ValueRef, rhs: ValueRef)
|
||||
pub fn BinOp(cx: Block,
|
||||
op: Opcode,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(lhs); }
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(lhs);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).binop(op, lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn Neg(cx: Block, v: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(v); }
|
||||
pub fn Neg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(v);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).neg(v)
|
||||
}
|
||||
|
||||
pub fn NSWNeg(cx: Block, v: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(v); }
|
||||
pub fn NSWNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(v);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nswneg(v)
|
||||
}
|
||||
|
||||
pub fn NUWNeg(cx: Block, v: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(v); }
|
||||
pub fn NUWNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(v);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).nuwneg(v)
|
||||
}
|
||||
pub fn FNeg(cx: Block, v: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(v); }
|
||||
pub fn FNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(v);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).fneg(v)
|
||||
}
|
||||
|
||||
pub fn Not(cx: Block, v: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return _Undef(v); }
|
||||
pub fn Not(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _Undef(v);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).not(v)
|
||||
}
|
||||
|
||||
/* Memory */
|
||||
pub fn Malloc(cx: Block, ty: Type) -> ValueRef {
|
||||
pub fn Malloc(cx: Block, ty: Type, debug_loc: DebugLoc) -> ValueRef {
|
||||
unsafe {
|
||||
if cx.unreachable.get() {
|
||||
return llvm::LLVMGetUndef(Type::i8p(cx.ccx()).to_ref());
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).malloc(ty)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ArrayMalloc(cx: Block, ty: Type, val: ValueRef) -> ValueRef {
|
||||
pub fn ArrayMalloc(cx: Block,
|
||||
ty: Type,
|
||||
val: ValueRef,
|
||||
debug_loc: DebugLoc) -> ValueRef {
|
||||
unsafe {
|
||||
if cx.unreachable.get() {
|
||||
return llvm::LLVMGetUndef(Type::i8p(cx.ccx()).to_ref());
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).array_malloc(ty, val)
|
||||
}
|
||||
}
|
||||
@ -327,6 +556,7 @@ pub fn Alloca(cx: Block, ty: Type, name: &str) -> ValueRef {
|
||||
pub fn AllocaFcx(fcx: &FunctionContext, ty: Type, name: &str) -> ValueRef {
|
||||
let b = fcx.ccx.builder();
|
||||
b.position_before(fcx.alloca_insert_pt.get().unwrap());
|
||||
DebugLoc::None.apply(fcx);
|
||||
b.alloca(ty, name)
|
||||
}
|
||||
|
||||
@ -335,6 +565,7 @@ pub fn ArrayAlloca(cx: Block, ty: Type, val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable.get() { return llvm::LLVMGetUndef(ty.ptr_to().to_ref()); }
|
||||
let b = cx.fcx.ccx.builder();
|
||||
b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
|
||||
DebugLoc::None.apply(cx.fcx);
|
||||
b.array_alloca(ty, val)
|
||||
}
|
||||
}
|
||||
@ -680,9 +911,16 @@ pub fn InlineAsmCall(cx: Block, asm: *const c_char, cons: *const c_char,
|
||||
B(cx).inline_asm_call(asm, cons, inputs, output, volatile, alignstack, dia)
|
||||
}
|
||||
|
||||
pub fn Call(cx: Block, fn_: ValueRef, args: &[ValueRef],
|
||||
attributes: Option<AttrBuilder>) -> ValueRef {
|
||||
if cx.unreachable.get() { return _UndefReturn(cx, fn_); }
|
||||
pub fn Call(cx: Block,
|
||||
fn_: ValueRef,
|
||||
args: &[ValueRef],
|
||||
attributes: Option<AttrBuilder>,
|
||||
debug_loc: DebugLoc)
|
||||
-> ValueRef {
|
||||
if cx.unreachable.get() {
|
||||
return _UndefReturn(cx, fn_);
|
||||
}
|
||||
debug_loc.apply(cx.fcx);
|
||||
B(cx).call(fn_, args, attributes)
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ use trans::common;
|
||||
use trans::common::*;
|
||||
use trans::consts;
|
||||
use trans::datum::*;
|
||||
use trans::debuginfo::{DebugLoc, ToDebugLoc};
|
||||
use trans::expr;
|
||||
use trans::glue;
|
||||
use trans::inline;
|
||||
@ -356,7 +357,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
|
||||
ArgVals(&llargs[]),
|
||||
dest).bcx;
|
||||
|
||||
finish_fn(&fcx, bcx, sig.output);
|
||||
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
|
||||
|
||||
ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty, llfn);
|
||||
|
||||
@ -646,7 +647,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
/// For non-lang items, `dest` is always Some, and hence the result is written into memory
|
||||
/// somewhere. Nonetheless we return the actual return value of the function.
|
||||
pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
call_info: Option<NodeInfo>,
|
||||
call_info: Option<NodeIdAndSpan>,
|
||||
callee_ty: Ty<'tcx>,
|
||||
get_callee: F,
|
||||
args: CallArgs<'a, 'tcx>,
|
||||
@ -703,7 +704,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
disr,
|
||||
args,
|
||||
dest.unwrap(),
|
||||
call_info);
|
||||
call_info.debug_loc());
|
||||
}
|
||||
};
|
||||
|
||||
@ -781,7 +782,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
llfn,
|
||||
&llargs[],
|
||||
callee_ty,
|
||||
call_info);
|
||||
call_info.debug_loc());
|
||||
bcx = b;
|
||||
llresult = llret;
|
||||
|
||||
@ -828,7 +829,10 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
match (dest, opt_llretslot, ret_ty) {
|
||||
(Some(expr::Ignore), Some(llretslot), ty::FnConverging(ret_ty)) => {
|
||||
// drop the value if it is not being saved.
|
||||
bcx = glue::drop_ty(bcx, llretslot, ret_ty, call_info);
|
||||
bcx = glue::drop_ty(bcx,
|
||||
llretslot,
|
||||
ret_ty,
|
||||
call_info.debug_loc());
|
||||
call_lifetime_end(bcx, llretslot);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -21,8 +21,8 @@ use trans::base;
|
||||
use trans::build;
|
||||
use trans::callee;
|
||||
use trans::common;
|
||||
use trans::common::{Block, FunctionContext, ExprId, NodeInfo};
|
||||
use trans::debuginfo;
|
||||
use trans::common::{Block, FunctionContext, ExprId, NodeIdAndSpan};
|
||||
use trans::debuginfo::{DebugLoc, ToDebugLoc};
|
||||
use trans::glue;
|
||||
use middle::region;
|
||||
use trans::type_::Type;
|
||||
@ -44,7 +44,7 @@ pub struct CleanupScope<'blk, 'tcx: 'blk> {
|
||||
|
||||
// The debug location any drop calls generated for this scope will be
|
||||
// associated with.
|
||||
debug_loc: Option<NodeInfo>,
|
||||
debug_loc: DebugLoc,
|
||||
|
||||
cached_early_exits: Vec<CachedEarlyExit>,
|
||||
cached_landing_pad: Option<BasicBlockRef>,
|
||||
@ -100,7 +100,7 @@ pub trait Cleanup<'tcx> {
|
||||
fn is_lifetime_end(&self) -> bool;
|
||||
fn trans<'blk>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx>;
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ pub enum ScopeId {
|
||||
|
||||
impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
|
||||
/// Invoked when we start to trans the code contained within a new cleanup scope.
|
||||
fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) {
|
||||
fn push_ast_cleanup_scope(&self, debug_loc: NodeIdAndSpan) {
|
||||
debug!("push_ast_cleanup_scope({})",
|
||||
self.ccx.tcx().map.node_to_string(debug_loc.id));
|
||||
|
||||
@ -139,7 +139,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
|
||||
}
|
||||
|
||||
self.push_scope(CleanupScope::new(AstScopeKind(debug_loc.id),
|
||||
Some(debug_loc)));
|
||||
debug_loc.debug_loc()));
|
||||
}
|
||||
|
||||
fn push_loop_cleanup_scope(&self,
|
||||
@ -168,19 +168,20 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
|
||||
.borrow()
|
||||
.last()
|
||||
.map(|opt_scope| opt_scope.debug_loc)
|
||||
.unwrap_or(None);
|
||||
.unwrap_or(DebugLoc::None);
|
||||
|
||||
self.push_scope(CleanupScope::new(CustomScopeKind, debug_loc));
|
||||
CustomScopeIndex { index: index }
|
||||
}
|
||||
|
||||
fn push_custom_cleanup_scope_with_debug_loc(&self,
|
||||
debug_loc: NodeInfo)
|
||||
debug_loc: NodeIdAndSpan)
|
||||
-> CustomScopeIndex {
|
||||
let index = self.scopes_len();
|
||||
debug!("push_custom_cleanup_scope(): {}", index);
|
||||
|
||||
self.push_scope(CleanupScope::new(CustomScopeKind, Some(debug_loc)));
|
||||
self.push_scope(CleanupScope::new(CustomScopeKind,
|
||||
debug_loc.debug_loc()));
|
||||
CustomScopeIndex { index: index }
|
||||
}
|
||||
|
||||
@ -664,7 +665,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||
scope.debug_loc);
|
||||
}
|
||||
}
|
||||
build::Br(bcx_out, prev_llbb);
|
||||
build::Br(bcx_out, prev_llbb, DebugLoc::None);
|
||||
prev_llbb = bcx_in.llbb;
|
||||
} else {
|
||||
debug!("no suitable cleanups in {}",
|
||||
@ -766,7 +767,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||
|
||||
// Generate the cleanup block and branch to it.
|
||||
let cleanup_llbb = self.trans_cleanups_to_exit_scope(UnwindExit);
|
||||
build::Br(pad_bcx, cleanup_llbb);
|
||||
build::Br(pad_bcx, cleanup_llbb, DebugLoc::None);
|
||||
|
||||
return pad_bcx.llbb;
|
||||
}
|
||||
@ -774,7 +775,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||
|
||||
impl<'blk, 'tcx> CleanupScope<'blk, 'tcx> {
|
||||
fn new(kind: CleanupScopeKind<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> CleanupScope<'blk, 'tcx> {
|
||||
CleanupScope {
|
||||
kind: kind,
|
||||
@ -896,7 +897,7 @@ impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> {
|
||||
|
||||
fn trans<'blk>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let bcx = if self.is_immediate {
|
||||
glue::drop_ty_immediate(bcx, self.val, self.ty, debug_loc)
|
||||
@ -937,9 +938,9 @@ impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> {
|
||||
|
||||
fn trans<'blk>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
apply_debug_loc(bcx.fcx, debug_loc);
|
||||
debug_loc.apply(bcx.fcx);
|
||||
|
||||
match self.heap {
|
||||
HeapExchange => {
|
||||
@ -972,9 +973,9 @@ impl<'tcx> Cleanup<'tcx> for FreeSlice {
|
||||
|
||||
fn trans<'blk>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
apply_debug_loc(bcx.fcx, debug_loc);
|
||||
debug_loc.apply(bcx.fcx);
|
||||
|
||||
match self.heap {
|
||||
HeapExchange => {
|
||||
@ -1004,9 +1005,9 @@ impl<'tcx> Cleanup<'tcx> for LifetimeEnd {
|
||||
|
||||
fn trans<'blk>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
apply_debug_loc(bcx.fcx, debug_loc);
|
||||
debug_loc.apply(bcx.fcx);
|
||||
base::call_lifetime_end(bcx, self.ptr);
|
||||
bcx
|
||||
}
|
||||
@ -1041,33 +1042,22 @@ fn cleanup_is_suitable_for(c: &Cleanup,
|
||||
!label.is_unwind() || c.clean_on_unwind()
|
||||
}
|
||||
|
||||
fn apply_debug_loc(fcx: &FunctionContext, debug_loc: Option<NodeInfo>) {
|
||||
match debug_loc {
|
||||
Some(ref src_loc) => {
|
||||
debuginfo::set_source_location(fcx, src_loc.id, src_loc.span);
|
||||
}
|
||||
None => {
|
||||
debuginfo::clear_source_location(fcx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// These traits just exist to put the methods into this file.
|
||||
|
||||
pub trait CleanupMethods<'blk, 'tcx> {
|
||||
fn push_ast_cleanup_scope(&self, id: NodeInfo);
|
||||
fn push_ast_cleanup_scope(&self, id: NodeIdAndSpan);
|
||||
fn push_loop_cleanup_scope(&self,
|
||||
id: ast::NodeId,
|
||||
exits: [Block<'blk, 'tcx>; EXIT_MAX]);
|
||||
fn push_custom_cleanup_scope(&self) -> CustomScopeIndex;
|
||||
fn push_custom_cleanup_scope_with_debug_loc(&self,
|
||||
debug_loc: NodeInfo)
|
||||
debug_loc: NodeIdAndSpan)
|
||||
-> CustomScopeIndex;
|
||||
fn pop_and_trans_ast_cleanup_scope(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
cleanup_scope: ast::NodeId)
|
||||
-> Block<'blk, 'tcx>;
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
cleanup_scope: ast::NodeId)
|
||||
-> Block<'blk, 'tcx>;
|
||||
fn pop_loop_cleanup_scope(&self,
|
||||
cleanup_scope: ast::NodeId);
|
||||
fn pop_custom_cleanup_scope(&self,
|
||||
|
@ -30,7 +30,7 @@ use trans::build;
|
||||
use trans::cleanup;
|
||||
use trans::consts;
|
||||
use trans::datum;
|
||||
use trans::debuginfo;
|
||||
use trans::debuginfo::{self, DebugLoc};
|
||||
use trans::machine;
|
||||
use trans::monomorphize;
|
||||
use trans::type_::Type;
|
||||
@ -317,13 +317,13 @@ pub struct tydesc_info<'tcx> {
|
||||
*/
|
||||
|
||||
#[derive(Copy)]
|
||||
pub struct NodeInfo {
|
||||
pub struct NodeIdAndSpan {
|
||||
pub id: ast::NodeId,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
|
||||
NodeInfo { id: expr.id, span: expr.span }
|
||||
pub fn expr_info(expr: &ast::Expr) -> NodeIdAndSpan {
|
||||
NodeIdAndSpan { id: expr.id, span: expr.span }
|
||||
}
|
||||
|
||||
pub struct BuilderRef_res {
|
||||
@ -517,7 +517,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||
let mut reachable = false;
|
||||
for bcx in in_cxs.iter() {
|
||||
if !bcx.unreachable.get() {
|
||||
build::Br(*bcx, out.llbb);
|
||||
build::Br(*bcx, out.llbb, DebugLoc::None);
|
||||
reachable = true;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ use trans::common::*;
|
||||
use trans::consts;
|
||||
use trans::datum;
|
||||
use trans::debuginfo;
|
||||
use trans::debuginfo::{DebugLoc, ToDebugLoc};
|
||||
use trans::expr;
|
||||
use trans::meth;
|
||||
use trans::type_::Type;
|
||||
@ -188,6 +189,8 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let then_bcx_out = trans_block(then_bcx_in, &*thn, dest);
|
||||
trans::debuginfo::clear_source_location(bcx.fcx);
|
||||
|
||||
let cond_source_loc = cond.debug_loc();
|
||||
|
||||
let next_bcx;
|
||||
match els {
|
||||
Some(elexpr) => {
|
||||
@ -195,13 +198,13 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let else_bcx_out = expr::trans_into(else_bcx_in, &*elexpr, dest);
|
||||
next_bcx = bcx.fcx.join_blocks(if_id,
|
||||
&[then_bcx_out, else_bcx_out]);
|
||||
CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb);
|
||||
CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb, cond_source_loc);
|
||||
}
|
||||
|
||||
None => {
|
||||
next_bcx = bcx.fcx.new_id_block("next-block", if_id);
|
||||
Br(then_bcx_out, next_bcx.llbb);
|
||||
CondBr(bcx, cond_val, then_bcx_in.llbb, next_bcx.llbb);
|
||||
Br(then_bcx_out, next_bcx.llbb, DebugLoc::None);
|
||||
CondBr(bcx, cond_val, then_bcx_in.llbb, next_bcx.llbb, cond_source_loc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +216,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
loop_id: ast::NodeId,
|
||||
loop_expr: &ast::Expr,
|
||||
cond: &ast::Expr,
|
||||
body: &ast::Block)
|
||||
-> Block<'blk, 'tcx> {
|
||||
@ -231,33 +234,34 @@ pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// | body_bcx_out --+
|
||||
// next_bcx_in
|
||||
|
||||
let next_bcx_in = fcx.new_id_block("while_exit", loop_id);
|
||||
let next_bcx_in = fcx.new_id_block("while_exit", loop_expr.id);
|
||||
let cond_bcx_in = fcx.new_id_block("while_cond", cond.id);
|
||||
let body_bcx_in = fcx.new_id_block("while_body", body.id);
|
||||
|
||||
fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, cond_bcx_in]);
|
||||
fcx.push_loop_cleanup_scope(loop_expr.id, [next_bcx_in, cond_bcx_in]);
|
||||
|
||||
Br(bcx, cond_bcx_in.llbb);
|
||||
Br(bcx, cond_bcx_in.llbb, loop_expr.debug_loc());
|
||||
|
||||
// compile the block where we will handle loop cleanups
|
||||
let cleanup_llbb = fcx.normal_exit_block(loop_id, cleanup::EXIT_BREAK);
|
||||
let cleanup_llbb = fcx.normal_exit_block(loop_expr.id, cleanup::EXIT_BREAK);
|
||||
|
||||
// compile the condition
|
||||
let Result {bcx: cond_bcx_out, val: cond_val} =
|
||||
expr::trans(cond_bcx_in, cond).to_llbool();
|
||||
CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, cleanup_llbb);
|
||||
|
||||
CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, cleanup_llbb, cond.debug_loc());
|
||||
|
||||
// loop body:
|
||||
let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore);
|
||||
Br(body_bcx_out, cond_bcx_in.llbb);
|
||||
Br(body_bcx_out, cond_bcx_in.llbb, DebugLoc::None);
|
||||
|
||||
fcx.pop_loop_cleanup_scope(loop_id);
|
||||
fcx.pop_loop_cleanup_scope(loop_expr.id);
|
||||
return next_bcx_in;
|
||||
}
|
||||
|
||||
/// Translates a `for` loop.
|
||||
pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
loop_info: NodeInfo,
|
||||
loop_info: NodeIdAndSpan,
|
||||
pat: &ast::Pat,
|
||||
head: &ast::Expr,
|
||||
body: &ast::Block)
|
||||
@ -292,7 +296,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
let body_bcx_in = bcx.fcx.new_id_block("for_body", body.id);
|
||||
bcx.fcx.push_loop_cleanup_scope(loop_info.id,
|
||||
[next_bcx_in, loopback_bcx_in]);
|
||||
Br(bcx, loopback_bcx_in.llbb);
|
||||
Br(bcx, loopback_bcx_in.llbb, DebugLoc::None);
|
||||
let cleanup_llbb = bcx.fcx.normal_exit_block(loop_info.id,
|
||||
cleanup::EXIT_BREAK);
|
||||
|
||||
@ -347,7 +351,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
None);
|
||||
let i1_type = Type::i1(loopback_bcx_out.ccx());
|
||||
let llcondition = Trunc(loopback_bcx_out, lldiscriminant, i1_type);
|
||||
CondBr(loopback_bcx_out, llcondition, body_bcx_in.llbb, cleanup_llbb);
|
||||
CondBr(loopback_bcx_out, llcondition, body_bcx_in.llbb, cleanup_llbb, DebugLoc::None);
|
||||
|
||||
// Now we're in the body. Unpack the `Option` value into the programmer-
|
||||
// supplied pattern.
|
||||
@ -377,7 +381,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
body_bcx_out.fcx
|
||||
.pop_and_trans_custom_cleanup_scope(body_bcx_out,
|
||||
option_cleanup_scope);
|
||||
Br(body_bcx_out, loopback_bcx_in.llbb);
|
||||
Br(body_bcx_out, loopback_bcx_in.llbb, DebugLoc::None);
|
||||
|
||||
// Codegen cleanups and leave.
|
||||
next_bcx_in.fcx.pop_loop_cleanup_scope(loop_info.id);
|
||||
@ -385,7 +389,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
loop_id: ast::NodeId,
|
||||
loop_expr: &ast::Expr,
|
||||
body: &ast::Block)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("trans_loop");
|
||||
@ -402,22 +406,22 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// Links between body_bcx_in and next_bcx are created by
|
||||
// break statements.
|
||||
|
||||
let next_bcx_in = bcx.fcx.new_id_block("loop_exit", loop_id);
|
||||
let next_bcx_in = bcx.fcx.new_id_block("loop_exit", loop_expr.id);
|
||||
let body_bcx_in = bcx.fcx.new_id_block("loop_body", body.id);
|
||||
|
||||
fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, body_bcx_in]);
|
||||
fcx.push_loop_cleanup_scope(loop_expr.id, [next_bcx_in, body_bcx_in]);
|
||||
|
||||
Br(bcx, body_bcx_in.llbb);
|
||||
Br(bcx, body_bcx_in.llbb, loop_expr.debug_loc());
|
||||
let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore);
|
||||
Br(body_bcx_out, body_bcx_in.llbb);
|
||||
Br(body_bcx_out, body_bcx_in.llbb, DebugLoc::None);
|
||||
|
||||
fcx.pop_loop_cleanup_scope(loop_id);
|
||||
fcx.pop_loop_cleanup_scope(loop_expr.id);
|
||||
|
||||
return next_bcx_in;
|
||||
}
|
||||
|
||||
pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
expr_id: ast::NodeId,
|
||||
expr: &ast::Expr,
|
||||
opt_label: Option<Ident>,
|
||||
exit: uint)
|
||||
-> Block<'blk, 'tcx> {
|
||||
@ -432,7 +436,7 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let loop_id = match opt_label {
|
||||
None => fcx.top_loop_scope(),
|
||||
Some(_) => {
|
||||
match bcx.tcx().def_map.borrow().get(&expr_id) {
|
||||
match bcx.tcx().def_map.borrow().get(&expr.id) {
|
||||
Some(&def::DefLabel(loop_id)) => loop_id,
|
||||
ref r => {
|
||||
bcx.tcx().sess.bug(&format!("{:?} in def-map for label",
|
||||
@ -444,39 +448,40 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
// Generate appropriate cleanup code and branch
|
||||
let cleanup_llbb = fcx.normal_exit_block(loop_id, exit);
|
||||
Br(bcx, cleanup_llbb);
|
||||
Br(bcx, cleanup_llbb, expr.debug_loc());
|
||||
Unreachable(bcx); // anything afterwards should be ignored
|
||||
return bcx;
|
||||
}
|
||||
|
||||
pub fn trans_break<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
expr_id: ast::NodeId,
|
||||
expr: &ast::Expr,
|
||||
label_opt: Option<Ident>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_BREAK);
|
||||
return trans_break_cont(bcx, expr, label_opt, cleanup::EXIT_BREAK);
|
||||
}
|
||||
|
||||
pub fn trans_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
expr_id: ast::NodeId,
|
||||
expr: &ast::Expr,
|
||||
label_opt: Option<Ident>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_LOOP);
|
||||
return trans_break_cont(bcx, expr, label_opt, cleanup::EXIT_LOOP);
|
||||
}
|
||||
|
||||
pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
e: Option<&ast::Expr>)
|
||||
return_expr: &ast::Expr,
|
||||
retval_expr: Option<&ast::Expr>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("trans_ret");
|
||||
let fcx = bcx.fcx;
|
||||
let mut bcx = bcx;
|
||||
let dest = match (fcx.llretslotptr.get(), e) {
|
||||
(Some(_), Some(e)) => {
|
||||
let ret_ty = expr_ty(bcx, &*e);
|
||||
let dest = match (fcx.llretslotptr.get(), retval_expr) {
|
||||
(Some(_), Some(retval_expr)) => {
|
||||
let ret_ty = expr_ty(bcx, &*retval_expr);
|
||||
expr::SaveIn(fcx.get_ret_slot(bcx, ty::FnConverging(ret_ty), "ret_slot"))
|
||||
}
|
||||
_ => expr::Ignore,
|
||||
};
|
||||
if let Some(x) = e {
|
||||
if let Some(x) = retval_expr {
|
||||
bcx = expr::trans_into(bcx, &*x, dest);
|
||||
match dest {
|
||||
expr::SaveIn(slot) if fcx.needs_ret_allocas => {
|
||||
@ -486,7 +491,7 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
}
|
||||
let cleanup_llbb = fcx.return_exit_block();
|
||||
Br(bcx, cleanup_llbb);
|
||||
Br(bcx, cleanup_llbb, return_expr.debug_loc());
|
||||
Unreachable(bcx);
|
||||
return bcx;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ use self::MemberOffset::*;
|
||||
use self::MemberDescriptionFactory::*;
|
||||
use self::RecursiveTypeDescription::*;
|
||||
use self::EnumDiscriminantInfo::*;
|
||||
use self::DebugLocation::*;
|
||||
use self::InternalDebugLocation::*;
|
||||
|
||||
use llvm;
|
||||
use llvm::{ModuleRef, ContextRef, ValueRef};
|
||||
@ -196,7 +196,8 @@ use llvm::debuginfo::*;
|
||||
use metadata::csearch;
|
||||
use middle::subst::{self, Substs};
|
||||
use trans::{self, adt, machine, type_of};
|
||||
use trans::common::*;
|
||||
use trans::common::{self, NodeIdAndSpan, CrateContext, FunctionContext, Block,
|
||||
C_bytes, C_i32, C_i64, NormalizingUnboxedClosureTyper};
|
||||
use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
|
||||
use trans::monomorphize;
|
||||
use trans::type_::Type;
|
||||
@ -624,7 +625,7 @@ macro_rules! return_if_metadata_created_in_meantime {
|
||||
pub struct CrateDebugContext<'tcx> {
|
||||
llcontext: ContextRef,
|
||||
builder: DIBuilderRef,
|
||||
current_debug_location: Cell<DebugLocation>,
|
||||
current_debug_location: Cell<InternalDebugLocation>,
|
||||
created_files: RefCell<FnvHashMap<String, DIFile>>,
|
||||
created_enum_disr_types: RefCell<DefIdMap<DIType>>,
|
||||
|
||||
@ -914,13 +915,14 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
};
|
||||
|
||||
let variable_type = node_id_type(bcx, node_id);
|
||||
let variable_type = common::node_id_type(bcx, node_id);
|
||||
let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
|
||||
|
||||
// env_pointer is the alloca containing the pointer to the environment,
|
||||
// so it's type is **EnvironmentType. In order to find out the type of
|
||||
// the environment we have to "dereference" two times.
|
||||
let llvm_env_data_type = val_ty(env_pointer).element_type().element_type();
|
||||
let llvm_env_data_type = common::val_ty(env_pointer).element_type()
|
||||
.element_type();
|
||||
let byte_offset_of_var_in_env = machine::llelement_offset(cx,
|
||||
llvm_env_data_type,
|
||||
env_index);
|
||||
@ -1097,7 +1099,7 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
node_span: Span,
|
||||
is_block: bool)
|
||||
-> NodeInfo {
|
||||
-> NodeIdAndSpan {
|
||||
// A debug location needs two things:
|
||||
// (1) A span (of which only the beginning will actually be used)
|
||||
// (2) An AST node-id which will be used to look up the lexical scope
|
||||
@ -1147,12 +1149,56 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
NodeInfo {
|
||||
NodeIdAndSpan {
|
||||
id: node_id,
|
||||
span: cleanup_span
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum DebugLoc {
|
||||
At(ast::NodeId, Span),
|
||||
None
|
||||
}
|
||||
|
||||
impl DebugLoc {
|
||||
pub fn apply(&self, fcx: &FunctionContext) {
|
||||
match *self {
|
||||
DebugLoc::At(node_id, span) => {
|
||||
set_source_location(fcx, node_id, span);
|
||||
}
|
||||
DebugLoc::None => {
|
||||
clear_source_location(fcx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToDebugLoc {
|
||||
fn debug_loc(&self) -> DebugLoc;
|
||||
}
|
||||
|
||||
impl ToDebugLoc for ast::Expr {
|
||||
fn debug_loc(&self) -> DebugLoc {
|
||||
DebugLoc::At(self.id, self.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToDebugLoc for NodeIdAndSpan {
|
||||
fn debug_loc(&self) -> DebugLoc {
|
||||
DebugLoc::At(self.id, self.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToDebugLoc for Option<NodeIdAndSpan> {
|
||||
fn debug_loc(&self) -> DebugLoc {
|
||||
match *self {
|
||||
Some(NodeIdAndSpan { id, span }) => DebugLoc::At(id, span),
|
||||
None => DebugLoc::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the current debug location at the beginning of the span.
|
||||
///
|
||||
/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
|
||||
@ -1176,9 +1222,9 @@ pub fn set_source_location(fcx: &FunctionContext,
|
||||
let loc = span_start(cx, span);
|
||||
let scope = scope_metadata(fcx, node_id, span);
|
||||
|
||||
set_debug_location(cx, DebugLocation::new(scope,
|
||||
loc.line,
|
||||
loc.col.to_usize()));
|
||||
set_debug_location(cx, InternalDebugLocation::new(scope,
|
||||
loc.line,
|
||||
loc.col.to_usize()));
|
||||
} else {
|
||||
set_debug_location(cx, UnknownLocation);
|
||||
}
|
||||
@ -1688,9 +1734,9 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
)
|
||||
};
|
||||
|
||||
set_debug_location(cx, DebugLocation::new(scope_metadata,
|
||||
loc.line,
|
||||
loc.col.to_usize()));
|
||||
set_debug_location(cx, InternalDebugLocation::new(scope_metadata,
|
||||
loc.line,
|
||||
loc.col.to_usize()));
|
||||
unsafe {
|
||||
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
|
||||
DIB(cx),
|
||||
@ -3069,13 +3115,13 @@ impl MetadataCreationResult {
|
||||
}
|
||||
|
||||
#[derive(Copy, PartialEq)]
|
||||
enum DebugLocation {
|
||||
enum InternalDebugLocation {
|
||||
KnownLocation { scope: DIScope, line: uint, col: uint },
|
||||
UnknownLocation
|
||||
}
|
||||
|
||||
impl DebugLocation {
|
||||
fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
|
||||
impl InternalDebugLocation {
|
||||
fn new(scope: DIScope, line: uint, col: uint) -> InternalDebugLocation {
|
||||
KnownLocation {
|
||||
scope: scope,
|
||||
line: line,
|
||||
@ -3084,7 +3130,7 @@ impl DebugLocation {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
|
||||
fn set_debug_location(cx: &CrateContext, debug_location: InternalDebugLocation) {
|
||||
if debug_location == debug_context(cx).current_debug_location.get() {
|
||||
return;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ use trans::build::*;
|
||||
use trans::cleanup::{self, CleanupMethods};
|
||||
use trans::common::*;
|
||||
use trans::datum::*;
|
||||
use trans::debuginfo;
|
||||
use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
|
||||
use trans::glue;
|
||||
use trans::machine;
|
||||
use trans::meth;
|
||||
@ -778,7 +778,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let expected = Call(bcx,
|
||||
expect,
|
||||
&[bounds_check, C_bool(ccx, false)],
|
||||
None);
|
||||
None,
|
||||
index_expr.debug_loc());
|
||||
bcx = with_cond(bcx, expected, |bcx| {
|
||||
controlflow::trans_fail_bounds_check(bcx,
|
||||
index_expr.span,
|
||||
@ -889,10 +890,10 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
trans_into(bcx, &**e, Ignore)
|
||||
}
|
||||
ast::ExprBreak(label_opt) => {
|
||||
controlflow::trans_break(bcx, expr.id, label_opt)
|
||||
controlflow::trans_break(bcx, expr, label_opt)
|
||||
}
|
||||
ast::ExprAgain(label_opt) => {
|
||||
controlflow::trans_cont(bcx, expr.id, label_opt)
|
||||
controlflow::trans_cont(bcx, expr, label_opt)
|
||||
}
|
||||
ast::ExprRet(ref ex) => {
|
||||
// Check to see if the return expression itself is reachable.
|
||||
@ -904,7 +905,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
};
|
||||
|
||||
if reachable {
|
||||
controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e))
|
||||
controlflow::trans_ret(bcx, expr, ex.as_ref().map(|e| &**e))
|
||||
} else {
|
||||
// If it's not reachable, just translate the inner expression
|
||||
// directly. This avoids having to manage a return slot when
|
||||
@ -920,7 +921,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
}
|
||||
ast::ExprWhile(ref cond, ref body, _) => {
|
||||
controlflow::trans_while(bcx, expr.id, &**cond, &**body)
|
||||
controlflow::trans_while(bcx, expr, &**cond, &**body)
|
||||
}
|
||||
ast::ExprForLoop(ref pat, ref head, ref body, _) => {
|
||||
controlflow::trans_for(bcx,
|
||||
@ -930,7 +931,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
&**body)
|
||||
}
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
controlflow::trans_loop(bcx, expr.id, &**body)
|
||||
controlflow::trans_loop(bcx, expr, &**body)
|
||||
}
|
||||
ast::ExprAssign(ref dst, ref src) => {
|
||||
let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
|
||||
@ -959,7 +960,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
bcx = glue::drop_ty(bcx,
|
||||
dst_datum.val,
|
||||
dst_datum.ty,
|
||||
Some(NodeInfo { id: expr.id, span: expr.span }));
|
||||
expr.debug_loc());
|
||||
src_datum.store_to(bcx, dst_datum.val)
|
||||
} else {
|
||||
src_datum.store_to(bcx, dst_datum.val)
|
||||
@ -1077,7 +1078,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
&numbered_fields[],
|
||||
None,
|
||||
dest,
|
||||
Some(NodeInfo { id: expr.id, span: expr.span }))
|
||||
expr.debug_loc())
|
||||
}
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
@ -1406,7 +1407,7 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
numbered_fields.as_slice(),
|
||||
optbase,
|
||||
dest,
|
||||
Some(NodeInfo { id: expr_id, span: expr_span }))
|
||||
DebugLoc::At(expr_id, expr_span))
|
||||
})
|
||||
}
|
||||
|
||||
@ -1437,18 +1438,13 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
fields: &[(uint, &ast::Expr)],
|
||||
optbase: Option<StructBaseInfo<'a, 'tcx>>,
|
||||
dest: Dest,
|
||||
source_location: Option<NodeInfo>)
|
||||
debug_location: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("trans_adt");
|
||||
let fcx = bcx.fcx;
|
||||
let repr = adt::represent_type(bcx.ccx(), ty);
|
||||
|
||||
match source_location {
|
||||
Some(src_loc) => debuginfo::set_source_location(bcx.fcx,
|
||||
src_loc.id,
|
||||
src_loc.span),
|
||||
None => {}
|
||||
};
|
||||
debug_location.apply(bcx.fcx);
|
||||
|
||||
// If we don't care about the result, just make a
|
||||
// temporary stack slot
|
||||
@ -1483,12 +1479,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
match source_location {
|
||||
Some(src_loc) => debuginfo::set_source_location(bcx.fcx,
|
||||
src_loc.id,
|
||||
src_loc.span),
|
||||
None => {}
|
||||
};
|
||||
debug_location.apply(bcx.fcx);
|
||||
|
||||
if ty::type_is_simd(bcx.tcx(), ty) {
|
||||
// This is the constructor of a SIMD type, such types are
|
||||
@ -1529,7 +1520,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
match dest {
|
||||
SaveIn(_) => bcx,
|
||||
Ignore => {
|
||||
bcx = glue::drop_ty(bcx, addr, ty, source_location);
|
||||
bcx = glue::drop_ty(bcx, addr, ty, debug_location);
|
||||
base::call_lifetime_end(bcx, addr);
|
||||
bcx
|
||||
}
|
||||
@ -1568,10 +1559,12 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
let un_ty = expr_ty(bcx, expr);
|
||||
|
||||
let debug_loc = expr.debug_loc();
|
||||
|
||||
match op {
|
||||
ast::UnNot => {
|
||||
let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
|
||||
let llresult = Not(bcx, datum.to_llscalarish(bcx));
|
||||
let llresult = Not(bcx, datum.to_llscalarish(bcx), debug_loc);
|
||||
immediate_rvalue_bcx(bcx, llresult, un_ty).to_expr_datumblock()
|
||||
}
|
||||
ast::UnNeg => {
|
||||
@ -1579,9 +1572,9 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let val = datum.to_llscalarish(bcx);
|
||||
let llneg = {
|
||||
if ty::type_is_fp(un_ty) {
|
||||
FNeg(bcx, val)
|
||||
FNeg(bcx, val, debug_loc)
|
||||
} else {
|
||||
Neg(bcx, val)
|
||||
Neg(bcx, val, debug_loc)
|
||||
}
|
||||
};
|
||||
immediate_rvalue_bcx(bcx, llneg, un_ty).to_expr_datumblock()
|
||||
@ -1680,56 +1673,69 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs);
|
||||
|
||||
let binop_debug_loc = binop_expr.debug_loc();
|
||||
|
||||
let mut bcx = bcx;
|
||||
let val = match op {
|
||||
ast::BiAdd => {
|
||||
if is_float { FAdd(bcx, lhs, rhs) }
|
||||
else { Add(bcx, lhs, rhs) }
|
||||
if is_float {
|
||||
FAdd(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
Add(bcx, lhs, rhs, binop_debug_loc)
|
||||
}
|
||||
}
|
||||
ast::BiSub => {
|
||||
if is_float { FSub(bcx, lhs, rhs) }
|
||||
else { Sub(bcx, lhs, rhs) }
|
||||
if is_float {
|
||||
FSub(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
Sub(bcx, lhs, rhs, binop_debug_loc)
|
||||
}
|
||||
}
|
||||
ast::BiMul => {
|
||||
if is_float { FMul(bcx, lhs, rhs) }
|
||||
else { Mul(bcx, lhs, rhs) }
|
||||
if is_float {
|
||||
FMul(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
Mul(bcx, lhs, rhs, binop_debug_loc)
|
||||
}
|
||||
}
|
||||
ast::BiDiv => {
|
||||
if is_float {
|
||||
FDiv(bcx, lhs, rhs)
|
||||
FDiv(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
// Only zero-check integers; fp /0 is NaN
|
||||
bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span,
|
||||
op, lhs, rhs, rhs_t);
|
||||
if is_signed {
|
||||
SDiv(bcx, lhs, rhs)
|
||||
SDiv(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
UDiv(bcx, lhs, rhs)
|
||||
UDiv(bcx, lhs, rhs, binop_debug_loc)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::BiRem => {
|
||||
if is_float {
|
||||
FRem(bcx, lhs, rhs)
|
||||
FRem(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
// Only zero-check integers; fp %0 is NaN
|
||||
bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span,
|
||||
op, lhs, rhs, rhs_t);
|
||||
if is_signed {
|
||||
SRem(bcx, lhs, rhs)
|
||||
SRem(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
URem(bcx, lhs, rhs)
|
||||
URem(bcx, lhs, rhs, binop_debug_loc)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::BiBitOr => Or(bcx, lhs, rhs),
|
||||
ast::BiBitAnd => And(bcx, lhs, rhs),
|
||||
ast::BiBitXor => Xor(bcx, lhs, rhs),
|
||||
ast::BiShl => Shl(bcx, lhs, rhs),
|
||||
ast::BiBitOr => Or(bcx, lhs, rhs, binop_debug_loc),
|
||||
ast::BiBitAnd => And(bcx, lhs, rhs, binop_debug_loc),
|
||||
ast::BiBitXor => Xor(bcx, lhs, rhs, binop_debug_loc),
|
||||
ast::BiShl => Shl(bcx, lhs, rhs, binop_debug_loc),
|
||||
ast::BiShr => {
|
||||
if is_signed {
|
||||
AShr(bcx, lhs, rhs)
|
||||
} else { LShr(bcx, lhs, rhs) }
|
||||
AShr(bcx, lhs, rhs, binop_debug_loc)
|
||||
} else {
|
||||
LShr(bcx, lhs, rhs, binop_debug_loc)
|
||||
}
|
||||
}
|
||||
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiGe | ast::BiLe | ast::BiGt => {
|
||||
if ty::type_is_scalar(rhs_t) {
|
||||
@ -1775,8 +1781,8 @@ fn trans_lazy_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let before_rhs = fcx.new_id_block("before_rhs", b.id);
|
||||
|
||||
match op {
|
||||
lazy_and => CondBr(past_lhs, lhs, before_rhs.llbb, join.llbb),
|
||||
lazy_or => CondBr(past_lhs, lhs, join.llbb, before_rhs.llbb)
|
||||
lazy_and => CondBr(past_lhs, lhs, before_rhs.llbb, join.llbb, DebugLoc::None),
|
||||
lazy_or => CondBr(past_lhs, lhs, join.llbb, before_rhs.llbb, DebugLoc::None)
|
||||
}
|
||||
|
||||
let DatumBlock {bcx: past_rhs, datum: rhs} = trans(before_rhs, b);
|
||||
@ -1786,7 +1792,7 @@ fn trans_lazy_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
return immediate_rvalue_bcx(join, lhs, binop_ty).to_expr_datumblock();
|
||||
}
|
||||
|
||||
Br(past_rhs, join.llbb);
|
||||
Br(past_rhs, join.llbb, DebugLoc::None);
|
||||
let phi = Phi(join, Type::i1(bcx.ccx()), &[lhs, rhs],
|
||||
&[past_lhs.llbb, past_rhs.llbb]);
|
||||
|
||||
|
@ -29,7 +29,7 @@ use trans::cleanup::CleanupMethods;
|
||||
use trans::consts;
|
||||
use trans::common::*;
|
||||
use trans::datum;
|
||||
use trans::debuginfo;
|
||||
use trans::debuginfo::DebugLoc;
|
||||
use trans::expr;
|
||||
use trans::machine::*;
|
||||
use trans::tvec;
|
||||
@ -106,7 +106,7 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
v: ValueRef,
|
||||
t: Ty<'tcx>,
|
||||
source_location: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
// NB: v is an *alias* of type t here, not a direct value.
|
||||
debug!("drop_ty(t={})", t.repr(bcx.tcx()));
|
||||
@ -121,12 +121,7 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
v
|
||||
};
|
||||
|
||||
match source_location {
|
||||
Some(sl) => debuginfo::set_source_location(bcx.fcx, sl.id, sl.span),
|
||||
None => debuginfo::clear_source_location(bcx.fcx)
|
||||
};
|
||||
|
||||
Call(bcx, glue, &[ptr], None);
|
||||
Call(bcx, glue, &[ptr], None, debug_loc);
|
||||
}
|
||||
bcx
|
||||
}
|
||||
@ -134,12 +129,12 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
pub fn drop_ty_immediate<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
v: ValueRef,
|
||||
t: Ty<'tcx>,
|
||||
source_location: Option<NodeInfo>)
|
||||
debug_loc: DebugLoc)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("drop_ty_immediate");
|
||||
let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
|
||||
store_ty(bcx, v, vp, t);
|
||||
drop_ty(bcx, vp, t, source_location)
|
||||
drop_ty(bcx, vp, t, debug_loc)
|
||||
}
|
||||
|
||||
pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> ValueRef {
|
||||
@ -295,7 +290,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
class_did,
|
||||
&[get_drop_glue_type(bcx.ccx(), t)],
|
||||
ty::mk_nil(bcx.tcx()));
|
||||
let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, None);
|
||||
let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, DebugLoc::None);
|
||||
|
||||
variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
|
||||
variant_cx
|
||||
@ -331,7 +326,7 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info:
|
||||
let (unsized_size, unsized_align) = size_and_align_of_dst(bcx, field_ty, info);
|
||||
|
||||
// Return the sum of sizes and max of aligns.
|
||||
let size = Add(bcx, sized_size, unsized_size);
|
||||
let size = Add(bcx, sized_size, unsized_size, DebugLoc::None);
|
||||
let align = Select(bcx,
|
||||
ICmp(bcx, llvm::IntULT, sized_align, unsized_align),
|
||||
sized_align,
|
||||
@ -353,7 +348,8 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info:
|
||||
let llunit_ty = sizing_type_of(bcx.ccx(), unit_ty);
|
||||
let unit_align = llalign_of_min(bcx.ccx(), llunit_ty);
|
||||
let unit_size = llsize_of_alloc(bcx.ccx(), llunit_ty);
|
||||
(Mul(bcx, info, C_uint(bcx.ccx(), unit_size)), C_uint(bcx.ccx(), unit_align))
|
||||
(Mul(bcx, info, C_uint(bcx.ccx(), unit_size), DebugLoc::None),
|
||||
C_uint(bcx.ccx(), unit_align))
|
||||
}
|
||||
_ => bcx.sess().bug(&format!("Unexpected unsized type, found {}",
|
||||
bcx.ty_to_string(t))[])
|
||||
@ -384,7 +380,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
Call(bcx,
|
||||
dtor,
|
||||
&[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
|
||||
None);
|
||||
None,
|
||||
DebugLoc::None);
|
||||
bcx
|
||||
})
|
||||
}
|
||||
@ -393,7 +390,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
let llbox = Load(bcx, llval);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let bcx = drop_ty(bcx, v0, content_ty, None);
|
||||
let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
|
||||
let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
|
||||
let info = Load(bcx, info);
|
||||
let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
|
||||
@ -406,7 +403,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
let llbox = Load(bcx, llval);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let bcx = drop_ty(bcx, llbox, content_ty, None);
|
||||
let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
|
||||
trans_exchange_free_ty(bcx, llbox, content_ty)
|
||||
})
|
||||
}
|
||||
@ -437,14 +434,16 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
}
|
||||
ty::NoDtor => {
|
||||
// No dtor? Just the default case
|
||||
iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, None))
|
||||
iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None))
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_unboxed_closure(..) => iter_structural_ty(bcx,
|
||||
v0,
|
||||
t,
|
||||
|bb, vv, tt| drop_ty(bb, vv, tt, None)),
|
||||
ty::ty_unboxed_closure(..) => {
|
||||
iter_structural_ty(bcx,
|
||||
v0,
|
||||
t,
|
||||
|bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None))
|
||||
}
|
||||
ty::ty_trait(..) => {
|
||||
// No need to do a null check here (as opposed to the Box<trait case
|
||||
// above), because this happens for a trait field in an unsized
|
||||
@ -456,7 +455,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
Call(bcx,
|
||||
dtor,
|
||||
&[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
|
||||
None);
|
||||
None,
|
||||
DebugLoc::None);
|
||||
bcx
|
||||
},
|
||||
ty::ty_vec(_, None) | ty::ty_str => {
|
||||
@ -465,9 +465,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
},
|
||||
_ => {
|
||||
assert!(type_is_sized(bcx.tcx(), t));
|
||||
if type_needs_drop(bcx.tcx(), t) &&
|
||||
ty::type_is_structural(t) {
|
||||
iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, None))
|
||||
if type_needs_drop(bcx.tcx(), t) && ty::type_is_structural(t) {
|
||||
iter_structural_ty(bcx,
|
||||
v0,
|
||||
t,
|
||||
|bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None))
|
||||
} else {
|
||||
bcx
|
||||
}
|
||||
@ -559,7 +561,7 @@ fn make_generic_glue<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint);
|
||||
let bcx = helper(bcx, llrawptr0, t);
|
||||
finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())));
|
||||
finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None);
|
||||
|
||||
llfn
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use trans::cleanup;
|
||||
use trans::cleanup::CleanupMethods;
|
||||
use trans::common::*;
|
||||
use trans::datum::*;
|
||||
use trans::debuginfo::DebugLoc;
|
||||
use trans::expr;
|
||||
use trans::glue;
|
||||
use trans::type_of::*;
|
||||
@ -149,9 +150,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
args: callee::CallArgs<'a, 'tcx>,
|
||||
dest: expr::Dest,
|
||||
substs: subst::Substs<'tcx>,
|
||||
call_info: NodeInfo)
|
||||
-> Result<'blk, 'tcx>
|
||||
{
|
||||
call_info: NodeIdAndSpan)
|
||||
-> Result<'blk, 'tcx> {
|
||||
let fcx = bcx.fcx;
|
||||
let ccx = fcx.ccx;
|
||||
let tcx = bcx.tcx();
|
||||
@ -270,10 +270,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
|
||||
fcx.pop_custom_cleanup_scope(cleanup_scope);
|
||||
|
||||
let call_debug_location = DebugLoc::At(call_info.id, call_info.span);
|
||||
|
||||
// These are the only intrinsic functions that diverge.
|
||||
if name.get() == "abort" {
|
||||
let llfn = ccx.get_intrinsic(&("llvm.trap"));
|
||||
Call(bcx, llfn, &[], None);
|
||||
Call(bcx, llfn, &[], None, call_debug_location);
|
||||
Unreachable(bcx);
|
||||
return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to()));
|
||||
} else if name.get() == "unreachable" {
|
||||
@ -304,11 +306,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
let simple = get_simple_intrinsic(ccx, &*foreign_item);
|
||||
let llval = match (simple, name.get()) {
|
||||
(Some(llfn), _) => {
|
||||
Call(bcx, llfn, llargs.as_slice(), None)
|
||||
Call(bcx, llfn, llargs.as_slice(), None, call_debug_location)
|
||||
}
|
||||
(_, "breakpoint") => {
|
||||
let llfn = ccx.get_intrinsic(&("llvm.debugtrap"));
|
||||
Call(bcx, llfn, &[], None)
|
||||
Call(bcx, llfn, &[], None, call_debug_location)
|
||||
}
|
||||
(_, "size_of") => {
|
||||
let tp_ty = *substs.types.get(FnSpace, 0);
|
||||
@ -384,29 +386,63 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
(_, "copy_nonoverlapping_memory") => {
|
||||
copy_intrinsic(bcx, false, false, *substs.types.get(FnSpace, 0),
|
||||
llargs[0], llargs[1], llargs[2])
|
||||
copy_intrinsic(bcx,
|
||||
false,
|
||||
false,
|
||||
*substs.types.get(FnSpace, 0),
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
llargs[2],
|
||||
call_debug_location)
|
||||
}
|
||||
(_, "copy_memory") => {
|
||||
copy_intrinsic(bcx, true, false, *substs.types.get(FnSpace, 0),
|
||||
llargs[0], llargs[1], llargs[2])
|
||||
copy_intrinsic(bcx,
|
||||
true,
|
||||
false,
|
||||
*substs.types.get(FnSpace, 0),
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
llargs[2],
|
||||
call_debug_location)
|
||||
}
|
||||
(_, "set_memory") => {
|
||||
memset_intrinsic(bcx, false, *substs.types.get(FnSpace, 0),
|
||||
llargs[0], llargs[1], llargs[2])
|
||||
memset_intrinsic(bcx,
|
||||
false,
|
||||
*substs.types.get(FnSpace, 0),
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
llargs[2],
|
||||
call_debug_location)
|
||||
}
|
||||
|
||||
(_, "volatile_copy_nonoverlapping_memory") => {
|
||||
copy_intrinsic(bcx, false, true, *substs.types.get(FnSpace, 0),
|
||||
llargs[0], llargs[1], llargs[2])
|
||||
copy_intrinsic(bcx,
|
||||
false,
|
||||
true,
|
||||
*substs.types.get(FnSpace, 0),
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
llargs[2],
|
||||
call_debug_location)
|
||||
}
|
||||
(_, "volatile_copy_memory") => {
|
||||
copy_intrinsic(bcx, true, true, *substs.types.get(FnSpace, 0),
|
||||
llargs[0], llargs[1], llargs[2])
|
||||
copy_intrinsic(bcx,
|
||||
true,
|
||||
true,
|
||||
*substs.types.get(FnSpace, 0),
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
llargs[2],
|
||||
call_debug_location)
|
||||
}
|
||||
(_, "volatile_set_memory") => {
|
||||
memset_intrinsic(bcx, true, *substs.types.get(FnSpace, 0),
|
||||
llargs[0], llargs[1], llargs[2])
|
||||
memset_intrinsic(bcx,
|
||||
true,
|
||||
*substs.types.get(FnSpace, 0),
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
llargs[2],
|
||||
call_debug_location)
|
||||
}
|
||||
(_, "volatile_load") => {
|
||||
VolatileLoad(bcx, llargs[0])
|
||||
@ -416,93 +452,208 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
C_nil(ccx)
|
||||
},
|
||||
|
||||
(_, "ctlz8") => count_zeros_intrinsic(bcx, "llvm.ctlz.i8", llargs[0]),
|
||||
(_, "ctlz16") => count_zeros_intrinsic(bcx, "llvm.ctlz.i16", llargs[0]),
|
||||
(_, "ctlz32") => count_zeros_intrinsic(bcx, "llvm.ctlz.i32", llargs[0]),
|
||||
(_, "ctlz64") => count_zeros_intrinsic(bcx, "llvm.ctlz.i64", llargs[0]),
|
||||
(_, "cttz8") => count_zeros_intrinsic(bcx, "llvm.cttz.i8", llargs[0]),
|
||||
(_, "cttz16") => count_zeros_intrinsic(bcx, "llvm.cttz.i16", llargs[0]),
|
||||
(_, "cttz32") => count_zeros_intrinsic(bcx, "llvm.cttz.i32", llargs[0]),
|
||||
(_, "cttz64") => count_zeros_intrinsic(bcx, "llvm.cttz.i64", llargs[0]),
|
||||
(_, "ctlz8") => count_zeros_intrinsic(bcx,
|
||||
"llvm.ctlz.i8",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "ctlz16") => count_zeros_intrinsic(bcx,
|
||||
"llvm.ctlz.i16",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "ctlz32") => count_zeros_intrinsic(bcx,
|
||||
"llvm.ctlz.i32",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "ctlz64") => count_zeros_intrinsic(bcx,
|
||||
"llvm.ctlz.i64",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "cttz8") => count_zeros_intrinsic(bcx,
|
||||
"llvm.cttz.i8",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "cttz16") => count_zeros_intrinsic(bcx,
|
||||
"llvm.cttz.i16",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "cttz32") => count_zeros_intrinsic(bcx,
|
||||
"llvm.cttz.i32",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
(_, "cttz64") => count_zeros_intrinsic(bcx,
|
||||
"llvm.cttz.i64",
|
||||
llargs[0],
|
||||
call_debug_location),
|
||||
|
||||
(_, "i8_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i8", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.sadd.with.overflow.i8",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i16_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i16", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.sadd.with.overflow.i16",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i32_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i32", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.sadd.with.overflow.i32",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i64_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i64", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.sadd.with.overflow.i64",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
|
||||
(_, "u8_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i8", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.uadd.with.overflow.i8",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u16_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i16", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.uadd.with.overflow.i16",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u32_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i32", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.uadd.with.overflow.i32",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u64_add_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i64", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.uadd.with.overflow.i64",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i8_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i8", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.ssub.with.overflow.i8",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i16_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i16", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.ssub.with.overflow.i16",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i32_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i32", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.ssub.with.overflow.i32",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i64_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i64", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.ssub.with.overflow.i64",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u8_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i8", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.usub.with.overflow.i8",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u16_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i16", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.usub.with.overflow.i16",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u32_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i32", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.usub.with.overflow.i32",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u64_sub_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i64", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.usub.with.overflow.i64",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i8_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i8", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.smul.with.overflow.i8",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i16_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i16", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.smul.with.overflow.i16",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i32_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i32", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.smul.with.overflow.i32",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "i64_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i64", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.smul.with.overflow.i64",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u8_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i8", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.umul.with.overflow.i8",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u16_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i16", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.umul.with.overflow.i16",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u32_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i32", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.umul.with.overflow.i32",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "u64_mul_with_overflow") =>
|
||||
with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i64", ret_ty,
|
||||
llargs[0], llargs[1]),
|
||||
|
||||
with_overflow_intrinsic(bcx,
|
||||
"llvm.umul.with.overflow.i64",
|
||||
ret_ty,
|
||||
llargs[0],
|
||||
llargs[1],
|
||||
call_debug_location),
|
||||
(_, "return_address") => {
|
||||
if !fcx.caller_expects_out_pointer {
|
||||
tcx.sess.span_err(call_info.span,
|
||||
@ -609,7 +760,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
// If we made a temporary stack slot, let's clean it up
|
||||
match dest {
|
||||
expr::Ignore => {
|
||||
bcx = glue::drop_ty(bcx, llresult, ret_ty, Some(call_info));
|
||||
bcx = glue::drop_ty(bcx, llresult, ret_ty, call_debug_location);
|
||||
}
|
||||
expr::SaveIn(_) => {}
|
||||
}
|
||||
@ -618,8 +769,14 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
fn copy_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
allow_overlap: bool, volatile: bool, tp_ty: Ty<'tcx>,
|
||||
dst: ValueRef, src: ValueRef, count: ValueRef) -> ValueRef {
|
||||
allow_overlap: bool,
|
||||
volatile: bool,
|
||||
tp_ty: Ty<'tcx>,
|
||||
dst: ValueRef,
|
||||
src: ValueRef,
|
||||
count: ValueRef,
|
||||
call_debug_location: DebugLoc)
|
||||
-> ValueRef {
|
||||
let ccx = bcx.ccx();
|
||||
let lltp_ty = type_of::type_of(ccx, tp_ty);
|
||||
let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32);
|
||||
@ -643,12 +800,25 @@ fn copy_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let src_ptr = PointerCast(bcx, src, Type::i8p(ccx));
|
||||
let llfn = ccx.get_intrinsic(&name);
|
||||
|
||||
Call(bcx, llfn, &[dst_ptr, src_ptr, Mul(bcx, size, count), align,
|
||||
C_bool(ccx, volatile)], None)
|
||||
Call(bcx,
|
||||
llfn,
|
||||
&[dst_ptr,
|
||||
src_ptr,
|
||||
Mul(bcx, size, count, DebugLoc::None),
|
||||
align,
|
||||
C_bool(ccx, volatile)],
|
||||
None,
|
||||
call_debug_location)
|
||||
}
|
||||
|
||||
fn memset_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, volatile: bool, tp_ty: Ty<'tcx>,
|
||||
dst: ValueRef, val: ValueRef, count: ValueRef) -> ValueRef {
|
||||
fn memset_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
volatile: bool,
|
||||
tp_ty: Ty<'tcx>,
|
||||
dst: ValueRef,
|
||||
val: ValueRef,
|
||||
count: ValueRef,
|
||||
call_debug_location: DebugLoc)
|
||||
-> ValueRef {
|
||||
let ccx = bcx.ccx();
|
||||
let lltp_ty = type_of::type_of(ccx, tp_ty);
|
||||
let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32);
|
||||
@ -662,22 +832,38 @@ fn memset_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, volatile: bool, tp_ty: T
|
||||
let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
|
||||
let llfn = ccx.get_intrinsic(&name);
|
||||
|
||||
Call(bcx, llfn, &[dst_ptr, val, Mul(bcx, size, count), align,
|
||||
C_bool(ccx, volatile)], None)
|
||||
Call(bcx,
|
||||
llfn,
|
||||
&[dst_ptr,
|
||||
val,
|
||||
Mul(bcx, size, count, DebugLoc::None),
|
||||
align,
|
||||
C_bool(ccx, volatile)],
|
||||
None,
|
||||
call_debug_location)
|
||||
}
|
||||
|
||||
fn count_zeros_intrinsic(bcx: Block, name: &'static str, val: ValueRef) -> ValueRef {
|
||||
fn count_zeros_intrinsic(bcx: Block,
|
||||
name: &'static str,
|
||||
val: ValueRef,
|
||||
call_debug_location: DebugLoc)
|
||||
-> ValueRef {
|
||||
let y = C_bool(bcx.ccx(), false);
|
||||
let llfn = bcx.ccx().get_intrinsic(&name);
|
||||
Call(bcx, llfn, &[val, y], None)
|
||||
Call(bcx, llfn, &[val, y], None, call_debug_location)
|
||||
}
|
||||
|
||||
fn with_overflow_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, name: &'static str,
|
||||
t: Ty<'tcx>, a: ValueRef, b: ValueRef) -> ValueRef {
|
||||
fn with_overflow_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
name: &'static str,
|
||||
t: Ty<'tcx>,
|
||||
a: ValueRef,
|
||||
b: ValueRef,
|
||||
call_debug_location: DebugLoc)
|
||||
-> ValueRef {
|
||||
let llfn = bcx.ccx().get_intrinsic(&name);
|
||||
|
||||
// Convert `i1` to a `bool`, and write it to the out parameter
|
||||
let val = Call(bcx, llfn, &[a, b], None);
|
||||
let val = Call(bcx, llfn, &[a, b], None, call_debug_location);
|
||||
let result = ExtractValue(bcx, val, 0);
|
||||
let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx()));
|
||||
let ret = C_undef(type_of::type_of(bcx.ccx(), t));
|
||||
|
@ -24,6 +24,7 @@ use trans::callee;
|
||||
use trans::cleanup;
|
||||
use trans::common::*;
|
||||
use trans::datum::*;
|
||||
use trans::debuginfo::DebugLoc;
|
||||
use trans::expr::{SaveIn, Ignore};
|
||||
use trans::expr;
|
||||
use trans::glue;
|
||||
@ -676,7 +677,7 @@ pub fn trans_object_shim<'a, 'tcx>(
|
||||
ArgVals(llargs.as_slice()),
|
||||
dest).bcx;
|
||||
|
||||
finish_fn(&fcx, bcx, sig.output);
|
||||
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
|
||||
|
||||
(llfn, method_bare_fn_ty)
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use trans::cleanup::CleanupMethods;
|
||||
use trans::common::*;
|
||||
use trans::consts;
|
||||
use trans::datum::*;
|
||||
use trans::debuginfo::DebugLoc;
|
||||
use trans::expr::{Dest, Ignore, SaveIn};
|
||||
use trans::expr;
|
||||
use trans::glue;
|
||||
@ -58,7 +59,11 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let dataptr = get_dataptr(bcx, vptr);
|
||||
let bcx = if type_needs_drop(tcx, unit_ty) {
|
||||
let len = get_len(bcx, vptr);
|
||||
iter_vec_raw(bcx, dataptr, unit_ty, len, |bb, vv, tt| glue::drop_ty(bb, vv, tt, None))
|
||||
iter_vec_raw(bcx,
|
||||
dataptr,
|
||||
unit_ty,
|
||||
len,
|
||||
|bb, vv, tt| glue::drop_ty(bb, vv, tt, DebugLoc::None))
|
||||
} else {
|
||||
bcx
|
||||
};
|
||||
@ -71,7 +76,7 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let not_empty = ICmp(bcx, llvm::IntNE, len, C_uint(ccx, 0u));
|
||||
with_cond(bcx, not_empty, |bcx| {
|
||||
let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty));
|
||||
let size = Mul(bcx, C_uint(ccx, unit_size), len);
|
||||
let size = Mul(bcx, C_uint(ccx, unit_size), len, DebugLoc::None);
|
||||
glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
|
||||
})
|
||||
} else {
|
||||
@ -420,14 +425,14 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
let cond_bcx = fcx.new_temp_block("expr_repeat: loop cond");
|
||||
let body_bcx = fcx.new_temp_block("expr_repeat: body: set");
|
||||
let inc_bcx = fcx.new_temp_block("expr_repeat: body: inc");
|
||||
Br(bcx, loop_bcx.llbb);
|
||||
Br(bcx, loop_bcx.llbb, DebugLoc::None);
|
||||
|
||||
let loop_counter = {
|
||||
// i = 0
|
||||
let i = alloca(loop_bcx, bcx.ccx().int_type(), "__i");
|
||||
Store(loop_bcx, C_uint(bcx.ccx(), 0u), i);
|
||||
|
||||
Br(loop_bcx, cond_bcx.llbb);
|
||||
Br(loop_bcx, cond_bcx.llbb, DebugLoc::None);
|
||||
i
|
||||
};
|
||||
|
||||
@ -436,7 +441,7 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
let rhs = count;
|
||||
let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs);
|
||||
|
||||
CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb);
|
||||
CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
|
||||
}
|
||||
|
||||
{ // loop body
|
||||
@ -448,15 +453,15 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
};
|
||||
let body_bcx = f(body_bcx, lleltptr, vt.unit_ty);
|
||||
|
||||
Br(body_bcx, inc_bcx.llbb);
|
||||
Br(body_bcx, inc_bcx.llbb, DebugLoc::None);
|
||||
}
|
||||
|
||||
{ // i += 1
|
||||
let i = Load(inc_bcx, loop_counter);
|
||||
let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1u));
|
||||
let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1u), DebugLoc::None);
|
||||
Store(inc_bcx, plusone, loop_counter);
|
||||
|
||||
Br(inc_bcx, cond_bcx.llbb);
|
||||
Br(inc_bcx, cond_bcx.llbb, DebugLoc::None);
|
||||
}
|
||||
|
||||
next_bcx
|
||||
@ -484,19 +489,19 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
// Now perform the iteration.
|
||||
let header_bcx = fcx.new_temp_block("iter_vec_loop_header");
|
||||
Br(bcx, header_bcx.llbb);
|
||||
Br(bcx, header_bcx.llbb, DebugLoc::None);
|
||||
let data_ptr =
|
||||
Phi(header_bcx, val_ty(data_ptr), &[data_ptr], &[bcx.llbb]);
|
||||
let not_yet_at_end =
|
||||
ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr);
|
||||
let body_bcx = fcx.new_temp_block("iter_vec_loop_body");
|
||||
let next_bcx = fcx.new_temp_block("iter_vec_next");
|
||||
CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb);
|
||||
CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
|
||||
let body_bcx = f(body_bcx, data_ptr, vt.unit_ty);
|
||||
AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
|
||||
&[C_int(bcx.ccx(), 1i)]),
|
||||
body_bcx.llbb);
|
||||
Br(body_bcx, header_bcx.llbb);
|
||||
Br(body_bcx, header_bcx.llbb, DebugLoc::None);
|
||||
next_bcx
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user