https://gcc.gnu.org/g:07fb0f1e3dc937bf45490fc769d81a35ca54c127

commit r15-8185-g07fb0f1e3dc937bf45490fc769d81a35ca54c127
Author: jjasmine <tanghocle...@gmail.com>
Date:   Mon May 27 20:51:38 2024 -0700

    gccrs: Big Refactor after meeting
    
    gcc/rust/ChangeLog:
    
            * ast/rust-expr.h (struct InlineAsmRegOrRegClass):
            Remove union
            (struct InlineAsmOperand): Make instances of inside struct.
            * expand/rust-macro-builtins-asm.cc (parse_clobber_abi):
            Change signature with inlineAsmCtx.
            (parse_reg): Likewise.
            (parse_operand): Likewise.
            (parse_reg_operand): Likewise.
            (check_and_set): Likewise.
            (parse_options): Likewise.
            (parse_format_string): Likewise.
            (parseAsmArg): Likewise.
            (parse_asm): Likewise.
            * expand/rust-macro-builtins-asm.h (class InlineAsmContext): 
Likewise.
            (parseAsmArg): Likewise.
            (check_and_set): Likewise.
            (parse_reg_operand): Likewise.
            (parse_options): Likewise.
            (parse_reg): Likewise.
            (parse_clobber_abi): Likewise.

Diff:
---
 gcc/rust/ast/rust-expr.h                   |  17 +++-
 gcc/rust/expand/rust-macro-builtins-asm.cc | 152 +++++++++++++++++++++--------
 gcc/rust/expand/rust-macro-builtins-asm.h  |  44 +++++++--
 3 files changed, 157 insertions(+), 56 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 1af72965a93e..76e5fa7c4475 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4744,11 +4744,9 @@ struct InlineAsmRegOrRegClass
   };
 
   Type type;
-  union
-  {
-    struct Reg reg;
-    struct RegClass regClass;
-  };
+  struct Reg reg;
+  struct RegClass regClass;
+
   Identifier name;
   location_t locus;
 };
@@ -4802,6 +4800,15 @@ struct InlineAsmOperand
   {
     std::unique_ptr<Expr> sym;
   };
+  RegisterType registerType;
+
+  struct In in;
+  struct Out out;
+  struct InOut inOut;
+  struct SplitInOut splitInOut;
+  struct Const cnst;
+  struct Sym sym;
+
   location_t locus;
 };
 
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 8c2b88c997d1..f7703ddd7303 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -39,11 +39,12 @@ parseDirSpec (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id)
 
 int
 parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-                  AST::InlineAsm &inlineAsm)
+                  InlineAsmContext &inlineAsmCtx)
 {
   // clobber_abi := "clobber_abi(" <abi> *("," <abi>) [","] ")"
   // PARSE EVERYTHING COMMITTEDLY IN THIS FUNCTION, WE CONFIRMED VIA 
clobber_abi
   // identifier keyword
+  auto &inlineAsm = inlineAsmCtx.inlineAsm;
   auto token = parser.peek_current_token ();
   if (!parser.skip_token (LEFT_PAREN))
     {
@@ -59,7 +60,6 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
                         "expected `(`, found end of macro arguments");
          return -1;
        }
-
       else
        {
          rust_error_at (
@@ -125,15 +125,16 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, 
TokenId last_token_id,
   return 0;
 }
 
-int
+tl::optional<AST::InlineAsmRegOrRegClass>
 parse_reg (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-          AST::InlineAsm &inlineAsm, bool is_explicit)
+          InlineAsmContext &inlineAsmCtx)
 {
+  using RegType = AST::InlineAsmRegOrRegClass::Type;
   if (!parser.skip_token (LEFT_PAREN))
     {
       // TODO: we expect a left parenthesis here, please return the correct
       // error.
-      return 0;
+      return tl::nullopt;
     }
 
   // after successful left parenthesis parsing, we should return ast of
@@ -144,6 +145,9 @@ parse_reg (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
   if (tok_id == IDENTIFIER)
     {
       // construct a InlineAsmRegOrRegClass
+      AST::InlineAsmRegOrRegClass regClass;
+      regClass.type = RegType::RegClass;
+      regClass.regClass.Symbol = token->as_string ();
     }
   else if (tok_id == STRING_LITERAL)
     {
@@ -151,6 +155,7 @@ parse_reg (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
       // for both?
 
       // construct a InlineAsmRegOrRegClass
+      // parse_format_string
     }
   else
     {
@@ -159,23 +164,86 @@ parse_reg (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
   if (!parser.skip_token (RIGHT_PAREN))
     {
       // we expect a left parenthesis here, please return the correct error.
-      return 0;
+      return tl::nullopt;
     }
 
-  return 0;
+  return tl::nullopt;
 }
 
 int
 parse_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-              AST::InlineAsm &inlineAsm)
+              InlineAsmContext &inlineAsmCtx)
 {
   return 0;
 }
 
+// From rustc
+tl::optional<AST::InlineAsmOperand>
+parse_reg_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+                  InlineAsmContext &inlineAsmCtx)
+{
+  // let name = if p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq) {
+  //           let (ident, _) = p.token.ident().unwrap();
+  //           p.bump();
+  //           p.expect(&token::Eq)?;
+  //           allow_templates = false;
+  //           Some(ident.name)
+  //       } else {
+  //           None
+  //       };
+
+  using RegisterType = AST::InlineAsmOperand::RegisterType;
+
+  auto token = parser.peek_current_token ();
+  auto iden_token = parser.peek_current_token ();
+  auto &inlineAsm = inlineAsmCtx.inlineAsm;
+  if (check_identifier (parser, ""))
+    {
+      auto equal_token = parser.peek_current_token ();
+      if (!parser.skip_token (EQUAL))
+       {
+         // TODO: Please handle this.
+         rust_unreachable ();
+       }
+    }
+
+  token = parser.peek_current_token ();
+
+  bool is_explicit_reg = false;
+  bool is_global_asm = inlineAsm.is_global_asm;
+  if (!is_global_asm && check_identifier (parser, "in"))
+    {}
+  else if (!is_global_asm && check_identifier (parser, "out"))
+    {}
+  else if (!is_global_asm && check_identifier (parser, "lateout"))
+    {}
+  else if (!is_global_asm && check_identifier (parser, "inout"))
+    {}
+  else if (!is_global_asm && check_identifier (parser, "inlateout"))
+    {}
+  else if (false && check_identifier (parser, "const"))
+    {
+      // todo: Please handle const
+    }
+  else if (false && check_identifier (parser, "sym"))
+    {
+      // todo: Please handle sym
+    }
+  else if (false && check_identifier (parser, "label"))
+    {
+      // todo: Please handle label
+    }
+  else
+    {
+      return tl::nullopt;
+    }
+  return tl::nullopt;
+}
 void
-check_and_set (Parser<MacroInvocLexer> &parser, AST::InlineAsm &inlineAsm,
+check_and_set (Parser<MacroInvocLexer> &parser, InlineAsmContext &inlineAsmCtx,
               AST::InlineAsmOption option)
 {
+  auto &inlineAsm = inlineAsmCtx.inlineAsm;
   if (inlineAsm.options.count (option) != 0)
     {
       // TODO: report an error of duplication
@@ -191,9 +259,9 @@ check_and_set (Parser<MacroInvocLexer> &parser, 
AST::InlineAsm &inlineAsm,
 }
 int
 parse_options (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-              AST::InlineAsm &inlineAsm)
+              InlineAsmContext &inlineAsmCtx)
 {
-  bool is_global_asm = inlineAsm.is_global_asm;
+  bool is_global_asm = inlineAsmCtx.inlineAsm.is_global_asm;
   // Parse everything commitedly
   if (!parser.skip_token (LEFT_PAREN))
     {
@@ -208,40 +276,42 @@ parse_options (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
     {
       if (!is_global_asm && check_identifier (parser, "pure"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::PURE);
+         check_and_set (parser, inlineAsmCtx, AST::InlineAsmOption::PURE);
        }
       else if (!is_global_asm && check_identifier (parser, "nomem"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::NOMEM);
+         check_and_set (parser, inlineAsmCtx, AST::InlineAsmOption::NOMEM);
        }
       else if (!is_global_asm && check_identifier (parser, "readonly"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::READONLY);
+         check_and_set (parser, inlineAsmCtx, AST::InlineAsmOption::READONLY);
        }
       else if (!is_global_asm && check_identifier (parser, "preserves_flags"))
        {
-         check_and_set (parser, inlineAsm,
+         check_and_set (parser, inlineAsmCtx,
                         AST::InlineAsmOption::PRESERVES_FLAGS);
        }
       else if (!is_global_asm && check_identifier (parser, "noreturn"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::NORETURN);
+         check_and_set (parser, inlineAsmCtx, AST::InlineAsmOption::NORETURN);
        }
       else if (!is_global_asm && check_identifier (parser, "nostack"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::NOSTACK);
+         check_and_set (parser, inlineAsmCtx, AST::InlineAsmOption::NOSTACK);
        }
       else if (!is_global_asm && check_identifier (parser, "may_unwind"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::MAY_UNWIND);
+         check_and_set (parser, inlineAsmCtx,
+                        AST::InlineAsmOption::MAY_UNWIND);
        }
       else if (check_identifier (parser, "att_syntax"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::ATT_SYNTAX);
+         check_and_set (parser, inlineAsmCtx,
+                        AST::InlineAsmOption::ATT_SYNTAX);
        }
       else if (check_identifier (parser, "raw"))
        {
-         check_and_set (parser, inlineAsm, AST::InlineAsmOption::RAW);
+         check_and_set (parser, inlineAsmCtx, AST::InlineAsmOption::RAW);
        }
       else
        {
@@ -290,7 +360,8 @@ check_identifier (Parser<MacroInvocLexer> &p, std::string 
ident)
     }
 }
 tl::optional<std::string>
-parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id)
+parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+                    InlineAsmContext &inlineAsmCtx)
 {
   auto token = parser.peek_current_token ();
 
@@ -315,8 +386,7 @@ MacroBuiltin::asm_handler (location_t invoc_locus, 
AST::MacroInvocData &invoc,
 
 int
 parseAsmArg (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-            AST::InlineAsm &inlineAsm,
-            bool consumed_comma_without_formatted_string)
+            InlineAsmContext &inlineAsmCtx)
 {
   auto token = parser.peek_current_token ();
   tl::optional<std::string> fm_string;
@@ -325,16 +395,17 @@ parseAsmArg (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
       token = parser.peek_current_token ();
 
       // We accept a comma token here.
-      if (token->get_id () != COMMA && consumed_comma_without_formatted_string)
+      if (token->get_id () != COMMA
+         && inlineAsmCtx.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;
+         inlineAsmCtx.consumed_comma_without_formatted_string = false;
        }
       else if (token->get_id () == COMMA
-              && !consumed_comma_without_formatted_string)
+              && !inlineAsmCtx.consumed_comma_without_formatted_string)
        {
-         consumed_comma_without_formatted_string = false;
+         inlineAsmCtx.consumed_comma_without_formatted_string = false;
          parser.skip_token ();
        }
       else
@@ -357,21 +428,21 @@ 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"))
        {
-         parse_clobber_abi (parser, last_token_id, inlineAsm);
+         parse_clobber_abi (parser, last_token_id, inlineAsmCtx);
          continue;
        }
 
       // TODO: Parse options
       if (check_identifier (parser, "options"))
        {
-         parse_options (parser, last_token_id, inlineAsm);
+         parse_options (parser, last_token_id, inlineAsmCtx);
          continue;
        }
 
       // 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);
+      fm_string = parse_format_string (parser, last_token_id, inlineAsmCtx);
     }
   return 0;
 }
@@ -401,10 +472,10 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
 
   AST::InlineAsm inlineAsm (invoc_locus, is_global_asm);
-  inlineAsm.is_global_asm = is_global_asm;
+  auto inlineAsmCtx = InlineAsmContext (inlineAsm);
 
   // Parse the first ever formatted string, success or not, will skip 1 token
-  auto fm_string = parse_format_string (parser, last_token_id);
+  auto fm_string = parse_format_string (parser, last_token_id, inlineAsmCtx);
 
   if (fm_string == tl::nullopt)
     {
@@ -414,32 +485,27 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
     }
 
   // 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)
+
+  while (parser.peek_current_token ()->get_id () != last_token_id)
     {
-      token = parser.peek_current_token ();
       if (!parser.skip_token (COMMA))
        {
          break;
        }
       // Ok after the comma is good, we better be parsing correctly everything
       // in here, which is formatted string in ABNF
+      inlineAsmCtx.consumed_comma_without_formatted_string = false;
 
-      fm_string = parse_format_string (parser, last_token_id);
-
+      fm_string = parse_format_string (parser, last_token_id, inlineAsmCtx);
       if (fm_string == tl::nullopt)
        {
-         consumed_comma_without_formatted_string = true;
+         inlineAsmCtx.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,
-              consumed_comma_without_formatted_string);
+  parseAsmArg (parser, last_token_id, inlineAsmCtx);
 
   return tl::nullopt;
 }
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index ffb438bcb89b..65763780979c 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -7,10 +7,33 @@ namespace Rust {
 // All the operands are called asm_args in rustc asm.rs, we create a struct 
that
 // can store all of these AsmArgs This replaces the phase where we have to 
parse
 // all operands.
+
+class InlineAsmContext
+{
+public:
+  bool allow_templates;
+  bool is_explicit;
+  bool consumed_comma_without_formatted_string;
+  AST::InlineAsm &inlineAsm;
+  InlineAsmContext (AST::InlineAsm &inlineAsm)
+    : allow_templates (true), is_explicit (false),
+      consumed_comma_without_formatted_string (false), inlineAsm (inlineAsm)
+  {}
+
+  bool is_global_asm () { return inlineAsm.is_global_asm; }
+
+  bool allows_templates () { return allow_templates; }
+
+  void set_allow_templates (bool allow_templates)
+  {
+    this->allow_templates = allow_templates;
+  }
+};
+
 int
 parseAsmArg (Parser<MacroInvocLexer> &p, TokenId last_token_id,
-            AST::InlineAsm &inlineAsm,
-            bool consumed_comma_without_formatted_string);
+            InlineAsmContext &inlineAsmCtx);
+
 tl::optional<AST::Fragment>
 parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
 tl::optional<AST::Fragment>
@@ -23,25 +46,30 @@ bool
 check_identifier (Parser<MacroInvocLexer> &p, std::string ident);
 
 void
-check_and_set (Parser<MacroInvocLexer> &p, AST::InlineAsm &inlineAsm,
+check_and_set (Parser<MacroInvocLexer> &p, InlineAsmContext &inlineAsmCtx,
               AST::InlineAsmOption option);
 // From rustc
 int
 parse_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-              AST::InlineAsm &inlineAsm);
+              InlineAsmContext &inlineAsmCtx);
+
+// From rustc
+tl::optional<AST::InlineAsmOperand>
+parse_reg_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+                  InlineAsmContext &inlineAsmCtx);
 
 // From rustc
 int
 parse_options (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-              AST::InlineAsm &inlineAsm);
+              InlineAsmContext &inlineAsmCtx);
 
 // From rustc
-int
+tl::optional<AST::InlineAsmRegOrRegClass>
 parse_reg (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-          AST::InlineAsm &inlineAsm, bool is_explicit);
+          InlineAsmContext &inlineAsmCtx);
 
 int
 parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
-                  AST::InlineAsm &inlineAsm);
+                  InlineAsmContext &inlineAsmCtx);
 
 } // namespace Rust
\ No newline at end of file

Reply via email to