Skip to content

Commit f358dbf

Browse files
committed
rollup merge of #20557: cactorium/prettyprinters
As per #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
2 parents e2f97f5 + d338572 commit f358dbf

File tree

3 files changed

+38
-22
lines changed

3 files changed

+38
-22
lines changed

src/etc/gdb_rust_pretty_printing.py

100644100755
Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def rust_pretty_printer_lookup_function(val):
5151
enum_member_count = len(enum_members)
5252

5353
if enum_member_count == 0:
54-
return RustStructPrinter(val, false)
54+
return RustStructPrinter(val, False)
5555

5656
if enum_member_count == 1:
5757
first_variant_name = enum_members[0].name
@@ -60,21 +60,27 @@ def rust_pretty_printer_lookup_function(val):
6060
return rust_pretty_printer_lookup_function(val[enum_members[0]])
6161
else:
6262
assert first_variant_name.startswith("RUST$ENCODED$ENUM$")
63-
# This is a space-optimized enum
63+
# This is a space-optimized enum.
64+
# This means this enum has only two states, and Rust uses one of the
65+
# fields somewhere in the struct to determine which of the two states
66+
# it's in. The location of the field is encoded in the name as something
67+
# like RUST$ENCODED$ENUM$(num$)*name_of_zero_state
6468
last_separator_index = first_variant_name.rfind("$")
65-
second_last_separator_index = first_variant_name.rfind("$", 0, last_separator_index)
66-
disr_field_index = first_variant_name[second_last_separator_index + 1 :
67-
last_separator_index]
68-
disr_field_index = int(disr_field_index)
69+
start_index = len("RUST$ENCODED$ENUM$")
70+
disr_field_indices = first_variant_name[start_index :
71+
last_separator_index].split("$")
72+
disr_field_indices = [int(index) for index in disr_field_indices]
6973

7074
sole_variant_val = val[enum_members[0]]
71-
disr_field = get_field_at_index(sole_variant_val, disr_field_index)
72-
discriminant = sole_variant_val[disr_field]
75+
discriminant = sole_variant_val
76+
for disr_field_index in disr_field_indices:
77+
disr_field = get_field_at_index(discriminant, disr_field_index)
78+
discriminant = discriminant[disr_field]
7379

7480
# If the discriminant field is a fat pointer we have to consider the
7581
# first word as the true discriminant
7682
if discriminant.type.code == gdb.TYPE_CODE_STRUCT:
77-
discriminant = discriminant[get_field_at_index(discriminant, 0)]
83+
discriminant = discriminant[get_field_at_index(discriminant, 0)]
7884

7985
if discriminant == 0:
8086
null_variant_name = first_variant_name[last_separator_index + 1:]
@@ -234,4 +240,5 @@ def get_field_at_index(val, index):
234240
for field in val.type.fields():
235241
if i == index:
236242
return field
243+
i += 1
237244
return None

src/etc/lldb_rust_formatters.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ def print_struct_val_starting_from(field_start_index, val, internal_dict):
7979
has_field_names = type_has_field_names(t)
8080

8181
if has_field_names:
82-
template = "%(type_name)s {\n%(body)s\n}"
83-
separator = ", \n"
82+
template = "%(type_name)s {\n%(body)s\n}"
83+
separator = ", \n"
8484
else:
85-
template = "%(type_name)s(%(body)s)"
86-
separator = ", "
85+
template = "%(type_name)s(%(body)s)"
86+
separator = ", "
8787

8888
if type_name.startswith("("):
8989
# this is a tuple, so don't print the type name
@@ -125,25 +125,25 @@ def print_enum_val(val, internal_dict):
125125
if last_separator_index == -1:
126126
return "<invalid enum encoding: %s>" % first_variant_name
127127

128-
second_last_separator_index = first_variant_name.rfind("$", 0, last_separator_index)
129-
if second_last_separator_index == -1:
130-
return "<invalid enum encoding: %s>" % first_variant_name
128+
start_index = len("RUST$ENCODED$ENUM$")
131129

132-
# Extract index of the discriminator field
130+
# Extract indices of the discriminator field
133131
try:
134-
disr_field_index = first_variant_name[second_last_separator_index + 1 :
135-
last_separator_index]
136-
disr_field_index = int(disr_field_index)
132+
disr_field_indices = first_variant_name[start_index :
133+
last_separator_index].split("$")
134+
disr_field_indices = [int(index) for index in disr_field_indices]
137135
except:
138136
return "<invalid enum encoding: %s>" % first_variant_name
139137

140138
# Read the discriminant
141-
disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index)
139+
disr_val = val.GetChildAtIndex(0)
140+
for index in disr_field_indices:
141+
disr_val = disr_val.GetChildAtIndex(index)
142142

143143
# If the discriminant field is a fat pointer we have to consider the
144144
# first word as the true discriminant
145145
if disr_val.GetType().GetTypeClass() == lldb.eTypeClassStruct:
146-
disr_val = disr_val.GetChildAtIndex(0)
146+
disr_val = disr_val.GetChildAtIndex(0)
147147

148148
if disr_val.GetValueAsUnsigned() == 0:
149149
# Null case: Print the name of the null-variant

src/test/debuginfo/gdb-pretty-struct-and-enums.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@
6969
// gdb-command: print nested_variant2
7070
// 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}}}
7171

72+
// gdb-command: print none_check1
73+
// gdb-check:$17 = None
74+
75+
// gdb-command: print none_check2
76+
// gdb-check:$18 = None
77+
7278
use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3};
7379
use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar};
7480
use self::NestedEnum::{NestedVariant1, NestedVariant2};
@@ -170,6 +176,9 @@ fn main() {
170176
}
171177
};
172178

179+
let none_check1: Option<(uint, Vec<uint>)> = None;
180+
let none_check2: Option<String> = None;
181+
173182
zzz(); // #break
174183
}
175184

0 commit comments

Comments
 (0)