use rustc::mir::traversal;
use common;
use super::MirContext;
-use super::rvalue;
pub fn lvalue_locals<'a, 'tcx>(mircx: &MirContext<'a, 'tcx>) -> BitVector {
let mir = mircx.mir;
if let mir::Lvalue::Local(index) = *lvalue {
self.mark_assigned(index);
- if !rvalue::rvalue_creates_operand(rvalue) {
+ if !self.cx.rvalue_creates_operand(rvalue) {
self.mark_as_lvalue(index);
}
} else {
use libc::c_uint;
use llvm::{self, ValueRef, BasicBlockRef};
use llvm::debuginfo::DIScope;
-use rustc::ty;
+use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, LayoutTyper};
use rustc::mir::{self, Mir};
use rustc::mir::tcx::LvalueTy;
use rustc::ty::subst::Substs;
use rustc::infer::TransNormalize;
-use rustc::ty::TypeFoldable;
use session::config::FullDebugInfo;
use base;
use builder::Builder;
-use common::{self, CrateContext, C_null, Funclet};
+use common::{self, CrateContext, Funclet};
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
use monomorphize::{self, Instance};
use abi::FnType;
impl<'tcx> LocalRef<'tcx> {
fn new_operand<'a>(ccx: &CrateContext<'a, 'tcx>,
- ty: ty::Ty<'tcx>) -> LocalRef<'tcx> {
+ ty: Ty<'tcx>) -> LocalRef<'tcx> {
if common::type_is_zero_size(ccx, ty) {
// Zero-size temporaries aren't always initialized, which
// doesn't matter because they don't contain data, but
// we need something in the operand.
- let llty = type_of::type_of(ccx, ty);
- let val = if common::type_is_imm_pair(ccx, ty) {
- let fields = llty.field_types();
- OperandValue::Pair(C_null(fields[0]), C_null(fields[1]))
- } else {
- OperandValue::Immediate(C_null(llty))
- };
- let op = OperandRef {
- val: val,
- ty: ty
- };
- LocalRef::Operand(Some(op))
+ LocalRef::Operand(Some(OperandRef::new_zst(ccx, ty)))
} else {
LocalRef::Operand(None)
}
use rustc_data_structures::indexed_vec::Idx;
use base;
-use common;
+use common::{self, CrateContext, C_null};
use builder::Builder;
use value::Value;
use type_of;
}
impl<'a, 'tcx> OperandRef<'tcx> {
+ pub fn new_zst(ccx: &CrateContext<'a, 'tcx>,
+ ty: Ty<'tcx>) -> OperandRef<'tcx> {
+ assert!(common::type_is_zero_size(ccx, ty));
+ let llty = type_of::type_of(ccx, ty);
+ let val = if common::type_is_imm_pair(ccx, ty) {
+ let fields = llty.field_types();
+ OperandValue::Pair(C_null(fields[0]), C_null(fields[1]))
+ } else {
+ OperandValue::Immediate(C_null(llty))
+ };
+ OperandRef {
+ val: val,
+ ty: ty
+ }
+ }
+
/// Asserts that this operand refers to a scalar and returns
/// a reference to its value.
pub fn immediate(self) -> ValueRef {
}
_ => {
- assert!(rvalue_creates_operand(rvalue));
+ assert!(self.rvalue_creates_operand(rvalue));
let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue);
self.store_operand(&bcx, dest.llval, dest.alignment.to_align(), temp);
bcx
rvalue: &mir::Rvalue<'tcx>)
-> (Builder<'a, 'tcx>, OperandRef<'tcx>)
{
- assert!(rvalue_creates_operand(rvalue), "cannot trans {:?} to operand", rvalue);
+ assert!(self.rvalue_creates_operand(rvalue), "cannot trans {:?} to operand", rvalue);
match *rvalue {
mir::Rvalue::Cast(ref kind, ref source, cast_ty) => {
}
mir::Rvalue::Repeat(..) |
mir::Rvalue::Aggregate(..) => {
- bug!("cannot generate operand from rvalue {:?}", rvalue);
-
+ // According to `rvalue_creates_operand`, only ZST
+ // aggregate rvalues are allowed to be operands.
+ let ty = rvalue.ty(self.mir, self.ccx.tcx());
+ (bcx, OperandRef::new_zst(self.ccx, self.monomorphize(&ty)))
}
}
}
OperandValue::Pair(val, of)
}
-}
-pub fn rvalue_creates_operand(rvalue: &mir::Rvalue) -> bool {
- match *rvalue {
- mir::Rvalue::Ref(..) |
- mir::Rvalue::Len(..) |
- mir::Rvalue::Cast(..) | // (*)
- mir::Rvalue::BinaryOp(..) |
- mir::Rvalue::CheckedBinaryOp(..) |
- mir::Rvalue::UnaryOp(..) |
- mir::Rvalue::Discriminant(..) |
- mir::Rvalue::Box(..) |
- mir::Rvalue::Use(..) => // (*)
- true,
- mir::Rvalue::Repeat(..) |
- mir::Rvalue::Aggregate(..) =>
- false,
- }
+ pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>) -> bool {
+ match *rvalue {
+ mir::Rvalue::Ref(..) |
+ mir::Rvalue::Len(..) |
+ mir::Rvalue::Cast(..) | // (*)
+ mir::Rvalue::BinaryOp(..) |
+ mir::Rvalue::CheckedBinaryOp(..) |
+ mir::Rvalue::UnaryOp(..) |
+ mir::Rvalue::Discriminant(..) |
+ mir::Rvalue::Box(..) |
+ mir::Rvalue::Use(..) => // (*)
+ true,
+ mir::Rvalue::Repeat(..) |
+ mir::Rvalue::Aggregate(..) => {
+ let ty = rvalue.ty(self.mir, self.ccx.tcx());
+ let ty = self.monomorphize(&ty);
+ common::type_is_zero_size(self.ccx, ty)
+ }
+ }
- // (*) this is only true if the type is suitable
+ // (*) this is only true if the type is suitable
+ }
}
#[derive(Copy, Clone)]