aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2025-04-25 17:32:33 -0600
committerTom Tromey <tom@tromey.com>2025-04-28 16:29:50 -0600
commit32c6e2fe20557441612b2957f22b1e9d673b423e (patch)
treeddb3d80d66d4116698edebe58f62ff322c409283
parent4a5312e736e0e7c9dca43fa682b5e60240008b4b (diff)
downloadbinutils-32c6e2fe20557441612b2957f22b1e9d673b423e.zip
binutils-32c6e2fe20557441612b2957f22b1e9d673b423e.tar.gz
binutils-32c6e2fe20557441612b2957f22b1e9d673b423e.tar.bz2
Fix "set debug parser"
While debugging my longer series, I discovered that I broken "set debug parser" a couple years ago. This patch fixes it and adds a minimal test case so that it, hopefully, will not break again. This patch also adds parser debugging to the C++ name canonicalizer. Thanks to Tom de Vries for fixing the test case.
-rw-r--r--gdb/cp-name-parser.y3
-rw-r--r--gdb/parse.c4
-rw-r--r--gdb/parser-defs.h3
-rw-r--r--gdb/printcmd.c4
-rw-r--r--gdb/testsuite/gdb.base/exprs.exp18
5 files changed, 29 insertions, 3 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 10f6e2d..e7317b7 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -2047,6 +2047,9 @@ cp_demangled_name_to_comp (const char *demangled_name,
auto result = std::make_unique<demangle_parse_info> ();
cpname_state state (demangled_name, result.get ());
+ scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+ parser_debug);
+
if (yyparse (&state))
{
if (state.global_errmsg && errmsg)
diff --git a/gdb/parse.c b/gdb/parse.c
index 3108017..64653c8 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -60,8 +60,8 @@ show_expressiondebug (struct ui_file *file, int from_tty,
}
-/* True if an expression parser should set yydebug. */
-static bool parser_debug;
+/* See parser-defs.h. */
+bool parser_debug;
static void
show_parserdebug (struct ui_file *file, int from_tty,
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index c13a56e..f5618f3 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -389,4 +389,7 @@ extern bool fits_in_type (int n_sign, const gdb_mpz &n, int type_bits,
extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3);
+/* True if an expression parser should set yydebug. */
+extern bool parser_debug;
+
#endif /* GDB_PARSER_DEFS_H */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 2be5eaa..6659c5a 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1320,7 +1320,9 @@ process_print_command_args (const char *args, value_print_options *print_opts,
value, so invert it for parse_expression. */
parser_flags flags = 0;
if (!voidprint)
- flags = PARSER_VOID_CONTEXT;
+ flags |= PARSER_VOID_CONTEXT;
+ if (parser_debug)
+ flags |= PARSER_DEBUG;
expression_up expr = parse_expression (exp, nullptr, flags);
return expr->evaluate ();
}
diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp
index eb2d0e4..f703c18 100644
--- a/gdb/testsuite/gdb.base/exprs.exp
+++ b/gdb/testsuite/gdb.base/exprs.exp
@@ -284,3 +284,21 @@ gdb_test "print v_short + " \
# Test for a syntax error in the middle of an expression.
gdb_test "print v_short =}{= 3" \
"A syntax error in expression, near `\\}\\{= 3'\\."
+
+gdb_test_no_output "set debug parse 1"
+set saw_start 0
+set saw_val 0
+gdb_test_multiple "print 23" "print with debugging" -lbl {
+ -re "\r\nStarting parse(?=\r\n)" {
+ set saw_start 1
+ exp_continue
+ }
+ -re "\r\n.$decimal = 23(?=\r\n)" {
+ set saw_val 1
+ exp_continue
+ }
+
+ -re -wrap "" {
+ gdb_assert {$saw_start && $saw_val} $gdb_test_name
+ }
+}