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