From 9d7b113b44457ae20cb90828f63edb1f6cea2f06 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 6 Nov 2015 13:31:02 +0000 Subject: Add proper support for indirect output constraints in inline asm --- src/libsyntax/ext/asm.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/libsyntax/ext') diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index d968858f634..f643f0be276 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -125,7 +125,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) }; let is_rw = output.is_some(); - outputs.push((output.unwrap_or(constraint), out, is_rw)); + let is_indirect = constraint.contains("*"); + outputs.push((output.unwrap_or(constraint), out, is_rw, is_indirect)); } } Inputs => { @@ -139,9 +140,9 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let (constraint, _str_style) = panictry!(p.parse_str()); - if constraint.starts_with("=") && !constraint.contains("*") { + if constraint.starts_with("=") { cx.span_err(p.last_span, "input operand constraint contains '='"); - } else if constraint.starts_with("+") && !constraint.contains("*") { + } else if constraint.starts_with("+") { cx.span_err(p.last_span, "input operand constraint contains '+'"); } -- cgit 1.4.1-3-g733a5 From 65707dfc001b4dea745a040c2ecc61847ccba608 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 5 Dec 2015 08:18:24 +0000 Subject: Use a struct instead of a tuple for inline asm output operands --- src/librustc/middle/cfg/construct.rs | 3 +-- src/librustc/middle/expr_use_visitor.rs | 10 +++++----- src/librustc/middle/liveness.rs | 20 ++++++++++---------- src/librustc_front/fold.rs | 9 +++++++-- src/librustc_front/hir.rs | 10 +++++++++- src/librustc_front/intravisit.rs | 4 ++-- src/librustc_front/lowering.rs | 9 +++++++-- src/librustc_front/print/pprust.rs | 10 +++++----- src/librustc_trans/trans/asm.rs | 16 ++++++++-------- .../trans/debuginfo/create_scope_map.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 4 ++-- src/libsyntax/ast.rs | 10 +++++++++- src/libsyntax/ext/asm.rs | 7 ++++++- src/libsyntax/fold.rs | 9 +++++++-- src/libsyntax/print/pprust.rs | 10 +++++----- src/libsyntax/visit.rs | 4 ++-- 16 files changed, 87 insertions(+), 52 deletions(-) (limited to 'src/libsyntax/ext') diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index de540e5cfb3..f17c865dc90 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -368,8 +368,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { }), 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]) } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 316b49e1de4..58f69722777 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -458,12 +458,12 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { 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 }); } } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 9c8cc45d396..30061212a85 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1167,15 +1167,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { 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) } } ); @@ -1423,11 +1423,11 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { } // 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); diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs index c9a09989f04..aa73871d84e 100644 --- a/src/librustc_front/fold.rs +++ b/src/librustc_front/fold.rs @@ -1127,8 +1127,13 @@ pub fn noop_fold_expr(Expr { id, node, span, attrs }: Expr, folder: & 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, diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index bc95599fb7a..192209b8f76 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -887,11 +887,19 @@ pub enum Ty_ { TyInfer, } +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct InlineAsmOutput { + pub constraint: InternedString, + pub expr: P, + 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, bool, bool)>, + pub outputs: Vec, pub inputs: Vec<(InternedString, P)>, pub clobbers: Vec, pub volatile: bool, diff --git a/src/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs index d0f2a9dca17..bf77301b03a 100644 --- a/src/librustc_front/intravisit.rs +++ b/src/librustc_front/intravisit.rs @@ -803,8 +803,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { 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) } } } diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index e5ea737f621..2baee3f5283 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -1202,8 +1202,13 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { .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(), diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs index c8775000268..d4cd70df38a 100644 --- a/src/librustc_front/print/pprust.rs +++ b/src/librustc_front/print/pprust.rs @@ -1502,15 +1502,15 @@ impl<'a> State<'a> { 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(()) })); diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs index efa34fbcbdc..ea0397c690c 100644 --- a/src/librustc_trans/trans/asm.rs +++ b/src/librustc_trans/trans/asm.rs @@ -41,27 +41,27 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) // 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, diff --git a/src/librustc_trans/trans/debuginfo/create_scope_map.rs b/src/librustc_trans/trans/debuginfo/create_scope_map.rs index c8a66fb611d..c9bcfe23aea 100644 --- a/src/librustc_trans/trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/trans/debuginfo/create_scope_map.rs @@ -480,8 +480,8 @@ fn walk_expr(cx: &CrateContext, 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); } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 722273ee0f8..e3439b6cf7f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3393,8 +3393,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, 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); } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ac3e26d0335..46110a3bee9 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1458,11 +1458,19 @@ pub enum AsmDialect { Intel, } +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct InlineAsmOutput { + pub constraint: InternedString, + pub expr: P, + 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, bool, bool)>, + pub outputs: Vec, pub inputs: Vec<(InternedString, P)>, pub clobbers: Vec, pub volatile: bool, diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index f643f0be276..b4f29f83726 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -126,7 +126,12 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) 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 => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 8619c3c0bdb..c637813f07e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1303,8 +1303,13 @@ pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mu 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, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a0b7df3e2e9..a96908e23db 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2221,16 +2221,16 @@ impl<'a> State<'a> { 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(()) })); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 5ede6596e8f..22bf135f4f9 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -786,8 +786,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { 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) } } } -- cgit 1.4.1-3-g733a5