// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.


use llvm;
use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
use llvm::{InternalLinkage, ValueRef, Bool, True};
use middle::const_qualif::ConstQualif;
use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, lookup_const_by_id, ErrKind};
use rustc_const_eval::eval_repeat_count;
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::map as hir_map;
use {abi, adt, closure, debuginfo, expr, machine};
use base::{self, push_ctxt};
use callee::Callee;
use trans_item::TransItem;
use common::{type_is_sized, C_nil, const_get_elt};
use common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty};
use common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint};
use common::{type_is_fat_ptr, Field, C_vector, C_array, C_null};
use datum::{Datum, Lvalue};
use declare;
use monomorphize::{self, Instance};
use type_::Type;
use type_of;
use value::Value;
use Disr;
use rustc::ty::subst::Substs;
use rustc::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::cast::{CastTy,IntTy};
use util::nodemap::NodeMap;
use rustc_const_math::{ConstInt, ConstUsize, ConstIsize};

use rustc::hir;

use std::ffi::{CStr, CString};
use std::borrow::Cow;
use libc::c_uint;
use syntax::ast::{self, LitKind};
use syntax::attr::{self, AttrMetaMethods};
use syntax::parse::token;
use syntax::ptr::P;
use syntax_pos::Span;

pub type FnArgMap<'a> = Option<&'a NodeMap<ValueRef>>;

pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
    -> ValueRef {
    let _icx = push_ctxt("trans_lit");
    debug!("const_lit: {:?}", lit);
    match lit.node {
        LitKind::Byte(b) => C_integral(Type::uint_from_ty(cx, ast::UintTy::U8), b as u64, false),
        LitKind::Char(i) => C_integral(Type::char(cx), i as u64, false),
        LitKind::Int(i, ast::LitIntType::Signed(t)) => {
            C_integral(Type::int_from_ty(cx, t), i, true)
        }
        LitKind::Int(u, ast::LitIntType::Unsigned(t)) => {
            C_integral(Type::uint_from_ty(cx, t), u, false)
        }
        LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
            let lit_int_ty = cx.tcx().node_id_to_type(e.id);
            match lit_int_ty.sty {
                ty::TyInt(t) => {
                    C_integral(Type::int_from_ty(cx, t), i as u64, true)
                }
                ty::TyUint(t) => {
                    C_integral(Type::uint_from_ty(cx, t), i as u64, false)
                }
                _ => span_bug!(lit.span,
                        "integer literal has type {:?} (expected int \
                         or usize)",
                        lit_int_ty)
            }
        }
        LitKind::Float(ref fs, t) => {
            C_floating(&fs, Type::float_from_ty(cx, t))
        }
        LitKind::FloatUnsuffixed(ref fs) => {
            let lit_float_ty = cx.tcx().node_id_to_type(e.id);
            match lit_float_ty.sty {
                ty::TyFloat(t) => {
                    C_floating(&fs, Type::float_from_ty(cx, t))
                }
                _ => {
                    span_bug!(lit.span,
                        "floating point literal doesn't have the right type");
                }
            }
        }
        LitKind::Bool(b) => C_bool(cx, b),
        LitKind::Str(ref s, _) => C_str_slice(cx, (*s).clone()),
        LitKind::ByteStr(ref data) => {
            addr_of(cx, C_bytes(cx, &data[..]), 1, "byte_str")
        }
    }
}

pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
    unsafe {
        llvm::LLVMConstPointerCast(val, ty.to_ref())
    }
}

pub fn addr_of_mut(ccx: &CrateContext,
                   cv: ValueRef,
                   align: machine::llalign,
                   kind: &str)
                    -> ValueRef {
    unsafe {
        // FIXME: this totally needs a better name generation scheme, perhaps a simple global
        // counter? Also most other uses of gensym in trans.
        let gsym = token::gensym("_");
        let name = format!("{}{}", kind, gsym.0);
        let gv = declare::define_global(ccx, &name[..], val_ty(cv)).unwrap_or_else(||{
            bug!("symbol `{}` is already defined", name);
        });
        llvm::LLVMSetInitializer(gv, cv);
        llvm::LLVMSetAlignment(gv, align);
        SetLinkage(gv, InternalLinkage);
        SetUnnamedAddr(gv, true);
        gv
    }
}

pub fn addr_of(ccx: &CrateContext,
               cv: ValueRef,
               align: machine::llalign,
               kind: &str)
               -> ValueRef {
    if let Some(&gv) = ccx.const_globals().borrow().get(&cv) {
        unsafe {
            // Upgrade the alignment in cases where the same constant is used with different
            // alignment requirements
            if align > llvm::LLVMGetAlignment(gv) {
                llvm::LLVMSetAlignment(gv, align);
            }
        }
        return gv;
    }
    let gv = addr_of_mut(ccx, cv, align, kind);
    unsafe {
        llvm::LLVMSetGlobalConstant(gv, True);
    }
    ccx.const_globals().borrow_mut().insert(cv, gv);
    gv
}

/// Deref a constant pointer
pub fn load_const(cx: &CrateContext, v: ValueRef, t: Ty) -> ValueRef {
    let v = match cx.const_unsized().borrow().get(&v) {
        Some(&v) => v,
        None => v
    };
    let d = unsafe { llvm::LLVMGetInitializer(v) };
    if !d.is_null() && t.is_bool() {
        unsafe { llvm::LLVMConstTrunc(d, Type::i1(cx).to_ref()) }
    } else {
        d
    }
}

fn const_deref<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         v: ValueRef,
                         ty: Ty<'tcx>)
                         -> (ValueRef, Ty<'tcx>) {
    match ty.builtin_deref(true, ty::NoPreference) {
        Some(mt) => {
            if type_is_sized(cx.tcx(), mt.ty) {
                (load_const(cx, v, mt.ty), mt.ty)
            } else {
                // Derefing a fat pointer does not change the representation,
                // just the type to the unsized contents.
                (v, mt.ty)
            }
        }
        None => {
            bug!("unexpected dereferenceable type {:?}", ty)
        }
    }
}

fn const_fn_call<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                           def_id: DefId,
                           substs: &'tcx Substs<'tcx>,
                           arg_vals: &[ValueRef],
                           param_substs: &'tcx Substs<'tcx>,
                           trueconst: TrueConst) -> Result<ValueRef, ConstEvalFailure> {
    let fn_like = lookup_const_fn_by_id(ccx.tcx(), def_id);
    let fn_like = fn_like.expect("lookup_const_fn_by_id failed in const_fn_call");

    let body = match fn_like.body().expr {
        Some(ref expr) => expr,
        None => return Ok(C_nil(ccx))
    };

    let args = &fn_like.decl().inputs;
    assert_eq!(args.len(), arg_vals.len());

    let arg_ids = args.iter().map(|arg| arg.pat.id);
    let fn_args = arg_ids.zip(arg_vals.iter().cloned()).collect();

    let substs = ccx.tcx().mk_substs(substs.clone().erase_regions());
    let substs = monomorphize::apply_param_substs(ccx.tcx(),
                                                  param_substs,
                                                  &substs);

    const_expr(ccx, body, substs, Some(&fn_args), trueconst).map(|(res, _)| res)
}

pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                def_id: DefId,
                                ref_expr: &hir::Expr,
                                param_substs: &'tcx Substs<'tcx>)
                                -> &'tcx hir::Expr {
    let substs = ccx.tcx().node_id_item_substs(ref_expr.id).substs;
    let substs = ccx.tcx().mk_substs(substs.clone().erase_regions());
    let substs = monomorphize::apply_param_substs(ccx.tcx(),
                                                  param_substs,
                                                  &substs);
    match lookup_const_by_id(ccx.tcx(), def_id, Some(substs)) {
        Some((ref expr, _ty)) => expr,
        None => {
            span_bug!(ref_expr.span, "constant item not found")
        }
    }
}

pub enum ConstEvalFailure {
    /// in case the const evaluator failed on something that panic at runtime
    /// as defined in RFC 1229
    Runtime(ConstEvalErr),
    // in case we found a true constant
    Compiletime(ConstEvalErr),
}

impl ConstEvalFailure {
    fn into_inner(self) -> ConstEvalErr {
        match self {
            Runtime(e) => e,
            Compiletime(e) => e,
        }
    }
    pub fn description(&self) -> Cow<str> {
        match self {
            &Runtime(ref e) => e.description(),
            &Compiletime(ref e) => e.description(),
        }
    }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum TrueConst {
    Yes, No
}

use self::ConstEvalFailure::*;

fn get_const_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                           def_id: DefId,
                           ref_expr: &hir::Expr,
                           param_substs: &'tcx Substs<'tcx>)
                           -> Result<ValueRef, ConstEvalFailure> {
    let expr = get_const_expr(ccx, def_id, ref_expr, param_substs);
    let empty_substs = ccx.tcx().mk_substs(Substs::empty());
    match get_const_expr_as_global(ccx, expr, ConstQualif::empty(), empty_substs, TrueConst::Yes) {
        Err(Runtime(err)) => {
            ccx.tcx().sess.span_err(expr.span, &err.description());
            Err(Compiletime(err))
        },
        other => other,
    }
}

pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                          expr: &hir::Expr,
                                          qualif: ConstQualif,
                                          param_substs: &'tcx Substs<'tcx>,
                                          trueconst: TrueConst)
                                          -> Result<ValueRef, ConstEvalFailure> {
    debug!("get_const_expr_as_global: {:?}", expr.id);
    // Special-case constants to cache a common global for all uses.
    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
        match ccx.tcx().expect_def(expr.id) {
            Def::Const(def_id) | Def::AssociatedConst(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, param_substs);
                }
            },
            _ => {},
        }
    }

    let key = (expr.id, param_substs);
    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));
    let val = if qualif.intersects(ConstQualif::NON_STATIC_BORROWS) {
        // Avoid autorefs as they would create global instead of stack
        // references, even when only the latter are correct.
        const_expr_unadjusted(ccx, expr, ty, param_substs, None, trueconst)?
    } else {
        const_expr(ccx, expr, param_substs, None, trueconst)?.0
    };

    // boolean SSA values are i1, but they have to be stored in i8 slots,
    // otherwise some LLVM optimization passes don't work as expected
    let val = unsafe {
        if llvm::LLVMTypeOf(val) == Type::i1(ccx).to_ref() {
            llvm::LLVMConstZExt(val, Type::i8(ccx).to_ref())
        } else {
            val
        }
    };

    let lvalue = addr_of(ccx, val, type_of::align_of(ccx, ty), "const");
    ccx.const_values().borrow_mut().insert(key, lvalue);
    Ok(lvalue)
}

pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                            e: &hir::Expr,
                            param_substs: &'tcx Substs<'tcx>,
                            fn_args: FnArgMap,
                            trueconst: TrueConst)
                            -> Result<(ValueRef, Ty<'tcx>), ConstEvalFailure> {
    let ety = monomorphize::apply_param_substs(cx.tcx(), param_substs,
                                               &cx.tcx().expr_ty(e));
    let llconst = const_expr_unadjusted(cx, e, ety, param_substs, fn_args, trueconst)?;
    let mut llconst = llconst;
    let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs,
                                                            &cx.tcx().expr_ty_adjusted(e));
    let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned();
    match opt_adj {
        Some(AdjustReifyFnPointer) => {
            match ety.sty {
                ty::TyFnDef(def_id, substs, _) => {
                    llconst = Callee::def(cx, def_id, substs).reify(cx).val;
                }
                _ => {
                    bug!("{} cannot be reified to a fn ptr", ety)
                }
            }
        }
        Some(AdjustUnsafeFnPointer) | Some(AdjustMutToConstPointer) => {
            // purely a type-level thing
        }
        Some(AdjustDerefRef(adj)) => {
            let mut ty = ety;
            // Save the last autoderef in case we can avoid it.
            if adj.autoderefs > 0 {
                for _ in 0..adj.autoderefs-1 {
                    let (dv, dt) = const_deref(cx, llconst, ty);
                    llconst = dv;
                    ty = dt;
                }
            }

            if adj.autoref.is_some() {
                if adj.autoderefs == 0 {
                    // Don't copy data to do a deref+ref
                    // (i.e., skip the last auto-deref).
                    llconst = addr_of(cx, llconst, type_of::align_of(cx, ty), "autoref");
                    ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReErased), ty);
                }
            } else if adj.autoderefs > 0 {
                let (dv, dt) = const_deref(cx, llconst, ty);
                llconst = dv;

                // If we derefed a fat pointer then we will have an
                // open type here. So we need to update the type with
                // the one returned from const_deref.
                ety_adjusted = dt;
            }

            if let Some(target) = adj.unsize {
                let target = monomorphize::apply_param_substs(cx.tcx(),
                                                              param_substs,
                                                              &target);

                let pointee_ty = ty.builtin_deref(true, ty::NoPreference)
                    .expect("consts: unsizing got non-pointer type").ty;
                let (base, old_info) = if !type_is_sized(cx.tcx(), pointee_ty) {
                    // Normally, the source is a thin pointer and we are
                    // adding extra info to make a fat pointer. The exception
                    // is when we are upcasting an existing object fat pointer
                    // to use a different vtable. In that case, we want to
                    // load out the original data pointer so we can repackage
                    // it.
                    (const_get_elt(llconst, &[abi::FAT_PTR_ADDR as u32]),
                     Some(const_get_elt(llconst, &[abi::FAT_PTR_EXTRA as u32])))
                } else {
                    (llconst, None)
                };

                let unsized_ty = target.builtin_deref(true, ty::NoPreference)
                    .expect("consts: unsizing got non-pointer target type").ty;
                let ptr_ty = type_of::in_memory_type_of(cx, unsized_ty).ptr_to();
                let base = ptrcast(base, ptr_ty);
                let info = base::unsized_info(cx, pointee_ty, unsized_ty, old_info);

                if old_info.is_none() {
                    let prev_const = cx.const_unsized().borrow_mut()
                                       .insert(base, llconst);
                    assert!(prev_const.is_none() || prev_const == Some(llconst));
                }
                assert_eq!(abi::FAT_PTR_ADDR, 0);
                assert_eq!(abi::FAT_PTR_EXTRA, 1);
                llconst = C_struct(cx, &[base, info], false);
            }
        }
        None => {}
    };

    let llty = type_of::sizing_type_of(cx, ety_adjusted);
    let csize = machine::llsize_of_alloc(cx, val_ty(llconst));
    let tsize = machine::llsize_of_alloc(cx, llty);
    if csize != tsize {
        cx.sess().abort_if_errors();
        unsafe {
            // FIXME these values could use some context
            llvm::LLVMDumpValue(llconst);
            llvm::LLVMDumpValue(C_undef(llty));
        }
        bug!("const {:?} of type {:?} has size {} instead of {}",
             e, ety_adjusted,
             csize, tsize);
    }
    Ok((llconst, ety_adjusted))
}

fn check_unary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
                             te: ValueRef, trueconst: TrueConst) -> Result<(), ConstEvalFailure> {
    // The only kind of unary expression that we check for validity
    // here is `-expr`, to check if it "overflows" (e.g. `-i32::MIN`).
    if let hir::ExprUnary(hir::UnNeg, ref inner_e) = e.node {

        // An unfortunate special case: we parse e.g. -128 as a
        // negation of the literal 128, which means if we're expecting
        // a i8 (or if it was already suffixed, e.g. `-128_i8`), then
        // 128 will have already overflowed to -128, and so then the
        // constant evaluator thinks we're trying to negate -128.
        //
        // Catch this up front by looking for ExprLit directly,
        // and just accepting it.
        if let hir::ExprLit(_) = inner_e.node { return Ok(()); }
        let cval = match to_const_int(te, t, cx.tcx()) {
            Some(v) => v,
            None => return Ok(()),
        };
        const_err(cx, e.span, (-cval).map_err(ErrKind::Math), trueconst)?;
    }
    Ok(())
}

pub fn to_const_int(value: ValueRef, t: Ty, tcx: TyCtxt) -> Option<ConstInt> {
    match t.sty {
        ty::TyInt(int_type) => const_to_opt_int(value).and_then(|input| match int_type {
            ast::IntTy::I8 => {
                assert_eq!(input as i8 as i64, input);
                Some(ConstInt::I8(input as i8))
            },
            ast::IntTy::I16 => {
                assert_eq!(input as i16 as i64, input);
                Some(ConstInt::I16(input as i16))
            },
            ast::IntTy::I32 => {
                assert_eq!(input as i32 as i64, input);
                Some(ConstInt::I32(input as i32))
            },
            ast::IntTy::I64 => {
                Some(ConstInt::I64(input))
            },
            ast::IntTy::Is => {
                ConstIsize::new(input, tcx.sess.target.int_type)
                    .ok().map(ConstInt::Isize)
            },
        }),
        ty::TyUint(uint_type) => const_to_opt_uint(value).and_then(|input| match uint_type {
            ast::UintTy::U8 => {
                assert_eq!(input as u8 as u64, input);
                Some(ConstInt::U8(input as u8))
            },
            ast::UintTy::U16 => {
                assert_eq!(input as u16 as u64, input);
                Some(ConstInt::U16(input as u16))
            },
            ast::UintTy::U32 => {
                assert_eq!(input as u32 as u64, input);
                Some(ConstInt::U32(input as u32))
            },
            ast::UintTy::U64 => {
                Some(ConstInt::U64(input))
            },
            ast::UintTy::Us => {
                ConstUsize::new(input, tcx.sess.target.uint_type)
                    .ok().map(ConstInt::Usize)
            },
        }),
        _ => None,
    }
}

pub fn const_err<T>(cx: &CrateContext,
                    span: Span,
                    result: Result<T, ErrKind>,
                    trueconst: TrueConst)
                    -> Result<T, ConstEvalFailure> {
    match (result, trueconst) {
        (Ok(x), _) => Ok(x),
        (Err(err), TrueConst::Yes) => {
            let err = ConstEvalErr{ span: span, kind: err };
            cx.tcx().sess.span_err(span, &err.description());
            Err(Compiletime(err))
        },
        (Err(err), TrueConst::No) => {
            let err = ConstEvalErr{ span: span, kind: err };
            cx.tcx().sess.span_warn(span, &err.description());
            Err(Runtime(err))
        },
    }
}

fn check_binary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
                              te1: ValueRef, te2: ValueRef,
                              trueconst: TrueConst) -> Result<(), ConstEvalFailure> {
    let b = if let hir::ExprBinary(b, _, _) = e.node { b } else { bug!() };
    let (lhs, rhs) = match (to_const_int(te1, t, cx.tcx()), to_const_int(te2, t, cx.tcx())) {
        (Some(v1), Some(v2)) => (v1, v2),
        _ => return Ok(()),
    };
    let result = match b.node {
        hir::BiAdd => lhs + rhs,
        hir::BiSub => lhs - rhs,
        hir::BiMul => lhs * rhs,
        hir::BiDiv => lhs / rhs,
        hir::BiRem => lhs % rhs,
        hir::BiShl => lhs << rhs,
        hir::BiShr => lhs >> rhs,
        _ => return Ok(()),
    };
    const_err(cx, e.span, result.map_err(ErrKind::Math), trueconst)?;
    Ok(())
}

fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                   e: &hir::Expr,
                                   ety: Ty<'tcx>,
                                   param_substs: &'tcx Substs<'tcx>,
                                   fn_args: FnArgMap,
                                   trueconst: TrueConst)
                                   -> Result<ValueRef, ConstEvalFailure>
{
    debug!("const_expr_unadjusted(e={:?}, ety={:?}, param_substs={:?})",
           e,
           ety,
           param_substs);

    let map_list = |exprs: &[P<hir::Expr>]| -> Result<Vec<ValueRef>, ConstEvalFailure> {
        exprs.iter()
             .map(|e| const_expr(cx, &e, param_substs, fn_args, trueconst).map(|(l, _)| l))
             .collect::<Vec<Result<ValueRef, ConstEvalFailure>>>()
             .into_iter()
             .collect()
         // this dance is necessary to eagerly run const_expr so all errors are reported
    };
    let _icx = push_ctxt("const_expr");
    Ok(match e.node {
        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. */
            let (te1, ty) = const_expr(cx, &e1, param_substs, fn_args, trueconst)?;
            debug!("const_expr_unadjusted: te1={:?}, ty={:?}",
                   Value(te1), ty);
            assert!(!ty.is_simd());
            let is_float = ty.is_fp();
            let signed = ty.is_signed();

            let (te2, ty2) = const_expr(cx, &e2, param_substs, fn_args, trueconst)?;
            debug!("const_expr_unadjusted: te2={:?}, ty={:?}",
                   Value(te2), ty2);

            check_binary_expr_validity(cx, e, ty, te1, te2, trueconst)?;

            unsafe { match b.node {
                hir::BiAdd if is_float => llvm::LLVMConstFAdd(te1, te2),
                hir::BiAdd             => llvm::LLVMConstAdd(te1, te2),

                hir::BiSub if is_float => llvm::LLVMConstFSub(te1, te2),
                hir::BiSub             => llvm::LLVMConstSub(te1, te2),

                hir::BiMul if is_float => llvm::LLVMConstFMul(te1, te2),
                hir::BiMul             => llvm::LLVMConstMul(te1, te2),

                hir::BiDiv if is_float => llvm::LLVMConstFDiv(te1, te2),
                hir::BiDiv if signed   => llvm::LLVMConstSDiv(te1, te2),
                hir::BiDiv             => llvm::LLVMConstUDiv(te1, te2),

                hir::BiRem if is_float => llvm::LLVMConstFRem(te1, te2),
                hir::BiRem if signed   => llvm::LLVMConstSRem(te1, te2),
                hir::BiRem             => llvm::LLVMConstURem(te1, te2),

                hir::BiAnd    => llvm::LLVMConstAnd(te1, te2),
                hir::BiOr     => llvm::LLVMConstOr(te1, te2),
                hir::BiBitXor => llvm::LLVMConstXor(te1, te2),
                hir::BiBitAnd => llvm::LLVMConstAnd(te1, te2),
                hir::BiBitOr  => llvm::LLVMConstOr(te1, te2),
                hir::BiShl    => {
                    let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
                    llvm::LLVMConstShl(te1, te2)
                },
                hir::BiShr    => {
                    let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
                    if signed { llvm::LLVMConstAShr(te1, te2) }
                    else      { llvm::LLVMConstLShr(te1, te2) }
                },
                hir::BiEq | hir::BiNe | hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe => {
                    if is_float {
                        let cmp = base::bin_op_to_fcmp_predicate(b.node);
                        ConstFCmp(cmp, te1, te2)
                    } else {
                        let cmp = base::bin_op_to_icmp_predicate(b.node, signed);
                        ConstICmp(cmp, te1, te2)
                    }
                },
            } } // unsafe { match b.node {
        },
        hir::ExprUnary(u, ref inner_e) => {
            let (te, ty) = const_expr(cx, &inner_e, param_substs, fn_args, trueconst)?;

            check_unary_expr_validity(cx, e, ty, te, trueconst)?;

            let is_float = ty.is_fp();
            unsafe { match u {
                hir::UnDeref           => const_deref(cx, te, ty).0,
                hir::UnNot             => llvm::LLVMConstNot(te),
                hir::UnNeg if is_float => llvm::LLVMConstFNeg(te),
                hir::UnNeg             => llvm::LLVMConstNeg(te),
            } }
        },
        hir::ExprField(ref base, field) => {
            let (bv, bt) = const_expr(cx, &base, param_substs, fn_args, trueconst)?;
            let brepr = adt::represent_type(cx, bt);
            let vinfo = VariantInfo::from_ty(cx.tcx(), bt, None);
            let ix = vinfo.field_index(field.node);
            adt::const_get_field(&brepr, bv, vinfo.discr, ix)
        },
        hir::ExprTupField(ref base, idx) => {
            let (bv, bt) = const_expr(cx, &base, param_substs, fn_args, trueconst)?;
            let brepr = adt::represent_type(cx, bt);
            let vinfo = VariantInfo::from_ty(cx.tcx(), bt, None);
            adt::const_get_field(&brepr, bv, vinfo.discr, idx.node)
        },
        hir::ExprIndex(ref base, ref index) => {
            let (bv, bt) = const_expr(cx, &base, param_substs, fn_args, trueconst)?;
            let iv = const_expr(cx, &index, param_substs, fn_args, TrueConst::Yes)?.0;
            let iv = if let Some(iv) = const_to_opt_uint(iv) {
                iv
            } else {
                span_bug!(index.span, "index is not an integer-constant expression");
            };
            let (arr, len) = match bt.sty {
                ty::TyArray(_, u) => (bv, C_uint(cx, u)),
                ty::TySlice(..) | ty::TyStr => {
                    let e1 = const_get_elt(bv, &[0]);
                    (load_const(cx, e1, bt), const_get_elt(bv, &[1]))
                },
                ty::TyRef(_, mt) => match mt.ty.sty {
                    ty::TyArray(_, u) => {
                        (load_const(cx, bv, mt.ty), C_uint(cx, u))
                    },
                    _ => span_bug!(base.span,
                                   "index-expr base must be a vector \
                                    or string type, found {:?}",
                                   bt),
                },
                _ => span_bug!(base.span,
                               "index-expr base must be a vector \
                                or string type, found {:?}",
                               bt),
            };

            let len = unsafe { llvm::LLVMConstIntGetZExtValue(len) as u64 };
            let len = match bt.sty {
                ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) => match ty.sty {
                    ty::TyStr => {
                        assert!(len > 0);
                        len - 1
                    },
                    _ => len,
                },
                _ => len,
            };
            if iv >= len {
                // FIXME #3170: report this earlier on in the const-eval
                // pass. Reporting here is a bit late.
                const_err(cx, e.span, Err(ErrKind::IndexOutOfBounds {
                    len: len,
                    index: iv
                }), trueconst)?;
                C_undef(val_ty(arr).element_type())
            } else {
                const_get_elt(arr, &[iv as c_uint])
            }
        },
        hir::ExprCast(ref base, _) => {
            let t_cast = ety;
            let llty = type_of::type_of(cx, t_cast);
            let (v, t_expr) = const_expr(cx, &base, param_substs, fn_args, trueconst)?;
            debug!("trans_const_cast({:?} as {:?})", t_expr, t_cast);
            if expr::cast_is_noop(cx.tcx(), base, t_expr, t_cast) {
                return Ok(v);
            }
            if type_is_fat_ptr(cx.tcx(), t_expr) {
                // Fat pointer casts.
                let t_cast_inner =
                    t_cast.builtin_deref(true, ty::NoPreference).expect("cast to non-pointer").ty;
                let ptr_ty = type_of::in_memory_type_of(cx, t_cast_inner).ptr_to();
                let addr = ptrcast(const_get_elt(v, &[abi::FAT_PTR_ADDR as u32]),
                                   ptr_ty);
                if type_is_fat_ptr(cx.tcx(), t_cast) {
                    let info = const_get_elt(v, &[abi::FAT_PTR_EXTRA as u32]);
                    return Ok(C_struct(cx, &[addr, info], false))
                } else {
                    return Ok(addr);
                }
            }
            unsafe { match (
                CastTy::from_ty(t_expr).expect("bad input type for cast"),
                CastTy::from_ty(t_cast).expect("bad output type for cast"),
            ) {
                (CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
                    let repr = adt::represent_type(cx, t_expr);
                    let discr = adt::const_get_discrim(&repr, v);
                    let iv = C_integral(cx.int_type(), discr.0, false);
                    let s = adt::is_discr_signed(&repr) as Bool;
                    llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
                },
                (CastTy::Int(_), CastTy::Int(_)) => {
                    let s = t_expr.is_signed() as Bool;
                    llvm::LLVMConstIntCast(v, llty.to_ref(), s)
                },
                (CastTy::Int(_), CastTy::Float) => {
                    if t_expr.is_signed() {
                        llvm::LLVMConstSIToFP(v, llty.to_ref())
                    } else {
                        llvm::LLVMConstUIToFP(v, llty.to_ref())
                    }
                },
                (CastTy::Float, CastTy::Float) => llvm::LLVMConstFPCast(v, llty.to_ref()),
                (CastTy::Float, CastTy::Int(IntTy::I)) => llvm::LLVMConstFPToSI(v, llty.to_ref()),
                (CastTy::Float, CastTy::Int(_)) => llvm::LLVMConstFPToUI(v, llty.to_ref()),
                (CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_))
                | (CastTy::RPtr(_), CastTy::Ptr(_)) => {
                    ptrcast(v, llty)
                },
                (CastTy::FnPtr, CastTy::FnPtr) => ptrcast(v, llty), // isn't this a coercion?
                (CastTy::Int(_), CastTy::Ptr(_)) => llvm::LLVMConstIntToPtr(v, llty.to_ref()),
                (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
                  llvm::LLVMConstPtrToInt(v, llty.to_ref())
                },
                _ => {
                  span_bug!(e.span, "bad combination of types for cast")
                },
            } } // unsafe { match ( ... ) {
        },
        hir::ExprAddrOf(hir::MutImmutable, ref sub) => {
            // If this is the address of some static, then we need to return
            // the actual address of the static itself (short circuit the rest
            // of const eval).
            let mut cur = sub;
            loop {
                match cur.node {
                    hir::ExprBlock(ref blk) => {
                        if let Some(ref sub) = blk.expr {
                            cur = sub;
                        } else {
                            break;
                        }
                    },
                    _ => break,
                }
            }
            if let Some(Def::Static(def_id, _)) = cx.tcx().expect_def_or_none(cur.id) {
                get_static(cx, def_id).val
            } else {
                // If this isn't the address of a static, then keep going through
                // normal constant evaluation.
                let (v, ty) = const_expr(cx, &sub, param_substs, fn_args, trueconst)?;
                addr_of(cx, v, type_of::align_of(cx, ty), "ref")
            }
        },
        hir::ExprAddrOf(hir::MutMutable, ref sub) => {
            let (v, ty) = const_expr(cx, &sub, param_substs, fn_args, trueconst)?;
            addr_of_mut(cx, v, type_of::align_of(cx, ty), "ref_mut_slice")
        },
        hir::ExprTup(ref es) => {
            let repr = adt::represent_type(cx, ety);
            let vals = map_list(&es[..])?;
            adt::trans_const(cx, &repr, Disr(0), &vals[..])
        },
        hir::ExprStruct(_, ref fs, ref base_opt) => {
            let repr = adt::represent_type(cx, ety);

            let base_val = match *base_opt {
                Some(ref base) => Some(const_expr(
                    cx,
                    &base,
                    param_substs,
                    fn_args,
                    trueconst,
                )?),
                None => None
            };

            let VariantInfo { discr, fields } = VariantInfo::of_node(cx.tcx(), ety, e.id);
            let cs = fields.iter().enumerate().map(|(ix, &Field(f_name, _))| {
                match (fs.iter().find(|f| f_name == f.name.node), base_val) {
                    (Some(ref f), _) => {
                        const_expr(cx, &f.expr, param_substs, fn_args, trueconst).map(|(l, _)| l)
                    },
                    (_, Some((bv, _))) => Ok(adt::const_get_field(&repr, bv, discr, ix)),
                    (_, None) => span_bug!(e.span, "missing struct field"),
                }
            })
            .collect::<Vec<Result<_, ConstEvalFailure>>>()
            .into_iter()
            .collect::<Result<Vec<_>,ConstEvalFailure>>();
            let cs = cs?;
            if ety.is_simd() {
                C_vector(&cs[..])
            } else {
                adt::trans_const(cx, &repr, discr, &cs[..])
            }
        },
        hir::ExprVec(ref es) => {
            let unit_ty = ety.sequence_element_type(cx.tcx());
            let llunitty = type_of::type_of(cx, unit_ty);
            let vs = es.iter()
                       .map(|e| const_expr(
                           cx,
                           &e,
                           param_substs,
                           fn_args,
                           trueconst,
                       ).map(|(l, _)| l))
                       .collect::<Vec<Result<_, ConstEvalFailure>>>()
                       .into_iter()
                       .collect::<Result<Vec<_>, ConstEvalFailure>>();
            let vs = vs?;
            // If the vector contains enums, an LLVM array won't work.
            if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
                C_struct(cx, &vs[..], false)
            } else {
                C_array(llunitty, &vs[..])
            }
        },
        hir::ExprRepeat(ref elem, ref count) => {
            let unit_ty = ety.sequence_element_type(cx.tcx());
            let llunitty = type_of::type_of(cx, unit_ty);
            let n = eval_repeat_count(cx.tcx(), count);
            let unit_val = const_expr(cx, &elem, param_substs, fn_args, trueconst)?.0;
            let vs = vec![unit_val; n];
            if val_ty(unit_val) != llunitty {
                C_struct(cx, &vs[..], false)
            } else {
                C_array(llunitty, &vs[..])
            }
        },
        hir::ExprPath(..) => {
            match cx.tcx().expect_def(e.id) {
                Def::Local(_, id) => {
                    if let Some(val) = fn_args.and_then(|args| args.get(&id).cloned()) {
                        val
                    } else {
                        span_bug!(e.span, "const fn argument not found")
                    }
                }
                Def::Fn(..) | Def::Method(..) => C_nil(cx),
                Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                    load_const(cx, get_const_val(cx, def_id, e, param_substs)?,
                               ety)
                }
                Def::Variant(enum_did, variant_did) => {
                    let vinfo = cx.tcx().lookup_adt_def(enum_did).variant_with_id(variant_did);
                    match vinfo.kind {
                        ty::VariantKind::Unit => {
                            let repr = adt::represent_type(cx, ety);
                            adt::trans_const(cx, &repr, Disr::from(vinfo.disr_val), &[])
                        }
                        ty::VariantKind::Tuple => C_nil(cx),
                        ty::VariantKind::Struct => {
                            span_bug!(e.span, "path-expr refers to a dict variant!")
                        }
                    }
                }
                // Unit struct or ctor.
                Def::Struct(..) => C_null(type_of::type_of(cx, ety)),
                _ => {
                    span_bug!(e.span, "expected a const, fn, struct, \
                                       or variant def")
                }
            }
        },
        hir::ExprCall(ref callee, ref args) => {
            let mut callee = &**callee;
            loop {
                callee = match callee.node {
                    hir::ExprBlock(ref block) => match block.expr {
                        Some(ref tail) => &tail,
                        None => break,
                    },
                    _ => break,
                };
            }
            let arg_vals = map_list(args)?;
            match cx.tcx().expect_def(callee.id) {
                Def::Fn(did) | Def::Method(did) => {
                    const_fn_call(
                        cx,
                        did,
                        cx.tcx().node_id_item_substs(callee.id).substs,
                        &arg_vals,
                        param_substs,
                        trueconst,
                    )?
                }
                Def::Struct(..) => {
                    if ety.is_simd() {
                        C_vector(&arg_vals[..])
                    } else {
                        let repr = adt::represent_type(cx, ety);
                        adt::trans_const(cx, &repr, Disr(0), &arg_vals[..])
                    }
                }
                Def::Variant(enum_did, variant_did) => {
                    let repr = adt::represent_type(cx, ety);
                    let vinfo = cx.tcx().lookup_adt_def(enum_did).variant_with_id(variant_did);
                    adt::trans_const(cx,
                                     &repr,
                                     Disr::from(vinfo.disr_val),
                                     &arg_vals[..])
                }
                _ => span_bug!(e.span, "expected a struct, variant, or const fn def"),
            }
        },
        hir::ExprMethodCall(_, _, ref args) => {
            let arg_vals = map_list(args)?;
            let method_call = ty::MethodCall::expr(e.id);
            let method = cx.tcx().tables.borrow().method_map[&method_call];
            const_fn_call(cx, method.def_id, method.substs,
                          &arg_vals, param_substs, trueconst)?
        },
        hir::ExprType(ref e, _) => const_expr(cx, &e, param_substs, fn_args, trueconst)?.0,
        hir::ExprBlock(ref block) => {
            match block.expr {
                Some(ref expr) => const_expr(
                    cx,
                    &expr,
                    param_substs,
                    fn_args,
                    trueconst,
                )?.0,
                None => C_nil(cx),
            }
        },
        hir::ExprClosure(_, ref decl, ref body, _) => {
            match ety.sty {
                ty::TyClosure(def_id, substs) => {
                    closure::trans_closure_expr(closure::Dest::Ignore(cx),
                                                decl,
                                                body,
                                                e.id,
                                                def_id,
                                                substs);
                }
                _ =>
                    span_bug!(
                        e.span,
                        "bad type for closure expr: {:?}", ety)
            }
            C_null(type_of::type_of(cx, ety))
        },
        _ => span_bug!(e.span,
                       "bad constant expression type in consts::const_expr"),
    })
}

pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
                            -> Datum<'tcx, Lvalue> {
    let ty = ccx.tcx().lookup_item_type(def_id).ty;

    let instance = Instance::mono(ccx.shared(), def_id);
    if let Some(&g) = ccx.instances().borrow().get(&instance) {
        return Datum::new(g, ty, Lvalue::new("static"));
    }

    let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) {

        let llty = type_of::type_of(ccx, ty);
        let (g, attrs) = match ccx.tcx().map.get(id) {
            hir_map::NodeItem(&hir::Item {
                ref attrs, span, node: hir::ItemStatic(..), ..
            }) => {
                let sym = ccx.symbol_map()
                             .get(TransItem::Static(id))
                             .expect("Local statics should always be in the SymbolMap");
                // Make sure that this is never executed for something inlined.
                assert!(!ccx.external_srcs().borrow().contains_key(&id));

                let defined_in_current_codegen_unit = ccx.codegen_unit()
                                                         .items
                                                         .contains_key(&TransItem::Static(id));
                if defined_in_current_codegen_unit {
                    if declare::get_declared_value(ccx, sym).is_none() {
                        span_bug!(span, "trans: Static not properly pre-defined?");
                    }
                } else {
                    if declare::get_declared_value(ccx, sym).is_some() {
                        span_bug!(span, "trans: Conflicting symbol names for static?");
                    }
                }

                let g = declare::define_global(ccx, sym, llty).unwrap();

                (g, attrs)
            }

            hir_map::NodeForeignItem(&hir::ForeignItem {
                ref attrs, span, node: hir::ForeignItemStatic(..), ..
            }) => {
                let sym = instance.symbol_name(ccx.shared());
                let g = if let Some(name) =
                        attr::first_attr_value_str_by_name(&attrs, "linkage") {
                    // If this is a static with a linkage specified, then we need to handle
                    // it a little specially. The typesystem prevents things like &T and
                    // extern "C" fn() from being non-null, so we can't just declare a
                    // static and call it a day. Some linkages (like weak) will make it such
                    // that the static actually has a null value.
                    let linkage = match base::llvm_linkage_by_name(&name) {
                        Some(linkage) => linkage,
                        None => {
                            ccx.sess().span_fatal(span, "invalid linkage specified");
                        }
                    };
                    let llty2 = match ty.sty {
                        ty::TyRawPtr(ref mt) => type_of::type_of(ccx, mt.ty),
                        _ => {
                            ccx.sess().span_fatal(span, "must have type `*const T` or `*mut T`");
                        }
                    };
                    unsafe {
                        // Declare a symbol `foo` with the desired linkage.
                        let g1 = declare::declare_global(ccx, &sym, llty2);
                        llvm::SetLinkage(g1, linkage);

                        // Declare an internal global `extern_with_linkage_foo` which
                        // is initialized with the address of `foo`.  If `foo` is
                        // discarded during linking (for example, if `foo` has weak
                        // linkage and there are no definitions), then
                        // `extern_with_linkage_foo` will instead be initialized to
                        // zero.
                        let mut real_name = "_rust_extern_with_linkage_".to_string();
                        real_name.push_str(&sym);
                        let g2 = declare::define_global(ccx, &real_name, llty).unwrap_or_else(||{
                            ccx.sess().span_fatal(span,
                                &format!("symbol `{}` is already defined", &sym))
                        });
                        llvm::SetLinkage(g2, llvm::InternalLinkage);
                        llvm::LLVMSetInitializer(g2, g1);
                        g2
                    }
                } else {
                    // Generate an external declaration.
                    declare::declare_global(ccx, &sym, llty)
                };

                (g, attrs)
            }

            item => bug!("get_static: expected static, found {:?}", item)
        };

        for attr in attrs {
            if attr.check_name("thread_local") {
                llvm::set_thread_local(g, true);
            }
        }

        g
    } else {
        let sym = instance.symbol_name(ccx.shared());

        // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
        // FIXME(nagisa): investigate whether it can be changed into define_global
        let g = declare::declare_global(ccx, &sym, type_of::type_of(ccx, ty));
        // Thread-local statics in some other crate need to *always* be linked
        // against in a thread-local fashion, so we need to be sure to apply the
        // thread-local attribute locally if it was present remotely. If we
        // don't do this then linker errors can be generated where the linker
        // complains that one object files has a thread local version of the
        // symbol and another one doesn't.
        for attr in ccx.tcx().get_attrs(def_id).iter() {
            if attr.check_name("thread_local") {
                llvm::set_thread_local(g, true);
            }
        }
        if ccx.use_dll_storage_attrs() {
            llvm::SetDLLStorageClass(g, llvm::DLLImportStorageClass);
        }
        g
    };

    ccx.instances().borrow_mut().insert(instance, g);
    ccx.statics().borrow_mut().insert(g, def_id);
    Datum::new(g, ty, Lvalue::new("static"))
}

pub fn trans_static(ccx: &CrateContext,
                    m: hir::Mutability,
                    expr: &hir::Expr,
                    id: ast::NodeId,
                    attrs: &[ast::Attribute])
                    -> Result<ValueRef, ConstEvalErr> {
    unsafe {
        let _icx = push_ctxt("trans_static");
        let def_id = ccx.tcx().map.local_def_id(id);
        let datum = get_static(ccx, def_id);

        let check_attrs = |attrs: &[ast::Attribute]| {
            let default_to_mir = ccx.sess().opts.debugging_opts.orbit;
            let invert = if default_to_mir { "rustc_no_mir" } else { "rustc_mir" };
            default_to_mir ^ attrs.iter().any(|item| item.check_name(invert))
        };
        let use_mir = check_attrs(ccx.tcx().map.attrs(id));

        let v = if use_mir {
            ::mir::trans_static_initializer(ccx, def_id)
        } else {
            let empty_substs = ccx.tcx().mk_substs(Substs::empty());
            const_expr(ccx, expr, empty_substs, None, TrueConst::Yes)
                .map(|(v, _)| v)
        }.map_err(|e| e.into_inner())?;

        // boolean SSA values are i1, but they have to be stored in i8 slots,
        // otherwise some LLVM optimization passes don't work as expected
        let mut val_llty = val_ty(v);
        let v = if val_llty == Type::i1(ccx) {
            val_llty = Type::i8(ccx);
            llvm::LLVMConstZExt(v, val_llty.to_ref())
        } else {
            v
        };

        let llty = type_of::type_of(ccx, datum.ty);
        let g = if val_llty == llty {
            datum.val
        } else {
            // If we created the global with the wrong type,
            // correct the type.
            let empty_string = CString::new("").unwrap();
            let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(datum.val));
            let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
            llvm::LLVMSetValueName(datum.val, empty_string.as_ptr());
            let new_g = llvm::LLVMGetOrInsertGlobal(
                ccx.llmod(), name_string.as_ptr(), val_llty.to_ref());
            // To avoid breaking any invariants, we leave around the old
            // global for the moment; we'll replace all references to it
            // with the new global later. (See base::trans_crate.)
            ccx.statics_to_rauw().borrow_mut().push((datum.val, new_g));
            new_g
        };
        llvm::LLVMSetAlignment(g, type_of::align_of(ccx, datum.ty));
        llvm::LLVMSetInitializer(g, v);

        // As an optimization, all shared statics which do not have interior
        // mutability are placed into read-only memory.
        if m != hir::MutMutable {
            let tcontents = datum.ty.type_contents(ccx.tcx());
            if !tcontents.interior_unsafe() {
                llvm::LLVMSetGlobalConstant(g, llvm::True);
            }
        }

        debuginfo::create_global_var_metadata(ccx, id, g);

        if attr::contains_name(attrs,
                               "thread_local") {
            llvm::set_thread_local(g, true);
        }

        base::set_link_section(ccx, g, attrs);

        Ok(g)
    }
}
