]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: expand: Move derive system to new one
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Fri, 2 Jun 2023 09:41:53 +0000 (11:41 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:26 +0000 (18:46 +0100)
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>
gcc/rust/ast/rust-ast-fragment.cc
gcc/rust/ast/rust-ast-fragment.h
gcc/rust/expand/rust-expand-visitor.cc
gcc/rust/expand/rust-expand-visitor.h
gcc/rust/expand/rust-macro-expand.cc
gcc/rust/expand/rust-macro-expand.h

index e5d0ccef9d4def18bd15a0b7f5ecaefa6fe5603c..22d2e6307488e9d4fdb31256772373184089fcfe 100644 (file)
@@ -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
 {
index fe1895f920cbcc535c78c0a69f04586036c0252d..e74632ae05562e28e3ed8a4ec71d84d7b5c51cc2 100644 (file)
@@ -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
index cb6c2993354090832240909689685a40c38268e8..48c438a4a99569d86e051ad57abbb009b77c319a 100644 (file)
@@ -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
index 0dd5c9a21d198ffc3f3d664172ad7adfc0379766..d86f0d03856a90baefd0ee2d85971ef10d7d248d 100644 (file)
@@ -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;
 };
index cb9f81669099c43e097a02bf3ea46d59deaf16a5..47384dfffdeb7cb1b06f705485b6f93d9c73e4cd 100644 (file)
@@ -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
index 588b1c8461e6cbf8b54ae7b4f4a52dbf0828a0a0..4274c124a25a3f42f1e4a2c7728339c46921e8e6 100644 (file)
@@ -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;