]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Introduce and use operation::type_p
authorTom Tromey <tromey@adacore.com>
Wed, 18 Sep 2024 16:25:13 +0000 (10:25 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 1 Oct 2024 19:25:25 +0000 (13:25 -0600)
There's currently code in gdb that checks if an expression evaluates
to a type.  In some spots this is done by comparing the opcode against
OP_TYPE, but other spots more correctly also compare with OP_TYPEOF
and OP_DECLTYPE.

This patch cleans up this area, replacing opcode-checking with a new
method on 'operation'.

Generally, checking the opcode should be considered deprecated,
although it's unfortunately difficult to get rid of opcodes entirely.

I also took advantage of this change to turn eval_op_type into a
method, removing a bit of indirection.

Reviewed-by: Keith Seitz <keiths@redhat.com>
gdb/ada-lang.c
gdb/dtrace-probe.c
gdb/eval.c
gdb/expop.h
gdb/expression.h
gdb/typeprint.c
gdb/varobj.c

index 9b61f19b072f061de526dc4834453c8323d34915..2ea7fd2a848f828e1d4ee2e13d963d454b29be36 100644 (file)
@@ -10772,7 +10772,7 @@ ada_unop_atr_operation::evaluate (struct type *expect_type,
   struct type *type_arg = nullptr;
   value *val = nullptr;
 
-  if (std::get<0> (m_storage)->opcode () == OP_TYPE)
+  if (std::get<0> (m_storage)->type_p ())
     {
       value *tem = std::get<0> (m_storage)->evaluate (nullptr, exp,
                                                      EVAL_AVOID_SIDE_EFFECTS);
index 0f4e1643483f1fc11f4e3856078dcf7f196197b3..ac1b1c5ef13f299c1675ddad4589f4bd6a2ec7c0 100644 (file)
@@ -493,7 +493,7 @@ dtrace_process_dof_probe (struct objfile *objfile,
            {
            }
 
-         if (expr != NULL && expr->first_opcode () == OP_TYPE)
+         if (expr != NULL && expr->type_p ())
            type = expr->evaluate_type ()->type ();
 
          args.emplace_back (type, std::move (type_str), std::move (expr));
index bbf4375f1d3caf2b91731c6d5cd9bc22748b8c7e..3929282da769576dad29709eccbd460af1619b48 100644 (file)
@@ -1872,18 +1872,21 @@ eval_op_postdec (struct type *expect_type, struct expression *exp,
     }
 }
 
-/* A helper function for OP_TYPE.  */
+namespace expr
+{
 
 struct value *
-eval_op_type (struct type *expect_type, struct expression *exp,
-             enum noside noside, struct type *type)
+type_operation::evaluate (struct type *expect_type, struct expression *exp,
+                         enum noside noside)
 {
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
-    return value::allocate (type);
+    return value::allocate (std::get<0> (m_storage));
   else
     error (_("Attempt to use a type name as an expression"));
 }
 
+}
+
 /* A helper function for BINOP_ASSIGN_MODIFY.  */
 
 struct value *
index 2d46a9dad6a75824ad5109115fad98c9a2a84770..af031f53133244e773d719983efe3a2088d0545a 100644 (file)
@@ -172,9 +172,6 @@ extern struct value *eval_op_ind (struct type *expect_type,
                                  struct expression *exp,
                                  enum noside noside,
                                  struct value *arg1);
-extern struct value *eval_op_type (struct type *expect_type,
-                                  struct expression *exp,
-                                  enum noside noside, struct type *type);
 extern struct value *eval_op_alignof (struct type *expect_type,
                                      struct expression *exp,
                                      enum noside noside,
@@ -1560,16 +1557,16 @@ public:
 
   value *evaluate (struct type *expect_type,
                   struct expression *exp,
-                  enum noside noside) override
-  {
-    return eval_op_type (expect_type, exp, noside, std::get<0> (m_storage));
-  }
+                  enum noside noside) override;
 
   enum exp_opcode opcode () const override
   { return OP_TYPE; }
 
   bool constant_p () const override
   { return true; }
+
+  bool type_p () const override
+  { return true; }
 };
 
 /* Implement the "typeof" operation.  */
@@ -1593,6 +1590,9 @@ public:
 
   enum exp_opcode opcode () const override
   { return OP_TYPEOF; }
+
+  bool type_p () const override
+  { return true; }
 };
 
 /* Implement 'decltype'.  */
@@ -1638,6 +1638,9 @@ public:
 
   enum exp_opcode opcode () const override
   { return OP_DECLTYPE; }
+
+  bool type_p () const override
+  { return true; }
 };
 
 /* Implement 'typeid'.  */
@@ -1652,9 +1655,8 @@ public:
                   struct expression *exp,
                   enum noside noside) override
   {
-    enum exp_opcode sub_op = std::get<0> (m_storage)->opcode ();
     enum noside sub_noside
-      = ((sub_op == OP_TYPE || sub_op == OP_DECLTYPE || sub_op == OP_TYPEOF)
+      = (std::get<0> (m_storage)->type_p ()
         ? EVAL_AVOID_SIDE_EFFECTS
         : noside);
 
index 5bfc74c973f216a2ae25c166d0c2e498bac887dd..2eb866f455bcb99cdb614e2bd9dc2ebabde92fc7 100644 (file)
@@ -147,6 +147,11 @@ public:
   virtual bool uses_objfile (struct objfile *objfile) const
   { return false; }
 
+  /* Some expression nodes represent a type, not a value.  This method
+     should be overridden to return 'true' in these situations.  */
+  virtual bool type_p () const
+  { return false; }
+
   /* Generate agent expression bytecodes for this operation.  */
   void generate_ax (struct expression *exp, struct agent_expr *ax,
                    struct axs_value *value,
@@ -215,6 +220,11 @@ struct expression
     op->dump (stream, 0);
   }
 
+  /* Call the type_p method on the outermost sub-expression of this
+     expression, and return the result.  */
+  bool type_p () const
+  { return op->type_p (); }
+
   /* Return true if this expression uses OBJFILE (and will become
      dangling when OBJFILE is unloaded), otherwise return false.
      OBJFILE must not be a separate debug info file.  */
index 2e1c5ea81e73d0173238aef15107475fc1fc103c..274f6029a7efbfeac0bf409105ee155dba9817d9 100644 (file)
@@ -513,7 +513,7 @@ whatis_exp (const char *exp, int show)
       val = expr->evaluate_type ();
       type = val->type ();
 
-      if (show == -1 && expr->first_opcode () == OP_TYPE)
+      if (show == -1 && expr->type_p ())
        {
          /* The user expression names a type directly.  */
 
index 0cd0bd03b6e2c2158277c69f4dd3c838b1c805df..04f1fc879d26c7ff538b0225e406d188f9d94816 100644 (file)
@@ -323,10 +323,7 @@ varobj_create (const char *objname,
        }
 
       /* Don't allow variables to be created for types.  */
-      enum exp_opcode opcode = var->root->exp->first_opcode ();
-      if (opcode == OP_TYPE
-         || opcode == OP_TYPEOF
-         || opcode == OP_DECLTYPE)
+      if (var->root->exp->type_p ())
        {
          gdb_printf (gdb_stderr, "Attempt to use a type name"
                      " as an expression.\n");