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:

  1. As a location, computed by an expression based on the object location (implicitly pushed). For this, we use DW_AT_data_member_location with an exprloc (formerly locdesc) class form.

  2. As a fixed byte offset, relative to the (beginning) location of the object. For this, we use DW_AT_data_member_location with a constant class form.

  3. As a fixed bit offset, relative to the location of the object. For this, we use DW_AT_data_bit_offset with 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_location attribute or a DW_AT_data_bit_offset attribute....

remove the last sentence and the following few paragraphs:

For a DW_AT_data_member_location attribute there are two cases:

  1. 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.

  2. 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 the DW_OP_push_object_address operation (see Section 2.5.2.3 on page 33); DW_OP_push_object_address therefore 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.

    A DW_AT_data_member_location attribute 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 a DW_AT_data_bit_offset attribute, 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:

  1. As a location, computed by an expression based on the containing object’s location. For this case, the DW_AT_data_member_location attribute 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_location operation (see {Context Query Operations}); therefore, DW_OP_push_object_location is 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 explicit DW_OP_push_object_location operator (or a DW_OP_dup operator).

  2. As a fixed byte offset, relative to the location of the containing object. For this case, the DW_AT_data_member_location attribute 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_offset
    
  3. As a fixed bit offset, relative to the location of the containing object. For this case, the DW_AT_data_bit_offset attribute 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.