Rewrite GNAT-encoded fixed point types in DWARF reader

gdb currently supports two different styles of fixed-point.  The
original style, where fixed point types are "GNAT encoded", is handled
primarily in the Ada code.  The newer style, encoded using DWARF, is
handled by the core of gdb.

This patch changes gdb to read the GNAT encodings in the DWARF reader
as well.  This removes some code and unifies the two paths.  As a
result, GNAT-encoded fixed-point now works a bit better.

One possible drawback of this change is that, if someone uses stabs,
then fixed-point might now stop working.  I consider stabs to be fully
obsolete, though, so I don't intend to address this.

gdb/ChangeLog
2021-03-02  Tom Tromey  <tromey@adacore.com>

	* ada-lang.c (cast_from_gnat_encoded_fixed_point_type)
	(cast_to_gnat_encoded_fixed_point_type): Remove.
	(ada_value_cast, ada_evaluate_subexp): Update.
	(gnat_encoded_fixed_point_type_info)
	(ada_is_gnat_encoded_fixed_point_type)
	(gnat_encoded_fixed_point_delta)
	(gnat_encoded_fixed_point_scaling_factor): Remove.
	* ada-lang.h (ada_is_gnat_encoded_fixed_point_type)
	(gnat_encoded_fixed_point_delta)
	(gnat_encoded_fixed_point_scaling_factor): Don't declare.
	* ada-typeprint.c (print_gnat_encoded_fixed_point_type): Remove.
	(ada_print_type): Update.
	* ada-valprint.c (ada_value_print_num): Update.
	* dwarf2/read.c (ada_get_gnat_encoded_number)
	(ada_get_gnat_encoded_ratio): New functions.
	(finish_fixed_point_type): Use them.  Add parameters.
	(GNAT_FIXED_POINT_SUFFIX): New define.
	(gnat_encoded_fixed_point_type_info): New function.
	(read_base_type): Handle gnat encodings.

gdb/testsuite/ChangeLog
2021-03-02  Tom Tromey  <tromey@adacore.com>

	* gdb.ada/fixed_points.exp: Remove most special cases for minimal
	encodings.
This commit is contained in:
Tom Tromey 2021-03-02 13:08:24 -07:00
parent 5f9febe0f6
commit bbcdf9ab73
8 changed files with 195 additions and 304 deletions

View file

@ -1,3 +1,25 @@
2021-03-02 Tom Tromey <tromey@adacore.com>
* ada-lang.c (cast_from_gnat_encoded_fixed_point_type)
(cast_to_gnat_encoded_fixed_point_type): Remove.
(ada_value_cast, ada_evaluate_subexp): Update.
(gnat_encoded_fixed_point_type_info)
(ada_is_gnat_encoded_fixed_point_type)
(gnat_encoded_fixed_point_delta)
(gnat_encoded_fixed_point_scaling_factor): Remove.
* ada-lang.h (ada_is_gnat_encoded_fixed_point_type)
(gnat_encoded_fixed_point_delta)
(gnat_encoded_fixed_point_scaling_factor): Don't declare.
* ada-typeprint.c (print_gnat_encoded_fixed_point_type): Remove.
(ada_print_type): Update.
* ada-valprint.c (ada_value_print_num): Update.
* dwarf2/read.c (ada_get_gnat_encoded_number)
(ada_get_gnat_encoded_ratio): New functions.
(finish_fixed_point_type): Use them. Add parameters.
(GNAT_FIXED_POINT_SUFFIX): New define.
(gnat_encoded_fixed_point_type_info): New function.
(read_base_type): Handle gnat encodings.
2021-03-02 Tom Tromey <tromey@adacore.com>
* ada-lang.c (ada_fold_name, ada_variant_discrim_name)

View file

@ -9129,33 +9129,6 @@ unwrap_value (struct value *val)
}
}
static struct value *
cast_from_gnat_encoded_fixed_point_type (struct type *type, struct value *arg)
{
struct value *scale
= gnat_encoded_fixed_point_scaling_factor (value_type (arg));
arg = value_cast (value_type (scale), arg);
arg = value_binop (arg, scale, BINOP_MUL);
return value_cast (type, arg);
}
static struct value *
cast_to_gnat_encoded_fixed_point_type (struct type *type, struct value *arg)
{
if (type == value_type (arg))
return arg;
struct value *scale = gnat_encoded_fixed_point_scaling_factor (type);
if (ada_is_gnat_encoded_fixed_point_type (value_type (arg)))
arg = cast_from_gnat_encoded_fixed_point_type (value_type (scale), arg);
else
arg = value_cast (value_type (scale), arg);
arg = value_binop (arg, scale, BINOP_DIV);
return value_cast (type, arg);
}
/* Given two array types T1 and T2, return nonzero iff both arrays
contain the same number of elements. */
@ -9655,12 +9628,6 @@ ada_value_cast (struct type *type, struct value *arg2)
if (type == ada_check_typedef (value_type (arg2)))
return arg2;
if (ada_is_gnat_encoded_fixed_point_type (type))
return cast_to_gnat_encoded_fixed_point_type (type, arg2);
if (ada_is_gnat_encoded_fixed_point_type (value_type (arg2)))
return cast_from_gnat_encoded_fixed_point_type (type, arg2);
return value_cast (type, arg2);
}
@ -10058,11 +10025,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
{
/* Nothing. */
}
else if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1)))
arg2 = cast_to_gnat_encoded_fixed_point_type (value_type (arg1), arg2);
else if (ada_is_gnat_encoded_fixed_point_type (value_type (arg2)))
error
(_("Fixed-point values must be assigned to fixed-point variables"));
else
arg2 = coerce_for_assign (value_type (arg1), arg2);
return ada_value_assign (arg1, arg2);
@ -10086,14 +10048,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
type = value_type (arg1);
while (type->code () == TYPE_CODE_REF)
type = TYPE_TARGET_TYPE (type);
if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1))
|| ada_is_gnat_encoded_fixed_point_type (value_type (arg2)))
{
if (value_type (arg1) != value_type (arg2))
error (_("Operands of fixed-point addition must have the same type"));
}
else
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
arg1 = value_binop (arg1, arg2, BINOP_ADD);
/* We need to special-case the result of adding to a range.
This is done for the benefit of "ptype". gdb's Ada support
@ -10122,15 +10077,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
type = value_type (arg1);
while (type->code () == TYPE_CODE_REF)
type = TYPE_TARGET_TYPE (type);
if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1))
|| ada_is_gnat_encoded_fixed_point_type (value_type (arg2)))
{
if (value_type (arg1) != value_type (arg2))
error (_("Operands of fixed-point subtraction "
"must have the same type"));
}
else
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
arg1 = value_binop (arg1, arg2, BINOP_SUB);
/* We need to special-case the result of adding to a range.
This is done for the benefit of "ptype". gdb's Ada support
@ -10156,10 +10103,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
else
{
type = builtin_type (exp->gdbarch)->builtin_double;
if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1)))
arg1 = cast_from_gnat_encoded_fixed_point_type (type, arg1);
if (ada_is_gnat_encoded_fixed_point_type (value_type (arg2)))
arg2 = cast_from_gnat_encoded_fixed_point_type (type, arg2);
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
return ada_value_binop (arg1, arg2, op);
}
@ -10186,8 +10129,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
arg1 = evaluate_subexp (nullptr, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
else if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1)))
return value_cast (value_type (arg1), value_neg (arg1));
else
{
unop_promote (exp->language_defn, exp->gdbarch, &arg1);
@ -11053,41 +10994,6 @@ nosideret:
}
/* Fixed point */
/* If TYPE encodes an Ada fixed-point type, return the suffix of the
type name that encodes the 'small and 'delta information.
Otherwise, return NULL. */
static const char *
gnat_encoded_fixed_point_type_info (struct type *type)
{
const char *name = ada_type_name (type);
enum type_code code = (type == NULL) ? TYPE_CODE_UNDEF : type->code ();
if ((code == TYPE_CODE_INT || code == TYPE_CODE_RANGE) && name != NULL)
{
const char *tail = strstr (name, "___XF_");
if (tail == NULL)
return NULL;
else
return tail + 5;
}
else if (code == TYPE_CODE_RANGE && TYPE_TARGET_TYPE (type) != type)
return gnat_encoded_fixed_point_type_info (TYPE_TARGET_TYPE (type));
else
return NULL;
}
/* Returns non-zero iff TYPE represents an Ada fixed-point type. */
int
ada_is_gnat_encoded_fixed_point_type (struct type *type)
{
return gnat_encoded_fixed_point_type_info (type) != NULL;
}
/* Return non-zero iff TYPE represents a System.Address type. */
int
@ -11096,60 +11002,6 @@ ada_is_system_address_type (struct type *type)
return (type->name () && strcmp (type->name (), "system__address") == 0);
}
/* Assuming that TYPE is the representation of an Ada fixed-point
type, return the target floating-point type to be used to represent
of this type during internal computation. */
static struct type *
ada_scaling_type (struct type *type)
{
return builtin_type (type->arch ())->builtin_long_double;
}
/* Assuming that TYPE is the representation of an Ada fixed-point
type, return its delta, or NULL if the type is malformed and the
delta cannot be determined. */
struct value *
gnat_encoded_fixed_point_delta (struct type *type)
{
const char *encoding = gnat_encoded_fixed_point_type_info (type);
struct type *scale_type = ada_scaling_type (type);
long long num, den;
if (sscanf (encoding, "_%lld_%lld", &num, &den) < 2)
return nullptr;
else
return value_binop (value_from_longest (scale_type, num),
value_from_longest (scale_type, den), BINOP_DIV);
}
/* Assuming that ada_is_gnat_encoded_fixed_point_type (TYPE), return
the scaling factor ('SMALL value) associated with the type. */
struct value *
gnat_encoded_fixed_point_scaling_factor (struct type *type)
{
const char *encoding = gnat_encoded_fixed_point_type_info (type);
struct type *scale_type = ada_scaling_type (type);
long long num0, den0, num1, den1;
int n;
n = sscanf (encoding, "_%lld_%lld_%lld_%lld",
&num0, &den0, &num1, &den1);
if (n < 2)
return value_from_longest (scale_type, 1);
else if (n == 4)
return value_binop (value_from_longest (scale_type, num1),
value_from_longest (scale_type, den1), BINOP_DIV);
else
return value_binop (value_from_longest (scale_type, num0),
value_from_longest (scale_type, den0), BINOP_DIV);
}
/* Range types */

View file

@ -280,14 +280,8 @@ extern struct type *ada_aligned_type (struct type *);
extern const gdb_byte *ada_aligned_value_addr (struct type *,
const gdb_byte *);
extern int ada_is_gnat_encoded_fixed_point_type (struct type *);
extern int ada_is_system_address_type (struct type *);
extern struct value *gnat_encoded_fixed_point_delta (struct type *);
extern struct value *gnat_encoded_fixed_point_scaling_factor (struct type *);
extern int ada_which_variant_applies (struct type *, struct value *);
extern struct type *ada_to_fixed_type (struct type *, const gdb_byte *,

View file

@ -339,31 +339,6 @@ print_enum_type (struct type *type, struct ui_file *stream)
fprintf_filtered (stream, ")");
}
/* Print representation of Ada fixed-point type TYPE on STREAM. */
static void
print_gnat_encoded_fixed_point_type (struct type *type, struct ui_file *stream)
{
struct value *delta = gnat_encoded_fixed_point_delta (type);
struct value *small = gnat_encoded_fixed_point_scaling_factor (type);
if (delta == nullptr)
fprintf_filtered (stream, "delta ??");
else
{
std::string str;
str = target_float_to_string (value_contents (delta),
value_type (delta), "%g");
fprintf_filtered (stream, "delta %s", str.c_str());
if (!value_equal (delta, small))
{
str = target_float_to_string (value_contents (small),
value_type (small), "%g");
fprintf_filtered (stream, " <'small = %s>", str.c_str());
}
}
}
/* Print simple (constrained) array type TYPE on STREAM. LEVEL is the
recursion (indentation) level, in case the element type itself has
nested structure, and SHOW is the number of levels of internal
@ -1026,27 +1001,22 @@ ada_print_type (struct type *type0, const char *varstring,
fprintf_filtered (stream, "(false, true)");
break;
case TYPE_CODE_INT:
if (ada_is_gnat_encoded_fixed_point_type (type))
print_gnat_encoded_fixed_point_type (type, stream);
else
{
const char *name = ada_type_name (type);
{
const char *name = ada_type_name (type);
if (!ada_is_range_type_name (name))
fprintf_styled (stream, metadata_style.style (),
_("<%s-byte integer>"),
pulongest (TYPE_LENGTH (type)));
else
{
fprintf_filtered (stream, "range ");
print_range_type (type, stream, 1 /* bounds_prefered_p */);
}
}
if (!ada_is_range_type_name (name))
fprintf_styled (stream, metadata_style.style (),
_("<%s-byte integer>"),
pulongest (TYPE_LENGTH (type)));
else
{
fprintf_filtered (stream, "range ");
print_range_type (type, stream, 1 /* bounds_prefered_p */);
}
}
break;
case TYPE_CODE_RANGE:
if (ada_is_gnat_encoded_fixed_point_type (type))
print_gnat_encoded_fixed_point_type (type, stream);
else if (is_fixed_point_type (type))
if (is_fixed_point_type (type))
{
fprintf_filtered (stream, "<");
print_type_fixed_point (type, stream);

View file

@ -741,22 +741,10 @@ ada_value_print_num (struct value *val, struct ui_file *stream, int recurse,
struct type *type = ada_check_typedef (value_type (val));
const gdb_byte *valaddr = value_contents_for_printing (val);
if (ada_is_gnat_encoded_fixed_point_type (type))
{
struct value *scale = gnat_encoded_fixed_point_scaling_factor (type);
val = value_cast (value_type (scale), val);
val = value_binop (val, scale, BINOP_MUL);
const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g";
std::string str
= target_float_to_string (value_contents (val), value_type (val), fmt);
fputs_filtered (str.c_str (), stream);
return;
}
else if (type->code () == TYPE_CODE_RANGE
&& (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM
|| TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_BOOL
|| TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR))
if (type->code () == TYPE_CODE_RANGE
&& (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM
|| TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_BOOL
|| TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR))
{
/* For enum-valued ranges, we want to recurse, because we'll end
up printing the constant's name rather than its numeric

View file

@ -18408,24 +18408,77 @@ get_dwarf2_unsigned_rational_constant (struct die_info *die,
*denominator = std::move (denom);
}
/* Assuming that ENCODING is a string whose contents starting at the
K'th character is "_nn" where "nn" is a decimal number, scan that
number and set RESULT to the value. K is updated to point to the
character immediately following the number.
If the string does not conform to the format described above, false
is returned, and K may or may not be changed. */
static bool
ada_get_gnat_encoded_number (const char *encoding, int &k, gdb_mpz *result)
{
/* The next character should be an underscore ('_') followed
by a digit. */
if (encoding[k] != '_' || !isdigit (encoding[k + 1]))
return false;
/* Skip the underscore. */
k++;
int start = k;
/* Determine the number of digits for our number. */
while (isdigit (encoding[k]))
k++;
if (k == start)
return false;
std::string copy (&encoding[start], k - start);
if (mpz_set_str (result->val, copy.c_str (), 10) == -1)
return false;
return true;
}
/* Scan two numbers from ENCODING at OFFSET, assuming the string is of
the form _NN_DD, where NN and DD are decimal numbers. Set NUM and
DENOM, update OFFSET, and return true on success. Return false on
failure. */
static bool
ada_get_gnat_encoded_ratio (const char *encoding, int &offset,
gdb_mpz *num, gdb_mpz *denom)
{
if (!ada_get_gnat_encoded_number (encoding, offset, num))
return false;
return ada_get_gnat_encoded_number (encoding, offset, denom);
}
/* Assuming DIE corresponds to a fixed point type, finish the creation
of the corresponding TYPE by setting its type-specific data.
CU is the DIE's CU. */
of the corresponding TYPE by setting its type-specific data. CU is
the DIE's CU. SUFFIX is the "XF" type name suffix coming from GNAT
encodings. It is nullptr if the GNAT encoding should be
ignored. */
static void
finish_fixed_point_type (struct type *type, struct die_info *die,
struct dwarf2_cu *cu)
finish_fixed_point_type (struct type *type, const char *suffix,
struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
gdb_assert (type->code () == TYPE_CODE_FIXED_POINT
&& TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FIXED_POINT);
attr = dwarf2_attr (die, DW_AT_binary_scale, cu);
if (!attr)
attr = dwarf2_attr (die, DW_AT_decimal_scale, cu);
if (!attr)
attr = dwarf2_attr (die, DW_AT_small, cu);
/* If GNAT encodings are preferred, don't examine the
attributes. */
struct attribute *attr = nullptr;
if (suffix == nullptr)
{
attr = dwarf2_attr (die, DW_AT_binary_scale, cu);
if (attr == nullptr)
attr = dwarf2_attr (die, DW_AT_decimal_scale, cu);
if (attr == nullptr)
attr = dwarf2_attr (die, DW_AT_small, cu);
}
/* Numerator and denominator of our fixed-point type's scaling factor.
The default is a scaling factor of 1, which we use as a fallback
@ -18438,11 +18491,29 @@ finish_fixed_point_type (struct type *type, struct die_info *die,
if (attr == nullptr)
{
/* Scaling factor not found. Assume a scaling factor of 1,
and hope for the best. At least the user will be able to see
the encoded value. */
complaint (_("no scale found for fixed-point type (DIE at %s)"),
sect_offset_str (die->sect_off));
int offset = 0;
if (suffix != nullptr
&& ada_get_gnat_encoded_ratio (suffix, offset, &scale_num,
&scale_denom)
/* The number might be encoded as _nn_dd_nn_dd, where the
second ratio is the 'small value. In this situation, we
want the second value. */
&& (suffix[offset] != '_'
|| ada_get_gnat_encoded_ratio (suffix, offset, &scale_num,
&scale_denom)))
{
/* Found it. */
}
else
{
/* Scaling factor not found. Assume a scaling factor of 1,
and hope for the best. At least the user will be able to
see the encoded value. */
scale_num = 1;
scale_denom = 1;
complaint (_("no scale found for fixed-point type (DIE at %s)"),
sect_offset_str (die->sect_off));
}
}
else if (attr->name == DW_AT_binary_scale)
{
@ -18486,6 +18557,20 @@ finish_fixed_point_type (struct type *type, struct die_info *die,
mpq_canonicalize (scaling_factor.val);
}
/* The gnat-encoding suffix for fixed point. */
#define GNAT_FIXED_POINT_SUFFIX "___XF_"
/* If NAME encodes an Ada fixed-point type, return a pointer to the
"XF" suffix of the name. The text after this is what encodes the
'small and 'delta information. Otherwise, return nullptr. */
static const char *
gnat_encoded_fixed_point_type_info (const char *name)
{
return strstr (name, GNAT_FIXED_POINT_SUFFIX);
}
/* Allocate a floating-point type of size BITS and name NAME. Pass NAME_HINT
(which may be different from NAME) to the architecture back-end to allow
it to guess the correct format if necessary. */
@ -18674,20 +18759,38 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
of fixed point types for which GNAT is unable to provide
the scaling factor via the standard DWARF mechanisms, and
for which the info is provided via the GNAT encodings instead.
This is likely what this DIE is about.
Ideally, GNAT should be declaring this type the same way
it declares other fixed point types when using the legacy
GNAT encoding, which is to use a simple signed or unsigned
base type. A report to the GNAT team has been created to
look into it. In the meantime, pretend this type is a simple
signed or unsigned integral, rather than a fixed point type,
to avoid any confusion later on as to how to process this type. */
This is likely what this DIE is about. */
encoding = (encoding == DW_ATE_signed_fixed
? DW_ATE_signed
: DW_ATE_unsigned);
}
/* With GNAT encodings, fixed-point information will be encoded in
the type name. Note that this can also occur with the above
zero-over-zero case, which is why this is a separate "if" rather
than an "else if". */
const char *gnat_encoding_suffix = nullptr;
if ((encoding == DW_ATE_signed || encoding == DW_ATE_unsigned)
&& cu->language == language_ada
&& name != nullptr)
{
gnat_encoding_suffix = gnat_encoded_fixed_point_type_info (name);
if (gnat_encoding_suffix != nullptr)
{
gdb_assert (startswith (gnat_encoding_suffix,
GNAT_FIXED_POINT_SUFFIX));
name = obstack_strndup (&cu->per_objfile->objfile->objfile_obstack,
name, gnat_encoding_suffix - name);
/* Use -1 here so that SUFFIX points at the "_" after the
"XF". */
gnat_encoding_suffix += strlen (GNAT_FIXED_POINT_SUFFIX) - 1;
encoding = (encoding == DW_ATE_signed
? DW_ATE_signed_fixed
: DW_ATE_unsigned_fixed);
}
}
switch (encoding)
{
case DW_ATE_address:
@ -18766,11 +18869,11 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
break;
case DW_ATE_signed_fixed:
type = init_fixed_point_type (objfile, bits, 0, name);
finish_fixed_point_type (type, die, cu);
finish_fixed_point_type (type, gnat_encoding_suffix, die, cu);
break;
case DW_ATE_unsigned_fixed:
type = init_fixed_point_type (objfile, bits, 1, name);
finish_fixed_point_type (type, die, cu);
finish_fixed_point_type (type, gnat_encoding_suffix, die, cu);
break;
default:

View file

@ -1,3 +1,8 @@
2021-03-02 Tom Tromey <tromey@adacore.com>
* gdb.ada/fixed_points.exp: Remove most special cases for minimal
encodings.
2021-02-27 Lancelot Six <lsix@lancelotix.com>
PR gdb/27393

View file

@ -49,84 +49,41 @@ foreach_with_prefix scenario {all minimal} {
gdb_test "print Overprecise_Object" \
"= 0.13579135791"
gdb_test_multiple "ptype Overprecise_Object" "" {
-re "type = <2-byte fixed point \\(small = 135791357913579/1000000000000000\\)>\r\n$gdb_prompt $" {
pass $gdb_test_name
}
-re "type = delta 0.135791\r\n$gdb_prompt $" {
# The (legacy) output we obtain when the compiler described
# our fixed point types using the GNAT encodings rather than
# standard DWARF. OK as well.
pass $gdb_test_name
}
}
gdb_test "ptype Overprecise_Object" \
"type = <2-byte fixed point \\(small = 135791357913579/1000000000000000\\)>"
# FP*_Var...
gdb_test "print fp1_var" \
" = 0.25"
gdb_test_multiple "ptype fp1_var" "" {
-re "type = <1-byte fixed point \\(small = 1/16\\)>\r\n$gdb_prompt $" {
pass $gdb_test_name
}
-re "type = delta 0\\.1 <'small = 0\\.0625>\r\n$gdb_prompt $" {
# The (legacy) output we obtain when the compiler described
# our fixed point types using the GNAT encodings rather than
# standard DWARF. OK as well.
pass $gdb_test_name
}
}
gdb_test "ptype fp1_var" "type = <1-byte fixed point \\(small = 1/16\\)>"
gdb_test "print fp2_var" \
" = -0.01"
gdb_test_multiple "ptype fp2_var" "" {
-re "type = <8-byte fixed point \\(small = 1/100\\)>\r\n$gdb_prompt $" {
pass $gdb_test_name
}
-re "type = delta 0\\.01\r\n$gdb_prompt $" {
# The (legacy) output we obtain when the compiler described
# our fixed point types using the GNAT encodings rather than
# standard DWARF. OK as well.
pass $gdb_test_name
}
}
gdb_test "ptype fp2_var" "type = <8-byte fixed point \\(small = 1/100\\)>"
gdb_test "print fp3_var" \
" = 0.1"
gdb_test_multiple "ptype fp3_var" "" {
-re "type = <1-byte fixed point \\(small = 1/30\\)>\r\n$gdb_prompt $" {
pass $gdb_test_name
}
-re "type = delta 0\\.1 <'small = 0\\.0333333>\r\n$gdb_prompt $" {
# The (legacy) output we obtain when the compiler described
# our fixed point types using the GNAT encodings rather than
# standard DWARF. OK as well.
pass $gdb_test_name
}
}
gdb_test "ptype fp3_var" "type = <1-byte fixed point \\(small = 1/30\\)>"
# One of the benefits of minimal encoding is that operations work
# a bit better.
if {$scenario == "minimal"} {
gdb_test "print fp2_var + 0" \
" = -0.01"
gdb_test "print 0 + fp2_var" \
" = -0.01"
gdb_test "print fp2_var - 0" \
" = -0.01"
gdb_test "print fp2_var + 0" \
" = -0.01"
gdb_test "print 0 + fp2_var" \
" = -0.01"
gdb_test "print fp2_var - 0" \
" = -0.01"
set fp4 "= 2e-07"
gdb_test "print fp4_var" $fp4
gdb_test "print fp4_var * 1" $fp4
gdb_test "print 1 * fp4_var" $fp4
gdb_test "print fp4_var / 1" $fp4
set fp4 "= 2e-07"
gdb_test "print fp4_var" $fp4
gdb_test "print fp4_var * 1" $fp4
gdb_test "print 1 * fp4_var" $fp4
gdb_test "print fp4_var / 1" $fp4
# This only started working in GCC 11.
if {[test_compiler_info {gcc-11-*}]} {
gdb_test "print fp5_var" " = 3e-19"
}
# This only started working in GCC 11.
if {$scenario == "minimal" && [test_compiler_info {gcc-11-*}]} {
gdb_test "print fp5_var" " = 3e-19"
}
}