[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