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: [PATCH 2/4] Ada support for wide strings
Date: Tue, 15 Mar 2022 07:24:58 -0600	[thread overview]
Message-ID: <20220315132500.1032991-3-tromey@adacore.com> (raw)
In-Reply-To: <20220315132500.1032991-1-tromey@adacore.com>

This adds some basic support for Wide_String and Wide_Wide_String to
the Ada expression evaluator.  In particular, a string literal may be
converted to a wide or wide-wide string depending on context.

The patch updates an existing test case.  Note that another test,
namely something like:

    ptype Wide_Wide_String'("literal")

... would be nice to add, but when tested against a distro GNAT, this
did not work (probably due to lack of debuginfo); so, I haven't
included it here.
---
 gdb/ada-lang.c                         | 63 +++++++++++++++++++++++---
 gdb/testsuite/gdb.ada/widewide.exp     |  4 ++
 gdb/testsuite/gdb.ada/widewide/foo.adb |  2 +
 3 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 12ff0353829..f097ad4b6f7 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10603,12 +10603,63 @@ ada_string_operation::evaluate (struct type *expect_type,
 				struct expression *exp,
 				enum noside noside)
 {
-  value *result = string_operation::evaluate (expect_type, exp, noside);
-  /* The result type will have code OP_STRING, bashed there from 
-     OP_ARRAY.  Bash it back.  */
-  if (value_type (result)->code () == TYPE_CODE_STRING)
-    value_type (result)->set_code (TYPE_CODE_ARRAY);
-  return result;
+  struct type *char_type;
+  if (expect_type != nullptr && ada_is_string_type (expect_type))
+    char_type = ada_array_element_type (expect_type, 1);
+  else
+    char_type = language_string_char_type (exp->language_defn, exp->gdbarch);
+
+  const std::string &str = std::get<0> (m_storage);
+  const char *encoding;
+  switch (TYPE_LENGTH (char_type))
+    {
+    case 1:
+      {
+	/* Simply copy over the data -- this isn't perhaps strictly
+	   correct according to the encodings, but it is gdb's
+	   historical behavior.  */
+	struct type *stringtype
+	  = lookup_array_range_type (char_type, 1, str.length ());
+	struct value *val = allocate_value (stringtype);
+	memcpy (value_contents_raw (val).data (), str.c_str (),
+		str.length ());
+	return val;
+      }
+
+    case 2:
+      if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
+	encoding = "UTF-16BE";
+      else
+	encoding = "UTF-16LE";
+      break;
+
+    case 4:
+      if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
+	encoding = "UTF-32BE";
+      else
+	encoding = "UTF-32LE";
+      break;
+
+    default:
+      error (_("unexpected character type size %s"),
+	     pulongest (TYPE_LENGTH (char_type)));
+    }
+
+  auto_obstack converted;
+  convert_between_encodings (host_charset (), encoding,
+			     (const gdb_byte *) str.c_str (),
+			     str.length (), 1,
+			     &converted, translit_none);
+
+  struct type *stringtype
+    = lookup_array_range_type (char_type, 1,
+			       obstack_object_size (&converted)
+			       / TYPE_LENGTH (char_type));
+  struct value *val = allocate_value (stringtype);
+  memcpy (value_contents_raw (val).data (),
+	  obstack_base (&converted),
+	  obstack_object_size (&converted));
+  return val;
 }
 
 value *
diff --git a/gdb/testsuite/gdb.ada/widewide.exp b/gdb/testsuite/gdb.ada/widewide.exp
index c0268f9c99b..d68a0b112c4 100644
--- a/gdb/testsuite/gdb.ada/widewide.exp
+++ b/gdb/testsuite/gdb.ada/widewide.exp
@@ -43,3 +43,7 @@ gdb_test "print my_wws(1)" "= 32 ' '"
 
 gdb_test "print my_wws(2)" "= 104 'h'"
 
+gdb_test "print my_wws = \" helo\"" " = true"
+
+gdb_test "print my_ws = \"wide\"" " = true"
+gdb_test "print my_ws = \"nope\"" " = false"
diff --git a/gdb/testsuite/gdb.ada/widewide/foo.adb b/gdb/testsuite/gdb.ada/widewide/foo.adb
index 45adbde20a1..d41734a485f 100644
--- a/gdb/testsuite/gdb.ada/widewide/foo.adb
+++ b/gdb/testsuite/gdb.ada/widewide/foo.adb
@@ -19,9 +19,11 @@ procedure Foo is
    Some_Easy : Wide_Wide_Character := 'J';
    Some_Larger : Wide_Wide_Character := Wide_Wide_Character'Val(16#beef#);
    Some_Big : Wide_Wide_Character := Wide_Wide_Character'Val(16#00dabeef#);
+   My_Ws : Wide_String := "wide";
    My_WWS : Wide_Wide_String := " helo";
 begin
    Do_Nothing (Some_Easy'Address);  -- START
    Do_Nothing (Some_Larger'Address);
+   Do_Nothing (My_Ws'Address);
    Do_Nothing (Some_Big'Address);
 end Foo;
-- 
2.34.1


  parent reply	other threads:[~2022-03-15 13:25 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-15 13:24 [PATCH 0/4] Some wide string improvements for Ada Tom Tromey
2022-03-15 13:24 ` [PATCH 1/4] Remove eval_op_string Tom Tromey
2022-03-16 11:57   ` Andrew Burgess
2022-03-15 13:24 ` Tom Tromey [this message]
2022-03-16 12:12   ` [PATCH 2/4] Ada support for wide strings Andrew Burgess
2022-03-15 13:24 ` [PATCH 3/4] Remove eval_op_concat Tom Tromey
2022-03-16 13:32   ` Andrew Burgess
2022-03-15 13:25 ` [PATCH 4/4] Reimplement array concatenation for Ada and D Tom Tromey
2022-03-15 14:32   ` Eli Zaretskii
2022-03-16 13:55   ` Andrew Burgess

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=20220315132500.1032991-3-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).