Hello Martin,
sorry for the long delay for getting back to you. The DWARF committee was on
hiatus over the summer but we're resuming regular meetings now and I would like
to prepare this issue for discussion now.
I have tried to remove everything from the proposal that could be considered an
implementation detail of the Pascal compiler. DWARF tries to be descriptive,
and not prescriptive in its approach so I'm intentionally leaving freedom for
languages to pick the right representation using the framework specified in the
standard. Below is my suggestion of what the wording could look like.
The wording I chose would also work with Objective-C and Swift properties. To
fully represent Objective-C properties we also need the
DW_AT_APPLE_property_attribute extension to encode language-specific flags, but
I think I'd fine with just keeping this as an extension for now.
Please let me know if I am missing any important use-cases that you could not
describe in the Pascal compiler following this specification, if there are any
mistakes in it, or if there are Pascal-specific details we should really move
into the DWARF spec itself instead of leaving them as an implementation detail
to the compiler/debugger.
thanks,
Adrian
PS: One thing I left out is DW_AT_Property_Object. It wasn't clear to me why
this wouldn't always be the address of the parent object of the DW_TAG_property.
# 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 has 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_specification` attribute to
point to a (member) function declaration. They may also have
`DW_TAG_formal_parameter` children 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 the object. In such cases the `DW_AT_specification` attribute of the
accessor entry may point to the `DW_TAG_member` entry of the field that holds
the properties underlying storage.
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 <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_TAG_property_getter
DW_AT_specification <ref to GetProp>
DW_TAG_property_setter
DW_AT_specification <ref to SetProp>
DW_TAG_property
DW_AT_name "MyOtherProp"
DW_TAG_property_getter
DW_AT_specification <ref to FField>
DW_TAG_subprogram
DW_AT_name "GetFoo"
...
DW_TAG_property
DW_AT_name "Foo"
DW_TAG_property_getter
DW_AT_specification <ref to GetFoo>
DW_TAG_formal_parameter ; _this (no default specified, details
inherited from GetFoo
DW_TAG_formal_parameter
DW_AT_default_value <DW_OP_lit 1> ; property index
DW_TAG_formal_parameter ; x (no default specified)
```
--
Dwarf-discuss mailing list
[email protected]
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss