Issue 250815.1: Clarify Means of Specifying Data Member Location
| Author: | Cary Coutant |
|---|---|
| Champion: | |
| Date submitted: | 2025-08-15 |
| Date revised: | 2025-08-18 |
| Date closed: | 2025-10-27 |
| Type: | Clarification |
| Status: | Accepted |
| DWARF version: | 6 |
Depends on Issue 230524.1, “Locations on the Stack.”
Background
This is related to 250501.1, “Dynamic DW_AT_data_bit_offset.”
That issue asked for a way to provide a dynamic bit offset
for a data member location. In DWARF 5, there is currently
no way for a location description to produce a location
that is not byte aligned, and the DW_AT_data_bit_offset
operator is defined only for constant class forms.
The obvious and straightforward solution would be to allow
the exprval class for this attribute (and for several other
attributes that take only constant class).
In discussion, we talked about whether there should be an implicit push object address before evaluating the expression.
The implicit push for DW_AT_data_member_location is for the
purpose of adding the computed offset to form the location
of the data member. If the expression needs to dereference
the object address to access its metadata (e.g., a dope
vector), it would still need to push the object address
again (or dup the one pushed implicitly). An implicit push
for DW_AT_data_bit_offset would be for the
purpose of accessing the metadata. Using that rationale, one
could argue that we should implicitly push two copies of
the object address for DW_AT_data_member_location.
Basically, we have three ways of providing the location of a data member:
-
As a location, computed by an expression based on the object location (implicitly pushed). For this, we use
DW_AT_data_member_locationwith an exprloc (formerly locdesc) class form. -
As a fixed byte offset, relative to the (beginning) location of the object. For this, we use
DW_AT_data_member_locationwith a constant class form. -
As a fixed bit offset, relative to the location of the object. For this, we use
DW_AT_data_bit_offsetwith a constant class form.
This could be clearer if we had a third attribute name,
DW_AT_data_offset (or DW_AT_data_byte_offset) for case (2),
rather than overloading the DW_AT_data_member_location
operation based on the class.
Looked at from this angle, the inability to have a dynamic bit offset seems more like an issue with case (1) rather than with case (3). And Issue 230524.1, “Locations on the Stack,” will solve that.
Accordingly, we decided that 250501.1 should be rejected on the grounds that 230524.1 will provide the proper solution. It was also decided that the text about data member offset should be clarified to make it clearer that a location expression is the preferred way to compute a dynamic bit offset.
Proposal
In Section 5.7.6, “Data Member Entries,” in the paragraph beginning:
The member entry corresponding to a data member that is defined in a structure, union or class may have either a
DW_AT_data_member_locationattribute or aDW_AT_data_bit_offsetattribute....
remove the last sentence and the following few paragraphs:
For aDW_AT_data_member_locationattribute there are two cases:
If the value is an integer constant, it is the offset in bytes from the beginning of the containing entity. If the beginning of the containing entity has a non-zero bit offset then the beginning of the member entry has that same bit offset as well.
Otherwise, the value must be a location description. In this case, the beginning of the containing entity must be byte aligned. The beginning address is pushed on the DWARF stack before the location description is evaluated; the result of the evaluation is the base address of the member entry (see Section 2.5.1 on page 27).
The push on the DWARF expression stack of the base address of the containing construct is equivalent to execution of theDW_OP_push_object_addressoperation (see Section 2.5.2.3 on page 33);DW_OP_push_object_addresstherefore is not needed at the beginning of a location description for a data member. The result of the evaluation is a location—either an address or the name of a register, not an offset to the member.
ADW_AT_data_member_locationattribute that has the form of a location description is not valid for a data member contained in an entity that is not byte aligned because DWARF operations do not allow for manipulating or computing bit offsets.
For aDW_AT_data_bit_offsetattribute, the value is an integer constant (see Section 2.19) that specifies the number of bits from the beginning of the containing entity to the beginning of the data member. This value must be greater than or equal to zero, but is not limited to less than the number of bits per byte.
and replace with the following:
There are three ways to describe a data member’s location:
As a location, computed by an expression based on the containing object’s location. For this case, the
DW_AT_data_member_locationattribute with an exprloc class form provides a location expression that yields the location of the data member. The beginning address of the containing object is implicitly pushed on the DWARF stack before the expression is evaluated. The result of the evaluation is the location of the data member.The push on the DWARF expression stack of the base address of the containing construct is equivalent to execution of the
DW_OP_push_object_locationoperation (see {Context Query Operations}); therefore,DW_OP_push_object_locationis not usually needed at the beginning of a location expression for a data member. In some cases, the computation of the data member’s location may involve reading an object’s metadata (or dope vector); this may require an explicitDW_OP_push_object_locationoperator (or aDW_OP_dupoperator).As a fixed byte offset, relative to the location of the containing object. For this case, the
DW_AT_data_member_locationattribute with a constant class form provides the byte offset from the beginning of the containing object to the beginning of the data member. This value must be an integral constant greater than or equal to zero.The result is the same as a location expression (as in case 1 preceding) consisting of
DW_OP_const[1,2,4,8]u [fixed byte offset] DW_OP_offsetAs a fixed bit offset, relative to the location of the containing object. For this case, the
DW_AT_data_bit_offsetattribute with a constant class form provides the bit offset from the beginning of the containing object to the beginning of the data member. This value must be an integral constant greater than or equal to zero, but is not limited to less than the number of bits per byte.The result is the same as an expression (as in case 1 preceding) consisting of
DW_OP_const[1,2,4,8]u [fixed bit offset] DW_OP_bit_offset
2025-08-18: Conditionally accepted, depending on Issue 230524.1, “Locations on the Stack.”
2025-10-27: Accepted.