]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/mir/statement.rs
c0cce297ef6a98263db3e01b2a8ccaf8b03cc4d9
[rust.git] / src / librustc_codegen_llvm / mir / statement.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 rustc::mir;
12
13 use asm;
14 use builder::Builder;
15
16 use super::FunctionCx;
17 use super::LocalRef;
18
19 impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
20     pub fn codegen_statement(&mut self,
21                            bx: Builder<'a, 'tcx>,
22                            statement: &mir::Statement<'tcx>)
23                            -> Builder<'a, 'tcx> {
24         debug!("codegen_statement(statement={:?})", statement);
25
26         self.set_debug_loc(&bx, statement.source_info);
27         match statement.kind {
28             mir::StatementKind::Assign(ref place, ref rvalue) => {
29                 if let mir::Place::Local(index) = *place {
30                     match self.locals[index] {
31                         LocalRef::Place(cg_dest) => {
32                             self.codegen_rvalue(bx, cg_dest, rvalue)
33                         }
34                         LocalRef::Operand(None) => {
35                             let (bx, operand) = self.codegen_rvalue_operand(bx, rvalue);
36                             self.locals[index] = LocalRef::Operand(Some(operand));
37                             bx
38                         }
39                         LocalRef::Operand(Some(op)) => {
40                             if !op.layout.is_zst() {
41                                 span_bug!(statement.source_info.span,
42                                           "operand {:?} already assigned",
43                                           rvalue);
44                             }
45
46                             // If the type is zero-sized, it's already been set here,
47                             // but we still need to make sure we codegen the operand
48                             self.codegen_rvalue_operand(bx, rvalue).0
49                         }
50                     }
51                 } else {
52                     let cg_dest = self.codegen_place(&bx, place);
53                     self.codegen_rvalue(bx, cg_dest, rvalue)
54                 }
55             }
56             mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
57                 self.codegen_place(&bx, place)
58                     .codegen_set_discr(&bx, variant_index);
59                 bx
60             }
61             mir::StatementKind::StorageLive(local) => {
62                 if let LocalRef::Place(cg_place) = self.locals[local] {
63                     cg_place.storage_live(&bx);
64                 }
65                 bx
66             }
67             mir::StatementKind::StorageDead(local) => {
68                 if let LocalRef::Place(cg_place) = self.locals[local] {
69                     cg_place.storage_dead(&bx);
70                 }
71                 bx
72             }
73             mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
74                 let outputs = outputs.iter().map(|output| {
75                     self.codegen_place(&bx, output)
76                 }).collect();
77
78                 let input_vals = inputs.iter().map(|input| {
79                     self.codegen_operand(&bx, input).immediate()
80                 }).collect();
81
82                 asm::codegen_inline_asm(&bx, asm, outputs, input_vals);
83                 bx
84             }
85             mir::StatementKind::ReadForMatch(_) |
86             mir::StatementKind::EndRegion(_) |
87             mir::StatementKind::Validate(..) |
88             mir::StatementKind::UserAssertTy(..) |
89             mir::StatementKind::Nop => bx,
90         }
91     }
92 }