+2017-05-19 Tom Tromey <tom@tromey.com>
+
+ PR rust/21484:
+ * rust-lang.c (exp_descriptor_rust): New function.
+ (rust_language_defn): Use it.
+ * p-lang.c (pascal_language_defn): Update.
+ * opencl-lang.c (opencl_language_defn): Update.
+ * objc-lang.c (objc_language_defn): Update.
+ * m2-lang.c (m2_language_defn): Update.
+ * language.h (struct language_defn)
+ <la_watch_location_expression>: New member.
+ * language.c (unknown_language_defn, auto_language_defn)
+ (local_language_defn): Update.
+ * go-lang.c (go_language_defn): Update.
+ * f-lang.c (f_language_defn): Update.
+ * d-lang.c (d_language_defn): Update.
+ * c-lang.h (c_watch_location_expression): Declare.
+ * c-lang.c (c_watch_location_expression): New function.
+ (c_language_defn, cplus_language_defn, asm_language_defn)
+ (minimal_language_defn): Use it.
+ * breakpoint.c (watch_command_1): Call
+ la_watch_location_expression.
+ * ada-lang.c (ada_language_defn): Update.
+
2017-05-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR tui/21482
ada_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
ada_get_symbol_name_cmp, /* la_get_symbol_name_cmp */
ada_iterate_over_symbols,
&ada_varobj_ops,
struct type *t = value_type (val);
CORE_ADDR addr = value_as_address (val);
- t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
-
- std::string name = type_to_string (t);
-
- w->exp_string_reparse = xstrprintf ("* (%s *) %s", name.c_str (),
- core_addr_to_string (addr));
+ w->exp_string_reparse
+ = current_language->la_watch_location_expression (t, addr).release ();
w->exp_string = xstrprintf ("-location %.*s",
(int) (exp_end - exp_start), exp_start);
-
- /* The above expression is in C. */
- b->language = language_c;
}
else
w->exp_string = savestring (exp_start, exp_end - exp_start);
}
return evaluate_subexp_standard (expect_type, exp, pos, noside);
}
+\f
+/* la_watch_location_expression for C. */
+gdb::unique_xmalloc_ptr<char>
+c_watch_location_expression (struct type *type, CORE_ADDR addr)
+{
+ type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
+ std::string name = type_to_string (type);
+ return gdb::unique_xmalloc_ptr<char>
+ (xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr)));
+}
\f
/* Table mapping opcodes into strings for printing operators
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&c_varobj_ops,
default_print_array_index,
cp_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&cplus_varobj_ops,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
extern const struct op_print c_op_print_tab[];
+extern gdb::unique_xmalloc_ptr<char> c_watch_location_expression
+ (struct type *type, CORE_ADDR addr);
+
/* These are in c-typeprint.c: */
extern void c_type_print_base (struct type *, struct ui_file *,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL,
iterate_over_symbols,
&default_varobj_ops,
#include "symfile.h"
#include "cp-support.h"
#include "frame.h"
+#include "c-lang.h"
extern void _initialize_language (void);
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
struct type **chartype, const char **charset);
+ /* Return an expression that can be used for a location
+ watchpoint. TYPE is a pointer type that points to the memory
+ to watch, and ADDR is the address of the watched memory. */
+ gdb::unique_xmalloc_ptr<char> (*la_watch_location_expression)
+ (struct type *type, CORE_ADDR addr);
+
/* Return a pointer to the function that should be used to match
a symbol name against LOOKUP_NAME. This is mostly for languages
such as Ada where the matching algorithm depends on LOOKUP_NAME.
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
#include "valprint.h"
#include "value.h"
#include <ctype.h>
+#include "c-lang.h"
extern void _initialize_pascal_language (void);
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ c_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
\f
+/* la_watch_location_expression for Rust. */
+
+static gdb::unique_xmalloc_ptr<char>
+rust_watch_location_expression (struct type *type, CORE_ADDR addr)
+{
+ type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
+ std::string name = type_to_string (type);
+ return gdb::unique_xmalloc_ptr<char>
+ (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr),
+ name.c_str ()));
+}
+
+\f
+
static const struct exp_descriptor exp_descriptor_rust =
{
rust_print_subexp,
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ rust_watch_location_expression,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
&default_varobj_ops,
+2017-05-19 Tom Tromey <tom@tromey.com>
+
+ PR rust/21484:
+ * gdb.rust/watch.exp: New file.
+ * gdb.rust/watch.rs: New file.
+
2017-05-18 Tom Tromey <tom@tromey.com>
* gdb.rust/simple.exp: Allow Box to be qualified.
--- /dev/null
+# Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
+
+# Test watch -location with Rust.
+
+load_lib rust-support.exp
+if {[skip_rust_tests]} {
+ continue
+}
+
+standard_testfile .rs
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug rust}]} {
+ return -1
+}
+
+set line [gdb_get_line_number "set breakpoint here"]
+if {![runto ${srcfile}:$line]} {
+ untested "could not run to breakpoint"
+ return -1
+}
+
+# Just setting a watchpoint was enough to trigger the bug.
+gdb_test "watch -location y" ".*watchpoint .* -location .*"
--- /dev/null
+// Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+
+fn main() {
+ let mut y = 7;
+ y = y + 1; // set breakpoint here
+ y = y + 1;
+}