about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-08-20 03:25:58 +0000
committerbors <bors@rust-lang.org>2014-08-20 03:25:58 +0000
commit4be4ea7bb00c343e7199dc5dcc059f911f33a0c6 (patch)
tree461dad2e00d4102e5ea18dab90854ac8ea9a5b1b /src/libsyntax
parent4a0272da67d8fab7e1dd8950e92fb33480ba669a (diff)
parent4155643428f10530cbdfe579c83f5070d58a18dd (diff)
downloadrust-4be4ea7bb00c343e7199dc5dcc059f911f33a0c6.tar.gz
rust-4be4ea7bb00c343e7199dc5dcc059f911f33a0c6.zip
auto merge of #16606 : pczarn/rust/inline-asm, r=alexcrichton
It's unfortunate that the read+write operands need special treatment in the AST. A separate vec for all expressions is an alternative, but it doesn't play nicely with trans.

Fixes #14936
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs4
-rw-r--r--src/libsyntax/ext/asm.rs18
-rw-r--r--src/libsyntax/fold.rs4
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/visit.rs6
5 files changed, 19 insertions, 23 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index d0adc75e5c8..42d9430d732 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -958,9 +958,9 @@ pub enum AsmDialect {
 pub struct InlineAsm {
     pub asm: InternedString,
     pub asm_str_style: StrStyle,
-    pub clobbers: InternedString,
+    pub outputs: Vec<(InternedString, Gc<Expr>, bool)>,
     pub inputs: Vec<(InternedString, Gc<Expr>)>,
-    pub outputs: Vec<(InternedString, Gc<Expr>)>,
+    pub clobbers: InternedString,
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index 13738e658e9..43fa0964f80 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -59,8 +59,6 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
     let mut state = Asm;
 
-    let mut read_write_operands = Vec::new();
-
     'statement: loop {
         match state {
             Asm => {
@@ -100,8 +98,6 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     let output = match constraint.get().slice_shift_char() {
                         (Some('='), _) => None,
                         (Some('+'), operand) => {
-                            // Save a reference to the output
-                            read_write_operands.push((outputs.len(), out));
                             Some(token::intern_and_get_ident(format!(
                                         "={}",
                                         operand).as_slice()))
@@ -112,7 +108,8 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         }
                     };
 
-                    outputs.push((output.unwrap_or(constraint), out));
+                    let is_rw = output.is_some();
+                    outputs.push((output.unwrap_or(constraint), out, is_rw));
                 }
             }
             Inputs => {
@@ -202,21 +199,14 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         }
     }
 
-    // Append an input operand, with the form of ("0", expr)
-    // that links to an output operand.
-    for &(i, out) in read_write_operands.iter() {
-        inputs.push((token::intern_and_get_ident(i.to_string().as_slice()),
-                                                 out));
-    }
-
     MacExpr::new(box(GC) ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprInlineAsm(ast::InlineAsm {
             asm: token::intern_and_get_ident(asm.get()),
             asm_str_style: asm_str_style.unwrap(),
-            clobbers: token::intern_and_get_ident(cons.as_slice()),
-            inputs: inputs,
             outputs: outputs,
+            inputs: inputs,
+            clobbers: token::intern_and_get_ident(cons.as_slice()),
             volatile: volatile,
             alignstack: alignstack,
             dialect: dialect
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 9ad28f02e80..fb96b4b83d7 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1189,8 +1189,8 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
                 inputs: a.inputs.iter().map(|&(ref c, input)| {
                     ((*c).clone(), folder.fold_expr(input))
                 }).collect(),
-                outputs: a.outputs.iter().map(|&(ref c, out)| {
-                    ((*c).clone(), folder.fold_expr(out))
+                outputs: a.outputs.iter().map(|&(ref c, out, is_rw)| {
+                    ((*c).clone(), folder.fold_expr(out), is_rw)
                 }).collect(),
                 .. (*a).clone()
             })
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 26d425563d0..6fe44078447 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1671,8 +1671,14 @@ impl<'a> State<'a> {
                 try!(self.word_space(":"));
 
                 try!(self.commasep(Inconsistent, a.outputs.as_slice(),
-                                   |s, &(ref co, ref o)| {
-                    try!(s.print_string(co.get(), ast::CookedStr));
+                                   |s, &(ref co, ref o, is_rw)| {
+                    match co.get().slice_shift_char() {
+                        (Some('='), operand) if is_rw => {
+                            try!(s.print_string(format!("+{}", operand).as_slice(),
+                                                ast::CookedStr))
+                        }
+                        _ => try!(s.print_string(co.get(), ast::CookedStr))
+                    }
                     try!(s.popen());
                     try!(s.print_expr(&**o));
                     try!(s.pclose());
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index ac1dbdc439c..9e371143311 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -854,11 +854,11 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
         ExprParen(ref subexpression) => {
             visitor.visit_expr(&**subexpression, env.clone())
         }
-        ExprInlineAsm(ref assembler) => {
-            for &(_, ref input) in assembler.inputs.iter() {
+        ExprInlineAsm(ref ia) => {
+            for &(_, ref input) in ia.inputs.iter() {
                 visitor.visit_expr(&**input, env.clone())
             }
-            for &(_, ref output) in assembler.outputs.iter() {
+            for &(_, ref output, _) in ia.outputs.iter() {
                 visitor.visit_expr(&**output, env.clone())
             }
         }