[PATCH] call cp_lookup_symbol_namespace recursively to search symbols in C++ base classes

Liu, Lei
2010-11-02T03:47:20Z

Hi,

This patch is trying to fix a bug in gdb. The problem is found in following
C++ test case.

#include <cstdio>

class A {
public:
enum E {X,Y,Z};
};

class B : A {
public:
void test(E e);
};

void B::test(E e) {
if (e == X) { //b 14 if e==X
printf("%d\n",e);
}
}

int main() {
B b;
b.test(A::X);
return 0;
}

Compiled by gcc-4.1.2 with -O0 -g.

I tried to plant a conditional breakpoint in line 14 as shown in comment but
got a error shows 'No symbol "X" in current context'. The symbol 'X' is
accessible in that scope.

The bug is that gdb did not look up enum constant symbols derived from base
classes. My patch adds some code in cp_lookup_symbol_namespace to call
itself
recursively, so that to make gdb search symbols from all base classes.

Is this patch OK?

Thanks.
Lei

2010-11-02 Lei Liu <lei.liu2@windriver.com>

* cp-namespace.c (cp_lookup_symbol_namespace): Recursively call
itself to search C++ base classes.
---
gdb/cp-namespace.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 16f58ca..822423e 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -513,6 +513,8 @@ cp_lookup_symbol_namespace (const char *scope,
const domain_enum domain)
{
struct symbol *sym;
+ struct symbol *scope_sym;
+ struct type *scope_type;

/* First, try to find the symbol in the given namespace. */
sym = cp_lookup_symbol_in_namespace (scope, name, block, domain);
@@ -530,6 +532,31 @@ cp_lookup_symbol_namespace (const char *scope,
block = BLOCK_SUPERBLOCK (block);
}

+ /* If scope is a C++ class, we need to search all its base classes. */
+ if (scope == NULL || scope[0] == '\0')
+ return NULL;
+
+ scope_sym = lookup_symbol (scope, NULL, VAR_DOMAIN, NULL);
+ if (scope_sym == NULL)
+ return NULL;
+
+ scope_type = SYMBOL_TYPE(scope_sym);
+ if (scope_type == NULL)
+ return NULL;
+
+ if (TYPE_CODE (scope_type) == TYPE_CODE_STRUCT)
+ {
+ int nbases = TYPE_N_BASECLASSES (scope_type);
+ int i;
+ for (i = 0; i < nbases; i++)
+ {
+ const char *base_name = TYPE_BASECLASS_NAME (scope_type, i);
+ sym = cp_lookup_symbol_namespace (base_name, name, block,
domain);
+ if (sym != NULL)
+ return sym;
+ }
+ }
+
return NULL;
}