From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15630 invoked by alias); 21 Feb 2011 11:06:50 -0000 Received: (qmail 15609 invoked by uid 22791); 21 Feb 2011 11:06:44 -0000 X-SWARE-Spam-Status: No, hits=-4.7 required=5.0 tests=AWL,BAYES_00,FAKE_REPLY_C,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,TW_CP,TW_GP,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; Mon, 21 Feb 2011 11:06:33 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p1LB6V1b021339 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 21 Feb 2011 06:06:32 -0500 Received: from host1.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p1LB6T4p013025 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 21 Feb 2011 06:06:31 -0500 Received: from host1.dyn.jankratochvil.net (localhost [127.0.0.1]) by host1.dyn.jankratochvil.net (8.14.4/8.14.4) with ESMTP id p1LB6T9U014365; Mon, 21 Feb 2011 12:06:29 +0100 Received: (from jkratoch@localhost) by host1.dyn.jankratochvil.net (8.14.4/8.14.4/Submit) id p1LB6Sco014363; Mon, 21 Feb 2011 12:06:28 +0100 Date: Mon, 21 Feb 2011 11:41:00 -0000 From: Jan Kratochvil To: Keith Seitz Cc: gdb-patches@sourceware.org Subject: Re: [patch 0/3] Re: [RFA] c++/11734 revisited (and c++/12273) Message-ID: <20110221110627.GA29540@host1.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <4D5DA1D0.9060701@redhat.com> <4D5D652B.9070200@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) 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-02/txt/msg00536.txt.bz2 Hi Keith, On Thu, 17 Feb 2011 19:12:59 +0100, Keith Seitz wrote: > These patches are largely the same as the past two I posted for > 11734 and 12273, but there is, of necessity, a handful of noteworthy > additions/changes worth mentioning here (perhaps if nothing more > than to facilitate review). > > - The test case for 11734 (now called ovsrch.exp) was modified to > expose more bugs. > - Fixes for the above bugs (passing valid blocks to lookup_symbol in > several places, reconstructing search name based on SYM_CLASS in > find_method -- see code for detailed explanation) > - Unilateral removal of the single quote in decode_compound - The new parameter `enum language language' was removed all over the code as it has been passed only `current_language->la_language' anyway. mv pr12273.exp cmpd-minsyms.exp mv pr12273.cc cmpd-minsyms.cc mv pr11734.exp ovsrch.exp mv pr11734.h ovsrch.h mv pr11734-1.cc ovsrch1.cc mv pr11734-2.cc ovsrch2.cc mv pr11734-3.cc ovsrch3.cc mv pr11734-4.cc ovsrch4.cc > --- linespec.c 9 Jan 2011 03:08:57 -0000 1.109 > +++ linespec.c 17 Feb 2011 17:45:12 -0000 > @@ -1057,6 +1057,10 @@ locate_first_half (char **argptr, int *i > error (_("malformed template specification in command")); > p = temp_end; > } > + > + if (p[0] == '(') > + p = find_method_overload_end (p); pre-physname: GNU gdb (GDB) 7.1.50.20100309-cvs (gdb) b A::outer::foo (int) Breakpoint 1 at 0x4005a3: file ./gdb.cp/ovsrch3.cc, line 23. (gdb) b A::outer::foo (void) Breakpoint 2 at 0x40058c: file ./gdb.cp/ovsrch2.cc, line 23. (gdb) b A::outer::foo (char *) Breakpoint 3 at 0x4005c0: file ./gdb.cp/ovsrch4.cc, line 23. patched: GNU gdb (GDB) 7.2.50.20110220-cvs (gdb) b A::outer::foo (int) the class A::outer does not have any method named foo (int) This is a regression. There should be some whitespace skipping, as strcmp_iw_ordered does. > + > /* Check for a colon and a plus or minus and a [ (which > indicates an Objective-C method). */ > if (is_objc_method_format (p)) > @@ -1226,7 +1230,7 @@ decode_objc (char **argptr, int funfirst > > static struct symtabs_and_lines > decode_compound (char **argptr, int funfirstline, char ***canonical, > - char *saved_arg, char *p, int *not_found_ptr) > + char *the_real_saved_arg, char *p, int *not_found_ptr) > { > struct symtabs_and_lines values; > char *p2; > @@ -1237,6 +1241,23 @@ decode_compound (char **argptr, int funf > struct symbol *sym_class; > struct type *t; > char *saved_java_argptr = NULL; > + char *saved_arg; > + > + /* If the user specified any single-quotes in the input, strip them. > + They are superfluous. */ > + saved_arg = alloca (strlen (the_real_saved_arg) + 1); > + { > + char *dst = saved_arg; > + char *src = the_real_saved_arg; > + > + while (*src != '\0') > + { > + if (*src != '\'') It assumes get_gdb_completer_quote_characters() is just "'" as currently is. It cannot be changed now anyway and for future it should be rather removed than extended. It was already hardcoded into decode_compound before physname patch. Depending on your choice either to call get_gdb_completer_quote_characters() or dropping get_gdb_completer_quote_characters() or maybe even a comment referencing it would suffice. BTW realized Ada has operator ' (seen in gdb.ada/*/*.adb) but it is applicable only to types and variables so probably not an issue for linespec. Googled: http://www.dei.isep.ipp.pt/~lpinho/ada95/linux_book/10.html#10.4 > + *dst++ = *src; > + ++src; > + } > + *dst = '\0'; > + } > > /* First check for "global" namespace specification, of the form > "::foo". If found, skip over the colons and jump to normal > @@ -1253,8 +1274,10 @@ decode_compound (char **argptr, int funf > find_method. > > 2) AAA::inA isn't the name of a class. In that case, either the > - user made a typo or AAA::inA is the name of a namespace. > - Either way, we just look up AAA::inA::fun with lookup_symbol. > + user made a typo, AAA::inA is the name of a namespace, or it is > + the name of a minimal symbol. > + We just look up AAA::inA::fun with lookup_symbol. If that fails, > + try lookup_minimal_symbol. > > Thus, our first task is to find everything before the last set of > double-colons and figure out if it's the name of a class. So we > @@ -1275,6 +1298,8 @@ decode_compound (char **argptr, int funf > > while (1) > { > + static char *break_characters = " \t\'("; Éxcessive backslash. Some comment and/or removal wrt get_gdb_completer_quote_characters for '. (OK, this ' hardcoded in decode_compound was present even before physname, I can clean it up afterwards.) > + > /* Move pointer up to next possible class/namespace token. */ > > p = p2 + 1; /* Restart with old value +1. */ > @@ -1285,8 +1310,7 @@ decode_compound (char **argptr, int funf > /* PASS2: p2->"::fun", p->":fun" */ > > /* Move pointer ahead to next double-colon. */ > - while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'') > - && (*p != '(')) > + while (*p && strchr (break_characters, *p) == NULL) > { > if (current_language->la_language == language_cplus) > p += cp_validate_operator (p); > @@ -1310,9 +1334,12 @@ decode_compound (char **argptr, int funf > else if ((p[0] == ':') && (p[1] == ':')) > break; /* Found double-colon. */ > else > - /* PASS2: We'll keep getting here, until p->"", at which point > - we exit this loop. */ > - p++; > + { > + /* PASS2: We'll keep getting here, until P points to one of the > + break characters, at which point we exit this loop. */ > + if (strchr (break_characters, *p) == NULL) > + p++; *p can == '\0' here, it works - but I would prefer for better readability: if (*p && strchr (break_characters, *p) == NULL) p++; > + } > } > > if (*p != ':') > @@ -1321,7 +1348,7 @@ decode_compound (char **argptr, int funf > unsuccessfully all the components of the > string, and p->""(PASS2). */ > > - /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e > + /* We get here if p points to one of the break characters or "" (i.e., > string ended). */ > /* Save restart for next time around. */ > p2 = p; > @@ -1472,6 +1499,18 @@ decode_compound (char **argptr, int funf > /* We couldn't find a class, so we're in case 2 above. We check the > entire name as a symbol instead. */ > > + if (current_language->la_language == language_cplus > + || current_language->la_language == language_java) > + { > + char *paren = strchr (p, '('); > + if (paren != NULL) > + p = find_method_overload_end (paren); 00000000004004ea W _ZNK1C1mEv 00000000004004ea W C::m() const pre-physname: GNU gdb (GDB) 7.1.50.20100309-cvs (gdb) b C::m if C::m() Breakpoint 1 at 0x4004f2: file 3.C, line 4. (gdb) b 'C::m' if C::m() Breakpoint 1 at 0x4004f2: file 3.C, line 4. patched: GNU gdb (GDB) 7.2.50.20110220-cvs (gdb) b C::m if C::m() the class C does not have any method named m if C::m() (gdb) b 'C::m' if C::m() the class C does not have any method named m' if C::m() This is a regression. pre-physname had that IMHO-not-so-nice `has_if' protection. > + > + /* Make sure we keep important kewords like "const" */ > + if (strncmp (p, " const", 6) == 0) > + p += 6; 00000000004004ea W _ZNK1C1mEv 00000000004004ea W C::m() const pre-physname: GNU gdb (GDB) 7.1.50.20100309-cvs (gdb) b 'C::m() const' Breakpoint 1 at 0x4004f2: file 3.C, line 4. patched: GNU gdb (GDB) 7.2.50.20110220-cvs (gdb) b 'C::m() const' Junk at end of arguments. This is a regression. There should be some whitespace skipping, as strcmp_iw_ordered does. > + } > + > copy = (char *) alloca (p - saved_arg2 + 1); > memcpy (copy, saved_arg2, p - saved_arg2); > /* Note: if is_quoted should be true, we snuff out quote here > @@ -1481,15 +1520,24 @@ decode_compound (char **argptr, int funf > *argptr = (*p == '\'') ? p + 1 : p; > > /* Look up entire name. */ > - sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0); > + sym = lookup_symbol (copy, get_selected_block (0), VAR_DOMAIN, 0); > if (sym) > return symbol_found (funfirstline, canonical, copy, sym, NULL); > + else > + { > + struct minimal_symbol *msym; > + > + /* Couldn't find any interpretation as classes/namespaces. As a last > + resort, try the minimal symbol tables. */ > + msym = lookup_minimal_symbol (copy, NULL, NULL); > + if (msym != NULL) > + return minsym_found (funfirstline, msym); > + } > > - /* Couldn't find any interpretation as classes/namespaces, so give > - up. The quotes are important if copy is empty. */ > + /* Couldn't find a minimal symbol, either, so give up. */ > if (not_found_ptr) > *not_found_ptr = 1; > - cplusplus_error (saved_arg, > + cplusplus_error (the_real_saved_arg, > "Can't find member of namespace, " > "class, struct, or union named \"%s\"\n", > copy); > @@ -1528,7 +1576,7 @@ lookup_prefix_sym (char **argptr, char * > /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA", > argptr->"inA::fun". */ > > - sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0); > + sym = lookup_symbol (copy, get_selected_block (0), STRUCT_DOMAIN, 0); > if (sym == NULL) > { > /* Typedefs are in VAR_DOMAIN so the above symbol lookup will > @@ -1599,17 +1647,31 @@ find_method (int funfirstline, char ***c > if (strchr (saved_arg, '(') != NULL) > { > int i; > - char *name = saved_arg; > - char *canon = cp_canonicalize_string (name); > + char *name; > + char *canon; > struct cleanup *cleanup; > > + /* Construct the proper search name based on SYM_CLASS and COPY. > + SAVED_ARG may contain a valid name, but that name might not be > + what is actually stored in the symbol table. For example, > + if SAVED_ARG (and SYM_CLASS) were found via an import > + ("using namespace" in C++), then the physname of > + SYM_CLASS ("A::myclass") may not be the same as SAVED_ARG > + ("myclass"). */ > + name = xmalloc (strlen (SYMBOL_LINKAGE_NAME (sym_class)) > + + 2 /* "::" */ + strlen (copy) + 1); > + strcpy (name, SYMBOL_LINKAGE_NAME (sym_class)); Probably not meaningful for SYM_CLASS but isn't here appropriate rather SYMBOL_NATURAL_NAME? If SYMBOL_LINKAGE_NAME would be a mangled name for the class fully qualified name it would not work. But linkage name of a class type does not make sense so the suggested change is rather for code readability. > + strcat (name, "::"); > + strcat (name, copy); > + canon = cp_canonicalize_string (name); > if (canon != NULL) > { > + xfree (name); > name = canon; > cleanup = make_cleanup (xfree, canon); > } > else > - cleanup = make_cleanup (null_cleanup, NULL); > + cleanup = make_cleanup (xfree, name); > > for (i = 0; i < i1; ++i) > { > Index: psymtab.c > =================================================================== > RCS file: /cvs/src/src/gdb/psymtab.c,v > retrieving revision 1.22 > diff -u -p -r1.22 psymtab.c > --- psymtab.c 10 Jan 2011 20:38:50 -0000 1.22 > +++ psymtab.c 17 Feb 2011 17:45:12 -0000 > @@ -33,6 +33,8 @@ > #include "readline/readline.h" > #include "gdb_regex.h" > #include "dictionary.h" > +#include "language.h" > +#include "cp-support.h" > > #ifndef DEV_TTY > #define DEV_TTY "/dev/tty" > @@ -426,7 +428,26 @@ lookup_symbol_aux_psymtabs (struct objfi > ALL_OBJFILE_PSYMTABS (objfile, ps) > { > if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain)) > - return PSYMTAB_TO_SYMTAB (ps); > + { > + struct symbol *sym = NULL; > + struct symtab *stab = PSYMTAB_TO_SYMTAB (ps); > + > + /* Some caution must be observed with overloaded functions > + and methods, since the psymtab will not contain any overload > + information (but NAME might contain it). */ > + if (stab->primary) > + { > + struct blockvector *bv = BLOCKVECTOR (stab); > + struct block *block = BLOCKVECTOR_BLOCK (bv, block_index); > + > + sym = lookup_block_symbol (block, name, domain); > + } > + > + if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) > + return stab; > + > + /* Keep looking through other psymtabs. */ > + } > } > > return NULL; > @@ -519,6 +540,39 @@ pre_expand_symtabs_matching_psymtabs (st > /* Nothing. */ > } > > +/* Returns the name used to search psymtabs. Unlike symtabs, psymtabs do > + not contain any method/function instance information (since this would > + force reading type information while reading psymtabs). Therefore, > + if NAME contains overload information, it must be stripped before searching > + psymtabs. > + > + The caller is responsible for freeing the return result. */ > + > +static char * > +psymtab_search_name (const char *name) > +{ > + switch (current_language->la_language) > + { > + case language_cplus: > + case language_java: > + { > + if (strchr (name, '(')) > + { > + char *ret = cp_remove_params (name); > + > + if (ret) > + return ret; > + } > + } > + break; > + > + default: > + break; > + } > + > + return xstrdup (name); > +} > + > /* Look, in partial_symtab PST, for symbol whose natural name is NAME. > Check the global symbols if GLOBAL, the static symbols if not. */ > > @@ -530,11 +584,16 @@ lookup_partial_symbol (struct partial_sy > struct partial_symbol **top, **real_top, **bottom, **center; > int length = (global ? pst->n_global_syms : pst->n_static_syms); > int do_linear_search = 1; > + char *search_name; > + struct cleanup *cleanup; > > if (length == 0) > { > return (NULL); > } > + > + search_name = psymtab_search_name (name); > + cleanup = make_cleanup (xfree, search_name); > start = (global ? > pst->objfile->global_psymbols.list + pst->globals_offset : > pst->objfile->static_psymbols.list + pst->statics_offset); > @@ -563,7 +622,8 @@ lookup_partial_symbol (struct partial_sy > { > do_linear_search = 1; > } > - if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0) > + if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), > + search_name) >= 0) > { > top = center; > } > @@ -577,11 +637,14 @@ lookup_partial_symbol (struct partial_sy > _("failed internal consistency check")); > > while (top <= real_top > - && SYMBOL_MATCHES_SEARCH_NAME (*top, name)) > + && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name)) > { > if (symbol_matches_domain (SYMBOL_LANGUAGE (*top), > SYMBOL_DOMAIN (*top), domain)) > - return (*top); > + { > + do_cleanups (cleanup); > + return (*top); > + } > top++; > } > } > @@ -595,11 +658,15 @@ lookup_partial_symbol (struct partial_sy > { > if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym), > SYMBOL_DOMAIN (*psym), domain) > - && SYMBOL_MATCHES_SEARCH_NAME (*psym, name)) > - return (*psym); > + && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name)) > + { > + do_cleanups (cleanup); > + return (*psym); > + } > } > } > > + do_cleanups (cleanup); > return (NULL); > } > > Index: testsuite/gdb.cp/cmpd-minsyms.exp > =================================================================== > RCS file: testsuite/gdb.cp/cmpd-minsyms.exp > diff -N testsuite/gdb.cp/cmpd-minsyms.exp > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ testsuite/gdb.cp/cmpd-minsyms.exp 17 Feb 2011 17:45:12 -0000 > @@ -0,0 +1,50 @@ > +# Copyright 2010 Free Software Foundation, Inc. 2011 > +# > +# 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 } > + > +# Test for c++/12273 > +set testfile "cmpd-minsyms" > +# Do NOT compile with debug flag. > +prepare_for_testing $testfile $testfile $testfile.cc {c++} if [prepare_for_testing ... ] { return -1 } > + > +gdb_test_no_output "set language c++" > + > +# A list of minimal symbol names to check. > +# Note that GDB::even_harder(char) is quoted and includes > +# the return type. This is necessary because this is the demangled name > +# of the minimal symbol. > +set min_syms [list \ > + "GDB::operator ==" \ > + "GDB::operator==(GDB const&)" \ > + "GDB::harder(char)" \ > + "GDB::harder(int)" \ > + {"int GDB::even_harder(char)"} \ > + "GDB::simple()"] > + > +foreach sym $min_syms { > + set tst "setting breakpoint at $sym" > + if {[gdb_breakpoint $sym]} { > + pass $tst > + } else { > + fail $tst [nitpick] gdb_breakpoint already always prints FAIL if it fails. > + } > +} > + > +gdb_exit > Index: testsuite/gdb.cp/cmpd-minsyms.cc > =================================================================== > RCS file: testsuite/gdb.cp/cmpd-minsyms.cc > diff -N testsuite/gdb.cp/cmpd-minsyms.cc > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ testsuite/gdb.cp/cmpd-minsyms.cc 17 Feb 2011 17:45:12 -0000 > @@ -0,0 +1,37 @@ > +/* This test case is part of GDB, the GNU debugger. > + > + Copyright 2010 Free Software Foundation, Inc. 2011 > + > + 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 . */ > + > +template > +class GDB > +{ > + public: > + static int simple (void) { return 0; } > + static int harder (T a) { return 1; } > + template > + static X even_harder (T a) { return static_cast (a); } > + int operator == (GDB const& other) > + { return 1; } > +}; > + > +int main(int argc, char **argv) > +{ > + GDB a, b; > + if (a == b) > + return GDB::harder('a') + GDB::harder(3) > + + GDB::even_harder ('a'); > + return GDB::simple (); > +} > Index: testsuite/gdb.cp/ovsrch.exp > =================================================================== > RCS file: testsuite/gdb.cp/ovsrch.exp > diff -N testsuite/gdb.cp/ovsrch.exp > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ testsuite/gdb.cp/ovsrch.exp 17 Feb 2011 17:45:12 -0000 > @@ -0,0 +1,103 @@ > +# 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. > + > +proc test_class {class} { > + > + # An array holding the overload types for the methods A::outer::foo > + # and A::B::inner::foo. The first element is the overloaded method > + # parameter. The second element is the expected source file number, > + # e.g. "ovsrch?.cc". > + array set tests { > + "char*" 4 > + "int" 3 > + "void" 2 > + } > + > + # Test each overload instance twice: once quoted, once unquoted > + foreach ovld [array names tests] { > + set method "${class}::foo\($ovld\)" Excessive backslashes. > + set result "Breakpoint (\[0-9\]).*file .*/ovsrch$tests($ovld).*" > + gdb_test "break $method" $result > + gdb_test "break '$method'" $result > + } > +} > + > +if { [skip_cplus_tests] } { continue } > + > +# Test for c++/11734 > +set testfile "ovsrch" > +set binfile [file join $objdir $subdir $testfile] > + > +set srcfiles {} > +for {set i 1} {$i < 5} {incr i} { > + lappend srcfiles [file join $srcdir $subdir $testfile$i.cc] > +} > +if {[gdb_compile $srcfiles $binfile executable {debug c++}] != "" } { > + untested $testfile.exp > + return -1 > +} > + > +if {[get_compiler_info $binfile "c++"]} { > + return -1 > +} > + > +gdb_exit > +gdb_start > +gdb_reinitialize_dir $srcdir/$subdir > +gdb_load $binfile > + > +if {![runto_main]} { > + perror "couldn't run to breakpoint" > + continue > +} > + > +# Break in A::stop_here and run tests. > +if {[gdb_breakpoint "stop_here"]} { > + pass "break stop_here" > +} else { > + fail "break stop_here" [nitpick] gdb_breakpoint already always prints FAIL if it fails. (and below) > +} > + > +if {[gdb_breakpoint "'stop_here'"]} { > + pass "break 'stop_here'" > +} else { > + fail "break 'stop_here'" > +} > + > +gdb_continue_to_breakpoint "stop_here" > +test_class outer > + > +# Break in A::B::stop_here_too and run tests. > +if {[gdb_breakpoint "B::stop_here_too"]} { > + pass "break B::stop_here_too" > +} else { > + fail "break B::stop_here_too" > +} > + > +if {[gdb_breakpoint "'B::stop_here_too'"]} { > + pass "break 'B::stop_here_too'" > +} else { > + fail "break 'B::stop_here_too'" > +} > + > +gdb_continue_to_breakpoint "stop_here_too" > +test_class inner > + > +gdb_exit > +return 0 [...] > Index: testsuite/gdb.cp/ovsrch4.cc > =================================================================== > RCS file: testsuite/gdb.cp/ovsrch4.cc > diff -N testsuite/gdb.cp/ovsrch4.cc > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ testsuite/gdb.cp/ovsrch4.cc 17 Feb 2011 17:45:12 -0000 > @@ -0,0 +1,28 @@ > +/* 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 . */ > + > +#include "ovsrch.h" > + > +void > +A::outer::foo (char *a) > +{ > +} > + > +void > +A::B::inner::foo (char *a) > +{ > +} On Thu, 17 Feb 2011 23:31:44 +0100, Keith Seitz wrote: > And of course, no sooner do I submit this, than I see I forgot something... > > On 02/17/2011 10:12 AM, Keith Seitz wrote: > >PR c++/11734 > >* gdb.cp/ovsrch.exp: New test. > > I have changed this to use prepare_for_testing: > > @@ -500,21 +500,10 @@ > + > +set srcfiles {} > +for {set i 1} {$i < 5} {incr i} { > -+ lappend srcfiles [file join $srcdir $subdir $testfile$i.cc] > -+} > -+if {[gdb_compile $srcfiles $binfile executable {debug c++}] != "" } { > -+ untested $testfile.exp > -+ return -1 > ++ lappend srcfiles $testfile$i.cc > +} > + > -+if {[get_compiler_info $binfile "c++"]} { > -+ return -1 > -+} > -+ > -+gdb_exit > -+gdb_start > -+gdb_reinitialize_dir $srcdir/$subdir > -+gdb_load $binfile > ++prepare_for_testing $testfile $testfile $srcfiles {c++ debug} if [prepare_for_testing ... ] { return -1 } > + > +if {![runto_main]} { > + perror "couldn't run to breakpoint" Sorry for the review delay. Thanks for all the linespec work, Jan