[fpc-devel] Feedback please - semantics of private vs strict private
Martin Frb
lazarus at mfriebe.de
Tue Oct 13 12:44:33 CEST 2026
Below the points I made. Please add/correct as necessary
On 13/10/2026 09:31, Martin Frb via fpc-devel wrote:
> I started a proposal to add strict private/protected to DWARF.
>
> If I could have some thoughts on the below question please.
Hi Ben, Hi Gary,
This answer has gotten a bit longer.
The points I made below are based on
- Pascal (as used by FPC) constructs that might be affected
- My reflections what a debugger might need to know
I am not myself much into the language design. But I have forwarded this
also to the FPC team, and maybe they will have some insights of their own.
I also added some compatibility concerns/expectations in the last paragraph.
In summary
- There are some pro on using only DW_ACCESS_private and an additional
tag for distinction
Albeit, from a language level I would say its 6 accessibility values.
- I am not sure if DW_AT_Visibility is a good choice for that, given all
its other use-cases
-------
If I understand correctly this is about private/protected (published
would not be using DW_AT_Visibility).
Then there would be:
- DW_ACCESS_private + DW_VIS_local = strict private
- DW_ACCESS_private + DW_VIS_exported = private (visible to unit)
DW_VIS_qualified would not be meaningful in this context.
--------
Potential conflict:
I am not sure if there is a conflict with another (new) feature (not
sure if yet documented, but implemented in the development branch)
https://forum.lazarus.freepascal.org/index.php/topic,75041.0.html
Basically a "union" for "record" types.
A record (another structured container type) can contain another record
("union").
The embedded record can have a name or not. Fields of the embedded
record can always be accessed as part of the parent (no qualification),
but if there is a name additional qualified access is also possible.
This may be a case for DW_AT_export_symbols? (if a structure is seen as
namespace?) Otherwise this is something that would use visibility?
*** If the nesting is expressed by DW_AT_Visibility then this conflicts
with the idea of using it for "strict". Records can have "strict
private" too. ***
--------
Some examples, different meaning of visibilities/accesibility depending
on context.
(those rules would need to be known independent of the TAG or Attribute
used)
The DWARF spec states about DW_AT_Visibility "visible outside of the
entity in which they are declared".
But it does not state how far outside? How many levels outside.
And for structure members it isn't "exactly one level outside".
- For a single class (that is declared in its unit) it is one level (as
the next outer level is the unit)
- classes can be nested. Then it still is up to the unit (several levels
outside).
unit Foo;
type
TBar = class
strict private type
TSome = class // DW_ACCESS_private + DW_VIS_local
private
MyValue: byte; // DW_ACCESS_private + DW_VIS_exported
end;
end;
MyValue can be accessed from methods of TBar.
But it cannot be accessed from outside of TBar, even within the same unit.
So DW_VIS_exported for such a private or protected member of a class
would have to be defined as
- accessible/visible up to either:
The unit (inclusive)
An outer DW_VIS_local (inclusive)
However the class TBar itself needs it visibility outside its unit to be
known. Like in ADA "package" vs "package body") the class can be either
in the "interface" or "implementation" section, making it visible or not
visible outside its owning unit.
So for the class itself, the visibility does not stop at the unit bounds.
Of course that can be done. But it needs to be clear that the meaning of
DW_AT_Visibility depends on
- the language
- the context (a member)
Also DW_AT_Visibility may also apply to Pascal enum.
type TWeekday = (Monday, Tuesday, ...)
can be declared such that
Monday is DW_VIS_exported
Monday is DW_VIS_qualified
And the DW_VIS_exported for Monday is to the unit.
Except if TWeekDay is also exorted, then Monday is visible to outside
the unit too.
--------
Another case where complex rules need to be known. But they need to be
known independent of which TAG expresses the accessibility/visibility.
So this likely does not affect the decision.
unit Foo;
type
TBar = class
private
MyValue: byte; // DW_ACCESS_private + DW_VIS_exported
protected
MyValue: byte; // DW_ACCESS_private + DW_VIS_exported
end;
This would be visible outside the class, But *not* outside the unit.
The same is true for "protected", except: A "class helper" (which is not
an inherited class) can see the protected value.
(We don't yet have a tag for helpers, albeit "friend" comes close)
--------
Compatibility concerns.
DW_ACCESS_private + DW_VIS_* may improve backward compatibility.
Old consumers will still handle DW_ACCESS_private as they always have.
And any old consumers that does not currently check for visibility on
those structure members would continue to work with new debug info.
New consumers would be able to use the added detail.
This solves that DW_ACCESS_module_private (instead of
DW_ACCESS_strict_private) creates its own problem.
While DW_ACCESS_module_private
- ensure consistent meaning across languages
- it risks inconsistencies across producers
Not all Pascal dialects have "strict". And not all compilers have it.
Currently all compilers use DW_ACCESS_private for "private" (and if they
have "strict private").
Any compiler that starts using DWARF-6 must then be aware that it must
change the value for "private".
But for compilers not having "strict" its probable that could be missed.
Yes, that may be considered a fault in that compiler, but it would still
be a problem.
Also, if all Pascal compilers would correctly update (even if they don't
have strict) then all of them would require consumers that also updated.
And some may rely on older consumers, and those wouldn't have it.
So IMHO DW_ACCESS_module_private creates more compatibility issues that
should be avoided.
(DW_ACCESS_strict_private would create some too, but with producers that
actually have both values)
Martin
More information about the fpc-devel
mailing list