use llvm;
use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
use llvm::{InternalLinkage, ValueRef, Bool, True};
-use metadata::cstore::LOCAL_CRATE;
use middle::{check_const, def};
+use middle::cstore::LOCAL_CRATE;
use middle::const_eval::{self, ConstVal, ConstEvalErr};
use middle::const_eval::{const_int_checked_neg, const_uint_checked_neg};
use middle::const_eval::{const_int_checked_add, const_uint_checked_add};
use trans::base::{self, push_ctxt};
use trans::common::{self, type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt};
use trans::common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty};
+use trans::common::C_floating_f64;
use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint};
use trans::common::{type_is_fat_ptr, Field, C_vector, C_array, C_null, ExprId, MethodCallKey};
use trans::declare;
}
}
+pub fn trans_constval<'blk, 'tcx>(bcx: common::Block<'blk, 'tcx>,
+ cv: &ConstVal,
+ ty: Ty<'tcx>,
+ param_substs: &'tcx Substs<'tcx>)
+ -> ValueRef
+{
+ let ccx = bcx.ccx();
+ let llty = type_of::type_of(ccx, ty);
+ match *cv {
+ ConstVal::Float(v) => C_floating_f64(v, llty),
+ ConstVal::Bool(v) => C_bool(ccx, v),
+ ConstVal::Int(v) => C_integral(llty, v as u64, true),
+ ConstVal::Uint(v) => C_integral(llty, v, false),
+ ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
+ ConstVal::ByteStr(ref v) => addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
+ ConstVal::Struct(id) | ConstVal::Tuple(id) => {
+ let expr = bcx.tcx().map.expect_expr(id);
+ match const_expr(ccx, expr, param_substs, None, TrueConst::Yes) {
+ Ok((val, _)) => val,
+ Err(e) => panic!("const eval failure: {}", e.description()),
+ }
+ },
+ ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => {
+ let expr = bcx.tcx().map.expect_expr(id);
+ expr::trans(bcx, expr).datum.val
+ },
+ ConstVal::Function(_) => {
+ unimplemented!()
+ },
+ }
+}
+
pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
unsafe {
llvm::LLVMConstPointerCast(val, ty.to_ref())
-> Result<ValueRef, ConstEvalFailure> {
debug!("get_const_expr_as_global: {:?}", expr.id);
// Special-case constants to cache a common global for all uses.
- match expr.node {
- hir::ExprPath(..) => {
- let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
- match def {
- def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
- if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
- debug!("get_const_expr_as_global ({:?}): found const {:?}",
- expr.id, def_id);
- return get_const_val(ccx, def_id, expr);
- }
+ if let hir::ExprPath(..) = expr.node {
+ // `def` must be its own statement and cannot be in the `match`
+ // otherwise the `def_map` will be borrowed for the entire match instead
+ // of just to get the `def` value
+ let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
+ match def {
+ def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
+ if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
+ debug!("get_const_expr_as_global ({:?}): found const {:?}",
+ expr.id, def_id);
+ return get_const_val(ccx, def_id, expr);
}
- _ => {}
- }
+ },
+ _ => {},
}
- _ => {}
}
let key = (expr.id, param_substs);
- match ccx.const_values().borrow().get(&key) {
- Some(&val) => return Ok(val),
- None => {}
+ if let Some(&val) = ccx.const_values().borrow().get(&key) {
+ return Ok(val);
}
let ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs,
&ccx.tcx().expr_ty(expr));
// references, even when only the latter are correct.
try!(const_expr_unadjusted(ccx, expr, ty, param_substs, None, trueconst))
} else {
- match const_expr(ccx, expr, param_substs, None, trueconst) {
- Err(err) => return Err(err),
- Ok((ok, _)) => ok,
- }
+ try!(const_expr(ccx, expr, param_substs, None, trueconst)).0
};
// boolean SSA values are i1, but they have to be stored in i8 slots,
};
let _icx = push_ctxt("const_expr");
Ok(match e.node {
- hir::ExprLit(ref lit) => {
- const_lit(cx, e, &**lit)
- },
+ hir::ExprLit(ref lit) => const_lit(cx, e, &**lit),
hir::ExprBinary(b, ref e1, ref e2) => {
/* Neither type is bottom, and we expect them to be unified
* already, so the following is safe. */
m: hir::Mutability,
expr: &hir::Expr,
id: ast::NodeId,
- attrs: &Vec<ast::Attribute>)
+ attrs: &[ast::Attribute])
-> Result<ValueRef, ConstEvalErr> {
unsafe {
let _icx = push_ctxt("trans_static");