[PATCH 10/11] Add Python support for dynamic types

Christian Biesinger cbiesinger@google.com
Fri Apr 10 17:44:06 GMT 2020


On Thu, Apr 9, 2020 at 1:44 PM Tom Tromey <tom@tromey.com> wrote:
>
> >>>>> "Christian" == Christian Biesinger via Gdb-patches <gdb-patches@sourceware.org> writes:
>
> >> This attribute is not available for @code{enum} or @code{static}
> >> (as in C@t{++}) fields.  The value is the position, counting
> >> -in bits, from the start of the containing type.
> >> +in bits, from the start of the containing type.  Note that, in a
> >> +dynamic type, the position of a field may not be constant.  In this
> >> +case, the value will be @code{None}.
>
> Christian> Just to make sure I understand, if I have a type like this (using
> Christian> Haskell-like syntax, I hope this makes sense):
>
> Christian> Type t =
> Christian>   Int x |
> Christian>   Float y |
> Christian>   (String a, Float b)
>
> Christian> This would be reflected in Python as the type having fields x, y, a
> Christian> and b, all of which have a None position?
>
> IIUC this would have field x, y, and a field with an anonymous structure
> type, that in turn has fields a and b.  But otherwise yes.
>
> Christian> Is there a way to access these fields, and is there a way to see which
> Christian> specific type a certain variable value is?
>
> Yes, the type of a value will be a concrete instance of such a dynamic
> type.
>
> The Rust test is similar:
>
> >> +gdb_test "python print(len(e.type.fields()))" "2"
> >> +gdb_test "python print(e.type.fields()\[0\].artificial)" "True"
> >> +gdb_test "python print(e.type.fields()\[1\].name)" "Two"
> >> +
> >> +gdb_test "python print(e.type.dynamic)" "False"
> >> +gdb_test "python print(gdb.lookup_type('simple::MoreComplicated').dynamic)" \
> >> +    "True"
>
> This is inspecting a dynamic type "MoreComplicated" and a value of that
> type, "e".
>
> MoreComplicated is an enum, which is the Rust equivalent of your Haskell
> example.
>
>     enum MoreComplicated {
>         One,
>         Two(i32),
>         Three(HiBob),
>         Four{this: bool, is: u8, a: char, struct_: u64, variant: u32},
>     }
>
> The value comes from:
>
>     let e = MoreComplicated::Two(73);
>
> So, if we have the dynamic type, "dynamic" is True and all the fields
> are available (not shown in the test).  If we have the value "e", only
> the applicable fields for the variant are available -- the
> compiler-provided discriminant, and the "Two" payload.

Thanks for the detailed explanation! I would suggest two things:
- For your note in the documentation that "the position of a field may
not be constant", maybe add that the field may not exist in a specific
value, and
- mention somewhere that value.type will be different from
gdb.lookup_type(value.type.name), and lets you access the concrete
fields

The "dynamic type" name is unfortunate, since it is unrelated to
Value.dynamic_type AFAICT. I thought discriminated/tagged union was a
more common name for this :(

Thanks,
Christian


More information about the Gdb-patches mailing list