Enhance debug info for fixed-point types
The Ada language supports fixed-point types as first-class citizens so they need to be described as-is in the debug info. We devised the langhook get_fixed_point_type_info for this purpose a few years ago, but it comes with a limitation for the representation of the scale factor that we would need to lift in order to be able to represent more fixed-point types. gcc/ChangeLog: * dwarf2out.h (struct fixed_point_type_info) <scale_factor>: Turn numerator and denominator into a tree. * dwarf2out.c (base_type_die): In the case of a fixed-point type with arbitrary scale factor, call add_scalar_info on numerator and denominator to emit the appropriate attributes. gcc/ada/ChangeLog: * exp_dbug.adb (Is_Handled_Scale_Factor): Delete. (Get_Encoded_Name): Do not call it. * gcc-interface/decl.c (gnat_to_gnu_entity) <Fixed_Point_Type>: Tidy up and always use a meaningful description for arbitrary scale factors. * gcc-interface/misc.c (gnat_get_fixed_point_type_info): Remove obsolete block and adjust the description of the scale factor.
This commit is contained in:
parent
0d8290959e
commit
43a0debd52
@ -133,11 +133,6 @@ package body Exp_Dbug is
|
||||
-- Determine whether the bounds of E match the size of the type. This is
|
||||
-- used to determine whether encoding is required for a discrete type.
|
||||
|
||||
function Is_Handled_Scale_Factor (U : Ureal) return Boolean;
|
||||
-- The argument U is the Small_Value of a fixed-point type. This function
|
||||
-- determines whether the back-end can handle this scale factor. When it
|
||||
-- cannot, we have to output a GNAT encoding for the corresponding type.
|
||||
|
||||
procedure Output_Homonym_Numbers_Suffix;
|
||||
-- If homonym numbers are stored, then output them into Name_Buffer
|
||||
|
||||
@ -594,27 +589,6 @@ package body Exp_Dbug is
|
||||
return Make_Null_Statement (Loc);
|
||||
end Debug_Renaming_Declaration;
|
||||
|
||||
-----------------------------
|
||||
-- Is_Handled_Scale_Factor --
|
||||
-----------------------------
|
||||
|
||||
function Is_Handled_Scale_Factor (U : Ureal) return Boolean is
|
||||
begin
|
||||
-- Keep in sync with gigi (see E_*_Fixed_Point_Type handling in
|
||||
-- decl.c:gnat_to_gnu_entity).
|
||||
|
||||
if UI_Eq (Numerator (U), Uint_1) then
|
||||
if Rbase (U) = 2 or else Rbase (U) = 10 then
|
||||
return True;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return
|
||||
(UI_Is_In_Int_Range (Norm_Num (U))
|
||||
and then
|
||||
UI_Is_In_Int_Range (Norm_Den (U)));
|
||||
end Is_Handled_Scale_Factor;
|
||||
|
||||
----------------------
|
||||
-- Get_Encoded_Name --
|
||||
----------------------
|
||||
@ -671,12 +645,10 @@ package body Exp_Dbug is
|
||||
|
||||
Has_Suffix := True;
|
||||
|
||||
-- Fixed-point case: generate GNAT encodings when asked to or when we
|
||||
-- know the back-end will not be able to handle the scale factor.
|
||||
-- Fixed-point case: generate GNAT encodings when asked to
|
||||
|
||||
if Is_Fixed_Point_Type (E)
|
||||
and then (GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal
|
||||
or else not Is_Handled_Scale_Factor (Small_Value (E)))
|
||||
and then GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal
|
||||
then
|
||||
Get_External_Name (E, True, "XF_");
|
||||
Add_Real_To_Buffer (Delta_Value (E));
|
||||
|
@ -1743,24 +1743,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
|
||||
gnu_type = make_signed_type (esize);
|
||||
|
||||
/* Try to decode the scale factor and to save it for the fixed-point
|
||||
types debug hook. */
|
||||
|
||||
/* There are various ways to describe the scale factor, however there
|
||||
are cases where back-end internals cannot hold it. In such cases,
|
||||
we output invalid scale factor for such cases (i.e. the 0/0
|
||||
rational constant) but we expect GNAT to output GNAT encodings,
|
||||
then. Thus, keep this in sync with
|
||||
Exp_Dbug.Is_Handled_Scale_Factor. */
|
||||
|
||||
/* When encoded as 1/2**N or 1/10**N, describe the scale factor as a
|
||||
binary or decimal scale: it is easier to read for humans. */
|
||||
if (UI_Eq (Numerator (gnat_small_value), Uint_1)
|
||||
&& (Rbase (gnat_small_value) == 2
|
||||
|| Rbase (gnat_small_value) == 10))
|
||||
{
|
||||
/* Given RM restrictions on 'Small values, we assume here that
|
||||
the denominator fits in an int. */
|
||||
tree base
|
||||
= build_int_cst (integer_type_node, Rbase (gnat_small_value));
|
||||
tree exponent
|
||||
@ -1773,29 +1761,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
base, exponent));
|
||||
}
|
||||
|
||||
/* Default to arbitrary scale factors descriptions. */
|
||||
else
|
||||
/* Use the arbitrary scale factor description. Note that we support
|
||||
a Small_Value whose magnitude is larger than 64-bit even on 32-bit
|
||||
platforms, so we unconditionally use a (dummy) 128-bit type. */
|
||||
{
|
||||
const Uint num = Norm_Num (gnat_small_value);
|
||||
const Uint den = Norm_Den (gnat_small_value);
|
||||
const Uint gnat_num = Norm_Num (gnat_small_value);
|
||||
const Uint gnat_den = Norm_Den (gnat_small_value);
|
||||
tree gnu_small_type = make_unsigned_type (128);
|
||||
tree gnu_num = UI_To_gnu (gnat_num, gnu_small_type);
|
||||
tree gnu_den = UI_To_gnu (gnat_den, gnu_small_type);
|
||||
|
||||
if (UI_Is_In_Int_Range (num) && UI_Is_In_Int_Range (den))
|
||||
{
|
||||
tree gnu_num
|
||||
= build_int_cst (integer_type_node,
|
||||
UI_To_Int (Norm_Num (gnat_small_value)));
|
||||
tree gnu_den
|
||||
= build_int_cst (integer_type_node,
|
||||
UI_To_Int (Norm_Den (gnat_small_value)));
|
||||
scale_factor = build2 (RDIV_EXPR, integer_type_node,
|
||||
gnu_num, gnu_den);
|
||||
}
|
||||
else
|
||||
/* If compiler internals cannot represent arbitrary scale
|
||||
factors, output an invalid scale factor so that debugger
|
||||
don't try to handle them but so that we still have a type
|
||||
in the output. Note that GNAT */
|
||||
scale_factor = integer_zero_node;
|
||||
scale_factor
|
||||
= build2 (RDIV_EXPR, gnu_small_type, gnu_num, gnu_den);
|
||||
}
|
||||
|
||||
TYPE_FIXED_POINT_P (gnu_type) = 1;
|
||||
|
@ -628,16 +628,6 @@ gnat_get_fixed_point_type_info (const_tree type,
|
||||
/* We expect here only a finite set of pattern. See fixed-point types
|
||||
handling in gnat_to_gnu_entity. */
|
||||
|
||||
/* Put invalid values when compiler internals cannot represent the scale
|
||||
factor. */
|
||||
if (scale_factor == integer_zero_node)
|
||||
{
|
||||
info->scale_factor_kind = fixed_point_scale_factor_arbitrary;
|
||||
info->scale_factor.arbitrary.numerator = 0;
|
||||
info->scale_factor.arbitrary.denominator = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TREE_CODE (scale_factor) == RDIV_EXPR)
|
||||
{
|
||||
tree num = TREE_OPERAND (scale_factor, 0);
|
||||
@ -677,8 +667,8 @@ gnat_get_fixed_point_type_info (const_tree type,
|
||||
&& TREE_CODE (den) == INTEGER_CST);
|
||||
|
||||
info->scale_factor_kind = fixed_point_scale_factor_arbitrary;
|
||||
info->scale_factor.arbitrary.numerator = tree_to_uhwi (num);
|
||||
info->scale_factor.arbitrary.denominator = tree_to_shwi (den);
|
||||
info->scale_factor.arbitrary.numerator = num;
|
||||
info->scale_factor.arbitrary.denominator = den;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12973,18 +12973,19 @@ base_type_die (tree type, bool reverse)
|
||||
break;
|
||||
|
||||
case fixed_point_scale_factor_arbitrary:
|
||||
/* Arbitrary scale factors cannot be described in standard DWARF,
|
||||
yet. */
|
||||
/* Arbitrary scale factors cannot be described in standard DWARF. */
|
||||
if (!dwarf_strict)
|
||||
{
|
||||
/* Describe the scale factor as a rational constant. */
|
||||
const dw_die_ref scale_factor
|
||||
= new_die (DW_TAG_constant, comp_unit_die (), type);
|
||||
|
||||
add_AT_unsigned (scale_factor, DW_AT_GNU_numerator,
|
||||
fpt_info.scale_factor.arbitrary.numerator);
|
||||
add_AT_int (scale_factor, DW_AT_GNU_denominator,
|
||||
fpt_info.scale_factor.arbitrary.denominator);
|
||||
add_scalar_info (scale_factor, DW_AT_GNU_numerator,
|
||||
fpt_info.scale_factor.arbitrary.numerator,
|
||||
dw_scalar_form_constant, NULL);
|
||||
add_scalar_info (scale_factor, DW_AT_GNU_denominator,
|
||||
fpt_info.scale_factor.arbitrary.denominator,
|
||||
dw_scalar_form_constant, NULL);
|
||||
|
||||
add_AT_die_ref (base_type_result, DW_AT_small, scale_factor);
|
||||
}
|
||||
|
@ -362,23 +362,18 @@ enum fixed_point_scale_factor
|
||||
|
||||
struct fixed_point_type_info
|
||||
{
|
||||
/* A scale factor is the value one has to multiply with physical data in
|
||||
order to get the fixed point logical data. The DWARF standard enables one
|
||||
to encode it in three ways. */
|
||||
/* The scale factor is the value one has to multiply the actual data with
|
||||
to get the fixed point value. We support three ways to encode it. */
|
||||
enum fixed_point_scale_factor scale_factor_kind;
|
||||
union
|
||||
{
|
||||
/* For binary scale factor, the scale factor is: 2 ** binary. */
|
||||
/* For a binary scale factor, the scale factor is 2 ** binary. */
|
||||
int binary;
|
||||
/* For decimal scale factor, the scale factor is: 10 ** binary. */
|
||||
/* For a decimal scale factor, the scale factor is 10 ** decimal. */
|
||||
int decimal;
|
||||
/* For arbitrary scale factor, the scale factor is:
|
||||
/* For an arbitrary scale factor, the scale factor is the ratio
|
||||
numerator / denominator. */
|
||||
struct
|
||||
{
|
||||
unsigned HOST_WIDE_INT numerator;
|
||||
HOST_WIDE_INT denominator;
|
||||
} arbitrary;
|
||||
struct { tree numerator; tree denominator; } arbitrary;
|
||||
} scale_factor;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user