Handle 'QWW' encoding case in Ada enums

In Ada, an enum can contain character literals.  GNAT encodes these
values in a special way.  For example, the Unicode character U+0178
would be represented as 'QW0178' in the DWARF:

 <3><112f>: Abbrev Number: 2 (DW_TAG_enumerator)
    <1130>   DW_AT_name        : (indirect string, offset: 0x19ff): QW0178
    <1134>   DW_AT_const_value : 2

gdb handles this reasonably well, but failed to handle the 'QWW'
encoding, which is used for characters outside the base plane.

Also, while working on this, I noticed that gdb will print the decimal
value for an enum character constant:

    (gdb) print Char_X
    $2 = 1 'x'

This is a nice feature, IMO, because in this situation the 'x' enum
constant does not have its usual decimal value -- it has the value
that's assigned based on the enumeration type.

However, gdb did not do this when it decided to print the constant
using the bracket notation:

    (gdb) print Char_Thorn
    $3 = ["de"]

This patch changes gdb to print the decimal value here as well, and to
put the bracket notation in single quotes -- otherwise gdb will be
printing something that it can't then read.  Now it looks like:

    (gdb) print Char_Thorn
    $3 = 4 '["de"]'

Note that gdb can't read longer bracket notations, like the other ones
printed in this test case:

    (gdb) print Char_King
    $4 = 3 '["01fa00"]'

While I think this is a bug, I plan to fix it separately.

Finally, in the new test case, the copyright dates are chosen this way
because this all started as a copy of an existing test.
This commit is contained in:
Tom Tromey 2022-01-25 11:26:15 -07:00
parent 659971cb0f
commit a7041de85a
5 changed files with 125 additions and 3 deletions

View file

@ -8786,7 +8786,13 @@ ada_enum_name (const char *name)
if (name[1] == 'U' || name[1] == 'W')
{
if (sscanf (name + 2, "%x", &v) != 1)
int offset = 2;
if (name[1] == 'W' && name[2] == 'W')
{
/* Also handle the QWW case. */
++offset;
}
if (sscanf (name + offset, "%x", &v) != 1)
return name;
}
else if (((name[1] >= '0' && name[1] <= '9')
@ -8802,9 +8808,11 @@ ada_enum_name (const char *name)
if (isascii (v) && isprint (v))
storage = string_printf ("'%c'", v);
else if (name[1] == 'U')
storage = string_printf ("[\"%02x\"]", v);
storage = string_printf ("'[\"%02x\"]'", v);
else if (name[2] != 'W')
storage = string_printf ("'[\"%04x\"]'", v);
else
storage = string_printf ("[\"%04x\"]", v);
storage = string_printf ("'[\"%06x\"]'", v);
return storage.c_str ();
}