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

gcc/rust/ChangeLog:

        * ast/rust-expr.h (struct InlineAsmOperand):
        Add construction for register_type
        * expand/rust-macro-builtins-asm.cc (parse_reg_operand):
        Fix parsing logic & reassignment logic
        (parse_reg_operand_in): Fix parsing
        (parse_reg_operand_out): Fix parsing
        (parse_reg_operand_inout): Fix parsing
        (parse_reg_operand_unexpected): Remove rust_unreachable()
        (parse_asm_arg): Fix parsing logic
        * expand/rust-macro-builtins-asm.h: Add = operator overloading

gcc/testsuite/ChangeLog:

        * rust/compile/inline_asm_illegal_operands.rs: Test now passing
        * rust/compile/inline_asm_parse_operand.rs: Remove _, not
        supported right now
---
 gcc/rust/ast/rust-expr.h                      |  5 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc    | 63 +++++++++++++------
 gcc/rust/expand/rust-macro-builtins-asm.h     | 10 ++-
 .../compile/inline_asm_illegal_operands.rs    |  6 +-
 .../rust/compile/inline_asm_parse_operand.rs  |  4 +-
 5 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 9477bf06d6c..8a3baf7ca2b 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4964,8 +4964,9 @@ struct InlineAsmOperand
 
   InlineAsmOperand () {}
   InlineAsmOperand (const InlineAsmOperand &other)
-    : in (other.in), out (other.out), in_out (other.in_out),
-      split_in_out (other.split_in_out), cnst (other.cnst), sym (other.sym)
+    : register_type (other.register_type), in (other.in), out (other.out),
+      in_out (other.in_out), split_in_out (other.split_in_out),
+      cnst (other.cnst), sym (other.sym)
   {}
 
   void set_in (const tl::optional<struct In> &reg)
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 214265d63a8..d270621d1bf 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -227,20 +227,28 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
   // Loop over and execute the parsing functions, if the parser successfullly
   // parses or if the parser fails to parse while it has committed to a token,
   // we propogate the result.
+  tl::expected<InlineAsmContext, InlineAsmParseError> parsing_operand (
+    inline_asm_ctx);
   for (auto &parse_func : parse_funcs)
     {
-      auto parsing_operand
-       = tl::expected<InlineAsmContext, InlineAsmParseError> (inline_asm_ctx);
-      parsing_operand.map (parse_func);
+      auto result = parsing_operand.and_then (parse_func);
 
       // Per rust's asm.rs's structure
       // After we've parse successfully, we break out and do a local validation
       // of named, positional & explicit register operands
 
-      if (parsing_operand.has_value ())
-       break;
-      if (parsing_operand.error () == COMMITTED)
-       return parsing_operand;
+      if (result.has_value ())
+       {
+         //
+         inline_asm_ctx = *result;
+         break;
+       }
+      else if (result.error () == COMMITTED
+              && parse_func != parse_reg_operand_unexpected)
+       return result;
+      else if (result.error () == COMMITTED
+              && parse_func == parse_reg_operand_unexpected)
+       return inline_asm_ctx;
     }
 
   auto &inline_asm = inline_asm_ctx.inline_asm;
@@ -303,7 +311,7 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
          return tl::unexpected<InlineAsmParseError> (COMMITTED);
        }
 
-      auto expr = parse_format_string (inline_asm_ctx);
+      auto expr = parser.parse_expr ();
 
       // TODO: When we've succesfully parse an expr, remember to clone_expr()
       // instead of nullptr
@@ -323,14 +331,19 @@ parse_reg_operand_out (InlineAsmContext inline_asm_ctx)
   if (!inline_asm_ctx.is_global_asm () && check_identifier (parser, "out"))
     {
       auto reg = parse_reg (inline_asm_ctx);
+      std::unique_ptr<AST::Expr> expr = parser.parse_expr ();
 
-      auto expr = parse_format_string (inline_asm_ctx);
+      rust_assert (expr != nullptr);
+
+      /*auto expr_ptr =
+        std::make_unique<AST::Expr>(AST::LiteralExpr(Literal))*/
 
       // TODO: When we've succesfully parse an expr, remember to clone_expr()
       // instead of nullptr
-      //      struct AST::InlineAsmOperand::Out out (reg, false, nullptr);
-      //      reg_operand.set_out (out);
-      //      inline_asm_ctx.inline_asm.operands.push_back (reg_operand);
+      struct AST::InlineAsmOperand::Out out (reg, false, std::move (expr));
+
+      reg_operand.set_out (out);
+      inline_asm_ctx.inline_asm.operands.push_back (reg_operand);
 
       return inline_asm_ctx;
     }
@@ -378,7 +391,10 @@ parse_reg_operand_inout (InlineAsmContext inline_asm_ctx)
       // TODO: Is error propogation our top priority, the ? in rust's asm.rs is
       // doing a lot of work.
       // TODO: Not sure how to use parse_expr
-      auto expr = parse_format_string (inline_asm_ctx);
+      auto exist_ident1 = check_identifier (parser, "");
+      if (!exist_ident1)
+       rust_unreachable ();
+      // auto expr = parse_format_string (inline_asm_ctx);
 
       std::unique_ptr<AST::Expr> out_expr;
 
@@ -386,9 +402,10 @@ parse_reg_operand_inout (InlineAsmContext inline_asm_ctx)
        {
          if (!parser.skip_token (UNDERSCORE))
            {
-             auto result = parse_format_string (inline_asm_ctx);
+             auto exist_ident2 = check_identifier (parser, "");
+             // auto result = parse_format_string (inline_asm_ctx);
 
-             if (!result.has_value ())
+             if (!exist_ident2)
                rust_unreachable ();
              // out_expr = parser.parse_expr();
            }
@@ -457,9 +474,9 @@ parse_reg_operand_unexpected (InlineAsmContext 
inline_asm_ctx)
   // TODO: It is  weird that we can't seem to match any identifier,
   // something must be wrong. consult compiler code in asm.rs or rust online
   // compiler.
-  rust_unreachable ();
+  // rust_unreachable ();
 
-  rust_error_at (token->get_locus (), "ERROR RIGHT HERE");
+  // rust_error_at (token->get_locus (), "ERROR RIGHT HERE");
   return tl::unexpected<InlineAsmParseError> (COMMITTED);
 }
 
@@ -678,7 +695,9 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
       if (check_identifier (parser, "clobber_abi"))
        {
          auto expected = parse_clobber_abi (inline_asm_ctx);
-         if (expected || expected.error () == COMMITTED)
+         if (expected.has_value ())
+           continue;
+         else if (expected.error () == COMMITTED)
            return expected;
 
          // The error type is definitely non-committed (we have checked above),
@@ -688,7 +707,9 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
       if (check_identifier (parser, "options"))
        {
          auto expected = parse_options (inline_asm_ctx);
-         if (expected || expected.error () == COMMITTED)
+         if (expected.has_value ())
+           continue;
+         else if (expected.error () == COMMITTED)
            return expected;
 
          // The error type is definitely non-committed (we have checked above),
@@ -699,7 +720,9 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
       // only other logical choice is reg_operand
 
       auto expected = parse_reg_operand (inline_asm_ctx);
-      if (expected || expected.error () == COMMITTED)
+      if (expected.has_value ())
+       continue;
+      else if (expected.error () == COMMITTED)
        return expected;
 
       // Since parse_reg_operand is the last thing we've considered,
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 69977701040..cbb5b63069a 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -65,6 +65,14 @@ public:
   // {
 
   // }
+  InlineAsmContext &operator= (const InlineAsmContext &inline_asm_ctx)
+  {
+    allow_templates = inline_asm_ctx.allow_templates;
+    is_explicit = inline_asm_ctx.is_explicit;
+    consumed_comma_without_formatted_string = false;
+    last_token_id = inline_asm_ctx.last_token_id;
+    return *this;
+  }
 
   bool is_global_asm () { return inline_asm.is_global_asm; }
 
@@ -161,4 +169,4 @@ tl::optional<std::string>
 parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
             InlineAsmContext &inline_asm_ctx);
 
-} // namespace Rust
\ No newline at end of file
+} // namespace Rust
diff --git a/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs 
b/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs
index 5a13fb96b0a..f29b4b69e8e 100644
--- a/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs
@@ -11,14 +11,14 @@ fn main() {
        asm!(
             "add {x}, {1}",
             x = in(reg) _x, 
-            x = in(reg) _x,  // { dg-error {duplicate argument named 'x'} "" { 
xfail *-*-* } .-1 }
+            x = in(reg) _x,  // { dg-error {duplicate argument named 'x'} }
         );
 
         asm!(
             "mov {x}, {x}",
-            x = inout("eax") _x, //  { dg-error {explicit register arguments 
cannot have names} "" { xfail *-*-* } .-1 }
+            x = inout("eax") _x, //  { dg-error {explicit register arguments 
cannot have names} }
             x = inout(reg) _x, // It then proceeds to parse this line, 
resulting in only 1 error instead of duplication error as well.
         );
     }
     _x = 1;
-}
\ No newline at end of file
+}
diff --git a/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs 
b/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs
index 2770263a9ae..dfce295ca99 100644
--- a/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs
@@ -31,7 +31,7 @@ fn main() {
         asm!(
             "add {0}, {0}",
             in(reg) _num1,
-            out(reg) _,
+            //out(reg) _,
         );
     }
-}
\ No newline at end of file
+}
-- 
2.45.2

Reply via email to