From: badumbatish <tanghocle...@gmail.com>

gcc/rust/ChangeLog:

        * expand/rust-macro-builtins-asm.cc (parse_reg_operand):
        Remove warnings
        (parse_reg_operand_out): Remove warnings
        (expand_inline_asm): New function for eventual expansion
        (parse_asm): Use expand_inline_asm

gcc/testsuite/ChangeLog:

        * rust/execute/torture/inline_asm_mov_x_5.rs: New test.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc    | 33 +++++++++++++++++--
 .../execute/torture/inline_asm_mov_x_5.rs     | 19 +++++++++++
 2 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 492bcfe3172..bbb8fff180f 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -21,6 +21,7 @@
 #include "rust-macro-builtins-asm.h"
 #include "rust-ast-fragment.h"
 #include "rust-ast.h"
+#include "rust-fmt.h"
 #include "rust-stmt.h"
 
 namespace Rust {
@@ -240,7 +241,7 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
 
       if (result.has_value ())
        {
-         inline_asm_ctx = result.value ();
+         inline_asm_ctx = *result;
          break;
        }
       else if (result.error () == COMMITTED)
@@ -741,6 +742,31 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
   return tl::expected<InlineAsmContext, InlineAsmParseError> (inline_asm_ctx);
 }
 
+tl::expected<InlineAsmContext, InlineAsmParseError>
+expand_inline_asm (InlineAsmContext &inline_asm_ctx)
+{
+  auto &inline_asm = inline_asm_ctx.inline_asm;
+
+  auto str_vec = inline_asm.get_template_strs ();
+  for (auto &template_str : str_vec)
+    {
+      std::cout << template_str.symbol << std::endl;
+
+      auto pieces = Fmt::Pieces::collect (template_str.symbol, false,
+                                         Fmt::ffi::ParseMode::Format)
+                     .get_pieces ();
+
+      for (size_t i = 0; i < pieces.size (); i++)
+       {
+         auto piece = pieces[i];
+         if (piece.tag == Fmt::ffi::Piece::Tag::String)
+           std::cout << "       " << i << ": " << piece.string._0.to_string ()
+                     << std::endl;
+       }
+    }
+
+  return inline_asm_ctx;
+}
 tl::optional<AST::Fragment>
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
           AST::InvocKind semicolon, AST::AsmKind is_global_asm)
@@ -770,7 +796,10 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   // here Per Arthur's advice we would actually do the validation in a 
different
   // stage. and visit on the InlineAsm AST instead of it's context.
   auto is_valid = (bool) resulting_context;
-
+  if (is_valid)
+    {
+      expand_inline_asm (resulting_context.value ());
+    }
   if (is_valid)
     {
       auto node = inline_asm_ctx.inline_asm.clone_expr_without_block ();
diff --git a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs 
b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
new file mode 100644
index 00000000000..18bc87ab554
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
@@ -0,0 +1,19 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn main() {
+    let mut _x: i32 = 0;
+    unsafe {
+        asm!(
+            "mov {}, 5",
+            out(reg) _x
+        );
+    }
+}
-- 
2.45.2

Reply via email to