On 22/06/2024 23:22, Adrian Prantl via Dwarf-discuss wrote:
2) DW_TAG_Property_Default
"default value" of a property.
property Foo: integer read FFoo default 1;
// In Pascal, there is no semicolon before "default" for this.
...
Here I think it would be appropriate to use DW_AT_default_value (the new
variant defined in https://dwarfstd.org/issues/141117.1.html
<https://dwarfstd.org/issues/141117.1.html> that takes an arbitrary string).
Yes, that should work.
> - What is the purpose of DW_TAG_Property_Stored?
> Maybe also add an example for this.
The DW_TAG_Property_Stored is used in a similar fashion as default.
But provide just a boolean.
It is also accessible via RTTI. It can be a constant but often is a
function.
property Foo: integer read FFoo stored GetFooStored;
If the properties value is only meaningful when the object is in a
specific state, then GetFooStored could return true/false depending on
that state.
E.g. if a RGBA color has a flag "Solid", then when it is solid, it
needs no alpha channel. The object may not want the unused alpha value
to appear in a stream. It could then implement a stored-function for
the Alpha property.
Interesting, am I misunderstanding or does Pascal use the exact inverse
nomenclature that Swift uses
(https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/ <https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/>)?
In Swift a stored property is one that is backed by a field in the
record, and a computed property is value produced by a function. It
sounds like in Pascal it's the exact opposite? Or does "stored function"
mean something different?
It is something different.
In Pascal the storage/computed depends on the getter/setter.
`property Foo: integer read _Field_Foo_ write _Field_Foo_;`
`property Bar: integer read _Function_Get_Bar write _Function_Set_Bar;`
It can also be mixed, i.e. a getter reading a field, and a setter
calling a function.
"stored" is an additional value/function associated with the property
(and does not depend on the presence of a field).
```
property Some integer
read _Function_Get_Some
write _Function_Set_Some
stored _Function_Some_IsStored; // should be stored
```
It does not affect setting/getting the value itself.
It is (can be) used when the data is streamed (e.g. ToJson, ToXml, ...).
The code that does the streaming can call the function, and then omit
the field from the resulting json or xml.
> - DW_TAG_Property_Argument_List would also benefit from an example.
The current use case would be several properties using the same getter.
Each property has an "index" (not the array-like index sorry another
naming conflict, will call this one "property-index").
```
class TMyClass
function GetProp(AIndex: Integer): integer;
property MyProp1: integer index 1 read GetProp;
property MyProp2: integer index 2 read GetProp
end;
class TMyOtherClass
function GetOtherProp(a: boolean; AIndex: Integer): integer;
property MyProp1[a:integer]: integer index 1 read GetOtherProp;
property MyProp2[a:integer]: integer index 2 read GetOtherProp;
end;
```
The property-index is passed as one of the arguments to the function.
Oh interesting, so here you declare on getter that handles multiple
properties and the language provides syntax for passing fixed or dynamic
arguments to that function. Yes, this will need special support in the
form of a custom Tag/Attribute. I'll think about this some more, but it
might be nice to come up with a representation that also works for other
languages that allow an arbitrary function to be used as a getter/setter
(like Objective-C) and maybe it can be combined with the existing
DW_AT_default_value, to represent the property index, but I'm not sure
about the subscript index.
I probably misread the above (if it is "putting the values as defaults
in the function itself). Probably not what you meant, as your example
further down does seem to keep them in the property.
As the function should be able to be specified by referring an existing
function, that function can already have defaults for its parameters.
Those would not be used, if invoked for the property.
```
TMyClass
function GetFoo(AnIndex: integer): char;
property Foo: char index 1 read GetFoo;
```
Accessing the property will call GetFoo. But code can call the function
directly too (and then the function params could benefit from defaults).
DW_TAG_Property
DW_AT_Name : "MyProp1"
DW_AT_Type : <...>
DW_TAG_Property_Getter
DW_AT_Property_Forward : reference to L1
Any reason not to use DW_AT_specification for this?
DW_AT_specification should be fine.
DW_TAG_Property_Argument_List
DW_AT_Property_Argument_Number : 1
! DW_TAG_formal_parameter at pos 1 "AIndex"
DW_AT_Property_Argument_Value : 1 ! the index value
We may be able to reuse a sequence of DW_TAG_format_parameter with
DW_AT_default_value here to avoid introducing multiple specialized
tags/attributes.
Yes, that would work.
In this case we can skip specifying the index/pos, if instead we can
give special "default values" for:
- _this (or the _this parameter is never in the list, and always
allocated following calling conventions)
- new value for setter
- user specified array-like-index values
(allow reordering by specifying the index in the user given list?)
```
function GetFoo(x: word; AIndex: Integer): char;
property Foo[x: word]: char index 1 read GetFoo;
```
```
DW_TAG_Property_Getter
DW_AT_Property_Forward : reference to L1
DW_TAG_format_parameter
DW_AT_default_value : <special _this>
DW_AT_default_value : constant 1 ! property index
DW_AT_default_value : <special user array index>
```
For some basic cases, there could be language specific defaults listed
in the dwarf spec. So the list can be omitted.
> - If I understand correctly, the purpose of DW_AT_Property_Forward
> is to reference a getter or setter DW_TAG_subprogram.
> Is there a specific reason you decided for this representation
> over nesting a DW_TAG_subprogram with a DW_AT_property_getter
(true) inside the DW_TAG_property?
Actually it can refer any other (non-property) member of an object.
(function, member, or variable (static member).
Or for properties outside a class, it can refer a function or variable.
I see, so it needs to be a DIE reference. We might be able to reuse
DW_AT_specification for this purpose though.
Yes, same as in the example above.
--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss