[gcc r14-7660] gccrs: expand: Move derive system to new one

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 17:51:28 GMT 2024


https://gcc.gnu.org/g:f1afcf9fd5e85722766a803dac6c9e6bd90161cc

commit r14-7660-gf1afcf9fd5e85722766a803dac6c9e6bd90161cc
Author: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Date:   Fri Jun 2 11:41:53 2023 +0200

    gccrs: expand: Move derive system to new one
    
    Builtin derive already had their own code scheme, incompatible with the
    proc macro pattern. This commit unifies derive macros with it.
    
    gcc/rust/ChangeLog:
    
            * ast/rust-ast-fragment.cc (Fragment::Fragment): Remove
            overwrite member in constructor.
            (Fragment::operator=): Removal of overwrite member in copy.
            (Fragment::should_overwrite): Remove overwrite getter.
            * ast/rust-ast-fragment.h: Remove overwrite boolean member.
            * expand/rust-expand-visitor.cc (derive_item): Add a function to
            derive items using the expander for now.
            (builtin_derive_item): Rename from derive_item to
            builtin_derive_item.
            (ExpandVisitor::visit): Remove visit to derive attributes.
            (ExpandVisitor::expand_derive): Remove derive attribute visitor.
            (ExpandVisitor::visit_attrs_with_derive): Likewise.
            * expand/rust-expand-visitor.h: Update insertion of other kind
            of proc macros. We no longer have an overwrite attribute in the
            fragment.
            * expand/rust-macro-expand.cc (MacroExpander::parse_procmacro_output):
            Return the fragment instead of inserting it.
            * expand/rust-macro-expand.h (struct MacroExpander): Return
            fragment.
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>

Diff:
---
 gcc/rust/ast/rust-ast-fragment.cc      | 18 ++-----
 gcc/rust/ast/rust-ast-fragment.h       | 10 +---
 gcc/rust/expand/rust-expand-visitor.cc | 87 +++++++++++++---------------------
 gcc/rust/expand/rust-expand-visitor.h  | 12 +----
 gcc/rust/expand/rust-macro-expand.cc   |  9 ++--
 gcc/rust/expand/rust-macro-expand.h    | 15 +++---
 6 files changed, 49 insertions(+), 102 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc
index e5d0ccef9d4..22d2e630748 100644
--- a/gcc/rust/ast/rust-ast-fragment.cc
+++ b/gcc/rust/ast/rust-ast-fragment.cc
@@ -23,8 +23,7 @@ namespace AST {
 
 Fragment::Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes,
 		    std::vector<std::unique_ptr<AST::Token>> tokens)
-  : kind (kind), nodes (std::move (nodes)), tokens (std::move (tokens)),
-    overwrite (true)
+  : kind (kind), nodes (std::move (nodes)), tokens (std::move (tokens))
 {}
 
 Fragment::Fragment (Fragment const &other) : kind (other.get_kind ())
@@ -47,8 +46,6 @@ Fragment::operator= (Fragment const &other)
   for (auto &t : other.tokens)
     tokens.emplace_back (t->clone_token ());
 
-  overwrite = other.overwrite;
-
   return *this;
 }
 
@@ -59,15 +56,14 @@ Fragment::create_error ()
 }
 
 Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
-		    std::vector<std::unique_ptr<AST::Token>> tokens,
-		    bool overwrite)
+		    std::vector<std::unique_ptr<AST::Token>> tokens)
   : kind (FragmentKind::Complete), nodes (std::move (nodes)),
-    tokens (std::move (tokens)), overwrite (overwrite)
+    tokens (std::move (tokens))
 {}
 
 Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
 		    std::unique_ptr<AST::Token> token)
-  : kind (FragmentKind::Complete), nodes (std::move (nodes)), overwrite (true)
+  : kind (FragmentKind::Complete), nodes (std::move (nodes))
 {
   tokens.emplace_back (std::move (token));
 }
@@ -102,12 +98,6 @@ Fragment::should_expand () const
   return !is_error ();
 }
 
-bool
-Fragment::should_overwrite () const
-{
-  return overwrite;
-}
-
 bool
 Fragment::is_expression_fragment () const
 {
diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h
index fe1895f920c..e74632ae055 100644
--- a/gcc/rust/ast/rust-ast-fragment.h
+++ b/gcc/rust/ast/rust-ast-fragment.h
@@ -64,8 +64,7 @@ public:
    * Create a complete AST fragment
    */
   Fragment (std::vector<AST::SingleASTNode> nodes,
-	    std::vector<std::unique_ptr<AST::Token>> tokens,
-	    bool overwrite = true);
+	    std::vector<std::unique_ptr<AST::Token>> tokens);
 
   /**
    * Create a complete AST fragment made of a single token
@@ -79,7 +78,6 @@ public:
 
   bool is_error () const;
   bool should_expand () const;
-  bool should_overwrite () const;
 
   bool is_expression_fragment () const;
   bool is_type_fragment () const;
@@ -111,12 +109,6 @@ private:
    */
   std::vector<std::unique_ptr<AST::Token>> tokens;
 
-  /**
-   * Whether the fragment should overwrite the original content. In most case
-   * it should overwrite it, but not with derive procedural macros.
-   */
-  bool overwrite;
-
   /**
    * We need to make a special case for Expression and Type fragments as only
    * one Node will be extracted from the `nodes` vector
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index cb6c2993354..48c438a4a99 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -128,12 +128,35 @@ get_traits_to_derive (std::vector<AST::Attribute> &outer_attrs)
 }
 
 static std::unique_ptr<AST::Item>
-derive_item (std::unique_ptr<AST::Item> &item, const AST::Attribute &derive,
-	     BuiltinMacro to_derive)
+builtin_derive_item (std::unique_ptr<AST::Item> &item,
+		     const AST::Attribute &derive, BuiltinMacro to_derive)
 {
   return AST::DeriveVisitor::derive (*item, derive, to_derive);
 }
 
+static std::vector<std::unique_ptr<AST::Item>>
+derive_item (std::unique_ptr<AST::Item> &item, std::string &to_derive,
+	     MacroExpander &expander)
+{
+  std::vector<std::unique_ptr<AST::Item>> result;
+  auto frag = expander.expand_derive_proc_macro (item, to_derive);
+  if (!frag.is_error ())
+    {
+      for (auto &node : frag.get_nodes ())
+	{
+	  switch (node.get_kind ())
+	    {
+	    case AST::SingleASTNode::ITEM:
+	      result.push_back (node.take_item ());
+	      break;
+	    default:
+	      gcc_unreachable ();
+	    }
+	}
+    }
+  return result;
+}
+
 void
 ExpandVisitor::expand_inner_items (
   std::vector<std::unique_ptr<AST::Item>> &items)
@@ -157,11 +180,17 @@ ExpandVisitor::expand_inner_items (
 	      if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
 		{
 		  auto new_item
-		    = derive_item (item, attr, maybe_builtin->second);
+		    = builtin_derive_item (item, attr, maybe_builtin->second);
 		  // this inserts the derive *before* the item - is it a
 		  // problem?
 		  it = items.insert (it, std::move (new_item));
 		}
+	      else
+		{
+		  auto new_items = derive_item (item, name, expander);
+		  std::move (new_items.begin (), new_items.end (),
+			     std::inserter (items, it));
+		}
 	    }
 	}
     }
@@ -1005,7 +1034,6 @@ ExpandVisitor::visit (AST::TypeAlias &type_alias)
 void
 ExpandVisitor::visit (AST::StructStruct &struct_item)
 {
-  visit_attrs_with_derive (struct_item);
   visit_outer_attrs (struct_item);
   for (auto &generic : struct_item.get_generic_params ())
     visit (generic);
@@ -1020,7 +1048,6 @@ void
 ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
 {
   visit_outer_attrs (tuple_struct);
-  visit_attrs_with_derive (tuple_struct);
   for (auto &generic : tuple_struct.get_generic_params ())
     visit (generic);
 
@@ -1057,7 +1084,6 @@ ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
 void
 ExpandVisitor::visit (AST::Enum &enum_item)
 {
-  visit_attrs_with_derive (enum_item);
   visit_outer_attrs (enum_item);
   for (auto &generic : enum_item.get_generic_params ())
     visit (generic);
@@ -1069,7 +1095,6 @@ ExpandVisitor::visit (AST::Enum &enum_item)
 void
 ExpandVisitor::visit (AST::Union &union_item)
 {
-  visit_attrs_with_derive (union_item);
   visit_outer_attrs (union_item);
   for (auto &generic : union_item.get_generic_params ())
     visit (generic);
@@ -1619,52 +1644,4 @@ ExpandVisitor::visit_inner_attrs (T &item)
   visit_inner_using_attrs (item, item.get_inner_attrs ());
 }
 
-template <typename T>
-void
-ExpandVisitor::expand_derive (T &item, std::unique_ptr<AST::TokenTree> trait)
-{
-  auto trait_name = trait->as_string ();
-  expander.expand_derive_proc_macro (item, trait_name);
-}
-
-template <typename T>
-void
-ExpandVisitor::expand_derive (T &item, AST::DelimTokenTree &attr)
-{
-  // Item is const because even though the tokenstream might be modified, it
-  // should appear as the same input for every derive proc macro.
-  auto &trees = attr.get_token_trees ();
-  if (trees.size () > 2)
-    {
-      // Skipping begin and end parenthesis
-      for (auto it = trees.begin () + 1; it < trees.end () - 1;
-	   it += 2 /* Increment + skip comma */)
-	{
-	  expand_derive (item, std::move (*it));
-	}
-    }
-}
-
-template <typename T>
-void
-ExpandVisitor::visit_attrs_with_derive (T &item)
-{
-  auto &attrs = item.get_outer_attrs ();
-  for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
-    {
-      auto current = *it;
-
-      if (!is_builtin (current) && is_derive (current))
-	{
-	  it = attrs.erase (it);
-	  // Downcasting checked in is_derive
-	  expand_derive (item, static_cast<AST::DelimTokenTree &> (
-				 current.get_attr_input ()));
-	}
-      else // Skip unknwown
-	{
-	  it++;
-	}
-    }
-}
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index 0dd5c9a21d1..d86f0d03856 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -146,10 +146,7 @@ public:
 	  }
 	else if (proc_macro_fragment.should_expand ())
 	  {
-	    if (proc_macro_fragment.should_overwrite ())
-	      it = values.erase (it);
-	    else
-	      it++;
+	    it = values.erase (it);
 	    for (auto &node : proc_macro_fragment.get_nodes ())
 	      {
 		auto new_node = extractor (node);
@@ -383,13 +380,6 @@ public:
 
   template <typename T> void visit_inner_attrs (T &item);
 
-  template <typename T>
-  void expand_derive (T &item, std::unique_ptr<AST::TokenTree> trait);
-
-  template <typename T> void expand_derive (T &item, AST::DelimTokenTree &attr);
-
-  template <typename T> void visit_attrs_with_derive (T &item);
-
 private:
   MacroExpander &expander;
 };
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index cb9f8166909..47384dfffde 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -1096,8 +1096,8 @@ MacroExpander::import_proc_macros (std::string extern_crate)
     }
 }
 
-void
-MacroExpander::parse_procmacro_output (ProcMacro::TokenStream ts, bool derive)
+AST::Fragment
+MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
 {
   ProcMacroInvocLexer lex (convert (ts));
   Parser<ProcMacroInvocLexer> parser (lex);
@@ -1133,10 +1133,9 @@ MacroExpander::parse_procmacro_output (ProcMacro::TokenStream ts, bool derive)
     }
 
   if (parser.has_errors ())
-    set_expanded_proc_macro_fragment (AST::Fragment::create_error ());
+    return AST::Fragment::create_error ();
   else
-    set_expanded_proc_macro_fragment (
-      {nodes, std::vector<std::unique_ptr<AST::Token>> (), !derive});
+    return {nodes, std::vector<std::unique_ptr<AST::Token>> ()};
 }
 
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 588b1c8461e..4274c124a25 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -357,7 +357,7 @@ struct MacroExpander
   void import_proc_macros (std::string extern_crate);
 
   template <typename T>
-  void expand_derive_proc_macro (T &item, std::string &trait_name)
+  AST::Fragment expand_derive_proc_macro (T &item, std::string &trait_name)
   {
     ProcMacro::CustomDerive macro;
 
@@ -387,11 +387,11 @@ struct MacroExpander
     auto c = collector.collect_tokens ();
     std::vector<const_TokenPtr> vec (c.cbegin (), c.cend ());
 
-    parse_procmacro_output (macro.macro (convert (vec)), true);
+    return parse_proc_macro_output (macro.macro (convert (vec)));
   }
 
   template <typename T>
-  void expand_bang_proc_macro (T &item, AST::SimplePath &path)
+  AST::Fragment expand_bang_proc_macro (T &item, AST::SimplePath &path)
   {
     ProcMacro::Bang macro;
 
@@ -419,7 +419,7 @@ struct MacroExpander
     auto c = collector.collect_tokens ();
     std::vector<const_TokenPtr> vec (c.cbegin (), c.cend ());
 
-    parse_procmacro_output (macro.macro (convert (vec)), false);
+    return parse_proc_macro_output (macro.macro (convert (vec)));
   }
 
   template <typename T>
@@ -453,9 +453,8 @@ struct MacroExpander
     std::vector<const_TokenPtr> vec (c.cbegin (), c.cend ());
 
     // FIXME: Handle attributes
-    parse_procmacro_output (
-      macro.macro (ProcMacro::TokenStream::make_tokenstream (), convert (vec)),
-      false);
+    parse_proc_macro_output (
+      macro.macro (ProcMacro::TokenStream::make_tokenstream (), convert (vec)));
   }
 
   /**
@@ -473,7 +472,7 @@ struct MacroExpander
   AST::MacroInvocation *get_last_invocation () { return last_invoc; }
 
 private:
-  void parse_procmacro_output (ProcMacro::TokenStream ts, bool derive);
+  AST::Fragment parse_proc_macro_output (ProcMacro::TokenStream ts);
 
   AST::Crate &crate;
   Session &session;


More information about the Gcc-cvs mailing list