From 5b12a61c763421f05d233ebcce94d96536b5c5d4 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 13 Jan 2013 18:57:01 +0000 Subject: [PATCH] gdb/ * parse.c (parse_exp_in_context): New variable inner_chain. Call make_cleanup_restore_current_language. Call set_language. Move OLD_CHAIN and INNER_CHAIN cleanups. * utils.c (do_restore_current_language) (make_cleanup_restore_current_language): New functions. * utils.h (make_cleanup_restore_current_language): New declaration. gdb/testsuite/ * gdb.cp/parse-lang.cc: New file. * gdb.cp/parse-lang.exp: New file. --- gdb/ChangeLog | 9 +++++++ gdb/parse.c | 13 +++++++--- gdb/testsuite/ChangeLog | 5 ++++ gdb/testsuite/gdb.cp/parse-lang.cc | 40 +++++++++++++++++++++++++++++ gdb/testsuite/gdb.cp/parse-lang.exp | 31 ++++++++++++++++++++++ gdb/utils.c | 22 ++++++++++++++++ gdb/utils.h | 2 ++ 7 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 gdb/testsuite/gdb.cp/parse-lang.cc create mode 100644 gdb/testsuite/gdb.cp/parse-lang.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e4c51325716..d9a2e456f5b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2013-01-13 Jan Kratochvil + + * parse.c (parse_exp_in_context): New variable inner_chain. Call + make_cleanup_restore_current_language. Call set_language. Move + OLD_CHAIN and INNER_CHAIN cleanups. + * utils.c (do_restore_current_language) + (make_cleanup_restore_current_language): New functions. + * utils.h (make_cleanup_restore_current_language): New declaration. + 2013-01-13 Jan Kratochvil * source.c (symtab_to_fullname): Apply rewrite_source_path also for diff --git a/gdb/parse.c b/gdb/parse.c index 2d530dfa7e8..09c378b98bb 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1143,7 +1143,7 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, const struct block *block, int comma, int void_context_p, int *out_subexp) { volatile struct gdb_exception except; - struct cleanup *old_chain; + struct cleanup *old_chain, *inner_chain; const struct language_defn *lang = NULL; int subexp; @@ -1213,7 +1213,13 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, const struct block *block, else lang = current_language; + /* get_current_arch may reset CURRENT_LANGUAGE via select_frame. + While we need CURRENT_LANGUAGE to be set to LANG (for lookup_symbol + and others called from *.y) ensure CURRENT_LANGUAGE gets restored + to the value matching SELECTED_FRAME as set by get_current_arch. */ initialize_expout (10, lang, get_current_arch ()); + inner_chain = make_cleanup_restore_current_language (); + set_language (lang->la_language); TRY_CATCH (except, RETURN_MASK_ALL) { @@ -1229,8 +1235,6 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, const struct block *block, } } - discard_cleanups (old_chain); - reallocate_expout (); /* Convert expression from postfix form as generated by yacc @@ -1249,6 +1253,9 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, const struct block *block, if (expressiondebug) dump_prefix_expression (expout, gdb_stdlog); + do_cleanups (inner_chain); + discard_cleanups (old_chain); + *stringptr = lexptr; return expout; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3e366d98e6c..717ea18297e 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-01-13 Jan Kratochvil + + * gdb.cp/parse-lang.cc: New file. + * gdb.cp/parse-lang.exp: New file. + 2013-01-13 Jan Kratochvil * gdb.mi/mi-fullname-deleted.exp: Set srcfileabssubst and initdir. diff --git a/gdb/testsuite/gdb.cp/parse-lang.cc b/gdb/testsuite/gdb.cp/parse-lang.cc new file mode 100644 index 00000000000..46af670b2a8 --- /dev/null +++ b/gdb/testsuite/gdb.cp/parse-lang.cc @@ -0,0 +1,40 @@ +/* Copyright 2013 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 . */ + +class C +{ +public: + int v; + void m (); +}; + +void +C::m () +{ +} + +void +marker () +{ +} + +int +main () +{ + C c = { 42 }; + + c.m (); + marker (); +} diff --git a/gdb/testsuite/gdb.cp/parse-lang.exp b/gdb/testsuite/gdb.cp/parse-lang.exp new file mode 100644 index 00000000000..c0051e9fc1c --- /dev/null +++ b/gdb/testsuite/gdb.cp/parse-lang.exp @@ -0,0 +1,31 @@ +# Copyright 2012-2013 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 . + +standard_testfile .cc + +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} { + return -1 +} + +# Place the breakpoint before inferior gets started. Then the breakpoint +# condition will be re-evaluated in non-C++ startup code. +gdb_breakpoint "C::m if v == 42" + +gdb_breakpoint "marker" + +# runto_main would delete the breakpoint. +gdb_run_cmd + +gdb_test "" {Breakpoint [0-9]+, C::m .*} "breakpoint hit" diff --git a/gdb/utils.c b/gdb/utils.c index e12888fa856..8bae4ebaa09 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -503,6 +503,28 @@ make_cleanup_free_so (struct so_list *so) return make_cleanup (do_free_so, so); } +/* Helper for make_cleanup_restore_current_language. */ + +static void +do_restore_current_language (void *p) +{ + enum language saved_lang = (uintptr_t) p; + + set_language (saved_lang); +} + +/* Remember the current value of CURRENT_LANGUAGE and make it restored when + the cleanup is run. */ + +struct cleanup * +make_cleanup_restore_current_language (void) +{ + enum language saved_lang = current_language->la_language; + + return make_cleanup (do_restore_current_language, + (void *) (uintptr_t) saved_lang); +} + /* This function is useful for cleanups. Do diff --git a/gdb/utils.h b/gdb/utils.h index 14235a9b356..6983a53c6f9 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -104,6 +104,8 @@ extern struct cleanup *make_cleanup_value_free (struct value *); struct so_list; extern struct cleanup *make_cleanup_free_so (struct so_list *so); +extern struct cleanup *make_cleanup_restore_current_language (void); + extern struct cleanup *make_cleanup_htab_delete (htab_t htab); extern void free_current_contents (void *);