Issue 240507.1: Add support for "properties"

Author: Martin Friebe
Champion: Adrian Prantl
Date submitted: 2024-05-07
Date revised: 2025-02-17
Date closed: 2025-03-31
Type: Enhancement
Status: Accepted
DWARF version: 6

This is the 2025-02-17 version of the proposal. [ Compare with previous version ] [ Return to the latest version ]

Background

Pascal has a property construct, that allows a "variable like" identifier, which can either point to a field (member variable) or a getter/setter function.

TFoo = class
  FField: integer;
  function GetProp: integer;
  procedure SetProp(AVal: Integer);
  property MyProp: integer read GetProp write SetProp;
  property MyOtherProp: integer read FField;
end;

There may be partial overlaps with properties in Objective-C and C#.

Update: This proposal has been updated in a way to make to also useful for properties in Objective-C and Swift.

References

Proposed Changes

Section 2.1: The Debugging Information Entry

In Table 2.1, add DW_TAG_property, DW_TAG_property_getter, DW_TAG_property_setter, and DW_TAG_property_stored.

New Section 5.7.11 Property Entries

A property member is represented by a debugging information entry with the tag DW_TAG_property as specified in Section 5.19.

New Section 5.19(?): Property Entries

Add the following new subsection to Chapter 5:

5.19(?) Property Entries

[Non-normative] Many object-oriented languages like Pascal and Objective-C have properties, which are member functions that syntactically behave like data members of an object. Pascal can also have global properties that behave like data members of a unit.

A property is represented by a debugging information entry with the tag DW_TAG_property. A property entry has a DW_AT_name string attribute whose value is the property name. A property entry may have a DW_AT_type attribute to denote the type of that property.

A property may have DW_AT_accessibility, DW_AT_external, DW_AT_virtuality, DW_AT_start_scope, DW_AT_decl_column, DW_AT_decl_file and DW_AT_decl_line attributes with the respective semantics described for these attributes for DW_TAG_member (see Section 5.7.6).

A property may have one or several of DW_TAG_property_getter, DW_TAG_property_setter, or DW_TAG_property_stored children to represent the getter and setter (member) functions, or the Pascal-style stored accessor for this property. Each of these tags have a DW_AT_property_forward attribute to point to a (member) function declaration or a data member. If they point to a function, they may also have DW_TAG_formal_parameter children (matching the ones in the function) that can have DW_AT_default_value attributes to declare additional default arguments for when these functions are used as property accessors.

Some languages can automatically derive accessors for properties from a field in property's parent object. In such cases the DW_AT_property_forward attribute of the accessor entry points to the DW_TAG_property's sibling DW_TAG_member entry of field that holds the properties underlying storage.

Property accessors may also have any other attributes allowed in a DW_TAG_subprogram function declaration. If the value of a property can be derived by evaluating a DWARF expression, the DW_TAG_property_getter may have a DW_AT_location holding a DWARF expression that may use DW_OP_push_object_address to inquire the address of the property's parent object.

To change the accessibility of a property in an inherited class, a access declaration [link to 5.7.4: Access Declarations] can be specified with the property name and accessibility. For example if in a subclass property a becomes private it is sufficient to add the following to the subclass entry:

DW_TAG_class
  DW_AT_name            "subclass"
  DW_TAG_inheritance
    ...

  DW_TAG_access_declaration
    DW_AT_name            "a"
    DW_AT_accessibility   DW_ACCESS_private

Section 7

Add to Table 7.3

DW_TAG_property         0x4c
DW_TAG_property_getter  0x4d
DW_TAG_property_setter  0x4e
DW_TAG_property_stored  0x4f

Add to Table 7.5

DW_AT_property_forward  0x61  reference

Appendix D: Examples

Add a new subsection:

D.x Properties

The properties in the Pascal object in this example are represented by the following DWARF.

TClass = class
  private
     PrivateField: integer;
     function shouldStore : boolean;
  public
     function GetProp: integer;
     procedure SetProp(AVal: Integer);
     property PropFromMethods: integer read GetProp write SetProp;
     property PropFromField: integer read PrivateField;
     function GetValue(x: word; AIndex: Integer): char;
     property Indexed[x: word]: char index 1 read GetValue;
     property MaybeStored: integer stored shouldStore;
end;


DW_TAG_class_type
  DW_AT_name "TClass"
  DW_TAG_member
    DW_AT_accessibility DW_AT_private
    DW_AT_name "PrivateField"
    DW_AT_type <ref to integer>
  DW_TAG_subprogram
    DW_AT_name "GetProp"
    ...
  DW_TAG_subprogram
    DW_AT_name "SetProp"
    ...

  DW_TAG_property
    DW_AT_name "PropFromMethods"
    DW_TAG_property_getter
      DW_AT_property_forward <ref to GetProp>
    DW_TAG_property_setter
      DW_AT_property_forward <ref to SetProp>

  DW_TAG_property
    DW_AT_name "PropFromField"
    DW_TAG_property_getter
      DW_AT_property_forward <ref to PrivateField>

  DW_TAG_subprogram
    DW_AT_name "GetValue"
    ...

  DW_TAG_property
    DW_AT_name "Indexed"

    DW_TAG_property_getter
      DW_AT_property_forward <ref to GetValue>

      DW_TAG_formal_parameter  ; _this (no default specified, details inherited from GetValue
      DW_TAG_formal_parameter  ; x (no default specified)
      DW_TAG_formal_parameter
        DW_AT_default_value <DW_OP_lit 1> ; property index

  DW_TAG_property
    DW_AT_name "MaybeStored"

    DW_TAG_property_stored
      DW_AT_property_forward <ref to shouldStore>

2024-05-07: Original proposal.

2024-10-12: Revised after online discussion.

2025-01-03: Revised with updated examples and Chapter 7 changes.

2025-02-17: Revised with updated examples and Chapter 7 changes, and a fix to accessibility.