Ada makes it possible to define fixed point types. In order to specify how these will be represented at runtime, the compiler selects a size in bytes and a "scale factor", which is a strictly positive rational number. Assuming type T is associated with the S scale factor, then values V will be represented at runtime by R so that V = S * R.
Fixed points in DWARF today
Since DWARFv3, there are several ways to describe fixed point types, all of these require to use DW_TAG_base_type DIEs. The encoding must be DW_ATE_signed_fixed or DW_ATE_unsigned_fixed and the scale factor must be encoded using one of the following attributes:
- DW_AT_decimal_scale, which makes it possible to represent scale factors of the form 10**N (with N any signed integer).
- DW_AT_binary_scale, which makes it possible to represent scale factors of the form 2**N (with N any signed integer).
- DW_AT_small, which is a reference to a DW_TAG_constant entry providing the scale factor itself.
While DW_AT_small enables one to describe any scale factor the two other attributes could, there are still some scale factors that are not encodable as of today.
In Ada, it is possible to define fixed point types with scale factors such as 1/3. For instance:
Trying to represent 1/3 with a DW_TAG_constant leads to a chicken an egg problem today: the constant is encoded in the DW_AT_const_value attribute, which must be "the actual constant value [...] represented as it would be on the target architecture". 1/3 can be represented on the target architecture, but only with a fixed point type... whose scalar factor is 1/3, or 1/30, etc.
Two new attributes are proposed to solve this problem: DW_AT_GNU_numerator and DW_AT_GNU_denominator, which would appear on DW_TAG_constant DIEs. Their forms are any constant form (DW_FORM_*data*) and which represent an integer (unsigned, unless the form represents a signed one).
The rational constant represented by DW_TAG_constant is N/D where:
- N is the integer represented by the DW_AT_GNU_numerator attribute;
- D is the integer represented by the DW_AT_GNU_denominator attribute;
With this new tag, it is possible to represent arbitrary rational scale factors for fixed point types, enabling one to describe all possible Ada fixed point types.