diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/rust-lang.c | 82 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.rust/simple.exp | 18 | ||||
-rw-r--r-- | gdb/testsuite/gdb.rust/simple.rs | 8 | ||||
-rw-r--r-- | gdb/typeprint.c | 3 |
6 files changed, 106 insertions, 20 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 677328b..2baf252 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2018-06-26 Tom Tromey <tom@tromey.com> + PR rust/22574: + * typeprint.c (whatis_exp): Allow ptype/o for Rust. + * rust-lang.c (rust_print_struct_def): Add podata parameter. + Update. + (rust_internal_print_type): Add podata parameter. + (rust_print_type): Update. + +2018-06-26 Tom Tromey <tom@tromey.com> + * typeprint.h (struct print_offset_data) <update, finish, maybe_print_hole>: New methods. <indentation>: New constant. diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index d9807d0..5f4aceb 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -31,8 +31,10 @@ #include "objfiles.h" #include "psymtab.h" #include "rust-lang.h" +#include "typeprint.h" #include "valprint.h" #include "varobj.h" +#include <algorithm> #include <string> #include <vector> @@ -616,14 +618,14 @@ static void rust_internal_print_type (struct type *type, const char *varstring, struct ui_file *stream, int show, int level, const struct type_print_options *flags, - bool for_rust_enum); + bool for_rust_enum, print_offset_data *podata); /* Print a struct or union typedef. */ static void rust_print_struct_def (struct type *type, const char *varstring, struct ui_file *stream, int show, int level, const struct type_print_options *flags, - bool for_rust_enum) + bool for_rust_enum, print_offset_data *podata) { /* Print a tuple type simply. */ if (rust_tuple_type_p (type)) @@ -636,6 +638,13 @@ rust_print_struct_def (struct type *type, const char *varstring, if (TYPE_N_BASECLASSES (type) > 0) c_print_type (type, varstring, stream, show, level, flags); + if (flags->print_offsets) + { + /* Temporarily bump the level so that the output lines up + correctly. */ + level += 2; + } + /* Compute properties of TYPE here because, in the enum case, the rest of the code ends up looking only at the variant part. */ const char *tagname = TYPE_NAME (type); @@ -674,16 +683,41 @@ rust_print_struct_def (struct type *type, const char *varstring, if (TYPE_NFIELDS (type) == 0 && !is_tuple) return; - if (for_rust_enum) + if (for_rust_enum && !flags->print_offsets) fputs_filtered (is_tuple_struct ? "(" : "{", stream); else fputs_filtered (is_tuple_struct ? " (\n" : " {\n", stream); + /* When printing offsets, we rearrange the fields into storage + order. This lets us show holes more clearly. We work using + field indices here because it simplifies calls to + print_offset_data::update below. */ + std::vector<int> fields; for (int i = 0; i < TYPE_NFIELDS (type); ++i) { - QUIT; if (field_is_static (&TYPE_FIELD (type, i))) continue; + if (is_enum && i == enum_discriminant_index) + continue; + fields.push_back (i); + } + if (flags->print_offsets) + std::sort (fields.begin (), fields.end (), + [&] (int a, int b) + { + return (TYPE_FIELD_BITPOS (type, a) + < TYPE_FIELD_BITPOS (type, b)); + }); + + for (int i : fields) + { + QUIT; + + gdb_assert (!field_is_static (&TYPE_FIELD (type, i))); + gdb_assert (! (is_enum && i == enum_discriminant_index)); + + if (flags->print_offsets) + podata->update (type, i, stream); /* We'd like to print "pub" here as needed, but rustc doesn't emit the debuginfo, and our types don't have @@ -691,27 +725,35 @@ rust_print_struct_def (struct type *type, const char *varstring, /* For a tuple struct we print the type but nothing else. */ - if (!for_rust_enum) + if (!for_rust_enum || flags->print_offsets) print_spaces_filtered (level + 2, stream); if (is_enum) - { - if (i == enum_discriminant_index) - continue; - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); else if (!is_tuple_struct) fprintf_filtered (stream, "%s: ", TYPE_FIELD_NAME (type, i)); rust_internal_print_type (TYPE_FIELD_TYPE (type, i), NULL, stream, (is_enum ? show : show - 1), - level + 2, flags, is_enum); - if (!for_rust_enum) + level + 2, flags, is_enum, podata); + if (!for_rust_enum || flags->print_offsets) fputs_filtered (",\n", stream); + /* Note that this check of "I" is ok because we only sorted the + fields by offset when print_offsets was set, so we won't take + this branch in that case. */ else if (i + 1 < TYPE_NFIELDS (type)) fputs_filtered (", ", stream); } - if (!for_rust_enum) + if (flags->print_offsets) + { + /* Undo the temporary level increase we did above. */ + level -= 2; + podata->finish (type, level, stream); + print_spaces_filtered (print_offset_data::indentation, stream); + if (level == 0) + print_spaces_filtered (2, stream); + } + if (!for_rust_enum || flags->print_offsets) print_spaces_filtered (level, stream); fputs_filtered (is_tuple_struct ? ")" : "}", stream); } @@ -735,7 +777,7 @@ static void rust_internal_print_type (struct type *type, const char *varstring, struct ui_file *stream, int show, int level, const struct type_print_options *flags, - bool for_rust_enum) + bool for_rust_enum, print_offset_data *podata) { int i; @@ -778,7 +820,7 @@ rust_internal_print_type (struct type *type, const char *varstring, if (i > 0) fputs_filtered (", ", stream); rust_internal_print_type (TYPE_FIELD_TYPE (type, i), "", stream, - -1, 0, flags, false); + -1, 0, flags, false, podata); } fputs_filtered (")", stream); /* If it returns unit, we can omit the return type. */ @@ -786,7 +828,7 @@ rust_internal_print_type (struct type *type, const char *varstring, { fputs_filtered (" -> ", stream); rust_internal_print_type (TYPE_TARGET_TYPE (type), "", stream, - -1, 0, flags, false); + -1, 0, flags, false, podata); } break; @@ -796,7 +838,8 @@ rust_internal_print_type (struct type *type, const char *varstring, fputs_filtered ("[", stream); rust_internal_print_type (TYPE_TARGET_TYPE (type), NULL, - stream, show - 1, level, flags, false); + stream, show - 1, level, flags, false, + podata); if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST) @@ -811,7 +854,7 @@ rust_internal_print_type (struct type *type, const char *varstring, case TYPE_CODE_UNION: case TYPE_CODE_STRUCT: rust_print_struct_def (type, varstring, stream, show, level, flags, - for_rust_enum); + for_rust_enum, podata); break; case TYPE_CODE_ENUM: @@ -856,8 +899,9 @@ rust_print_type (struct type *type, const char *varstring, struct ui_file *stream, int show, int level, const struct type_print_options *flags) { + print_offset_data podata; rust_internal_print_type (type, varstring, stream, show, level, - flags, false); + flags, false, &podata); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 73f5545..b2901db 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-06-26 Tom Tromey <tom@tromey.com> + + PR rust/22574: + * gdb.rust/simple.exp (test_one_slice): Add ptype/o tests. + * gdb.rust/simple.rs (struct SimpleLayout): New. + 2018-06-22 Simon Marchi <simon.marchi@ericsson.com> * gdb.base/jit-reader.exp (jit_reader_test): Expect spaces in diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp index ba90e06..20fe8dd 100644 --- a/gdb/testsuite/gdb.rust/simple.exp +++ b/gdb/testsuite/gdb.rust/simple.exp @@ -285,6 +285,24 @@ gdb_test "print parametrized" \ gdb_test "print u" " = simple::Union {f1: -1, f2: 255}" +gdb_test_sequence "ptype/o Union" "" { + "/\\* offset | size \\*/ type = union simple::Union {" + "/\\* 1 \\*/ f1: i8," + "/\\* 1 \\*/ f2: u8," + "" + " /\\* total size \\(bytes\\): 1 \\*/" + " }" +} + +gdb_test_sequence "ptype/o SimpleLayout" "" { + "/\\* offset | size \\*/ type = struct simple::SimpleLayout {" + "/\\* 0 | 2 \\*/ f1: u16," + "/\\* 2 | 2 \\*/ f2: u16," + "" + " /\\* total size \\(bytes\\): 4 \\*/" + " }" +} + load_lib gdb-python.exp if {[skip_python_tests]} { continue diff --git a/gdb/testsuite/gdb.rust/simple.rs b/gdb/testsuite/gdb.rust/simple.rs index e5bbe52..9d89361 100644 --- a/gdb/testsuite/gdb.rust/simple.rs +++ b/gdb/testsuite/gdb.rust/simple.rs @@ -85,6 +85,13 @@ union Union { f2: u8, } +// A simple structure whose layout won't be changed by the compiler, +// so that ptype/o testing will work on any platform. +struct SimpleLayout { + f1: u16, + f2: u16 +} + fn main () { let a = (); let b : [i32; 0] = []; @@ -159,6 +166,7 @@ fn main () { }; let u = Union { f2: 255 }; + let v = SimpleLayout { f1: 8, f2: 9 }; println!("{}, {}", x.0, x.1); // set breakpoint here println!("{}", diff2(92, 45)); diff --git a/gdb/typeprint.c b/gdb/typeprint.c index b29ad5f..7a0b762 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -490,7 +490,8 @@ whatis_exp (const char *exp, int show) feature. */ if (show > 0 && (current_language->la_language == language_c - || current_language->la_language == language_cplus)) + || current_language->la_language == language_cplus + || current_language->la_language == language_rust)) { flags.print_offsets = 1; flags.print_typedefs = 0; |