[Dwarf-Discuss] data-location containing "DW_OP_push_object_address / DW_OP_deref" if the variable could be in memory or register

2021-10-24 Thread Martin via Dwarf-Discuss
The problem was already described here 
http://lists.dwarfstd.org/pipermail/dwarf-discuss-dwarfstd.org/2005-April/002844.html

But the replies in that thread only answered the case for DW_AT_frame_base


However, if you have a data-type like described

- At "Address of variable": e.g. pointer to 0x1234
- At 0x1234: some data, e.g. a structure or array

Note, that the address of the variable can not be 0x1234, as taking the 
address of the variable "&var" should return a pointer to the first block.


The variable can have a DW_AT_location
- that is an address in memory
- the name of a register
- a location list, that returns sometimes an address,
  sometimes a register

In order to access data at 0x1234, the data type would have an 
DW_AT_data_location like:

  DW_OP_push_object_address, DW_OP_deref, ...
(maybe followed by an adding an offset or other OPs)

But that only works for memory locations. (at least various emails on 
the list suggest this)



How can such a type be represented?

Since DW_OP_push_object_address is documented

The DW_OP_push_object_address operation pushes the address of the object
3 currently being evaluated


it would be good if DW_OP_deref would always work.

DW_OP_regN

The DW_OP_reg operations encode the names of up to 32 registers,
8 numbered from 0 through 31, inclusive. The object addressed is in register n


The last sentence can be read that this is "the address" of that register.

If so, then maybe DW_OP_deref should be documented to fetch the value in 
the register.


The above example also illustrates why the register-content should be 
the result of the dereferencing, as it leads to the same final address 
(and that is correct if it is the same variable to start with)



And there is more:
The part of the variable data that is 0x1234 could be stored across 
several registers. Then the DW_AT_location of the variable would contain 
several DW_OP_piece.


There is an example that gives some clue what should happen, if a 
DW_AT_location returns a value like this.

Page 291 (Dwarf 5)

DW_OP_lit1 DW_OP_stack_value DW_OP_piece 4 DW_OP_breg3 0 DW_OP_breg4 0
1110 DW_OP_plus DW_OP_stack_value DW_OP_piece 4
The object value is found in an anonymous (virtual) location 


So DW_OP_piece also returns a location (albeit a virtual one). That 
could then also be dereferenced by DW_OP_deref (or maybe it already can?).


IMHO, that should be explicitly clarified. Or alternatives should be given.


** Actual real world example.

FPC (Free Pascal) has several types, that have such an hidden pointer. 
(AnsiString (array of char), dynamic array, objects)


The "pointer part" is being passed around as the variable (e.g. as a 
function parameter, or on assignment).
All variables that have the same value in the "pointer part" share the 
same data in the "pointed to part".


So the pointer-part could be ending up in a register. But the type must 
still be able to describe the data location.

___
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org


Re: [Dwarf-Discuss] data-location containing "DW_OP_push_object_address / DW_OP_deref" if the variable could be in memory or register

2021-10-28 Thread Martin via Dwarf-Discuss

On 27/10/2021 17:34, John DelSignore wrote:

One of the key concepts in the extensions, which I think addresses the 
problem you described, is to make locations (memory, register, 
composite, implicit, and undefined) first-class objects that can be 
pushed onto the DWARF evaluation stack.


Certainly relates to the problem. I would have just called them all 
"address" in different address spaces.


Register already have ordinal/numeric "addresses". They just do not 
point to memory.


But yes, given its a "location expression" the word "location is better.

Dwarf5 itself introduces this (as I pointed out) in its examples

There is an example that gives some clue what should happen, if a
DW_AT_location returns a value like this.
Page 291 (Dwarf 5)

DW_OP_lit1 DW_OP_stack_value DW_OP_piece 4 DW_OP_breg3 0 DW_OP_breg4 0
1110 DW_OP_plus DW_OP_stack_value DW_OP_piece 4
The object value is found in an anonymous (virtual) location


However, it does not allow such a location to be DW_OP_deref.

And that is the real pity. Because a member or data location, now only 
works, if the new address is stored in memory.
But if a register contains a pointer, then the location of that register 
can not be dereferenced to the memory location described by that pointer.


That is, to be exact: There is no single expression that can take a 
memory OR register location, and deref them.


And at minute 3:02:05 they add exactly that extension:
Allow DW_OP_deref to take any location. And make the content of that 
location an address pointing to memory.




making a location the /result/ of an evaluation, locations can be 
pushed, popped, and operated on just like addresses and values in the 
current model.


If locations can not get on the stack at all currently then what does 
the following do?


- variable DW_AT_Location: DW_OP_reg1
- type DW_AT_data_location:  DW_OP_push_object_address

What is now on the stack of the DW_AT_data_location?
I would have thought it is the register-location.
Meaning that the DW_AT_data_location can do no useful operation at all.

And the same applies for DW_OP_piece appearing in DW_TAG_location, which 
is a virtual location and can not be processed into anything.



The problem is, that you need a different expression in 
DW_AT_data_location, depending if a pointer is stored in memory or register.
Changing the DW_at_location, to return the register value, instead of 
location, will not work either.


-
Hoping that more debuggers adapt to the new DW_OP_deref I can use 
exactly that. And it will work fine.

But then maybe it should be made part of the DWARF spec?


Personally I think DW_AT_location should always return a location.
E.g. DW_OP_stack_value should be a virtual location. (afaik that would 
not even break anything)


Btw the DWARF5 says "DW_OP_stack_value operation" but contradicts this 
in the examples.


If locations are used like this, then it needs to be defined which 
operations can deal which with type of location.


E.g. DW_OP_deref would always take the value at the location, and treat 
it as an address (memory location).


Other ops can be decided when/if needed.






___
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org


[Dwarf-discuss] Question on "pascal property"

2024-05-01 Thread Martin via Dwarf-discuss

Hello,

I am writing the below to see if any of this might be of interest to add 
new tags/attributes to the Dwarf spec.


If not, or for the parts for which it is a no, then I am happy to use 
vendor extensions.



In Pascal there is a construct called property. 
https://www.freepascal.org/docs-html/ref/refse27.html


To the user (and to any code accessing it, it behaves like a variable in 
that it can be read or assigned too. But it can not have its address 
taken. (The last bit may be ignorable for the rest of this email)


In the most basic form it provides a setter and getter, which can either 
be a field or method. Setter and getter are always references to 
existing fields/methods.


In order to describe this to a debugger, I can see 2 features that could 
be added to dwarf



1) Probably a new DW_TAG_PROPERTY

Albeit, it might be possible to sub-divide existing DW_TAG_Variable / 
DW_TAG_Member into sub-sections, but I don't think that is advisable.


The tag could then be sub-divided, as it needs the same info for 
different accessors. DW_TAG_PROPERTY_ where  is


- "reader" => description on how to get the value
- "setter" => description on how to write the value
- "default" => how to get the default value, if one exsits
- "stored" => information if this value should be serialized, if the 
object is serialized (may depend on its vaule, can be a function)

- user/other

Alternatively to dividing it into accessor tags, there could be just 
attributes for each method of access. Then however the below idea to 
allow direct variable/member tags will not work.



The property would also be able to have attributes directly (not in sub 
sections), like virtuality.


And it could be without sub-sections, if it just changed virtuality. 
This is common in Pascal, that a sub-class makes an inherited property 
more visible.



Maybe There would be the question, if existing variable/member could 
benefit from any of that information. (I don't know a case were it would 
be needed). If there was, then the variable/member would be encoded as 
it currently is, but a DW_TAG_PROPERTY_WRITE[R] could be added, to 
override the handling of how it is written. Just a thought.



2) Forwarding to the existing member/method/function

As indicated in Pascal the getter/setter are always a reference to an 
existing field/getter. Though defaults/stored can be a constant too.
And to make it more flexible, it might be considered to allow embedding 
DW_TAG_Variable / DW_TAG_Member directly?


In Pascal the reference can be
- reference to a field or method
- references to a field or method in a different object (needs 
specification of the target obj)

- reference to a function (not part of an object/structure)

So the accessors could have a simple tag

For forwarding the would need a new DW_AT_FORWARD or DW_AT_ALIAS (better 
names may exist) attribute.


References already exist. But they only reference the TAG describing the 
value. They can't hold an object (e.g. for DW_OP_push_object_address).


So there would also be the need for DW_AT_FORWARD_OBJECT.

I don't know if there are cases where such an ref-with-object would be 
interesting to existing encoding (such as when a ref is used to get the 
bounds of an array)




If the forwarder is to a function, then there is a need to know how to 
call it. For a getter a function (or method, only taking the _this 
instance), the "how to call" is implicit.


For a setter, there needs to be an extra argument, to pass the value. 
This could be implicit, if it is the only argument (other than maybe _this).



Pascal has properties, that can share a getter and share a setter. The 
getter/setter then takes an index (of any type).

For this a description would be needed, how to call the function.

DW_TAG_CALL_ARGUMENT_LIST with a list of DW_AT_CALL_ARGUMENT. (that 
could be const, ref, expr), or Special values for _this and for "the 
value".


--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Question on "pascal property"

2024-05-02 Thread Martin via Dwarf-discuss

On 01/05/2024 23:46, Adrian Prantl wrote:
Just a quick very general remark: For Objective-C, Clang (and presumably 
also GCC) are producing a couple of property-related attributes in the 
DW_AT_APPLE extension space


https://github.com/llvm/llvm-project/blob/505f6da1961ab55c601d7239648c53ce863b5d70/llvm/include/llvm/BinaryFormat/Dwarf.def#L630
 


maybe these are useful for you. I also wouldn't be opposed to 
standardizing a more generally useful mechanism for properties; we could 
potentially also find use for them in the Swift compiler.





Thanks for the link.

HANDLE_DW_AT(0x3b11, BORLAND_property_read, 0, BORLAND)
HANDLE_DW_AT(0x3b12, BORLAND_property_write, 0, BORLAND)
HANDLE_DW_AT(0x3b13, BORLAND_property_implements, 0, BORLAND)
HANDLE_DW_AT(0x3b14, BORLAND_property_index, 0, BORLAND)
HANDLE_DW_AT(0x3b15, BORLAND_property_default, 0, BORLAND)

Those are certainly matching most of what FreePascal has (same 
underlying language). I will try and find how they are implemented.



So with the APPLE extensions and this, there are probably two concurrent 
ways already.


--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Question on "pascal property"

2024-05-03 Thread Martin via Dwarf-discuss
I had a look at the Apple properties extension. There is also a Borland 
one, but for that I could not find anything beyond just the names.


The apple one bears some similarities. There documentation is here
https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#debugging-information-format-1

I don't have any Objective-C experience myself, but briefly consulted 
with someone who has.


1) ObjC apparently always has an "ivar" (field) - Pascal may not have one
2) In ObjC the "ivar" refers to the property - For Pascal the opposite 
direction would be desirable (though of course a debugger could perform 
a backward search)
3) InObjC getter and setter attributes are strings => Apparently the 
given names are used for some dispatch call. In Pascal getter/setter 
should have to be either -field, -procedure/function (no oop), 
-method(oop), -method on different object


There are a few other things to be added for Pascal.

.

Then next is the question, how to start an attempt to get it standardized?

What to submit and where?

How specific/generic should the specs be?

E.g. the above Apple extension appears to rely on the debugger knowing 
it is ObjC, and the debugger knowing how to invoke the dispatch (well, 
that is from what I understood on my brief consultation).

Adding a description for a getter/setter method:
- should this assume the debugger knows how to call it (where the 
parameter goes, etc)? Even if there could be different languages with 
different ways to call it?
- should it have some defaults? (e.g. where the _this param goes, 
default for the value param)
- should it give detailed instructions (describe how to compute each 
param).



I don't know the full needs properties in other languages would have. 
But some provisions could be included (and maybe someone with additional 
knowledge will join).
Like C#, properties can have their own getter/setter instead of a 
reference to an existing, so that could be accommodated.






On 01/05/2024 23:46, Adrian Prantl wrote:
Just a quick very general remark: For Objective-C, Clang (and presumably 
also GCC) are producing a couple of property-related attributes in the 
DW_AT_APPLE extension space


https://github.com/llvm/llvm-project/blob/505f6da1961ab55c601d7239648c53ce863b5d70/llvm/include/llvm/BinaryFormat/Dwarf.def#L630
 


maybe these are useful for you. I also wouldn't be opposed to 
standardizing a more generally useful mechanism for properties; we could 
potentially also find use for them in the Swift compiler.



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Question on "pascal property"

2024-05-03 Thread Martin via Dwarf-discuss

On 03/05/2024 10:08, Martin via Dwarf-discuss wrote:

Then next is the question, how to start an attempt to get it standardized?



I started on a DRAFT. (still discussing on the Pascal community, to 
ensure it comprises everything required.


I post it here for comments on the general direction and format.


# Proposal to implement "properties" for 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.

They can be read/write, read only, write only.
  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 have one or more array like indexes.
  TFoo = class
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;

  end;

Properties can share a method, and provide an index (constant) to 
identify which property called the method.

  TFoo = class
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;
  end;

Properties can be streamed  and therefore can have a default value 
(constant or via function). They can also have a "stored" value 
(function) indicating if they need to be stored in the stream.


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#

## Proposed Changes

Introducing a new tag

DW_TAG_PROPERTY or DW_TAG_PROPERTY_PASCAL
This tag can occur anywhere where DW_TAG_MEMBER can occur. It can also 
occur on a global scope.


It can have
  DW_AT_NAME
  DW_AT_TYPE
  DW_AT_ACCESSIBILITY
  DW_AT_decl_column, DW_AT_decl_file and DW_AT_decl_line.

It can then contain any of
  DW_TAG_PROPERTY_SETTER
  DW_TAG_PROPERTY_READER
  DW_TAG_PROPERTY_DEFAULT
  DW_TAG_PROPERTY_STORED

Each of them can have

  DW_AT_PROPERTY_FORWARD  reference/constant
refernce to the field or function
  DW_AT_PROPERTY_OBJECT  reference/expression/constant
the object on which the value is stored (value for 
DW_OP_push_object_address)
can be omitted for inherited classes, if it computes to the same as 
the current class


A getter (also "default" and "stored" should be a function returning the 
same type as the property. It should either take no arguments or only 
DW_AT_object_pointer
A setter should be a procedure, it should take optional 
DW_AT_object_pointer and one argument of the same type as the property.


Instead of having attributes grouped in DW_TAG_PROPERTY_SETTER/... all 
attribute could exist top level, in 4 versions. That would be shorter if 
no object needs to be specified. But it is less flexible for later 
additions.



For indexed properties the DW_TAG_PROPERTY also has
  DW_TAG_PROPERTY_INDEX_LIST
containing one or more
  DW_TAG_PROPERTY_INDEX

  DW_AT_NAME
  DW_AT_TYPE
  DW_AT_VALUE  reference or constant or expression (returning value)
  DW_AT_IS_PROPERTY_VALUE  flag

DW_AT_NAME and  DW_AT_TYPE can be optional. They can be gotten from the 
linked procedure

DW_AT_VALUE is optional. It is used when properties share a getter.

DW_AT_IS_PROPERTY_VALUE is optional. It can be used to specify the 
position of the "assigned value" in a setter. If not specified the 
assigned value will be passed as the last parametr.



To change visibility of an inherited property,
DW_TAG_PROPERTY
  DW_AT_NAME
  DW_AT_ACCESSIBILITY


OFF TOPIC:
  For C# it may be of interest to allow DW_TAG_PROPERTY_SETTER/... to 
have their own   DW_AT_ACCESSIBILITY
  For C# it may be of interest to allow an inlined function declaration 
instead of DW_AT_PROPERTY_VALUE



## References

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



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


[Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-05-07 Thread Martin via Dwarf-discuss

# 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#

## Proposed Changes

### `DW_TAG_Property` or `DW_TAG_Property_Pascal`

This tag can occur anywhere where `DW_TAG_MEMBER` can occur. It can also 
occur on a `global scope`.


It supports (at least) the following existing attributes:
* DW_AT_Name
* DW_AT_Type
* 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.
* ... others from the var/member tags, except for actual value or 
location of value


It will support the following new attributes
* DW_AT_Default_Property flag
  Specify this is a default property
* DW_TAG_Property_Setter
* DW_TAG_Property_Reader
* DW_TAG_Property_Default
* DW_TAG_Property_Stored

### `DW_TAG_Property_[Setter|Getter|...]`

Specifies how the property is accessed for read/write and other access.

 Reference to a field/var/function.

* DW_AT_Property_Forward  reference/constant
  A reference to an existing the field or function.
  * This could be a constant for the reader/default/stored accessors.
  * This could be a string to support the current 
`AT_APPLE_property_setter` extension


* DW_AT_Property_Object  reference/expression/constant
  The object on which the value is stored (value for 
`DW_OP_push_object_address`). This can be omitted for inherited classes, 
if it computes to the same address as the current class.


* DW_TAG_Member, DW_TAG_Variable, DW_TAG_subprogram.
  For inlining the accessor. E.g. subprogram for C#

The referenced element must have the same `DW_AT_Type` as the property. 
Except for "stored" which should be boolean.


 function parameters

* A getter should
  * take one parameter, which is the _this value of the object. For 
global properties no parameters are given

* A setter should
  * take _this as the first parameter (except for global properties)
  * the `value` as the 2nd parameter.

For shared/indexed properties the order of parameters should default to
* _this
* indexes from array-like access
* the `value` (setter only)

For the **shared getter/setter index** the value of the argument must be 
specified. For this the list of arguments to a getter/setter can be 
specified.

* DW_TAG_Property_Argument_List
* containing a list of DW_TAG_Property_Argument
* each having the following attributes.
  * DW_AT_Property_Argument_Number
zero-based number of the function parameter for which a value is given
  * DW_AT_Property_Argument_Value  reference or constant or expression 
(returning value)

The value that should be passed

For the position of the `value` in the parameter list
* DW_AT_Property_Value_Argument_Number const/expression

The values for _this, array-index and value (if not specified) are 
passed to the function remaining parameters.



 Other attributes for getter/setter/default/stored

The following attributes should be allowed in 
DW_TAG_Property_[Setter|Getter|...] to overwrite value given in the 
DW_TAG_Property

* DW_AT_Accessibility
* DW_AT_external
* DW_AT_virtuality
* DW_AT_start_scope

### Other usage forms of DW_TAG_Property

To change accessibility (private/public) of a property in an inherited 
class, DW_TAG_Property will be specified with just a name and accessibility.

```
DW_TAG_PROPERTY
  DW_AT_NAME
  DW_A

Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-05-08 Thread Martin via Dwarf-discuss

On 08/05/2024 06:34, Cary Coutant via Dwarf-discuss wrote:

It will support the following new attributes
* DW_AT_Default_Property flag
    Specify this is a default property
* DW_TAG_Property_Setter
* DW_TAG_Property_Reader
* DW_TAG_Property_Default
* DW_TAG_Property_Stored

### `DW_TAG_Property_[Setter|Getter|...]` 



Should these all be DW_AT_xxx?



No, they should have been a separate list "It will have the following 
new tags"


As the next big header "### `DW_TAG_Property_[Setter|Getter|...]`" 
shows, they each contain several attributes.


Maybe, it would be clearer, if they were moved into the next header, but 
then it needs to be clarified that they are children of the DW_Tag_Property.


--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-05-08 Thread Martin via Dwarf-discuss

Here are 2 examples of what it would look like

## Property with different visibility

```
  type
TFoo = class
private
  MyMember: integer;
  function MyFunc: integer;
protected
  // "read public" is currently from oxygene, but may be added to 
FreePascal

  property MyProp: integer read public MyFunc write MyMember;
end;

TBar = clall(TFoo)
public
  property MyProp; // elevate to public
end;
```

```
  DW_TAG_Structure_type
DW_AT_Name :  "TFoo"
L1:
DW_TAG_Member
DW_AT_Name:  "MyMember"
DW_AT_Type:  <...>
DW_AT_Member_location :  <...>
L2:
DW_TAG_subprogram
DW_AT_Name:  "MyFunc"
DW_AT_Type:  <...>

DW_TAG_Property
DW_AT_Name :  "MyProp"
DW_AT_Type :  <...>
DW_AT_Accessibility:  DW_ACCESS_protected
DW_AT_Default_Property :  TRUE
  DW_TAG_Property_Getter
  DW_AT_Property_Forward :  reference to L2
  DW_AT_Accessibility:  DW_ACCESS_public
  DW_TAG_Property_Setter
  DW_AT_Property_Forward :  reference to L1

  DW_TAG_Structure_type
DW_AT_Name :  "TBar"
DW_TAG_Inheritance
<...>
DW_TAG_Property
DW_AT_Name :  "MyProp"
DW_AT_Accessibility:  DW_ACCESS_public
```

## Property with access to nested field


```
  type
TFoo = class
  OtherData: DWORD;
  FNested: record
MyMember: integer;
  end;
  property MyProp: integer read FNested.MyMember;
end;
```

```
L1:
  DW_TAG_Structure_type
L2:
DW_TAG_Member
DW_AT_Name:  "MyMember"
DW_AT_Type:  <...>
DW_AT_Member_location :  <...>! inside FNested

  DW_TAG_Structure_type
DW_AT_Name :  "TFoo"
DW_TAG_Member
DW_AT_Name :  "OtherData"
DW_TAG_Member
DW_AT_Name :  "FNested"
DW_AT_Type:  reference to L1
DW_AT_Member_location :
  DW_OP_plus_uconst 4 ! where 4 == offset of 
MyMember in the instance data


DW_TAG_Property
DW_AT_Name :  "MyProp"
DW_AT_Type :  <...>
  DW_TAG_Property_Getter
  DW_AT_Property_Forward :  reference to L2
  DW_AT_Property_Object  :
  DW_OP_push_object_address  ! maybe should be on stack by 
default
  DW_OP_plus_uconst 4! where 4 == offset of 
MyMember in the instance data
 ! There could be several 
levels of nesting, so that expression could be more complex

```

In the example the property does not have a reference to FNested itself. 
All it needs is the object_address of FNested, so it can calculate the 
location of the referenced field MyMember (using the member_location).



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-05-08 Thread Martin via Dwarf-discuss

Small correction

  property MyProp: integer read public MyFunc write MyMember;

Should be
  property MyProp: integer read public MyFunc write MyMember; default;

As I added the  DW_AT_Default_Property flag in the example.
In FreePascal, this would currently only be valid for properties with 
array-indexes, but may be extended in future. For the example it just 
shows where the attribute would go.




On 08/05/2024 12:35, Martin via Dwarf-discuss wrote:

Here are 2 examples of what it would look like

## Property with different visibility

```
   type
     TFoo = class
     private
   MyMember: integer;
   function MyFunc: integer;
     protected
   // "read public" is currently from oxygene, but may be added to 
FreePascal

   property MyProp: integer read public MyFunc write MyMember;
     end;

     TBar = clall(TFoo)
     public
   property MyProp; // elevate to public
     end;
```

```
   DW_TAG_Structure_type
     DW_AT_Name :  "TFoo"
L1:
     DW_TAG_Member
     DW_AT_Name    :  "MyMember"
     DW_AT_Type    :  <...>
     DW_AT_Member_location :  <...>
L2:
     DW_TAG_subprogram
     DW_AT_Name    :  "MyFunc"
     DW_AT_Type    :  <...>

     DW_TAG_Property
     DW_AT_Name :  "MyProp"
     DW_AT_Type :  <...>
     DW_AT_Accessibility    :  DW_ACCESS_protected
     DW_AT_Default_Property :  TRUE
   DW_TAG_Property_Getter
   DW_AT_Property_Forward :  reference to L2
   DW_AT_Accessibility    :  DW_ACCESS_public
   DW_TAG_Property_Setter
   DW_AT_Property_Forward :  reference to L1

   DW_TAG_Structure_type
     DW_AT_Name :  "TBar"
     DW_TAG_Inheritance
     <...>
     DW_TAG_Property
     DW_AT_Name :  "MyProp"
     DW_AT_Accessibility    :  DW_ACCESS_public
```

## Property with access to nested field


```
   type
     TFoo = class
   OtherData: DWORD;
   FNested: record
     MyMember: integer;
   end;
   property MyProp: integer read FNested.MyMember;
     end;
```

```
L1:
   DW_TAG_Structure_type
L2:
     DW_TAG_Member
     DW_AT_Name    :  "MyMember"
     DW_AT_Type    :  <...>
     DW_AT_Member_location :  <...>    ! inside FNested

   DW_TAG_Structure_type
     DW_AT_Name :  "TFoo"
     DW_TAG_Member
     DW_AT_Name :  "OtherData"
     DW_TAG_Member
     DW_AT_Name :  "FNested"
     DW_AT_Type    :  reference to L1
     DW_AT_Member_location :
   DW_OP_plus_uconst 4 ! where 4 == offset of 
MyMember in the instance data


     DW_TAG_Property
     DW_AT_Name :  "MyProp"
     DW_AT_Type :  <...>
   DW_TAG_Property_Getter
   DW_AT_Property_Forward :  reference to L2
   DW_AT_Property_Object  :
   DW_OP_push_object_address  ! maybe should be on stack by 
default
   DW_OP_plus_uconst 4    ! where 4 == offset of 
MyMember in the instance data
  ! There could be several 
levels of nesting, so that expression could be more complex

```

In the example the property does not have a reference to FNested itself. 
All it needs is the object_address of FNested, so it can calculate the 
location of the referenced field MyMember (using the member_location).





--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


[Dwarf-discuss] Question on DW_AT_low_pc for "repeated" DW_TAG_subprogram

2024-05-16 Thread Martin via Dwarf-discuss
If a compiler adds a DW_TAG_subprogram for a routine from a different 
compilation unit ...

Maybe because
- the other CU has no debug info
- The compiler does not support referencing cross CU

Would there be any reason why the compiler would not be allowed to 
include a  DW_AT_low_pc  for that routine (if the compiler has the address)?


In the concrete example the compiler in question (on some platforms, due 
to afaik linker restrictions) repeats any structure definitions from 
other CU, if they are needed as base classes for inheritance). But that 
is just background on why (afaik) this situation exists.


The only such reason that I can find (if I didn't miss any) is in 
chapter 3.3.3 on "subroutine declaration". The complier in question does 
not add a DW_AT_declaration though.


> 3.3.3 Subroutine and Entry Point Locations
> ...
> A subroutine entry representing a subroutine declaration that is not 
also a definition does not have code address or range attributes.



If such a "repeated" subroutine would somehow fall into that category, 
how could the routines address be communicated to the debugger?


--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Question on DW_AT_low_pc for "repeated" DW_TAG_subprogram

2024-05-16 Thread Martin via Dwarf-discuss

On 16/05/2024 18:46, David Blaikie via Dwarf-discuss wrote:
On Thu, May 16, 2024 at 7:10 AM Martin via Dwarf-discuss 
<mailto:dwarf-discuss@lists.dwarfstd.org>> wrote:


If a compiler adds a DW_TAG_subprogram for a routine from a different
compilation unit ...
Maybe because
- the other CU has no debug info
- The compiler does not support referencing cross CU


None that I can think of.

This happens in some cases in more normal situations - such as concrete 
definitions of inline functions - you'd have multiple CUs with 
subprograms that describe the same function definition, with low/high pc.


In the "doesn't support cross-CU references" - I'd expect in that case 
to only produce a subprogram declaration (eg: if you need a call_site 
for a call to a function defined in another object file). In the first 
case (other CU has no debug info) yeah, theoretically, I guess, maybe 
you'd want to produce debug info for the thing you didn't define.


But generally my understanding is producers don't do that.


Thanks for the answer, but I am not quite sure how to interpret it.

"None that I can think of" => So, it would be ok for a producer to add a 
DW_AT_low_pc ?


But
- "producers don't do that" => It would not be ok?
- "only produce a subprogram declaration" => not ok

If there is code (with debug info) that uses a class/struct that is 
defined in a unit with debug info (or at least a base class is in such a 
unit), then IMHO the debugger should be able to show the entire 
structure, including fields/methods from that unit without debug info. 
(because only the type is in the other unit, but the variable itself is 
in a unit with debug info).


For that, the declaration of that class can be repeated. But if the user 
then wants to call (from the debugger) a function on that (base-) class, 
then it needs the DW_AT_low_pc?


What is the recommended way for the producer to supply this?


About your answers regarding the linking, I will keep that in mind, when 
discussing it with the others involved.
For info, my background is on implementing the debugger. The compiler is 
done by others. But obviously both ends need to work together.


Thanks
Martin
--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Question on DW_AT_low_pc for "repeated" DW_TAG_subprogram

2024-05-16 Thread Martin via Dwarf-discuss

On 16/05/2024 21:58, Martin via Dwarf-discuss wrote:



If there is code (with debug info) that uses a class/struct that is 
defined in a unit with debug info (or at least a base class is in such a 


Tiny but important mistake..., it meant to write

 uses a class/struct that is defined in a unit *WITHOUT* debug info


unit), then IMHO the debugger should be able to show the entire 
structure, including fields/methods from that unit without debug info. 
(because only the type is in the other unit, but the variable itself is 
in a unit with debug info).


For that, the declaration of that class can be repeated. But if the user 
then wants to call (from the debugger) a function on that (base-) class, 
then it needs the DW_AT_low_pc?


What is the recommended way for the producer to supply this?



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Question on DW_AT_low_pc for "repeated" DW_TAG_subprogram

2024-05-22 Thread Martin via Dwarf-discuss

On 20/05/2024 22:34, David Blaikie via Dwarf-discuss wrote:
On Thu, May 16, 2024 at 1:05 PM Martin via Dwarf-discuss 
<mailto:dwarf-discuss@lists.dwarfstd.org>> wrote:


On 16/05/2024 21:58, Martin via Dwarf-discuss wrote:

 >
 > If there is code (with debug info) that uses a class/struct that is
 > defined in a unit WITHOUT debug info (or at least a base class is
 > in such a 
 > unit), then IMHO the debugger should be able to show the entire

 > structure, including fields/methods from that unit without debug
info.
 >
 > For that, the declaration of that class can be repeated. But if
the user
 > then wants to call (from the debugger) a function on that (base-)
class,
 > then it needs the DW_AT_low_pc?


Oh, perhaps the easier thing is to address this question directly.

I believe this is done with existing producers and consumers by having 
the DW_AT_linkage_name attached to the function declaration. Hmm, just 
tried with GDB and even if I omit the linkage name, it's able to call 
the function - I guess by using the DWARF it has, and searching the 
mangled names of the symbols, it can demangle them and match them up (or 
create a mangled name from the DWARF to match that up - though that 
might fail in some cases where the DWARF doesn't have enough info to 
produce the matching mangled name) and it knows the return type and can 
decode the bits to render them correctly.


So, there's a couple of options at least.



Many thanks.

That gives indeed a couple of working options.



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


[Dwarf-discuss] Question: Clarification for DW_AT_string_length

2024-05-22 Thread Martin via Dwarf-discuss
DW_AT_string_length is described as "that provides the value of the 
length of the string"


Is that the length in characters or bytes?

That matters for e.g. Utf-16 when the DW_TAG_base_type for the char has 
a DW_AT_byte_size of 2 (or more).




Below is from the draft for DWARF-6, but the same info is in earlier 
versions.



5.11 String Type Entries
 The string type entry may also have a DW_AT_string_length attribute whose
 value is either (a) a reference (see Section 2.19) to another debugging 
information
 entry that provides the value of the length of the string, or (b) a location
 description yielding the location where the length of the string is stored in 
the
 program. If the DW_AT_string_length attribute is not present, the size of the
 string is assumed to be the amount of storage that is allocated for the string 
(as
 specified by the DW_AT_byte_size or DW_AT_bit_size attribute)


--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


[Dwarf-discuss] Proposal: add DW_AT_lower_bound to DW_TAG_string_type

2024-05-22 Thread Martin via Dwarf-discuss



# Proposal to add DW_AT_lower_bound to DW_TAG_string_type

## Background

Pascal normally use 1-based indexes for strings. But it can also 
generate strings with a 0-based index.


Other languages may have varying defaults.

For a debugger to show the result of an expression like
  `MyString[5]`
the start value of the index is needed.


## Proposed Changes

1. Allow DW_AT_lower_bound as an attribute in DW_TAG_string_type.

2. Define a list of language specific defaults (as exists for subrange 
low bounds)


The default for DW_LANG_Pascal83 should be `1`

## References

http://docwiki.embarcadero.com/RADStudio/Athens/en/Zero-based_strings_(Delphi)
Also supported by FreePascal
--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-06-20 Thread Martin via Dwarf-discuss

Sorry for the late reply. I've been away.

> - What does it mean for a property to be default? I couldn't find that
> defined in the linked FreePascal documentation.

The property can be accessed without its name being specified.

This currently exists for (array-like) indexed properties.

`   property Foo [AnIndex: TSomeType]: TPropType read GetVal; default;`

If variable Bar is of a type having above property, then instead of
  `Bar.Foo[SomeVal]`
The code/expression can read
  `Bar[SomeVal]`

Bar as on object itself does not have an index. So by giving an index it 
is clear that the expression accesses the property.


Currently this is limited to array-like properties. There are some ideas 
to extend this, but nothing concrete.
The determination, if an expression accesses a "default property" does 
not belong to the DWARF specs, it has to be done by a language specific 
expression parser.


Also right now, only one indexed property can be marked default, but 
this may get extended. Multiply properties with different index-types 
could be each default.



> - Why is there both a DW_AT_Default_Property and
> a DW_TAG_Property_Default?

1) DW_AT_Default_Property
Above "default property".

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.

The latter can (in Pascal) be accessed via Run-Time-Type-Information. It 
is e.g. used in streaming of objects.
The property can be omitted from the stream, if it has its default 
value. Or when reading a stream, the default value will be assigned, if 
no value is present in the stream.
The compiler only generate the RTTI. Streaming can be implemented by the 
user, but the RTL provides functionality using the "default" as described.


On 2nd thought: I don't know if (or in which form) such info exists in 
other languages. And the amount/kind of such info available may be 
subject to change. I included it, as default-value and stored (below) in 
Pascal are commonly used. But there is room to discuss them as an 
extension (and possible more generic: some form of attributes that can 
be associated with any value/type)



> - 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.



> - 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.

In general, this may also be useful for other languages, if they pass 
multiple arguments to a getter/setter, and the order of arguments needs 
to be clarified.


For the above, it avoids a (probably) Pascal specific 
`DW_AT_pascal_property_index_value`.


The proposal has some notes on this in the "function parameters" section.

Example, the default parameters (without the property-index) for
- GetProp is (_this)
- GetOtherProp are (_this, a)
And setters
- SetProp is (_this, NewValue)
- SetOtherProp are (_this, a, NewValue)

The position for the value of 1 or 2 (for the property-index) must be 
specified.


Alternatively, it could be hard-specified in the DWARF spec, as a 
language specific order...

But then, there would be a need for `DW_AT_pascal_property_index_value`.
And other languages may need their own extra values.

The idea is, that having a property, it can be translated into a 
function/method call as follows:

- 'Foo.MyProp' = `Foo.MyPropGetter()`
- global/non-class: 'MyProp' = `MyPropGetter()`
- 'Foo.MyProp[1,2]' = `Foo.MyPropGetter(1,2)`

Any arguments not specified by the user (and not _this) will be given as 
a list of: argument-position / argument-value



For the classes above

```
  DW_TAG_Structure_type
DW_AT_Name :  "TMyClass"
L1:
DW_TAG_subprogram
DW_AT_Name:  "GetProp"
   

Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-06-22 Thread Martin via Dwarf-discuss

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 
 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/ )?
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 :

Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-10-13 Thread Martin via Dwarf-discuss

On 13/10/2024 00:59, Adrian Prantl via Dwarf-discuss wrote:

On Sep 30, 2024, at 1:39 PM, Martin  wrote:


On 30/09/2024 19:30, Adrian Prantl wrote:

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.


There is a construct where a property can point to an embedded structure.

type
TMyRecord = record
   a,b: integer;
end;

TMyClass = class
   FPadding: word;
   FData: TMyRecord;
   FOther: TMyRecord; // Can't use the type to search for FData
   property ValA: integer read FData.a;
end;

In that case DW_AT_Property_Forward  points to the member "a" in "TMyRecord". 
This would be a DW_TAG_Member, which would have a DW_AT_data_member_location relative to the 
structure FData address. However there is no address where MyRecord is stored.


Interesting example! In this case a DW_TAG_property_getter needs to point to the member "a" of the 
field FData specifically, so it can't be a reference to the DW_TAG_member "a" in TMyRecord. I can't 
think of a good way of preserving the access path of the field here. We could allow a DW_AT_location + 
DW_AT_type to allow a consumer to derive the value, but not the access path. In the general case (think 
something like "read FBinaryTree.left.left.right.data") we lack the expressivity to preserve which 
sub-field in the data structure, since DWARF does not encode expressions, only types.

I think it would be reasonable to allow the common case of referring to a 
top-level field via a DW_TAG_member ref, and having an arbitrary DWARF 
expression in a DW_AT_location to recover the location in all other cases.

Well, I don't think we need the "access path", as in full access path. 
As you pointed out "a" could be in a nested record of TMyRecord, but I 
can't think of any case where that access path would matter.


If we add DW_AT_Location:
- keep the normal fields in the property, including the refernce to "a"
- add DW_AT_Location to overwrite the DW_AT_data_member_location
then, yes we have all the info we need.

There is a choice to make that DW_AT_Location point directly to the data 
of the field. Or to the location of the directly enclosing object.


My original idea was to describe the location of "FData" with a location 
expression, and then the debugger still adds the 
DW_AT_data_member_location to that.


Currently directly specifying the location of the "pointed to field" is 
the simplest way.


And currently, in Pascal, the above only works for fields in a record. 
So the address of the record containing the field should never be 
needed. But if that ever is extended (or if any other language allows) 
to use a getter method from such an object, then the object address 
would be needed for the "this" parameter.
So maybe it is saver to use the DW_AT_Location to specify the address of 
that containing object?


In either case, the nested object can be different for getter/setter. So 
that additional address must given per getter/setter.

--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-10-14 Thread Martin via Dwarf-discuss

On 14/10/2024 20:56, Todd Allen via Dwarf-discuss wrote:

Playing devil's advocate here: Can you mix these two types of
properties?  That is, something like the following (please excuse any
wrong syntax):

type
TMyRecord = record
     a,b: integer;
end;

TMyClass = class
     function GetProp: TMyRecord;
     procedure SetProp(AVal: TMyRecord);
     property MyProp: TMyRecord read GetProp write SetProp;
     property MyPropA: integer read MyProp.a;
end;

That is, a read of TMyClass's MyPropA would call TMyClass.GetProp and
then return only its member a?

No, you can't. And I don't think it will be added, because then the 
location of "a" is not known at compile time. (it depends on the 
function result).


Currently the implementation is such that the compiler can compute the 
location of the final field.
That is it must be in a "record" (inlined structure), rather than a 
"class" which would have a (hidden) pointer that could be nil.


With the record, the final field is still directly known at compile 
time. And it is always there (no condition such as a nil-able pointer in 
the middle).


Currently it also only works for a field. Originally records did not 
have functions. That has changed.


However:
I am not aware of plans to allow a getter method from a record. But it 
would fulfil the condition that the compiler can resolve it at compile 
time.


So currently having the location of the final field will work for all 
existing cases.


Having DW_AT_Location point to the directly enclosing object will do the 
same. It's my personal preference, but not a big issue.


It could even be
DW_AT_Location : location of the directly enclosing object
DW_AT_data_location : location/address of the properties data
(ignore/replace the DW_AT_data_member_location)

Both may be valuable in some future scenario.



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-10-07 Thread Martin via Dwarf-discuss

On 07/10/2024 22:40, Augusto Noronha wrote:



Streaming as a language construct (and controlling whether a property should be 
streamable or not) seems like a pretty Pascal specific feature, maybe this 
could be a Pascal extension?


Or probably be moved to RTTI, of which I have not yet evaluated if it 
needs special DWARF support.


RTTI seems to exist in C++, but I haven't used it there myself. Also 
RTTI is in the end a structure of its own, and the most that DWARF may 
need if at all would be a pointer to it, but even that could be an 
artificial field.


"stored" only has a language constructs for defining it. Calling it is 
done via the fields in RTTI.


So, yes. "stored" can be dropped.






On Oct 7, 2024, at 2:23 AM, Martin via Dwarf-discuss 
 wrote:

On 04/10/2024 21:56, Augusto Noronha via Dwarf-discuss wrote:

Hi Martin,
Could you explain what a Pascal-style stored accessor is or link to a reference 
to it? I tried looking it up but couldn’t find anything relevant.




I may just have done above.

There is a hidden field in the class that points to RTTI. And in RTTI 
there is a field "pointer to function".


So you would actually not find any code that directly calls that 
function (via any language construct).


I initially went only through how the property is defined, not how it is 
used.


--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-10-07 Thread Martin via Dwarf-discuss

On 04/10/2024 21:56, Augusto Noronha via Dwarf-discuss wrote:

Hi Martin,

Could you explain what a Pascal-style stored accessor is or link to a reference 
to it? I tried looking it up but couldn’t find anything relevant.



https://www.freepascal.org/docs-html/ref/refsu38.html

FreePascal and Delphi have RTTI, which allows accessing data. One use 
case is streaming of a class (well the published part of it).


This is for example used for GUI apps where the properties of a designed 
GUI (form, buttons, ..) are streamed so the runtime can load them. But 
also ORM libs make use of it, or REST.


For classes there is a "published" section (public + RTTI).
It can contain fields and properties.
And any code, without knowledge of the class, can read those fields.

In some scenarios it is not needed to stream properties if they have 
there default value. So the streaming code needs to access that.


property Foo: integer read GetFoo write SetFoo stored ShouldStoreFoo 
default 123;


default takes a value (and exists only for certain data types like 
integer properties. It is stored in the RTTI.


Stored can be a function or field (or constant) of boolean type. The 
RTTI also has a link to it, so the streaming code can call it.


Stored = true => the property should be stored in the stream
Stored = false -> the property should not be stored

--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Proposal: Add support for "property" with getter/setter (based on Pascal properties)

2024-09-30 Thread Martin via Dwarf-discuss

On 30/09/2024 19:30, Adrian Prantl wrote:

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.


There is a construct where a property can point to an embedded structure.

type
  TMyRecord = record
a,b: integer;
  end;

  TMyClass = class
FPadding: word;
FData: TMyRecord;
FOther: TMyRecord; // Can't use the type to search for FData
property ValA: integer read FData.a;
  end;

In that case DW_AT_Property_Forward  points to the member "a" in 
"TMyRecord". This would be a DW_TAG_Member, which would have a 
DW_AT_data_member_location relative to the structure FData address. 
However there is no address where MyRecord is stored.




The proposed text IMHO covers my ideas. I made a few comments below.




## 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.


Technically the DW_AT_type can be optional, at least for Pascal. It will 
always be the same as the type of the getter and setter.

I don't know if that is true for all other languages.




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.


Maybe clarify how they are mapped? They could have the same name as in 
the function?

Or are the mapped by position? (empty ones for params without default)?

I see from the example that it is by position. ok.
If there are no further defaults after a parameter, do the remaining 
empty DW_TAG_formal_parameter have to be given, or can they be omitted?




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
```



Oxygene has different visibility for read/write access
https://docs.elementscompiler.com/Oxygene/Members/Properties/#visibility

Maybe allow DW_AT_accessibility in the getter/setter tags too.





### 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_property
 DW_AT_name "Foo"

 DW_TAG_property_getter
   DW_AT_specification 
DW_TAG_formal_parameter  ; _this (no default specified, details 
inherited from GetFoo
DW_TAG_formal_parameter
DW_AT_default_value  ; property index
DW_TAG_formal_parameter  ; x (no default specified)
```



The DW_TAG_formal_parameter for "x" and "index" appear to be swapped in 
order?



--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss