[v2,1/1] don't list typedef symbols in C++, d and ada

Message ID 1500163721-9343-1-git-send-email-zhouzhouyi@gmail.com
State New, archived
Headers

Commit Message

Zhouyi Zhou July 16, 2017, 12:08 a.m. UTC
  C++ "struct foo { ... }" also defines a typedef for "foo", in order
to make command like "gdb) ptype (foo *)0" work, function
symbol_matches_domain relaxes the check for domain check for cplus,
d and ada.

However the command "list foo" will invoke symbol_matches_domain,
which results in odd result when execute command "list foo".

For example, consider debugging following program.
struct foo {
        int i;
};

int foo(void);

int main()
{
        struct foo l;
        return foo();
}

int foo() {
        return 0;
}

(gdb) list foo
file: "example.c", line number: 1
file: "example.c", line number: 13

Following patch get rid of "non var" symbols in function
find_function_symbols. 

Tested on x86-64 GNU/Linux. 
Signed-off-by: Zhouyi Zhou <zhouzhouyi@gmail.com>

gdb/ChangeLog:
2017-07-16 Zhouyi Zhou <zhouzhouyi@gmail.com>
	* linespec.c (find_function_symbols): remove non-var symbols
	from the matching result.
---
 gdb/linespec.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
  

Comments

Pedro Alves July 18, 2017, 4:16 p.m. UTC | #1
On 07/16/2017 01:08 AM, Zhouyi Zhou wrote:

> However the command "list foo" will invoke symbol_matches_domain,
> which results in odd result when execute command "list foo".
> 
> (gdb) list foo
> file: "example.c", line number: 1
> file: "example.c", line number: 13

GDB is showing this odd output whenever "list" finds more than
one thing to list.  For example, with a couple overloads:

 int bar() { return 0;}
 int bar(int) { return 0; }

and no "bar" typedef in sight, you get the same:

 (gdb) list bar
 file: "overload.cc", line number: 1
 file: "overload.cc", line number: 2

Note you can explicitly tell GDB about the overload
you want to list, with

  (gdb) list bar()
  (gdb) list bar(int)

and likewise in your original example, you can do
"list foo()" to disambiguate with the typedef.

It might be pretty handy to list the definition of actual
typedefs (and classes).  So IMO, it'd be nice to go in the
other direction, and make "list TYPE" work properly, if
it doesn't.  Note that linespecs already purposely work
differently in list mode, see, in linespec.c:

 bool
 collect_info::add_symbol (symbol *sym)
 {
   /* In list mode, add all matching symbols, regardless of class.
      This allows the user to type "list a_global_variable".  */
   if (SYMBOL_CLASS (sym) == LOC_BLOCK || this->state->list_mode)
     VEC_safe_push (symbolp, this->result.symbols, sym);
 }

This, however:

 (gdb) list bar
 file: "overload.cc", line number: 1
 file: "overload.cc", line number: 2

does look like a plain bug that should be fixed to me.
I.e., IMO GDB should list the actual code around those
two locations, not just print the location.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 4c076fe..fd74cde 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -3223,6 +3223,8 @@  find_function_symbols (struct linespec_state *state,
 {
   struct collect_info info;
   VEC (const_char_ptr) *symbol_names = NULL;
+  int ix;
+  struct symbol *sym;
   struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
 					  &symbol_names);
 
@@ -3240,7 +3242,17 @@  find_function_symbols (struct linespec_state *state,
     add_matching_symbols_to_info (name, &info, state->search_pspace);
 
   do_cleanups (cleanup);
-
+  
+  for (ix = 0; VEC_iterate (symbolp, info.result.symbols, ix, sym); ++ix)
+    {
+      if (sym->domain != VAR_DOMAIN)
+	{
+	  VEC_unordered_remove (symbolp,
+				info.result.symbols, ix);
+	  --ix;
+	}
+    }
+  
   if (VEC_empty (symbolp, info.result.symbols))
     {
       VEC_free (symbolp, info.result.symbols);