mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-24 12:35:55 +08:00
Add 128-bit integer support to the Ada parser
This adds support for 128-bit integers to the Ada parser. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30188
This commit is contained in:
parent
8a2ced4fe4
commit
e49831ba43
@ -68,6 +68,11 @@ static struct parser_state *pstate = NULL;
|
||||
/* The original expression string. */
|
||||
static const char *original_expr;
|
||||
|
||||
/* We don't have a good way to manage non-POD data in Yacc, so store
|
||||
values here. The storage here is only valid for the duration of
|
||||
the parse. */
|
||||
static std::vector<std::unique_ptr<gdb_mpz>> int_storage;
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
static int yylex (void);
|
||||
@ -416,9 +421,13 @@ make_tick_completer (struct stoken tok)
|
||||
{
|
||||
LONGEST lval;
|
||||
struct {
|
||||
LONGEST val;
|
||||
const gdb_mpz *val;
|
||||
struct type *type;
|
||||
} typed_val;
|
||||
struct {
|
||||
LONGEST val;
|
||||
struct type *type;
|
||||
} typed_char;
|
||||
struct {
|
||||
gdb_byte val[16];
|
||||
struct type *type;
|
||||
@ -433,7 +442,8 @@ make_tick_completer (struct stoken tok)
|
||||
%type <lval> aggregate_component_list
|
||||
%type <tval> var_or_type type_prefix opt_type_prefix
|
||||
|
||||
%token <typed_val> INT NULL_PTR CHARLIT
|
||||
%token <typed_val> INT NULL_PTR
|
||||
%token <typed_char> CHARLIT
|
||||
%token <typed_val_float> FLOAT
|
||||
%token TRUEKEYWORD FALSEKEYWORD
|
||||
%token COLONCOLON
|
||||
@ -867,7 +877,7 @@ primary : primary TICK_ACCESS
|
||||
tick_arglist : %prec '('
|
||||
{ $$ = 1; }
|
||||
| '(' INT ')'
|
||||
{ $$ = $2.val; }
|
||||
{ $$ = $2.val->as_integer<LONGEST> (); }
|
||||
;
|
||||
|
||||
type_prefix :
|
||||
@ -888,7 +898,10 @@ opt_type_prefix :
|
||||
|
||||
|
||||
primary : INT
|
||||
{ write_int (pstate, (LONGEST) $1.val, $1.type); }
|
||||
{
|
||||
pstate->push_new<long_const_operation> ($1.type, *$1.val);
|
||||
ada_wrap<ada_wrapped_operation> ();
|
||||
}
|
||||
;
|
||||
|
||||
primary : CHARLIT
|
||||
@ -1144,6 +1157,7 @@ ada_parse (struct parser_state *par_state)
|
||||
obstack_init (&temp_parse_space);
|
||||
components.clear ();
|
||||
associations.clear ();
|
||||
int_storage.clear ();
|
||||
|
||||
int result = yyparse ();
|
||||
if (!result)
|
||||
|
@ -13544,6 +13544,8 @@ class ada_language : public language_defn
|
||||
"long_float", gdbarch_double_format (gdbarch)));
|
||||
add (init_integer_type (alloc, gdbarch_long_long_bit (gdbarch),
|
||||
0, "long_long_integer"));
|
||||
add (init_integer_type (alloc, 128, 0, "long_long_long_integer"));
|
||||
add (init_integer_type (alloc, 128, 1, "unsigned_long_long_long_integer"));
|
||||
add (init_float_type (alloc, gdbarch_long_double_bit (gdbarch),
|
||||
"long_long_float",
|
||||
gdbarch_long_double_format (gdbarch)));
|
||||
|
@ -179,15 +179,15 @@ static int paren_depth;
|
||||
}
|
||||
|
||||
<INITIAL>"'"({GRAPHIC}|\")"'" {
|
||||
yylval.typed_val.val = yytext[1];
|
||||
yylval.typed_val.type = type_for_char (pstate, yytext[1]);
|
||||
yylval.typed_char.val = yytext[1];
|
||||
yylval.typed_char.type = type_for_char (pstate, yytext[1]);
|
||||
return CHARLIT;
|
||||
}
|
||||
|
||||
<INITIAL>"'[\""{HEXDIG}{2,}"\"]'" {
|
||||
ULONGEST v = strtoulst (yytext+3, nullptr, 16);
|
||||
yylval.typed_val.val = v;
|
||||
yylval.typed_val.type = type_for_char (pstate, v);
|
||||
yylval.typed_char.val = v;
|
||||
yylval.typed_char.type = type_for_char (pstate, v);
|
||||
return CHARLIT;
|
||||
}
|
||||
|
||||
@ -462,52 +462,35 @@ processInt (struct parser_state *par_state, const char *base0,
|
||||
return FLOAT;
|
||||
}
|
||||
|
||||
if (result > gdb_mpz (ULONGEST_MAX))
|
||||
error (_("Integer literal out of range"));
|
||||
int_storage.emplace_back (new gdb_mpz (std::move (result)));
|
||||
const gdb_mpz *value = int_storage.back ().get ();
|
||||
|
||||
int int_bits = gdbarch_int_bit (par_state->gdbarch ());
|
||||
int long_bits = gdbarch_long_bit (par_state->gdbarch ());
|
||||
int long_long_bits = gdbarch_long_long_bit (par_state->gdbarch ());
|
||||
|
||||
ULONGEST value = result.as_integer<ULONGEST> ();
|
||||
if (fits_in_type (1, value, int_bits, true))
|
||||
if (fits_in_type (1, *value, int_bits, true))
|
||||
yylval.typed_val.type = parse_type (par_state)->builtin_int;
|
||||
else if (fits_in_type (1, value, long_bits, true))
|
||||
else if (fits_in_type (1, *value, long_bits, true))
|
||||
yylval.typed_val.type = parse_type (par_state)->builtin_long;
|
||||
else if (fits_in_type (1, value, long_bits, false))
|
||||
{
|
||||
/* We have a number representable as an unsigned integer quantity.
|
||||
For consistency with the C treatment, we will treat it as an
|
||||
anonymous modular (unsigned) quantity. Alas, the types are such
|
||||
that we need to store .val as a signed quantity. Sorry
|
||||
for the mess, but C doesn't officially guarantee that a simple
|
||||
assignment does the trick (no, it doesn't; read the reference manual).
|
||||
*/
|
||||
yylval.typed_val.type
|
||||
= builtin_type (par_state->gdbarch ())->builtin_unsigned_long;
|
||||
if (value & LONGEST_SIGN)
|
||||
yylval.typed_val.val =
|
||||
(LONGEST) (value & ~LONGEST_SIGN)
|
||||
- (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
|
||||
else
|
||||
yylval.typed_val.val = (LONGEST) value;
|
||||
return INT;
|
||||
}
|
||||
else if (fits_in_type (1, value, long_long_bits, true))
|
||||
else if (fits_in_type (1, *value, long_bits, false))
|
||||
yylval.typed_val.type
|
||||
= builtin_type (par_state->gdbarch ())->builtin_unsigned_long;
|
||||
else if (fits_in_type (1, *value, long_long_bits, true))
|
||||
yylval.typed_val.type = parse_type (par_state)->builtin_long_long;
|
||||
else if (fits_in_type (1, value, long_long_bits, false))
|
||||
{
|
||||
yylval.typed_val.type
|
||||
= builtin_type (par_state->gdbarch ())->builtin_unsigned_long_long;
|
||||
/* See unsigned long case above. */
|
||||
if (value & LONGEST_SIGN)
|
||||
yylval.typed_val.val =
|
||||
(LONGEST) (value & ~LONGEST_SIGN)
|
||||
- (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
|
||||
else
|
||||
yylval.typed_val.val = (LONGEST) value;
|
||||
return INT;
|
||||
}
|
||||
else if (fits_in_type (1, *value, long_long_bits, false))
|
||||
yylval.typed_val.type
|
||||
= builtin_type (par_state->gdbarch ())->builtin_unsigned_long_long;
|
||||
else if (fits_in_type (1, *value, 128, true))
|
||||
yylval.typed_val.type
|
||||
= language_lookup_primitive_type (par_state->language (),
|
||||
par_state->gdbarch (),
|
||||
"long_long_long_integer");
|
||||
else if (fits_in_type (1, *value, 128, false))
|
||||
yylval.typed_val.type
|
||||
= language_lookup_primitive_type (par_state->language (),
|
||||
par_state->gdbarch (),
|
||||
"unsigned_long_long_long_integer");
|
||||
else
|
||||
error (_("Integer literal out of range"));
|
||||
|
||||
|
@ -36,3 +36,8 @@ gdb_test "print x - x" " = 0"
|
||||
gdb_test "print x - 99 + 1" " = 170141183460469231731687303715884105629"
|
||||
gdb_test "print -x" " = -170141183460469231731687303715884105727"
|
||||
gdb_test "print +x" " = 170141183460469231731687303715884105727"
|
||||
|
||||
gdb_test "print 170141183460469231731687303715884105727" \
|
||||
" = 170141183460469231731687303715884105727"
|
||||
gdb_test "print x = 170141183460469231731687303715884105727" \
|
||||
" = true"
|
||||
|
Loading…
Reference in New Issue
Block a user