3 use crate::traits
::BuilderMethods
;
6 use super::OperandValue
;
9 use rustc_error_codes
::*;
11 impl<'a
, 'tcx
, Bx
: BuilderMethods
<'a
, 'tcx
>> FunctionCx
<'a
, 'tcx
, Bx
> {
12 pub fn codegen_statement(
15 statement
: &mir
::Statement
<'tcx
>
17 debug
!("codegen_statement(statement={:?})", statement
);
19 self.set_debug_loc(&mut bx
, statement
.source_info
);
20 match statement
.kind
{
21 mir
::StatementKind
::Assign(box(ref place
, ref rvalue
)) => {
22 if let Some(index
) = place
.as_local() {
23 match self.locals
[index
] {
24 LocalRef
::Place(cg_dest
) => {
25 self.codegen_rvalue(bx
, cg_dest
, rvalue
)
27 LocalRef
::UnsizedPlace(cg_indirect_dest
) => {
28 self.codegen_rvalue_unsized(bx
, cg_indirect_dest
, rvalue
)
30 LocalRef
::Operand(None
) => {
31 let (mut bx
, operand
) = self.codegen_rvalue_operand(bx
, rvalue
);
32 self.locals
[index
] = LocalRef
::Operand(Some(operand
));
33 self.debug_introduce_local(&mut bx
, index
);
36 LocalRef
::Operand(Some(op
)) => {
37 if !op
.layout
.is_zst() {
38 span_bug
!(statement
.source_info
.span
,
39 "operand {:?} already assigned",
43 // If the type is zero-sized, it's already been set here,
44 // but we still need to make sure we codegen the operand
45 self.codegen_rvalue_operand(bx
, rvalue
).0
49 let cg_dest
= self.codegen_place(&mut bx
, &place
.as_ref());
50 self.codegen_rvalue(bx
, cg_dest
, rvalue
)
53 mir
::StatementKind
::SetDiscriminant{box ref place, variant_index}
=> {
54 self.codegen_place(&mut bx
, &place
.as_ref())
55 .codegen_set_discr(&mut bx
, variant_index
);
58 mir
::StatementKind
::StorageLive(local
) => {
59 if let LocalRef
::Place(cg_place
) = self.locals
[local
] {
60 cg_place
.storage_live(&mut bx
);
61 } else if let LocalRef
::UnsizedPlace(cg_indirect_place
) = self.locals
[local
] {
62 cg_indirect_place
.storage_live(&mut bx
);
66 mir
::StatementKind
::StorageDead(local
) => {
67 if let LocalRef
::Place(cg_place
) = self.locals
[local
] {
68 cg_place
.storage_dead(&mut bx
);
69 } else if let LocalRef
::UnsizedPlace(cg_indirect_place
) = self.locals
[local
] {
70 cg_indirect_place
.storage_dead(&mut bx
);
74 mir
::StatementKind
::InlineAsm(ref asm
) => {
75 let outputs
= asm
.outputs
.iter().map(|output
| {
76 self.codegen_place(&mut bx
, &output
.as_ref())
79 let input_vals
= asm
.inputs
.iter()
80 .fold(Vec
::with_capacity(asm
.inputs
.len()), |mut acc
, (span
, input
)| {
81 let op
= self.codegen_operand(&mut bx
, input
);
82 if let OperandValue
::Immediate(_
) = op
.val
{
83 acc
.push(op
.immediate());
85 span_err
!(bx
.sess(), span
.to_owned(), E0669
,
86 "invalid value for constraint in inline assembly");
91 if input_vals
.len() == asm
.inputs
.len() {
92 let res
= bx
.codegen_inline_asm(
96 statement
.source_info
.span
,
99 span_err
!(bx
.sess(), statement
.source_info
.span
, E0668
,
100 "malformed inline assembly");
105 mir
::StatementKind
::FakeRead(..) |
106 mir
::StatementKind
::Retag { .. }
|
107 mir
::StatementKind
::AscribeUserType(..) |
108 mir
::StatementKind
::Nop
=> bx
,