Introduce var_msym_value_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:15 +0000 (07:28 -0700)
This adds class var_msym_value_operation, which implements
OP_VAR_MSYM_VALUE.  A new method is added to class operation in order
to support a special case in minsym evaluation.

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

* expression.h (class operation) <set_outermost>: New method.
* expop.h (class var_msym_value_operation): New.
* eval.c (eval_op_var_msym_value): No longer static.
(var_msym_value_operation::evaluate_for_address)
(var_msym_value_operation::evaluate_for_sizeof)
(var_msym_value_operation::evaluate_for_cast): New methods.
* ax-gdb.c (var_msym_value_operation::do_generate_ax): New
method.

gdb/ChangeLog
gdb/ax-gdb.c
gdb/eval.c
gdb/expop.h
gdb/expression.h

index 1b08ff5b9ecd5cf7b593152fb952bb0f8c421a2f..129a2383da8b873be1191dab022653975f11df9d 100644 (file)
@@ -1,3 +1,14 @@
+2021-03-08  Tom Tromey  <tom@tromey.com>
+
+       * expression.h (class operation) <set_outermost>: New method.
+       * expop.h (class var_msym_value_operation): New.
+       * eval.c (eval_op_var_msym_value): No longer static.
+       (var_msym_value_operation::evaluate_for_address)
+       (var_msym_value_operation::evaluate_for_sizeof)
+       (var_msym_value_operation::evaluate_for_cast): New methods.
+       * ax-gdb.c (var_msym_value_operation::do_generate_ax): New
+       method.
+
 2021-03-08  Tom Tromey  <tom@tromey.com>
 
        * expop.h (class long_const_operation): New.
index 7640b1ba925982db8f91fc6066e79c2d6f404fa5..602817007035fed6f9e461858920d539a5ab26e7 100644 (file)
@@ -2324,6 +2324,23 @@ long_const_operation::do_generate_ax (struct expression *exp,
                   std::get<0> (m_storage));
 }
 
+void
+var_msym_value_operation::do_generate_ax (struct expression *exp,
+                                         struct agent_expr *ax,
+                                         struct axs_value *value,
+                                         struct type *cast_type)
+{
+  gen_msym_var_ref (ax, value, std::get<0> (m_storage),
+                   std::get<1> (m_storage));
+
+  if (value->type->code () == TYPE_CODE_ERROR)
+    {
+      if (cast_type == nullptr)
+       error_unknown_type (std::get<0> (m_storage)->linkage_name ());
+      value->type = cast_type;
+    }
+}
+
 }
 
 /* This handles the middle-to-right-side of code generation for binary
index 452f088a515987f19daa2a0812191d9cf26d0a15..85e67f3fb933d09c0f2ee7ab407a0cc397fd48e4 100644 (file)
@@ -1221,7 +1221,7 @@ eval_op_var_entry_value (struct type *expect_type, struct expression *exp,
 
 /* Helper function that implements the body of OP_VAR_MSYM_VALUE.  */
 
-static struct value *
+struct value *
 eval_op_var_msym_value (struct type *expect_type, struct expression *exp,
                        enum noside noside, bool outermost_p,
                        minimal_symbol *msymbol, struct objfile *objfile)
@@ -3301,6 +3301,22 @@ scope_operation::evaluate_for_address (struct expression *exp,
   return x;
 }
 
+value *
+var_msym_value_operation::evaluate_for_address (struct expression *exp,
+                                               enum noside noside)
+{
+  value *val = evaluate_var_msym_value (noside,
+                                       std::get<1> (m_storage),
+                                       std::get<0> (m_storage));
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    {
+      struct type *type = lookup_pointer_type (value_type (val));
+      return value_zero (type, not_lval);
+    }
+  else
+    return value_addr (val);
+}
+
 }
 
 /* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
@@ -3501,6 +3517,25 @@ operation::evaluate_for_sizeof (struct expression *exp, enum noside noside)
   return evaluate_subexp_for_sizeof_base (exp, value_type (val));
 }
 
+value *
+var_msym_value_operation::evaluate_for_sizeof (struct expression *exp,
+                                              enum noside noside)
+
+{
+  minimal_symbol *msymbol = std::get<0> (m_storage);
+  value *mval = evaluate_var_msym_value (noside,
+                                        std::get<1> (m_storage),
+                                        msymbol);
+
+  struct type *type = value_type (mval);
+  if (type->code () == TYPE_CODE_ERROR)
+    error_unknown_type (msymbol->print_name ());
+
+  /* FIXME: This should be size_t.  */
+  struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
+  return value_from_longest (size_type, TYPE_LENGTH (type));
+}
+
 }
 
 /* Evaluate a subexpression of EXP, at index *POS, and return a value
@@ -3558,6 +3593,38 @@ evaluate_subexp_for_cast (expression *exp, int *pos,
   return value_cast (to_type, val);
 }
 
+namespace expr
+{
+
+value *
+var_msym_value_operation::evaluate_for_cast (struct type *to_type,
+                                            struct expression *exp,
+                                            enum noside noside)
+{
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    return value_zero (to_type, not_lval);
+
+  value *val = evaluate_var_msym_value (noside,
+                                       std::get<1> (m_storage),
+                                       std::get<0> (m_storage));
+
+  if (noside == EVAL_SKIP)
+    return eval_skip_value (exp);
+
+  val = value_cast (to_type, val);
+
+  /* Don't allow e.g. '&(int)var_with_no_debug_info'.  */
+  if (VALUE_LVAL (val) == lval_memory)
+    {
+      if (value_lazy (val))
+       value_fetch_lazy (val);
+      VALUE_LVAL (val) = not_lval;
+    }
+  return val;
+}
+
+}
+
 /* Parse a type expression in the string [P..P+LENGTH).  */
 
 struct type *
index ed883be6fc4b18aa6eb14da19edb393a7ce38f0c..345cac2997672b558fca4715df93e304adf9d5c0 100644 (file)
@@ -45,6 +45,12 @@ extern struct value *eval_op_scope (struct type *expect_type,
                                    struct expression *exp,
                                    enum noside noside,
                                    struct type *type, const char *string);
+extern struct value *eval_op_var_msym_value (struct type *expect_type,
+                                            struct expression *exp,
+                                            enum noside noside,
+                                            bool outermost_p,
+                                            minimal_symbol *msymbol,
+                                            struct objfile *objfile);
 
 namespace expr
 {
@@ -481,6 +487,52 @@ protected:
     override;
 };
 
+class var_msym_value_operation
+  : public maybe_constant_operation<minimal_symbol *, struct objfile *>
+{
+public:
+
+  using maybe_constant_operation::maybe_constant_operation;
+
+  value *evaluate (struct type *expect_type,
+                  struct expression *exp,
+                  enum noside noside) override
+  {
+    return eval_op_var_msym_value (expect_type, exp, noside, m_outermost,
+                                  std::get<0> (m_storage),
+                                  std::get<1> (m_storage));
+  }
+
+  value *evaluate_for_sizeof (struct expression *exp, enum noside noside)
+    override;
+
+  value *evaluate_for_address (struct expression *exp, enum noside noside)
+    override;
+
+  value *evaluate_for_cast (struct type *expect_type,
+                           struct expression *exp,
+                           enum noside noside) override;
+
+  enum exp_opcode opcode () const override
+  { return OP_VAR_MSYM_VALUE; }
+
+  void set_outermost () override
+  {
+    m_outermost = true;
+  }
+
+protected:
+
+  /* True if this is the outermost operation in the expression.  */
+  bool m_outermost = false;
+
+  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 */
index 24a0eb37722a3a433b4f2577adf40f28058737ed..4d75058dc22ee491a54b94a08b4a33784f0bdbd5 100644 (file)
@@ -165,6 +165,10 @@ public:
   /* Print this operation to STREAM.  */
   virtual void dump (struct ui_file *stream, int depth) const = 0;
 
+  /* Call to indicate that this is the outermost operation in the
+     expression.  This should almost never be overridden.  */
+  virtual void set_outermost () { }
+
 protected:
 
   /* Called by generate_ax to do the work for this particular