static struct type *type_long_double (struct parser_state *);
-static struct type *type_char (struct parser_state *);
+static struct type *type_for_char (struct parser_state *, ULONGEST);
static struct type *type_boolean (struct parser_state *);
}
static struct type *
-type_char (struct parser_state *par_state)
+type_for_char (struct parser_state *par_state, ULONGEST value)
{
- return language_string_char_type (par_state->language (),
- par_state->gdbarch ());
+ if (value <= 0xff)
+ return language_string_char_type (par_state->language (),
+ par_state->gdbarch ());
+ else if (value <= 0xffff)
+ return language_lookup_primitive_type (par_state->language (),
+ par_state->gdbarch (),
+ "wide_character");
+ return language_lookup_primitive_type (par_state->language (),
+ par_state->gdbarch (),
+ "wide_wide_character");
}
static struct type *
return std::move (owner);
}
-/* Convert the character literal whose ASCII value would be VAL to the
+/* Convert the character literal whose value would be VAL to the
appropriate value of type TYPE, if there is a translation.
Otherwise return VAL. Hence, in an enumeration type ('A', 'B'),
the literal 'A' (VAL == 65), returns 0. */
static LONGEST
convert_char_literal (struct type *type, LONGEST val)
{
- char name[7];
+ char name[12];
int f;
if (type == NULL)
if ((val >= 'a' && val <= 'z') || (val >= '0' && val <= '9'))
xsnprintf (name, sizeof (name), "Q%c", (int) val);
+ else if (val >= 0 && val < 256)
+ xsnprintf (name, sizeof (name), "QU%02x", (unsigned) val);
+ else if (val >= 0 && val < 0x10000)
+ xsnprintf (name, sizeof (name), "QW%04x", (unsigned) val);
else
- xsnprintf (name, sizeof (name), "QU%02x", (int) val);
+ xsnprintf (name, sizeof (name), "QWW%08lx", (unsigned long) val);
size_t len = strlen (name);
for (f = 0; f < type->num_fields (); f += 1)
{
add (arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch),
0, "short_integer"));
struct type *char_type = arch_character_type (gdbarch, TARGET_CHAR_BIT,
- 0, "character");
+ 1, "character");
lai->set_string_char_type (char_type);
add (char_type);
+ add (arch_character_type (gdbarch, 16, 1, "wide_character"));
+ add (arch_character_type (gdbarch, 32, 1, "wide_wide_character"));
add (arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
"float", gdbarch_float_format (gdbarch)));
add (arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
-/* FLEX lexer for Ada expressions, for GDB.
+/* FLEX lexer for Ada expressions, for GDB. -*- c++ -*-
Copyright (C) 1994-2022 Free Software Foundation, Inc.
This file is part of GDB.
}
<INITIAL>"'"({GRAPHIC}|\")"'" {
- yylval.typed_val.type = type_char (pstate);
yylval.typed_val.val = yytext[1];
+ yylval.typed_val.type = type_for_char (pstate, yytext[1]);
return CHARLIT;
}
-<INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
- int v;
- yylval.typed_val.type = type_char (pstate);
- sscanf (yytext+3, "%2x", &v);
+<INITIAL>"'[\""{HEXDIG}{2,}"\"]'" {
+ ULONGEST v = strtoulst (yytext+3, nullptr, 16);
yylval.typed_val.val = v;
+ yylval.typed_val.type = type_for_char (pstate, v);
return CHARLIT;
}
-\"({GRAPHIC}|"[\""({HEXDIG}{2}|\")"\"]")*\" {
+ /* Note that we don't handle bracket sequences of more than 2
+ digits here. Currently there's no support for wide or
+ wide-wide strings. */
+\"({GRAPHIC}|"[\""({HEXDIG}{2,}|\")"\"]")*\" {
yylval.sval = processString (yytext+1, yyleng-2);
return STRING;
}
}
else
{
- int chr;
- sscanf (p+2, "%2x", &chr);
+ const char *end;
+ ULONGEST chr = strtoulst (p + 2, &end, 16);
+ if (chr > 0xff)
+ error (_("wide strings are not yet supported"));
*q = (char) chr;
- p += 5;
+ p = end + 1;
}
}
else
fprintf_filtered (stream, "%c", c);
}
else
- fprintf_filtered (stream, "[\"%0*x\"]", type_len * 2, c);
+ {
+ /* Follow GNAT's lead here and only use 6 digits for
+ wide_wide_character. */
+ fprintf_filtered (stream, "[\"%0*x\"]", std::min (6, type_len * 2), c);
+ }
}
/* Character #I of STRING, given that TYPE_LEN is the size in bytes
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'('\[\"0178\"\]')" " = 2 $y"
+gdb_test "print Char_Enum_Type'('\[\"1fa00\"\]')" " = 3 $king"
gdb_test "print Char_Enum_Type'('\[\"de\"\]')" " = 4 $thorn"
+
+gdb_test "print '\[\"0178\"\]'" " = 376 $y"
+gdb_test "print '\[\"01fa00\"\]'" " = 129536 $king"
+gdb_test "print '\[\"de\"\]'" " = 222 $thorn"
+
+gdb_test "print \"\[\"0178\"\]\"" "wide strings are not yet supported"
+gdb_test "print \"\[\"de\"\]\"" " = \"\\\[\"de\"\\\]\""
gdb_test "print some_easy" "= 74 'J'"
-gdb_test "print some_larger" "= 48879 '\\\[\"0000beef\"\\\]'"
+gdb_test "print some_larger" "= 48879 '\\\[\"00beef\"\\\]'"
-gdb_test "print some_big" "= 14335727 '\\\[\"00dabeef\"\\\]'"
+gdb_test "print some_big" "= 14335727 '\\\[\"dabeef\"\\\]'"
gdb_test "print my_wws" "= \" helo\""