Skip to content

Fix gdb/lldb pretty printers for nullable-opt enums with fat pointers. #19474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 5, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/etc/gdb_rust_pretty_printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,27 @@ def rust_pretty_printer_lookup_function(val):
return RustStructPrinter(val, false)

if enum_member_count == 1:
if enum_members[0].name == None:
first_variant_name = enum_members[0].name
if first_variant_name == None:
# This is a singleton enum
return rust_pretty_printer_lookup_function(val[enum_members[0]])
else:
assert enum_members[0].name.startswith("RUST$ENCODED$ENUM$")
assert first_variant_name.startswith("RUST$ENCODED$ENUM$")
# This is a space-optimized enum
last_separator_index = enum_members[0].name.rfind("$")
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)

sole_variant_val = val[enum_members[0]]
disr_field = get_field_at_index(sole_variant_val, disr_field_index)
discriminant = int(sole_variant_val[disr_field])
discriminant = sole_variant_val[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)]

if discriminant == 0:
null_variant_name = first_variant_name[last_separator_index + 1:]
Expand Down Expand Up @@ -173,7 +179,7 @@ def to_string(self):

class IdentityPrinter:
def __init__(self, string):
self.string
self.string = string

def to_string(self):
return self.string
Expand Down
9 changes: 7 additions & 2 deletions src/etc/lldb_rust_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,14 @@ def print_enum_val(val, internal_dict):
return "<invalid enum encoding: %s>" % first_variant_name

# Read the discriminant
disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index).GetValueAsUnsigned()
disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index)

if disr_val == 0:
# 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)

if disr_val.GetValueAsUnsigned() == 0:
# Null case: Print the name of the null-variant
null_variant_name = first_variant_name[last_separator_index + 1:]
return null_variant_name
Expand Down
12 changes: 10 additions & 2 deletions src/test/debuginfo/gdb-pretty-struct-and-enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,17 @@
// gdb-command: print none
// gdb-check:$12 = None

// gdb-command: print some_fat
// gdb-check:$13 = Some = {"abc"}

// gdb-command: print none_fat
// gdb-check:$14 = None

// gdb-command: print nested_variant1
// gdb-check:$13 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}
// gdb-check:$15 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}

// gdb-command: print nested_variant2
// gdb-check:$14 = 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-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}}}

use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3};
use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar};
Expand Down Expand Up @@ -129,6 +135,8 @@ fn main() {

let some = Some(110u);
let none: Option<int> = None;
let some_fat = Some("abc");
let none_fat: Option<&'static str> = None;

let nested_variant1 = NestedVariant1(
NestedStruct {
Expand Down
9 changes: 9 additions & 0 deletions src/test/debuginfo/option-like-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
// lldb-command:print void_droid
// lldb-check:[...]$5 = Void

// lldb-command:print some_str
// lldb-check:[...]$6 = Some(&str { data_ptr: [...], length: 3 })

// lldb-command:print none_str
// lldb-check:[...]$7 = None


// If a struct has exactly two variants, one of them is empty, and the other one
// contains a non-nullable pointer, then this value is used as the discriminator.
Expand Down Expand Up @@ -96,6 +102,9 @@ struct NamedFieldsRepr<'a> {

fn main() {

let some_str: Option<&'static str> = Some("abc");
let none_str: Option<&'static str> = None;

let some: Option<&u32> = Some(unsafe { std::mem::transmute(0x12345678u) });
let none: Option<&u32> = None;

Expand Down