public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] expand: further improves the handling of recursive macros ...
@ 2022-07-29 14:44 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-07-29 14:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5e63ca064ab52d026112166fd1b6601c61591778

commit 5e63ca064ab52d026112166fd1b6601c61591778
Author: liushuyu <liushuyu011@gmail.com>
Date:   Thu Jul 28 01:37:07 2022 -0600

    expand: further improves the handling of recursive macros ...
    
    ... now all the attribute visitor that expands the
    macro fragment will recursively expand the macro
    using the unified expanding function
    `expand_macro_fragment_recursive` instead of expanding
    the fragment only once.
    
    Signed-off-by: Zixing Liu <liushuyu011@gmail.com>

Diff:
---
 gcc/rust/expand/rust-attribute-visitor.cc          | 27 +++++---------
 gcc/rust/expand/rust-attribute-visitor.h           | 42 ++++++++++++++++++++--
 .../rust/compile/torture/macro-issue1403.rs        | 23 ++++++++++++
 3 files changed, 71 insertions(+), 21 deletions(-)

diff --git a/gcc/rust/expand/rust-attribute-visitor.cc b/gcc/rust/expand/rust-attribute-visitor.cc
index bbcf2cbadd0..8016f9430eb 100644
--- a/gcc/rust/expand/rust-attribute-visitor.cc
+++ b/gcc/rust/expand/rust-attribute-visitor.cc
@@ -1122,12 +1122,12 @@ AttrVisitor::visit (AST::CallExpr &expr)
 
       stmt->accept_vis (*this);
 
-      auto fragment = expander.take_expanded_fragment (*this);
-      if (fragment.should_expand ())
+      auto final_fragment = expand_macro_fragment_recursive ();
+      if (final_fragment.should_expand ())
 	{
 	  // Remove the current expanded invocation
 	  it = params.erase (it);
-	  for (auto &node : fragment.get_nodes ())
+	  for (auto &node : final_fragment.get_nodes ())
 	    {
 	      it = params.insert (it, node.take_expr ());
 	      it++;
@@ -3430,25 +3430,16 @@ AttrVisitor::visit (AST::BareFunctionType &type)
 void
 AttrVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
 {
-  auto fragment = expander.take_expanded_fragment (*this);
-  unsigned int original_depth = expander.expansion_depth;
-  while (fragment.should_expand ())
-    {
-      expr = fragment.take_expression_fragment ();
-      expander.expansion_depth++;
-      auto new_fragment = expander.take_expanded_fragment (*this);
-      if (new_fragment.is_error ())
-	break;
-      fragment = std::move (new_fragment);
-    }
-  expander.expansion_depth = original_depth;
+  auto final_fragment = expand_macro_fragment_recursive ();
+  if (final_fragment.should_expand ())
+    expr = final_fragment.take_expression_fragment ();
 }
 
 void
 AttrVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
 {
-  auto fragment = expander.take_expanded_fragment (*this);
-  if (fragment.should_expand ())
-    type = fragment.take_type_fragment ();
+  auto final_fragment = expand_macro_fragment_recursive ();
+  if (final_fragment.should_expand ())
+    type = final_fragment.take_type_fragment ();
 }
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-attribute-visitor.h b/gcc/rust/expand/rust-attribute-visitor.h
index 02208c6a7c7..0f9d1065334 100644
--- a/gcc/rust/expand/rust-attribute-visitor.h
+++ b/gcc/rust/expand/rust-attribute-visitor.h
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-ast-visitor.h"
+#include "rust-ast.h"
 #include "rust-macro-expand.h"
 
 namespace Rust {
@@ -42,6 +43,39 @@ public:
   void expand_trait_function_decl (AST::TraitFunctionDecl &decl);
   void expand_trait_method_decl (AST::TraitMethodDecl &decl);
 
+  /**
+   * Expand The current macro fragment recursively until it could not be
+   * expanded further.
+   *
+   * The return value checking works because correctly
+   * expanded fragment can never be an error (if the fragment can not be
+   * expanded, a stand-in error fragment will be returned; for fragments that
+   * could not be further expanded: the fragment prior to the expansion failure
+   * will be returned).
+   *
+   * @return Either the expanded fragment or an empty errored-out fragment
+   * indicating an expansion failure.
+   */
+  AST::ASTFragment expand_macro_fragment_recursive ()
+  {
+    auto fragment = expander.take_expanded_fragment (*this);
+    unsigned int original_depth = expander.expansion_depth;
+    auto final_fragment = AST::ASTFragment ({}, true);
+
+    while (fragment.should_expand ())
+      {
+	final_fragment = std::move (fragment);
+	expander.expansion_depth++;
+	// further expand the previously expanded macro fragment
+	auto new_fragment = expander.take_expanded_fragment (*this);
+	if (new_fragment.is_error ())
+	  break;
+	fragment = std::move (new_fragment);
+      }
+    expander.expansion_depth = original_depth;
+    return final_fragment;
+  }
+
   /**
    * Expand a set of values, erasing them if they are marked for strip, and
    * replacing them with expanded macro nodes if necessary.
@@ -67,11 +101,13 @@ public:
 	// mark for stripping if required
 	value->accept_vis (*this);
 
-	auto fragment = expander.take_expanded_fragment (*this);
-	if (fragment.should_expand ())
+	// recursively expand the children
+	auto final_fragment = expand_macro_fragment_recursive ();
+
+	if (final_fragment.should_expand ())
 	  {
 	    it = values.erase (it);
-	    for (auto &node : fragment.get_nodes ())
+	    for (auto &node : final_fragment.get_nodes ())
 	      {
 		auto new_node = extractor (node);
 		if (new_node != nullptr && !new_node->is_marked_for_strip ())
diff --git a/gcc/testsuite/rust/compile/torture/macro-issue1403.rs b/gcc/testsuite/rust/compile/torture/macro-issue1403.rs
new file mode 100644
index 00000000000..7fe6c51053c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/macro-issue1403.rs
@@ -0,0 +1,23 @@
+macro_rules! stmt {
+    ($s:stmt) => {
+        $s
+    };
+    ($s:stmt, $($ss:stmt),*) => {
+        $s;
+        stmt!($($ss),*);
+    };
+}
+
+fn main() {
+    stmt!(
+        struct S;
+    );
+    stmt!(
+        struct A;,
+        struct B;,
+        struct C;,
+        struct D;,
+        struct E;
+    );
+}
+


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-29 14:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-29 14:44 [gcc/devel/rust/master] expand: further improves the handling of recursive macros Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).