提交 d98d5083 编写于 作者: M Michael Woerister

debuginfo: Assign debuginfo source locations to lang-item calls.

上级 7884eb8e
......@@ -244,25 +244,29 @@ fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
// An option identifying a branch (either a literal, an enum variant or a range)
#[derive(Debug)]
enum Opt<'a, 'tcx> {
ConstantValue(ConstantExpr<'a>),
ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>),
Variant(ty::Disr, Rc<adt::Repr<'tcx>>, ast::DefId),
SliceLengthEqual(uint),
SliceLengthGreaterOrEqual(/* prefix length */ uint, /* suffix length */ uint),
ConstantValue(ConstantExpr<'a>, DebugLoc),
ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>, DebugLoc),
Variant(ty::Disr, Rc<adt::Repr<'tcx>>, ast::DefId, DebugLoc),
SliceLengthEqual(uint, DebugLoc),
SliceLengthGreaterOrEqual(/* prefix length */ uint,
/* suffix length */ uint,
DebugLoc),
}
impl<'a, 'tcx> Opt<'a, 'tcx> {
fn eq(&self, other: &Opt<'a, 'tcx>, tcx: &ty::ctxt<'tcx>) -> bool {
match (self, other) {
(&ConstantValue(a), &ConstantValue(b)) => a.eq(b, tcx),
(&ConstantRange(a1, a2), &ConstantRange(b1, b2)) => {
(&ConstantValue(a, _), &ConstantValue(b, _)) => a.eq(b, tcx),
(&ConstantRange(a1, a2, _), &ConstantRange(b1, b2, _)) => {
a1.eq(b1, tcx) && a2.eq(b2, tcx)
}
(&Variant(a_disr, ref a_repr, a_def), &Variant(b_disr, ref b_repr, b_def)) => {
(&Variant(a_disr, ref a_repr, a_def, _),
&Variant(b_disr, ref b_repr, b_def, _)) => {
a_disr == b_disr && *a_repr == *b_repr && a_def == b_def
}
(&SliceLengthEqual(a), &SliceLengthEqual(b)) => a == b,
(&SliceLengthGreaterOrEqual(a1, a2), &SliceLengthGreaterOrEqual(b1, b2)) => {
(&SliceLengthEqual(a, _), &SliceLengthEqual(b, _)) => a == b,
(&SliceLengthGreaterOrEqual(a1, a2, _),
&SliceLengthGreaterOrEqual(b1, b2, _)) => {
a1 == b1 && a2 == b2
}
_ => false
......@@ -273,29 +277,39 @@ fn trans<'blk>(&self, mut bcx: Block<'blk, 'tcx>) -> OptResult<'blk, 'tcx> {
let _icx = push_ctxt("match::trans_opt");
let ccx = bcx.ccx();
match *self {
ConstantValue(ConstantExpr(lit_expr)) => {
ConstantValue(ConstantExpr(lit_expr), _) => {
let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id);
let (llval, _) = consts::const_expr(ccx, &*lit_expr);
let lit_datum = immediate_rvalue(llval, lit_ty);
let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
SingleResult(Result::new(bcx, lit_datum.val))
}
ConstantRange(ConstantExpr(ref l1), ConstantExpr(ref l2)) => {
ConstantRange(ConstantExpr(ref l1), ConstantExpr(ref l2), _) => {
let (l1, _) = consts::const_expr(ccx, &**l1);
let (l2, _) = consts::const_expr(ccx, &**l2);
RangeResult(Result::new(bcx, l1), Result::new(bcx, l2))
}
Variant(disr_val, ref repr, _) => {
Variant(disr_val, ref repr, _, _) => {
adt::trans_case(bcx, &**repr, disr_val)
}
SliceLengthEqual(length) => {
SliceLengthEqual(length, _) => {
SingleResult(Result::new(bcx, C_uint(ccx, length)))
}
SliceLengthGreaterOrEqual(prefix, suffix) => {
SliceLengthGreaterOrEqual(prefix, suffix, _) => {
LowerBound(Result::new(bcx, C_uint(ccx, prefix + suffix)))
}
}
}
fn debug_loc(&self) -> DebugLoc {
match *self {
ConstantValue(_,debug_loc) |
ConstantRange(_, _, debug_loc) |
Variant(_, _, _, debug_loc) |
SliceLengthEqual(_, debug_loc) |
SliceLengthGreaterOrEqual(_, _, debug_loc) => debug_loc
}
}
}
#[derive(Copy, PartialEq)]
......@@ -527,18 +541,18 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
let _indenter = indenter();
let ctor = match opt {
&ConstantValue(ConstantExpr(expr)) => check_match::ConstantValue(
&ConstantValue(ConstantExpr(expr), _) => check_match::ConstantValue(
const_eval::eval_const_expr(bcx.tcx(), &*expr)
),
&ConstantRange(ConstantExpr(lo), ConstantExpr(hi)) => check_match::ConstantRange(
&ConstantRange(ConstantExpr(lo), ConstantExpr(hi), _) => check_match::ConstantRange(
const_eval::eval_const_expr(bcx.tcx(), &*lo),
const_eval::eval_const_expr(bcx.tcx(), &*hi)
),
&SliceLengthEqual(n) =>
&SliceLengthEqual(n, _) =>
check_match::Slice(n),
&SliceLengthGreaterOrEqual(before, after) =>
&SliceLengthGreaterOrEqual(before, after, _) =>
check_match::SliceWithSubslice(before, after),
&Variant(_, _, def_id) =>
&Variant(_, _, def_id, _) =>
check_match::Constructor::Variant(def_id)
};
......@@ -563,27 +577,34 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let mut found: Vec<Opt> = vec![];
for br in m {
let cur = br.pats[col];
let debug_loc = DebugLoc::At(cur.id, cur.span);
let opt = match cur.node {
ast::PatLit(ref l) => ConstantValue(ConstantExpr(&**l)),
ast::PatLit(ref l) => {
ConstantValue(ConstantExpr(&**l), debug_loc)
}
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
// This is either an enum variant or a variable binding.
let opt_def = tcx.def_map.borrow().get(&cur.id).cloned();
match opt_def {
Some(def::DefVariant(enum_id, var_id, _)) => {
let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
Variant(variant.disr_val, adt::represent_node(bcx, cur.id), var_id)
Variant(variant.disr_val,
adt::represent_node(bcx, cur.id),
var_id,
debug_loc)
}
_ => continue
}
}
ast::PatRange(ref l1, ref l2) => {
ConstantRange(ConstantExpr(&**l1), ConstantExpr(&**l2))
ConstantRange(ConstantExpr(&**l1), ConstantExpr(&**l2), debug_loc)
}
ast::PatVec(ref before, None, ref after) => {
SliceLengthEqual(before.len() + after.len())
SliceLengthEqual(before.len() + after.len(), debug_loc)
}
ast::PatVec(ref before, Some(_), ref after) => {
SliceLengthGreaterOrEqual(before.len(), after.len())
SliceLengthGreaterOrEqual(before.len(), after.len(), debug_loc)
}
_ => continue
};
......@@ -779,19 +800,21 @@ fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> uint {
fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
rhs_t: Ty<'tcx>)
rhs_t: Ty<'tcx>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
rhs_t: Ty<'tcx>)
rhs_t: Ty<'tcx>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let did = langcall(cx,
None,
&format!("comparison of `{}`",
cx.ty_to_string(rhs_t))[],
StrEqFnLangItem);
callee::trans_lang_call(cx, did, &[lhs, rhs], None)
callee::trans_lang_call(cx, did, &[lhs, rhs], None, debug_loc)
}
let _icx = push_ctxt("compare_values");
......@@ -802,7 +825,7 @@ fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
match rhs_t.sty {
ty::ty_rptr(_, mt) => match mt.ty.sty {
ty::ty_str => compare_str(cx, lhs, rhs, rhs_t),
ty::ty_str => compare_str(cx, lhs, rhs, rhs_t, debug_loc),
ty::ty_vec(ty, _) => match ty.sty {
ty::ty_uint(ast::TyU8) => {
// NOTE: cast &[u8] to &str and abuse the str_eq lang item,
......@@ -812,7 +835,7 @@ fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
ast::MutImmutable);
let lhs = BitCast(cx, lhs, type_of::type_of(cx.ccx(), t).ptr_to());
let rhs = BitCast(cx, rhs, type_of::type_of(cx.ccx(), t).ptr_to());
compare_str(cx, lhs, rhs, rhs_t)
compare_str(cx, lhs, rhs, rhs_t, debug_loc)
},
_ => cx.sess().bug("only byte strings supported in compare_values"),
},
......@@ -1044,7 +1067,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
debug!("test_val={}", bcx.val_to_string(test_val));
if opts.len() > 0 {
match opts[0] {
ConstantValue(_) | ConstantRange(_, _) => {
ConstantValue(..) | ConstantRange(..) => {
test_val = load_if_immediate(bcx, val, left_ty);
kind = if ty::type_is_integral(left_ty) {
Switch
......@@ -1052,12 +1075,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
Compare
};
}
Variant(_, ref repr, _) => {
Variant(_, ref repr, _, _) => {
let (the_kind, val_opt) = adt::trans_switch(bcx, &**repr, val);
kind = the_kind;
if let Some(tval) = val_opt { test_val = tval; }
}
SliceLengthEqual(_) | SliceLengthGreaterOrEqual(_, _) => {
SliceLengthEqual(..) | SliceLengthGreaterOrEqual(..) => {
let (_, len) = tvec::get_base_and_len(bcx, val, left_ty);
test_val = len;
kind = Switch;
......@@ -1066,8 +1089,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
for o in &opts {
match *o {
ConstantRange(_, _) => { kind = Compare; break },
SliceLengthGreaterOrEqual(_, _) => { kind = CompareSliceLength; break },
ConstantRange(..) => { kind = Compare; break },
SliceLengthGreaterOrEqual(..) => { kind = CompareSliceLength; break },
_ => ()
}
}
......@@ -1093,10 +1116,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
// for the current conditional branch.
let mut branch_chk = None;
let mut opt_cx = else_cx;
let debug_loc = opt.debug_loc();
if !exhaustive || i + 1 < len {
opt_cx = bcx.fcx.new_temp_block("match_case");
match kind {
Single => Br(bcx, opt_cx.llbb, DebugLoc::None),
Single => Br(bcx, opt_cx.llbb, debug_loc),
Switch => {
match opt.trans(bcx) {
SingleResult(r) => {
......@@ -1119,7 +1144,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let Result { bcx: after_cx, val: matches } = {
match opt.trans(bcx) {
SingleResult(Result { bcx, val }) => {
compare_values(bcx, test_val, val, t)
compare_values(bcx, test_val, val, t, debug_loc)
}
RangeResult(Result { val: vbegin, .. },
Result { bcx, val: vend }) => {
......@@ -1131,7 +1156,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, DebugLoc::None))
Result::new(bcx, And(bcx, llge, llle, debug_loc))
}
LowerBound(Result { bcx, val }) => {
compare_scalar_types(bcx, test_val, val, t, ast::BiGe)
......@@ -1149,37 +1174,37 @@ 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, DebugLoc::None);
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb, debug_loc);
}
_ => ()
}
} else if kind == Compare || kind == CompareSliceLength {
Br(bcx, else_cx.llbb, DebugLoc::None);
Br(bcx, else_cx.llbb, debug_loc);
}
let mut size = 0;
let mut unpacked = Vec::new();
match *opt {
Variant(disr_val, ref repr, _) => {
Variant(disr_val, ref repr, _, _) => {
let ExtractedBlock {vals: argvals, bcx: new_bcx} =
extract_variant_args(opt_cx, &**repr, disr_val, val);
size = argvals.len();
unpacked = argvals;
opt_cx = new_bcx;
}
SliceLengthEqual(len) => {
SliceLengthEqual(len, _) => {
let args = extract_vec_elems(opt_cx, left_ty, len, 0, val);
size = args.vals.len();
unpacked = args.vals.clone();
opt_cx = args.bcx;
}
SliceLengthGreaterOrEqual(before, after) => {
SliceLengthGreaterOrEqual(before, after, _) => {
let args = extract_vec_elems(opt_cx, left_ty, before, after, val);
size = args.vals.len();
unpacked = args.vals.clone();
opt_cx = args.bcx;
}
ConstantValue(_) | ConstantRange(_, _) => ()
ConstantValue(..) | ConstantRange(..) => ()
}
let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val);
let mut opt_vals = unpacked;
......
......@@ -57,7 +57,7 @@
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::{Result};
use trans::common::{Result, NodeIdAndSpan};
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};
......@@ -379,7 +379,8 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
llty_ptr: Type,
info_ty: Ty<'tcx>,
size: ValueRef,
align: ValueRef)
align: ValueRef,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let _icx = push_ctxt("malloc_raw_exchange");
......@@ -387,7 +388,8 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let r = callee::trans_lang_call(bcx,
require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem),
&[size, align],
None);
None,
debug_loc);
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
}
......@@ -851,7 +853,7 @@ pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
cx: Block<'blk, 'tcx>,
span: Span,
call_info: NodeIdAndSpan,
divrem: ast::BinOp,
lhs: ValueRef,
rhs: ValueRef,
......@@ -879,7 +881,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
}
};
let bcx = with_cond(cx, is_zero, |bcx| {
controlflow::trans_fail(bcx, span, InternedString::new(zero_text))
controlflow::trans_fail(bcx, call_info, InternedString::new(zero_text))
});
// To quote LLVM's documentation for the sdiv instruction:
......@@ -913,7 +915,8 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
let is_min = ICmp(bcx, llvm::IntEQ, lhs,
C_integral(llty, min, true));
with_cond(bcx, is_min, |bcx| {
controlflow::trans_fail(bcx, span,
controlflow::trans_fail(bcx,
call_info,
InternedString::new(overflow_text))
})
})
......
......@@ -36,8 +36,8 @@
use trans::cleanup;
use trans::cleanup::CleanupMethods;
use trans::closure;
use trans::common;
use trans::common::*;
use trans::common::{self, Block, Result, NodeIdAndSpan, ExprId, CrateContext,
ExprOrMethodCall, FunctionContext, MethodCallKey};
use trans::consts;
use trans::datum::*;
use trans::debuginfo::{DebugLoc, ToDebugLoc};
......@@ -136,7 +136,7 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
ref_expr: &ast::Expr)
-> Callee<'blk, 'tcx> {
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
let expr_ty = node_id_type(bcx, ref_expr.id);
let expr_ty = common::node_id_type(bcx, ref_expr.id);
match def {
def::DefFn(did, _) if {
let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
......@@ -147,8 +147,9 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
_ => false
}
} => {
let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
bcx.fcx.param_substs);
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
Callee {
bcx: bcx,
data: NamedTupleConstructor(substs, 0)
......@@ -158,8 +159,9 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
ty::ty_bare_fn(_, ref f) => f.abi == synabi::RustIntrinsic,
_ => false
} => {
let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
bcx.fcx.param_substs);
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
}
......@@ -178,8 +180,9 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
def::DefVariant(tid, vid, _) => {
let vinfo = ty::enum_variant_with_id(bcx.tcx(), tid, vid);
let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
bcx.fcx.param_substs);
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
// Nullary variants are not callable
assert!(vinfo.args.len() > 0);
......@@ -190,8 +193,9 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}
def::DefStruct(_) => {
let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
bcx.fcx.param_substs);
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
Callee {
bcx: bcx,
data: NamedTupleConstructor(substs, 0)
......@@ -226,7 +230,7 @@ pub fn trans_fn_ref<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-> Datum<'tcx, Rvalue> {
let _icx = push_ctxt("trans_fn_ref");
let substs = node_id_substs(ccx, node, param_substs);
let substs = common::node_id_substs(ccx, node, param_substs);
debug!("trans_fn_ref(def_id={}, node={:?}, substs={})",
def_id.repr(ccx.tcx()),
node,
......@@ -269,7 +273,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let _icx = push_ctxt("trans_fn_pointer_shim");
let tcx = ccx.tcx();
let bare_fn_ty = erase_regions(tcx, &bare_fn_ty);
let bare_fn_ty = common::erase_regions(tcx, &bare_fn_ty);
match ccx.fn_pointer_shims().borrow().get(&bare_fn_ty) {
Some(&llval) => { return llval; }
None => { }
......@@ -352,7 +356,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
);
bcx = trans_call_inner(bcx,
None,
DebugLoc::None,
bare_fn_ty,
|bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
ArgVals(&llargs[]),
......@@ -515,7 +519,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
param_substs,
&ref_ty);
let llptrty = type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to();
if llptrty != val_ty(val) {
if llptrty != common::val_ty(val) {
let val = consts::ptrcast(val, llptrty);
return Datum::new(val, ref_ty, Rvalue::new(ByValue));
}
......@@ -563,7 +567,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
// other weird situations. Annoying.
let llty = type_of::type_of_fn_from_ty(ccx, fn_type);
let llptrty = llty.ptr_to();
if val_ty(val) != llptrty {
if common::val_ty(val) != llptrty {
debug!("trans_fn_ref_with_vtables(): casting pointer!");
val = consts::ptrcast(val, llptrty);
} else {
......@@ -577,34 +581,34 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
// Translating calls
pub fn trans_call<'a, 'blk, 'tcx>(in_cx: Block<'blk, 'tcx>,
call_ex: &ast::Expr,
call_expr: &ast::Expr,
f: &ast::Expr,
args: CallArgs<'a, 'tcx>,
dest: expr::Dest)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("trans_call");
trans_call_inner(in_cx,
Some(common::expr_info(call_ex)),
expr_ty_adjusted(in_cx, f),
call_expr.debug_loc(),
common::expr_ty_adjusted(in_cx, f),
|cx, _| trans(cx, f),
args,
Some(dest)).bcx
}
pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
call_ex: &ast::Expr,
call_expr: &ast::Expr,
rcvr: &ast::Expr,
args: CallArgs<'a, 'tcx>,
dest: expr::Dest)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_ex={})", call_ex.repr(bcx.tcx()));
let method_call = MethodCall::expr(call_ex.id);
debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx()));
let method_call = MethodCall::expr(call_expr.id);
let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
trans_call_inner(
bcx,
Some(common::expr_info(call_ex)),
monomorphize_type(bcx, method_ty),
call_expr.debug_loc(),
common::monomorphize_type(bcx, method_ty),
|cx, arg_cleanup_scope| {
meth::trans_method_callee(cx, method_call, Some(rcvr), arg_cleanup_scope)
},
......@@ -615,7 +619,8 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
did: ast::DefId,
args: &[ValueRef],
dest: Option<expr::Dest>)
dest: Option<expr::Dest>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let fty = if did.krate == ast::LOCAL_CRATE {
ty::node_id_to_type(bcx.tcx(), did.node)
......@@ -623,7 +628,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
csearch::get_type(bcx.tcx(), did).ty
};
callee::trans_call_inner(bcx,
None,
debug_loc,
fty,
|bcx, _| {
trans_fn_ref_with_substs_to_callee(bcx,
......@@ -646,7 +651,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<NodeIdAndSpan>,
debug_loc: DebugLoc,
callee_ty: Ty<'tcx>,
get_callee: F,
args: CallArgs<'a, 'tcx>,
......@@ -687,7 +692,13 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
assert!(abi == synabi::RustIntrinsic);
assert!(dest.is_some());
let call_info = call_info.expect("no call info for intrinsic call?");
let call_info = match debug_loc {
DebugLoc::At(id, span) => NodeIdAndSpan { id: id, span: span },
DebugLoc::None => {
bcx.sess().bug("No call info for intrinsic call?")
}
};
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
arg_cleanup_scope, args,
dest.unwrap(), substs,
......@@ -703,7 +714,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
disr,
args,
dest.unwrap(),
call_info.debug_loc());
debug_loc);
}
};
......@@ -724,12 +735,12 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
};
if !is_rust_fn ||
type_of::return_uses_outptr(ccx, ret_ty) ||
type_needs_drop(bcx.tcx(), ret_ty) {
common::type_needs_drop(bcx.tcx(), ret_ty) {
// Push the out-pointer if we use an out-pointer for this
// return type, otherwise push "undef".
if type_is_zero_size(ccx, ret_ty) {
if common::type_is_zero_size(ccx, ret_ty) {
let llty = type_of::type_of(ccx, ret_ty);
Some(C_undef(llty.ptr_to()))
Some(common::C_undef(llty.ptr_to()))
} else {
Some(alloc_ty(bcx, ret_ty, "__llret"))
}
......@@ -781,7 +792,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
llfn,
&llargs[],
callee_ty,
call_info.debug_loc());
debug_loc);
bcx = b;
llresult = llret;
......@@ -790,7 +801,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
match (opt_llretslot, ret_ty) {
(Some(llretslot), ty::FnConverging(ret_ty)) => {
if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
!type_is_zero_size(bcx.ccx(), ret_ty)
!common::type_is_zero_size(bcx.ccx(), ret_ty)
{
store_ty(bcx, llret, llretslot, ret_ty)
}
......@@ -804,7 +815,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let mut llargs = Vec::new();
let arg_tys = match args {
ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, &**x)).collect(),
ArgExprs(a) => a.iter().map(|x| common::expr_ty(bcx, &**x)).collect(),
_ => panic!("expected arg exprs.")
};
bcx = trans_args(bcx,
......@@ -831,7 +842,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
bcx = glue::drop_ty(bcx,
llretslot,
ret_ty,
call_info.debug_loc());
debug_loc);
call_lifetime_end(bcx, llretslot);
}
_ => {}
......@@ -892,7 +903,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
// Now untuple the rest of the arguments.
let tuple_expr = &arg_exprs[1];
let tuple_type = node_id_type(bcx, tuple_expr.id);
let tuple_type = common::node_id_type(bcx, tuple_expr.id);
match tuple_type.sty {
ty::ty_tup(ref field_types) => {
......@@ -1014,7 +1025,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
}
let arg_ty = if i >= num_formal_args {
assert!(variadic);
expr_ty_adjusted(cx, &**arg_expr)
common::expr_ty_adjusted(cx, &**arg_expr)
} else {
arg_tys[i]
};
......
......@@ -940,11 +940,12 @@ fn trans<'blk>(&self,
bcx: Block<'blk, 'tcx>,
debug_loc: DebugLoc)
-> Block<'blk, 'tcx> {
debug_loc.apply(bcx.fcx);
match self.heap {
HeapExchange => {
glue::trans_exchange_free_ty(bcx, self.ptr, self.content_ty)
glue::trans_exchange_free_ty(bcx,
self.ptr,
self.content_ty,
debug_loc)
}
}
}
......@@ -975,11 +976,13 @@ fn trans<'blk>(&self,
bcx: Block<'blk, 'tcx>,
debug_loc: DebugLoc)
-> Block<'blk, 'tcx> {
debug_loc.apply(bcx.fcx);
match self.heap {
HeapExchange => {
glue::trans_exchange_free_dyn(bcx, self.ptr, self.size, self.align)
glue::trans_exchange_free_dyn(bcx,
self.ptr,
self.size,
self.align,
debug_loc)
}
}
}
......
......@@ -28,7 +28,6 @@
use syntax::ast;
use syntax::ast::Ident;
use syntax::ast_util;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit::Visitor;
......@@ -361,31 +360,32 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
sp: Span,
call_info: NodeIdAndSpan,
fail_str: InternedString)
-> Block<'blk, 'tcx> {
let ccx = bcx.ccx();
let _icx = push_ctxt("trans_fail_value");
let v_str = C_str_slice(ccx, fail_str);
let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
let filename = token::intern_and_get_ident(&loc.file.name[]);
let filename = C_str_slice(ccx, filename);
let line = C_uint(ccx, loc.line);
let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const, ast::MutImmutable);
let args = vec!(expr_file_line);
let did = langcall(bcx, Some(sp), "", PanicFnLangItem);
let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
&args[],
Some(expr::Ignore)).bcx;
Some(expr::Ignore),
call_info.debug_loc()).bcx;
Unreachable(bcx);
return bcx;
}
pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
sp: Span,
call_info: NodeIdAndSpan,
index: ValueRef,
len: ValueRef)
-> Block<'blk, 'tcx> {
......@@ -393,7 +393,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _icx = push_ctxt("trans_fail_bounds_check");
// Extract the file/line from the span
let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
let filename = token::intern_and_get_ident(&loc.file.name[]);
// Invoke the lang item
......@@ -402,11 +402,12 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let file_line_const = C_struct(ccx, &[filename, line], false);
let file_line = consts::const_addr_of(ccx, file_line_const, ast::MutImmutable);
let args = vec!(file_line, index, len);
let did = langcall(bcx, Some(sp), "", PanicBoundsCheckFnLangItem);
let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
&args[],
Some(expr::Ignore)).bcx;
Some(expr::Ignore),
call_info.debug_loc()).bcx;
Unreachable(bcx);
return bcx;
}
......@@ -1113,7 +1113,7 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum DebugLoc {
At(ast::NodeId, Span),
None
......
......@@ -586,7 +586,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let contents_ty = expr_ty(bcx, &**contents);
match box_ty.sty {
ty::ty_uniq(..) => {
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
trans_uniq_expr(bcx, expr, box_ty, &**contents, contents_ty)
}
_ => bcx.sess().span_bug(expr.span,
"expected unique box")
......@@ -787,7 +787,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
index_expr.debug_loc());
bcx = with_cond(bcx, expected, |bcx| {
controlflow::trans_fail_bounds_check(bcx,
index_expr.span,
expr_info(index_expr),
ix_val,
len)
});
......@@ -1574,7 +1574,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
immediate_rvalue_bcx(bcx, llneg, un_ty).to_expr_datumblock()
}
ast::UnUniq => {
trans_uniq_expr(bcx, un_ty, sub_expr, expr_ty(bcx, sub_expr))
trans_uniq_expr(bcx, expr, un_ty, sub_expr, expr_ty(bcx, sub_expr))
}
ast::UnDeref => {
let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
......@@ -1584,6 +1584,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
box_expr: &ast::Expr,
box_ty: Ty<'tcx>,
contents: &ast::Expr,
contents_ty: Ty<'tcx>)
......@@ -1595,7 +1596,12 @@ fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let size = llsize_of(bcx.ccx(), llty);
let align = C_uint(bcx.ccx(), type_of::align_of(bcx.ccx(), contents_ty));
let llty_ptr = llty.ptr_to();
let Result { bcx, val } = malloc_raw_dyn(bcx, llty_ptr, box_ty, size, align);
let Result { bcx, val } = malloc_raw_dyn(bcx,
llty_ptr,
box_ty,
size,
align,
box_expr.debug_loc());
// Unique boxes do not allocate for zero-size types. The standard library
// may assume that `free` is never called on the pointer returned for
// `Box<ZeroSizeType>`.
......@@ -1697,8 +1703,12 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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);
bcx = base::fail_if_zero_or_overflows(bcx,
expr_info(binop_expr),
op,
lhs,
rhs,
rhs_t);
if is_signed {
SDiv(bcx, lhs, rhs, binop_debug_loc)
} else {
......@@ -1711,7 +1721,8 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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,
bcx = base::fail_if_zero_or_overflows(bcx,
expr_info(binop_expr),
op, lhs, rhs, rhs_t);
if is_signed {
SRem(bcx, lhs, rhs, binop_debug_loc)
......@@ -1845,7 +1856,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-> Result<'blk, 'tcx> {
let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
callee::trans_call_inner(bcx,
Some(expr_info(expr)),
expr.debug_loc(),
monomorphize_type(bcx, method_ty),
|bcx, arg_cleanup_scope| {
meth::trans_method_callee(bcx,
......@@ -1872,7 +1883,7 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
all_args.extend(args.iter().map(|e| &**e));
unpack_result!(bcx,
callee::trans_call_inner(bcx,
Some(expr_info(expr)),
expr.debug_loc(),
monomorphize_type(bcx,
method_type),
|bcx, arg_cleanup_scope| {
......
......@@ -45,25 +45,39 @@
use syntax::ast;
use syntax::parse::token;
pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef,
size: ValueRef, align: ValueRef)
pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
v: ValueRef,
size: ValueRef,
align: ValueRef,
debug_loc: DebugLoc)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("trans_exchange_free");
let ccx = cx.ccx();
callee::trans_lang_call(cx,
langcall(cx, None, "", ExchangeFreeFnLangItem),
&[PointerCast(cx, v, Type::i8p(ccx)), size, align],
Some(expr::Ignore)).bcx
Some(expr::Ignore),
debug_loc).bcx
}
pub fn trans_exchange_free<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef,
size: u64, align: u32) -> Block<'blk, 'tcx> {
trans_exchange_free_dyn(cx, v, C_uint(cx.ccx(), size),
C_uint(cx.ccx(), align))
pub fn trans_exchange_free<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
v: ValueRef,
size: u64,
align: u32,
debug_loc: DebugLoc)
-> Block<'blk, 'tcx> {
trans_exchange_free_dyn(cx,
v,
C_uint(cx.ccx(), size),
C_uint(cx.ccx(), align),
debug_loc)
}
pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef,
content_ty: Ty<'tcx>) -> Block<'blk, 'tcx> {
pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
ptr: ValueRef,
content_ty: Ty<'tcx>,
debug_loc: DebugLoc)
-> Block<'blk, 'tcx> {
assert!(type_is_sized(bcx.ccx().tcx(), content_ty));
let sizing_type = sizing_type_of(bcx.ccx(), content_ty);
let content_size = llsize_of_alloc(bcx.ccx(), sizing_type);
......@@ -71,7 +85,7 @@ pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef,
// `Box<ZeroSizeType>` does not allocate.
if content_size != 0 {
let content_align = align_of(bcx.ccx(), content_ty);
trans_exchange_free(bcx, ptr, content_size, content_align)
trans_exchange_free(bcx, ptr, content_size, content_align, debug_loc)
} else {
bcx
}
......@@ -394,7 +408,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
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);
trans_exchange_free_dyn(bcx, llbox, llsize, llalign)
trans_exchange_free_dyn(bcx, llbox, llsize, llalign, DebugLoc::None)
})
}
_ => {
......@@ -404,7 +418,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
let not_null = IsNotNull(bcx, llbox);
with_cond(bcx, not_null, |bcx| {
let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
trans_exchange_free_ty(bcx, llbox, content_ty)
trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
})
}
}
......
......@@ -667,7 +667,7 @@ pub fn trans_object_shim<'a, 'tcx>(
method_offset_in_vtable);
bcx = trans_call_inner(bcx,
None,
DebugLoc::None,
method_bare_fn_ty,
|bcx, _| trans_trait_callee_from_llval(bcx,
method_bare_fn_ty,
......
......@@ -77,7 +77,11 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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, DebugLoc::None);
glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
glue::trans_exchange_free_dyn(bcx,
dataptr,
size,
llalign,
DebugLoc::None)
})
} else {
bcx
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册