[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:
Joel Brobecker 2010-12-29 08:01:32 +00:00
parent 113a6f1ec9
commit 720d1a4025
9 changed files with 119 additions and 17 deletions

View File

@ -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>
* target.h (enum target_object): Expand the documentation of

View File

@ -228,8 +228,6 @@ static int ada_resolve_function (struct ada_symbol_info *, int,
struct value **, int, const char *,
struct type *);
static struct value *ada_coerce_to_simple_array (struct value *);
static int ada_is_direct_array_type (struct type *);
static void ada_language_arch_info (struct gdbarch *,
@ -366,6 +364,41 @@ ada_inferior_exit (struct inferior *inf)
/* 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
decoded form (ie using the Ada dotted notation), returns
its unqualified name. */
@ -1354,6 +1387,9 @@ desc_base_type (struct type *type)
if (type == NULL)
return NULL;
type = ada_check_typedef (type);
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
type = ada_typedef_target_type (type);
if (type != NULL
&& (TYPE_CODE (type) == TYPE_CODE_PTR
|| 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
be ARR itself if it already is in the proper form). */
static struct value *
struct value *
ada_coerce_to_simple_array (struct value *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
decode_packed_array_bitsize (struct type *type)
{
char *raw_name = ada_type_name (ada_check_typedef (type));
char *raw_name;
char *tail;
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)
raw_name = ada_type_name (desc_base_type (type));
@ -1904,6 +1947,7 @@ decode_packed_array_bitsize (struct type *type)
return 0;
tail = strstr (raw_name, "___XP");
gdb_assert (tail != NULL);
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);
/* 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_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
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.
*/
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)))
return type;
@ -7789,6 +7842,15 @@ ada_check_typedef (struct type *type)
if (type == 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);
if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
|| !TYPE_STUB (type)
@ -9282,6 +9344,13 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
argvec[0] = value_addr (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)
{
switch (TYPE_CODE (ada_check_typedef (TYPE_TARGET_TYPE (type))))

View File

@ -197,6 +197,8 @@ struct type *ada_type_of_array (struct value *, int);
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_array_descriptor_type (struct type *);

View File

@ -796,6 +796,7 @@ ada_print_type (struct type *type0, const char *varstring,
fprintf_filtered (stream, ">");
break;
case TYPE_CODE_PTR:
case TYPE_CODE_TYPEDEF:
fprintf_filtered (stream, "access ");
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
break;

View File

@ -684,7 +684,10 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
struct value *val;
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)
{
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))
{
fprintf_filtered (stream, "(");
type_print (type, "", stream, -1);
fprintf_filtered (stream, ") ");
/* We do not print the type description unless TYPE is an array
access type (this is encoded by the compiler as a typedef to
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))
{

View File

@ -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>
* gdb.texinfo (Packets) <read registers packet>: Document support

View File

@ -13665,13 +13665,6 @@ some of which will be fixed with planned future releases of the debugger
and the GNU Ada compiler.
@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
Static constants that the compiler chooses not to materialize as objects in
storage are invisible to the debugger.

View File

@ -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>
* gdb.threads/tls.exp: Fix typo.

View File

@ -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
# by checking the string parameter.
gdb_test "bt" \
".*#1.*lang_switch\\.ada_procedure\\s*\\(msg=$hex\\).*" \
".*#1.*lang_switch\\.ada_procedure\\s*\\(msg=\"msg\"\\).*" \
"backtrace"
# Now, make sure that the language doesn't get automatically switched