Sign in Join

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

Mailing lists / fpc-devel / 2026-08

Consideration on "$CapturerClass" - reference to function - and debugging

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Martin Frb

I understand that a reference to a function is an interface, and therefore the only really know think is that it has zero, one or more functions, and the definition of those functions...

In practice reference to function has an underlying Pascal class that implements the function. This class is of course hidden, and it could change, and no guarantees are given.

That does not mean, that it might not be useful if a debugger could show it.

FpDebug already can resolve interfaces to a class that implements it => if that class exists. => It is the user responsibility to trigger this on such data only (in practice errors will be detected...)

The syntax in a watch for fpdebug is:  i2o(the_interface)

And that works for "reference to function" too.
Well, if and only if you are paused in the very method that does the capture.

Because for some reason the class is declared inside the function. So its scoped to only exist there.

True another work around could be added to the debugger, and functions could be all searched.

*** But the question is: Could the compiler just write that class on the top level? ***

Yes, the name is not always unique. But that already exists for user defined classes too.
And the name is unique per compilation unit.
So there would be no problem arising from putting it at top level.

Not sure if the name could be made more unique?
- generic like hash
- or include (in addition to module,file,line,col) the type name of the declared ref=type: "TFoo = reference to function" (then it would be the users responsibility)

Reply by email

Sven Barth
to Martin Frb
Martin Frb wrote
*** But the question is: Could the compiler just write that class on the top level? ***

No, it makes no logical sense to put a type, that is *logically* a child of a routine be part of the top level. Also it may contain references to types that are local to the surrounding routine.

Regards,
Sven

Reply by email

Martin Frb
to Sven Barth
Sven Barth wrote 7 lines
Am 25.08.2026 um 09:21 schrieb Martin Frb via fpc-devel: > *** But the question is: Could the compiler just write that class on > the top level? *** No, it makes no logical sense to put a type, that is *logically* a child of a routine be part of the top level. Also it may contain references to types that are local to the surrounding routine.

Ok.

btw, and unrelated to my initial reasons... But has this been tested with gdb/lldb?

I don't know if it is related to this or maybe it could be something entirely else, but my gdb (17.1 on Windows) reports (when trying to step through an anon proc / pascal code at the end)
=> line 22 is outside / calling the invoke.
=> line 14 is correct
=> and then gdb looses it.

Thread 1 hit Breakpoint 1, B (X=0x14e7cf8) at project1.lpr:22 22        write(x());
(gdb) s
WRPR_$P$PROJECT1$_$F$$TFUNC_$$_$CAPTURERCLASS_1_1_10_10_$_P$PROJECT1$_$F$$TFUNC_$$HK1jjfl_kbwP () at project1.lpr:14
14        result := function: integer begin
(gdb) n
0x0000000100001709 in INVOKE__FPCINTERNAL__1_1_14_21 (this=0x14e7cf8) (gdb) n
Single stepping until exit from function INVOKE__FPCINTERNAL__1_1_14_21, which has no line number information.
2B (X=0x14e7cf8) at project1.lpr:21
21      begin
(gdb) n
23      end;

The line info is there. So that must be some issue in the GDB that I have. (interestingly gdb also reports the addresses for those lines to the IDE on a different query)

I haven't tested with LLDB.
FpDebug had no problems.

program Project1;
{$Mode objfpc}
{$ModeSwitch anonymousfunctions}
{$ModeSwitch functionreferences}
type TFunc = reference to function: integer;
var
   n: TFunc;
function f: TFunc;
var a: integer;
begin
   a := 1;
   result := function: integer begin
     inc(a);
     result := a;
   end;
end;
procedure b(x: TFunc);
begin
   write(x());
end;
begin
   n := f;
   b(n);
   b(n);
   b(n);
end.

Reply by email

Martin Frb
to Martin Frb
Martin Frb wrote 5 lines
On 25/08/2026 21:42, Sven Barth via fpc-devel wrote: > No, it makes no logical sense to put a type, that is *logically* a > child of a routine be part of the top level. Also it may contain > references to types that are local to the surrounding routine.

Off topic to the original question, but this just reminds me.

What is the stance on representing

type
  Tfoo = class
  protected type
    TBar = class
....

With the same nesting in DWARF?

After all, currently all of those go top level, and they are
- causing real name conflicts
- don't resolve if users copy the full qualified name from code
- don't resolve if a debugger uses RTTI to get the name

Reply by email