[Ada] do not print arrays as array pointers
This patch enhances the debugger to distinguish between fat pointers that represent either: array types, or array access types. In the latter case, the object/type is encoded as a typedef type pointing to the fat pointer. The first part of the change is to adjust ada_check_typedef to avoid stripping the typedef layer when it points to a fat pointer. The rest of the patch is adjustments required in various places to deal with the fact that the type is uses might now be a typedef. gdb/ChangeLog: * ada-lang.h (ada_coerce_to_simple_array): Add declaration. * ada-lang.c (ada_typedef_target_type): New function. (desc_base_type): Add handling of fat pointer typedefs. (ada_coerce_to_simple_array): Make non-static. (decode_packed_array_bitsize): Add handling of fat pointer typedefs. Add assertion. (ada_template_to_fixed_record_type_1, ada_to_fixed_type) (ada_check_typedef): Add handling of fat pointer typedefs. (ada_evaluate_subexp) [OP_FUNCALL]: Likewise. * ada-typeprint.c (ada_print_type): Add handling of fat pointer typedefs. * ada-valprint.c (ada_val_print_1): Convert fat pointers that are not array accesses to simple arrays rather than simple array pointers. (ada_value_print): In the case of array descriptors, do not print the value type description unless it is an array access. gdb/testsuite/ChangeLog: * gdb.ada/lang_switch.exp: Correct expected parameter value. gdb/doc/ChangeLog: * gdb.texinfo (Ada Glitches): Remove paragraph describing the occasional case where the debugger prints an array address instead of the array itself.
This commit is contained in:
parent
113a6f1ec9
commit
720d1a4025
9 changed files with 119 additions and 17 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
2010-12-29 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
|
* ada-lang.h (ada_coerce_to_simple_array): Add declaration.
|
||||||
|
* ada-lang.c (ada_typedef_target_type): New function.
|
||||||
|
(desc_base_type): Add handling of fat pointer typedefs.
|
||||||
|
(ada_coerce_to_simple_array): Make non-static.
|
||||||
|
(decode_packed_array_bitsize): Add handling of fat pointer typedefs.
|
||||||
|
Add assertion.
|
||||||
|
(ada_template_to_fixed_record_type_1, ada_to_fixed_type)
|
||||||
|
(ada_check_typedef): Add handling of fat pointer typedefs.
|
||||||
|
(ada_evaluate_subexp) [OP_FUNCALL]: Likewise.
|
||||||
|
* ada-typeprint.c (ada_print_type): Add handling of fat pointer
|
||||||
|
typedefs.
|
||||||
|
* ada-valprint.c (ada_val_print_1): Convert fat pointers that are not
|
||||||
|
array accesses to simple arrays rather than simple array pointers.
|
||||||
|
(ada_value_print): In the case of array descriptors, do not print
|
||||||
|
the value type description unless it is an array access.
|
||||||
|
|
||||||
2010-12-29 Joel Brobecker <brobecker@adacore.com>
|
2010-12-29 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
* target.h (enum target_object): Expand the documentation of
|
* target.h (enum target_object): Expand the documentation of
|
||||||
|
|
|
@ -228,8 +228,6 @@ static int ada_resolve_function (struct ada_symbol_info *, int,
|
||||||
struct value **, int, const char *,
|
struct value **, int, const char *,
|
||||||
struct type *);
|
struct type *);
|
||||||
|
|
||||||
static struct value *ada_coerce_to_simple_array (struct value *);
|
|
||||||
|
|
||||||
static int ada_is_direct_array_type (struct type *);
|
static int ada_is_direct_array_type (struct type *);
|
||||||
|
|
||||||
static void ada_language_arch_info (struct gdbarch *,
|
static void ada_language_arch_info (struct gdbarch *,
|
||||||
|
@ -366,6 +364,41 @@ ada_inferior_exit (struct inferior *inf)
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
|
|
||||||
|
/* If TYPE is a TYPE_CODE_TYPEDEF type, return the target type after
|
||||||
|
all typedef layers have been pealed. Otherwise, return TYPE.
|
||||||
|
|
||||||
|
Normally, we really expect a typedef type to only have 1 typedef layer.
|
||||||
|
In other words, we really expect the target type of a typedef type to be
|
||||||
|
a non-typedef type. This is particularly true for Ada units, because
|
||||||
|
the language does not have a typedef vs not-typedef distinction.
|
||||||
|
In that respect, the Ada compiler has been trying to eliminate as many
|
||||||
|
typedef definitions in the debugging information, since they generally
|
||||||
|
do not bring any extra information (we still use typedef under certain
|
||||||
|
circumstances related mostly to the GNAT encoding).
|
||||||
|
|
||||||
|
Unfortunately, we have seen situations where the debugging information
|
||||||
|
generated by the compiler leads to such multiple typedef layers. For
|
||||||
|
instance, consider the following example with stabs:
|
||||||
|
|
||||||
|
.stabs "pck__float_array___XUP:Tt(0,46)=s16P_ARRAY:(0,47)=[...]"[...]
|
||||||
|
.stabs "pck__float_array___XUP:t(0,36)=(0,46)",128,0,6,0
|
||||||
|
|
||||||
|
This is an error in the debugging information which causes type
|
||||||
|
pck__float_array___XUP to be defined twice, and the second time,
|
||||||
|
it is defined as a typedef of a typedef.
|
||||||
|
|
||||||
|
This is on the fringe of legality as far as debugging information is
|
||||||
|
concerned, and certainly unexpected. But it is easy to handle these
|
||||||
|
situations correctly, so we can afford to be lenient in this case. */
|
||||||
|
|
||||||
|
static struct type *
|
||||||
|
ada_typedef_target_type (struct type *type)
|
||||||
|
{
|
||||||
|
while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||||
|
type = TYPE_TARGET_TYPE (type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/* Given DECODED_NAME a string holding a symbol name in its
|
/* Given DECODED_NAME a string holding a symbol name in its
|
||||||
decoded form (ie using the Ada dotted notation), returns
|
decoded form (ie using the Ada dotted notation), returns
|
||||||
its unqualified name. */
|
its unqualified name. */
|
||||||
|
@ -1354,6 +1387,9 @@ desc_base_type (struct type *type)
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
type = ada_check_typedef (type);
|
type = ada_check_typedef (type);
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||||
|
type = ada_typedef_target_type (type);
|
||||||
|
|
||||||
if (type != NULL
|
if (type != NULL
|
||||||
&& (TYPE_CODE (type) == TYPE_CODE_PTR
|
&& (TYPE_CODE (type) == TYPE_CODE_PTR
|
||||||
|| TYPE_CODE (type) == TYPE_CODE_REF))
|
|| TYPE_CODE (type) == TYPE_CODE_REF))
|
||||||
|
@ -1819,7 +1855,7 @@ ada_coerce_to_simple_array_ptr (struct value *arr)
|
||||||
Otherwise, returns a standard GDB array describing ARR (which may
|
Otherwise, returns a standard GDB array describing ARR (which may
|
||||||
be ARR itself if it already is in the proper form). */
|
be ARR itself if it already is in the proper form). */
|
||||||
|
|
||||||
static struct value *
|
struct value *
|
||||||
ada_coerce_to_simple_array (struct value *arr)
|
ada_coerce_to_simple_array (struct value *arr)
|
||||||
{
|
{
|
||||||
if (ada_is_array_descriptor_type (value_type (arr)))
|
if (ada_is_array_descriptor_type (value_type (arr)))
|
||||||
|
@ -1893,10 +1929,17 @@ ada_is_unconstrained_packed_array_type (struct type *type)
|
||||||
static long
|
static long
|
||||||
decode_packed_array_bitsize (struct type *type)
|
decode_packed_array_bitsize (struct type *type)
|
||||||
{
|
{
|
||||||
char *raw_name = ada_type_name (ada_check_typedef (type));
|
char *raw_name;
|
||||||
char *tail;
|
char *tail;
|
||||||
long bits;
|
long bits;
|
||||||
|
|
||||||
|
/* Access to arrays implemented as fat pointers are encoded as a typedef
|
||||||
|
of the fat pointer type. We need the name of the fat pointer type
|
||||||
|
to do the decoding, so strip the typedef layer. */
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||||
|
type = ada_typedef_target_type (type);
|
||||||
|
|
||||||
|
raw_name = ada_type_name (ada_check_typedef (type));
|
||||||
if (!raw_name)
|
if (!raw_name)
|
||||||
raw_name = ada_type_name (desc_base_type (type));
|
raw_name = ada_type_name (desc_base_type (type));
|
||||||
|
|
||||||
|
@ -1904,6 +1947,7 @@ decode_packed_array_bitsize (struct type *type)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tail = strstr (raw_name, "___XP");
|
tail = strstr (raw_name, "___XP");
|
||||||
|
gdb_assert (tail != NULL);
|
||||||
|
|
||||||
if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1)
|
if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1)
|
||||||
{
|
{
|
||||||
|
@ -7146,6 +7190,15 @@ ada_template_to_fixed_record_type_1 (struct type *type,
|
||||||
{
|
{
|
||||||
struct type *field_type = TYPE_FIELD_TYPE (type, f);
|
struct type *field_type = TYPE_FIELD_TYPE (type, f);
|
||||||
|
|
||||||
|
/* If our field is a typedef type (most likely a typedef of
|
||||||
|
a fat pointer, encoding an array access), then we need to
|
||||||
|
look at its target type to determine its characteristics.
|
||||||
|
In particular, we would miscompute the field size if we took
|
||||||
|
the size of the typedef (zero), instead of the size of
|
||||||
|
the target type. */
|
||||||
|
if (TYPE_CODE (field_type) == TYPE_CODE_TYPEDEF)
|
||||||
|
field_type = ada_typedef_target_type (field_type);
|
||||||
|
|
||||||
TYPE_FIELD_TYPE (rtype, f) = field_type;
|
TYPE_FIELD_TYPE (rtype, f) = field_type;
|
||||||
TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
|
TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
|
||||||
if (TYPE_FIELD_BITSIZE (type, f) > 0)
|
if (TYPE_FIELD_BITSIZE (type, f) > 0)
|
||||||
|
@ -7703,7 +7756,7 @@ ada_to_fixed_type (struct type *type, const gdb_byte *valaddr,
|
||||||
because we call check_typedef/ada_check_typedef pretty much everywhere.
|
because we call check_typedef/ada_check_typedef pretty much everywhere.
|
||||||
*/
|
*/
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
|
||||||
&& (TYPE_MAIN_TYPE (TYPE_TARGET_TYPE (type))
|
&& (TYPE_MAIN_TYPE (ada_typedef_target_type (type))
|
||||||
== TYPE_MAIN_TYPE (fixed_type)))
|
== TYPE_MAIN_TYPE (fixed_type)))
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
|
@ -7789,6 +7842,15 @@ ada_check_typedef (struct type *type)
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* If our type is a typedef type of a fat pointer, then we're done.
|
||||||
|
We don't want to strip the TYPE_CODE_TYPDEF layer, because this is
|
||||||
|
what allows us to distinguish between fat pointers that represent
|
||||||
|
array types, and fat pointers that represent array access types
|
||||||
|
(in both cases, the compiler implements them as fat pointers). */
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
|
||||||
|
&& is_thick_pntr (ada_typedef_target_type (type)))
|
||||||
|
return type;
|
||||||
|
|
||||||
CHECK_TYPEDEF (type);
|
CHECK_TYPEDEF (type);
|
||||||
if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
|
if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
|
||||||
|| !TYPE_STUB (type)
|
|| !TYPE_STUB (type)
|
||||||
|
@ -9282,6 +9344,13 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
|
||||||
argvec[0] = value_addr (argvec[0]);
|
argvec[0] = value_addr (argvec[0]);
|
||||||
|
|
||||||
type = ada_check_typedef (value_type (argvec[0]));
|
type = ada_check_typedef (value_type (argvec[0]));
|
||||||
|
|
||||||
|
/* Ada allows us to implicitly dereference arrays when subscripting
|
||||||
|
them. So, if this is an typedef (encoding use for array access
|
||||||
|
types encoded as fat pointers), strip it now. */
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||||
|
type = ada_typedef_target_type (type);
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||||
{
|
{
|
||||||
switch (TYPE_CODE (ada_check_typedef (TYPE_TARGET_TYPE (type))))
|
switch (TYPE_CODE (ada_check_typedef (TYPE_TARGET_TYPE (type))))
|
||||||
|
|
|
@ -197,6 +197,8 @@ struct type *ada_type_of_array (struct value *, int);
|
||||||
|
|
||||||
extern struct value *ada_coerce_to_simple_array_ptr (struct value *);
|
extern struct value *ada_coerce_to_simple_array_ptr (struct value *);
|
||||||
|
|
||||||
|
struct value *ada_coerce_to_simple_array (struct value *);
|
||||||
|
|
||||||
extern int ada_is_simple_array_type (struct type *);
|
extern int ada_is_simple_array_type (struct type *);
|
||||||
|
|
||||||
extern int ada_is_array_descriptor_type (struct type *);
|
extern int ada_is_array_descriptor_type (struct type *);
|
||||||
|
|
|
@ -796,6 +796,7 @@ ada_print_type (struct type *type0, const char *varstring,
|
||||||
fprintf_filtered (stream, ">");
|
fprintf_filtered (stream, ">");
|
||||||
break;
|
break;
|
||||||
case TYPE_CODE_PTR:
|
case TYPE_CODE_PTR:
|
||||||
|
case TYPE_CODE_TYPEDEF:
|
||||||
fprintf_filtered (stream, "access ");
|
fprintf_filtered (stream, "access ");
|
||||||
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
|
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -684,7 +684,10 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
|
||||||
struct value *val;
|
struct value *val;
|
||||||
|
|
||||||
val = value_from_contents_and_address (type, valaddr, address);
|
val = value_from_contents_and_address (type, valaddr, address);
|
||||||
val = ada_coerce_to_simple_array_ptr (val);
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) /* array access type. */
|
||||||
|
val = ada_coerce_to_simple_array_ptr (val);
|
||||||
|
else
|
||||||
|
val = ada_coerce_to_simple_array (val);
|
||||||
if (val == NULL)
|
if (val == NULL)
|
||||||
{
|
{
|
||||||
fprintf_filtered (stream, "(null)");
|
fprintf_filtered (stream, "(null)");
|
||||||
|
@ -947,9 +950,15 @@ ada_value_print (struct value *val0, struct ui_file *stream,
|
||||||
}
|
}
|
||||||
else if (ada_is_array_descriptor_type (type))
|
else if (ada_is_array_descriptor_type (type))
|
||||||
{
|
{
|
||||||
fprintf_filtered (stream, "(");
|
/* We do not print the type description unless TYPE is an array
|
||||||
type_print (type, "", stream, -1);
|
access type (this is encoded by the compiler as a typedef to
|
||||||
fprintf_filtered (stream, ") ");
|
a fat pointer - hence the check against TYPE_CODE_TYPEDEF). */
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||||
|
{
|
||||||
|
fprintf_filtered (stream, "(");
|
||||||
|
type_print (type, "", stream, -1);
|
||||||
|
fprintf_filtered (stream, ") ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ada_is_bogus_array_descriptor (type))
|
else if (ada_is_bogus_array_descriptor (type))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2010-12-29 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
|
* gdb.texinfo (Ada Glitches): Remove paragraph describing the
|
||||||
|
occasional case where the debugger prints an array address
|
||||||
|
instead of the array itself.
|
||||||
|
|
||||||
2010-12-23 Pedro Alves <pedro@codesourcery.com>
|
2010-12-23 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* gdb.texinfo (Packets) <read registers packet>: Document support
|
* gdb.texinfo (Packets) <read registers packet>: Document support
|
||||||
|
|
|
@ -13665,13 +13665,6 @@ some of which will be fixed with planned future releases of the debugger
|
||||||
and the GNU Ada compiler.
|
and the GNU Ada compiler.
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
|
||||||
Currently, the debugger
|
|
||||||
has insufficient information to determine whether certain pointers represent
|
|
||||||
pointers to objects or the objects themselves.
|
|
||||||
Thus, the user may have to tack an extra @code{.all} after an expression
|
|
||||||
to get it printed properly.
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Static constants that the compiler chooses not to materialize as objects in
|
Static constants that the compiler chooses not to materialize as objects in
|
||||||
storage are invisible to the debugger.
|
storage are invisible to the debugger.
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2010-12-29 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
|
* gdb.ada/lang_switch.exp: Correct expected parameter value.
|
||||||
|
|
||||||
2010-12-25 Andreas Schwab <schwab@linux-m68k.org>
|
2010-12-25 Andreas Schwab <schwab@linux-m68k.org>
|
||||||
|
|
||||||
* gdb.threads/tls.exp: Fix typo.
|
* gdb.threads/tls.exp: Fix typo.
|
||||||
|
|
|
@ -46,7 +46,7 @@ gdb_test_no_output "set print frame-arguments all"
|
||||||
# Make sure that the language is switched to Ada for the second frame
|
# Make sure that the language is switched to Ada for the second frame
|
||||||
# by checking the string parameter.
|
# by checking the string parameter.
|
||||||
gdb_test "bt" \
|
gdb_test "bt" \
|
||||||
".*#1.*lang_switch\\.ada_procedure\\s*\\(msg=$hex\\).*" \
|
".*#1.*lang_switch\\.ada_procedure\\s*\\(msg=\"msg\"\\).*" \
|
||||||
"backtrace"
|
"backtrace"
|
||||||
|
|
||||||
# Now, make sure that the language doesn't get automatically switched
|
# Now, make sure that the language doesn't get automatically switched
|
||||||
|
|
Loading…
Add table
Reference in a new issue