From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30083 invoked by alias); 4 Nov 2010 08:51:42 -0000 Received: (qmail 30070 invoked by uid 22791); 4 Nov 2010 08:51:41 -0000 X-SWARE-Spam-Status: No, hits=-0.3 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.windriver.com (HELO mail.windriver.com) (147.11.1.11) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 04 Nov 2010 08:51:33 +0000 Received: from ALA-MAIL03.corp.ad.wrs.com (ala-mail03 [147.11.57.144]) by mail.windriver.com (8.14.3/8.14.3) with ESMTP id oA48pBQv016677; Thu, 4 Nov 2010 01:51:11 -0700 (PDT) Received: from ala-mail06.corp.ad.wrs.com ([147.11.57.147]) by ALA-MAIL03.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 4 Nov 2010 01:51:11 -0700 Received: from [128.224.158.168] ([128.224.158.168]) by ala-mail06.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 4 Nov 2010 01:51:10 -0700 Message-ID: <4CD27431.30401@windriver.com> Date: Thu, 04 Nov 2010 08:51:00 -0000 From: "Liu, Lei" User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101027 Thunderbird/3.0.10 MIME-Version: 1.0 To: Pedro Alves CC: gdb-patches@sourceware.org Subject: Re: [PATCH] call cp_lookup_symbol_namespace recursively to search symbols in C++ base classes References: <4CCF89F0.5090100@windriver.com> <201011030009.47662.pedro@codesourcery.com> In-Reply-To: <201011030009.47662.pedro@codesourcery.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-11/txt/msg00086.txt.bz2 On 2010年11月03日 08:09, Pedro Alves wrote: > Your testcase is not hitting this empty scope check, due to your > "#include", 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 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 . + +# 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