This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On 2010å11æ03æ 08:09, Pedro Alves wrote:
Your testcase is not hitting this empty scope check, due to your
"#include<cstdio>", which does namespace things, and
ends up emitting DW_TAG_namespace in the debug info, and
so dwarf2read.c sets the processing_has_namespace_info
global, and so a "namespace" for you test's class
is installed by:

   /* For C++, set the block's scope.  */
   if (cu->language == language_cplus || cu->language == language_fortran)
     cp_set_block_scope (new->name, block,&objfile->objfile_obstack,
			determine_prefix (die, cu),
			processing_has_namespace_info);

If I remove that include from your test (and the printf), then
the patch no longer works.  We need to do something here.

I updated my patch to deal with this as long as the suggestions from Tom and Yao.

I think in cp_set_block_scope, we should set scope name on a block
regardless of whether processing_has_namespace_info has been set.
For the cases that we only have classes but no namespaces, we still
need scope information to tell us which symbols are valid in a block.

How about this?

Thanks.
Lei


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


gdb/
* cp-namespace.c (cp_lookup_symbol_namespace): Recursively call
itself.
(cp_set_block_scope): Call block_set_scope if a valid scope name is
given.
gdb/testsuite/
* gdb.cp/enum.exp: New test case.
* gdb.cp/enum1.cc: Ditto.
* gdb.cp/enum2.cc: Ditto.
---
gdb/cp-namespace.c | 38 +++++++++++++++++++++
gdb/testsuite/gdb.cp/enum.exp | 74 +++++++++++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.cp/enum1.cc | 34 +++++++++++++++++++
gdb/testsuite/gdb.cp/enum2.cc | 37 ++++++++++++++++++++
4 files changed, 183 insertions(+), 0 deletions(-)
create mode 100644 gdb/testsuite/gdb.cp/enum.exp
create mode 100644 gdb/testsuite/gdb.cp/enum1.cc
create mode 100644 gdb/testsuite/gdb.cp/enum2.cc

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 16f58ca..bbce580 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -214,6 +214,16 @@ cp_set_block_scope (const struct symbol *symbol,
obsavestring (name, prefix_len, obstack),
obstack);
}
+ else if (processing_current_prefix != NULL
+ && processing_current_prefix[0] != '\0')
+ {
+ /* Just set the scope name if we get a valid one. */
+ block_set_scope
+ (block, obsavestring (processing_current_prefix,
+ strlen (processing_current_prefix),
+ obstack),
+ obstack);
+ }
}

/* Test whether or not NAMESPACE looks like it mentions an anonymous
@@ -513,6 +523,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 +542,32 @@ 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;
+
+ scope_type = check_typedef (scope_type);
+ 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;
}

diff --git a/gdb/testsuite/gdb.cp/enum.exp b/gdb/testsuite/gdb.cp/enum.exp
new file mode 100644
index 0000000..3d5e0f6
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/enum.exp
@@ -0,0 +1,74 @@
+# Copyright 2010 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/>.
+
+# Test searching enum constant symbols derived from base classes.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile1 enum1
+set testfile2 enum2
+set srcfile1 ${testfile1}.cc
+set srcfile2 ${testfile2}.cc
+set binfile1 ${objdir}/${subdir}/${testfile1}
+set binfile2 ${objdir}/${subdir}/${testfile2}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {debug c++}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug c++}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+if [get_compiler_info ${binfile1}] {
+ return -1
+}
+if [get_compiler_info ${binfile2}] {
+ return -1
+}
+
+# Get things started.
+
+############################################
+# Test printing an enum constant symbol derived from base
+# class without namespaces
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile1}
+
+gdb_breakpoint [gdb_get_line_number "breakpoint" $srcfile1]
+gdb_run_cmd
+gdb_test "print X" "= A::X" "Print enum constant X of class A"
+
+
+############################################
+# Test printing an enum constant symbol derived from base
+# class in a namespace
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile2}
+
+gdb_breakpoint [gdb_get_line_number "breakpoint" $srcfile2]
+gdb_run_cmd
+gdb_test "print X" "= N::A::X" \
+ "Print enum constant X of class A in namespace N"
+
diff --git a/gdb/testsuite/gdb.cp/enum1.cc b/gdb/testsuite/gdb.cp/enum1.cc
new file mode 100644
index 0000000..6211cea
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/enum1.cc
@@ -0,0 +1,34 @@
+class A
+{
+public:
+ enum E {X,Y,Z};
+};
+
+class B1 : public A
+{
+};
+
+class B2 : public A
+{
+};
+
+class C : public B1, public B2
+{
+public:
+ void test(E e);
+};
+
+void C::test(E e)
+{
+ if (e == X) //breakpoint
+ {
+ }
+}
+
+int main()
+{
+ C c;
+ c.test(A::X);
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.cp/enum2.cc b/gdb/testsuite/gdb.cp/enum2.cc
new file mode 100644
index 0000000..c864c1c
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/enum2.cc
@@ -0,0 +1,37 @@
+namespace N
+{
+ class A
+ {
+ public:
+ enum E {X,Y,Z};
+ };
+
+ class B1 : public A
+ {
+ };
+
+ class B2 : public A
+ {
+ };
+
+ class C : public B1, public B2
+ {
+ public:
+ void test(E e);
+ };
+
+ void C::test(E e)
+ {
+ if (e == X) //breakpoint
+ {
+ }
+ }
+};
+
+int main()
+{
+ N::C c;
+ c.test(N::A::X);
+ return 0;
+}
+
--
1.6.0.4



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]