Proposal to implement “properties” (based on Pascal)

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; * Properties can exist in a structure, interface, or on a global level. * Properties can be read/write, read only, write only. * Properties can have one or more array like indexes (of any type). function GetProp(AIdx:word; AIdx2: boolean): integer; procedure SetProp(AIdx:word; AIdx2: boolean; AVal: Integer); property MyProp[AIdx:word; AIdx2: boolean]: integer read GetProp write SetProp; * Properties can share a method, and provide an index (constant) to identify which property called the method. function GetProp(AIndex: Integer): integer; procedure SetProp(AIndex: Integer; AValue: integer); property MyProp1: integer index 1 read GetProp write SetProp; property MyProp2: integer index 2 read GetProp write SetProp; * Properties can have a “default” flag, indicating that the array [] access can omit the property name. I.e. accessing “Object[n]” is a shortcut for the default property. (default for non-array properties is being considered for future addition) * Properties can have “default” and “stored” values for streaming (constant or via function). * Properties can be elevated to a higher visibility (private/public) in inherited classes.

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

References

FreePascal property doc https://www.freepascal.org/docs-html/ref/refse27.html Oxygene https://docs.elementscompiler.com/Oxygene/Members/Properties/ APPLE extension for Objective-C https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#debugging-information-format-1

Proposed Changes

Table 2.1

add DW_TAG_property.

5.7.6 add the following normative text

DW_TAG_property

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.

A property is represented by a debugging information entry with the tag DW_TAG_property. At 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 chaper 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_TAG_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 DW_TAG_property can be specified with just a 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_property DW_AT_name "a" DW_AT_accessibility DW_ACCESS_private

D Examples

Add

Properties

The properties in the Pascal object in this example is represented by the following DWARF. ``` TClass = class FField: integer; function GetProp: integer; procedure SetProp(AVal: Integer); property MyProp: integer read GetProp write SetProp; property MyOtherProp: integer read FField; function GetFoo(x: word; AIndex: Integer): char; property Foo[x: word]: char index 1 read GetFoo; end;

DW_TAG_class_type DW_AT_name “TClass” DW_TAG_member DW_AT_name “FField” DW_AT_type DW_TAG_subprogram DW_AT_name “GetProp” … DW_TAG_subprogram DW_AT_name “SetProp” …

DW_TAG_property DW_AT_name “MyProp” DW_TAG_property_getter DW_AT_property_forward DW_TAG_property_setter DW_AT_property_forward

DW_TAG_property DW_AT_name “MyOtherProp” DW_TAG_property_getter DW_AT_property_forward

DW_TAG_subprogram DW_AT_name “GetFoo” …

DW_TAG_property DW_AT_name “Foo”

DW_TAG_property_getter
  DW_AT_property_forward <ref to GetFoo>

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

```