diff options
author | jjasmine <tanghocle456@gmail.com> | 2024-06-04 23:14:19 -0700 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-17 16:35:45 +0100 |
commit | 58a5a14875e7c47de24b0a1c3ed34dfab665fded (patch) | |
tree | a73a34f688259dd7cd7dca0d4aeea7a69a99744e /gcc/rust | |
parent | 7039e95a67c062c413857db39b1850e2117d288c (diff) | |
download | gcc-58a5a14875e7c47de24b0a1c3ed34dfab665fded.zip gcc-58a5a14875e7c47de24b0a1c3ed34dfab665fded.tar.gz gcc-58a5a14875e7c47de24b0a1c3ed34dfab665fded.tar.bz2 |
gccrs: Successful parse of in and inout, albeit with str
gcc/rust/ChangeLog:
* expand/rust-macro-builtins-asm.cc (parse_reg_operand):
Successful parse of in and inout, albeit with str
(check_identifier): Likewise.
(parse_asm_arg): Likewise.
* expand/rust-macro-builtins-asm.h (parse_format_string): Likewise.
gcc/testsuite/ChangeLog:
* rust/compile/inline_asm_parse_operand.rs: New test.
Diffstat (limited to 'gcc/rust')
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-asm.cc | 108 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-asm.h | 4 |
2 files changed, 102 insertions, 10 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc index 95a268a..23f78c0 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.cc +++ b/gcc/rust/expand/rust-macro-builtins-asm.cc @@ -204,11 +204,15 @@ parse_reg_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id, // }; AST::InlineAsmOperand reg_operand; + rust_debug("Enter parse_reg_operand"); auto token = parser.peek_current_token (); auto iden_token = parser.peek_current_token (); auto &inline_asm = inline_asm_ctx.inline_asm; if (check_identifier (parser, "")) { + + rust_debug("Didn't get passed identifier checking, %s", token->as_string().c_str()); + auto equal_token = parser.peek_current_token (); if (!parser.skip_token (EQUAL)) { @@ -218,12 +222,40 @@ parse_reg_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id, } token = parser.peek_current_token (); + rust_debug_loc(token->get_locus(), "Got pass identifier checking with %s", token->as_string().c_str()); + bool is_global_asm = inline_asm.is_global_asm; - if (!is_global_asm && check_identifier (parser, "in")) + + // For the keyword IN, currently we count it as a seperate keyword called Rust::IN + // search for #define RS_TOKEN_LIST in code base. + if (!is_global_asm && parser.skip_token(IN)) { - rust_unreachable (); - return tl::nullopt; + rust_debug("Enter parse_reg_operand in"); + + auto reg = parse_reg(parser, last_token_id, inline_asm_ctx); + + if (parser.skip_token(UNDERSCORE)) { + // We are sure to be failing a test here, based on asm.rs + // https://github.com/rust-lang/rust/blob/a330e49593ee890f9197727a3a558b6e6b37f843/compiler/rustc_builtin_macros/src/asm.rs#L112 + rust_unreachable(); + } + + auto expr = parse_format_string(parser, last_token_id, inline_asm_ctx) ; + reg_operand.register_type = AST::InlineAsmOperand::RegisterType::In; + + // Since reg is of type optional<T>, we need to check if it is not optional first. + // TODO: We don't throw any errors since we should have throw any encountered parsing error in parse_reg + if (reg) { + reg_operand.in.reg = reg.value(); + } + + // Only clone_expr() if we know that we have parse an expression successfully + // if (expr) { + // reg_operand.in.expr = expr->clone_expr(); + // } + + return reg_operand; } else if (!is_global_asm && check_identifier (parser, "out")) { @@ -237,8 +269,51 @@ parse_reg_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id, } else if (!is_global_asm && check_identifier (parser, "inout")) { - rust_unreachable (); + rust_debug("Enter parse_reg_operand inout"); + + auto reg = parse_reg(parser, last_token_id, inline_asm_ctx); + + if (parser.skip_token(UNDERSCORE)) { + // We are sure to be failing a test here, based on asm.rs + // https://github.com/rust-lang/rust/blob/a330e49593ee890f9197727a3a558b6e6b37f843/compiler/rustc_builtin_macros/src/asm.rs#L112 + rust_unreachable(); + } + + // 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(parser, last_token_id, inline_asm_ctx) ; + + std::unique_ptr<AST::Expr> out_expr; + + if (parser.skip_token(MATCH_ARROW)) { + rust_debug("Matched MATCH_ARROW"); + if (!parser.skip_token(UNDERSCORE)) { + + parse_format_string(parser, last_token_id, inline_asm_ctx) ; + //out_expr = parser.parse_expr(); + } + + reg_operand.register_type = AST::InlineAsmOperand::RegisterType::SplitInOut; + // reg_operand.split_in_out.in_expr = expr->clone_expr(); + // reg_operand.split_in_out.out_expr = out_expr->clone_expr(); + // reg_operand.split_in_out.late = false; + return reg_operand; + + } else { + reg_operand.register_type = AST::InlineAsmOperand::RegisterType::InOut; + // reg_operand.in_out.expr = expr->clone_expr(); + // reg_operand.in_out.late = false; + return reg_operand; + } + // if p.eat(&token::FatArrow) { + // let out_expr = + // if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) }; + // ast::InlineAsmOperand::SplitInOut { reg, in_expr: expr, out_expr, late: false } + // } else { + // ast::InlineAsmOperand::InOut { reg, expr, late: false } + // } return tl::nullopt; + } else if (!is_global_asm && check_identifier (parser, "inlateout")) { @@ -389,17 +464,30 @@ 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 == "")) - { + + if (token->get_id () == IDENTIFIER) { + auto str = token->as_string(); + + // For non-promoted keywords, we need to also check for them. + + if (str == ident) { p.skip_token (); return true; } - else - { + if (ident == "") { + if (str != "in" && str != "out" && str != "lateout" && str != "inout" && str != "inlateout" && str != "const" && str != "sym" && str != "label") + { + p.skip_token (); + return true; + } return false; } + } + + return false; + } + tl::optional<std::string> parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id, InlineAsmContext &inline_asm_ctx) @@ -485,7 +573,7 @@ parse_asm_arg (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, inline_asm_ctx); + auto operand = parse_reg_operand (parser, last_token_id, inline_asm_ctx); } return 0; } diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h index 45f1fd2..37f5f5a 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.h +++ b/gcc/rust/expand/rust-macro-builtins-asm.h @@ -68,4 +68,8 @@ int parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId last_token_id, InlineAsmContext &inline_asm_ctx); +tl::optional<std::string> +parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id, + InlineAsmContext &inline_asm_ctx); + } // namespace Rust
\ No newline at end of file |