Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2024-04

Help/Guidance please: Dwarf support for properties

20 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Frb

Ok, I would like to start another attempt to support properties when using fpdebug as debugger.

The idea is to add custom tags in the dwarf info. This can be done by a new option -godwarfporperties
Though, it may be better to go with -godwarffpdbg / similar to -godwarfcpp

Making it fpdebug specific will allow to add other info, that would benefit debugging Pascal, but isn't in Dwarf...

In 2022 Joost did an attempt:
https://gitlab.com/freepascal.org/fpc/source/-/compare/main...joost%2Fdwarfproperties?from_project_id=28644964&straight=false

I didn't understand the reasons behind (but then I am not familiar with the FPC codebase).
I do now get some guesses as to why...

-----------------
But anyway, I started my own attempt based on that. https://gitlab.com/martin_frb/fpc-src/-/compare/main...martin-dwarf-properties?from_project_id=28644964&straight=false

The first problem is getting labels for items that need to be referenced.

2a267440b240be3aa99d0c14fd6c8dcf90a27f99
For procedures this is explained in the first commit => they currently have an (possible intentional) unbalanced dbg_state_writing. Requiring them to have a label, conflicts with that. I welcome feedback on the suggestions in my commit message.

19e6b4fea54b85df1ad8df221947231d01d98bb9
Just completing the above, and write the labels.

959566d705d6a464b3076a97ddaa8213c9d9ec9f
Same problem for DW_TAG_MEMBER
My "workaround" is certainly wrong.  But currently there is no SYM. How can I get labels for it?
Such as that they also work, if the field is in the parent, in a diff unit => which on linux requires a global label, since the declaration is NOT copied into the current unit.

50f7d0d53a20cef541f87b474a7b8cc39558808d
Write the basic info.
Currently only works if the property field/getter is in the same object (or base class), but not if it is in a record belonging to the object. The latter requires the structure address to be also written, and resolving the record to the field...

But before I go and spent time on that, I would like to first resolve all the issues that already exist.

-----------------
Using -godwarffpdbg would also allow for this:
https://gitlab.com/martin_frb/fpc-src/-/compare/main...martin-entry-pc?from_project_id=28644964&straight=false

Which makes sure there is an address for each of the functions that need to be called.

-----------------
Test implementation in Lazarus
https://gitlab.com/martin_frb/lazarus/-/commits/fpdebug-godwarfproperties

properties with getters aren't called yet. It shows the getter, as if it was an event variable.

But if the getter has an address, it can be called by adding "()" (and enabling function eval).
At least for datatypes supported in function calls.

Looking forward to some feedback.
Martin

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote
Ok, I would like to start another attempt to support properties when using fpdebug as debugger.

I would recommend asking guidance on the DWARF list (dwarf-discuss). Maybe there are already standard-supported constructs to do this.

Jonas

Reply by email

Martin Frb
to Martin Frb
Martin Frb wrote 12 lines
On 27/04/2024 15:24, Jonas Maebe via fpc-devel wrote: > On 27/04/2024 13:45, Martin Frb via fpc-devel wrote: >> Ok, I would like to start another attempt to support properties when >> using fpdebug as debugger. > > I would recommend asking guidance on the DWARF list (dwarf-discuss). > Maybe there are already standard-supported constructs to do this. > > It is not mentioned in the latest draft for dwarf 6. https://snapshots.sourceware.org/dwarfstd/dwarf-spec/latest/

Joost actually checked
https://lists.dwarfstd.org/pipermail/dwarf-discuss/2021-May/thread.html https://lists.dwarfstd.org/pipermail/dwarf-discuss/2021-June/thread.html

And Joost based his implementation on this.

One of the posts also brings up the idea of avoiding labels (in asm), and keep track of locations by counting the bytes in the generated dwarf as part of the compilers work (IMHO duplicate what the asm already can do?)

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote
One of the posts also brings up the idea of avoiding labels (in asm), and keep track of locations by counting the bytes in the generated dwarf as part of the compilers work (IMHO duplicate what the asm already can do?)

That's not the assembler's, but the linker's job. And on macOS, the DWARF info is not processed by the linker and hence can only contain relative offsets (differences between two local labels).

Jonas

Reply by email

Martin Frb
to Jonas Maebe
Jonas Maebe wrote 10 lines
On 27/04/2024 17:18, Martin Frb via fpc-devel wrote: > > One of the posts also brings up the idea of avoiding labels (in asm), > and keep track of locations by counting the bytes in the generated > dwarf as part of the compilers work (IMHO duplicate what the asm > already can do?) That's not the assembler's, but the linker's job. And on macOS, the DWARF info is not processed by the linker and hence can only contain relative offsets (differences between two local labels).

Maybe a miss understanding: storing the difference between 2 local labels would be the asm?
But if (e.g. on Linux) it is cross units then its the linker.

There are 2 consideration here.

1)
First, telling the asm to store  ".l99 - .ldebuginfo" or telling the asm to store 733 (having done the math already) will result in the same dwarf info.
Of course this only works for local labels.

The big question here is, if it is ok to use labels (potentially many labels) for this purpose.
From the mails at the dwarf list, it seems Joost wanted to avoid this, but it is not clear why.

Joost then went on, to count the bytes that are added by each bit of dwarf info written (same as the asm would do), and therefore be able to write the number directly (or in some cases iirc write it later into the gap).
That leads to a very big changeset, as the entire dwarf generating code needs to do counting.
(And IMHO, that is very easy to accidentally break / and if just one very specific dwarf encoding breaks it, it may be months until found)

But, then again I don't know anything about the impact of such amounts of additional labels...

2)
At least on Linux, references for dwarf go across compilation units.

On Windows, if "unit1" has "TForm1 = class(TForm)", that leads to *all* base classes being encoded into that unit. Almost every unit will therefore have a copy of TObject (if it is oop). On Linux, only one unit has this.

I must say, I haven't checked how Joost's code deals with that. (and mine would probably still need work for that too, but before doing anything, I am trying to find out what is ok).
Afaik that is why there is:     tf_dwarf_only_local_labels in target_info.flags

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote 14 lines
Maybe a miss understanding: storing the difference between 2 local labels would be the asm? But if (e.g. on Linux) it is cross units then its the linker. There are 2 consideration here. 1) First, telling the asm to store  ".l99 - .ldebuginfo" or telling the asm to store 733 (having done the math already) will result in the same dwarf info. Of course this only works for local labels. The big question here is, if it is ok to use labels (potentially many labels) for this purpose.

Sure. The current DWARF writer also does this.

Show quoted text 11 lines
From the mails at the dwarf list, it seems Joost wanted to avoid this, but it is not clear why. Joost then went on, to count the bytes that are added by each bit of dwarf info written (same as the asm would do), and therefore be able to write the number directly (or in some cases iirc write it later into the gap). That leads to a very big changeset, as the entire dwarf generating code needs to do counting. (And IMHO, that is very easy to accidentally break / and if just one very specific dwarf encoding breaks it, it may be months until found)

There's one case in which you would have to do it manually: if you want to save those offsets in leb128 encoding. At least on macOS there's no support for storing the difference between two labels in s/uleb128 in DWARF.

Show quoted text 13 lines
2) At least on Linux, references for dwarf go across compilation units. On Windows, if "unit1" has "TForm1 = class(TForm)", that leads to *all* base classes being encoded into that unit. Almost every unit will therefore have a copy of TObject (if it is oop). On Linux, only one unit has this. I must say, I haven't checked how Joost's code deals with that. (and mine would probably still need work for that too, but before doing anything, I am trying to find out what is ok). Afaik that is why there is:     tf_dwarf_only_local_labels in target_info.flags

Correct.

Jonas

Reply by email

Martin Frb
to Jonas Maebe
Jonas Maebe wrote 11 lines
On 27/04/2024 21:40, Martin Frb via fpc-devel wrote: > First, telling the asm to store  ".l99 - .ldebuginfo" or telling the > asm to store 733 (having done the math already) will result in the > same dwarf info. > Of course this only works for local labels. > > The big question here is, if it is ok to use labels (potentially many > labels) for this purpose. Sure. The current DWARF writer also does this.

So on Windows (and presumingly Mac) that will all be local labels.

On Linux (I just checked) the current Dwarf writer generates global labels (with relocations).
The change in question would add quite a few more of them. As any field or method in a class can be referred to by a property (even from another unit (except private), it would need to add a label to each and every field and method.
[[ see below ]]

So, if that is OK, then I would appreciate some pointers how I can best generate those labels.
Some of the code does not have a TDef - Which is needed for "get_def_dwarf_labs()".

Then again, I might have another look at Joost's code and try to rebase/fix it for current trunk....

But then before I do, is there any feedback on it? What would be the requirements to get it accepted?

Would there be preferences between the 2 approaches?

At least on macOS there's no support for storing the difference between two labels in s/uleb128 in DWARF.

That should be (from dwarf point of view) the same as on Windows? On Windows the generated dwarf does only have references within each compilation unit.
I don't have a Mac at hand right now, but I assume that an Mac any declaration from another unit (such as e.g.  base classes) will have a copy written to any unit in which they need to be referenced.

-----------------------
Off topic to properties, but looking at what currently happens on Linux

The compiler is smart enough to only add exported-labels for types in an "interface section".

Types private to the unit, well... It seems they were meant to get local labels, but do get exported too?
They get (on linux) labels like (on windows that is just .ld20):     _$UNIT1$_Ld20

And that label is present in the .o file.

Reply by email

Martin Frb
to Martin Frb: Ok, I would like to start another attempt to support properties when using fpdebug as…

https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#debugging-information-format-1

Show quoted text 5 lines
Objective C properties exist separately from class members.  A property can be defined only by "setter" and "getter" selectors, and be calculated anew on each access.  Or a property can just be a direct access to some declared ivar.

I don't know if in Apple terms "ivar" has any special meaning?

Nor if there is more to "calculated anew on each access"?

---------------

I don't have background on the Apple properties.

But the fact that the link between a "field" (tag_member) and the property goes from the member to the property strikes me as odd. (first example of dwarf)
It indicates, that the property is only meant to be found when starting at the member?

For FPC properties that is the other way round.
The property would have to point to the field. (or function)

Also the Apple spec uses strings (names) to refer to the getter/setter. I don't know if there is a particular underlying need. It's more costly than a reference. Also It gets problematic if the getter is in an embedded record, or if there are overloaded functions, ....

-----------------
There do exist Borland properties
https://android.googlesource.com/platform//prebuilts/clang/host/linux-x86/+/b669748458572622ed716407611633c5415da25c/clang-r416183d/include/llvm/BinaryFormat/Dwarf.def

But I could not find any details at all....

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote 9 lines
https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#debugging-information-format-1 > Objective C properties exist separately from class members.  A > property can be > defined only by "setter" and "getter" selectors, and be calculated > anew on each > access.  Or a property can just be a direct access to some declared ivar. I don't know if in Apple terms "ivar" has any special meaning?

ivar = instance var. Basically a regular field (as opposed to a class/static field), i.e. the equivalent of a "property size: longint read fsize write fsize;"

Nor if there is more to "calculated anew on each access"?

I think they mean that on each access, the getter/setter gets called again.

--------------- I don't have background on the Apple properties.

It's not Apple, but Objective-C.

property goes from the member to the property strikes me as odd. (first example of dwarf) It indicates, that the property is only meant to be found when starting at the member?

Objective-C also knows the concept of "computed properties", which are not tied to a particular field. I don't immediately see how the proposal deals/would deal with that.

Also the Apple spec uses strings (names) to refer to the getter/setter. I don't know if there is a particular underlying need. It's more costly than a reference. Also It gets problematic if the getter is in an embedded record, or if there are overloaded functions, ....

It doesn't use a symbol name, but a selector name. Objective-C method dispatching mostly does not happen using a VMT, but by looking up a (hash of a) selector in a table. "Calling a method" is called "sending a message to" in Objective-C lingo; it's also how it can fairly transparently support working with remote objects.

There are various optimisations to make this less costly than a naive implementation when running on a single system. But that is the reason why it uses a string. As Objective-C is an extension of C rather than C++, it does not support overloading either (although due to the way its method names are split up when calling, it can support something syntactically similar).

Jonas

Reply by email

Martin Frb
to Jonas Maebe
Jonas Maebe wrote 16 lines
> --------------- > > I don't have background on the Apple properties. It's not Apple, but Objective-C. > property goes from the member to the property strikes me as odd. > (first example of dwarf) > It indicates, that the property is only meant to be found when > starting at the member? Objective-C also knows the concept of "computed properties", which are not tied to a particular field. I don't immediately see how the proposal deals/would deal with that.

Ok, I don't know how to read that, but potentially many fields could link to the same property.

Do those properties need a field at all?

Show quoted text 11 lines
> Also the Apple spec uses strings (names) to refer to the getter/setter. > I don't know if there is a particular underlying need. It's more > costly than a reference. Also It gets problematic if the getter is in > an embedded record, or if there are overloaded functions, .... It doesn't use a symbol name, but a selector name. Objective-C method dispatching mostly does not happen using a VMT, but by looking up a (hash of a) selector in a table. "Calling a method" is called "sending a message to" in Objective-C lingo; it's also how it can fairly transparently support working with remote objects.

ok. Explains maybe half...

I am not immediately sure if dwarf has anything to describe dispatching. Or if this is just left for the debugger to know. Which is ok, with custom tags that are for Objective-C only.
I don't know if that table is precomputed / I.e. get completely created at compile time => in which case the location of the looked up hash would be known in the table, and the address of the method could be gotten via a dwarf expression?

The other part that I really don't understand is, why you find the property from the field, and not the other way round (above)? Does that mean the code/user would not start with "object.my_property" but rather do "object.field as property"?

I am trying to understand if there is any common ground with properties in Pascal.

I've ask if they (dwarf makers) see potential for our properties https://lists.dwarfstd.org/pipermail/dwarf-discuss/2024-May/thread.html So, I am trying to figure out were those Apple tags fit into it, and how/if I treat them in that discussion. (the Borland ones, have no docs to be found)

However from what I have seen so far, I do think there are fundamental differences.
Pascal properties should have
- the property as a declaration that is a start point (except for being owned by a class / but also exists without)
- links to other entities starting at the property (or no links, and duplication of accessor declarations)

Maybe there is still stuff that could be proposed as share-able?

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote 21 lines
On 02/05/2024 20:59, Jonas Maebe via fpc-devel wrote: > > >> --------------- >> >> I don't have background on the Apple properties. > > It's not Apple, but Objective-C. > >> property goes from the member to the property strikes me as odd. >> (first example of dwarf) >> It indicates, that the property is only meant to be found when >> starting at the member? > > Objective-C also knows the concept of "computed properties", which are > not tied to a particular field. I don't immediately see how the > proposal deals/would deal with that. Ok, I don't know how to read that, but potentially many fields could link to the same property. Do those properties need a field at all?

No, as far as I can tell they're more or less equivalent to Pascal properties.

Show quoted text 16 lines
>> Also the Apple spec uses strings (names) to refer to the getter/setter. >> I don't know if there is a particular underlying need. It's more >> costly than a reference. Also It gets problematic if the getter is in >> an embedded record, or if there are overloaded functions, .... > > It doesn't use a symbol name, but a selector name. Objective-C method > dispatching mostly does not happen using a VMT, but by looking up a > (hash of a) selector in a table. "Calling a method" is called "sending > a message to" in Objective-C lingo; it's also how it can fairly > transparently support working with remote objects. ok. Explains maybe half... I am not immediately sure if dwarf has anything to describe dispatching. Or if this is just left for the debugger to know. Which is ok, with custom tags that are for Objective-C only.

Yes, Objective-C's runtime has a publicly documented API. It has C functions that you can use to call mathods with a particular name on a particular object (or, in Objective-C terminology, send a message by name to an instance).

The other part that I really don't understand is, why you find the property from the field, and not the other way round (above)? Does that mean the code/user would not start with "object.my_property" but rather do "object.field as property"?

It's because except for computed properties, properties are explicitly tied to a particular field. They provide getters and/or setters for a particular field.

Jonas

Reply by email

Martin Frb
to Jonas Maebe

In case it goes ahead, I am trying to thing of what would be needed.... Can anyone think of any feature for Pascal properties that is not covered by the below?

# 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

Reply by email

Sven Barth
to Martin Frb: In case it goes ahead, I am trying to thing of what would be needed.... Can anyone think…

Martin Frb via fpc-devel schrieb am Fr.,
3. Mai 2024, 12:13:

In case it goes ahead, I am trying to thing of what would be needed.... Can anyone think of any feature for Pascal properties that is not covered by the below?

A property can be marked "default". Currently only array properties, but there is still the idea to implement "hoisting" of sub members through single properties.

Properties of type interface or class can have an "implements" clause that redirects the implementation of an interface implemented by the class (note: class type properties are not yet supported by FPC, but are on the ToDo list for Delphi compatibility).

Oxygene introduced per setter/getter visibility and since I had need of this here and then in the past I might still be inclined to implement that in the future, so this might not only be for C# then.

Regards,
Sven

Reply by email

Martin Frb
to Sven Barth
Sven Barth wrote 12 lines
Martin Frb via fpc-devel schrieb am Fr., 3. Mai 2024, 12:13: In case it goes ahead, I am trying to thing of what would be needed.... Can anyone think of any feature for Pascal properties that is not covered by the below? A property can be marked "default". Currently only array properties, but there is still the idea to implement "hoisting" of sub members through single properties.

Right. I will add a "default" flag.

Out of interest (I recall having seen the discussion, but I don't recall the details), how would that be accessed?
a := MyObj; // will a be assigned the object or the default properties value?

Will that also mean multiple default properties, if the index signature differs?

Show quoted text 6 lines
Properties of type interface or class can have an "implements" clause that redirects the implementation of an interface implemented by the class (note: class type properties are not yet supported by FPC, but are on the ToDo list for Delphi compatibility).

Right. Is that relevant for the debugger though?

Or would that be the other way round? I.e. if we implemented debug info for interfaces, then an interface would in the debug info be a structure with lots of functions.
Those functions then point to the correct functions in the object. And through the self param, would reveal the object, or in this case the  "implements" interface as object (allowing the debugger to forward resolve).

Actually, I don't think that the class debug info even includes which interfaces the class implements?

The Borland extension seems to have had it:
https://github.com/llvm-mirror/llvm/blob/master/include/llvm/BinaryFormat/Dwarf.def#L390

Oxygene introduced per setter/getter visibility and since I had need of this here and then in the past I might still be inclined to implement that in the future, so this might not only be for C# then.

Good to know, I will amend that.

-------------
I was also thinking if it might help to have a link to an inherited property, if only visibility is changed.
But that does not exist for functions either (though actually indirectly yes, through the vmt pointer).

That way the debugger could use that to avoid double listing it.

E.g. currently there is already the problem that with "strict private" (or private across units) an object can have several fields "MyField". Of the same or different type. (which I still haven't 100% dealt with in fpdebug).
With fields though, they are always different. With properties they may be a newly introduced, or a visibility change. But then the absence of any setter/getter would indicate that too.

Reply by email

Jonas Maebe
to Martin Frb: Does FPC create such Objective-C code / properties? If yes, how does it decide on how to…
Martin Frb wrote 11 lines
On 02/05/2024 20:59, Jonas Maebe via fpc-devel wrote: > >> --------------- >> >> I don't have background on the Apple properties. > > It's not Apple, but Objective-C. Does FPC create such Objective-C code / properties? If yes, how does it decide on how to translate "property Foo..."?

FPC does not currently support properties in Objective-C classes.

Jonas

Reply by email

Martin Frb
to Martin Frb
Martin Frb wrote
It's now an issue for the Dwarf standard. https://dwarfstd.org/issues/240507.1.html

Looking at the time other proposals have taken, I think it is reasonable to implement properties as custom extension now. And then later make any amendments (best case, just change the numeric constants for the DW_TAG/_AT... ).

I have done some experiments on Joost's work. But I now reached the point were I do need feedback and help:
https://gitlab.com/martin_frb/fpc-src/-/compare/main...martin-dwarf-prop-2?from_project_id=28644964&straight=false

Joost's code had some of the "tai" sizes hard-coded in dbgdwarf.pas. I moved that into each of the "tai" classes.
https://gitlab.com/freepascal.org/fpc/source/-/commit/6623ccd6245bb0b8d2d46453ac680c18d6c6aad1#1666e6c01f5086b3630dcd10a1b24557a1c178f6_2741_2831

begin { write dummy for now } AddConstToAbbrev(ord(DW_FORM_string)); append_to_al_dwarf_info(tai_string.create(''),1);

Joost's code did write labels to the "tai" list, where the location of the label was unknown, and later
See "|TPendingOffsetConst" in
|https://gitlab.com/freepascal.org/fpc/source/-/commit/6623ccd6245bb0b8d2d46453ac680c18d6c6aad1#1666e6c01f5086b3630dcd10a1b24557a1c178f6

I tried to use (local) labels for that. This only happens if the Dwarf target DIE is in the same CU.
However, I encountered some issues
- On Linux, I think I get global labels.
- I needed labels for TSym
- for code like
    TFoo = record a: integer; property b: integer read a; end;     TBar = type TFoo;
  TBar is written using the same symbol (same instance). So I can't get 2 labels (currently the same label gets written twice, leading to an error)

So what is the best way to proceed there?

I also did not yet manage to create a link to the static variable that is written for static fields, when it is referred by a class property. But maybe that can be done, when static fields are moved inside the class....  DWARF-5 "5.7.7 Class Variable Entries" allows DW_TAG_Variable in a structure.

Btw, while writing the dwarf, is there a way to tell from the data, if a property is written because setter/getter are declared here, or because it changes only visibility?

Other comments/suggestions?

A lazarus proof of concept counter part.
(To view properties, each watch still must have "function calling" enabled) https://gitlab.com/martin_frb/lazarus

Reply by email

Martin Frb
to Martin Frb

Anyone any feedback, please?

Or, who would be knowledgeable, and might at least tell me when there might be time, if too busy right now?

Martin Frb wrote 62 lines
On 09/05/2024 19:53, Martin Frb via fpc-devel wrote: > It's now an issue for the Dwarf standard. > https://dwarfstd.org/issues/240507.1.html Looking at the time other proposals have taken, I think it is reasonable to implement properties as custom extension now. And then later make any amendments (best case, just change the numeric constants for the DW_TAG/_AT... ). I have done some experiments on Joost's work. But I now reached the point were I do need feedback and help: https://gitlab.com/martin_frb/fpc-src/-/compare/main...martin-dwarf-prop-2?from_project_id=28644964&straight=false Joost's code had some of the "tai" sizes hard-coded in dbgdwarf.pas. I moved that into each of the "tai" classes. https://gitlab.com/freepascal.org/fpc/source/-/commit/6623ccd6245bb0b8d2d46453ac680c18d6c6aad1#1666e6c01f5086b3630dcd10a1b24557a1c178f6_2741_2831 > begin > { write dummy for now } > AddConstToAbbrev(ord(DW_FORM_string)); > append_to_al_dwarf_info(tai_string.create(''),1); Joost's code did write labels to the "tai" list, where the location of the label was unknown, and later See "|TPendingOffsetConst" in |https://gitlab.com/freepascal.org/fpc/source/-/commit/6623ccd6245bb0b8d2d46453ac680c18d6c6aad1#1666e6c01f5086b3630dcd10a1b24557a1c178f6 I tried to use (local) labels for that. This only happens if the Dwarf target DIE is in the same CU. However, I encountered some issues - On Linux, I think I get global labels. - I needed labels for TSym - for code like     TFoo = record a: integer; property b: integer read a; end;     TBar = type TFoo;   TBar is written using the same symbol (same instance). So I can't get 2 labels (currently the same label gets written twice, leading to an error) So what is the best way to proceed there? I also did not yet manage to create a link to the static variable that is written for static fields, when it is referred by a class property. But maybe that can be done, when static fields are moved inside the class....  DWARF-5 "5.7.7 Class Variable Entries" allows DW_TAG_Variable in a structure. Btw, while writing the dwarf, is there a way to tell from the data, if a property is written because setter/getter are declared here, or because it changes only visibility? Other comments/suggestions? A lazarus proof of concept counter part. (To view properties, each watch still must have "function calling" enabled) https://gitlab.com/martin_frb/lazarus

Reply by email