From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

Struct fields can have outer attributes on their field for various
purpose, this behavior should be reflected upon struct expr fields.

gcc/rust/ChangeLog:

        * ast/rust-ast-collector.cc (TokenCollector::visit): Output field
        attributes.
        * ast/rust-expr.h (class StructExprField): Add outer attributes member.
        * parse/rust-parse-impl.h (Parser::parse_struct_expr_field): Parse
        outer attributes and store them in the appropriate AST node.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
---
 gcc/rust/ast/rust-ast-collector.cc |  9 ++----
 gcc/rust/ast/rust-expr.h           | 44 +++++++++++++++++++++++-------
 gcc/rust/parse/rust-parse-impl.h   |  5 ++++
 3 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index a75722587f5..d43aef80760 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1099,8 +1099,7 @@ TokenCollector::visit (StructExprStruct &expr)
 void
 TokenCollector::visit (StructExprFieldIdentifier &expr)
 {
-  // TODO: Add attributes
-  // visit_items_as_lines (expr.get_attrs ());
+  visit_items_as_lines (expr.get_outer_attrs ());
   auto id = expr.get_field_name ().as_string ();
   push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
 }
@@ -1108,8 +1107,7 @@ TokenCollector::visit (StructExprFieldIdentifier &expr)
 void
 TokenCollector::visit (StructExprFieldIdentifierValue &expr)
 {
-  // TODO: Add attributes
-  // visit_items_as_lines (expr.get_attrs ());
+  visit_items_as_lines (expr.get_outer_attrs ());
   auto id = expr.get_field_name ();
   push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
   push (Rust::Token::make (COLON, UNDEF_LOCATION));
@@ -1119,8 +1117,7 @@ TokenCollector::visit (StructExprFieldIdentifierValue 
&expr)
 void
 TokenCollector::visit (StructExprFieldIndexValue &expr)
 {
-  // TODO: Add attributes
-  // visit_items_as_lines (expr.get_attrs ());
+  visit_items_as_lines (expr.get_outer_attrs ());
   push (Rust::Token::make_int (expr.get_locus (),
                               std::to_string (expr.get_index ())));
   push (Rust::Token::make (COLON, UNDEF_LOCATION));
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index c3b93d4dc0d..50c0cb146ed 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -1758,6 +1758,13 @@ public:
 
   NodeId get_node_id () const { return node_id; }
 
+  const std::vector<AST::Attribute> &get_outer_attrs () const
+  {
+    return outer_attrs;
+  }
+
+  std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
+
 protected:
   // pure virtual clone implementation
   virtual StructExprField *clone_struct_expr_field_impl () const = 0;
@@ -1765,6 +1772,12 @@ protected:
   StructExprField () : node_id (Analysis::Mappings::get ().get_next_node_id ())
   {}
 
+  StructExprField (AST::AttrVec outer_attrs)
+    : outer_attrs (std::move (outer_attrs)),
+      node_id (Analysis::Mappings::get ().get_next_node_id ())
+  {}
+
+  AST::AttrVec outer_attrs;
   NodeId node_id;
 };
 
@@ -1775,9 +1788,10 @@ class StructExprFieldIdentifier : public StructExprField
   location_t locus;
 
 public:
-  StructExprFieldIdentifier (Identifier field_identifier, location_t locus)
-    : StructExprField (), field_name (std::move (field_identifier)),
-      locus (locus)
+  StructExprFieldIdentifier (Identifier field_identifier,
+                            AST::AttrVec outer_attrs, location_t locus)
+    : StructExprField (std::move (outer_attrs)),
+      field_name (std::move (field_identifier)), locus (locus)
   {}
 
   std::string as_string () const override { return field_name.as_string (); }
@@ -1804,19 +1818,22 @@ class StructExprFieldWithVal : public StructExprField
   std::unique_ptr<Expr> value;
 
 protected:
-  StructExprFieldWithVal (std::unique_ptr<Expr> field_value)
-    : StructExprField (), value (std::move (field_value))
+  StructExprFieldWithVal (std::unique_ptr<Expr> field_value,
+                         AST::AttrVec outer_attrs)
+    : StructExprField (std::move (outer_attrs)), value (std::move 
(field_value))
   {}
 
   // Copy constructor requires clone
   StructExprFieldWithVal (StructExprFieldWithVal const &other)
-    : value (other.value->clone_expr ())
+    : StructExprField (other.get_outer_attrs ()),
+      value (other.value->clone_expr ())
   {}
 
   // Overload assignment operator to clone unique_ptr
   StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other)
   {
     value = other.value->clone_expr ();
+    outer_attrs = other.get_outer_attrs ();
 
     return *this;
   }
@@ -1843,10 +1860,17 @@ class StructExprFieldIdentifierValue : public 
StructExprFieldWithVal
   location_t locus;
 
 public:
+  StructExprFieldIdentifierValue (Identifier field_identifier,
+                                 std::unique_ptr<Expr> field_value,
+                                 AST::AttrVec outer_attrs, location_t locus)
+    : StructExprFieldWithVal (std::move (field_value), std::move 
(outer_attrs)),
+      field_name (std::move (field_identifier)), locus (locus)
+  {}
+
   StructExprFieldIdentifierValue (Identifier field_identifier,
                                  std::unique_ptr<Expr> field_value,
                                  location_t locus)
-    : StructExprFieldWithVal (std::move (field_value)),
+    : StructExprFieldWithVal (std::move (field_value), {}),
       field_name (std::move (field_identifier)), locus (locus)
   {}
 
@@ -1876,9 +1900,9 @@ class StructExprFieldIndexValue : public 
StructExprFieldWithVal
 public:
   StructExprFieldIndexValue (TupleIndex tuple_index,
                             std::unique_ptr<Expr> field_value,
-                            location_t locus)
-    : StructExprFieldWithVal (std::move (field_value)), index (tuple_index),
-      locus (locus)
+                            AST::AttrVec outer_attrs, location_t locus)
+    : StructExprFieldWithVal (std::move (field_value), std::move 
(outer_attrs)),
+      index (tuple_index), locus (locus)
   {}
 
   std::string as_string () const override;
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 6eb19551980..e2a9b199a9b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -11699,6 +11699,7 @@ template <typename ManagedTokenSource>
 std::unique_ptr<AST::StructExprField>
 Parser<ManagedTokenSource>::parse_struct_expr_field ()
 {
+  AST::AttrVec outer_attrs = parse_outer_attributes ();
   const_TokenPtr t = lexer.peek_token ();
   switch (t->get_id ())
     {
@@ -11724,6 +11725,7 @@ Parser<ManagedTokenSource>::parse_struct_expr_field ()
          return std::unique_ptr<AST::StructExprFieldIdentifierValue> (
            new AST::StructExprFieldIdentifierValue (std::move (ident),
                                                     std::move (expr),
+                                                    std::move (outer_attrs),
                                                     t->get_locus ()));
        }
       else
@@ -11734,6 +11736,7 @@ Parser<ManagedTokenSource>::parse_struct_expr_field ()
 
          return std::unique_ptr<AST::StructExprFieldIdentifier> (
            new AST::StructExprFieldIdentifier (std::move (ident),
+                                               std::move (outer_attrs),
                                                t->get_locus ()));
        }
       case INT_LITERAL: {
@@ -11761,6 +11764,7 @@ Parser<ManagedTokenSource>::parse_struct_expr_field ()
 
        return std::unique_ptr<AST::StructExprFieldIndexValue> (
          new AST::StructExprFieldIndexValue (index, std::move (expr),
+                                             std::move (outer_attrs),
                                              t->get_locus ()));
       }
     case DOT_DOT:
@@ -14082,6 +14086,7 @@ 
Parser<ManagedTokenSource>::parse_struct_expr_struct_partial (
       /* technically this would give a struct base-only struct, but this
        * algorithm should work too. As such, AST type not happening. */
     case IDENTIFIER:
+    case HASH:
       case INT_LITERAL: {
        // struct with struct expr fields
 
-- 
2.45.2

Reply via email to