diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-06 15:24:52 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-06 15:24:52 -0800 |
| commit | f358dbf1e7c3c3b474164f3d8bb4bd9f8e563c29 (patch) | |
| tree | 4f89b89075c76c44705aa0da56d47d487ab725a6 | |
| parent | e2f97f51ad4cf902e5a5835b5332447fe59089c4 (diff) | |
| parent | d33857208f9af74fd414c79eeda40bdf50bf4574 (diff) | |
| download | rust-f358dbf1e7c3c3b474164f3d8bb4bd9f8e563c29.tar.gz rust-f358dbf1e7c3c3b474164f3d8bb4bd9f8e563c29.zip | |
rollup merge of #20557: cactorium/prettyprinters
As per https://github.com/rust-lang/rust/issues/20405. To be more precise, the changes just the processing of enums when the name is "RUST$ENCODED$ENUM$..." so it correctly parses when there is more than one number encoding the location of the field it's looking for to determine state of the enum
| -rwxr-xr-x[-rw-r--r--] | src/etc/gdb_rust_pretty_printing.py | 25 | ||||
| -rw-r--r-- | src/etc/lldb_rust_formatters.py | 26 | ||||
| -rw-r--r-- | src/test/debuginfo/gdb-pretty-struct-and-enums.rs | 9 |
3 files changed, 38 insertions, 22 deletions
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index 7e5918ea39e..b6770c99975 100644..100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -51,7 +51,7 @@ def rust_pretty_printer_lookup_function(val): enum_member_count = len(enum_members) if enum_member_count == 0: - return RustStructPrinter(val, false) + return RustStructPrinter(val, False) if enum_member_count == 1: first_variant_name = enum_members[0].name @@ -60,21 +60,27 @@ def rust_pretty_printer_lookup_function(val): return rust_pretty_printer_lookup_function(val[enum_members[0]]) else: assert first_variant_name.startswith("RUST$ENCODED$ENUM$") - # This is a space-optimized enum + # This is a space-optimized enum. + # This means this enum has only two states, and Rust uses one of the + # fields somewhere in the struct to determine which of the two states + # it's in. The location of the field is encoded in the name as something + # like RUST$ENCODED$ENUM$(num$)*name_of_zero_state last_separator_index = first_variant_name.rfind("$") - second_last_separator_index = first_variant_name.rfind("$", 0, last_separator_index) - disr_field_index = first_variant_name[second_last_separator_index + 1 : - last_separator_index] - disr_field_index = int(disr_field_index) + start_index = len("RUST$ENCODED$ENUM$") + disr_field_indices = first_variant_name[start_index : + last_separator_index].split("$") + disr_field_indices = [int(index) for index in disr_field_indices] sole_variant_val = val[enum_members[0]] - disr_field = get_field_at_index(sole_variant_val, disr_field_index) - discriminant = sole_variant_val[disr_field] + discriminant = sole_variant_val + for disr_field_index in disr_field_indices: + disr_field = get_field_at_index(discriminant, disr_field_index) + discriminant = discriminant[disr_field] # If the discriminant field is a fat pointer we have to consider the # first word as the true discriminant if discriminant.type.code == gdb.TYPE_CODE_STRUCT: - discriminant = discriminant[get_field_at_index(discriminant, 0)] + discriminant = discriminant[get_field_at_index(discriminant, 0)] if discriminant == 0: null_variant_name = first_variant_name[last_separator_index + 1:] @@ -234,4 +240,5 @@ def get_field_at_index(val, index): for field in val.type.fields(): if i == index: return field + i += 1 return None diff --git a/src/etc/lldb_rust_formatters.py b/src/etc/lldb_rust_formatters.py index f4f1a5121d1..05d71902904 100644 --- a/src/etc/lldb_rust_formatters.py +++ b/src/etc/lldb_rust_formatters.py @@ -79,11 +79,11 @@ def print_struct_val_starting_from(field_start_index, val, internal_dict): has_field_names = type_has_field_names(t) if has_field_names: - template = "%(type_name)s {\n%(body)s\n}" - separator = ", \n" + template = "%(type_name)s {\n%(body)s\n}" + separator = ", \n" else: - template = "%(type_name)s(%(body)s)" - separator = ", " + template = "%(type_name)s(%(body)s)" + separator = ", " if type_name.startswith("("): # this is a tuple, so don't print the type name @@ -125,25 +125,25 @@ def print_enum_val(val, internal_dict): if last_separator_index == -1: return "<invalid enum encoding: %s>" % first_variant_name - second_last_separator_index = first_variant_name.rfind("$", 0, last_separator_index) - if second_last_separator_index == -1: - return "<invalid enum encoding: %s>" % first_variant_name + start_index = len("RUST$ENCODED$ENUM$") - # Extract index of the discriminator field + # Extract indices of the discriminator field try: - disr_field_index = first_variant_name[second_last_separator_index + 1 : - last_separator_index] - disr_field_index = int(disr_field_index) + disr_field_indices = first_variant_name[start_index : + last_separator_index].split("$") + disr_field_indices = [int(index) for index in disr_field_indices] except: return "<invalid enum encoding: %s>" % first_variant_name # Read the discriminant - disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index) + disr_val = val.GetChildAtIndex(0) + for index in disr_field_indices: + disr_val = disr_val.GetChildAtIndex(index) # If the discriminant field is a fat pointer we have to consider the # first word as the true discriminant if disr_val.GetType().GetTypeClass() == lldb.eTypeClassStruct: - disr_val = disr_val.GetChildAtIndex(0) + disr_val = disr_val.GetChildAtIndex(0) if disr_val.GetValueAsUnsigned() == 0: # Null case: Print the name of the null-variant diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs index 64c120e1ab3..4b2628b2a1f 100644 --- a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs +++ b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs @@ -69,6 +69,12 @@ // gdb-command: print nested_variant2 // gdb-check:$16 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}} +// gdb-command: print none_check1 +// gdb-check:$17 = None + +// gdb-command: print none_check2 +// gdb-check:$18 = None + use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3}; use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar}; use self::NestedEnum::{NestedVariant1, NestedVariant2}; @@ -170,6 +176,9 @@ fn main() { } }; + let none_check1: Option<(uint, Vec<uint>)> = None; + let none_check2: Option<String> = None; + zzz(); // #break } |
