[112/203] Introduce unop_sizeof_operation

Message ID 20210101214723.1784144-113-tom@tromey.com
State Superseded
Headers show
Series
  • Refactor expressions
Related show

Commit Message

Tom Tromey Jan. 1, 2021, 9:45 p.m.
This adds class unop_sizeof_operation, which implements UNOP_SIZEOF.

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

	* expop.h (class unop_sizeof_operation): New.
	* ax-gdb.c (unop_sizeof_operation::do_generate_ax): New method.
---
 gdb/ChangeLog |  5 +++++
 gdb/ax-gdb.c  | 23 +++++++++++++++++++++++
 gdb/expop.h   | 29 +++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+)

-- 
2.26.2

Patch

diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 64710887534..756f4d7969a 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2491,6 +2491,29 @@  comma_operation::do_generate_ax (struct expression *exp,
   /* It's the consumer's responsibility to trace the right operand.  */
 }
 
+void
+unop_sizeof_operation::do_generate_ax (struct expression *exp,
+				       struct agent_expr *ax,
+				       struct axs_value *value,
+				       struct type *cast_type)
+{
+  /* We don't care about the value of the operand expression; we only
+     care about its type.  However, in the current arrangement, the
+     only way to find an expression's type is to generate code for it.
+     So we generate code for the operand, and then throw it away,
+     replacing it with code that simply pushes its size.  */
+  int start = ax->len;
+
+  std::get<0> (m_storage)->generate_ax (exp, ax, value);
+
+  /* Throw away the code we just generated.  */
+  ax->len = start;
+
+  ax_const_l (ax, TYPE_LENGTH (value->type));
+  value->kind = axs_rvalue;
+  value->type = builtin_type (ax->gdbarch)->builtin_int;
+}
+
 }
 
 /* This handles the middle-to-right-side of code generation for binary
diff --git a/gdb/expop.h b/gdb/expop.h
index 8ddc26d329a..22af0c824e2 100644
--- a/gdb/expop.h
+++ b/gdb/expop.h
@@ -1571,6 +1571,35 @@  class unop_addr_operation
   }
 };
 
+/* Implement 'sizeof'.  */
+class unop_sizeof_operation
+  : public maybe_constant_operation<operation_up>
+{
+public:
+
+  using maybe_constant_operation::maybe_constant_operation;
+
+  value *evaluate (struct type *expect_type,
+		   struct expression *exp,
+		   enum noside noside) override
+  {
+    if (noside == EVAL_SKIP)
+      return eval_skip_value (exp);
+    return std::get<0> (m_storage)->evaluate_for_sizeof (exp, noside);
+  }
+
+  enum exp_opcode opcode () const override
+  { return UNOP_SIZEOF; }
+
+protected:
+
+  void do_generate_ax (struct expression *exp,
+		       struct agent_expr *ax,
+		       struct axs_value *value,
+		       struct type *cast_type)
+    override;
+};
+
 } /* namespace expr */
 
 #endif /* EXPOP_H */