Handle block-local names for Ada

GNAT can generate a mangled name with "B_N" (where N is a number) in
the middle, like "hello__B_1__fourth.0".  This is used for names local
to a block.  Multiple levels of block-local name can also occur, a
possibility that was neglected by v1 of this patch.  This patch
changes gdb to handle these names.

The wild name matcher is updated a straightforward way.  The full
matcher is rewritten.  The hash function is updated to ensure that
this works.

This version does not seem to have the performance problems that
affected v1.  In particular, the previously-slow "bt" problem has been
fixed.

gdb/ChangeLog
2020-12-14  Tom Tromey  <tromey@adacore.com>

	* dictionary.c (language_defn::search_name_hash): Ignore "B".
	* ada-lang.c (advance_wild_match): Ignore "B".
	(full_match): Remove.
	(do_full_match): Rewrite.

gdb/testsuite/ChangeLog
2020-12-14  Tom Tromey  <tromey@adacore.com>

	* gdb.ada/nested.exp: Add new tests.
	* gdb.ada/nested/hello.adb (Fourth, Fifth): New procedures.
This commit is contained in:
Tom Tromey
2020-12-14 08:14:06 -07:00
parent 25a1127be7
commit 86b442599b
6 changed files with 92 additions and 25 deletions

View File

@ -1,3 +1,10 @@
2020-12-14 Tom Tromey <tromey@adacore.com>
* dictionary.c (language_defn::search_name_hash): Ignore "B".
* ada-lang.c (advance_wild_match): Ignore "B".
(full_match): Remove.
(do_full_match): Rewrite.
2020-12-14 Tom Tromey <tromey@adacore.com>
* ada-lang.c (get_var_value): Only consider exact matches.

View File

@ -6037,6 +6037,13 @@ advance_wild_match (const char **namep, const char *name0, char target0)
name += 2;
break;
}
else if (t1 == '_' && name[2] == 'B' && name[3] == '_')
{
/* Names like "pkg__B_N__name", where N is a number, are
block-local. We can handle these by simply skipping
the "B_" here. */
name += 4;
}
else
return 0;
}
@ -6081,28 +6088,6 @@ wild_match (const char *name, const char *patn)
}
}
/* Returns true iff symbol name SYM_NAME matches SEARCH_NAME, ignoring
any trailing suffixes that encode debugging information or leading
_ada_ on SYM_NAME (see is_name_suffix commentary for the debugging
information that is ignored). */
static bool
full_match (const char *sym_name, const char *search_name)
{
size_t search_name_len = strlen (search_name);
if (strncmp (sym_name, search_name, search_name_len) == 0
&& is_name_suffix (sym_name + search_name_len))
return true;
if (startswith (sym_name, "_ada_")
&& strncmp (sym_name + 5, search_name, search_name_len) == 0
&& is_name_suffix (sym_name + search_name_len + 5))
return true;
return false;
}
/* Add symbols from BLOCK matching LOOKUP_NAME in DOMAIN to vector
*defn_symbols, updating the list of symbols in OBSTACKP (if
necessary). OBJFILE is the section containing BLOCK. */
@ -13606,7 +13591,41 @@ do_full_match (const char *symbol_search_name,
const lookup_name_info &lookup_name,
completion_match_result *comp_match_res)
{
return full_match (symbol_search_name, ada_lookup_name (lookup_name));
if (startswith (symbol_search_name, "_ada_"))
symbol_search_name += 5;
const char *lname = lookup_name.ada ().lookup_name ().c_str ();
int uscore_count = 0;
while (*lname != '\0')
{
if (*symbol_search_name != *lname)
{
if (*symbol_search_name == 'B' && uscore_count == 2
&& symbol_search_name[1] == '_')
{
symbol_search_name += 2;
while (isdigit (*symbol_search_name))
++symbol_search_name;
if (symbol_search_name[0] == '_'
&& symbol_search_name[1] == '_')
{
symbol_search_name += 2;
continue;
}
}
return false;
}
if (*symbol_search_name == '_')
++uscore_count;
else
uscore_count = 0;
++symbol_search_name;
++lname;
}
return is_name_suffix (symbol_search_name);
}
/* symbol_name_matcher_ftype for exact (verbatim) matches. */

View File

@ -761,6 +761,13 @@ language_defn::search_name_hash (const char *string0) const
{
int c = string[2];
if (c == 'B' && string[3] == '_')
{
for (string += 4; ISDIGIT (*string); ++string)
;
continue;
}
if ((c < 'a' || c > 'z') && c != 'O')
return hash;
hash = 0;

View File

@ -1,3 +1,8 @@
2020-12-14 Tom Tromey <tromey@adacore.com>
* gdb.ada/nested.exp: Add new tests.
* gdb.ada/nested/hello.adb (Fourth, Fifth): New procedures.
2020-12-14 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/ada-thick-pointer.exp: New file.

View File

@ -34,3 +34,18 @@ gdb_test "break first" \
"Breakpoint $any_nb at $any_addr: file .*hello.adb, line $any_nb." \
"break on nested function First"
gdb_test "break fourth" \
"Breakpoint $any_nb at $any_addr: file .*hello.adb, line $any_nb." \
"break on nested function fourth"
gdb_test "break hello.fourth" \
"Breakpoint $any_nb at $any_addr: file .*hello.adb, line $any_nb." \
"full-qualified break on nested function fourth"
gdb_test "break fifth" \
"Breakpoint $any_nb at $any_addr: file .*hello.adb, line $any_nb." \
"break on nested function fifth"
gdb_test "break hello.fourth.fifth" \
"Breakpoint $any_nb at $any_addr: file .*hello.adb, line $any_nb." \
"full-qualified break on nested function fifth"

View File

@ -31,6 +31,20 @@ procedure Hello is
end Third;
begin
Third;
declare
procedure Fourth is
begin
Third;
declare
procedure Fifth is
begin
Second;
end Fifth;
begin
Fifth;
end;
end Fourth;
begin
Fourth;
end;
end Hello;