[PATCH v6 1/2] gdb: add annotation in 'info locals' command for variables shadowing case
Guinevere Larsen
blarsen@redhat.com
Tue Jan 16 15:40:40 GMT 2024
On 22/11/2023 09:13, Abdul Basit Ijaz wrote:
> From: "Ijaz, Abdul B" <abdul.b.ijaz@intel.com>
>
> For C/C++/Fortran/Ada languages GDB prints same name variable multiple
> times in case of variable shadowing and it is confusing for user to identify
> which variable belongs to the current scope. So for such cases add location
> info to the innermost listed variables and for super block variables add
> "shadowed" annotation in the form of "<file.c:line, shadowed>".
>
> Suppose we have
>
> 1:int x = 42;
> 2: {
> 3: int x = 99;
> 4: int y = 52;
> 5: x = 99; /* break here */
> 6: }
>
> Currently:
>
> (gdb) info locals
> x = 99
> x = 42
> y = 52
>
> After applying this patch, we obtain:
>
> (gdb) info locals
> x = 99 <file.c:3>
> y = 52
> x = 42 <file.c:1, shadowed>
>
> The patch adds the location annotations by keeping track of inner block
> and already printed variables to identify shadowing. So, GDB now prints
> "<file.c:line, shadowed>" for shadowed super-block variables and
> "<file.c:line>" for innermost declarations of such variables only.
>
> The location annotations are printed for shadowed variables in case of
> C/C++/Fortran/Ada languages. In Rust, it is possible to declare a
> variable with the same name many times. So in this case, just the first
> instance of the variable is printed. RUST language test "var_reuse.exp"
> fails with rustc compiler version >= 1.73 so XFAIL is added accordingly.
> ---
Changes look good to me, and looks like a good feature.
Reviewed-By: Guinevere Larsen <blarsen@redhat.com>
--
Cheers,
Guinevere Larsen
She/Her/Hers
> gdb/doc/gdb.texinfo | 15 ++++
> gdb/printcmd.c | 11 ++-
> gdb/stack.c | 64 +++++++++++--
> gdb/stack.h | 3 +-
> gdb/testsuite/gdb.ada/var_shadowing.exp | 38 ++++++++
> .../gdb.ada/var_shadowing/var_shadowing.adb | 30 +++++++
> gdb/testsuite/gdb.base/var-shadowing.c | 49 ++++++++++
> gdb/testsuite/gdb.base/var-shadowing.exp | 90 +++++++++++++++++++
> gdb/testsuite/gdb.base/var-shadowing2.c | 16 ++++
> gdb/testsuite/gdb.rust/var_reuse.exp | 34 +++++++
> gdb/testsuite/gdb.rust/var_reuse.rs | 20 +++++
> gdb/tracepoint.c | 3 +-
> gdb/value.h | 4 +-
> 13 files changed, 366 insertions(+), 11 deletions(-)
> create mode 100644 gdb/testsuite/gdb.ada/var_shadowing.exp
> create mode 100644 gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb
> create mode 100755 gdb/testsuite/gdb.base/var-shadowing.c
> create mode 100755 gdb/testsuite/gdb.base/var-shadowing.exp
> create mode 100644 gdb/testsuite/gdb.base/var-shadowing2.c
> create mode 100755 gdb/testsuite/gdb.rust/var_reuse.exp
> create mode 100755 gdb/testsuite/gdb.rust/var_reuse.rs
>
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index e4c00143fd1..6efcc5a8dc9 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -8833,6 +8833,21 @@ The optional flag @samp{-q}, which stands for @samp{quiet}, disables
> printing header information and messages explaining why no local variables
> have been printed.
>
> +@smallexample
> +1: int x = 3;
> +2: @{
> +3: int x = 4; // breakpt
> +4: @}
> +(gdb) info locals
> +x = 4 <file.c:3>
> +x = 3 <file.c:1, shadowed>
> +@end smallexample
> +
> +A variable is shadowed when there's another variable by the same
> +name which is declared within an inner scope (decision block,
> +method, or inner class). For such cases, its location for the
> +outermost scope is followed by @samp{shadowed}.
> +
> @item info locals [-q] [-t @var{type_regexp}] [@var{regexp}]
> Like @kbd{info locals}, but only print the local variables selected
> with the provided regexp(s).
> diff --git a/gdb/printcmd.c b/gdb/printcmd.c
> index c5e6a815580..f2bdce398ec 100644
> --- a/gdb/printcmd.c
> +++ b/gdb/printcmd.c
> @@ -56,6 +56,7 @@
> #include "gdbsupport/gdb-safe-ctype.h"
> #include "gdbsupport/rsp-low.h"
> #include "inferior.h"
> +#include "include/libiberty.h"
>
> /* Chain containing all defined memory-tag subcommands. */
>
> @@ -2331,7 +2332,8 @@ clear_dangling_display_expressions (struct objfile *objfile)
> void
> print_variable_and_value (const char *name, struct symbol *var,
> frame_info_ptr frame,
> - struct ui_file *stream, int indent)
> + struct ui_file *stream, int indent,
> + bool shadowed, bool printed)
> {
>
> if (!name)
> @@ -2344,6 +2346,7 @@ print_variable_and_value (const char *name, struct symbol *var,
> {
> struct value *val;
> struct value_print_options opts;
> + const char *file_name = lbasename (var->owner.symtab->filename);
>
> /* READ_VAR_VALUE needs a block in order to deal with non-local
> references (i.e. to handle nested functions). In this context, we
> @@ -2353,6 +2356,12 @@ print_variable_and_value (const char *name, struct symbol *var,
> get_user_print_options (&opts);
> opts.deref_ref = true;
> common_val_print_checked (val, stream, indent, &opts, current_language);
> +
> + if (shadowed)
> + /* Print location and shadowed variable information. */
> + fprintf_styled (stream, metadata_style.style (),
> + _("\t<%s:%d%s>"), file_name,
> + var->line (), printed ? ", shadowed" : "");
> }
> catch (const gdb_exception_error &except)
> {
> diff --git a/gdb/stack.c b/gdb/stack.c
> index ef565445c16..ef8f0f24b39 100644
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -56,6 +56,7 @@
> #include "cli/cli-option.h"
> #include "cli/cli-style.h"
> #include "gdbsupport/buildargv.h"
> +#include <unordered_set>
>
> /* The possible choices of "set print frame-arguments", and the value
> of this setting. */
> @@ -2211,10 +2212,16 @@ backtrace_command_completer (struct cmd_list_element *ignore,
>
> static void
> iterate_over_block_locals (const struct block *b,
> - iterate_over_block_arg_local_vars_cb cb)
> + iterate_over_block_arg_local_vars_cb cb,
> + const std::unordered_set<std::string> *shadowed_vars,
> + std::unordered_set<std::string> &printed_vars)
> {
> for (struct symbol *sym : block_iterator_range (b))
> {
> + const char *name = sym->print_name ();
> + bool already_printed = !printed_vars.insert (name).second;
> + bool shadowed = shadowed_vars->find (name) != shadowed_vars->end ();
> +
> switch (sym->aclass ())
> {
> case LOC_CONST:
> @@ -2227,7 +2234,25 @@ iterate_over_block_locals (const struct block *b,
> break;
> if (sym->domain () == COMMON_BLOCK_DOMAIN)
> break;
> - cb (sym->print_name (), sym);
> + /* Only for C/C++/Fortran/Ada languages, in case of variables
> + shadowing print <file:line, shadowed> annotation after
> + the superblock variable. Iteration of block starts from inner
> + block which is printed only with location information. */
> + if ((current_language->la_language == language_c
> + || current_language->la_language == language_cplus
> + || current_language->la_language == language_fortran
> + || current_language->la_language == language_ada)
> + && shadowed)
> + cb (name, sym, true, already_printed);
> + /* In case of Rust language it is possible to declare variable with
> + same name multiple times and only latest declaration of variable
> + is accessible. So print only the first instance and there is no
> + need of printing duplicates. */
> + else if (current_language->la_language == language_rust
> + && shadowed && already_printed)
> + break;
> + else
> + cb (name, sym, false, false);
> break;
>
> default:
> @@ -2244,9 +2269,31 @@ void
> iterate_over_block_local_vars (const struct block *block,
> iterate_over_block_arg_local_vars_cb cb)
> {
> + std::unordered_set<std::string> collected_vars, shadowed_vars, printed_vars;
> + const struct block *orig_block = block;
> +
> + /* Iterate over all the local variables in a block and store the list of
> + shadowed variables to later distinguish them from other variables. */
> + while (block != nullptr)
> + {
> + for (struct symbol *sym : block_iterator_range (block))
> + {
> + if (!sym->is_argument ())
> + {
> + const char *name = sym->print_name ();
> + if (!collected_vars.insert (name).second)
> + shadowed_vars.insert (name);
> + }
> + }
> + if (block->function ())
> + break;
> + block = block->superblock ();
> + }
> +
> + block = orig_block;
> while (block)
> {
> - iterate_over_block_locals (block, cb);
> + iterate_over_block_locals (block, cb, &shadowed_vars, printed_vars);
> /* After handling the function's top-level block, stop. Don't
> continue to its superblock, the block of per-file
> symbols. */
> @@ -2268,14 +2315,16 @@ struct print_variable_and_value_data
> struct ui_file *stream;
> int values_printed;
>
> - void operator() (const char *print_name, struct symbol *sym);
> + void operator() (const char *print_name, struct symbol *sym, bool shadowed,
> + bool printed);
> };
>
> /* The callback for the locals and args iterators. */
>
> void
> print_variable_and_value_data::operator() (const char *print_name,
> - struct symbol *sym)
> + struct symbol *sym,
> + bool shadowed, bool printed)
> {
> frame_info_ptr frame;
>
> @@ -2295,7 +2344,8 @@ print_variable_and_value_data::operator() (const char *print_name,
> return;
> }
>
> - print_variable_and_value (print_name, sym, frame, stream, num_tabs);
> + print_variable_and_value (print_name, sym, frame, stream, num_tabs, shadowed,
> + printed);
>
> /* print_variable_and_value invalidates FRAME. */
> frame = NULL;
> @@ -2476,7 +2526,7 @@ iterate_over_block_arg_vars (const struct block *b,
> struct symbol *sym2
> = lookup_symbol_search_name (sym->search_name (),
> b, VAR_DOMAIN).symbol;
> - cb (sym->print_name (), sym2);
> + cb (sym->print_name (), sym2, false, false);
> }
> }
> }
> diff --git a/gdb/stack.h b/gdb/stack.h
> index 1b0c2b342a4..72d843b66fb 100644
> --- a/gdb/stack.h
> +++ b/gdb/stack.h
> @@ -24,7 +24,8 @@ gdb::unique_xmalloc_ptr<char> find_frame_funname (frame_info_ptr frame,
> enum language *funlang,
> struct symbol **funcp);
>
> -typedef gdb::function_view<void (const char *print_name, struct symbol *sym)>
> +typedef gdb::function_view<void (const char *print_name, struct symbol *sym,
> + bool shadowed, bool printed)>
> iterate_over_block_arg_local_vars_cb;
>
> void iterate_over_block_arg_vars (const struct block *block,
> diff --git a/gdb/testsuite/gdb.ada/var_shadowing.exp b/gdb/testsuite/gdb.ada/var_shadowing.exp
> new file mode 100644
> index 00000000000..da279da258d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/var_shadowing.exp
> @@ -0,0 +1,38 @@
> +# Copyright 2023 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +load_lib "ada.exp"
> +
> +require allow_ada_tests
> +
> +standard_ada_testfile var_shadowing
> +
> +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
> + return -1
> +}
> +
> +clean_restart ${testfile}
> +
> +set i_level1 [gdb_get_line_number "I-Level1" ${testdir}/var_shadowing.adb]
> +set i_level2 [gdb_get_line_number "I-Level2" ${testdir}/var_shadowing.adb]
> +set i_level3 [gdb_get_line_number "I-Level3" ${testdir}/var_shadowing.adb]
> +set bp_location [gdb_get_line_number "BREAK" ${testdir}/var_shadowing.adb]
> +runto "var_shadowing.adb:$bp_location"
> +
> +gdb_test "info locals" [multi_line \
> + "i = 111\t<$testfile.adb:$i_level3>" \
> + "i = 11\t<$testfile.adb:$i_level2, shadowed>" \
> + "i = 1\t<$testfile.adb:$i_level1, shadowed>" \
> +] "info locals at innermost level"
> diff --git a/gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb b/gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb
> new file mode 100644
> index 00000000000..93cef5f0d6c
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb
> @@ -0,0 +1,30 @@
> +-- Copyright 2023 Free Software Foundation, Inc.
> +--
> +-- This program is free software; you can redistribute it and/or modify
> +-- it under the terms of the GNU General Public License as published by
> +-- the Free Software Foundation; either version 3 of the License, or
> +-- (at your option) any later version.
> +--
> +-- This program is distributed in the hope that it will be useful,
> +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
> +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +-- GNU General Public License for more details.
> +--
> +-- You should have received a copy of the GNU General Public License
> +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +with Ada.Text_IO; use Ada.Text_IO;
> +
> +procedure Varshadow is
> + I : Integer := 1; -- I-Level1
> +begin
> + declare
> + I : Integer := 11; -- I-Level2
> + begin
> + declare
> + I : Integer := 111; -- I-Level3
> + begin
> + Put_Line ("hello"); -- BREAK
> + end;
> + end;
> +end;
> diff --git a/gdb/testsuite/gdb.base/var-shadowing.c b/gdb/testsuite/gdb.base/var-shadowing.c
> new file mode 100755
> index 00000000000..18963514bbf
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/var-shadowing.c
> @@ -0,0 +1,49 @@
> +/* Copyright (C) 2023 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +#include <stdlib.h>
> +
> +void
> +shadowing (void)
> +{
> + int a; /* bp for entry */
> + unsigned int val1 = 1; /* val1-d1 */
> + unsigned int val2 = 2; /* val2-d1 */
> + a = 101; /* bp for locals 1 */
> + {
> + unsigned int val2 = 3; /* val2-d2 */
> + unsigned int val3 = 4; /* val3-d1 */
> + a = 102; /* bp for locals 2 */
> + {
> + unsigned int val1 = 5; /* val1-d2 */
> + a = 103; /* bp for locals 3 */
> + {
> + #include "var-shadowing2.c"
> + unsigned int val1 = 6; /* val1-d3 */
> + unsigned int val2 = 7; /* val2-d3 */
> + unsigned int val3 = 8; /* val3-d2 */
> + a = 104; /* bp for locals 4 */
> + }
> + }
> + }
> + a = 0; /* bp for locals 5 */
> +}
> +
> +int
> +main (void)
> +{
> + shadowing ();
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.base/var-shadowing.exp b/gdb/testsuite/gdb.base/var-shadowing.exp
> new file mode 100755
> index 00000000000..c7e1e9eae2e
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/var-shadowing.exp
> @@ -0,0 +1,90 @@
> +# Copyright 2023 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +standard_testfile
> +if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
> + return -1
> +}
> +
> +if ![runto_main] {
> + untested "failed to run to main"
> + return -1
> +}
> +
> +set bp_line1 [gdb_get_line_number "bp for locals 1" ${srcfile}]
> +set bp_line2 [gdb_get_line_number "bp for locals 2" ${srcfile}]
> +set bp_line3 [gdb_get_line_number "bp for locals 3" ${srcfile}]
> +set bp_line4 [gdb_get_line_number "bp for locals 4" ${srcfile}]
> +set bp_line5 [gdb_get_line_number "bp for locals 5" ${srcfile}]
> +
> +set val1_d1 [gdb_get_line_number "val1-d1" ${srcfile}]
> +set val1_d2 [gdb_get_line_number "val1-d2" ${srcfile}]
> +set val1_d3 [gdb_get_line_number "val1-d3" ${srcfile}]
> +set val2_d1 [gdb_get_line_number "val2-d1" ${srcfile}]
> +set val2_d2 [gdb_get_line_number "val2-d2" ${srcfile}]
> +set val2_d3 [gdb_get_line_number "val2-d3" ${srcfile}]
> +set val3_d1 [gdb_get_line_number "val3-d1" ${srcfile}]
> +set val3_d2 [gdb_get_line_number "val3-d2" ${srcfile}]
> +set a_line [gdb_get_line_number "bp for entry" ${srcfile}]
> +
> +gdb_breakpoint $srcfile:$bp_line1
> +gdb_test "continue" ".*bp for locals 1.*" "continue to outermost level"
> +gdb_test "info locals" [multi_line \
> + "val1 = 1" \
> + "val2 = 2" \
> + ] "info locals at outermost level"
> +
> +gdb_breakpoint $srcfile:$bp_line2
> +gdb_test "continue" ".*bp for locals 2.*" "continue to first level"
> +gdb_test "info locals" [multi_line \
> + "val2 = 3\t<$srcfile:$val2_d2>" \
> + "val3 = 4" \
> + "a = 101" \
> + "val1 = 1" \
> + "val2 = 2\t<$srcfile:$val2_d1, shadowed>" \
> + ] "info locals first level"
> +
> +gdb_breakpoint $srcfile:$bp_line3
> +gdb_test "continue" ".*bp for locals 3.*" "continue to second level"
> +gdb_test "info locals" [multi_line \
> + "val1 = 5\t<$srcfile:$val1_d2>" \
> + "val2 = 3\t<$srcfile:$val2_d2>" \
> + "val3 = 4" \
> + "a = 102" \
> + "val1 = 1\t<$srcfile:$val1_d1, shadowed>" \
> + "val2 = 2\t<$srcfile:$val2_d1, shadowed>" \
> + ] "info locals second level"
> +
> +gdb_breakpoint $srcfile:$bp_line4
> +gdb_test "continue" ".*bp for locals 4.*" "continue to innermost level"
> +gdb_test "info locals" [multi_line \
> + "a = 999\t<${testfile}2.c:16>" \
> + "val1 = 6\t<$srcfile:$val1_d3>" \
> + "val2 = 7\t<$srcfile:$val2_d3>" \
> + "val3 = 8\t<$srcfile:$val3_d2>" \
> + "val1 = 5\t<$srcfile:$val1_d2, shadowed>" \
> + "val2 = 3\t<$srcfile:$val2_d2, shadowed>" \
> + "val3 = 4\t<$srcfile:$val3_d1, shadowed>" \
> + "a = 103\t<$srcfile:$a_line, shadowed>" \
> + "val1 = 1\t<$srcfile:$val1_d1, shadowed>" \
> + "val2 = 2\t<$srcfile:$val2_d1, shadowed>" \
> + ] "info locals at innermost level"
> +
> +gdb_breakpoint $srcfile:$bp_line5
> +gdb_test "continue" ".*bp for locals 5.*" "continue to outermost level last"
> +gdb_test "info locals" [multi_line \
> + "val1 = 1" \
> + "val2 = 2" \
> + ] "info locals at outermost level last"
> diff --git a/gdb/testsuite/gdb.base/var-shadowing2.c b/gdb/testsuite/gdb.base/var-shadowing2.c
> new file mode 100644
> index 00000000000..9bc55f95a84
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/var-shadowing2.c
> @@ -0,0 +1,16 @@
> +/* Copyright (C) 2023 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +int a = 999;
> diff --git a/gdb/testsuite/gdb.rust/var_reuse.exp b/gdb/testsuite/gdb.rust/var_reuse.exp
> new file mode 100755
> index 00000000000..f5715f5e0cd
> --- /dev/null
> +++ b/gdb/testsuite/gdb.rust/var_reuse.exp
> @@ -0,0 +1,34 @@
> +# Copyright 2023 Free Software Foundation, Inc.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +load_lib rust-support.exp
> +require allow_rust_tests
> +require {can_compile rust}
> +
> +standard_testfile .rs
> +if {[prepare_for_testing "failed to prepare" \
> + $testfile $srcfile {debug rust}]} {
> + return -1
> +}
> +
> +set line [gdb_get_line_number "set breakpoint here"]
> +if {![runto ${srcfile}:$line]} {
> + untested "could not run to breakpoint"
> + return -1
> +}
> +
> +# Wrong local values are shown for rustc version >= 1.73.
> +setup_xfail "*-*-*" "gdb/31079"
> +gdb_test "info local _x" "_x = 12" "print local _x variable"
> diff --git a/gdb/testsuite/gdb.rust/var_reuse.rs b/gdb/testsuite/gdb.rust/var_reuse.rs
> new file mode 100755
> index 00000000000..03be7981ff1
> --- /dev/null
> +++ b/gdb/testsuite/gdb.rust/var_reuse.rs
> @@ -0,0 +1,20 @@
> +// Copyright (C) 2023 Free Software Foundation, Inc.
> +
> +// This program is free software; you can redistribute it and/or modify
> +// it under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; either version 3 of the License, or
> +// (at your option) any later version.
> +//
> +// This program is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +// GNU General Public License for more details.
> +//
> +// You should have received a copy of the GNU General Public License
> +// along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +fn main() {
> + let _x = 5;
> + let _x = _x + 7;
> + let _y = 8; // set breakpoint here
> +}
> diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
> index 750185341ea..215d726dd77 100644
> --- a/gdb/tracepoint.c
> +++ b/gdb/tracepoint.c
> @@ -1047,7 +1047,8 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc,
> int count = 0;
>
> auto do_collect_symbol = [&] (const char *print_name,
> - struct symbol *sym)
> + struct symbol *sym,
> + bool shadowed, bool printed)
> {
> collect_symbol (sym, gdbarch, frame_regno,
> frame_offset, pc, trace_string);
> diff --git a/gdb/value.h b/gdb/value.h
> index e4912717684..f5130bacdac 100644
> --- a/gdb/value.h
> +++ b/gdb/value.h
> @@ -1537,7 +1537,9 @@ extern void print_variable_and_value (const char *name,
> struct symbol *var,
> frame_info_ptr frame,
> struct ui_file *stream,
> - int indent);
> + int indent,
> + bool shadowed,
> + bool printed);
>
> extern void typedef_print (struct type *type, struct symbol *news,
> struct ui_file *stream);
More information about the Gdb-patches
mailing list