}), pred);
let post_outputs = self.exprs(outputs.map(|a| {
debug!("cfg::construct InlineAsm id:{} output:{:?}", expr.id, a);
- let &(_, ref expr, _, _) = a;
- &**expr
+ &*a.expr
}), post_inputs);
self.add_ast_node(expr.id, &[post_outputs])
}
self.consume_expr(&**input);
}
- for &(_, ref output, is_rw, is_indirect) in &ia.outputs {
- if is_indirect {
- self.consume_expr(&**output);
+ for output in &ia.outputs {
+ if output.is_indirect {
+ self.consume_expr(&*output.expr);
} else {
- self.mutate_expr(expr, &**output,
- if is_rw { WriteAndRead } else { JustWrite });
+ self.mutate_expr(expr, &*output.expr,
+ if output.is_rw { WriteAndRead } else { JustWrite });
}
}
}
hir::ExprInlineAsm(ref ia) => {
let succ = ia.outputs.iter().rev().fold(succ,
- |succ, &(_, ref expr, is_rw, is_indirect)| {
+ |succ, out| {
// see comment on lvalues
// in propagate_through_lvalue_components()
- if is_indirect {
- self.propagate_through_expr(&**expr, succ)
+ if out.is_indirect {
+ self.propagate_through_expr(&*out.expr, succ)
} else {
- let acc = if is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
- let succ = self.write_lvalue(&**expr, succ, acc);
- self.propagate_through_lvalue_components(&**expr, succ)
+ let acc = if out.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
+ let succ = self.write_lvalue(&*out.expr, succ, acc);
+ self.propagate_through_lvalue_components(&*out.expr, succ)
}
}
);
}
// Output operands must be lvalues
- for &(_, ref out, _, is_indirect) in &ia.outputs {
- if !is_indirect {
- this.check_lvalue(&**out);
+ for out in &ia.outputs {
+ if !out.is_indirect {
+ this.check_lvalue(&*out.expr);
}
- this.visit_expr(&**out);
+ this.visit_expr(&*out.expr);
}
intravisit::walk_expr(this, expr);
expn_id,
}) => ExprInlineAsm(InlineAsm {
inputs: inputs.move_map(|(c, input)| (c, folder.fold_expr(input))),
- outputs: outputs.move_map(|(c, out, is_rw, is_indirect)| {
- (c, folder.fold_expr(out), is_rw, is_indirect)
+ outputs: outputs.move_map(|out| {
+ InlineAsmOutput {
+ constraint: out.constraint,
+ expr: folder.fold_expr(out.expr),
+ is_rw: out.is_rw,
+ is_indirect: out.is_indirect,
+ }
}),
asm: asm,
asm_str_style: asm_str_style,
TyInfer,
}
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct InlineAsmOutput {
+ pub constraint: InternedString,
+ pub expr: P<Expr>,
+ pub is_rw: bool,
+ pub is_indirect: bool,
+}
+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
pub asm: InternedString,
pub asm_str_style: StrStyle,
- pub outputs: Vec<(InternedString, P<Expr>, bool, bool)>,
+ pub outputs: Vec<InlineAsmOutput>,
pub inputs: Vec<(InternedString, P<Expr>)>,
pub clobbers: Vec<InternedString>,
pub volatile: bool,
for &(_, ref input) in &ia.inputs {
visitor.visit_expr(&input)
}
- for &(_, ref output, _, _) in &ia.outputs {
- visitor.visit_expr(&output)
+ for output in &ia.outputs {
+ visitor.visit_expr(&output.expr)
}
}
}
.map(|&(ref c, ref input)| (c.clone(), lower_expr(lctx, input)))
.collect(),
outputs: outputs.iter()
- .map(|&(ref c, ref out, is_rw, is_indirect)| {
- (c.clone(), lower_expr(lctx, out), is_rw, is_indirect)
+ .map(|out| {
+ hir::InlineAsmOutput {
+ constraint: out.constraint.clone(),
+ expr: lower_expr(lctx, &out.expr),
+ is_rw: out.is_rw,
+ is_indirect: out.is_indirect,
+ }
})
.collect(),
asm: asm.clone(),
try!(self.print_string(&a.asm, a.asm_str_style));
try!(self.word_space(":"));
- try!(self.commasep(Inconsistent, &a.outputs, |s, &(ref co, ref o, is_rw, _)| {
- match co.slice_shift_char() {
- Some(('=', operand)) if is_rw => {
+ try!(self.commasep(Inconsistent, &a.outputs, |s, out| {
+ match out.constraint.slice_shift_char() {
+ Some(('=', operand)) if out.is_rw => {
try!(s.print_string(&format!("+{}", operand), ast::CookedStr))
}
- _ => try!(s.print_string(&co, ast::CookedStr)),
+ _ => try!(s.print_string(&out.constraint, ast::CookedStr)),
}
try!(s.popen());
- try!(s.print_expr(&**o));
+ try!(s.print_expr(&*out.expr));
try!(s.pclose());
Ok(())
}));
// Prepare the output operands
let mut outputs = Vec::new();
let mut inputs = Vec::new();
- for (i, &(ref c, ref out, is_rw, is_indirect)) in ia.outputs.iter().enumerate() {
- constraints.push((*c).clone());
+ for (i, out) in ia.outputs.iter().enumerate() {
+ constraints.push(out.constraint.clone());
- let out_datum = unpack_datum!(bcx, expr::trans(bcx, &**out));
- if is_indirect {
+ let out_datum = unpack_datum!(bcx, expr::trans(bcx, &*out.expr));
+ if out.is_indirect {
bcx = callee::trans_arg_datum(bcx,
- expr_ty(bcx, &**out),
+ expr_ty(bcx, &*out.expr),
out_datum,
cleanup::CustomScope(temp_scope),
callee::DontAutorefArg,
&mut inputs);
- if is_rw {
+ if out.is_rw {
ext_inputs.push(*inputs.last().unwrap());
ext_constraints.push(i.to_string());
}
} else {
output_types.push(type_of::type_of(bcx.ccx(), out_datum.ty));
outputs.push(out_datum.val);
- if is_rw {
+ if out.is_rw {
bcx = callee::trans_arg_datum(bcx,
- expr_ty(bcx, &**out),
+ expr_ty(bcx, &*out.expr),
out_datum,
cleanup::CustomScope(temp_scope),
callee::DontAutorefArg,
walk_expr(cx, &**exp, scope_stack, scope_map);
}
- for &(_, ref exp, _, _) in outputs {
- walk_expr(cx, &**exp, scope_stack, scope_map);
+ for out in outputs {
+ walk_expr(cx, &*out.expr, scope_stack, scope_map);
}
}
}
for &(_, ref input) in &ia.inputs {
check_expr(fcx, &**input);
}
- for &(_, ref out, _, _) in &ia.outputs {
- check_expr(fcx, &**out);
+ for out in &ia.outputs {
+ check_expr(fcx, &*out.expr);
}
fcx.write_nil(id);
}
Intel,
}
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct InlineAsmOutput {
+ pub constraint: InternedString,
+ pub expr: P<Expr>,
+ pub is_rw: bool,
+ pub is_indirect: bool,
+}
+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
pub asm: InternedString,
pub asm_str_style: StrStyle,
- pub outputs: Vec<(InternedString, P<Expr>, bool, bool)>,
+ pub outputs: Vec<InlineAsmOutput>,
pub inputs: Vec<(InternedString, P<Expr>)>,
pub clobbers: Vec<InternedString>,
pub volatile: bool,
let is_rw = output.is_some();
let is_indirect = constraint.contains("*");
- outputs.push((output.unwrap_or(constraint), out, is_rw, is_indirect));
+ outputs.push(ast::InlineAsmOutput {
+ constraint: output.unwrap_or(constraint),
+ expr: out,
+ is_rw: is_rw,
+ is_indirect: is_indirect,
+ });
}
}
Inputs => {
inputs: inputs.move_map(|(c, input)| {
(c, folder.fold_expr(input))
}),
- outputs: outputs.move_map(|(c, out, is_rw, is_indirect)| {
- (c, folder.fold_expr(out), is_rw, is_indirect)
+ outputs: outputs.move_map(|out| {
+ InlineAsmOutput {
+ constraint: out.constraint,
+ expr: folder.fold_expr(out.expr),
+ is_rw: out.is_rw,
+ is_indirect: out.is_indirect,
+ }
}),
asm: asm,
asm_str_style: asm_str_style,
try!(self.word_space(":"));
try!(self.commasep(Inconsistent, &a.outputs,
- |s, &(ref co, ref o, is_rw, _)| {
- match co.slice_shift_char() {
- Some(('=', operand)) if is_rw => {
+ |s, out| {
+ match out.constraint.slice_shift_char() {
+ Some(('=', operand)) if out.is_rw => {
try!(s.print_string(&format!("+{}", operand),
ast::CookedStr))
}
- _ => try!(s.print_string(&co, ast::CookedStr))
+ _ => try!(s.print_string(&out.constraint, ast::CookedStr))
}
try!(s.popen());
- try!(s.print_expr(&**o));
+ try!(s.print_expr(&*out.expr));
try!(s.pclose());
Ok(())
}));
for &(_, ref input) in &ia.inputs {
visitor.visit_expr(&input)
}
- for &(_, ref output, _, _) in &ia.outputs {
- visitor.visit_expr(&output)
+ for output in &ia.outputs {
+ visitor.visit_expr(&output.expr)
}
}
}