https://gcc.gnu.org/g:3c14514dbcbef818169cc06e5bace8daa1b4b476
commit r15-8204-g3c14514dbcbef818169cc06e5bace8daa1b4b476 Author: jjasmine <tanghocle...@gmail.com> Date: Tue Jun 11 22:07:14 2024 -0700 gccrs: Expected first layer done gcc/rust/ChangeLog: * expand/rust-macro-builtins-asm.cc (parse_reg): Expected first layer done (parse_reg_operand): Likewise. (parse_asm_arg): Likewise. (parse_format_strings): Likewise. (parse_asm): Likewise. (validate): Likewise. * expand/rust-macro-builtins-asm.h (parse_asm_arg): Likewise. (validate): Likewise. (parse_format_strings): Likewise. Diff: --- gcc/rust/expand/rust-macro-builtins-asm.cc | 74 +++++++++++++++++------------- gcc/rust/expand/rust-macro-builtins-asm.h | 23 ++++++++-- 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc index 21634725aa2c..49d1fd4014f3 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.cc +++ b/gcc/rust/expand/rust-macro-builtins-asm.cc @@ -131,7 +131,6 @@ parse_reg (InlineAsmContext &inline_asm_ctx) { using RegType = AST::InlineAsmRegOrRegClass::Type; auto &parser = inline_asm_ctx.parser; - auto last_token_id = inline_asm_ctx.last_token_id; if (!parser.skip_token (LEFT_PAREN)) { @@ -204,7 +203,6 @@ parse_reg_operand (InlineAsmContext &inline_asm_ctx) // None // }; auto &parser = inline_asm_ctx.parser; - auto last_token_id = inline_asm_ctx.last_token_id; AST::InlineAsmOperand reg_operand; rust_debug ("Enter parse_reg_operand"); auto token = parser.peek_current_token (); @@ -562,8 +560,8 @@ MacroBuiltin::asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc, return parse_asm (invoc_locus, invoc, is_global_asm); } -int -parse_asm_arg (InlineAsmContext &inline_asm_ctx) +tl::expected<InlineAsmContext, std::string> +parse_asm_arg (InlineAsmContext inline_asm_ctx) { auto &parser = inline_asm_ctx.parser; auto last_token_id = inline_asm_ctx.last_token_id; @@ -625,7 +623,7 @@ parse_asm_arg (InlineAsmContext &inline_asm_ctx) // std::cout << "reg_operand" << std::endl; auto operand = parse_reg_operand (inline_asm_ctx); } - return 0; + return tl::expected<InlineAsmContext, std::string> (inline_asm_ctx); } tl::optional<AST::Fragment> @@ -655,14 +653,48 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, AST::InlineAsm inline_asm (invoc_locus, is_global_asm); auto inline_asm_ctx = InlineAsmContext (inline_asm, parser, last_token_id); + // operands stream, also handles the optional "," + tl::expected<InlineAsmContext, std::string> resulting_context + = tl::expected<InlineAsmContext, std::string> (inline_asm_ctx); + resulting_context.and_then (parse_format_strings) + .and_then (parse_asm_arg) + .and_then (validate); + + // TODO: I'm putting the validation here because the rust reference put it + // here Per Arthur's advice we would actually do the validation in a different + // stage. and visit on the InlineAsm AST instead of it's context. + auto is_valid = (bool) resulting_context; + + if (is_valid) + { + AST::SingleASTNode single = AST::SingleASTNode ( + inline_asm_ctx.inline_asm.clone_expr_without_block ()); + std::vector<AST::SingleASTNode> single_vec = {single}; + + AST::Fragment fragment_ast + = AST::Fragment (single_vec, + std::vector<std::unique_ptr<AST::Token>> ()); + return fragment_ast; + } + else + { + return tl::nullopt; + } +} + +tl::expected<InlineAsmContext, std::string> +parse_format_strings (InlineAsmContext inline_asm_ctx) +{ // Parse the first ever formatted string, success or not, will skip 1 token + auto parser = inline_asm_ctx.parser; + auto last_token_id = inline_asm_ctx.last_token_id; auto fm_string = parse_format_string (inline_asm_ctx); if (fm_string == tl::nullopt) { rust_error_at (parser.peek_current_token ()->get_locus (), "%s template must be a string literal", "asm"); - return tl::nullopt; + return tl::unexpected<std::string> ("ERROR"); } // formatted string stream @@ -685,29 +717,7 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, } } - // operands stream, also handles the optional "," - parse_asm_arg (inline_asm_ctx); - - // TODO: I'm putting the validation here because the rust reference put it - // here Per Arthur's advice we would actually do the validation in a different - // stage. and visit on the InlineAsm AST instead of it's context. - auto is_valid = validate (inline_asm_ctx); - - if (is_valid) - { - AST::SingleASTNode single = AST::SingleASTNode ( - inline_asm_ctx.inline_asm.clone_expr_without_block ()); - std::vector<AST::SingleASTNode> single_vec = {single}; - - AST::Fragment fragment_ast - = AST::Fragment (single_vec, - std::vector<std::unique_ptr<AST::Token>> ()); - return fragment_ast; - } - else - { - return tl::nullopt; - } + return tl::expected<InlineAsmContext, std::string> (inline_asm_ctx); } // bool @@ -727,9 +737,9 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, // return true; // } -bool -validate (InlineAsmContext &inline_asm_ctx) +tl::expected<InlineAsmContext, std::string> +validate (InlineAsmContext inline_asm_ctx) { - return true; + return tl::expected<InlineAsmContext, std::string> (inline_asm_ctx); } } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h index 90c469f54f78..6d064ea6eb6a 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.h +++ b/gcc/rust/expand/rust-macro-builtins-asm.h @@ -1,6 +1,7 @@ #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" +#include "expected.h" #include "rust-macro-invoc-lexer.h" #include "rust/ast/rust-expr.h" namespace Rust { @@ -29,6 +30,14 @@ public: parser (parser), last_token_id (last_token_id) {} + // InlineAsmContext (InlineAsmContext && inline_asm_ctx) + // : allow_templates(inline_asm_ctx.allow_templates), + // is_explicit(inline_asm_ctx.is_explicit), + // consumed_comma_without_formatted_string(inline_asm_ctx.consumed_comma_without_formatted_string), + // inline_asm(inline_asm_ctx.inline_asm), + // parser(inline_asm_ctx.parser), + // last_token_id(inline_asm_ctx.last_token_id) {} + bool is_global_asm () { return inline_asm.is_global_asm; } bool allows_templates () { return allow_templates; } @@ -39,8 +48,15 @@ public: } }; -int -parse_asm_arg (InlineAsmContext &inline_asm_ctx); +// Expected calls +tl::expected<InlineAsmContext, std::string> +validate (InlineAsmContext inline_asm_ctx); + +tl::expected<InlineAsmContext, std::string> +parse_asm_arg (InlineAsmContext inline_asm_ctx); + +tl::expected<InlineAsmContext, std::string> +parse_format_strings (InlineAsmContext inline_asm_ctx); tl::optional<AST::Fragment> parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, @@ -76,8 +92,7 @@ parse_format_string (InlineAsmContext &inline_asm_ctx); tl::optional<std::string> parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id, InlineAsmContext &inline_asm_ctx); -bool -validate (InlineAsmContext &inline_asm_ctx); + std::set<std::string> potentially_nonpromoted_keywords = {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};