]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2015 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. | |
4 | // | |
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. | |
10 | ||
11 | //! Miscellaneous builder routines that are not specific to building any particular | |
12 | //! kind of thing. | |
13 | ||
14 | use build::Builder; | |
3157f602 XL |
15 | |
16 | use rustc_const_math::{ConstInt, ConstUsize, ConstIsize}; | |
17 | use rustc::middle::const_val::ConstVal; | |
18 | use rustc::ty::{self, Ty}; | |
19 | ||
c30ab7b3 | 20 | use rustc::mir::*; |
3157f602 | 21 | use syntax::ast; |
ff7c6d11 | 22 | use syntax_pos::{Span, DUMMY_SP}; |
e9174d1e | 23 | |
a7813a04 | 24 | impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { |
e9174d1e SL |
25 | /// Add a new temporary value of type `ty` storing the result of |
26 | /// evaluating `expr`. | |
27 | /// | |
28 | /// NB: **No cleanup is scheduled for this temporary.** You should | |
29 | /// call `schedule_drop` once the temporary is initialized. | |
ff7c6d11 | 30 | pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> { |
cc61c64b | 31 | let temp = self.local_decls.push(LocalDecl::new_temp(ty, span)); |
ff7c6d11 | 32 | let place = Place::Local(temp); |
e9174d1e | 33 | debug!("temp: created temp {:?} with type {:?}", |
ff7c6d11 XL |
34 | place, self.local_decls[temp].ty); |
35 | place | |
e9174d1e SL |
36 | } |
37 | ||
92a42be0 SL |
38 | pub fn literal_operand(&mut self, |
39 | span: Span, | |
40 | ty: Ty<'tcx>, | |
41 | literal: Literal<'tcx>) | |
42 | -> Operand<'tcx> { | |
cc61c64b | 43 | let constant = box Constant { |
3b2f2976 XL |
44 | span, |
45 | ty, | |
46 | literal, | |
b039eaaf | 47 | }; |
92a42be0 | 48 | Operand::Constant(constant) |
e9174d1e SL |
49 | } |
50 | ||
a7813a04 | 51 | pub fn unit_rvalue(&mut self) -> Rvalue<'tcx> { |
cc61c64b | 52 | Rvalue::Aggregate(box AggregateKind::Tuple, vec![]) |
a7813a04 XL |
53 | } |
54 | ||
3157f602 XL |
55 | // Returns a zero literal operand for the appropriate type, works for |
56 | // bool, char and integers. | |
57 | pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { | |
58 | let literal = match ty.sty { | |
59 | ty::TyBool => { | |
60 | self.hir.false_literal() | |
61 | } | |
ea8adc8c XL |
62 | ty::TyChar => { |
63 | Literal::Value { | |
64 | value: self.hir.tcx().mk_const(ty::Const { | |
65 | val: ConstVal::Char('\0'), | |
66 | ty | |
67 | }) | |
68 | } | |
69 | } | |
3157f602 XL |
70 | ty::TyUint(ity) => { |
71 | let val = match ity { | |
72 | ast::UintTy::U8 => ConstInt::U8(0), | |
73 | ast::UintTy::U16 => ConstInt::U16(0), | |
74 | ast::UintTy::U32 => ConstInt::U32(0), | |
75 | ast::UintTy::U64 => ConstInt::U64(0), | |
32a655c1 | 76 | ast::UintTy::U128 => ConstInt::U128(0), |
2c00a5a8 | 77 | ast::UintTy::Usize => { |
ea8adc8c | 78 | let uint_ty = self.hir.tcx().sess.target.usize_ty; |
3157f602 XL |
79 | let val = ConstUsize::new(0, uint_ty).unwrap(); |
80 | ConstInt::Usize(val) | |
81 | } | |
82 | }; | |
83 | ||
ea8adc8c XL |
84 | Literal::Value { |
85 | value: self.hir.tcx().mk_const(ty::Const { | |
86 | val: ConstVal::Integral(val), | |
87 | ty | |
88 | }) | |
89 | } | |
3157f602 XL |
90 | } |
91 | ty::TyInt(ity) => { | |
92 | let val = match ity { | |
93 | ast::IntTy::I8 => ConstInt::I8(0), | |
94 | ast::IntTy::I16 => ConstInt::I16(0), | |
95 | ast::IntTy::I32 => ConstInt::I32(0), | |
96 | ast::IntTy::I64 => ConstInt::I64(0), | |
32a655c1 | 97 | ast::IntTy::I128 => ConstInt::I128(0), |
2c00a5a8 | 98 | ast::IntTy::Isize => { |
ea8adc8c | 99 | let int_ty = self.hir.tcx().sess.target.isize_ty; |
3157f602 XL |
100 | let val = ConstIsize::new(0, int_ty).unwrap(); |
101 | ConstInt::Isize(val) | |
102 | } | |
103 | }; | |
104 | ||
ea8adc8c XL |
105 | Literal::Value { |
106 | value: self.hir.tcx().mk_const(ty::Const { | |
107 | val: ConstVal::Integral(val), | |
108 | ty | |
109 | }) | |
110 | } | |
3157f602 XL |
111 | } |
112 | _ => { | |
113 | span_bug!(span, "Invalid type for zero_literal: `{:?}`", ty) | |
114 | } | |
115 | }; | |
116 | ||
117 | self.literal_operand(span, ty, literal) | |
118 | } | |
119 | ||
54a0048b SL |
120 | pub fn push_usize(&mut self, |
121 | block: BasicBlock, | |
3157f602 | 122 | source_info: SourceInfo, |
54a0048b | 123 | value: u64) |
ff7c6d11 | 124 | -> Place<'tcx> { |
e9174d1e | 125 | let usize_ty = self.hir.usize_ty(); |
cc61c64b | 126 | let temp = self.temp(usize_ty, source_info.span); |
e9174d1e | 127 | self.cfg.push_assign_constant( |
3157f602 | 128 | block, source_info, &temp, |
e9174d1e | 129 | Constant { |
3157f602 | 130 | span: source_info.span, |
b039eaaf SL |
131 | ty: self.hir.usize_ty(), |
132 | literal: self.hir.usize_literal(value), | |
e9174d1e SL |
133 | }); |
134 | temp | |
135 | } | |
ff7c6d11 XL |
136 | |
137 | pub fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> { | |
138 | let tcx = self.hir.tcx(); | |
139 | let ty = place.ty(&self.local_decls, tcx).to_ty(tcx); | |
140 | if self.hir.type_moves_by_default(ty, DUMMY_SP) { | |
141 | Operand::Move(place) | |
142 | } else { | |
143 | Operand::Copy(place) | |
144 | } | |
145 | } | |
e9174d1e | 146 | } |