aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-name-parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/cp-name-parser.y')
-rw-r--r--gdb/cp-name-parser.y42
1 files changed, 33 insertions, 9 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 10f6e2d..7221b78 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -39,7 +39,6 @@
#include <unistd.h>
-#include "gdbsupport/gdb-safe-ctype.h"
#include "demangle.h"
#include "cp-support.h"
#include "c-support.h"
@@ -374,6 +373,22 @@ function
| colon_ext_only function_arglist start_opt
{ $$ = state->fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
if ($3) $$ = state->fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
+ | colon_ext_only
+ {
+ /* This production is a hack to handle
+ something like "name::operator new[]" --
+ without arguments, this ordinarily would
+ not parse, but canonicalizing it is
+ important. So we infer the "()" and then
+ remove it when converting back to string.
+ Note that this works because this
+ production is terminal. */
+ demangle_component *comp
+ = state->fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE,
+ nullptr, nullptr);
+ $$ = state->fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, comp);
+ state->demangle_info->added_parens = true;
+ }
| conversion_op_name start_opt
{ $$ = $1.comp;
@@ -1346,7 +1361,7 @@ cpname_state::parse_number (const char *p, int len, int parsed_float,
/* See if it has `f' or `l' suffix (float or long double). */
- c = TOLOWER (p[len - 1]);
+ c = c_tolower (p[len - 1]);
if (c == 'f')
{
@@ -1358,7 +1373,7 @@ cpname_state::parse_number (const char *p, int len, int parsed_float,
len--;
type = make_builtin_type ("long double");
}
- else if (ISDIGIT (c) || c == '.')
+ else if (c_isdigit (c) || c == '.')
type = make_builtin_type ("double");
else
return ERROR;
@@ -1423,10 +1438,10 @@ cpname_state::parse_number (const char *p, int len, int parsed_float,
for (int off = 0; off < len; ++off)
{
int dig;
- if (ISDIGIT (p[off]))
+ if (c_isdigit (p[off]))
dig = p[off] - '0';
else
- dig = TOLOWER (p[off]) - 'a' + 10;
+ dig = c_tolower (p[off]) - 'a' + 10;
if (dig >= base)
return ERROR;
value *= base;
@@ -1753,7 +1768,7 @@ yylex (YYSTYPE *lvalp, cpname_state *state)
}
/* 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))
+ else if (! c_isalnum (*p))
break;
if (no_tick.has_value ())
no_tick->push_back (*p);
@@ -2047,6 +2062,11 @@ cp_demangled_name_to_comp (const char *demangled_name,
auto result = std::make_unique<demangle_parse_info> ();
cpname_state state (demangled_name, result.get ());
+ /* Note that we can't set yydebug here, as is done in the other
+ parsers. Bison implements yydebug as a global, even with a pure
+ parser, and this parser is run from worker threads. So, changing
+ yydebug causes TSan reports. If you need to debug this parser,
+ debug gdb and set the global from the outer gdb. */
if (yyparse (&state))
{
if (state.global_errmsg && errmsg)
@@ -2106,13 +2126,17 @@ canonicalize_tests ()
should_be_the_same ("Foozle<int>::fogey<Empty<int> > (Empty<int>)",
"Foozle<int>::fogey<Empty<int>> (Empty<int>)");
+
+ should_be_the_same ("something :: operator new [ ]",
+ "something::operator new[]");
+ should_be_the_same ("something :: operator new",
+ "something::operator new");
+ should_be_the_same ("operator()", "operator ()");
}
#endif
-void _initialize_cp_name_parser ();
-void
-_initialize_cp_name_parser ()
+INIT_GDB_FILE (cp_name_parser)
{
#if GDB_SELF_TEST
selftests::register_test ("canonicalize", canonicalize_tests);