1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use rustc
::ty
::{Ty, TypeFoldable}
;
13 use rustc
::middle
::const_val
::ConstVal
;
14 use rustc_const_math
::ConstInt
::*;
15 use rustc_const_eval
::lookup_const_by_id
;
16 use rustc
::mir
::repr
as mir
;
18 use common
::{self, BlockAndBuilder
, C_bool
, C_bytes
, C_floating_f64
, C_integral
,
19 C_str_slice
, C_undef
};
26 use super::operand
::{OperandRef, OperandValue}
;
27 use super::MirContext
;
30 impl<'bcx
, 'tcx
> MirContext
<'bcx
, 'tcx
> {
31 pub fn trans_constval(&mut self,
32 bcx
: &BlockAndBuilder
<'bcx
, 'tcx
>,
38 let val
= self.trans_constval_inner(bcx
, cv
, ty
);
39 let val
= if common
::type_is_immediate(ccx
, ty
) {
40 OperandValue
::Immediate(val
)
41 } else if common
::type_is_fat_ptr(bcx
.tcx(), ty
) {
42 let data
= common
::const_get_elt(val
, &[abi
::FAT_PTR_ADDR
as u32]);
43 let extra
= common
::const_get_elt(val
, &[abi
::FAT_PTR_EXTRA
as u32]);
44 OperandValue
::FatPtr(data
, extra
)
46 OperandValue
::Ref(val
)
49 assert
!(!ty
.has_erasable_regions());
57 /// Translate ConstVal into a bare LLVM ValueRef.
58 fn trans_constval_inner(&mut self,
59 bcx
: &BlockAndBuilder
<'bcx
, 'tcx
>,
65 let llty
= type_of
::type_of(ccx
, ty
);
67 ConstVal
::Float(v
) => C_floating_f64(v
, llty
),
68 ConstVal
::Bool(v
) => C_bool(ccx
, v
),
69 ConstVal
::Integral(I8(v
)) => C_integral(Type
::i8(ccx
), v
as u64, true),
70 ConstVal
::Integral(I16(v
)) => C_integral(Type
::i16(ccx
), v
as u64, true),
71 ConstVal
::Integral(I32(v
)) => C_integral(Type
::i32(ccx
), v
as u64, true),
72 ConstVal
::Integral(I64(v
)) => C_integral(Type
::i64(ccx
), v
as u64, true),
73 ConstVal
::Integral(Isize(v
)) => {
74 let i
= v
.as_i64(ccx
.tcx().sess
.target
.int_type
);
75 C_integral(Type
::int(ccx
), i
as u64, true)
77 ConstVal
::Integral(U8(v
)) => C_integral(Type
::i8(ccx
), v
as u64, false),
78 ConstVal
::Integral(U16(v
)) => C_integral(Type
::i16(ccx
), v
as u64, false),
79 ConstVal
::Integral(U32(v
)) => C_integral(Type
::i32(ccx
), v
as u64, false),
80 ConstVal
::Integral(U64(v
)) => C_integral(Type
::i64(ccx
), v
, false),
81 ConstVal
::Integral(Usize(v
)) => {
82 let u
= v
.as_u64(ccx
.tcx().sess
.target
.uint_type
);
83 C_integral(Type
::int(ccx
), u
, false)
85 ConstVal
::Integral(Infer(v
)) => C_integral(llty
, v
as u64, false),
86 ConstVal
::Integral(InferSigned(v
)) => C_integral(llty
, v
as u64, true),
87 ConstVal
::Str(ref v
) => C_str_slice(ccx
, v
.clone()),
88 ConstVal
::ByteStr(ref v
) => consts
::addr_of(ccx
, C_bytes(ccx
, v
), 1, "byte_str"),
89 ConstVal
::Struct(_
) | ConstVal
::Tuple(_
) |
90 ConstVal
::Array(..) | ConstVal
::Repeat(..) |
91 ConstVal
::Function(_
) => {
92 bug
!("MIR must not use {:?} (which refers to a local ID)", cv
)
94 ConstVal
::Char(c
) => C_integral(Type
::char(ccx
), c
as u64, false),
95 ConstVal
::Dummy
=> bug
!(),
99 pub fn trans_constant(&mut self,
100 bcx
: &BlockAndBuilder
<'bcx
, 'tcx
>,
101 constant
: &mir
::Constant
<'tcx
>)
104 let ty
= bcx
.monomorphize(&constant
.ty
);
105 match constant
.literal
{
106 mir
::Literal
::Item { def_id, substs }
=> {
107 // Shortcut for zero-sized types, including function item
108 // types, which would not work with lookup_const_by_id.
109 if common
::type_is_zero_size(bcx
.ccx(), ty
) {
110 let llty
= type_of
::type_of(bcx
.ccx(), ty
);
112 val
: OperandValue
::Immediate(C_undef(llty
)),
117 let substs
= Some(bcx
.monomorphize(substs
));
118 let expr
= lookup_const_by_id(bcx
.tcx(), def_id
, substs
)
119 .expect("def was const, but lookup_const_by_id failed").0;
120 // FIXME: this is falling back to translating from HIR. This is not easy to fix,
121 // because we would have somehow adapt const_eval to work on MIR rather than HIR.
122 let d
= bcx
.with_block(|bcx
| {
123 expr
::trans(bcx
, expr
)
126 let datum
= d
.datum
.to_rvalue_datum(d
.bcx
, "").datum
;
128 match datum
.kind
.mode
{
129 datum
::RvalueMode
::ByValue
=> {
132 val
: OperandValue
::Immediate(datum
.val
)
135 datum
::RvalueMode
::ByRef
=> self.trans_load(bcx
, datum
.val
, datum
.ty
)
138 mir
::Literal
::Value { ref value }
=> {
139 self.trans_constval(bcx
, value
, ty
)