aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/expand/rust-macro-builtins-include.cc
diff options
context:
space:
mode:
authorLiam Naddell <liam.naddell@mail.utoronto.ca>2024-07-27 00:28:13 -0400
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-19 15:32:03 +0100
commitad3fc42abd84b7fc40e78c3a83b883c9b83af22d (patch)
tree784787bf6a0b18a86499203c61dbdb93ee32aa06 /gcc/rust/expand/rust-macro-builtins-include.cc
parent86970cc56e6d3521a815ce7e3bf14071ce61ff98 (diff)
downloadgcc-ad3fc42abd84b7fc40e78c3a83b883c9b83af22d.zip
gcc-ad3fc42abd84b7fc40e78c3a83b883c9b83af22d.tar.gz
gcc-ad3fc42abd84b7fc40e78c3a83b883c9b83af22d.tar.bz2
gccrs: Eager expansion for include* gccrs#1805 gccrs#1865
gcc/rust/ChangeLog: * expand/rust-expand-visitor.h: remove auto keyword * expand/rust-macro-builtins-helpers.cc: allow for changing macro invoc types on eager expansions to semicoloned macros * expand/rust-macro-builtins-helpers.h: add default semicoloned argument * expand/rust-macro-builtins-include.cc: allow for eager expansion for include and include_bytes allow for parsing include invocations as items instead of expressions, which allows invocations at global scope * expand/rust-macro-expand.cc: push Expr type for eager invocations gcc/testsuite/ChangeLog: * rust/compile/macros/builtin/include1.rs: add basic include test at global scope * rust/compile/macros/builtin/include2.rs: add basic include test at local scope with expression * rust/compile/macros/builtin/include3.rs: add eager expansion test at global scope * rust/compile/macros/builtin/include4.rs: add eager expansion test at local scope with expression * rust/compile/macros/builtin/include_bytes.rs: add eager expansion test at global scope * rust/compile/macros/builtin/include_rs: supporting test file with dummy function * rust/compile/macros/builtin/include_rs2: supporting test file with dummy string * rust/compile/macros/builtin/include_str.rs: add eager expansion test at global scope * rust/execute/torture/builtin_macro_include_bytes.rs: clean up old test logic, add permutations for eager expansion * rust/execute/torture/builtin_macro_include_str.rs: add eager expansion permutations
Diffstat (limited to 'gcc/rust/expand/rust-macro-builtins-include.cc')
-rw-r--r--gcc/rust/expand/rust-macro-builtins-include.cc54
1 files changed, 45 insertions, 9 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins-include.cc b/gcc/rust/expand/rust-macro-builtins-include.cc
index cf3f93d..4719b0e 100644
--- a/gcc/rust/expand/rust-macro-builtins-include.cc
+++ b/gcc/rust/expand/rust-macro-builtins-include.cc
@@ -40,7 +40,12 @@ MacroBuiltin::include_bytes_handler (location_t invoc_locus,
if (lit_expr == nullptr)
return AST::Fragment::create_error ();
- rust_assert (lit_expr->is_literal ());
+ 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);
@@ -188,16 +193,36 @@ MacroBuiltin::include_handler (location_t invoc_locus,
AST::MacroInvocData &invoc,
AST::InvocKind semicolon)
{
+ bool is_semicoloned = semicolon == AST::InvocKind::Semicoloned;
/* 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
+ std::unique_ptr<AST::Expr> lit_expr
= parse_single_string_literal (BuiltinMacro::Include,
invoc.get_delim_tok_tree (), invoc_locus,
- invoc.get_expander ());
+ invoc.get_expander (), is_semicoloned);
if (lit_expr == nullptr)
return AST::Fragment::create_error ();
- rust_assert (lit_expr->is_literal ());
+ if (!lit_expr->is_literal ())
+ {
+ // We have to expand an inner macro eagerly
+ auto token_tree = invoc.get_delim_tok_tree ();
+
+ // parse_single_string_literal returned an AST::MacroInvocation, which
+ // can either be an AST::Item or AST::Expr. Depending on the context the
+ // original macro was invoked in, we will set AST::Item or AST::Expr
+ // appropriately.
+ if (is_semicoloned)
+ {
+ std::unique_ptr<AST::Item> lit_item = std::unique_ptr<AST::Item> (
+ static_cast<AST::MacroInvocation *> (lit_expr.release ()));
+ return AST::Fragment ({AST::SingleASTNode (std::move (lit_item))},
+ token_tree.to_token_stream ());
+ }
+ else
+ return AST::Fragment ({AST::SingleASTNode (std::move (lit_expr))},
+ token_tree.to_token_stream ());
+ }
std::string filename
= source_relative_path (lit_expr->as_string (), invoc_locus);
@@ -218,8 +243,14 @@ MacroBuiltin::include_handler (location_t invoc_locus,
Lexer lex (target_filename, std::move (target_file), linemap);
Parser<Lexer> parser (lex);
+ std::unique_ptr<AST::Expr> parsed_expr = nullptr;
+ std::vector<std::unique_ptr<AST::Item>> parsed_items{};
+
+ if (is_semicoloned)
+ parsed_items = parser.parse_items ();
+ else
+ parsed_expr = parser.parse_expr ();
- auto parsed_items = parser.parse_items ();
bool has_error = !parser.get_errors ().empty ();
for (const auto &error : parser.get_errors ())
@@ -233,17 +264,22 @@ MacroBuiltin::include_handler (location_t invoc_locus,
}
std::vector<AST::SingleASTNode> nodes{};
- for (auto &item : parsed_items)
+ if (is_semicoloned)
+ for (auto &item : parsed_items)
+ {
+ AST::SingleASTNode node (std::move (item));
+ nodes.push_back (node);
+ }
+ else
{
- AST::SingleASTNode node (std::move (item));
+ AST::SingleASTNode node (std::move (parsed_expr));
nodes.push_back (node);
}
-
// FIXME: This returns an empty vector of tokens and works fine, but is that
// the expected behavior? `include` macros are a bit harder to reason about
// since they include tokens. Furthermore, our lexer has no easy way to return
// a slice of tokens like the MacroInvocLexer. So it gets even harder to
- // extrac tokens from here. For now, let's keep it that way and see if it
+ // extract tokens from here. For now, let's keep it that way and see if it
// eventually breaks, but I don't expect it to cause many issues since the
// list of tokens is only used when a macro invocation mixes eager
// macro invocations and already expanded tokens. Think