[Dwarf-discuss] Proposal: Add DW_AT_refcount for ref-counted types

Martin dwarf@mfriebe.de
Sun May 31 10:38:41 GMT 2026


The below proposal is with reference to
https://lists.dwarfstd.org/pipermail/dwarf-discuss/2026-April/002809.html
https://lists.dwarfstd.org/pipermail/dwarf-discuss/2026-April/002808.html

For current FreePascal such a ref-count would at least need to apply to
* DW_TAG_string_type
* DW_TAG_array_type

I listed more types, since the concept may apply to other types in 
futures. Also other language may have ref-counts too.

I wasn't sure if to also add DW_TAG_reference_type?

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


# Proposal to implement DW_AT_refcount (e.g. for Pascal strings and 
dynamic array)

## Background

Pascal (examples for FreePascal / similar in Delphi) has some types that 
are ref-counted by compiler generated code.

The compiler internally adds a ref-count field to the memory of those 
types. Those are currently
* Some string types like AnsiStrings. But not ShortString
* Dynamic arrays (arrays with variable length, controlled at runtime). 
But not static (fixed size) array.

Those ref-counts are not accessible to user-code. They are fully managed 
by the compiler.

The refcount may be needed:
* for inspection by the user during debugging
* for the debugger to modify/create/release such data on the users request.

A debugger would still need to know the producer, in order to know how 
to handle such data. E.g. calling special methods to increase/decrease 
the value.
Also with Pascal the special value -1 exists for constant data (that can 
not decrease its reference, and not be freed).

But even if a debugger does not know how to modify ref-counts, it may 
still use the information to reject requests to modify the data.


## Proposed Changes for types

Add new attributes
* DW_AT_ref_count  (location, reference, constant, flag)
* DW_AT_ref_count_size, DW_AT_ref_count_bit_size

If DW_AT_ref_count is a flag then it indicates the presence of a 
refcount for which the value is not known.
This may have been optimised away. Individual data-tags may provide 
values as specified below.

Those attributes should be allowe with any TAG that defines a type.
* DW_TAG_string_type
* DW_TAG_array_type
* DW_TAG_base_type
* DW_TAG_class_type
* DW_TAG_interface_type
* DW_TAG_structure_type
* DW_TAG_pointer_type
* DW_TAG_enumeration_type
* DW_TAG_set_type
* DW_TAG_file_type
* DW_TAG_subrange_type
* DW_TAG_subroutine_type
* DW_TAG_thrown_type
* DW_TAG_pointer_to_member
* DW_TAG_dynamic_type
* DW_TAG_union_type


## Proposed Changes for data

Data may not always be hold in memory. (DW_AT_const_value / 
DW_op_implicit_value). In such cases a ref value may not be encoded into 
the constant data.

It would be good, if those value would still be able to use the same 
type declaration.

The following tags should therefore support the new DW_AT_ref_count, 
DW_AT_ref_count_size, DW_AT_ref_count_bit_size:
* DW_TAG_formal_parameter
* DW_TAG_variable
* DW_TAG_constant
* type

If they specify a refcount then the value given overrides the value in 
the type.
* For those tags, the presence of those attribute should only be allowed 
if the type has at least a type.
* If any of those tags specifies such an override, then all ref-count 
related attributes in the type are ignored. Therefore the type 
DW_AT_ref_count must then be present on this type.
* If DW_AT_ref_count for such a tag is a flag, it should be expected to 
be true, as the type demands the presence of a ref-count. types should 
be interpreted as, there is a ref-count, but its value is not type

## type

1$: DW_TAG_string_type
         DW_AT_type(reference to chartype)
         DW_AT_data_location(expression= ! Get raw data address
             DW_OP_push_object_address
             DW_OP_deref)
         DW_AT_string_length (n)
         DW_AT_ref_count (expression= ! Get raw data address
             DW_OP_push_object_address
             DW_OP_deref
             DW_OP_lit1
             DW_OP_minus)
         DW_AT_ref_count_size (1) ! byte sized

2$  DW_TAG_variable
         DW_AT_name
         DW_AT_location
         DW_AT_type($1)

3$  DW_TAG_constant
         DW_AT_name
         DW_AT_const_value  ! The const_value starts with the first char 
of the string
         DW_AT_type($1)
         DW_AT_ref_count (-1)  ! constant, the location "1 byte before 
the string-data can not be accessed in the const_value





More information about the Dwarf-discuss mailing list