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