aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/ast/rust-expr.h11
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc38
2 files changed, 47 insertions, 2 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index adf9b68..2791a8c 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2487,6 +2487,17 @@ public:
return expr;
}
+ std::unique_ptr<Expr> take_tail_expr ()
+ {
+ rust_assert (has_tail_expr ());
+ return std::move (expr);
+ }
+
+ void set_tail_expr (std::unique_ptr<Expr> expr)
+ {
+ this->expr = std::move (expr);
+ }
+
// Removes the tail expression from the block.
void strip_tail_expr () { expr = nullptr; }
// Normalizes a trailing statement without a semicolon to a tail expression.
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index e9eefdb..6df9f7c 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -149,9 +149,9 @@ expand_item_attribute (AST::Item &item, AST::SimplePath &name,
return result;
}
+template <typename T>
static std::vector<std::unique_ptr<AST::Stmt>>
-expand_stmt_attribute (AST::Item &item, AST::SimplePath &name,
- MacroExpander &expander)
+expand_stmt_attribute (T &item, AST::SimplePath &name, MacroExpander &expander)
{
std::vector<std::unique_ptr<AST::Stmt>> result;
auto frag = expander.expand_attribute_proc_macro (item, name);
@@ -173,6 +173,39 @@ expand_stmt_attribute (AST::Item &item, AST::SimplePath &name,
}
void
+expand_tail_expr (AST::BlockExpr &item, MacroExpander &expander)
+{
+ if (item.has_tail_expr ())
+ {
+ auto tail = item.take_tail_expr ();
+ auto attrs = tail->get_outer_attrs ();
+ bool changed = false;
+ for (auto it = attrs.begin (); it != attrs.end ();)
+ {
+ auto current = *it;
+ if (is_builtin (current))
+ {
+ it++;
+ }
+ else
+ {
+ it = attrs.erase (it);
+ changed = true;
+ auto new_stmts
+ = expand_stmt_attribute (item, current.get_path (), expander);
+ auto &stmts = item.get_statements ();
+ std::move (new_stmts.begin (), new_stmts.end (),
+ std::inserter (stmts, stmts.end ()));
+ }
+ }
+ if (changed)
+ item.strip_tail_expr ();
+ else
+ item.set_tail_expr (std::move (tail));
+ }
+}
+
+void
ExpandVisitor::expand_inner_items (
std::vector<std::unique_ptr<AST::Item>> &items)
{
@@ -799,6 +832,7 @@ ExpandVisitor::visit (AST::BlockExpr &expr)
{
expand_inner_stmts (expr.get_statements ());
+ expand_tail_expr (expr, expander);
if (expr.has_tail_expr ())
maybe_expand_expr (expr.get_tail_expr ());
}