From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12429 invoked by alias); 19 May 2011 22:52:41 -0000 Received: (qmail 12405 invoked by uid 22791); 19 May 2011 22:52:36 -0000 X-SWARE-Spam-Status: No, hits=-5.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD 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; Thu, 19 May 2011 22:52:16 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p4JMqFwL032201 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 19 May 2011 18:52:15 -0400 Received: from valrhona.uglyboxes.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p4JMqD9C006071 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Thu, 19 May 2011 18:52:14 -0400 Message-ID: <4DD59F1C.6040608@redhat.com> Date: Thu, 19 May 2011 22:52:00 -0000 From: Keith Seitz User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.38.b3pre.fc13 Lightning/1.0b3pre Thunderbird/3.1.9 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: [RFA] Anonymous namespaces and linespecs Content-Type: multipart/mixed; boundary="------------080908040807080606000204" 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: 2011-05/txt/msg00465.txt.bz2 This is a multi-part message in MIME format. --------------080908040807080606000204 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1511 Hi, This is actually a patch for symtab/12704, reported by Jan: (gdb) b 'FOO::(anonymous namespace)::BAR()' Junk at end of arguments. This is happening because along with the physname patch, there was also alot of mucking around with decode_line_1 and decode_compound. This is fallout from that. [Remember: we used to push almost everything through decode_variable -- in which the quoting is /required/.] If we see "(anonymous namespace)", we must keep it as a significant part of the name. On the upside, we now no longer have to quote this stuff, either. This patch also contains one cleanup. The string "(anonymous namespace)" was beginning to proliferate throughout the sources. I've added a macro to cp-support.h to define this string and changed all the places it had been hard-coded. Tested on the buildbot. Keith ChangeLog 2010-05-18 Keith Seitz PR symtab/12704 * cp-namespace.c (ANONYMOUS_NAMESPACE_LEN): Remove. (cp_scan_for_anonymous_namespaces): Use CP_ANONYMOUS_NAMESPACE_STR and CP_ANONYMOUS_NAMESPACE_LEN. (cp_is_anonymous): Likewise. * cp_support.h (CP_ANONYMOUS_NAMESPACE_STR): Define. (CP_ANONYMOUS_NAMESPACE_LEN): Define. * dwarf2read.c (namespace_name): Likewise. (fixup_partial_die): Likewise. * linespec.c (decode_compound): If CP_ANONYMOUS_NAMESPACE_STR is seen in the input, keep it. testsuite/ChangeLog 2010-05-18 Keith Seitz PR symtab/12704 * gdb.cp/anon-ns.cc: New file. * gdb.cp/anon-ns.exp: New file. --------------080908040807080606000204 Content-Type: text/plain; name="12704.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="12704.patch" Content-length: 8584 diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index 00c68b3..7ff7bf7 100644 --- gdb/cp-namespace.c +++ gdb/cp-namespace.c @@ -52,10 +52,6 @@ static struct type *cp_lookup_transparent_type_loop (const char *name, /* Check to see if SYMBOL refers to an object contained within an anonymous namespace; if so, add an appropriate using directive. */ -/* Optimize away strlen ("(anonymous namespace)"). */ - -#define ANONYMOUS_NAMESPACE_LEN 21 - void cp_scan_for_anonymous_namespaces (const struct symbol *symbol) { @@ -76,10 +72,11 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) while (name[next_component] == ':') { - if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN + if (((next_component - previous_component) + == CP_ANONYMOUS_NAMESPACE_LEN) && strncmp (name + previous_component, - "(anonymous namespace)", - ANONYMOUS_NAMESPACE_LEN) == 0) + CP_ANONYMOUS_NAMESPACE_STR, + CP_ANONYMOUS_NAMESPACE_LEN) == 0) { int dest_len = (previous_component == 0 ? 0 : previous_component - 2); @@ -207,7 +204,7 @@ cp_set_block_scope (const struct symbol *symbol, int cp_is_anonymous (const char *namespace) { - return (strstr (namespace, "(anonymous namespace)") + return (strstr (namespace, CP_ANONYMOUS_NAMESPACE_STR) != NULL); } diff --git a/gdb/cp-support.h b/gdb/cp-support.h index 57aa03a..52d4cb7 100644 --- gdb/cp-support.h +++ gdb/cp-support.h @@ -36,6 +36,14 @@ struct objfile; struct type; struct demangle_component; +/* A string representing the name of the anonymous namespace used in GDB. */ + +#define CP_ANONYMOUS_NAMESPACE_STR "(anonymous namespace)" + +/* The length of the string representing the anonymous namespace. */ + +#define CP_ANONYMOUS_NAMESPACE_LEN 21 + /* This struct is designed to store data from using directives. It says that names from namespace IMPORT_SRC should be visible within namespace IMPORT_DEST. These form a linked list; NEXT is the next diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 658205e..ee27c2d 100644 --- gdb/dwarf2read.c +++ gdb/dwarf2read.c @@ -7847,7 +7847,7 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu) *is_anonymous = (name == NULL); if (*is_anonymous) - name = "(anonymous namespace)"; + name = CP_ANONYMOUS_NAMESPACE_STR; return name; } @@ -9517,7 +9517,7 @@ fixup_partial_die (struct partial_die_info *part_die, /* Set default names for some unnamed DIEs. */ if (part_die->name == NULL && part_die->tag == DW_TAG_namespace) - part_die->name = "(anonymous namespace)"; + part_die->name = CP_ANONYMOUS_NAMESPACE_STR; /* If there is no parent die to provide a namespace, and there are children, see if we can determine the namespace from their linkage diff --git a/gdb/linespec.c b/gdb/linespec.c index 871d37d..4658e2d 100644 --- gdb/linespec.c +++ gdb/linespec.c @@ -1422,8 +1422,15 @@ decode_compound (char **argptr, int funfirstline, { /* PASS2: We'll keep getting here, until P points to one of the break characters, at which point we exit this loop. */ - if (*p && strchr (break_characters, *p) == NULL) - p++; + if (*p) + { + if (p[1] == '(' + && strncmp (&p[1], CP_ANONYMOUS_NAMESPACE_STR, + CP_ANONYMOUS_NAMESPACE_LEN) == 0) + p += CP_ANONYMOUS_NAMESPACE_LEN; + else if (strchr (break_characters, *p) == NULL) + ++p; + } } } diff --git a/gdb/testsuite/gdb.cp/anon-ns.cc b/gdb/testsuite/gdb.cp/anon-ns.cc new file mode 100644 index 0000000..949754d --- /dev/null +++ gdb/testsuite/gdb.cp/anon-ns.cc @@ -0,0 +1,92 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 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 . + + Contributed by Red Hat, originally written by Keith Seitz. */ + +#include + +namespace +{ + void doit1 (void) { } // doit1(void) + void doit1 (int a) { } // doit1(int) + void doit1 (char *a) { } // doit1(char *) + + class one + { + public: + one (void) { } // one::one(void) + one (int a) { } // one::one(int) + one (char *a) { } // one::one(char *) + static void doit (void) { } // one::doit(void) + }; + + namespace A + { + void doit2 (void) { } // A::doit2(void) + void doit2 (int a) { } // A::doit2(int) + void doit2 (char *a) { } // A::doit2(char *) + + class two + { + public: + two (void) { } // A::two::two(void) + two (int a) { } // A::two::two(int) + two (char *a) { } // A::two::two(char *) + static void doit (void) { } // A::two::doit(void) + }; + + namespace + { + namespace + { + void doit3 (void) { } // A::doit3(void) + void doit3 (int a) { } // A::doit3(int) + void doit3 (char *a) { } // A::doit3(char *) + + class three + { + public: + three (void) { } // A::three::three(void) + three (int a) { } // A::three::three(int) + three (char *a) { } // A::three::three(char *) + static void doit (void) { } // A::three::doit(void) + }; + } + } + } +} + +int +main (void) +{ + one a, b (3), c (static_cast (NULL)); + one::doit (); + A::two d, e (3), f (static_cast (NULL)); + A::two::doit (); + A::three g, h (3), i (static_cast (NULL)); + A::three::doit (); + doit1 (); + doit1 (3); + doit1 (static_cast (NULL)); + A::doit2 (); + A::doit2 (3); + A::doit2 (static_cast (NULL)); + A::doit3 (); + A::doit3 (3); + A::doit3 (static_cast (NULL)); + return 0; +} diff --git a/gdb/testsuite/gdb.cp/anon-ns.exp b/gdb/testsuite/gdb.cp/anon-ns.exp new file mode 100644 index 0000000..07d804c --- /dev/null +++ gdb/testsuite/gdb.cp/anon-ns.exp @@ -0,0 +1,70 @@ +# Copyright 2011 Free Software Foundation, Inc. +# +# Contributed by Red Hat, originally written by Keith Seitz. +# +# 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 . + +# This file is part of the gdb testsuite. + +if {[skip_cplus_tests]} { continue } + +# Tests for c++/12750/12704 +set testfile "anon-ns" +set srcfile $testfile.cc + +if {[prepare_for_testing $testfile $testfile $srcfile {c++ debug}]} { + return -1 +} + +if {![runto_main]} { + perror "couldn't run to breakpoint" + continue +} + +set ans {(anonymous namespace)} +set types {"void" "int" "char *"} +set methods {} +foreach t $types { + lappend methods "${ans}::doit1($t)" + lappend methods "${ans}::one::one($t)" + lappend methods "${ans}::A::doit2($t)" + lappend methods "${ans}::A::two::two($t)" + lappend methods "${ans}::A::${ans}::${ans}::doit3($t)" + lappend methods "${ans}::A::${ans}::${ans}::three::three($t)" +} + +lappend methods "${ans}::one::doit(void)" +lappend methods "${ans}::A::two::doit(void)" +lappend methods "${ans}::A::${ans}::${ans}::three::doit(void)" + +gdb_test_no_output "set listsize 1" "" + +foreach test $methods { + # The result we expect is the source code name of the symbol, + # i.e., without "(anonymous namespace)". + regsub -all [string_to_regexp "${ans}::"] $test "" expected + set result ".*// [string_to_regexp $expected]" + + gdb_test "list $test" $result + gdb_test "list '$test'" $result + if {[gdb_breakpoint $test]} { + pass "break $test" + } + if {[gdb_breakpoint '$test']} { + pass "break '$test'" + } +} + +gdb_exit +return 0 --------------080908040807080606000204--