From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 3F3793858410; Tue, 28 Feb 2023 22:36:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3F3793858410 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1677623799; bh=59Imt21TyGYn/KTaj03FM8a0UwXkMlCYP1b+MydYJG4=; h=From:To:Subject:Date:From; b=x0kkNXJQiMXB5G8th+fS5iSi5u/ykpc4FYVL3+uogW+WMEy+ALnqBB8Jc/ZbuEUMD vYskBO7T8aQo+2Kzg/BiEyQSobK8H7x3FPXJ7xyqfX4l6hJHcIhU2tfUF+Uhz8N9e7 0h8t7K3bn9hLwpb73MzR3B6kHiWCxc+PICKQ89V8= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Implement and test include_str eager expansion X-Act-Checkin: gcc X-Git-Author: omkar-mohanty X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: ce43f55e9976929f9ff2388c8971a65afd24e26d X-Git-Newrev: 5c2ed969a2d58217797cf2e938c0f833a50d7cb4 Message-Id: <20230228223639.3F3793858410@sourceware.org> Date: Tue, 28 Feb 2023 22:36:39 +0000 (GMT) List-Id: https://gcc.gnu.org/g:5c2ed969a2d58217797cf2e938c0f833a50d7cb4 commit 5c2ed969a2d58217797cf2e938c0f833a50d7cb4 Author: omkar-mohanty Date: Thu Feb 16 10:10:24 2023 +0530 Implement and test include_str eager expansion builtins: Implement eager expansion for include_str!() gcc/rust/ChangeLog: * expand/rust-macro-builtins.cc (MacroBuiltin::include_str_handler): eager expansion (make_macro_path_str): macto to string (parse_single_string_literal): check for eager invocation (MacroBuiltin::assert_handler): eager expansion (MacroBuiltin::include_bytes_handler): eager expansion (MacroBuiltin::include_str_handler): eager expansion (MacroBuiltin::compile_error_handler): eager expansion (MacroBuiltin::include_handler): eager expansion gcc/testsuite/ChangeLog: * rust/compile/builtin_macro_eager3.rs: New test. Signed-off-by: omkar-mohanty Diff: --- gcc/rust/expand/rust-macro-builtins.cc | 160 ++++++++++++++------- gcc/testsuite/rust/compile/builtin_macro_eager3.rs | 16 +++ 2 files changed, 126 insertions(+), 50 deletions(-) diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index cf90b384cb5..d7f15784ceb 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -16,42 +16,24 @@ // along with GCC; see the file COPYING3. If not see // . +#include "rust-system.h" #include "rust-macro-builtins.h" +#include "rust-ast-fragment.h" #include "rust-ast.h" +#include "rust-attribute-visitor.h" #include "rust-diagnostics.h" +#include "rust-early-name-resolver.h" #include "rust-expr.h" -#include "rust-session-manager.h" -#include "rust-macro-invoc-lexer.h" #include "rust-lex.h" +#include "rust-macro-invoc-lexer.h" +#include "rust-macro.h" #include "rust-parse.h" -#include "rust-early-name-resolver.h" -#include "rust-attribute-visitor.h" +#include "rust-session-manager.h" namespace Rust { namespace { - -/** - * Shorthand function for creating unique_ptr tokens - */ -static std::unique_ptr -make_token (const TokenPtr tok) -{ - return std::unique_ptr (new AST::Token (tok)); -} - -std::unique_ptr -make_string (Location locus, std::string value) -{ - return std::unique_ptr ( - new AST::LiteralExpr (value, AST::Literal::STRING, - PrimitiveCoreType::CORETYPE_STR, {}, locus)); -} - -// TODO: Is this correct? -static AST::Fragment -make_eager_builtin_invocation ( - AST::BuiltinMacro kind, Location locus, AST::DelimTokenTree arguments, - std::vector> &&pending_invocations) +std::string +make_macro_path_str (AST::BuiltinMacro kind) { std::string path_str; @@ -93,6 +75,48 @@ make_eager_builtin_invocation ( break; } + return path_str; +} + +static std::vector> +check_for_eager_invocations ( + std::vector> &expressions) +{ + std::vector> pending; + + for (auto &expr : expressions) + if (expr->get_ast_kind () == AST::Kind::MACRO_INVOCATION) + pending.emplace_back (std::unique_ptr ( + static_cast (expr->clone_expr ().release ()))); + + return pending; +} + +/** + * Shorthand function for creating unique_ptr tokens + */ +static std::unique_ptr +make_token (const TokenPtr tok) +{ + return std::unique_ptr (new AST::Token (tok)); +} + +std::unique_ptr +make_string (Location locus, std::string value) +{ + return std::unique_ptr ( + new AST::LiteralExpr (value, AST::Literal::STRING, + PrimitiveCoreType::CORETYPE_STR, {}, locus)); +} + +// TODO: Is this correct? +static AST::Fragment +make_eager_builtin_invocation ( + AST::BuiltinMacro kind, Location locus, AST::DelimTokenTree arguments, + std::vector> &&pending_invocations) +{ + auto path_str = make_macro_path_str (kind); + std::unique_ptr node = AST::MacroInvocation::Builtin ( kind, AST::MacroInvocData (AST::SimplePath ( @@ -195,8 +219,9 @@ try_expand_many_expr (Parser &parser, and return the LiteralExpr for it. Allow for an optional trailing comma, but otherwise enforce that these are the only tokens. */ -std::unique_ptr -parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree, +std::unique_ptr +parse_single_string_literal (AST::BuiltinMacro kind, + AST::DelimTokenTree &invoc_token_tree, Location invoc_locus, MacroExpander *expander) { MacroInvocLexer lex (invoc_token_tree.to_token_stream ()); @@ -205,6 +230,7 @@ parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree, auto last_token_id = macro_end_token (invoc_token_tree, parser); std::unique_ptr lit_expr = nullptr; + std::unique_ptr macro_invoc = nullptr; if (parser.peek_current_token ()->get_id () == STRING_LITERAL) { @@ -219,11 +245,42 @@ parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree, else if (parser.peek_current_token ()->get_id () == last_token_id) rust_error_at (invoc_locus, "macro takes 1 argument"); else - rust_error_at (invoc_locus, "argument must be a string literal"); + { + macro_invoc = parser.parse_macro_invocation (AST::AttrVec ()); + + parser.maybe_skip_token (COMMA); + if (parser.peek_current_token ()->get_id () != last_token_id) + { + lit_expr = nullptr; + rust_error_at (invoc_locus, "macro takes 1 argument"); + } + + if (macro_invoc != nullptr) + { + auto path_str = make_macro_path_str (kind); + + auto pending_invocations + = std::vector> (); + + pending_invocations.push_back (std::move (macro_invoc)); + + return AST::MacroInvocation::Builtin ( + kind, + AST::MacroInvocData (AST::SimplePath ({AST::SimplePathSegment ( + path_str, invoc_locus)}), + std::move (invoc_token_tree)), + {}, invoc_locus, std::move (pending_invocations)); + } + else + { + rust_error_at (invoc_locus, "argument must be a string literal or a " + "macro which expands to a string"); + } + } parser.skip_token (last_token_id); - return lit_expr; + return std::unique_ptr (std::move (lit_expr)); } /* Treat PATH as a path relative to the source file currently being @@ -278,7 +335,7 @@ load_file_bytes (const char *filename) } // namespace AST::Fragment -MacroBuiltin::assert_handler (Location, AST::MacroInvocData &) +MacroBuiltin::assert_handler (Location invoc_locus, AST::MacroInvocData &invoc) { rust_debug ("assert!() called"); @@ -323,11 +380,14 @@ MacroBuiltin::include_bytes_handler (Location invoc_locus, /* Get target filename from the macro invocation, which is treated as a path relative to the include!-ing file (currently being compiled). */ auto lit_expr - = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, + = parse_single_string_literal (AST::BuiltinMacro::IncludeBytes, + invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) return AST::Fragment::create_error (); + rust_assert (lit_expr->is_literal ()); + std::string target_filename = source_relative_path (lit_expr->as_string (), invoc_locus); @@ -379,11 +439,19 @@ MacroBuiltin::include_str_handler (Location invoc_locus, /* Get target filename from the macro invocation, which is treated as a path relative to the include!-ing file (currently being compiled). */ auto lit_expr - = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, + = parse_single_string_literal (AST::BuiltinMacro::IncludeStr, + invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) return AST::Fragment::create_error (); + if (!lit_expr->is_literal ()) + { + auto token_tree = invoc.get_delim_tok_tree (); + return AST::Fragment ({AST::SingleASTNode (std::move (lit_expr))}, + token_tree.to_token_stream ()); + } + std::string target_filename = source_relative_path (lit_expr->as_string (), invoc_locus); @@ -453,31 +521,20 @@ MacroBuiltin::compile_error_handler (Location invoc_locus, AST::MacroInvocData &invoc) { auto lit_expr - = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, + = parse_single_string_literal (AST::BuiltinMacro::CompileError, + invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) return AST::Fragment::create_error (); + rust_assert (lit_expr->is_literal ()); + std::string error_string = lit_expr->as_string (); rust_error_at (invoc_locus, "%s", error_string.c_str ()); return AST::Fragment::create_error (); } -static std::vector> -check_for_eager_invocations ( - std::vector> &expressions) -{ - std::vector> pending; - - for (auto &expr : expressions) - if (expr->get_ast_kind () == AST::Kind::MACRO_INVOCATION) - pending.emplace_back (std::unique_ptr ( - static_cast (expr->clone_expr ().release ()))); - - return pending; -} - /* Expand builtin macro concat!(), which joins all the literal parameters into a string with no delimiter. */ @@ -707,11 +764,14 @@ MacroBuiltin::include_handler (Location invoc_locus, AST::MacroInvocData &invoc) /* Get target filename from the macro invocation, which is treated as a path relative to the include!-ing file (currently being compiled). */ auto lit_expr - = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus, + = parse_single_string_literal (AST::BuiltinMacro::Include, + invoc.get_delim_tok_tree (), invoc_locus, invoc.get_expander ()); if (lit_expr == nullptr) return AST::Fragment::create_error (); + rust_assert (lit_expr->is_literal ()); + std::string filename = source_relative_path (lit_expr->as_string (), invoc_locus); auto target_filename diff --git a/gcc/testsuite/rust/compile/builtin_macro_eager3.rs b/gcc/testsuite/rust/compile/builtin_macro_eager3.rs new file mode 100644 index 00000000000..3b62cfe7c83 --- /dev/null +++ b/gcc/testsuite/rust/compile/builtin_macro_eager3.rs @@ -0,0 +1,16 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include_str { + () => {{}}; +} + +macro_rules! file1 { + () => { + "builtin_macro_include_str.rs" + }; +} + +fn main () { + include_str!(file1!()); // ok +}