From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19868 invoked by alias); 4 Sep 2009 16:57:02 -0000 Received: (qmail 19856 invoked by uid 22791); 4 Sep 2009 16:57:00 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 04 Sep 2009 16:56:48 +0000 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n84Gukbr014832 for ; Fri, 4 Sep 2009 12:56:46 -0400 Received: from toner.yyz.redhat.com (toner.yyz.redhat.com [10.15.16.55]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n84GujPc007414; Fri, 4 Sep 2009 12:56:45 -0400 Message-ID: <4AA14648.7090600@redhat.com> Date: Fri, 04 Sep 2009 16:57:00 -0000 From: Sami Wagiaalla User-Agent: Thunderbird 2.0.0.17 (X11/20081009) MIME-Version: 1.0 To: Sami Wagiaalla , GDB Patches Subject: Re: [patch 2/2] Perform a namespace lookup at every block level References: <4A57512A.7090208@redhat.com> <20090710194949.GA2064@caradoc.them.org> <4A5B68A4.30006@redhat.com> <4A68B91D.2080206@redhat.com> <4A8B0FD9.7010603@redhat.com> In-Reply-To: <4A8B0FD9.7010603@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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: 2009-09/txt/msg00100.txt.bz2 > A recursive search must be performed. This patch provides that > functionality: > That implementation performed redundant searches. This problem is fixed by this patch. 2009-09-04 Sami Wagiaalla * cp-namespace.c (cp_lookup_symbol_namespace): Added search_parent argument. * cp-support.h (cp_lookup_symbol_imports): Ditto. * cp-namespace.c (cp_lookup_symbol_imports): Ditto. Implement non parent search. * valops.c (value_maybe_namespace_elt): Updated. 2009-09-04 Sami Wagiaalla * gdb.cp/namespace-stress.exp: New test. * gdb.cp/namespace-stress.cc: New test file. diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index 909ec2c..eeaf851 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -46,7 +46,8 @@ static struct symbol *cp_lookup_symbol_imports (const char *scope, const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain); + const domain_enum domain, + const int search_parents); static struct symbol *cp_lookup_symbol_in_namespace (const char *namespace, const char *name, @@ -287,7 +288,7 @@ cp_lookup_symbol_nonlocal (const char *name, if ( sym != NULL) return sym; - return cp_lookup_symbol_namespace(scope, name, linkage_name, block, domain); + return cp_lookup_symbol_namespace(scope, name, linkage_name, block, domain, 1); } /* Searches for NAME in the current namespace, and by applying relevant import @@ -299,14 +300,16 @@ cp_lookup_symbol_namespace (const char *scope, const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain) + const domain_enum domain, + const int search_parents) { struct symbol *sym; /* Search for name in namespaces imported to this and parent blocks. */ while (block != NULL) { - sym = cp_lookup_symbol_imports(scope,name, linkage_name, block, domain); + sym = cp_lookup_symbol_imports(scope,name, linkage_name, block, domain, + search_parents ); if (sym) return sym; @@ -402,17 +405,33 @@ cp_lookup_symbol_in_namespace (const char *namespace, } /* Search for NAME by applying all import statements belonging - to BLOCK which are applicable in SCOPE. */ + to BLOCK which are applicable in SCOPE. + If SEARCH_PARENTS the search will include imports which are applicable in + parents of scopes. + Example: + + namespace A{ + using namespace X; + namespace B{ + using namespace Y; + } + } + + If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X + and Y will be considered. If SEARCH_PARENTS is false only the import of Y + is considered. */ static struct symbol * cp_lookup_symbol_imports (const char *scope, const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain) + const domain_enum domain, + const int search_parents) { struct using_direct *current; struct symbol *sym; + int directive_match; /* First, try to find the symbol in the given namespace. */ sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block, @@ -429,9 +448,15 @@ cp_lookup_symbol_imports (const char *scope, current = current->next) { + directive_match = search_parents ? + strncmp (scope, current->import_dest, + strlen(current->import_dest)) == 0 : + strcmp (scope, current->import_dest) == 0; + /* If the import destination is the current scope or one of its ancestors then it is applicable. */ - if (strncmp (scope, current->import_dest, + if (directive_match && + strncmp (scope, current->import_dest, strlen(current->import_dest)) == 0 && !current->searched ) { @@ -442,8 +467,8 @@ cp_lookup_symbol_imports (const char *scope, name, linkage_name, block, - domain); - + domain, 0); + current->searched = 0; if (sym != NULL) return sym; diff --git a/gdb/cp-support.h b/gdb/cp-support.h index c9d53e5..348d7c9 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -108,7 +108,8 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace, const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain); + const domain_enum domain, + const int search_parents); extern struct type *cp_lookup_nested_type (struct type *parent_type, const char *nested_name, diff --git a/gdb/testsuite/gdb.cp/namespace-stress.cc b/gdb/testsuite/gdb.cp/namespace-stress.cc new file mode 100644 index 0000000..f34083e --- /dev/null +++ b/gdb/testsuite/gdb.cp/namespace-stress.cc @@ -0,0 +1,60 @@ + +namespace A{ int x; } +namespace B{ int x; } +namespace C{ int x; } +namespace D{ int x; } +namespace E{ int x; } +namespace F{ int x; } +namespace G{ int x; } +namespace H{ int x; } +namespace I{ int x; } +namespace J{ int x; } +namespace K{ int x; } +namespace L{ int x; } +namespace M{ int x; } +namespace N{ int x; } +namespace O{ int x; } +namespace P{ int x; } +namespace Q{ int x; } +namespace R{ int x; } +namespace S{ int x; } +namespace T{ int x; } +namespace U{ int x; } +namespace V{ int x; } +namespace W{ int x; } +namespace X{ int x; } +namespace Y{ int x; } +namespace Z{ int x; } + + +int main(){ + + using namespace A; + using namespace B; + using namespace C; + using namespace D; + using namespace E; + using namespace F; + using namespace G; + using namespace H; + using namespace I; + using namespace J; + using namespace K; + using namespace L; + using namespace M; + using namespace N; + using namespace O; + using namespace P; + using namespace Q; + using namespace R; + using namespace S; + using namespace T; + using namespace U; + using namespace V; + using namespace W; + using namespace X; + using namespace Y; + using namespace Z; + + return 0; +} \ No newline at end of file diff --git a/gdb/testsuite/gdb.cp/namespace-stress.exp b/gdb/testsuite/gdb.cp/namespace-stress.exp new file mode 100644 index 0000000..36e0628 --- /dev/null +++ b/gdb/testsuite/gdb.cp/namespace-stress.exp @@ -0,0 +1,50 @@ +# Copyright 2008 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 . + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +set testfile namespace-stress +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +if [get_compiler_info ${binfile}] { + return -1; +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + perror "couldn't run to breakpoint main" + continue +} + +############################################ +# Test that the search can fail efficiently + +gdb_test "print y" "No symbol \"y\" in current context." diff --git a/gdb/valops.c b/gdb/valops.c index 5e5c4ed..3448b4a 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -2754,7 +2754,7 @@ value_maybe_namespace_elt (const struct type *curtype, sym = cp_lookup_symbol_namespace (namespace_name, name, NULL, get_selected_block (0), - VAR_DOMAIN); + VAR_DOMAIN,1); if (sym == NULL) return NULL;