]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/trans/mir/operand.rs
a0308032ac07bb4e1e4a0438af3769bafaf4e394
[rust.git] / src / librustc_trans / trans / mir / operand.rs
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.
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 use llvm::ValueRef;
12 use rustc::middle::ty::Ty;
13 use rustc_mir::repr as mir;
14 use trans::base;
15 use trans::build;
16 use trans::common::Block;
17 use trans::datum;
18
19 use super::{MirContext, TempRef};
20
21 #[derive(Copy, Clone)]
22 pub struct OperandRef<'tcx> {
23     // This will be "indirect" if `appropriate_rvalue_mode` returns
24     // ByRef, and otherwise ByValue.
25     pub llval: ValueRef,
26
27     // The type of value being returned.
28     pub ty: Ty<'tcx>
29 }
30
31 impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
32     pub fn trans_operand(&mut self,
33                          bcx: Block<'bcx, 'tcx>,
34                          operand: &mir::Operand<'tcx>)
35                          -> OperandRef<'tcx>
36     {
37         debug!("trans_operand(operand={:?})", operand);
38
39         match *operand {
40             mir::Operand::Consume(ref lvalue) => {
41                 // watch out for temporaries that do not have an
42                 // alloca; they are handled somewhat differently
43                 if let &mir::Lvalue::Temp(index) = lvalue {
44                     match self.temps[index as usize] {
45                         TempRef::Operand(Some(o)) => {
46                             return o;
47                         }
48                         TempRef::Operand(None) => {
49                             bcx.tcx().sess.bug(
50                                 &format!("use of {:?} before def", lvalue));
51                         }
52                         TempRef::Lvalue(..) => {
53                             // use path below
54                         }
55                     }
56                 }
57
58                 // for most lvalues, to consume them we just load them
59                 // out from their home
60                 let tr_lvalue = self.trans_lvalue(bcx, lvalue);
61                 let ty = tr_lvalue.ty.to_ty(bcx.tcx());
62                 debug!("trans_operand: tr_lvalue={} @ {:?}",
63                        bcx.val_to_string(tr_lvalue.llval),
64                        ty);
65                 let llval = match datum::appropriate_rvalue_mode(bcx.ccx(), ty) {
66                     datum::ByValue => build::Load(bcx, tr_lvalue.llval),
67                     datum::ByRef => tr_lvalue.llval,
68                 };
69                 OperandRef {
70                     llval: llval,
71                     ty: ty
72                 }
73             }
74
75             mir::Operand::Constant(ref constant) => {
76                 let llval = self.trans_constant(bcx, constant);
77                 let ty = bcx.monomorphize(&constant.ty);
78                 OperandRef {
79                     llval: llval,
80                     ty: ty,
81                 }
82             }
83         }
84     }
85
86     pub fn trans_operand_into(&mut self,
87                               bcx: Block<'bcx, 'tcx>,
88                               lldest: ValueRef,
89                               operand: &mir::Operand<'tcx>)
90     {
91         debug!("trans_operand_into(lldest={}, operand={:?})",
92                bcx.val_to_string(lldest),
93                operand);
94
95         match *operand {
96             mir::Operand::Consume(ref lvalue) => {
97                 let tr_lvalue = self.trans_lvalue(bcx, lvalue);
98                 let lvalue_ty = tr_lvalue.ty.to_ty(bcx.tcx());
99                 debug!("trans_operand_into: tr_lvalue={} @ {:?}",
100                        bcx.val_to_string(tr_lvalue.llval),
101                        lvalue_ty);
102                 base::memcpy_ty(bcx, lldest, tr_lvalue.llval, lvalue_ty);
103             }
104
105             mir::Operand::Constant(..) => {
106                 unimplemented!()
107             }
108         }
109     }
110 }