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

gcc/rust/ChangeLog:

        * ast/rust-expr.h (struct InlineAsmOperand):
        Partial support for operand
        * expand/rust-macro-builtins-asm.cc (parse_reg_operand): Likewise.
        (parse_label): Likewise.
        * expand/rust-macro-builtins-asm.h (parse_label): Likewise.
---
 gcc/rust/ast/rust-expr.h                   | 38 +++++++++++++
 gcc/rust/expand/rust-macro-builtins-asm.cc | 62 +++++++++++++++++++---
 gcc/rust/expand/rust-macro-builtins-asm.h  |  4 ++
 3 files changed, 97 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 30146b2d57c..ba413da95df 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -7,6 +7,7 @@
 #include "rust-macro.h"
 #include "rust-operators.h"
 #include "rust-system.h"
+#include <memory>
 
 namespace Rust {
 namespace AST {
@@ -4777,6 +4778,7 @@ struct InlineAsmOperand
     SplitInOut,
     Const,
     Sym,
+    Label,
   };
 
   struct In
@@ -4933,6 +4935,34 @@ struct InlineAsmOperand
       return *this;
     }
   };
+
+  struct Label
+  {
+    std::string label_name;
+    std::unique_ptr<Expr> expr;
+
+    Label () {}
+
+    Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr)
+      : expr (std::move (expr))
+    {
+      if (label_name.has_value ())
+       this->label_name = label_name.value ();
+    }
+    Label (const struct Label &other)
+    {
+      if (other.expr)
+       expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+    }
+
+    Label operator= (const struct Label &other)
+    {
+      if (other.expr)
+       expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+      return *this;
+    }
+  };
+
   RegisterType register_type;
 
   struct In in;
@@ -4941,6 +4971,7 @@ struct InlineAsmOperand
   struct SplitInOut split_in_out;
   struct Const cnst;
   struct Sym sym;
+  struct Label label;
 
   InlineAsmOperand () {}
   InlineAsmOperand (const InlineAsmOperand &other)
@@ -4992,6 +5023,13 @@ struct InlineAsmOperand
       this->sym = reg.value ();
   }
 
+  void set_label (const tl::optional<struct Label> &reg)
+  {
+    this->register_type = Label;
+    if (reg.has_value ())
+      this->label = reg.value ();
+  }
+
   location_t locus;
 };
 
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index d1f6897fcc4..47a47607cfe 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -373,19 +373,30 @@ parse_reg_operand (Parser<MacroInvocLexer> &parser, 
TokenId last_token_id,
     }
   else if (parser.peek_current_token ()->get_id () == CONST)
     {
-      // TODO: Please handle const
-      rust_unreachable ();
-      return tl::nullopt;
+      // TODO: Please handle const with parse_expr instead.
+      auto anon_const
+       = parse_format_string (parser, last_token_id, inline_asm_ctx);
+      reg_operand.set_cnst (tl::nullopt);
+      return reg_operand;
     }
-  else if (false && check_identifier (parser, "sym"))
+  else if (check_identifier (parser, "sym"))
     {
-      // TODO: Please handle sym
+      // TODO: Please handle sym, which needs ExprKind::Path in Rust's asm.rs
       rust_unreachable ();
       return tl::nullopt;
     }
-  else if (false && check_identifier (parser, "label"))
+  else if (auto label_str = parse_label (parser, last_token_id, 
inline_asm_ctx))
+    {
+      auto block = parser.parse_block_expr ();
+      struct AST::InlineAsmOperand::Label label (label_str,
+                                                block ? block->clone_expr ()
+                                                      : nullptr);
+      reg_operand.set_label (label);
+      return reg_operand;
+    }
+  else if (inline_asm_ctx.allows_templates ())
     {
-      // TODO: Please handle label
+      // TODO: If we allow templating, do sth here
       rust_unreachable ();
       return tl::nullopt;
     }
@@ -701,4 +712,41 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   return fragment_ast;
 }
 
+tl::optional<std::string>
+parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+            InlineAsmContext &inline_asm_ctx)
+{
+  auto token = parser.peek_current_token ();
+
+  if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL)
+    {
+      // very nice, we got a string.
+      auto label = token->as_string ();
+
+      bool flag = true;
+      if (label.empty () || label.back () != ':')
+       flag = false; // Check if string is empty or does not end with a colon
+
+      // Check if all characters before the last colon are digits
+      for (int i = 0; i < label.length () - 1 && flag == true; i++)
+       {
+         if (label[i] < '0' || label[i] > '9')
+           flag = false;
+       }
+
+      if (flag == true)
+       {
+         parser.skip_token ();
+         return token->as_string ();
+       }
+      else
+       {
+         return tl::nullopt;
+       }
+    }
+  else
+    {
+      return tl::nullopt;
+    }
+}
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 1ed3148e572..267c1b609d9 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -72,6 +72,10 @@ tl::optional<std::string>
 parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
                     InlineAsmContext &inline_asm_ctx);
 
+tl::optional<std::string>
+parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+            InlineAsmContext &inline_asm_ctx);
+
 std::set<std::string> potentially_nonpromoted_keywords
   = {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};
 
-- 
2.45.2

Reply via email to