* Breaking in a c++ method with current language set to c.
@ 2007-03-05 3:37 Pedro Alves
2007-03-05 12:41 ` Daniel Jacobowitz
0 siblings, 1 reply; 5+ messages in thread
From: Pedro Alves @ 2007-03-05 3:37 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1169 bytes --]
Hi all,
I got a fail in gdb.cp/psmang.exp while debugging gdbserver, related to the fact
that I have debug info in my c startup files, which in turn made me have the
current language set to c. The test tried to do a break like,
break A::method
, which failed, because the current way of finding struct/union methods doesn't
take into account the language of A. When we get to linespec.c:find_method, if
we know that A is a c++ class, we know that 'method' is a c++ method.
I've looked at several ways to fix it, and all but this one turned out more
invasive than I hoped for, because current_language is used in a several places
(in symtab.c). Instead, I simply wrapped linespec.c:find_method with a
set_language (lang of A), guarded with a cleanup.
With class A from the new testcase in the patch,
before:
(gdb) set lang c
(gdb) b A::method
the class A does not have any method named method
Hint: try 'A::method<TAB> or 'A::method<ESC-?>
(Note leading single quote.)
after:
(gdb) set lang c
[0] cancel
[1] all
[2] A::method(A*) at main.cc:17
[3] A::method(int) at main.cc:12
[4] A::method() at main.cc:7
Tested on i686-pc-cygwin,
OK?
Cheers,
Pedro Alves
[-- Attachment #2: psmang.exp.diff --]
[-- Type: text/plain, Size: 6207 bytes --]
gdb/
2007-03-05 Pedro Alves <pedro_alves@portugalmail.pt>
* linespec.c (find_method_1): Renamed from find_method.
(set_language_ptr): New.
(find_method): New as wrapper around find_method_1.
gdb/testsuite/
2007-03-05 Pedro Alves <pedro_alves@portugalmail.pt>
* gdb.cp/method2.cc: New test.
* gdb.cp/method2.exp: New test.
* gdb.cp/Makefile.in (EXECUTABLES): Add method2.
---
gdb/linespec.c | 40 +++++++++++++++++++++-
gdb/testsuite/gdb.cp/Makefile.in | 2 -
gdb/testsuite/gdb.cp/method2.cc | 27 +++++++++++++++
gdb/testsuite/gdb.cp/method2.exp | 70 +++++++++++++++++++++++++++++++++++++++
4 files changed, 137 insertions(+), 2 deletions(-)
Index: src/gdb/linespec.c
===================================================================
--- src.orig/gdb/linespec.c 2007-03-05 02:42:26.000000000 +0000
+++ src/gdb/linespec.c 2007-03-05 02:50:50.000000000 +0000
@@ -37,6 +37,7 @@
#include "objc-lang.h"
#include "linespec.h"
#include "exceptions.h"
+#include "language.h"
/* We share this one with symtab.c, but it is not exported widely. */
@@ -1398,7 +1399,7 @@ lookup_prefix_sym (char **argptr, char *
symbol is SYM_CLASS. */
static struct symtabs_and_lines
-find_method (int funfirstline, char ***canonical, char *saved_arg,
+find_method_1 (int funfirstline, char ***canonical, char *saved_arg,
char *copy, struct type *t, struct symbol *sym_class)
{
struct symtabs_and_lines values;
@@ -1461,6 +1462,43 @@ find_method (int funfirstline, char ***c
}
}
+static void
+set_language_ptr (void *language)
+{
+ enum language *l = language;
+ set_language (*l);
+}
+
+/* A wrapper for find_method_1 that sets the current language
+ temporarily to the language of SYM_CLASS. */
+
+static struct symtabs_and_lines
+find_method (int funfirstline, char ***canonical, char *saved_arg,
+ char *copy, struct type *t, struct symbol *sym_class)
+{
+ struct symtabs_and_lines result;
+
+ if (SYMBOL_LANGUAGE (sym_class) != current_language->la_language
+ && SYMBOL_LANGUAGE (sym_class) != language_unknown)
+ {
+ enum language saved_current_language = current_language->la_language;
+ struct cleanup *cleanups;
+ set_language (SYMBOL_LANGUAGE (sym_class));
+ cleanups = make_cleanup (set_language_ptr, &saved_current_language);
+ result = find_method_1 (funfirstline, canonical, saved_arg,
+ copy, t, sym_class);
+ do_cleanups (cleanups);
+ }
+ else
+ {
+ result = find_method_1 (funfirstline, canonical, saved_arg,
+ copy, t, sym_class);
+ }
+
+ return result;
+}
+
+
/* Find all methods named COPY in the class whose type is T, and put
them in SYM_ARR. Return the number of methods found. */
Index: src/gdb/testsuite/gdb.cp/method2.cc
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/gdb.cp/method2.cc 2007-03-05 02:50:50.000000000 +0000
@@ -0,0 +1,27 @@
+struct A
+{
+ void method ();
+ void method (int a);
+ void method (A* a);
+};
+
+void
+A::method ()
+{
+}
+
+void
+A::method (int a)
+{
+}
+
+void
+A::method (A* a)
+{
+}
+
+int
+main (int argc, char** argv)
+{
+ return 0;
+}
Index: src/gdb/testsuite/gdb.cp/method2.exp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/gdb.cp/method2.exp 2007-03-05 03:19:40.000000000 +0000
@@ -0,0 +1,70 @@
+# Copyright 2007
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This file is part of the gdb testsuite
+
+# This tests setting a break in an ambiguous c++ method with
+# current_language set to c.
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "method2"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ untested method2.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] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+proc test_break { lang } {
+ global gdb_prompt
+
+ gdb_test "set lang $lang" \
+ "" \
+ "setting language $lang"
+
+ send_gdb "break A::method\n"
+ gdb_expect {
+ -re ".0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. A::method\\(A\\*\\) at .*\[\r\n\]*.3. A::method\\(int\\) at .*\[\r\n\]*\[\r\n\]*.4. A::method\\(\\) at .*\[\r\n\]*> $" {
+ gdb_test "0" \
+ "canceled" \
+ "breaking in method ($lang)"
+ }
+ -re ".*$gdb_prompt $" { fail "breaking in method ($lang)" }
+ default { fail "breaking in method ($lang) (timeout)" }
+ }
+}
+
+test_break "c"
+test_break "c++"
+
+gdb_continue_to_end "continue to end"
Index: src/gdb/testsuite/gdb.cp/Makefile.in
===================================================================
--- src.orig/gdb/testsuite/gdb.cp/Makefile.in 2006-07-13 05:31:42.000000000 +0100
+++ src/gdb/testsuite/gdb.cp/Makefile.in 2007-03-05 02:54:12.000000000 +0000
@@ -4,7 +4,7 @@ srcdir = @srcdir@
EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \
derivation inherit local member-ptr method misc \
overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace \
- ref-types ref-params
+ ref-types ref-params method2
all info install-info dvi install uninstall installcheck check:
@echo "Nothing to be done for $@..."
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: Breaking in a c++ method with current language set to c. 2007-03-05 3:37 Breaking in a c++ method with current language set to c Pedro Alves @ 2007-03-05 12:41 ` Daniel Jacobowitz 2007-03-11 21:07 ` Pedro Alves 0 siblings, 1 reply; 5+ messages in thread From: Daniel Jacobowitz @ 2007-03-05 12:41 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On Mon, Mar 05, 2007 at 03:37:15AM +0000, Pedro Alves wrote: > I've looked at several ways to fix it, and all but this one turned out more > invasive than I hoped for, because current_language is used in a several > places > (in symtab.c). Instead, I simply wrapped linespec.c:find_method with a > set_language (lang of A), guarded with a cleanup. How much invasive? I don't like the global "current language"; like the global "selected frame", it's prone to this sort of problem when we'd really rather be looking at a different language. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Breaking in a c++ method with current language set to c. 2007-03-05 12:41 ` Daniel Jacobowitz @ 2007-03-11 21:07 ` Pedro Alves 2007-03-27 18:58 ` Daniel Jacobowitz 0 siblings, 1 reply; 5+ messages in thread From: Pedro Alves @ 2007-03-11 21:07 UTC (permalink / raw) To: gdb-patches [-- Attachment #1: Type: text/plain, Size: 1934 bytes --] Daniel Jacobowitz wrote: > On Mon, Mar 05, 2007 at 03:37:15AM +0000, Pedro Alves wrote: > >> I've looked at several ways to fix it, and all but this one turned out more >> invasive than I hoped for, because current_language is used in a several >> places >> (in symtab.c). Instead, I simply wrapped linespec.c:find_method with a >> set_language (lang of A), guarded with a cleanup. >> > > How much invasive? I don't like the global "current language"; like > the global "selected frame", it's prone to this sort of problem when > we'd really rather be looking at a different language. As my first approach I had added a new parameter to lookup_symbol, and changed all the calls throughout to pass the language that seemed to make sense or current_language otherwise. I ended up touching many files I wouldn't be able to test, like fortran, scheme, java and ada support. It was more invasive than I could afford :) (,and probably wrong). As an intermediate step, I came up with this version. It adds a new lookup_symbol_in_language, and tweaks a few worker functions to accept the language by parameter, instead of relying on the current language. lookup_symbol is then a simple wrapper that passes the current_language to the new lookup_symbol_in_language. I needed to tweak ada-lang.c, because the lookup_symbol_in_language name was already taken there. The approach implemented there was similar to my previous patch, that is, it temporarily switched the current language [1]. As I don't have an ada compiler (and I can't fit any on my machine), I can't be be sure I caught all the hard coded current_language uses, so I've just make the ada function static and added a FIXME. Maybe someone will be able to try with the new version in symtab.c. What do you think of this approach? Tested on i686-pc-cygwin, no regressions. Cheers, Pedro Alves [1] http://sourceware.org/ml/gdb-patches/2004-06/msg00152.html [-- Attachment #2: cpp_break_in_c.diff --] [-- Type: text/plain, Size: 14984 bytes --] gdb/ * linespec.c: Include language.h. (find_methods): Add language parameter. Call lookup_symbol_in_language. Pass language down. (add_matching_methods): Likewise. Call lookup_symbol_in_language. (add_constructors): Likewise. (find_method): Pass sym_class to collect_methods. (collect_methods): Add sym_class parameter. Pass language down. * symtab.c (lookup_symbol): Rename to ... (lookup_symbol_in_language): ... this. Add language parameter. Use passed language instead of current_language. (lookup_symbol): New as wrapper around lookup_symbol_in_language. (lookup_symbol_aux): Add language parameter. Use passed language instead of current_language. (search_symbols): Indent. * symtab.h (enum language): Forward declare. (lookup_symbol_in_language): Declare. (lookup_symbol): Update description. * ada-lang.h (lookup_symbol_in_language): Remove declaration. * ada-lang.c (lookup_symbol_in_language): Rename to ... (ada_lookup_symbol_in_language): ... this, and make static. (standard_lookup): Call ada_lookup_symbol_in_language. --- gdb/ada-lang.c | 19 ++++++++++++++----- gdb/ada-lang.h | 11 ----------- gdb/linespec.c | 36 ++++++++++++++++++++---------------- gdb/symtab.c | 52 ++++++++++++++++++++++++++++++++++++---------------- gdb/symtab.h | 10 +++++++++- 5 files changed, 79 insertions(+), 49 deletions(-) Index: src/gdb/ada-lang.c =================================================================== --- src.orig/gdb/ada-lang.c 2007-03-09 01:12:02.000000000 +0000 +++ src/gdb/ada-lang.c 2007-03-11 20:42:46.000000000 +0000 @@ -271,6 +271,13 @@ static struct value *ada_evaluate_subexp static void ada_forward_operator_length (struct expression *, int, int *, int *); + +static struct symbol *ada_lookup_symbol_in_language (const char *, + const struct block *, + domain_enum, + enum language, + int *, + struct symtab **); \f @@ -3828,7 +3835,8 @@ standard_lookup (const char *name, const if (lookup_cached_symbol (name, domain, &sym, NULL, NULL)) return sym; sym = - lookup_symbol_in_language (name, block, domain, language_c, 0, &symtab); + ada_lookup_symbol_in_language (name, block, domain, language_c, + 0, &symtab); cache_symbol (name, domain, sym, block_found, symtab); return sym; } @@ -4221,11 +4229,12 @@ restore_language (void *lang) set_language ((enum language) lang); } -/* As for lookup_symbol, but performed as if the current language - were LANG. */ +/* Look up a symbol by name using the search conventions of + a specific language (optional block, optional symtab). + FIXME: Should use lookup_symbol_in_language from symtab.c instead. */ -struct symbol * -lookup_symbol_in_language (const char *name, const struct block *block, +static struct symbol * +ada_lookup_symbol_in_language (const char *name, const struct block *block, domain_enum domain, enum language lang, int *is_a_field_of_this, struct symtab **symtab) { Index: src/gdb/linespec.c =================================================================== --- src.orig/gdb/linespec.c 2007-03-09 01:12:02.000000000 +0000 +++ src/gdb/linespec.c 2007-03-09 01:44:12.000000000 +0000 @@ -37,6 +37,7 @@ #include "objc-lang.h" #include "linespec.h" #include "exceptions.h" +#include "language.h" /* We share this one with symtab.c, but it is not exported widely. */ @@ -74,7 +75,7 @@ static struct symtabs_and_lines find_met struct type *t, struct symbol *sym_class); -static int collect_methods (char *copy, struct type *t, +static int collect_methods (char *copy, struct type *t, struct symbol *sym_class, struct symbol **sym_arr); static NORETURN void cplusplus_error (const char *name, @@ -83,13 +84,14 @@ static NORETURN void cplusplus_error (co static int total_number_of_methods (struct type *type); -static int find_methods (struct type *, char *, struct symbol **); +static int find_methods (struct type *, char *, enum language, struct symbol **); static int add_matching_methods (int method_counter, struct type *t, + enum language language, struct symbol **sym_arr); static int add_constructors (int method_counter, struct type *t, - struct symbol **sym_arr); + enum language language, struct symbol **sym_arr); static void build_canonical_line_spec (struct symtab_and_line *, char *, char ***); @@ -196,7 +198,7 @@ total_number_of_methods (struct type *ty Note that this function is g++ specific. */ static int -find_methods (struct type *t, char *name, struct symbol **sym_arr) +find_methods (struct type *t, char *name, enum language language, struct symbol **sym_arr) { int i1 = 0; int ibase; @@ -206,8 +208,8 @@ find_methods (struct type *t, char *name unless we figure out how to get the physname without the name of the class, then the loop can't do any good. */ if (class_name - && (lookup_symbol (class_name, (struct block *) NULL, - STRUCT_DOMAIN, (int *) NULL, + && (lookup_symbol_in_language (class_name, (struct block *) NULL, + STRUCT_DOMAIN, language, (int *) NULL, (struct symtab **) NULL))) { int method_counter; @@ -238,12 +240,12 @@ find_methods (struct type *t, char *name if (strcmp_iw (name, method_name) == 0) /* Find all the overloaded methods with that name. */ - i1 += add_matching_methods (method_counter, t, + i1 += add_matching_methods (method_counter, t, language, sym_arr + i1); else if (strncmp (class_name, name, name_len) == 0 && (class_name[name_len] == '\0' || class_name[name_len] == '<')) - i1 += add_constructors (method_counter, t, + i1 += add_constructors (method_counter, t, language, sym_arr + i1); } } @@ -261,7 +263,7 @@ find_methods (struct type *t, char *name if (i1 == 0) for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) - i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1); + i1 += find_methods (TYPE_BASECLASS (t, ibase), name, language, sym_arr + i1); return i1; } @@ -271,7 +273,7 @@ find_methods (struct type *t, char *name array SYM_ARR. Return the number of methods added. */ static int -add_matching_methods (int method_counter, struct type *t, +add_matching_methods (int method_counter, struct type *t, enum language language, struct symbol **sym_arr) { int field_counter; @@ -305,8 +307,9 @@ add_matching_methods (int method_counter if (is_destructor_name (phys_name) != 0) continue; - sym_arr[i1] = lookup_symbol (phys_name, + sym_arr[i1] = lookup_symbol_in_language (phys_name, NULL, VAR_DOMAIN, + language, (int *) NULL, (struct symtab **) NULL); if (sym_arr[i1]) @@ -332,7 +335,7 @@ add_matching_methods (int method_counter array SYM_ARR. Return the number of methods added. */ static int -add_constructors (int method_counter, struct type *t, +add_constructors (int method_counter, struct type *t, enum language language, struct symbol **sym_arr) { int field_counter; @@ -362,8 +365,9 @@ add_constructors (int method_counter, st /* If this method is actually defined, include it in the list. */ - sym_arr[i1] = lookup_symbol (phys_name, + sym_arr[i1] = lookup_symbol_in_language (phys_name, NULL, VAR_DOMAIN, + language, (int *) NULL, (struct symtab **) NULL); if (sym_arr[i1]) @@ -1410,7 +1414,7 @@ find_method (int funfirstline, char ***c /* Find all methods with a matching name, and put them in sym_arr. */ - i1 = collect_methods (copy, t, sym_arr); + i1 = collect_methods (copy, t, sym_class, sym_arr); if (i1 == 1) { @@ -1465,7 +1469,7 @@ find_method (int funfirstline, char ***c them in SYM_ARR. Return the number of methods found. */ static int -collect_methods (char *copy, struct type *t, +collect_methods (char *copy, struct type *t, struct symbol *sym_class, struct symbol **sym_arr) { int i1 = 0; /* Counter for the symbol array. */ @@ -1488,7 +1492,7 @@ collect_methods (char *copy, struct type } } else - i1 = find_methods (t, copy, sym_arr); + i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr); return i1; } Index: src/gdb/symtab.c =================================================================== --- src.orig/gdb/symtab.c 2007-03-09 01:12:02.000000000 +0000 +++ src/gdb/symtab.c 2007-03-09 01:44:12.000000000 +0000 @@ -84,6 +84,7 @@ static struct symbol *lookup_symbol_aux const char *linkage_name, const struct block *block, const domain_enum domain, + enum language language, int *is_a_field_of_this, struct symtab **symtab); @@ -1079,9 +1080,10 @@ fixup_psymbol_section (struct partial_sy code). */ struct symbol * -lookup_symbol (const char *name, const struct block *block, - const domain_enum domain, int *is_a_field_of_this, - struct symtab **symtab) +lookup_symbol_in_language (const char *name, const struct block *block, + const domain_enum domain, enum language lang, + int *is_a_field_of_this, + struct symtab **symtab) { char *demangled_name = NULL; const char *modified_name = NULL; @@ -1093,7 +1095,7 @@ lookup_symbol (const char *name, const s /* If we are using C++ or Java, demangle the name before doing a lookup, so we can always binary search. */ - if (current_language->la_language == language_cplus) + if (lang == language_cplus) { demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); if (demangled_name) @@ -1103,7 +1105,7 @@ lookup_symbol (const char *name, const s needtofreename = 1; } } - else if (current_language->la_language == language_java) + else if (lang == language_java) { demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); @@ -1129,7 +1131,8 @@ lookup_symbol (const char *name, const s } returnval = lookup_symbol_aux (modified_name, mangled_name, block, - domain, is_a_field_of_this, symtab); + domain, lang, + is_a_field_of_this, symtab); if (needtofreename) xfree (demangled_name); @@ -1140,7 +1143,20 @@ lookup_symbol (const char *name, const s return returnval; } -/* Behave like lookup_symbol_aux except that NAME is the natural name +/* Behave like lookup_symbol_in_language, but performed with the + current language. */ + +struct symbol * +lookup_symbol (const char *name, const struct block *block, + domain_enum domain, int *is_a_field_of_this, + struct symtab **symtab) +{ + return lookup_symbol_in_language (name, block, domain, + current_language->la_language, + is_a_field_of_this, symtab); +} + +/* Behave like lookup_symbol except that NAME is the natural name of the symbol that we're looking for and, if LINKAGE_NAME is non-NULL, ensure that the symbol's linkage name matches as well. */ @@ -1148,9 +1164,11 @@ lookup_symbol (const char *name, const s static struct symbol * lookup_symbol_aux (const char *name, const char *linkage_name, const struct block *block, const domain_enum domain, + enum language language, int *is_a_field_of_this, struct symtab **symtab) { struct symbol *sym; + const struct language_defn *langdef; /* Make sure we do something sensible with is_a_field_of_this, since the callers that set this parameter to some non-null value will @@ -1168,13 +1186,15 @@ lookup_symbol_aux (const char *name, con if (sym != NULL) return sym; - /* If requested to do so by the caller and if appropriate for the - current language, check to see if NAME is a field of `this'. */ + /* If requested to do so by the caller and if appropriate for LANGUAGE, + check to see if NAME is a field of `this'. */ + + langdef = language_def (language); - if (current_language->la_value_of_this != NULL + if (langdef->la_value_of_this != NULL && is_a_field_of_this != NULL) { - struct value *v = current_language->la_value_of_this (0); + struct value *v = langdef->la_value_of_this (0); if (v && check_field (v, name)) { @@ -1185,12 +1205,11 @@ lookup_symbol_aux (const char *name, con } } - /* Now do whatever is appropriate for the current language to look + /* Now do whatever is appropriate for LANGUAGE to look up static and global variables. */ - sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name, - block, domain, - symtab); + sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, + block, domain, symtab); if (sym != NULL) return sym; @@ -3070,7 +3089,8 @@ search_symbols (char *regexp, domain_enu || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), (struct block *) NULL, VAR_DOMAIN, - 0, (struct symtab **) NULL) == NULL) + 0, (struct symtab **) NULL) + == NULL) found_misc = 1; } } Index: src/gdb/symtab.h =================================================================== --- src.orig/gdb/symtab.h 2007-03-09 01:12:02.000000000 +0000 +++ src/gdb/symtab.h 2007-03-09 01:44:12.000000000 +0000 @@ -34,6 +34,7 @@ struct block; struct blockvector; struct axs_value; struct agent_expr; +enum language; /* Some of the structures in this file are space critical. The space-critical structures are: @@ -1007,7 +1008,14 @@ extern int asm_demangle; extern struct symtab *lookup_symtab (const char *); -/* lookup a symbol by name (optional block, optional symtab) */ +/* lookup a symbol by name (optional block, optional symtab) in language */ + +extern struct symbol *lookup_symbol_in_language (const char *, const struct block *, + const domain_enum, enum language, + int *, + struct symtab **); + +/* lookup a symbol by name (optional block, optional symtab) in the current language */ extern struct symbol *lookup_symbol (const char *, const struct block *, const domain_enum, int *, Index: src/gdb/ada-lang.h =================================================================== --- src.orig/gdb/ada-lang.h 2007-03-09 01:12:02.000000000 +0000 +++ src/gdb/ada-lang.h 2007-03-09 01:44:12.000000000 +0000 @@ -474,17 +474,6 @@ extern void ada_reset_thread_registers ( extern int ada_build_task_list (void); -/* Look up a symbol by name using the search conventions of - a specific language (optional block, optional symtab). - FIXME: Should be symtab.h. */ - -extern struct symbol *lookup_symbol_in_language (const char *, - const struct block *, - domain_enum, - enum language, - int *, - struct symtab **); - extern int ada_exception_catchpoint_p (struct breakpoint *b); extern struct symtab_and_line [-- Attachment #3: cpp_break_in_c_tests.diff --] [-- Type: text/plain, Size: 3826 bytes --] gdb/testsuite/ * gdb.cp/method2.cc: New test. * gdb.cp/method2.exp: New test. * gdb.cp/Makefile.in (EXECUTABLES): Add method2. --- gdb/testsuite/gdb.cp/Makefile.in | 2 - gdb/testsuite/gdb.cp/method2.cc | 27 +++++++++++++++ gdb/testsuite/gdb.cp/method2.exp | 70 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) Index: src/gdb/testsuite/gdb.cp/method2.cc =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.cp/method2.cc 2007-03-11 20:39:30.000000000 +0000 @@ -0,0 +1,27 @@ +struct A +{ + void method (); + void method (int a); + void method (A* a); +}; + +void +A::method () +{ +} + +void +A::method (int a) +{ +} + +void +A::method (A* a) +{ +} + +int +main (int argc, char** argv) +{ + return 0; +} Index: src/gdb/testsuite/gdb.cp/method2.exp =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.cp/method2.exp 2007-03-11 20:39:30.000000000 +0000 @@ -0,0 +1,70 @@ +# Copyright 2007 +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file is part of the gdb testsuite + +# This tests setting a break in an ambiguous c++ method with +# current_language set to c. + +if { [skip_cplus_tests] } { continue } + +set testfile "method2" +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested method2.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] then { + perror "couldn't run to breakpoint" + continue +} + +proc test_break { lang } { + global gdb_prompt + + gdb_test "set lang $lang" \ + "" \ + "setting language $lang" + + send_gdb "break A::method\n" + gdb_expect { + -re ".0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. A::method\\(A\\*\\) at .*\[\r\n\]*.3. A::method\\(int\\) at .*\[\r\n\]*\[\r\n\]*.4. A::method\\(\\) at .*\[\r\n\]*> $" { + gdb_test "0" \ + "canceled" \ + "breaking in method ($lang)" + } + -re ".*$gdb_prompt $" { fail "breaking in method ($lang)" } + default { fail "breaking in method ($lang) (timeout)" } + } +} + +test_break "c" +test_break "c++" + +gdb_continue_to_end "continue to end" Index: src/gdb/testsuite/gdb.cp/Makefile.in =================================================================== --- src.orig/gdb/testsuite/gdb.cp/Makefile.in 2007-03-05 03:28:38.000000000 +0000 +++ src/gdb/testsuite/gdb.cp/Makefile.in 2007-03-11 20:39:30.000000000 +0000 @@ -4,7 +4,7 @@ srcdir = @srcdir@ EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \ derivation inherit local member-ptr method misc \ overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace \ - ref-types ref-params + ref-types ref-params method2 all info install-info dvi install uninstall installcheck check: @echo "Nothing to be done for $@..." ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Breaking in a c++ method with current language set to c. 2007-03-11 21:07 ` Pedro Alves @ 2007-03-27 18:58 ` Daniel Jacobowitz 2007-03-29 0:58 ` Pedro Alves 0 siblings, 1 reply; 5+ messages in thread From: Daniel Jacobowitz @ 2007-03-27 18:58 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On Sun, Mar 11, 2007 at 09:06:34PM +0000, Pedro Alves wrote: > >How much invasive? I don't like the global "current language"; like > >the global "selected frame", it's prone to this sort of problem when > >we'd really rather be looking at a different language. > As my first approach I had added a new parameter to lookup_symbol, and > changed all the calls throughout to pass the language that seemed to > make sense or current_language otherwise. I ended up touching many > files I wouldn't be able to test, like fortran, scheme, java and ada > support. It was more invasive than I could afford :) (,and probably wrong). > As an intermediate step, I came up with this version. It adds a new > lookup_symbol_in_language, and tweaks a few worker functions to accept > the language by parameter, instead of relying on the current language. > lookup_symbol is then a simple wrapper that passes the current_language > to the new lookup_symbol_in_language. I needed to tweak ada-lang.c, > because the lookup_symbol_in_language name was already taken there. The > approach implemented there was similar to my previous patch, that is, it > temporarily switched the current language [1]. As I don't have an ada > compiler (and I can't fit any on my machine), I can't be be sure I caught > all the hard coded current_language uses, so I've just make the ada > function static and added a FIXME. Maybe someone will be able to try > with the new version in symtab.c. > What do you think of this approach? I like this much better. I tested using your version for Ada, and it seemed to work - but we don't have test coverage for the problem case, apparently, since commenting out the set_language call in ada_lookup_symbol_in_language did not cause any test failures. I think you should go ahead and remove the Ada-specific version. If there's a problem we can fix it. Could you do that, and also check for overly long lines in your patch? Thanks in advance. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Breaking in a c++ method with current language set to c. 2007-03-27 18:58 ` Daniel Jacobowitz @ 2007-03-29 0:58 ` Pedro Alves 0 siblings, 0 replies; 5+ messages in thread From: Pedro Alves @ 2007-03-29 0:58 UTC (permalink / raw) To: gdb-patches [-- Attachment #1: Type: text/plain, Size: 621 bytes --] Daniel Jacobowitz wrote: > I like this much better. I tested using your version for Ada, and it > seemed to work - but we don't have test coverage for the problem case, > apparently, since commenting out the set_language call in > ada_lookup_symbol_in_language did not cause any test failures. I > think you should go ahead and remove the Ada-specific version. If > there's a problem we can fix it. > > Could you do that, and also check for overly long lines in your patch? > Thanks in advance. > OK, thanks for testing! I've committed the attached, plus the same testcase I originally sent. Cheers, Pedro Alves [-- Attachment #2: cpp_break_in_c.diff --] [-- Type: text/plain, Size: 14486 bytes --] gdb/ * linespec.c: Include language.h. (find_methods): Add language parameter. Call lookup_symbol_in_language. Pass language down. (add_matching_methods): Likewise. Call lookup_symbol_in_language. (add_constructors): Likewise. (find_method): Pass sym_class to collect_methods. (collect_methods): Add sym_class parameter. Pass language down. * symtab.c (lookup_symbol): Rename to ... (lookup_symbol_in_language): ... this. Add language parameter. Use passed language instead of current_language. (lookup_symbol): New as wrapper around lookup_symbol_in_language. (lookup_symbol_aux): Add language parameter. Use passed language instead of current_language. (search_symbols): Indent. * symtab.h (enum language): Forward declare. (lookup_symbol_in_language): Declare. (lookup_symbol): Update description. * ada-lang.h (lookup_symbol_in_language): Remove declaration. * ada-lang.c (restore_language): Remove. (lookup_symbol_in_language): Remove. --- gdb/ada-lang.c | 25 ------------------------- gdb/ada-lang.h | 11 ----------- gdb/linespec.c | 41 +++++++++++++++++++++++++---------------- gdb/symtab.c | 52 ++++++++++++++++++++++++++++++++++++---------------- gdb/symtab.h | 13 ++++++++++++- 5 files changed, 73 insertions(+), 69 deletions(-) Index: src/gdb/ada-lang.c =================================================================== --- src.orig/gdb/ada-lang.c 2007-03-14 19:38:42.000000000 +0000 +++ src/gdb/ada-lang.c 2007-03-28 00:15:28.000000000 +0100 @@ -4213,31 +4213,6 @@ add_symbols_from_enclosing_procs (struct { } -/* FIXME: The next two routines belong in symtab.c */ - -static void -restore_language (void *lang) -{ - set_language ((enum language) lang); -} - -/* As for lookup_symbol, but performed as if the current language - were LANG. */ - -struct symbol * -lookup_symbol_in_language (const char *name, const struct block *block, - domain_enum domain, enum language lang, - int *is_a_field_of_this, struct symtab **symtab) -{ - struct cleanup *old_chain - = make_cleanup (restore_language, (void *) current_language->la_language); - struct symbol *result; - set_language (lang); - result = lookup_symbol (name, block, domain, is_a_field_of_this, symtab); - do_cleanups (old_chain); - return result; -} - /* True if TYPE is definitely an artificial type supplied to a symbol for which no debugging information was given in the symbol file. */ Index: src/gdb/linespec.c =================================================================== --- src.orig/gdb/linespec.c 2007-03-14 19:38:42.000000000 +0000 +++ src/gdb/linespec.c 2007-03-28 00:23:30.000000000 +0100 @@ -37,6 +37,7 @@ #include "objc-lang.h" #include "linespec.h" #include "exceptions.h" +#include "language.h" /* We share this one with symtab.c, but it is not exported widely. */ @@ -75,6 +76,7 @@ static struct symtabs_and_lines find_met struct symbol *sym_class); static int collect_methods (char *copy, struct type *t, + struct symbol *sym_class, struct symbol **sym_arr); static NORETURN void cplusplus_error (const char *name, @@ -83,12 +85,15 @@ static NORETURN void cplusplus_error (co static int total_number_of_methods (struct type *type); -static int find_methods (struct type *, char *, struct symbol **); +static int find_methods (struct type *, char *, + enum language, struct symbol **); static int add_matching_methods (int method_counter, struct type *t, + enum language language, struct symbol **sym_arr); static int add_constructors (int method_counter, struct type *t, + enum language language, struct symbol **sym_arr); static void build_canonical_line_spec (struct symtab_and_line *, @@ -196,7 +201,8 @@ total_number_of_methods (struct type *ty Note that this function is g++ specific. */ static int -find_methods (struct type *t, char *name, struct symbol **sym_arr) +find_methods (struct type *t, char *name, enum language language, + struct symbol **sym_arr) { int i1 = 0; int ibase; @@ -206,8 +212,8 @@ find_methods (struct type *t, char *name unless we figure out how to get the physname without the name of the class, then the loop can't do any good. */ if (class_name - && (lookup_symbol (class_name, (struct block *) NULL, - STRUCT_DOMAIN, (int *) NULL, + && (lookup_symbol_in_language (class_name, (struct block *) NULL, + STRUCT_DOMAIN, language, (int *) NULL, (struct symtab **) NULL))) { int method_counter; @@ -238,12 +244,12 @@ find_methods (struct type *t, char *name if (strcmp_iw (name, method_name) == 0) /* Find all the overloaded methods with that name. */ - i1 += add_matching_methods (method_counter, t, + i1 += add_matching_methods (method_counter, t, language, sym_arr + i1); else if (strncmp (class_name, name, name_len) == 0 && (class_name[name_len] == '\0' || class_name[name_len] == '<')) - i1 += add_constructors (method_counter, t, + i1 += add_constructors (method_counter, t, language, sym_arr + i1); } } @@ -261,7 +267,8 @@ find_methods (struct type *t, char *name if (i1 == 0) for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) - i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1); + i1 += find_methods (TYPE_BASECLASS (t, ibase), name, + language, sym_arr + i1); return i1; } @@ -272,7 +279,7 @@ find_methods (struct type *t, char *name static int add_matching_methods (int method_counter, struct type *t, - struct symbol **sym_arr) + enum language language, struct symbol **sym_arr) { int field_counter; int i1 = 0; @@ -299,14 +306,15 @@ add_matching_methods (int method_counter } else phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - + /* Destructor is handled by caller, don't add it to the list. */ if (is_destructor_name (phys_name) != 0) continue; - sym_arr[i1] = lookup_symbol (phys_name, + sym_arr[i1] = lookup_symbol_in_language (phys_name, NULL, VAR_DOMAIN, + language, (int *) NULL, (struct symtab **) NULL); if (sym_arr[i1]) @@ -333,7 +341,7 @@ add_matching_methods (int method_counter static int add_constructors (int method_counter, struct type *t, - struct symbol **sym_arr) + enum language language, struct symbol **sym_arr) { int field_counter; int i1 = 0; @@ -349,7 +357,7 @@ add_constructors (int method_counter, st { struct fn_field *f; char *phys_name; - + f = TYPE_FN_FIELDLIST1 (t, method_counter); /* GCC 3.x will never produce stabs stub methods, so @@ -362,8 +370,9 @@ add_constructors (int method_counter, st /* If this method is actually defined, include it in the list. */ - sym_arr[i1] = lookup_symbol (phys_name, + sym_arr[i1] = lookup_symbol_in_language (phys_name, NULL, VAR_DOMAIN, + language, (int *) NULL, (struct symtab **) NULL); if (sym_arr[i1]) @@ -1410,7 +1419,7 @@ find_method (int funfirstline, char ***c /* Find all methods with a matching name, and put them in sym_arr. */ - i1 = collect_methods (copy, t, sym_arr); + i1 = collect_methods (copy, t, sym_class, sym_arr); if (i1 == 1) { @@ -1466,7 +1475,7 @@ find_method (int funfirstline, char ***c static int collect_methods (char *copy, struct type *t, - struct symbol **sym_arr) + struct symbol *sym_class, struct symbol **sym_arr) { int i1 = 0; /* Counter for the symbol array. */ @@ -1488,7 +1497,7 @@ collect_methods (char *copy, struct type } } else - i1 = find_methods (t, copy, sym_arr); + i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr); return i1; } Index: src/gdb/symtab.c =================================================================== --- src.orig/gdb/symtab.c 2007-03-27 21:09:16.000000000 +0100 +++ src/gdb/symtab.c 2007-03-28 00:56:02.000000000 +0100 @@ -84,6 +84,7 @@ static struct symbol *lookup_symbol_aux const char *linkage_name, const struct block *block, const domain_enum domain, + enum language language, int *is_a_field_of_this, struct symtab **symtab); @@ -1079,9 +1080,10 @@ fixup_psymbol_section (struct partial_sy code). */ struct symbol * -lookup_symbol (const char *name, const struct block *block, - const domain_enum domain, int *is_a_field_of_this, - struct symtab **symtab) +lookup_symbol_in_language (const char *name, const struct block *block, + const domain_enum domain, enum language lang, + int *is_a_field_of_this, + struct symtab **symtab) { char *demangled_name = NULL; const char *modified_name = NULL; @@ -1093,7 +1095,7 @@ lookup_symbol (const char *name, const s /* If we are using C++ or Java, demangle the name before doing a lookup, so we can always binary search. */ - if (current_language->la_language == language_cplus) + if (lang == language_cplus) { demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); if (demangled_name) @@ -1103,7 +1105,7 @@ lookup_symbol (const char *name, const s needtofreename = 1; } } - else if (current_language->la_language == language_java) + else if (lang == language_java) { demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); @@ -1129,7 +1131,8 @@ lookup_symbol (const char *name, const s } returnval = lookup_symbol_aux (modified_name, mangled_name, block, - domain, is_a_field_of_this, symtab); + domain, lang, + is_a_field_of_this, symtab); if (needtofreename) xfree (demangled_name); @@ -1140,7 +1143,20 @@ lookup_symbol (const char *name, const s return returnval; } -/* Behave like lookup_symbol_aux except that NAME is the natural name +/* Behave like lookup_symbol_in_language, but performed with the + current language. */ + +struct symbol * +lookup_symbol (const char *name, const struct block *block, + domain_enum domain, int *is_a_field_of_this, + struct symtab **symtab) +{ + return lookup_symbol_in_language (name, block, domain, + current_language->la_language, + is_a_field_of_this, symtab); +} + +/* Behave like lookup_symbol except that NAME is the natural name of the symbol that we're looking for and, if LINKAGE_NAME is non-NULL, ensure that the symbol's linkage name matches as well. */ @@ -1148,9 +1164,11 @@ lookup_symbol (const char *name, const s static struct symbol * lookup_symbol_aux (const char *name, const char *linkage_name, const struct block *block, const domain_enum domain, + enum language language, int *is_a_field_of_this, struct symtab **symtab) { struct symbol *sym; + const struct language_defn *langdef; /* Make sure we do something sensible with is_a_field_of_this, since the callers that set this parameter to some non-null value will @@ -1168,13 +1186,15 @@ lookup_symbol_aux (const char *name, con if (sym != NULL) return sym; - /* If requested to do so by the caller and if appropriate for the - current language, check to see if NAME is a field of `this'. */ + /* If requested to do so by the caller and if appropriate for LANGUAGE, + check to see if NAME is a field of `this'. */ + + langdef = language_def (language); - if (current_language->la_value_of_this != NULL + if (langdef->la_value_of_this != NULL && is_a_field_of_this != NULL) { - struct value *v = current_language->la_value_of_this (0); + struct value *v = langdef->la_value_of_this (0); if (v && check_field (v, name)) { @@ -1185,12 +1205,11 @@ lookup_symbol_aux (const char *name, con } } - /* Now do whatever is appropriate for the current language to look + /* Now do whatever is appropriate for LANGUAGE to look up static and global variables. */ - sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name, - block, domain, - symtab); + sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, + block, domain, symtab); if (sym != NULL) return sym; @@ -3070,7 +3089,8 @@ search_symbols (char *regexp, domain_enu || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), (struct block *) NULL, VAR_DOMAIN, - 0, (struct symtab **) NULL) == NULL) + 0, (struct symtab **) NULL) + == NULL) found_misc = 1; } } Index: src/gdb/symtab.h =================================================================== --- src.orig/gdb/symtab.h 2007-03-14 19:38:42.000000000 +0000 +++ src/gdb/symtab.h 2007-03-28 00:26:44.000000000 +0100 @@ -34,6 +34,7 @@ struct block; struct blockvector; struct axs_value; struct agent_expr; +enum language; /* Some of the structures in this file are space critical. The space-critical structures are: @@ -1007,7 +1008,17 @@ extern int asm_demangle; extern struct symtab *lookup_symtab (const char *); -/* lookup a symbol by name (optional block, optional symtab) */ +/* lookup a symbol by name (optional block, optional symtab) in language */ + +extern struct symbol *lookup_symbol_in_language (const char *, + const struct block *, + const domain_enum, + enum language, + int *, + struct symtab **); + +/* lookup a symbol by name (optional block, optional symtab) + in the current language */ extern struct symbol *lookup_symbol (const char *, const struct block *, const domain_enum, int *, Index: src/gdb/ada-lang.h =================================================================== --- src.orig/gdb/ada-lang.h 2007-03-14 19:38:44.000000000 +0000 +++ src/gdb/ada-lang.h 2007-03-28 00:08:16.000000000 +0100 @@ -474,17 +474,6 @@ extern void ada_reset_thread_registers ( extern int ada_build_task_list (void); -/* Look up a symbol by name using the search conventions of - a specific language (optional block, optional symtab). - FIXME: Should be symtab.h. */ - -extern struct symbol *lookup_symbol_in_language (const char *, - const struct block *, - domain_enum, - enum language, - int *, - struct symtab **); - extern int ada_exception_catchpoint_p (struct breakpoint *b); extern struct symtab_and_line ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-03-29 0:58 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-03-05 3:37 Breaking in a c++ method with current language set to c Pedro Alves 2007-03-05 12:41 ` Daniel Jacobowitz 2007-03-11 21:07 ` Pedro Alves 2007-03-27 18:58 ` Daniel Jacobowitz 2007-03-29 0:58 ` Pedro Alves
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox