]>
Commit | Line | Data |
---|---|---|
c30ab7b3 | 1 | use rustc::mir; |
3157f602 | 2 | |
a1dfa0c6 | 3 | use traits::BuilderMethods; |
2c00a5a8 | 4 | use super::FunctionCx; |
3157f602 | 5 | use super::LocalRef; |
0bf4aa26 | 6 | use super::OperandValue; |
a1dfa0c6 | 7 | use traits::*; |
92a42be0 | 8 | |
a1dfa0c6 XL |
9 | impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
10 | pub fn codegen_statement( | |
11 | &mut self, | |
12 | mut bx: Bx, | |
13 | statement: &mir::Statement<'tcx> | |
14 | ) -> Bx { | |
94b46f34 | 15 | debug!("codegen_statement(statement={:?})", statement); |
92a42be0 | 16 | |
a1dfa0c6 | 17 | self.set_debug_loc(&mut bx, statement.source_info); |
92a42be0 | 18 | match statement.kind { |
ff7c6d11 XL |
19 | mir::StatementKind::Assign(ref place, ref rvalue) => { |
20 | if let mir::Place::Local(index) = *place { | |
3157f602 | 21 | match self.locals[index] { |
94b46f34 XL |
22 | LocalRef::Place(cg_dest) => { |
23 | self.codegen_rvalue(bx, cg_dest, rvalue) | |
3157f602 | 24 | } |
b7449926 XL |
25 | LocalRef::UnsizedPlace(cg_indirect_dest) => { |
26 | self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue) | |
27 | } | |
3157f602 | 28 | LocalRef::Operand(None) => { |
94b46f34 | 29 | let (bx, operand) = self.codegen_rvalue_operand(bx, rvalue); |
3157f602 | 30 | self.locals[index] = LocalRef::Operand(Some(operand)); |
2c00a5a8 | 31 | bx |
3157f602 | 32 | } |
ff7c6d11 XL |
33 | LocalRef::Operand(Some(op)) => { |
34 | if !op.layout.is_zst() { | |
3157f602 XL |
35 | span_bug!(statement.source_info.span, |
36 | "operand {:?} already assigned", | |
37 | rvalue); | |
92a42be0 | 38 | } |
ff7c6d11 XL |
39 | |
40 | // If the type is zero-sized, it's already been set here, | |
94b46f34 XL |
41 | // but we still need to make sure we codegen the operand |
42 | self.codegen_rvalue_operand(bx, rvalue).0 | |
92a42be0 SL |
43 | } |
44 | } | |
3157f602 | 45 | } else { |
a1dfa0c6 | 46 | let cg_dest = self.codegen_place(&mut bx, place); |
94b46f34 | 47 | self.codegen_rvalue(bx, cg_dest, rvalue) |
92a42be0 SL |
48 | } |
49 | } | |
ff7c6d11 | 50 | mir::StatementKind::SetDiscriminant{ref place, variant_index} => { |
a1dfa0c6 XL |
51 | self.codegen_place(&mut bx, place) |
52 | .codegen_set_discr(&mut bx, variant_index); | |
2c00a5a8 | 53 | bx |
5bcae85e | 54 | } |
ea8adc8c | 55 | mir::StatementKind::StorageLive(local) => { |
94b46f34 | 56 | if let LocalRef::Place(cg_place) = self.locals[local] { |
a1dfa0c6 | 57 | cg_place.storage_live(&mut bx); |
b7449926 | 58 | } else if let LocalRef::UnsizedPlace(cg_indirect_place) = self.locals[local] { |
a1dfa0c6 | 59 | cg_indirect_place.storage_live(&mut bx); |
ff7c6d11 | 60 | } |
2c00a5a8 | 61 | bx |
5bcae85e | 62 | } |
ea8adc8c | 63 | mir::StatementKind::StorageDead(local) => { |
94b46f34 | 64 | if let LocalRef::Place(cg_place) = self.locals[local] { |
a1dfa0c6 | 65 | cg_place.storage_dead(&mut bx); |
b7449926 | 66 | } else if let LocalRef::UnsizedPlace(cg_indirect_place) = self.locals[local] { |
a1dfa0c6 | 67 | cg_indirect_place.storage_dead(&mut bx); |
ff7c6d11 | 68 | } |
2c00a5a8 | 69 | bx |
5bcae85e | 70 | } |
8bb4bdeb XL |
71 | mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { |
72 | let outputs = outputs.iter().map(|output| { | |
a1dfa0c6 | 73 | self.codegen_place(&mut bx, output) |
8bb4bdeb XL |
74 | }).collect(); |
75 | ||
0bf4aa26 | 76 | let input_vals = inputs.iter() |
a1dfa0c6 XL |
77 | .fold(Vec::with_capacity(inputs.len()), |mut acc, (span, input)| { |
78 | let op = self.codegen_operand(&mut bx, input); | |
0bf4aa26 XL |
79 | if let OperandValue::Immediate(_) = op.val { |
80 | acc.push(op.immediate()); | |
0bf4aa26 | 81 | } else { |
a1dfa0c6 XL |
82 | span_err!(bx.sess(), span.to_owned(), E0669, |
83 | "invalid value for constraint in inline assembly"); | |
0bf4aa26 | 84 | } |
a1dfa0c6 | 85 | acc |
0bf4aa26 | 86 | }); |
8bb4bdeb | 87 | |
a1dfa0c6 XL |
88 | if input_vals.len() == inputs.len() { |
89 | let res = bx.codegen_inline_asm(asm, outputs, input_vals); | |
0bf4aa26 XL |
90 | if !res { |
91 | span_err!(bx.sess(), statement.source_info.span, E0668, | |
92 | "malformed inline assembly"); | |
93 | } | |
94 | } | |
2c00a5a8 | 95 | bx |
8bb4bdeb | 96 | } |
0bf4aa26 | 97 | mir::StatementKind::FakeRead(..) | |
a1dfa0c6 | 98 | mir::StatementKind::Retag { .. } | |
b7449926 | 99 | mir::StatementKind::AscribeUserType(..) | |
2c00a5a8 | 100 | mir::StatementKind::Nop => bx, |
5bcae85e SL |
101 | } |
102 | } | |
92a42be0 | 103 | } |