mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 09:58:19 +08:00
Ada support for wide strings
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.
This commit is contained in:
@ -10603,12 +10603,63 @@ ada_string_operation::evaluate (struct type *expect_type,
|
|||||||
struct expression *exp,
|
struct expression *exp,
|
||||||
enum noside noside)
|
enum noside noside)
|
||||||
{
|
{
|
||||||
value *result = string_operation::evaluate (expect_type, exp, noside);
|
struct type *char_type;
|
||||||
/* The result type will have code OP_STRING, bashed there from
|
if (expect_type != nullptr && ada_is_string_type (expect_type))
|
||||||
OP_ARRAY. Bash it back. */
|
char_type = ada_array_element_type (expect_type, 1);
|
||||||
if (value_type (result)->code () == TYPE_CODE_STRING)
|
else
|
||||||
value_type (result)->set_code (TYPE_CODE_ARRAY);
|
char_type = language_string_char_type (exp->language_defn, exp->gdbarch);
|
||||||
return result;
|
|
||||||
|
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 *
|
value *
|
||||||
|
@ -43,3 +43,7 @@ gdb_test "print my_wws(1)" "= 32 ' '"
|
|||||||
|
|
||||||
gdb_test "print my_wws(2)" "= 104 'h'"
|
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"
|
||||||
|
@ -19,9 +19,11 @@ procedure Foo is
|
|||||||
Some_Easy : Wide_Wide_Character := 'J';
|
Some_Easy : Wide_Wide_Character := 'J';
|
||||||
Some_Larger : Wide_Wide_Character := Wide_Wide_Character'Val(16#beef#);
|
Some_Larger : Wide_Wide_Character := Wide_Wide_Character'Val(16#beef#);
|
||||||
Some_Big : Wide_Wide_Character := Wide_Wide_Character'Val(16#00dabeef#);
|
Some_Big : Wide_Wide_Character := Wide_Wide_Character'Val(16#00dabeef#);
|
||||||
|
My_Ws : Wide_String := "wide";
|
||||||
My_WWS : Wide_Wide_String := " helo";
|
My_WWS : Wide_Wide_String := " helo";
|
||||||
begin
|
begin
|
||||||
Do_Nothing (Some_Easy'Address); -- START
|
Do_Nothing (Some_Easy'Address); -- START
|
||||||
Do_Nothing (Some_Larger'Address);
|
Do_Nothing (Some_Larger'Address);
|
||||||
|
Do_Nothing (My_Ws'Address);
|
||||||
Do_Nothing (Some_Big'Address);
|
Do_Nothing (Some_Big'Address);
|
||||||
end Foo;
|
end Foo;
|
||||||
|
Reference in New Issue
Block a user