diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/block.c | 9 | ||||
-rw-r--r-- | gdb/block.h | 10 | ||||
-rw-r--r-- | gdb/symtab.c | 34 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/decl-before-def-decl.c | 25 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/decl-before-def-def.c | 18 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/decl-before-def.exp | 26 |
8 files changed, 124 insertions, 12 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cbe2693..f1ebf09 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2020-04-23 Tom de Vries <tdevries@suse.de> + + PR symtab/25807 + * block.c (best_symbol, better_symbol): Promote to external. + * block.h (best_symbol, better_symbol): Declare. + * symtab.c (lookup_symbol_in_objfile_symtabs): Prefer def over + decl. + 2020-04-23 Tom Tromey <tromey@adacore.com> PR ada/25837: diff --git a/gdb/block.c b/gdb/block.c index 9b58243..597d6d5 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -657,19 +657,18 @@ block_iter_match_next (const lookup_name_info &name, return block_iter_match_step (iterator, name, 0); } -/* Return true if symbol A is the best match possible for DOMAIN. */ +/* See block.h. */ -static bool +bool best_symbol (struct symbol *a, const domain_enum domain) { return (SYMBOL_DOMAIN (a) == domain && SYMBOL_CLASS (a) != LOC_UNRESOLVED); } -/* Return symbol B if it is a better match than symbol A for DOMAIN. - Otherwise return A. */ +/* See block.h. */ -static struct symbol * +struct symbol * better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain) { if (a == NULL) diff --git a/gdb/block.h b/gdb/block.h index 7c0b2d3..50ab049 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -342,6 +342,16 @@ extern struct symbol *block_iter_match_first (const struct block *block, extern struct symbol *block_iter_match_next (const lookup_name_info &name, struct block_iterator *iterator); +/* Return true if symbol A is the best match possible for DOMAIN. */ + +extern bool best_symbol (struct symbol *a, const domain_enum domain); + +/* Return symbol B if it is a better match than symbol A for DOMAIN. + Otherwise return A. */ + +extern struct symbol *better_symbol (struct symbol *a, struct symbol *b, + const domain_enum domain); + /* Search BLOCK for symbol NAME in DOMAIN. */ extern struct symbol *block_lookup_symbol (const struct block *block, diff --git a/gdb/symtab.c b/gdb/symtab.c index dc079ef..1eef978 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -2285,6 +2285,8 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile, name, domain_name (domain)); } + struct block_symbol other; + other.symbol = NULL; for (compunit_symtab *cust : objfile->compunits ()) { const struct blockvector *bv; @@ -2295,18 +2297,36 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile, block = BLOCKVECTOR_BLOCK (bv, block_index); result.symbol = block_lookup_symbol_primary (block, name, domain); result.block = block; - if (result.symbol != NULL) + if (result.symbol == NULL) + continue; + if (best_symbol (result.symbol, domain)) { - if (symbol_lookup_debug > 1) + other = result; + break; + } + if (symbol_matches_domain (result.symbol->language (), + SYMBOL_DOMAIN (result.symbol), domain)) + { + struct symbol *better + = better_symbol (other.symbol, result.symbol, domain); + if (better != other.symbol) { - fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n", - host_address_to_string (result.symbol), - host_address_to_string (block)); + other.symbol = better; + other.block = block; } - result.symbol = fixup_symbol_section (result.symbol, objfile); - return result; + } + } + if (other.symbol != NULL) + { + if (symbol_lookup_debug > 1) + { + fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n", + host_address_to_string (other.symbol), + host_address_to_string (other.block)); } + other.symbol = fixup_symbol_section (other.symbol, objfile); + return other; } if (symbol_lookup_debug > 1) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 7e6bf73..e37aca2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2020-04-23 Tom de Vries <tdevries@suse.de> + * gdb.base/decl-before-def-decl.c: New test. + * gdb.base/decl-before-def-def.c: New test. + * gdb.base/decl-before-def.exp: New file. + +2020-04-23 Tom de Vries <tdevries@suse.de> + * gdb.base/readnever.exp: Skip if GDBFLAGS contain -readnow/--readnow. 2020-04-22 Tom de Vries <tdevries@suse.de> diff --git a/gdb/testsuite/gdb.base/decl-before-def-decl.c b/gdb/testsuite/gdb.base/decl-before-def-decl.c new file mode 100644 index 0000000..3e4e6d7 --- /dev/null +++ b/gdb/testsuite/gdb.base/decl-before-def-decl.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 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/>. */ + +extern int a[]; + +int +main (void) +{ + a[0] = 1; + return 0; +} diff --git a/gdb/testsuite/gdb.base/decl-before-def-def.c b/gdb/testsuite/gdb.base/decl-before-def-def.c new file mode 100644 index 0000000..4d25248 --- /dev/null +++ b/gdb/testsuite/gdb.base/decl-before-def-def.c @@ -0,0 +1,18 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 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[2] = { 1, 2 }; diff --git a/gdb/testsuite/gdb.base/decl-before-def.exp b/gdb/testsuite/gdb.base/decl-before-def.exp new file mode 100644 index 0000000..feb2084 --- /dev/null +++ b/gdb/testsuite/gdb.base/decl-before-def.exp @@ -0,0 +1,26 @@ +# Copyright 2020 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 decl-before-def-decl.c decl-before-def-def.c +set sources [list $srcfile $srcfile2] + +if {[prepare_for_testing "failed to prepare" $testfile $sources]} { + return -1 +} + +# This is required due to PR25764. +gdb_test "maint expand-symtabs" + +gdb_test "p a" { = \{1, 2\}} |