000302.1 | B | A | R. Brender | Representation | Class constant FORM |
I happened to notice when going over the response from Jim
regarding my
991108-12/-11 proposal that I used two different forms of operand in the
DW_AT_data_member_location attributes in my examples, to wit:
In the main example--
4$: DW_TAG_member
DW_AT_name("ap")
DW_AT_type(reference to 1$)
DW_AT_data_member_location(constant 4)
In the second example--
9$: DW_TAG_member
DW_AT_name("VEC")
DW_AT_type(reference to unnamed array type at 8$)
DW_AT_data_member_location(machine=
DW_OP_lit<n> ! where n ==
offset(REC2, VEC)
DW_OP_add)
[[Oops: actually I left out the DW_OP_add in
this one!]]
Then I noticed that Figure 19, page 71 lists only classes block and reference
as FORMs that can be used with this attribute, not class constant. Further,
Section 5.5.2 mentions only the use of a location description (class block)
when DW_AT_data_member_location is used with DW_TAG_inheritance for an
inherited base class. And, similarly in Section 5.5.4/p41 when describing
the use of DW_AT_data_member_location with DW_TAG_member for a data member.
Problems
--------
A) No where is there a description of what class reference means for this
attribute.
B) It would save space to allow class constant as one of the alternative
classes, defined to be the byte offset relative to the base of the
structure/class of the member being described.
In the above example, DW_AT_data_member_location(constant 4) requires
just one byte of memory in the Dwarf description (assuming use of
DW_FORM_udata or DW_FORM_data1).
In contract, DW_AT_data_member_location(machine=DW_OP_lit<n>,
DW_OP_add)
takes two bytes, a one byte difference, provided that <n> is small
enough
to have a special case one byte DW_OP_LIT<n> operator (0 <= n <=
31).
For larger <n>, there will be always be a two byte difference, due to
DW_OP_const<x> and DW_OP_add operators (since the value <n>
itself will
be the same size in both cases).
Now, one or two bytes may seem like not a big deal. But, remember
that this is one or two bytes for almost *every* data member described
in a compilation (since the vast majority of data members are at fixed
offsets). That has got to add up.
Besides, it feels so natural to describe the offset as an immediate
constant value when that all that really needs to be communicated!
(I, at least, did it automatically without even thinking about it when
preparing the examples!)
Proposal
--------
Clean up the description of DW_AT_data_member_location to allow three
classes of operands, interpreted as follows:
1) For class block (location expression): Same as now.
2) For class reference: The value "points to" the DIE of an object
(variable, parameter, constant) whose value (contents) is to be added
to the base of the structure/class to produce the address of the data
member.
3) For class constant: The immediate value of the constant is added to
the base of the structure/class to produce the address of the data
member.
Note: This makes the interpretation of DW_AT_data_member_location more
similar to the triple class operand choices that have been proposed elsewhere.
This attribute does result in an address (of course), while most of the other
attributes (so far) happen to result in a value (array bound or the like) --
which is fine.
Changes to FORM CONSTANT approved.