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
This commit is contained in:
commit
f358dbf1e7
25
src/etc/gdb_rust_pretty_printing.py
Normal file → Executable file
25
src/etc/gdb_rust_pretty_printing.py
Normal file → Executable file
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user