diff options
author | jjasmine <tanghocle456@gmail.com> | 2024-06-10 16:54:34 -0700 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-17 16:35:47 +0100 |
commit | c1662670f70e8c06164da58a2b020dcd89ae75d6 (patch) | |
tree | 382a372a7004cb74873a11519ee672109a2f035e | |
parent | 83465864dbddcebca788df417783eb4e074626f8 (diff) | |
download | gcc-c1662670f70e8c06164da58a2b020dcd89ae75d6.zip gcc-c1662670f70e8c06164da58a2b020dcd89ae75d6.tar.gz gcc-c1662670f70e8c06164da58a2b020dcd89ae75d6.tar.bz2 |
gccrs: Partial support for operand
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.
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 38 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-asm.cc | 62 | ||||
-rw-r--r-- | 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 30146b2..ba413da 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> ®) + { + 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 d1f6897..47a4760 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 1ed3148..267c1b6 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"}; |