public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@adacore.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tromey@adacore.com>
Subject: [pushed 1/2] Handle 'QWW' encoding case in Ada enums
Date: Mon, 28 Feb 2022 10:48:55 -0700	[thread overview]
Message-ID: <20220228174856.287372-2-tromey@adacore.com> (raw)
In-Reply-To: <20220228174856.287372-1-tromey@adacore.com>

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.
---
 gdb/ada-lang.c                                | 14 ++++--
 gdb/testsuite/gdb.ada/char_enum_unicode.exp   | 43 +++++++++++++++++++
 .../gdb.ada/char_enum_unicode/foo.adb         | 30 +++++++++++++
 .../gdb.ada/char_enum_unicode/pck.adb         | 21 +++++++++
 .../gdb.ada/char_enum_unicode/pck.ads         | 20 +++++++++
 5 files changed, 125 insertions(+), 3 deletions(-)
 create mode 100644 gdb/testsuite/gdb.ada/char_enum_unicode.exp
 create mode 100644 gdb/testsuite/gdb.ada/char_enum_unicode/foo.adb
 create mode 100644 gdb/testsuite/gdb.ada/char_enum_unicode/pck.adb
 create mode 100644 gdb/testsuite/gdb.ada/char_enum_unicode/pck.ads

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d2f620cbb04..f1d59d2aadb 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -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 ();
     }
diff --git a/gdb/testsuite/gdb.ada/char_enum_unicode.exp b/gdb/testsuite/gdb.ada/char_enum_unicode.exp
new file mode 100644
index 00000000000..aa8136054e7
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/char_enum_unicode.exp
@@ -0,0 +1,43 @@
+# Copyright 2011-2022 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib "ada.exp"
+
+if { [skip_ada_tests] } { return -1 }
+
+standard_ada_testfile foo
+
+set flags [list debug additional_flags=-gnatW8]
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
+runto "foo.adb:$bp_location"
+
+set y "'\\\[\"0178\"\\\]'"
+set king "'\\\[\"01fa00\"\\\]'"
+set thorn "'\\\[\"de\"\\\]'"
+
+gdb_test "ptype Char_Enum_Type" "type = \\(alpha, 'x', $y, $king, $thorn\\)"
+gdb_test "print Char_Alpha" " = alpha"
+gdb_test "print Char_X" " = 1 'x'"
+gdb_test "print Char_Y" " = 2 $y"
+gdb_test "print Char_King" " = 3 $king"
+gdb_test "print Char_Thorn" " = 4 $thorn"
+gdb_test "print Char_Enum_Type'('x')" " = 1 'x'"
+gdb_test "print Char_Enum_Type'('\[\"de\"\]')" " = 4 $thorn"
diff --git a/gdb/testsuite/gdb.ada/char_enum_unicode/foo.adb b/gdb/testsuite/gdb.ada/char_enum_unicode/foo.adb
new file mode 100644
index 00000000000..09756870320
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/char_enum_unicode/foo.adb
@@ -0,0 +1,30 @@
+--  Copyright 2011-2022 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+with Pck; use Pck;
+
+procedure Foo is
+   type Char_Enum_Type is (alpha, 'x', 'Ÿ', '🨀', 'Þ');
+   Char_Alpha : Char_Enum_Type := alpha;
+   Char_X : Char_Enum_Type := 'x';
+   Char_Thorn : Char_Enum_Type := 'Þ';
+   Char_Y : Char_Enum_Type := 'Ÿ';
+   Char_King : Char_Enum_Type := '🨀';
+begin
+   Do_Nothing (Char_Alpha'Address);  -- STOP
+   Do_Nothing (Char_X'Address);
+   Do_Nothing (Char_Y'Address);
+   Do_Nothing (Char_King'Address);
+end Foo;
diff --git a/gdb/testsuite/gdb.ada/char_enum_unicode/pck.adb b/gdb/testsuite/gdb.ada/char_enum_unicode/pck.adb
new file mode 100644
index 00000000000..d9308b6c04d
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/char_enum_unicode/pck.adb
@@ -0,0 +1,21 @@
+--  Copyright 2011-2022 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package body Pck is
+   procedure Do_Nothing (A : System.Address) is
+   begin
+      null;
+   end Do_Nothing;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/char_enum_unicode/pck.ads b/gdb/testsuite/gdb.ada/char_enum_unicode/pck.ads
new file mode 100644
index 00000000000..4e937b8a5a2
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/char_enum_unicode/pck.ads
@@ -0,0 +1,20 @@
+--  Copyright 2011-2022 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+with System;
+
+package Pck is
+   procedure Do_Nothing (A : System.Address);
+end Pck;
-- 
2.31.1


  reply	other threads:[~2022-02-28 17:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-28 17:48 [pushed 0/2] Two fixes for Ada character enum literals Tom Tromey
2022-02-28 17:48 ` Tom Tromey [this message]
2022-02-28 17:48 ` [pushed 2/2] Handle multi-byte bracket sequences in Ada lexer Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220228174856.287372-2-tromey@adacore.com \
    --to=tromey@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).