Issue 240507.1: Add support for "properties"
| Author: | Martin Friebe |
|---|---|
| Champion: | Adrian Prantl |
| Date submitted: | 2024-05-07 |
| Date revised: | 2025-01-03 |
| Date closed: | 2025-03-31 |
| Type: | Enhancement |
| Status: | Accepted |
| DWARF version: | 6 |
Comparing 2024-11-25 with 2025-01-03. [ View this 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;
* 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][freepascal]
- [Oxygene][oxygene]
- [Apple extension for Objective-C][objc]
[freepascal]: https://www.freepascal.org/docs-html/ref/refse27.html
[oxygene]: https://docs.elementscompiler.com/Oxygene/Members/Properties/
[objc]: https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#debugging-information-format-1
## 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`.
### Section 5.7: Structure, Union and Class Type Entries
Add the following new subsection after Section 5.7.6 Data Member Entries:
> 5.7.x 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.
>
> 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_TAG_location` holding a DWARF
> `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 > `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
### 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
> FField: integer;
> PrivateField: integer; > public
> function GetProp: integer; > procedure SetProp(AVal: Integer);
> property MyProp: integer read GetProp write SetProp;
> property PropFromMethods: integer read GetProp write SetProp;
> property MyOtherProp: integer read FField;
> property PropFromField: integer read PrivateField;
> function GetFoo(x: word; AIndex: Integer): char;
> function GetValue(x: word; AIndex: Integer): char;
> property Foo[x: word]: char index 1 read GetFoo;
> property Indexed[x: word]: char index 1 read GetValue;
> end; > > > DW_TAG_class_type > DW_AT_name "TClass" > DW_TAG_member
> DW_AT_accessibility DW_AT_private
> DW_AT_name "FField"
> 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 "MyProp"
> 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 "MyOtherProp"
> DW_AT_name "PropFromField"
> DW_TAG_property_getter
> DW_AT_property_forward <ref to FField>
> DW_AT_property_forward <ref to PrivateField>
> > DW_TAG_subprogram
> DW_AT_name "GetFoo"
> DW_AT_name "GetValue"
> ... > > DW_TAG_property
> DW_AT_name "Foo"
> DW_AT_name "Indexed"
> > DW_TAG_property_getter
> DW_AT_property_forward <ref to GetFoo>
> DW_AT_property_forward <ref to GetValue>
>
> DW_TAG_formal_parameter ; _this (no default specified, details inherited from GetFoo
> 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 ---
2024-05-07: [Original proposal][orig].
2024-10-12: Revised after online discussion.
2024-10-12: [Revised][diff1] after online discussion. 2025-01-03: [Revised][diff2] with updated examples and Chapter 7 changes.