https://gcc.gnu.org/g:26c50996efd2d79f6f86e8decc7006f1384075ca

commit r15-8176-g26c50996efd2d79f6f86e8decc7006f1384075ca
Author: jjasmine <tanghocle...@gmail.com>
Date:   Tue May 21 19:46:18 2024 -0700

    gccrs: Implemented parse_clobber_abi to pass new tests
    
    gcc/rust/ChangeLog:
    
            * expand/rust-macro-builtins-asm.cc (parse_clobber_abi):
            implemented parse_clobber_abi
            (parse_format_string): likewise.
            (parseAsmArg): likewise.
            (parse_asm): likewise.
            * expand/rust-macro-builtins-asm.h (parseAsmArg): likewise.

Diff:
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 81 ++++++++++++++++++++++--------
 gcc/rust/expand/rust-macro-builtins-asm.h  |  3 +-
 2 files changed, 61 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 6e602c463edd..bcf8b6fb3f25 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -31,14 +31,31 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
                   AST::InlineAsm &inlineAsm)
 {
   // clobber_abi := "clobber_abi(" <abi> *("," <abi>) [","] ")"
-
   // PARSE EVERYTHING COMMITTEDLY IN THIS FUNCTION, WE CONFIRMED VIA 
clobber_abi
   // identifier keyword
-
+  auto token = parser.peek_current_token ();
   if (!parser.skip_token (LEFT_PAREN))
     {
       // TODO: Raise error exactly like rustc if left parenthesis is not
       // encountered.
+      token = parser.peek_current_token ();
+
+      // TODO: Error reporting shifted to the left 1 character, I'm not sure
+      // why.
+      if (token->get_id () == last_token_id)
+       {
+         rust_error_at (parser.peek_current_token ()->get_locus (),
+                        "expected `(`, found end of macro arguments");
+         return -1;
+       }
+
+      else
+       {
+         rust_error_at (
+           parser.peek_current_token ()->get_locus (),
+           "expected `(`, found `%s`",
+           parser.peek_current_token ()->get_token_description ());
+       }
       return -1;
     }
 
@@ -46,12 +63,15 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
     {
       // TODO: We encountered a "clobber_abi()", which should be illegal?
       // 
https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_builtin_macros/src/asm.rs#L381
+      rust_error_at (
+       parser.peek_current_token ()->get_locus (),
+       "at least one abi must be provided as an argument to `clobber_abi`");
       return -1;
     }
 
   std::vector<AST::TupleClobber> new_abis;
 
-  auto token = parser.peek_current_token ();
+  token = parser.peek_current_token ();
 
   while (token->get_id () != last_token_id && token->get_id () != RIGHT_PAREN)
     {
@@ -198,7 +218,6 @@ bool
 check_identifier (Parser<MacroInvocLexer> &p, std::string ident)
 {
   auto token = p.peek_current_token ();
-
   if (token->get_id () == IDENTIFIER
       && (token->as_string () == ident || ident == ""))
     {
@@ -218,17 +237,11 @@ parse_format_string (Parser<MacroInvocLexer> &parser, 
TokenId last_token_id)
   if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL)
     {
       // very nice, we got a supposedly formatted string.
-      std::cout << token->get_token_description () << std::endl;
       parser.skip_token ();
-      return "formatted string";
+      return token->as_string ();
     }
   else
     {
-      parser.skip_token ();
-      std::cout << token->get_token_description () << std::endl;
-
-      rust_error_at (token->get_locus (),
-                    "asm template must be a string literal");
       return tl::nullopt;
     }
 }
@@ -253,22 +266,32 @@ MacroBuiltin::nonglobal_asm_handler (location_t 
invoc_locus,
 
 int
 parseAsmArg (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-            AST::InlineAsm &inlineAsm)
+            AST::InlineAsm &inlineAsm,
+            bool consumed_comma_without_formatted_string)
 {
   auto token = parser.peek_current_token ();
   tl::optional<std::string> fm_string;
   while (token->get_id () != last_token_id)
     {
-      std::cout << token->get_token_description () << std::endl;
-
       token = parser.peek_current_token ();
 
       // We accept a comma token here.
-      if (token->get_id () != COMMA)
+      if (token->get_id () != COMMA && consumed_comma_without_formatted_string)
+       {
+         // if it is not a comma, but we consumed it previously, this is fine
+         // but we have to set it to false tho.
+         consumed_comma_without_formatted_string = false;
+       }
+      else if (token->get_id () == COMMA
+              && !consumed_comma_without_formatted_string)
+       {
+         consumed_comma_without_formatted_string = false;
+         parser.skip_token ();
+       }
+      else
        {
          break;
        }
-      parser.skip_token ();
 
       // And if that token comma is also the trailing comma, we break
       // TODO: Check with mentor see what last_token_id means
@@ -285,7 +308,7 @@ parseAsmArg (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
       // TODO: Parse clobber abi, eat the identifier named "clobber_abi" if 
true
       if (check_identifier (parser, "clobber_abi"))
        {
-         std::cout << "Clobber abi tee hee" << std::endl;
+         parse_clobber_abi (parser, last_token_id, inlineAsm);
          continue;
        }
 
@@ -298,6 +321,7 @@ parseAsmArg (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
 
       // Ok after we have check that neither clobber_abi nor options works, the
       // only other logical choice is reg_operand
+      std::cout << "reg_operand" << std::endl;
       fm_string = parse_format_string (parser, last_token_id);
     }
   return 0;
@@ -332,28 +356,41 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
 
   // Parse the first ever formatted string, success or not, will skip 1 token
   auto fm_string = parse_format_string (parser, last_token_id);
+
   if (fm_string == tl::nullopt)
-    return tl::nullopt;
+    {
+      rust_error_at (parser.peek_current_token ()->get_locus (),
+                    "asm template must be a string literal");
+      return tl::nullopt;
+    }
 
   // formatted string stream
+  int i = 0;
+  bool consumed_comma_without_formatted_string = false;
   auto token = parser.peek_current_token ();
   while (token->get_id () != last_token_id)
     {
-      std::cout << token->get_token_description () << std::endl;
       token = parser.peek_current_token ();
-      if (token->get_id () != COMMA)
+      if (!parser.skip_token (COMMA))
        {
          break;
        }
-      parser.skip_token ();
       // Ok after the comma is good, we better be parsing correctly everything
       // in here, which is formatted string in ABNF
 
       fm_string = parse_format_string (parser, last_token_id);
+
+      if (fm_string == tl::nullopt)
+       {
+         consumed_comma_without_formatted_string = true;
+         break;
+       }
+      consumed_comma_without_formatted_string = false;
     }
 
   // operands stream, also handles the optional ","
-  parseAsmArg (parser, last_token_id, inlineAsm);
+  parseAsmArg (parser, last_token_id, inlineAsm,
+              consumed_comma_without_formatted_string);
 
   return tl::nullopt;
 }
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 204ac0e72389..1d7889f2698d 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -9,7 +9,8 @@ namespace Rust {
 // all operands.
 int
 parseAsmArg (Parser<MacroInvocLexer> &p, TokenId last_token_id,
-            AST::InlineAsm &inlineAsm);
+            AST::InlineAsm &inlineAsm,
+            bool consumed_comma_without_formatted_string);
 static tl::optional<AST::Fragment>
 parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
 static tl::optional<AST::Fragment>

Reply via email to