From 86b442599bca468f997a3f1f58cba68b752ef6b2 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 14 Dec 2020 08:14:06 -0700 Subject: [PATCH] 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 * 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 * gdb.ada/nested.exp: Add new tests. * gdb.ada/nested/hello.adb (Fourth, Fifth): New procedures. --- gdb/ChangeLog | 7 +++ gdb/ada-lang.c | 65 +++++++++++++++++--------- gdb/dictionary.c | 7 +++ gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.ada/nested.exp | 15 ++++++ gdb/testsuite/gdb.ada/nested/hello.adb | 18 ++++++- 6 files changed, 92 insertions(+), 25 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 21a6b9730eb..e15d6958cbf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-12-14 Tom Tromey + + * 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 * ada-lang.c (get_var_value): Only consider exact matches. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index ca66642dee0..564cdbee13c 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -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. */ diff --git a/gdb/dictionary.c b/gdb/dictionary.c index c94a49ee373..d51f209e715 100644 --- a/gdb/dictionary.c +++ b/gdb/dictionary.c @@ -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; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f0d452b7a31..d5442f9a1d8 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-12-14 Tom Tromey + + * gdb.ada/nested.exp: Add new tests. + * gdb.ada/nested/hello.adb (Fourth, Fifth): New procedures. + 2020-12-14 Tom Tromey * gdb.dwarf2/ada-thick-pointer.exp: New file. diff --git a/gdb/testsuite/gdb.ada/nested.exp b/gdb/testsuite/gdb.ada/nested.exp index ea4bb4de355..74f9f1f87ae 100644 --- a/gdb/testsuite/gdb.ada/nested.exp +++ b/gdb/testsuite/gdb.ada/nested.exp @@ -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" diff --git a/gdb/testsuite/gdb.ada/nested/hello.adb b/gdb/testsuite/gdb.ada/nested/hello.adb index 2d1e532e47d..10ec6bf8201 100644 --- a/gdb/testsuite/gdb.ada/nested/hello.adb +++ b/gdb/testsuite/gdb.ada/nested/hello.adb @@ -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; - -- 2.30.2