aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-name-parser.y
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2024-04-19 20:22:11 -0600
committerTom Tromey <tom@tromey.com>2024-05-14 13:28:40 -0600
commita4b7c5f5cda16795dd8be11494e8f1b5de21d69f (patch)
tree793808a959af265d3e86677a8334aff6f3cd3c98 /gdb/cp-name-parser.y
parent383a3d99c361ff66b9b5bceb28c0ab9485cd1789 (diff)
downloadbinutils-a4b7c5f5cda16795dd8be11494e8f1b5de21d69f.zip
binutils-a4b7c5f5cda16795dd8be11494e8f1b5de21d69f.tar.gz
binutils-a4b7c5f5cda16795dd8be11494e8f1b5de21d69f.tar.bz2
Implement C++14 numeric separators
C++14 allows the use of the apostrophe as a numeric separator; that is, "23000" and "23'000" represent the same number. This patch implements this for gdb's C++ parser and the C++ name canonicalizer. I did this unconditionally for all C variants because I think it's unambiguous. For the name canonicalizer, there's at least one compiler that can emit constants with this form, see bug 30845. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23457 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30845 Approved-By: John Baldwin <jhb@FreeBSD.org>
Diffstat (limited to 'gdb/cp-name-parser.y')
-rw-r--r--gdb/cp-name-parser.y31
1 files changed, 26 insertions, 5 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index a84051a..c0138ef 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -1686,6 +1686,10 @@ yylex (YYSTYPE *lvalp, cpname_state *state)
hex = 0;
}
+ /* If the token includes the C++14 digits separator, we make a
+ copy so that we don't have to handle the separator in
+ parse_number. */
+ std::optional<std::string> no_tick;
for (;; ++p)
{
/* This test includes !hex because 'e' is a valid hex digit
@@ -1703,16 +1707,31 @@ yylex (YYSTYPE *lvalp, cpname_state *state)
got_dot = 1;
else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
&& (*p == '-' || *p == '+'))
- /* This is the sign of the exponent, not the end of the
- number. */
- continue;
+ {
+ /* This is the sign of the exponent, not the end of
+ the number. */
+ }
+ /* C++14 allows a separator. */
+ else if (*p == '\'')
+ {
+ if (!no_tick.has_value ())
+ no_tick.emplace (tokstart, p);
+ continue;
+ }
/* We will take any letters or digits. parse_number will
complain if past the radix, or if L or U are not final. */
else if (! ISALNUM (*p))
break;
+ if (no_tick.has_value ())
+ no_tick->push_back (*p);
}
- toktype = state->parse_number (tokstart, p - tokstart, got_dot|got_e,
- lvalp);
+ if (no_tick.has_value ())
+ toktype = state->parse_number (no_tick->c_str (),
+ no_tick->length (),
+ got_dot|got_e, lvalp);
+ else
+ toktype = state->parse_number (tokstart, p - tokstart,
+ got_dot|got_e, lvalp);
if (toktype == ERROR)
{
yyerror (state, _("invalid number"));
@@ -2041,6 +2060,8 @@ canonicalize_tests ()
should_be_the_same ("x::y::z<0b111>", "x::y::z<7>");
should_be_the_same ("x::y::z<0b111>", "x::y::z<0t7>");
should_be_the_same ("x::y::z<0b111>", "x::y::z<0D7>");
+
+ should_be_the_same ("x::y::z<0xff'ff>", "x::y::z<65535>");
}
#endif