Introduce rust_aggregate_operation
authorTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:27:57 +0000 (07:27 -0700)
committerTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:28:27 +0000 (07:28 -0700)
This adds class rust_aggregate_operation, which implements
OP_AGGREGATE for Rust.

gdb/ChangeLog
2021-03-08  Tom Tromey  <tom@tromey.com>

* rust-lang.c (rust_aggregate_operation::evaluate): New method.
* rust-exp.h (class rust_aggregate_operation): New.

gdb/ChangeLog
gdb/rust-exp.h
gdb/rust-lang.c

index 69a514cf8bc19275f13bb13713ae32ca6fed4baf..ccd8d4601aabfed7182e8ba5e2aa6f1aa1d4e1b6 100644 (file)
@@ -1,3 +1,8 @@
+2021-03-08  Tom Tromey  <tom@tromey.com>
+
+       * rust-lang.c (rust_aggregate_operation::evaluate): New method.
+       * rust-exp.h (class rust_aggregate_operation): New.
+
 2021-03-08  Tom Tromey  <tom@tromey.com>
 
        * rust-lang.c (eval_op_rust_struct_anon, eval_op_rust_structop):
index 19e945c806be9dc940325cedb18d13f1ad5c6608..6e529f8e600149208583c490ebf65815e1aa2565 100644 (file)
@@ -207,6 +207,24 @@ public:
   { return STRUCTOP_STRUCT; }
 };
 
+/* Rust aggregate initialization.  */
+class rust_aggregate_operation
+  : public tuple_holding_operation<struct type *, operation_up,
+                                  std::vector<std::pair<std::string,
+                                                        operation_up>>>
+{
+public:
+
+  using tuple_holding_operation::tuple_holding_operation;
+
+  value *evaluate (struct type *expect_type,
+                  struct expression *exp,
+                  enum noside noside) override;
+
+  enum exp_opcode opcode () const override
+  { return OP_AGGREGATE; }
+};
+
 } /* namespace expr */
 
 #endif /* RUST_EXP_H */
index 1373de94035eeab1c19d10450967c2340bdb852f..3604535209deac43945a3959a7e9f5dcec9ab0d4 100644 (file)
@@ -1700,6 +1700,64 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
   return result;
 }
 
+namespace expr
+{
+
+value *
+rust_aggregate_operation::evaluate (struct type *expect_type,
+                                   struct expression *exp,
+                                   enum noside noside)
+{
+  struct type *type = std::get<0> (m_storage);
+  CORE_ADDR addr = 0;
+  struct value *addrval = NULL;
+  value *result;
+
+  if (noside == EVAL_NORMAL)
+    {
+      addrval = value_allocate_space_in_inferior (TYPE_LENGTH (type));
+      addr = value_as_long (addrval);
+      result = value_at_lazy (type, addr);
+    }
+
+  if (std::get<1> (m_storage) != nullptr)
+    {
+      struct value *init = std::get<1> (m_storage)->evaluate (nullptr, exp,
+                                                             noside);
+
+      if (noside == EVAL_NORMAL)
+       {
+         /* This isn't quite right but will do for the time
+            being, seeing that we can't implement the Copy
+            trait anyway.  */
+         value_assign (result, init);
+       }
+    }
+
+  for (const auto &item : std::get<2> (m_storage))
+    {
+      value *val = item.second->evaluate (nullptr, exp, noside);
+      if (noside == EVAL_NORMAL)
+       {
+         const char *fieldname = item.first.c_str ();
+         value *field = value_struct_elt (&result, nullptr, fieldname,
+                                          nullptr, "structure");
+         value_assign (field, val);
+       }
+    }
+
+  if (noside == EVAL_SKIP)
+    result = value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
+  else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    result = allocate_value (type);
+  else
+    result = value_at_lazy (type, addr);
+
+  return result;
+}
+
+}
+
 /* operator_length implementation for Rust.  */
 
 static void