Sign in Join

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

Mailing lists / fpc-devel / 2026-10

Feedback please - semantics of private vs strict private

2 messages · 1 person ·

Reply by email Subscribe to this list Your subscription

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

Martin Frb

I started a proposal to add strict private/protected to DWARF.

If I could have some thoughts on the below question please.

If I understand that correct, the idea may be to add DW_VIS_local / DW_VIS_exported in addition to DW_ACCESS_private.
And this would indicate if a private symbol can be seen within its containing unit. (same for protected)

1) from a language design point: how fitting is this?

2) Is this complete, as in: No "side effect" of "strict" is being overlooked? (strict really only affects code of the same unit, that is outside the class and its decendents / no decendent is affected, not in, nor outside the unit)

-------- Forwarded Message --------
Subject: Re: New Issue: Accessibility Declarations for FreePascal

Hey Martin,

We have been discussing your request for new Accessibility Declarations for Free Pascal. https://dwarfstd.org/issues/260428.1.html

If you look at the latest version of the draft standard https://snapshots.sourceware.org/dwarfstd/dwarf-spec/2026-09-20_22-49_1789944541/dwarf6-20260920-2248.pdf on page 30 there are two sections very close to each other. Accessibility of Declarations and Visibility of Declarations and it needs to be understood that the second one does not refer to ELF symbol visibility it is language level visibility.

When we refer to your language
https://www.freepascal.org/docs-html/ref/refse35.html specification it talks about

--class visibility
specifier-------------private------------------------- |-strict-| -protected--|| |-------public---------| -------published -------

And so it specifies "class visibility specifier". So we are trying to figure out if FreePascal should use visibility rather than or in addition to Accessibility of Declarations. The problem is I don't think any of us are really well versed in FreePascal or the old Delphi and Borland TurboPascal and the language semantics of those compilers to be able to really be able to know what the intent is for sure.

So far what we have kind of decided that strict private and strict protected map more closely to  DW_ACCESS_private and DW_ACCESS_protected since they are conceptually closer to C++'s private and protected.

Then in my draft we have added DW_ACCESS_module_private and DW_ACCESS_module_protected but is that actually more like DW_ACCESS_public with DW_VIS_local. Would you be able to shed some light on the matter with regards to how Delphi and now FreePascal understand the visibility and accessability question. I'm sorry, while there are a few of us who have some Familiariaty with Modula 2 but it is a distant recollection from University and I don't think any of us have any experience with the later evolution of Pascal and so we are all a bit confused by this.

-ben

Ben Woodard wrote 32 lines
Cary, this references the DWARF discussion "Additional values for DW_AT_accessibility" recently on DWARF-discuss. If this actually needs a champion, I'll champion it. Super simple, add a couple of defines. Like the recent errata, I feel like it is a wave-through. --------------------------------- Issue: DWARF5 only has Accessibility declarations DW_ACCESS_public DW_ACCESS_private and DW_ACCESS_protecte. However, FreePascal has a couple more that need to be represented. This is needed so that debuggers can report it back to users and so that ABI checkers like libabigail can detect changes to the API which would then change the ABI of an object. The full list can be found at: https://www.freepascal.org/docs-html/ref/refse35.html Proposal: In Section 2.7 in Table 2.4 Add two more accessibility codes: DW_ACCESS_strict_private and DW_ACCESS_strict_protected. In Section 8.9 in Table 8.14 Add the following entries to table 8.14: Accessibility code name Value DW_ACCESS_strict_private TBD DW_ACCESS_strict_protected TBD

Reply by email

Martin Frb
to Martin Frb

Below the points I made. Please add/correct as necessary

Martin Frb 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

Reply by email