[Dwarf-Discuss] About self-referencial sized types

Pierre-Marie de Rodat derodat at adacore.com
Wed May 14 05:38:57 PDT 2014

On 04/28/2014 05:29 PM, Agovic, Sanimir wrote:
>> In GCC, however, computing the upper bound of "A" is more subtle:
>> it is internally represented as: max(0, <record>.N) so that when
>> "N" is negative, 0 is returned.
> I`m not being familiar with internal gcc representations but what is
> preventing you of referencing the member N?

Nothing: actually, the internal GCC representation for Ada arrays bounds 
(GENERIC trees) is already there and works well for quite a while. My 
problem here is that I do not know what DWARF operations to output in 
the DW_AT_{lower,upper}_bound attributes in order to retrieve array 
"neighbors" members so that we can compute the array bounds using them.

>> So what address would this operation [DW_OP_push_object_address]
>> push on top of the stack? The address of the "A" member, or the
>> address of the embedding record?
> It pushes the address of the currently evaluated object, in your
> case it is the address of member "A". You may have a look at 'D.2
> Aggregate Examples' and Figure 51 in the latest dwarf standard.
> DW_OP_push_object_address is usually used to address meta information
> of a type e.g. bound information of an array. This information is
> usually part of the array descriptor hence the address of the object
> is needed and not the embedding type.

> Can you illustrate the record descriptor representation? e.g. a
> simple representation in form of a C struct. My knowledge about how
> vla work is pretty limited to C99 and Fortran. It might help to
> understand the problem a bit better.

Sure, I should have done it earlier. The Record_Type I was refering to 
in my example would be translated to something like:

   struct record_type {
     int n;
     int a[1 .. max(n, 0)];

>> On the other hand, getting the address of the "A" member would not
>> be sufficient: in more complex cases, the offset of the "A" member
>> can depend on discriminants!
> So the bounds information of an array is not stored as part of the
> array descriptor but rather in the embedding type?

Indeed, there is no descriptor. That's why the DW_TAG_array_type DIE is 
put under the DW_TAG_record_type one: the array type has no meaning 
without the embedding record type.

> We have implemented the opcode in our vla project at [1], see commits [2]
> and [3].
>   [1] https://github.com/intel-gdb/vla/commits/vla-fortran
>   [2] https://github.com/intel-gdb/vla/commit/2d354ffed66a91a0ecf5848f33179c2b4e84c115
>   [3] https://github.com/intel-gdb/vla/commit/014913ff8433a661ee8a1dfe158d66465c8f343c

Thank you for the pointers.

So, if I understand correctly, the C99 VLAs rely on "neighbor" local 
variables, the Fortran ones rely on descriptors (i.e. wrapped pointers 
that embbed information about the array), while the Ada ones can rely on 
both _plus_ other cases, like the example I introduced at the beginning 
of the thread. The DW_OP_push_object_address seems to be suited only for 
descriptors, and thus it is not adapted to describe such bound 
computations in DWARF.

By the way, I came across an issue on dwarfstd.org[1]: it defines a new 
operation (DW_OP_implicit_pointer) which can be used to get the address 
of an object from the corresponding DIE. While it was created to deal 
with "optimized out" objects (that obviously cannot be referenced with a 
real pointer), it fits more what we would need to do here than 
DW_OP_push_object_address. Using it would look more like a hack to me, 

[1] http://dwarfstd.org/ShowIssue.php?issue=100831.1

Pierre-Marie de Rodat

More information about the Dwarf-Discuss mailing list