diff options
author | Tom Tromey <tom@tromey.com> | 2021-03-08 07:27:57 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2021-03-08 07:28:35 -0700 |
commit | e8c33fa16a85801af1812bc9e6120cdf0538b401 (patch) | |
tree | 925ca7ffa23714402c31e2a8de3789da2577b8d6 /gdb | |
parent | 065ec8268d5b1eb1895da4328d3bc9a5a5d043d1 (diff) | |
download | gdb-e8c33fa16a85801af1812bc9e6120cdf0538b401.zip gdb-e8c33fa16a85801af1812bc9e6120cdf0538b401.tar.gz gdb-e8c33fa16a85801af1812bc9e6120cdf0538b401.tar.bz2 |
Introduce ada_unop_ind_operation
This adds class ada_unop_ind_operation, which implements UNOP_IND for
Ada.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* ada-lang.c (ada_unop_ind_operation::evaluate): New method.
* ada-exp.h (class ada_unop_ind_operation): New.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/ada-exp.h | 13 | ||||
-rw-r--r-- | gdb/ada-lang.c | 85 |
3 files changed, 103 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 95659b4..5f6dcfb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,10 @@ 2021-03-08 Tom Tromey <tom@tromey.com> + * ada-lang.c (ada_unop_ind_operation::evaluate): New method. + * ada-exp.h (class ada_unop_ind_operation): New. + +2021-03-08 Tom Tromey <tom@tromey.com> + * ada-lang.c (ada_binop_exp): No longer static. * ada-exp.h (ada_binop_exp_operation): New typedef. diff --git a/gdb/ada-exp.h b/gdb/ada-exp.h index 8e90846..c87036e 100644 --- a/gdb/ada-exp.h +++ b/gdb/ada-exp.h @@ -358,6 +358,19 @@ public: { return OP_ATR_VAL; } }; +/* The indirection operator for Ada. */ +class ada_unop_ind_operation + : public unop_ind_base_operation +{ +public: + + using unop_ind_base_operation::unop_ind_base_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override; +}; + } /* namespace expr */ #endif /* ADA_EXP_H */ diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 8a4de77..5998ae7 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -10703,6 +10703,91 @@ ada_atr_val_operation::evaluate (struct type *expect_type, return ada_val_atr (noside, std::get<0> (m_storage), arg); } +value * +ada_unop_ind_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *arg1 = std::get<0> (m_storage)->evaluate (expect_type, exp, noside); + + struct type *type = ada_check_typedef (value_type (arg1)); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + if (ada_is_array_descriptor_type (type)) + /* GDB allows dereferencing GNAT array descriptors. */ + { + struct type *arrType = ada_type_of_array (arg1, 0); + + if (arrType == NULL) + error (_("Attempt to dereference null array pointer.")); + return value_at_lazy (arrType, 0); + } + else if (type->code () == TYPE_CODE_PTR + || type->code () == TYPE_CODE_REF + /* In C you can dereference an array to get the 1st elt. */ + || type->code () == TYPE_CODE_ARRAY) + { + /* As mentioned in the OP_VAR_VALUE case, tagged types can + only be determined by inspecting the object's tag. + This means that we need to evaluate completely the + expression in order to get its type. */ + + if ((type->code () == TYPE_CODE_REF + || type->code () == TYPE_CODE_PTR) + && ada_is_tagged_type (TYPE_TARGET_TYPE (type), 0)) + { + arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, + EVAL_NORMAL); + type = value_type (ada_value_ind (arg1)); + } + else + { + type = to_static_fixed_type + (ada_aligned_type + (ada_check_typedef (TYPE_TARGET_TYPE (type)))); + } + ada_ensure_varsize_limit (type); + return value_zero (type, lval_memory); + } + else if (type->code () == TYPE_CODE_INT) + { + /* GDB allows dereferencing an int. */ + if (expect_type == NULL) + return value_zero (builtin_type (exp->gdbarch)->builtin_int, + lval_memory); + else + { + expect_type = + to_static_fixed_type (ada_aligned_type (expect_type)); + return value_zero (expect_type, lval_memory); + } + } + else + error (_("Attempt to take contents of a non-pointer value.")); + } + arg1 = ada_coerce_ref (arg1); /* FIXME: What is this for?? */ + type = ada_check_typedef (value_type (arg1)); + + if (type->code () == TYPE_CODE_INT) + /* GDB allows dereferencing an int. If we were given + the expect_type, then use that as the target type. + Otherwise, assume that the target type is an int. */ + { + if (expect_type != NULL) + return ada_value_ind (value_cast (lookup_pointer_type (expect_type), + arg1)); + else + return value_at_lazy (builtin_type (exp->gdbarch)->builtin_int, + (CORE_ADDR) value_as_address (arg1)); + } + + if (ada_is_array_descriptor_type (type)) + /* GDB allows dereferencing GNAT array descriptors. */ + return ada_coerce_to_simple_array (arg1); + else + return ada_value_ind (arg1); +} + } /* Implement the evaluate_exp routine in the exp_descriptor structure |