This updates the gdb test suite for Rust.
2016-05-17 Tom Tromey <tom@tromey.com>
Manish Goregaokar <manishsmail@gmail.com>
* lib/rust-support.exp: New file.
* lib/gdb.exp (skip_rust_tests): New proc.
(build_executable_from_specs): Handle rust.
* lib/future.exp (gdb_find_rustc): New proc.
(gdb_default_target_compile): Handle rust.
* gdb.rust/expr.exp: New file.
* gdb.rust/generics.exp: New file.
* gdb.rust/generics.rs: New file.
* gdb.rust/methods.exp: New file.
* gdb.rust/methods.rs: New file.
* gdb.rust/modules.exp: New file.
* gdb.rust/modules.rs: New file.
* gdb.rust/simple.exp: New file.
* gdb.rust/simple.rs: New file.
+2016-05-17 Tom Tromey <tom@tromey.com>
+ Manish Goregaokar <manishsmail@gmail.com>
+
+ * lib/rust-support.exp: New file.
+ * lib/gdb.exp (skip_rust_tests): New proc.
+ (build_executable_from_specs): Handle rust.
+ * lib/future.exp (gdb_find_rustc): New proc.
+ (gdb_default_target_compile): Handle rust.
+ * gdb.rust/expr.exp: New file.
+ * gdb.rust/generics.exp: New file.
+ * gdb.rust/generics.rs: New file.
+ * gdb.rust/methods.exp: New file.
+ * gdb.rust/methods.rs: New file.
+ * gdb.rust/modules.exp: New file.
+ * gdb.rust/modules.rs: New file.
+ * gdb.rust/simple.exp: New file.
+ * gdb.rust/simple.rs: New file.
+
2016-05-17 Tom Tromey <tom@tromey.com>
* gdb.base/default.exp (set language): Add rust.
--- /dev/null
+# Copyright (C) 2016 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 basic expression parsing and evaluation, without requiring a
+# Rust compiler. This serves as a smoke test.
+
+load_lib "rust-support.exp"
+if {[skip_rust_tests]} { continue }
+
+gdb_start
+
+gdb_test_no_output "set var \$something = 27"
+
+if {![set_lang_rust]} {
+ warning "Rust expression tests suppressed."
+ continue
+}
+
+gdb_test "print 9__97" " = 997"
+gdb_test "print -5" " = -5"
+gdb_test "print +5" " = 5"
+gdb_test "print +-+-5" " = 5"
+gdb_test "print 3_2i32" " = 32"
+gdb_test "print 32i64" " = 32"
+gdb_test "print 8u8" " = 8"
+gdb_test "print 0x1f" " = 31"
+gdb_test "print 0o07" " = 7"
+gdb_test "print 0o70" " = 56"
+gdb_test "print 0b1_111" " = 15"
+gdb_test "print 32usize" " = 32"
+gdb_test "print 0x_4" " = 4"
+
+gdb_test "print 'z'" " = 122 'z'"
+gdb_test "print '\\t'" " = 9 '\\\\t'"
+gdb_test "print '\\n'" " = 10 '\\\\n'"
+gdb_test "print '\\r'" " = 13 '\\\\r'"
+gdb_test "print '\\\\'" " = 92 '\\\\\\\\'"
+gdb_test "print '\\0'" " = 0 '\\\\0'"
+gdb_test "print '\\''" " = 39 '\\\\''"
+gdb_test "print '\\\"'" " = 34 '\"'"
+gdb_test "print '\\xff'" " = 255 '\\\\xff'"
+gdb_test "print '\\xFF'" " = 255 '\\\\xff'"
+gdb_test "print '\\u\{F0eF\}'" " = 61679 '\\\\u\\{00f0ef\\}'"
+
+gdb_test "print b'z'" " = 122"
+gdb_test "print b'\\xfe'" " = 254"
+gdb_test "print b'\\t'" " = 9"
+gdb_test "print b'\\n'" " = 10"
+gdb_test "print b'\\r'" " = 13"
+gdb_test "print b'\\\\'" " = 92"
+gdb_test "print b'\\0'" " = 0"
+gdb_test "print b'\\''" " = 39"
+gdb_test "print b'\\\"'" " = 34"
+gdb_test "print b'\\xff'" " = 255"
+
+gdb_test "print 23.5" " = 23.5"
+gdb_test "print 23.5e1" " = 235"
+gdb_test "print 2e4" " = 20000"
+gdb_test "print 2_E+4_f64" " = 20000"
+gdb_test "print 5e-1" " = 0.5"
+gdb_test "print 5e-1f32" " = 0.5"
+
+gdb_test "print false" " = false"
+gdb_test "print true" " = true"
+
+gdb_test "print 1+2" " = 3"
+gdb_test "print 1i32 + 2i32" " = 3"
+gdb_test "print 2.0 - 1.0" " = 1"
+gdb_test "print !false" " = true"
+gdb_test "print !true" " = false"
+gdb_test "print !0u8" " = 255"
+gdb_test "print 7 * 7" " = 49"
+gdb_test "print 7usize * 7usize" " = 49"
+gdb_test "print 42 / 7" " = 6"
+gdb_test "print 42 % 7" " = 0"
+gdb_test "print 1.0 / 2.0" " = 0.5"
+gdb_test "print 1 < 2" " = true"
+gdb_test "print !(1 < 2)" " = false"
+gdb_test "print 3 + 4 * 7" " = 31"
+gdb_test "print 1 > 2" " = false"
+gdb_test "print 1 | 2" " = 3"
+gdb_test "print 1 & 2" " = 0"
+gdb_test "print 3 & 2" " = 2"
+gdb_test "print 3 ^ 2" " = 1"
+gdb_test "print (1 < 0) || true" " = true"
+gdb_test "print (1 > 0) && false" " = false"
+gdb_test "print 'z' == 'z'" " = true"
+gdb_test "print '\\u{1016f}' != 'q'" " = true"
+gdb_test "print 32 <= 32" " = true"
+gdb_test "print 32 >= 32" " = true"
+gdb_test "print 1 << 5" " = 32"
+gdb_test "print 32usize >> 5" " = 1"
+gdb_test "ptype 32i32 as f64" "type = f64"
+
+gdb_test "print ()" " = \\(\\)"
+
+gdb_test "print \[1,2,3,4\]" " = \\\[1, 2, 3, 4\\\]"
+gdb_test "ptype \[1,2,3,4\]" "type = \\\[i32; 4\\\]"
+gdb_test "print \[mut 1,2,3,4\]" " = \\\[1, 2, 3, 4\\\]"
+
+gdb_test "print b\"hi rust\"" " = b\"hi rust\""
+# This isn't rusty syntax yet, but that's another bug -- this is just
+# testing that byte escapes work properly.
+gdb_test "print b\"\\xddhi bob\"" " = b\"\\\\335hi bob\""
+gdb_test "print b\"has\\0nul\"" " = b\"has\\\\000nul\""
+
+gdb_test "print br##\"hi\"##" " = b\"hi\""
+gdb_test "print br##\"hi" "Unexpected EOF in string"
+gdb_test "print br##\"hi\"" "Unexpected EOF in string"
+gdb_test "print br##\"hi\"#" "Unexpected EOF in string"
+
+# Test that convenience variables and functions work with the Rust
+# parser.
+gdb_test "print \$something" " = 27"
+gdb_test "print \$_isvoid(\$nosuchvariable)" " = 1"
+gdb_test "print \$_isvoid(\$something)" " = 0"
+
+gdb_test "print \[23usize; 4\]" " = \\\[23, 23, 23, 23\\\]"
+gdb_test "ptype \[23usize; 4\]" " = \\\[usize; 4\\\]"
+gdb_test "print \[mut 23usize; 4\]" " = \\\[23, 23, 23, 23\\\]"
+
+# Test a lexer corner case.
+gdb_test "print r#" "syntax error in expression, near `#'\\."
+
+gdb_test "printf \"%d %d\\n\", 23+1, 23-1" "24 22"
--- /dev/null
+# Copyright (C) 2016 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 expressions involving generics.
+
+load_lib rust-support.exp
+if {[skip_rust_tests]} {
+ continue
+}
+
+standard_testfile .rs
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug rust}]} {
+ return -1
+}
+
+set line [gdb_get_line_number "set breakpoint here"]
+if {![runto ${srcfile}:$line]} {
+ untested $testfile
+ return -1
+}
+
+gdb_test "print identity::<u32>(23u32)" " = 23"
+gdb_test "ptype identity::<u32>(23u32)" " = u32"
+gdb_test "print identity::<f64>(23)" " = 23"
+gdb_test "ptype identity::<f64>(23)" " = f64"
+
+gdb_test "print e" " = generics::Hold<i32> \\(7\\)"
+gdb_test "print generics::Hold::<i32> (7)" " = generics::Hold<i32> \\(7\\)"
+gdb_test "print Hold::<i32> (7)" " = generics::Hold<i32> \\(7\\)"
+gdb_test "print identity::< Hold<i32> >(e)" " = generics::Hold<i32> \\(7\\)"
+gdb_test "print identity::<generics::Hold<i32> >(e)" \
+ " = generics::Hold<i32> \\(7\\)"
+gdb_test "print identity::<Hold<i32>>(e)" " = generics::Hold<i32> \\(7\\)"
--- /dev/null
+// Copyright (C) 2016 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)]
+
+
+#[derive(Clone, Copy)]
+struct Hold<T>(T);
+
+pub fn identity<T>(x: T) -> T { x }
+
+fn dowhatever() { () }
+
+pub fn main() {
+ let a = identity(23u32);
+ let b = identity(23.0f64);
+
+ let d = identity::<u32>(7);
+
+ let e = Hold(7);
+ let f = Hold::<u8>(7);
+
+ let g = identity(e);
+
+ let h = Hold(e);
+ let i = identity(h);
+
+ let z = (); // set breakpoint here
+ dowhatever()
+}
--- /dev/null
+# Copyright (C) 2016 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 method calls.
+
+load_lib rust-support.exp
+if {[skip_rust_tests]} {
+ continue
+}
+
+standard_testfile .rs
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug rust}]} {
+ return -1
+}
+
+set line [gdb_get_line_number "set breakpoint 1 here"]
+if {![runto ${srcfile}:$line]} {
+ untested $testfile
+ return -1
+}
+
+gdb_test "print x" " = methods::HasMethods \\{value: 0\\}"
+
+gdb_test "print methods::HasMethods{value: 73}" \
+ " = methods::HasMethods \\{value: 73\\}"
+gdb_test "print methods::HasMethods{..x}" \
+ " = methods::HasMethods \\{value: 0\\}"
+gdb_test "print methods::HasMethods{value:19, ..x}" \
+ " = methods::HasMethods \\{value: 19\\}"
+
+gdb_test "print x.take()" " = methods::HasMethods \\{value: 0\\}"
+gdb_test "print *(x.incr())" " = methods::HasMethods \\{value: 1\\}"
+gdb_test "print *((&mut x).incr())" " = methods::HasMethods \\{value: 2\\}"
+
+gdb_test "print a.value()" " = 23"
+gdb_test "print (&mut a).value()" " = 23"
+# gdb_test "print a.take_value().0" " = 23"
+gdb_test "print b.value()" " = 24"
+
+gdb_test "print c.value()" " = 452"
+
+set line [gdb_get_line_number "set breakpoint 2 here"]
+gdb_breakpoint ${srcfile}:$line
+gdb_continue_to_breakpoint "second breakpoint"
+
+gdb_test "print *self" " = 23"
+
+
+gdb_test "info functions HasMethods::new" \
+ "fn methods::HasMethods::new\\(\\) -> methods::HasMethods;"
+
--- /dev/null
+// Copyright (C) 2016 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)]
+
+
+pub trait Whatever {
+ fn whatever(&self) -> i32;
+ fn static_i32(x: i32) -> Self;
+}
+
+impl Whatever for i32 {
+ fn whatever(&self) -> i32 {
+ *self // set breakpoint 2 here
+ }
+
+ fn static_i32(x: i32) -> i32 {
+ x
+ }
+}
+
+pub struct HasMethods {
+ value: i32
+}
+
+impl HasMethods {
+ pub fn new() -> HasMethods {
+ HasMethods { value: 0 }
+ }
+
+ pub fn incr(&mut self) -> &mut HasMethods {
+ self.value += 1;
+ self
+ }
+
+ pub fn take(self) -> HasMethods {
+ self
+ }
+}
+
+impl Whatever for HasMethods {
+ fn whatever(&self) -> i32 {
+ self.value
+ }
+
+ fn static_i32(x: i32) -> HasMethods {
+ HasMethods{value: x}
+ }
+}
+
+enum SomeEnum {
+ One,
+ Two,
+ Three(i32),
+ Four{x: i32}
+}
+
+impl SomeEnum {
+ fn value(&self) -> i32 {
+ match *self {
+ SomeEnum::Three(x) => x,
+ SomeEnum::Four{x} => x,
+ _ => 0
+ }
+ }
+
+ fn mut_value(&mut self) -> i32 {
+ match *self {
+ SomeEnum::Three(x) => x,
+ SomeEnum::Four{x} => x,
+ _ => 0
+ }
+ }
+
+ fn take_value(self) -> (i32, SomeEnum) {
+ (match self {
+ SomeEnum::Three(x) => x,
+ SomeEnum::Four{x} => x,
+ _ => 0
+ }, self)
+ }
+}
+
+enum SimpleEnum {
+ One,
+ Two,
+ Three
+}
+
+impl SimpleEnum {
+ fn value(&self) -> i32 {
+ match *self {
+ SimpleEnum::One => 1,
+ SimpleEnum::Two => 2,
+ SimpleEnum::Three => 452,
+ }
+ }
+}
+
+fn main() {
+ let mut a = SomeEnum::Three(23);
+ let av = a.value();
+ let amv = (&mut a).mut_value();
+ let atv = a.take_value();
+ let b = SomeEnum::Four{x: 24};
+ let bv = b.value();
+ let c = SimpleEnum::Three;
+ let d = c.value();
+ let mut x = HasMethods::new();
+ x.incr(); // set breakpoint 1 here
+ (&mut x).incr();
+ let y = 23i32.whatever();
+ println!("{}", y);
+ let z = x.take();
+}
--- /dev/null
+# Copyright (C) 2016 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 name lookup.
+
+load_lib rust-support.exp
+if {[skip_rust_tests]} {
+ continue
+}
+
+standard_testfile .rs
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug rust}]} {
+ return -1
+}
+
+set line [gdb_get_line_number "set breakpoint here"]
+if {![runto ${srcfile}:$line]} {
+ untested $testfile
+ return -1
+}
+
+# Currently a closure type is not described by rustc.
+# https://github.com/rust-lang/rust/issues/33121
+# gdb_test "call f2()" "lambda f2"
+
+gdb_test "call f3()" "mod1::inner::innest::f3"
+gdb_test "call self::f2()" "mod1::inner::innest::f2"
+gdb_test "call self::super::f2()" "mod1::inner::f2"
+gdb_test "call super::f2()" "mod1::inner::f2"
+gdb_test "call self::super::super::f2()" "mod1::f2"
+gdb_test "call super::super::f2()" "mod1::f2"
+gdb_test "call ::f2()" "::f2"
+gdb_test "call super::super::super::f2()" \
+ "Too many super:: uses from 'modules::mod1::inner::innest'"
+gdb_test "call extern modules::mod1::f2()" "mod1::f2"
+
+gdb_test_sequence "ptype ::Generic::<::Generic<::Type> >" "" {
+ "type = struct modules::Generic<modules::Generic<modules::Type>> \\("
+ " modules::Generic<modules::Type>,"
+ "\\)"
+}
+
+gdb_test_sequence "ptype ::Generic::<::Generic<extern modules::Type> >" "" {
+ "type = struct modules::Generic<modules::Generic<modules::Type>> \\("
+ " modules::Generic<modules::Type>,"
+ "\\)"
+}
+
+gdb_test_sequence "ptype ::Generic::<::Generic<::mod1::Type>>" "" {
+ "type = struct modules::Generic<modules::Generic<modules::mod1::Type>> \\("
+ " modules::Generic<modules::mod1::Type>,"
+ "\\)"
+}
+
+gdb_test_sequence "ptype ::Generic::<::Generic<super::Type>>" "" {
+ "type = struct modules::Generic<modules::Generic<modules::mod1::inner::Type>> \\("
+ " modules::Generic<modules::mod1::inner::Type>,"
+ "\\)"
+}
+
+gdb_test_sequence "ptype ::Generic::<::Generic<self::Type>>" "" {
+ "type = struct modules::Generic<modules::Generic<modules::mod1::inner::innest::Type>> \\("
+ " modules::Generic<modules::mod1::inner::innest::Type>,"
+ "\\)"
+}
+
+# Not working yet.
+# gdb_test_sequence "ptype ::Generic<Type>" "" ...
+
+# Some basic linespec tests.
+foreach mod {mod1::inner::innest mod1::inner mod1 {}} {
+ if {$mod != ""} {
+ append mod ::
+ }
+ gdb_breakpoint modules::${mod}f2 message
+ gdb_breakpoint "*::${mod}f2" message
+}
--- /dev/null
+// Copyright (C) 2016 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 f2() {
+ println!("::f2");
+}
+
+pub struct Generic<T>(T);
+
+pub struct Type;
+
+pub mod mod1 {
+ pub struct Type(usize, isize);
+
+ pub mod inner {
+ pub struct Type(f64);
+
+ pub mod innest {
+ pub struct Type {pub x : u32}
+
+ fn wrap<T> (x: T) -> ::Generic<::Generic<T>> {
+ ::Generic(::Generic(x))
+ }
+
+ pub fn f1 () {
+ struct Type(i8);
+
+ let x: u8 = 0;
+
+ let ct = ::Type;
+ let ctg = wrap(ct);
+ let m1t = ::mod1::Type(23, 97);
+ let m1tg = wrap(m1t);
+ let innert = super::Type(10101.5);
+ let innertg = wrap(innert);
+ let innestt = self::Type{x: 0xfff};
+ let innesttg = wrap(innestt);
+ let f1t = Type(9);
+ let f1tg = wrap(f1t);
+
+ let f2 = || println!("lambda f2");
+
+ f2(); // set breakpoint here
+ f3();
+ self::f2();
+ super::f2();
+ self::super::f2();
+ self::super::super::f2();
+ super::super::f2();
+ ::f2();
+ }
+
+ pub fn f2() {
+ println!("mod1::inner::innest::f2");
+ }
+
+ pub fn f3() {
+ println!("mod1::inner::innest::f3");
+ }
+ }
+
+ pub fn f2() {
+ println!("mod1::inner::f2");
+ }
+ }
+
+ pub fn f2() {
+ println!("mod1::f2");
+ }
+}
+
+fn main () {
+ mod1::inner::innest::f1();
+}
--- /dev/null
+# Copyright (C) 2016 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 expression parsing and evaluation that requires Rust compiler.
+
+load_lib rust-support.exp
+if {[skip_rust_tests]} {
+ continue
+}
+
+standard_testfile .rs
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug rust}]} {
+ return -1
+}
+
+set line [gdb_get_line_number "set breakpoint here"]
+if {![runto ${srcfile}:$line]} {
+ untested $testfile
+ return -1
+}
+
+gdb_test "print a" " = \\(\\)"
+gdb_test "ptype a" " = \\(\\)"
+
+gdb_test "print b" " = \\\[\\\]"
+gdb_test "ptype b" " = \\\[i32; 0\\\]"
+gdb_test "print *(&b as *const \[i32; 0\])" " = \\\[\\\]"
+gdb_test "print *(&b as *const \[i32; 0_0\])" " = \\\[\\\]"
+
+gdb_test "print c" " = 99"
+gdb_test "ptype c" " = i32"
+
+gdb_test "print c = 87" " = \\(\\)"
+gdb_test "print c" " = 87"
+gdb_test "print c += 3" " = \\(\\)"
+gdb_test "print c" " = 90"
+gdb_test "print c -= 90" " = \\(\\)"
+gdb_test "print c" " = 0"
+gdb_test "print *&c" " = 0"
+gdb_test "print *(&c as &i32)" " = 0"
+gdb_test "print *(&c as *const i32)" " = 0"
+gdb_test "print *(&c as *mut i32)" " = 0"
+
+gdb_test "print j" " = simple::Unit"
+gdb_test "ptype j" " = struct simple::Unit"
+gdb_test "print simple::Unit" " = simple::Unit"
+
+gdb_test "print g" " = \\(u8 \\(\\*\\)\\\[6\\\]\\) $hex b\"hi bob\""
+gdb_test "ptype g" " = u8 \\(\\*\\)\\\[6\\\]"
+
+gdb_test "print v" " = simple::Something::Three"
+gdb_test_sequence "ptype v" "" {
+ " = enum simple::Something \\{"
+ " One,"
+ " Two,"
+ " Three,"
+ "\\}"
+}
+
+gdb_test "print w" " = \\\[1, 2, 3, 4\\\]"
+gdb_test "ptype w" " = \\\[i32; 4\\\]"
+gdb_test "print w\[2\]" " = 3"
+gdb_test "print w\[2\] @ 2" " = \\\[3, 4\\\]"
+gdb_test "print fromslice" " = 3"
+gdb_test "print slice\[0\]" " = 3"
+gdb_test "print slice as &\[i32\]\[0\]" " = 3"
+
+gdb_test "print x" " = \\(23, 25\\.5\\)"
+gdb_test "ptype x" " = \\(i32, f64\\)"
+gdb_test "print x as (i32,f64)" " = \\(23, 25\\.5\\)"
+
+gdb_test "print y" " = simple::HiBob \\{field1: 7, field2: 8\\}"
+gdb_test_sequence "ptype y" "" {
+ " = struct simple::HiBob \\{"
+ " field1: i32,"
+ " field2: u64,"
+ "\\}"
+}
+gdb_test "print y.field2" " = 8"
+
+gdb_test "print z" " = simple::ByeBob \\(7, 8\\)"
+gdb_test_sequence "ptype z" "" {
+ " = struct simple::ByeBob \\("
+ " i32,"
+ " u64,"
+ "\\)"
+}
+gdb_test "print z.1" " = 8"
+
+gdb_test_sequence "ptype simple::ByeBob" "" {
+ " = struct simple::ByeBob \\("
+ " i32,"
+ " u64,"
+ "\\)"
+}
+gdb_test "print simple::ByeBob(0xff, 5)" \
+ " = simple::ByeBob \\(255, 5\\)"
+gdb_test "print simple::ByeBob\{field1: 0xff, field2:5\}" \
+ "Struct expression applied to non-struct type"
+
+gdb_test "print simple::HiBob(0xff, 5)" \
+ "Type simple::HiBob is not a tuple struct"
+gdb_test "print nosuchsymbol" \
+ "No symbol 'nosuchsymbol' in current context"
+
+gdb_test "print e" " = simple::MoreComplicated::Two\\(73\\)"
+gdb_test "print e2" \
+ " = simple::MoreComplicated::Four\\{this: true, is: 8, a: 109 'm', struct_: 100, variant: 10\\}"
+
+gdb_test_sequence "ptype e" "" {
+ " = enum simple::MoreComplicated \\{"
+ " One,"
+ " Two\\(i32\\),"
+ " Three\\(simple::HiBob\\),"
+ " Four\\{this: bool, is: u8, a: char, struct_: u64, variant: u32\\},"
+ "\\}"
+}
+
+gdb_test "print e.0" " = 73"
+gdb_test "print e.1" \
+ "Cannot access field 1 of variant simple::MoreComplicated::Two, there are only 1 fields"
+gdb_test "print e.foo" \
+ "Attempting to access named field foo of tuple variant simple::MoreComplicated::Two, which has only anonymous fields"
+
+gdb_test "print e2.variant" " = 10"
+gdb_test "print e2.notexist" \
+ "Could not find field notexist of struct variant simple::MoreComplicated::Four"
+gdb_test "print e2.0" \
+ "Variant simple::MoreComplicated::Four is not a tuple variant"
+
+gdb_test "print k" " = simple::SpaceSaver::Nothing"
+gdb_test "print l" " = simple::SpaceSaver::Thebox\\(9, $hex\\)"
+gdb_test "print *l.1" " = 1729"
+
+gdb_test "print diff2(3, 7)" " = -4"
+gdb_test "print self::diff2(8, 9)" " = -1"
+gdb_test "print ::diff2(23, -23)" " = 46"
+
+gdb_test "ptype diff2" "fn \\(i32, i32\\) -> i32"
+
+gdb_test "print (diff2 as fn(i32, i32) -> i32)(19, -2)" " = 21"
+
+# We need the ".*" because currently we don't extract the length and
+# use it to intelligently print the string data.
+gdb_test "print \"hello rust\"" \
+ " = &str \\{data_ptr: $hex \"hello rust.*\", length: 10\\}"
+gdb_test "print \"hello" "Unexpected EOF in string"
+gdb_test "print r##\"hello \" rust\"##" \
+ " = &str \\{data_ptr: $hex \"hello \\\\\" rust.*\", length: 12\\}"
+gdb_test "print r\"hello" "Unexpected EOF in string"
+gdb_test "print r###\"###hello\"" "Unexpected EOF in string"
+gdb_test "print r###\"###hello\"##" "Unexpected EOF in string"
+gdb_test "print r###\"hello###" "Unexpected EOF in string"
+
+gdb_test "print 0..5" " = .*::ops::Range.* \\{start: 0, end: 5\\}"
+gdb_test "print ..5" " = .*::ops::RangeTo.* \\{end: 5\\}"
+gdb_test "print 5.." " = .*::ops::RangeFrom.* \\{start: 5\\}"
+gdb_test "print .." " = .*::ops::RangeFull"
+
+proc test_one_slice {svar length base range} {
+ global hex
+
+ set result " = &\\\[.*\\\] \\{data_ptr: $hex, length: $length\\}"
+
+ gdb_test "print $svar" $result
+ gdb_test "print &${base}\[${range}\]" $result
+}
+
+test_one_slice slice 1 w 2..3
+test_one_slice slice2 1 slice 0..1
+
+test_one_slice all1 4 w ..
+test_one_slice all2 1 slice ..
+
+test_one_slice from1 3 w 1..
+test_one_slice from2 0 slice 1..
+
+test_one_slice to1 3 w ..3
+test_one_slice to2 1 slice ..1
+
+gdb_test "print w\[2..3\]" "Can't take slice of array without '&'"
+
+
+gdb_test_sequence "complete print y.f" "" \
+ {"print y.field1" "print y.field2"}
+gdb_test_sequence "complete print y." "" \
+ {"print y.field1" "print y.field2"}
+
+# Unimplemented, but we can at least test the parser productions.
+gdb_test "print (1,2,3)" "Tuple expressions not supported yet"
+gdb_test "print (1,)" "Tuple expressions not supported yet"
+gdb_test "print (1)" " = 1"
+
+gdb_test "print 23..97.0" "Range expression with different types"
--- /dev/null
+// Copyright (C) 2016 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)]
+
+
+pub struct HiBob {
+ pub field1: i32,
+ field2: u64,
+}
+
+struct ByeBob(i32, u64);
+
+enum Something {
+ One,
+ Two,
+ Three
+}
+
+enum MoreComplicated {
+ One,
+ Two(i32),
+ Three(HiBob),
+ Four{this: bool, is: u8, a: char, struct_: u64, variant: u32},
+}
+
+fn diff2(x: i32, y: i32) -> i32 {
+ x - y
+}
+
+pub struct Unit;
+
+// This triggers the non-zero optimization that yields a different
+// enum representation in the debug info.
+enum SpaceSaver {
+ Thebox(u8, Box<i32>),
+ Nothing,
+}
+
+fn main () {
+ let a = ();
+ let b : [i32; 0] = [];
+
+ let mut c = 27;
+ let d = c = 99;
+
+ let e = MoreComplicated::Two(73);
+ let e2 = MoreComplicated::Four {this: true, is: 8, a: 'm',
+ struct_: 100, variant: 10};
+
+ let f = "hi bob";
+ let g = b"hi bob";
+ let h = b'9';
+
+ let i = ["whatever"; 8];
+
+ let j = Unit;
+
+ let k = SpaceSaver::Nothing;
+ let l = SpaceSaver::Thebox(9, Box::new(1729));
+
+ let v = Something::Three;
+ let w = [1,2,3,4];
+ let x = (23, 25.5);
+ let y = HiBob {field1: 7, field2: 8};
+ let z = ByeBob(7, 8);
+
+ let slice = &w[2..3];
+ let fromslice = slice[0];
+ let slice2 = &slice[0..1];
+
+ let all1 = &w[..];
+ let all2 = &slice[..];
+
+ let from1 = &w[1..];
+ let from2 = &slice[1..];
+
+ let to1 = &w[..3];
+ let to2 = &slice[..1];
+
+ println!("{}, {}", x.0, x.1); // set breakpoint here
+ println!("{}", diff2(92, 45));
+}
return [find_go]
}
+proc gdb_find_rustc {} {
+ global tool_root_dir
+ if {![is_remote host]} {
+ set rustc [lookfor_file $tool_root_dir rustc]
+ if {$rustc == ""} {
+ set rustc rustc
+ }
+ } else {
+ set rustc ""
+ }
+ if {$rustc != ""} {
+ append rustc " --color never"
+ }
+ return $rustc
+}
+
proc gdb_find_ldd {} {
global LDD_FOR_TARGET
if [info exists LDD_FOR_TARGET] {
}
}
+ if { $i == "rust" } {
+ set compiler_type "rust"
+ if {[board_info $dest exists rustflags]} {
+ append add_flags " [target_info rustflags]"
+ }
+ if {[board_info $dest exists rustflags]} {
+ set compiler [target_info rustflags]
+ } else {
+ set compiler [find_rustc]
+ }
+ }
+
if {[regexp "^dest=" $i]} {
regsub "^dest=" $i "" tmp
if {[board_info $tmp exists name]} {
global GNATMAKE_FOR_TARGET
global GO_FOR_TARGET
global GO_LD_FOR_TARGET
+ global RUSTC_FOR_TARGET
if {[info exists GNATMAKE_FOR_TARGET]} {
if { $compiler_type == "ada" } {
}
}
+ if {[info exists RUSTC_FOR_TARGET]} {
+ if {$compiler_type == "rust"} {
+ set compiler $RUSTC_FOR_TARGET
+ }
+ }
+
if { $type == "executable" && $linker != "" } {
set compiler $linker
}
}
if {$type == "object"} {
- append add_flags " -c"
+ if {$compiler_type == "rust"} {
+ append add_flags "--emit obj"
+ } else {
+ append add_flags " -c"
+ }
}
if { $type == "preprocess" } {
set use_gdb_compile 1
}
+if {[info procs find_rustc] == ""} {
+ rename gdb_find_rustc find_rustc
+ set use_gdb_compile 1
+}
+
if {$use_gdb_compile} {
catch {rename default_target_compile {}}
rename gdb_default_target_compile default_target_compile
return 0
}
+# Return 1 to skip Rust tests, 0 to try them.
+proc skip_rust_tests {} {
+ return [expr {![isnative]}]
+}
+
# Return a 1 for configurations that do not support Python scripting.
# PROMPT_REGEXP is the expected prompt.
}
}
set ret [$func $sources_path "${binfile}" $options]
+ } elseif {[lsearch -exact $options rust] != -1} {
+ set sources_path {}
+ foreach {s local_options} $args {
+ if { [regexp "^/" "$s"] } then {
+ lappend sources_path "$s"
+ } else {
+ lappend sources_path "$srcdir/$subdir/$s"
+ }
+ }
+ set ret [gdb_compile_rust $sources_path "${binfile}" $options]
} else {
set objects {}
set i 0
--- /dev/null
+# Copyright 2016 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/>.
+
+# Auxiliary function to set the language to Rust.
+# The result is 1 (true) for success, 0 (false) for failure.
+proc set_lang_rust {} {
+ if [gdb_test_no_output "set language rust"] {
+ return 0
+ }
+ if [gdb_test "show language" ".* source language is \"rust\"." \
+ "set language to \"rust\""] {
+ return 0
+ }
+ return 1
+}
+
+proc gdb_compile_rust {sources dest options} {
+ if {[llength $sources] > 1} {
+ error "gdb rust setup can only compile one source file at a time"
+ }
+ if {[gdb_compile [lindex $sources 0] $dest executable $options] != ""} {
+ return -1
+ }
+ return ""
+}