gdb/fortran: Add support for the ABS intrinsic function

Adds support for the abs intrinsic function, this requires adding a
new pattern to the Fortran parser.  Currently only float and integer
argument types are supported to ABS, complex is still not supported,
this can be added later if needed.

gdb/ChangeLog:

	* f-exp.y: New token, UNOP_INTRINSIC.
	(exp): New pattern using UNOP_INTRINSIC token.
	(f77_keywords): Add 'abs' keyword.
	* f-lang.c: Add 'target-float.h' and 'math.h' includes.
	(value_from_host_double): New function.
	(evaluate_subexp_f): Support UNOP_ABS.

gdb/testsuite/ChangeLog:

	* gdb.fortran/intrinsics.exp: Extend to cover ABS.
This commit is contained in:
Andrew Burgess 2019-01-18 14:44:48 +00:00
parent 4a270568d9
commit 0841c79a3d
5 changed files with 70 additions and 1 deletions

View file

@ -34,7 +34,9 @@
#include "cp-support.h"
#include "charset.h"
#include "c-lang.h"
#include "target-float.h"
#include <math.h>
/* Local functions */
@ -239,6 +241,20 @@ f_collect_symbol_completion_matches (completion_tracker &tracker,
text, word, ":", code);
}
/* Create and return a value object of TYPE containing the value D. The
TYPE must be of TYPE_CODE_FLT, and must be large enough to hold D once
it is converted to target format. */
static struct value *
value_from_host_double (struct type *type, double d)
{
struct value *value = allocate_value (type);
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
target_float_from_host_double (value_contents_raw (value),
value_type (value), d);
return value;
}
/* Special expression evaluation cases for Fortran. */
struct value *
evaluate_subexp_f (struct type *expect_type, struct expression *exp,
@ -259,6 +275,29 @@ evaluate_subexp_f (struct type *expect_type, struct expression *exp,
*pos -= 1;
return evaluate_subexp_standard (expect_type, exp, pos, noside);
case UNOP_ABS:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
return eval_skip_value (exp);
type = value_type (arg1);
switch (TYPE_CODE (type))
{
case TYPE_CODE_FLT:
{
double d
= fabs (target_float_to_host_double (value_contents (arg1),
value_type (arg1)));
return value_from_host_double (type, d);
}
case TYPE_CODE_INT:
{
LONGEST l = value_as_long (arg1);
l = llabs (l);
return value_from_longest (type, l);
}
}
error (_("ABS of type %s not supported"), TYPE_SAFE_NAME (type));
case UNOP_KIND:
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (arg1);