diff options
-rw-r--r-- | gdb/rust-exp.h | 27 | ||||
-rw-r--r-- | gdb/rust-parse.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.rust/fnfield.exp | 38 | ||||
-rw-r--r-- | gdb/testsuite/gdb.rust/fnfield.rs | 39 |
4 files changed, 105 insertions, 1 deletions
diff --git a/gdb/rust-exp.h b/gdb/rust-exp.h index 6a24f2c..778d87f 100644 --- a/gdb/rust-exp.h +++ b/gdb/rust-exp.h @@ -197,6 +197,33 @@ public: { return OP_AGGREGATE; } }; +/* Rust parenthesized operation. This is needed to distinguish + between 'obj.f()', which is a method call, and '(obj.f)()', which + is a call of a function-valued field 'f'. */ +class rust_parenthesized_operation + : public tuple_holding_operation<operation_up> +{ +public: + + explicit rust_parenthesized_operation (operation_up op) + : tuple_holding_operation (std::move (op)) + { + } + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override + { + return std::get<0> (m_storage)->evaluate (expect_type, exp, noside); + } + + enum exp_opcode opcode () const override + { + /* A lie but this isn't worth introducing a new opcode for. */ + return UNOP_PLUS; + } +}; + } /* namespace expr */ #endif /* RUST_EXP_H */ diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c index 31a1ee3..894f2e7 100644 --- a/gdb/rust-parse.c +++ b/gdb/rust-parse.c @@ -1105,7 +1105,7 @@ rust_parser::parse_tuple () { /* Parenthesized expression. */ lex (); - return expr; + return make_operation<rust_parenthesized_operation> (std::move (expr)); } std::vector<operation_up> ops; diff --git a/gdb/testsuite/gdb.rust/fnfield.exp b/gdb/testsuite/gdb.rust/fnfield.exp new file mode 100644 index 0000000..4575571 --- /dev/null +++ b/gdb/testsuite/gdb.rust/fnfield.exp @@ -0,0 +1,38 @@ +# Copyright (C) 2022 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 trait object printing. + +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 +} + +gdb_test "print foo.f()" " = 6" "call impl function" +gdb_test "print (foo.f)()" " = 5" "call function field" +gdb_test "print foo.g()" " = 7" "call impl function g" +gdb_test "print (foo.g)()" "There is no member named g." \ + "cannot call g with parens" diff --git a/gdb/testsuite/gdb.rust/fnfield.rs b/gdb/testsuite/gdb.rust/fnfield.rs new file mode 100644 index 0000000..b80136c --- /dev/null +++ b/gdb/testsuite/gdb.rust/fnfield.rs @@ -0,0 +1,39 @@ +// Copyright (C) 2022 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(warnings)] + +fn five() -> i32 { 5 } + +fn main() { + let foo = Foo {x: 5, f: five}; + foo.print(); // set breakpoint here + println!("Hello, world! {}, {}, {}", foo.f(), (foo.f)(), + foo.g ()); +} + +struct Foo { + x :i32, + f: fn () -> i32, +} + +impl Foo { + fn print(&self) { + println!("hello {}", self.x) + } + + fn f(&self) -> i32 { 6 } + fn g(&self) -> i32 { 7 } +} |