* [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers
@ 2023-03-28 15:49 Tom Tromey
2023-03-28 15:49 ` [PATCH 1/6] Additions to gdb_mpz Tom Tromey
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
This series changes the Ada and Rust parser to support 128-bit types.
It would be reasonably easy to add this for C/C++ as well, following
the Ada model, but I haven't done this.
Regression tested on x86-64 Fedora 36.
Tom
---
Tom Tromey (6):
Additions to gdb_mpz
Convert long_const_operation to use gdb_mpz
Add 128-bit integer support to the Rust parser
Add overload of fits_in_type
Remove some Ada parser helper functions
Add 128-bit integer support to the Ada parser
gdb/ada-exp.y | 74 ++++++++++++--------------------
gdb/ada-lang.c | 6 ++-
gdb/ada-lex.l | 75 +++++++++++++--------------------
gdb/ax-gdb.c | 4 +-
gdb/expop.h | 26 ++++++++++--
gdb/expprint.c | 6 +++
gdb/gmp-utils.c | 10 +++--
gdb/gmp-utils.h | 48 ++++++++++++++++++++-
gdb/parse.c | 26 ++++++++++++
gdb/parser-defs.h | 2 +
gdb/rust-lang.c | 2 +
gdb/rust-parse.c | 37 ++++++++++------
gdb/testsuite/gdb.ada/verylong.exp | 5 +++
gdb/testsuite/gdb.base/parse_number.exp | 9 ++--
gdb/testsuite/gdb.rust/onetwoeight.exp | 4 ++
15 files changed, 211 insertions(+), 123 deletions(-)
---
base-commit: 134ec14b1502f30f0028293b35f57c18e44614d0
change-id: 20230328-expr-128-bit-d8d749b7089a
Best regards,
--
Tom Tromey <tromey@adacore.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] Additions to gdb_mpz
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
@ 2023-03-28 15:49 ` Tom Tromey
2023-03-28 15:49 ` [PATCH 2/6] Convert long_const_operation to use gdb_mpz Tom Tromey
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
In preparation for adding more 128-bit support to gdb, a few additions
to gdb_mpz are needed.
First, this adds a new 'as_integer_truncate' method. This method
works like 'as_integer' but does not require the value to fit in the
target type -- it just truncates.
Second, gdb_mpz::export_bits is changed to handle the somewhat unusual
situation of zero-length types. This can happen for a Rust '()' type;
but I think other languages have zero-bit integer types as well.
Finally, this adds some operator== overloads.
---
gdb/gmp-utils.c | 10 ++++++----
gdb/gmp-utils.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/gdb/gmp-utils.c b/gdb/gmp-utils.c
index 0afa344781b..13fa61d61e3 100644
--- a/gdb/gmp-utils.c
+++ b/gdb/gmp-utils.c
@@ -69,19 +69,21 @@ void
gdb_mpz::export_bits (gdb::array_view<gdb_byte> buf, int endian, bool unsigned_p,
bool safe) const
{
- gdb_assert (buf.size () > 0);
-
int sign = mpz_sgn (m_val);
if (sign == 0)
{
/* Our value is zero, so no need to call mpz_export to do the work,
especially since mpz_export's documentation explicitly says
that the function is a noop in this case. Just write zero to
- BUF ourselves. */
- memset (buf.data (), 0, buf.size ());
+ BUF ourselves, if it is non-empty. In some languages, a
+ zero-bit type can exist and this is also fine. */
+ if (buf.size () > 0)
+ memset (buf.data (), 0, buf.size ());
return;
}
+ gdb_assert (buf.size () > 0);
+
if (safe)
{
/* Determine the maximum range of values that our buffer can
diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h
index f294ab622ee..d05c11ecbe4 100644
--- a/gdb/gmp-utils.h
+++ b/gdb/gmp-utils.h
@@ -119,11 +119,17 @@ struct gdb_mpz
return result;
}
- /* Convert VAL to an integer of the given type.
+ /* Convert this value to an integer of the given type.
The return type can signed or unsigned, with no size restriction. */
template<typename T> T as_integer () const;
+ /* Convert this value to an integer of the given type. If this
+ value is too large, it is truncated.
+
+ The return type can signed or unsigned, with no size restriction. */
+ template<typename T> T as_integer_truncate () const;
+
/* Set VAL by importing the number stored in the byte array (BUF),
using the given BYTE_ORDER. The size of the data to read is
the byte array's size.
@@ -312,7 +318,7 @@ struct gdb_mpz
return mpz_cmp (m_val, other.m_val) <= 0;
}
- bool operator< (int other) const
+ bool operator< (long other) const
{
return mpz_cmp_si (m_val, other) < 0;
}
@@ -322,6 +328,28 @@ struct gdb_mpz
return mpz_cmp_si (m_val, other) == 0;
}
+ bool operator== (long other) const
+ {
+ return mpz_cmp_si (m_val, other) == 0;
+ }
+
+ bool operator== (unsigned long other) const
+ {
+ return mpz_cmp_ui (m_val, other) == 0;
+ }
+
+ template<typename T,
+ typename = gdb::Requires<
+ gdb::And<std::is_integral<T>,
+ std::integral_constant<bool,
+ (sizeof (T) > sizeof (long))>>
+ >
+ >
+ bool operator== (T src)
+ {
+ return *this == gdb_mpz (src);
+ }
+
bool operator== (const gdb_mpz &other) const
{
return mpz_cmp (m_val, other.m_val) == 0;
@@ -612,4 +640,20 @@ gdb_mpz::as_integer () const
return result;
}
+/* See declaration above. */
+
+template<typename T>
+T
+gdb_mpz::as_integer_truncate () const
+{
+ T result;
+
+ this->export_bits ({(gdb_byte *) &result, sizeof (result)},
+ 0 /* endian (0 = native) */,
+ !std::is_signed<T>::value /* unsigned_p */,
+ false /* safe */);
+
+ return result;
+}
+
#endif
--
2.39.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/6] Convert long_const_operation to use gdb_mpz
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
2023-03-28 15:49 ` [PATCH 1/6] Additions to gdb_mpz Tom Tromey
@ 2023-03-28 15:49 ` Tom Tromey
2023-03-28 15:49 ` [PATCH 3/6] Add 128-bit integer support to the Rust parser Tom Tromey
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
This changes long_const_operation to use gdb_mpz for its storage.
---
gdb/ada-lang.c | 4 ++--
gdb/ax-gdb.c | 4 ++--
gdb/expop.h | 26 +++++++++++++++++++++++---
gdb/expprint.c | 6 ++++++
4 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 5301c72d514..e51fd082d73 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10612,10 +10612,10 @@ ada_char_operation::replace (operation_up &&owner,
if (context_type != nullptr && context_type->code () == TYPE_CODE_ENUM)
{
+ LONGEST val = as_longest ();
gdb_assert (result.get () == this);
std::get<0> (m_storage) = context_type;
- std::get<1> (m_storage)
- = convert_char_literal (context_type, std::get<1> (m_storage));
+ std::get<1> (m_storage) = convert_char_literal (context_type, val);
}
return result;
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 1ed648ce002..9dda7fe524d 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -1630,8 +1630,8 @@ long_const_operation::do_generate_ax (struct expression *exp,
struct axs_value *value,
struct type *cast_type)
{
- gen_int_literal (ax, value, std::get<1> (m_storage),
- std::get<0> (m_storage));
+ LONGEST val = as_longest ();
+ gen_int_literal (ax, value, val, std::get<0> (m_storage));
}
void
diff --git a/gdb/expop.h b/gdb/expop.h
index d973d2314bb..854945c8688 100644
--- a/gdb/expop.h
+++ b/gdb/expop.h
@@ -274,6 +274,12 @@ check_objfile (ULONGEST val, struct objfile *objfile)
return false;
}
+static inline bool
+check_objfile (const gdb_mpz &val, struct objfile *objfile)
+{
+ return false;
+}
+
template<typename T>
static inline bool
check_objfile (enum_flags<T> val, struct objfile *objfile)
@@ -319,6 +325,8 @@ extern void dump_for_expression (struct ui_file *stream, int depth,
struct type *type);
extern void dump_for_expression (struct ui_file *stream, int depth,
CORE_ADDR addr);
+extern void dump_for_expression (struct ui_file *stream, int depth,
+ const gdb_mpz &addr);
extern void dump_for_expression (struct ui_file *stream, int depth,
internalvar *ivar);
extern void dump_for_expression (struct ui_file *stream, int depth,
@@ -468,6 +476,12 @@ check_constant (ULONGEST cst)
return true;
}
+static inline bool
+check_constant (const gdb_mpz &cst)
+{
+ return true;
+}
+
static inline bool
check_constant (struct symbol *sym)
{
@@ -665,18 +679,21 @@ class var_value_operation
};
class long_const_operation
- : public tuple_holding_operation<struct type *, LONGEST>
+ : public tuple_holding_operation<struct type *, gdb_mpz>
{
public:
using tuple_holding_operation::tuple_holding_operation;
+ long_const_operation (struct type *type, LONGEST val)
+ : long_const_operation (type, gdb_mpz (val))
+ { }
+
value *evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside) override
{
- return value_from_longest (std::get<0> (m_storage),
- std::get<1> (m_storage));
+ return value_from_mpz (std::get<0> (m_storage), std::get<1> (m_storage));
}
enum exp_opcode opcode () const override
@@ -687,6 +704,9 @@ class long_const_operation
protected:
+ LONGEST as_longest () const
+ { return std::get<1> (m_storage).as_integer_truncate<LONGEST> (); }
+
void do_generate_ax (struct expression *exp,
struct agent_expr *ax,
struct axs_value *value,
diff --git a/gdb/expprint.c b/gdb/expprint.c
index 0c7cc754179..e0ec25573c2 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -108,6 +108,12 @@ dump_for_expression (struct ui_file *stream, int depth, CORE_ADDR addr)
core_addr_to_string (addr));
}
+void
+dump_for_expression (struct ui_file *stream, int depth, const gdb_mpz &val)
+{
+ gdb_printf (stream, _("%*sConstant: %s\n"), depth, "", val.str ().c_str ());
+}
+
void
dump_for_expression (struct ui_file *stream, int depth, internalvar *ivar)
{
--
2.39.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/6] Add 128-bit integer support to the Rust parser
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
2023-03-28 15:49 ` [PATCH 1/6] Additions to gdb_mpz Tom Tromey
2023-03-28 15:49 ` [PATCH 2/6] Convert long_const_operation to use gdb_mpz Tom Tromey
@ 2023-03-28 15:49 ` Tom Tromey
2023-03-28 15:49 ` [PATCH 4/6] Add overload of fits_in_type Tom Tromey
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
This adds support for 128-bit integers to the Rust parser.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=21185
---
gdb/rust-lang.c | 2 ++
gdb/rust-parse.c | 37 ++++++++++++++++++++-------------
gdb/testsuite/gdb.base/parse_number.exp | 7 ++++---
gdb/testsuite/gdb.rust/onetwoeight.exp | 4 ++++
4 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index cb128f13f0e..3ef8fcaa329 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -1607,6 +1607,8 @@ rust_language::language_arch_info (struct gdbarch *gdbarch,
add (init_integer_type (alloc, 32, 1, "u32"));
add (init_integer_type (alloc, 64, 0, "i64"));
add (init_integer_type (alloc, 64, 1, "u64"));
+ add (init_integer_type (alloc, 128, 0, "i128"));
+ add (init_integer_type (alloc, 128, 1, "u128"));
unsigned int length = 8 * builtin->builtin_data_ptr->length ();
add (init_integer_type (alloc, length, 0, "isize"));
diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c
index eca98aa286f..6c7922de9c7 100644
--- a/gdb/rust-parse.c
+++ b/gdb/rust-parse.c
@@ -69,7 +69,7 @@ static const char number_regex_text[] =
#define INT_TEXT 5
#define INT_TYPE 6
"(0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*)"
- "([iu](size|8|16|32|64))?"
+ "([iu](size|8|16|32|64|128))?"
")";
/* The number of subexpressions to allocate space for, including the
"0th" whole match subexpression. */
@@ -126,7 +126,7 @@ enum token_type : int
struct typed_val_int
{
- ULONGEST val;
+ gdb_mpz val;
struct type *type;
};
@@ -1007,7 +1007,6 @@ rust_parser::lex_number ()
/* Parse the number. */
if (is_integer)
{
- uint64_t value;
int radix = 10;
int offset = 0;
@@ -1026,14 +1025,22 @@ rust_parser::lex_number ()
}
}
- const char *trailer;
- value = strtoulst (number.c_str () + offset, &trailer, radix);
- if (*trailer != '\0')
- error (_("Integer literal is too large"));
- if (implicit_i32 && value >= ((uint64_t) 1) << 31)
- type = get_type ("i64");
+ if (!current_int_val.val.set (number.c_str () + offset, radix))
+ {
+ /* Shouldn't be possible. */
+ error (_("Invalid integer"));
+ }
+ if (implicit_i32)
+ {
+ static gdb_mpz sixty_three_bit = gdb_mpz::pow (2, 63);
+ static gdb_mpz thirty_one_bit = gdb_mpz::pow (2, 31);
+
+ if (current_int_val.val >= sixty_three_bit)
+ type = get_type ("i128");
+ else if (current_int_val.val >= thirty_one_bit)
+ type = get_type ("i64");
+ }
- current_int_val.val = value;
current_int_val.type = type;
}
else
@@ -1556,9 +1563,11 @@ rust_parser::parse_field (operation_up &&lhs)
break;
case DECIMAL_INTEGER:
- result = make_operation<rust_struct_anon> (current_int_val.val,
- std::move (lhs));
- lex ();
+ {
+ int idx = current_int_val.val.as_integer<int> ();
+ result = make_operation<rust_struct_anon> (idx, std::move (lhs));
+ lex ();
+ }
break;
case INTEGER:
@@ -1659,7 +1668,7 @@ rust_parser::parse_array_type ()
if (current_token != INTEGER && current_token != DECIMAL_INTEGER)
error (_("integer expected"));
- ULONGEST val = current_int_val.val;
+ ULONGEST val = current_int_val.val.as_integer<ULONGEST> ();
lex ();
require (']');
diff --git a/gdb/testsuite/gdb.base/parse_number.exp b/gdb/testsuite/gdb.base/parse_number.exp
index 07104433a16..5dd4fa705e9 100644
--- a/gdb/testsuite/gdb.base/parse_number.exp
+++ b/gdb/testsuite/gdb.base/parse_number.exp
@@ -108,9 +108,10 @@ proc parse_number { lang n } {
return [list "i32" $n]
} elseif { [fits_in_type $n 64 s] } {
return [list "i64" $n]
- } elseif { [fits_in_type $n 64 u] } {
- # Note: Interprets MAX_U64 as -1.
- return [list "i64" $n]
+ } elseif { [fits_in_type $n 128 u] } {
+ return [list "i128" $n]
+ } elseif { [fits_in_type $n 128 u] } {
+ return [list "i128" $n]
} else {
# Overflow.
return [list $re_overflow $re_overflow]
diff --git a/gdb/testsuite/gdb.rust/onetwoeight.exp b/gdb/testsuite/gdb.rust/onetwoeight.exp
index ef56bcafda2..5ca30712830 100644
--- a/gdb/testsuite/gdb.rust/onetwoeight.exp
+++ b/gdb/testsuite/gdb.rust/onetwoeight.exp
@@ -64,3 +64,7 @@ gdb_test "print x >> 2" "= 85070591730234615865843651857942052863"
gdb_test "print/x x & mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0"
gdb_test "print/x x ^ mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"
gdb_test "print/x mask | (mask >> 4)" " = 0xffffffffffffffffffffffffffffffff"
+
+gdb_test "print 170141183460469231731687303715884105727" \
+ " = 170141183460469231731687303715884105727"
+gdb_test "ptype 23i128" "type = i128"
--
2.39.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/6] Add overload of fits_in_type
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
` (2 preceding siblings ...)
2023-03-28 15:49 ` [PATCH 3/6] Add 128-bit integer support to the Rust parser Tom Tromey
@ 2023-03-28 15:49 ` Tom Tromey
2023-03-28 15:49 ` [PATCH 5/6] Remove some Ada parser helper functions Tom Tromey
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
This adds an overload of fits_in_type that accepts a gdb_mpz. A
subsequent patch will use this.
---
gdb/parse.c | 26 ++++++++++++++++++++++++++
gdb/parser-defs.h | 2 ++
2 files changed, 28 insertions(+)
diff --git a/gdb/parse.c b/gdb/parse.c
index 24db3ca57d9..23545e32160 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -648,6 +648,32 @@ fits_in_type (int n_sign, ULONGEST n, int type_bits, bool type_signed_p)
else
gdb_assert_not_reached ("");
}
+
+/* Return true if the number N_SIGN * N fits in a type with TYPE_BITS and
+ TYPE_SIGNED_P. N_SIGNED is either 1 or -1. */
+
+bool
+fits_in_type (int n_sign, const gdb_mpz &n, int type_bits, bool type_signed_p)
+{
+ /* N must be nonnegative. */
+ gdb_assert (n.sgn () >= 0);
+
+ /* Zero always fits. */
+ /* Normalize -0. */
+ if (n.sgn () == 0)
+ return true;
+
+ if (n_sign == -1 && !type_signed_p)
+ /* Can't fit a negative number in an unsigned type. */
+ return false;
+
+ gdb_mpz max = gdb_mpz::pow (2, (type_signed_p
+ ? type_bits - 1
+ : type_bits));
+ if (n_sign == -1)
+ return n <= max;
+ return n < max;
+}
\f
/* This function avoids direct calls to fprintf
in the parser generated debug code. */
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 1780d856744..62829a86f9a 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -414,6 +414,8 @@ extern bool parse_float (const char *p, int len,
const struct type *type, gdb_byte *data);
extern bool fits_in_type (int n_sign, ULONGEST n, int type_bits,
bool type_signed_p);
+extern bool fits_in_type (int n_sign, const gdb_mpz &n, int type_bits,
+ bool type_signed_p);
\f
/* Function used to avoid direct calls to fprintf
--
2.39.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/6] Remove some Ada parser helper functions
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
` (3 preceding siblings ...)
2023-03-28 15:49 ` [PATCH 4/6] Add overload of fits_in_type Tom Tromey
@ 2023-03-28 15:49 ` Tom Tromey
2023-03-28 15:49 ` [PATCH 6/6] Add 128-bit integer support to the Ada parser Tom Tromey
2023-04-17 17:03 ` [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
These helper functions in the Ada parser don't seem all that
worthwhile to me, so this patch removes them.
---
gdb/ada-exp.y | 52 ++++++---------------------------
gdb/ada-lex.l | 8 ++---
gdb/testsuite/gdb.base/parse_number.exp | 2 ++
3 files changed, 15 insertions(+), 47 deletions(-)
diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index a9c37bedff0..4095106bb09 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -93,18 +93,8 @@ static const struct block *block_lookup (const struct block *, const char *);
static void write_ambiguous_var (struct parser_state *,
const struct block *, const char *, int);
-static struct type *type_int (struct parser_state *);
-
-static struct type *type_long (struct parser_state *);
-
-static struct type *type_long_long (struct parser_state *);
-
-static struct type *type_long_double (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_system_address (struct parser_state *);
static std::string find_completion_bounds (struct parser_state *);
@@ -934,9 +924,15 @@ primary : STRING
;
primary : TRUEKEYWORD
- { write_int (pstate, 1, type_boolean (pstate)); }
+ {
+ write_int (pstate, 1,
+ parse_type (pstate)->builtin_bool);
+ }
| FALSEKEYWORD
- { write_int (pstate, 0, type_boolean (pstate)); }
+ {
+ write_int (pstate, 0,
+ parse_type (pstate)->builtin_bool);
+ }
;
primary : NEW NAME
@@ -1268,7 +1264,7 @@ write_object_renaming (struct parser_state *par_state,
if (next == renaming_expr)
goto BadEncoding;
renaming_expr = next;
- write_int (par_state, val, type_int (par_state));
+ write_int (par_state, val, parse_type (par_state)->builtin_int);
}
else
{
@@ -1841,30 +1837,6 @@ write_name_assoc (struct parser_state *par_state, struct stoken name)
push_association<ada_name_association> (ada_pop ());
}
-static struct type *
-type_int (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_int;
-}
-
-static struct type *
-type_long (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_long;
-}
-
-static struct type *
-type_long_long (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_long_long;
-}
-
-static struct type *
-type_long_double (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_long_double;
-}
-
static struct type *
type_for_char (struct parser_state *par_state, ULONGEST value)
{
@@ -1880,12 +1852,6 @@ type_for_char (struct parser_state *par_state, ULONGEST value)
"wide_wide_character");
}
-static struct type *
-type_boolean (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_bool;
-}
-
static struct type *
type_system_address (struct parser_state *par_state)
{
diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l
index 69fc14f7107..0634f337cb2 100644
--- a/gdb/ada-lex.l
+++ b/gdb/ada-lex.l
@@ -471,9 +471,9 @@ processInt (struct parser_state *par_state, const char *base0,
ULONGEST value = result.as_integer<ULONGEST> ();
if (fits_in_type (1, value, int_bits, true))
- yylval.typed_val.type = type_int (par_state);
+ yylval.typed_val.type = parse_type (par_state)->builtin_int;
else if (fits_in_type (1, value, long_bits, true))
- yylval.typed_val.type = type_long (par_state);
+ 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.
@@ -494,7 +494,7 @@ processInt (struct parser_state *par_state, const char *base0,
return INT;
}
else if (fits_in_type (1, value, long_long_bits, true))
- yylval.typed_val.type = type_long_long (par_state);
+ 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
@@ -518,7 +518,7 @@ processInt (struct parser_state *par_state, const char *base0,
static int
processReal (struct parser_state *par_state, const char *num0)
{
- yylval.typed_val_float.type = type_long_double (par_state);
+ yylval.typed_val_float.type = parse_type (par_state)->builtin_long_double;
bool parsed = parse_float (num0, strlen (num0),
yylval.typed_val_float.type,
diff --git a/gdb/testsuite/gdb.base/parse_number.exp b/gdb/testsuite/gdb.base/parse_number.exp
index 5dd4fa705e9..8800dead53b 100644
--- a/gdb/testsuite/gdb.base/parse_number.exp
+++ b/gdb/testsuite/gdb.base/parse_number.exp
@@ -145,6 +145,8 @@ proc parse_number { lang n } {
} elseif { [fits_in_type $n $long_long_bits u] } {
# Note: Interprets ULLONG_MAX as -1.
return [list "<$sizeof_long_long-byte integer>" $n]
+ } elseif { [fits_in_type $n 128 u] } {
+ return [list "<16-byte integer>" $n]
} else {
# Overflow.
return [list $re_overflow $re_overflow]
--
2.39.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 6/6] Add 128-bit integer support to the Ada parser
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
` (4 preceding siblings ...)
2023-03-28 15:49 ` [PATCH 5/6] Remove some Ada parser helper functions Tom Tromey
@ 2023-03-28 15:49 ` Tom Tromey
2023-04-17 17:03 ` [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-03-28 15:49 UTC (permalink / raw)
To: gdb-patches
This adds support for 128-bit integers to the Ada parser.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30188
---
gdb/ada-exp.y | 22 ++++++++++---
gdb/ada-lang.c | 2 ++
gdb/ada-lex.l | 67 ++++++++++++++------------------------
gdb/testsuite/gdb.ada/verylong.exp | 5 +++
4 files changed, 50 insertions(+), 46 deletions(-)
diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index 4095106bb09..3e31d275046 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -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)
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index e51fd082d73..9c683888ade 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -13566,6 +13566,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)));
diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l
index 0634f337cb2..f2af21292f4 100644
--- a/gdb/ada-lex.l
+++ b/gdb/ada-lex.l
@@ -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"));
diff --git a/gdb/testsuite/gdb.ada/verylong.exp b/gdb/testsuite/gdb.ada/verylong.exp
index 93df785862b..c8ae63f744b 100644
--- a/gdb/testsuite/gdb.ada/verylong.exp
+++ b/gdb/testsuite/gdb.ada/verylong.exp
@@ -35,3 +35,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"
--
2.39.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
` (5 preceding siblings ...)
2023-03-28 15:49 ` [PATCH 6/6] Add 128-bit integer support to the Ada parser Tom Tromey
@ 2023-04-17 17:03 ` Tom Tromey
6 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2023-04-17 17:03 UTC (permalink / raw)
To: Tom Tromey via Gdb-patches; +Cc: Tom Tromey
>>>>> "Tom" == Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> writes:
Tom> This series changes the Ada and Rust parser to support 128-bit types.
Tom> It would be reasonably easy to add this for C/C++ as well, following
Tom> the Ada model, but I haven't done this.
Tom> Regression tested on x86-64 Fedora 36.
I've rebased this (no changes needed) and re-regression tested it.
I am checking it in.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-04-17 17:03 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-28 15:49 [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
2023-03-28 15:49 ` [PATCH 1/6] Additions to gdb_mpz Tom Tromey
2023-03-28 15:49 ` [PATCH 2/6] Convert long_const_operation to use gdb_mpz Tom Tromey
2023-03-28 15:49 ` [PATCH 3/6] Add 128-bit integer support to the Rust parser Tom Tromey
2023-03-28 15:49 ` [PATCH 4/6] Add overload of fits_in_type Tom Tromey
2023-03-28 15:49 ` [PATCH 5/6] Remove some Ada parser helper functions Tom Tromey
2023-03-28 15:49 ` [PATCH 6/6] Add 128-bit integer support to the Ada parser Tom Tromey
2023-04-17 17:03 ` [PATCH 0/6] Add 128-bit integers to Ada and Rust parsers Tom Tromey
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).