]> git.lizzy.rs Git - rust.git/commitdiff
Implement SetDiscriminant
authorbjorn3 <bjorn3@users.noreply.github.com>
Sun, 24 Jun 2018 12:29:56 +0000 (14:29 +0200)
committerbjorn3 <bjorn3@users.noreply.github.com>
Sun, 24 Jun 2018 12:29:56 +0000 (14:29 +0200)
src/base.rs

index 51c715a2d1e4bd7748bc89534d82df2a0f043b5b..6aa67721256b61f498752fa16bfd815da5f53230 100644 (file)
@@ -292,23 +292,24 @@ fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &mut
 
 fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx>) {
     match &stmt.kind {
-        /*StatementKind::SetDiscriminant { place, variant_index } => {
-            if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited {
+        StatementKind::SetDiscriminant { place, variant_index } => {
+            let place_ty = fx.monomorphize(&place.ty(&fx.mir.local_decls, fx.tcx).to_ty(fx.tcx));
+            let place = trans_place(fx, place);
+            let layout = fx.layout_of(place_ty);
+            if layout.for_variant(&*fx, *variant_index).abi == layout::Abi::Uninhabited {
                 return;
             }
-            match self.layout.variants {
+            match layout.variants {
                 layout::Variants::Single { index } => {
-                    assert_eq!(index, variant_index);
+                    assert_eq!(index, *variant_index);
                 }
                 layout::Variants::Tagged { .. } => {
-                    let ptr = self.project_field(bx, 0);
-                    let to = self.layout.ty.ty_adt_def().unwrap()
-                        .discriminant_for_variant(bx.tcx(), variant_index)
+                    let ptr = place.place_field(fx, mir::Field::new(0), place_ty);
+                    let to = layout.ty.ty_adt_def().unwrap()
+                        .discriminant_for_variant(fx.tcx, *variant_index)
                         .val;
-                    bx.store(
-                        C_uint_big(ptr.layout.llvm_type(bx.cx), to),
-                        ptr.llval,
-                        ptr.align);
+                    let discr = CValue::const_val(fx, ptr.1.ty, to as u64 as i64);
+                    ptr.0.write_cvalue(fx, discr, ptr.1.ty);
                 }
                 layout::Variants::NicheFilling {
                     dataful_variant,
@@ -316,35 +317,22 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
                     niche_start,
                     ..
                 } => {
-                    if variant_index != dataful_variant {
-                        if bx.sess().target.target.arch == "arm" ||
-                        bx.sess().target.target.arch == "aarch64" {
-                            // Issue #34427: As workaround for LLVM bug on ARM,
-                            // use memset of 0 before assigning niche value.
-                            let llptr = bx.pointercast(self.llval, Type::i8(bx.cx).ptr_to());
-                            let fill_byte = C_u8(bx.cx, 0);
-                            let (size, align) = self.layout.size_and_align();
-                            let size = C_usize(bx.cx, size.bytes());
-                            let align = C_u32(bx.cx, align.abi() as u32);
-                            base::call_memset(bx, llptr, fill_byte, size, align, false);
-                        }
-
-                        let niche = self.project_field(bx, 0);
-                        let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
+                    if *variant_index != dataful_variant {
+                        let niche = place.place_field(fx, mir::Field::new(0), place_ty);
+                        //let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
                         let niche_value = ((variant_index - *niche_variants.start()) as u128)
                             .wrapping_add(niche_start);
                         // FIXME(eddyb) Check the actual primitive type here.
                         let niche_llval = if niche_value == 0 {
-                            // HACK(eddyb) Using `C_null` as it works on all types.
-                            C_null(niche_llty)
+                            CValue::const_val(fx, niche.1.ty, 0)
                         } else {
-                            C_uint_big(niche_llty, niche_value)
+                            CValue::const_val(fx, niche.1.ty, niche_value as u64 as i64)
                         };
-                        OperandValue::Immediate(niche_llval).store(bx, niche);
+                        niche.0.write_cvalue(fx, niche_llval, niche.1.ty);
                     }
                 }
             }
-        }*/
+        }
         StatementKind::Assign(to_place, rval) => {
             let dest_ty = fx.monomorphize(&to_place.ty(&fx.mir.local_decls, fx.tcx).to_ty(fx.tcx));
             let lval = trans_place(fx, to_place);
@@ -402,6 +390,15 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
                                 bin_op => unimplemented!("checked uint bin op {:?} {:?} {:?}", bin_op, lhs, rhs),
                             }
                         }
+                        TypeVariants::TyInt(_) => {
+                            match bin_op {
+                                BinOp::Add => fx.bcx.ins().iadd(lhs, rhs),
+                                BinOp::Sub => fx.bcx.ins().isub(lhs, rhs),
+                                BinOp::Mul => fx.bcx.ins().imul(lhs, rhs),
+                                BinOp::Div => fx.bcx.ins().sdiv(lhs, rhs),
+                                bin_op => unimplemented!("checked int bin op {:?} {:?} {:?}", bin_op, lhs, rhs),
+                            }
+                        }
                         _ => unimplemented!(),
                     };
                     lval.write_cvalue(fx, CValue::ByVal(res), ty);
@@ -493,10 +490,10 @@ fn trans_place<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, place: &Place<'tcx>)
         Place::Local(local) => fx.get_local_place(*local),
         Place::Projection(projection) => {
             let base = trans_place(fx, &projection.base);
-            let place_ty = fx.monomorphize(&place.ty(&*fx.mir, fx.tcx)).to_ty(fx.tcx);
+            let base_ty = projection.base.ty(&*fx.mir, fx.tcx).to_ty(fx.tcx);
             match projection.elem {
                 ProjectionElem::Deref => {
-                    CPlace::Addr(base.to_cvalue(fx).load_value(fx, place_ty))
+                    CPlace::Addr(base.to_cvalue(fx).load_value(fx, base_ty))
                 }
                 ProjectionElem::Field(field, ty) => {
                     base.place_field(fx, field, ty).0