1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use rustc::mir;
use base;
use asm;
use common;
use builder::Builder;
use super::MirContext;
use super::LocalRef;
use super::super::adt;
use super::super::disr::Disr;
impl<'a, 'tcx> MirContext<'a, 'tcx> {
pub fn trans_statement(&mut self,
bcx: Builder<'a, 'tcx>,
statement: &mir::Statement<'tcx>)
-> Builder<'a, 'tcx> {
debug!("trans_statement(statement={:?})", statement);
self.set_debug_loc(&bcx, statement.source_info);
match statement.kind {
mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
if let mir::Lvalue::Local(index) = *lvalue {
match self.locals[index] {
LocalRef::Lvalue(tr_dest) => {
self.trans_rvalue(bcx, tr_dest, rvalue)
}
LocalRef::Operand(None) => {
let (bcx, operand) = self.trans_rvalue_operand(bcx, rvalue);
self.locals[index] = LocalRef::Operand(Some(operand));
bcx
}
LocalRef::Operand(Some(_)) => {
let ty = self.monomorphized_lvalue_ty(lvalue);
if !common::type_is_zero_size(bcx.ccx, ty) {
span_bug!(statement.source_info.span,
"operand {:?} already assigned",
rvalue);
} else {
self.trans_rvalue_operand(bcx, rvalue).0
}
}
}
} else {
let tr_dest = self.trans_lvalue(&bcx, lvalue);
self.trans_rvalue(bcx, tr_dest, rvalue)
}
}
mir::StatementKind::SetDiscriminant{ref lvalue, variant_index} => {
let ty = self.monomorphized_lvalue_ty(lvalue);
let lvalue_transed = self.trans_lvalue(&bcx, lvalue);
adt::trans_set_discr(&bcx,
ty,
lvalue_transed.llval,
Disr::from(variant_index));
bcx
}
mir::StatementKind::StorageLive(ref lvalue) => {
self.trans_storage_liveness(bcx, lvalue, base::Lifetime::Start)
}
mir::StatementKind::StorageDead(ref lvalue) => {
self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End)
}
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
let outputs = outputs.iter().map(|output| {
let lvalue = self.trans_lvalue(&bcx, output);
(lvalue.llval, lvalue.ty.to_ty(bcx.tcx()))
}).collect();
let input_vals = inputs.iter().map(|input| {
self.trans_operand(&bcx, input).immediate()
}).collect();
asm::trans_inline_asm(&bcx, asm, outputs, input_vals);
bcx
}
mir::StatementKind::Nop => bcx,
}
}
fn trans_storage_liveness(&self,
bcx: Builder<'a, 'tcx>,
lvalue: &mir::Lvalue<'tcx>,
intrinsic: base::Lifetime)
-> Builder<'a, 'tcx> {
if let mir::Lvalue::Local(index) = *lvalue {
if let LocalRef::Lvalue(tr_lval) = self.locals[index] {
intrinsic.call(&bcx, tr_lval.llval);
}
}
bcx
}
}