Update gdb test suite for Rust

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.
This commit is contained in:
Tom Tromey 2016-04-26 19:38:43 -06:00
parent c44af4ebc0
commit 67218854b1
13 changed files with 1015 additions and 1 deletions

View File

@ -1,3 +1,21 @@
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.

View File

@ -0,0 +1,137 @@
# 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"

View File

@ -0,0 +1,45 @@
# 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\\)"

View File

@ -0,0 +1,44 @@
// 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()
}

View File

@ -0,0 +1,63 @@
# 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;"

View File

@ -0,0 +1,129 @@
// 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();
}

View File

@ -0,0 +1,89 @@
# 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
}

View File

@ -0,0 +1,90 @@
// 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();
}

View File

@ -0,0 +1,206 @@
# 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"

View File

@ -0,0 +1,97 @@
// 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));
}

View File

@ -105,6 +105,22 @@ proc gdb_find_go_linker {} {
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] {
@ -262,6 +278,18 @@ proc gdb_default_target_compile {source destfile type options} {
}
}
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]} {
@ -324,6 +352,7 @@ proc gdb_default_target_compile {source destfile type options} {
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" } {
@ -370,6 +399,12 @@ proc gdb_default_target_compile {source destfile type options} {
}
}
if {[info exists RUSTC_FOR_TARGET]} {
if {$compiler_type == "rust"} {
set compiler $RUSTC_FOR_TARGET
}
}
if { $type == "executable" && $linker != "" } {
set compiler $linker
}
@ -388,7 +423,11 @@ proc gdb_default_target_compile {source destfile type options} {
}
if {$type == "object"} {
append add_flags " -c"
if {$compiler_type == "rust"} {
append add_flags "--emit obj"
} else {
append add_flags " -c"
}
}
if { $type == "preprocess" } {
@ -605,6 +644,11 @@ if {[info procs find_gdc] == ""} {
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

View File

@ -1733,6 +1733,11 @@ proc skip_d_tests {} {
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.
@ -5258,6 +5263,16 @@ proc build_executable_from_specs {testname executable options args} {
}
}
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

View File

@ -0,0 +1,37 @@
# 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 ""
}