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:
parent
4a270568d9
commit
0841c79a3d
5 changed files with 70 additions and 1 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
Chris January <chris.january@arm.com>
|
||||||
|
David Lecomber <david.lecomber@arm.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com>
|
2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* f-lang.c (build_fortran_types): Use TYPE_CODE_CHAR for character
|
* f-lang.c (build_fortran_types): Use TYPE_CODE_CHAR for character
|
||||||
|
|
|
@ -168,6 +168,7 @@ static int parse_number (struct parser_state *, const char *, int,
|
||||||
%token <voidval> DOLLAR_VARIABLE
|
%token <voidval> DOLLAR_VARIABLE
|
||||||
|
|
||||||
%token <opcode> ASSIGN_MODIFY
|
%token <opcode> ASSIGN_MODIFY
|
||||||
|
%token <opcode> UNOP_INTRINSIC
|
||||||
|
|
||||||
%left ','
|
%left ','
|
||||||
%left ABOVE_COMMA
|
%left ABOVE_COMMA
|
||||||
|
@ -252,6 +253,10 @@ exp : exp '('
|
||||||
OP_F77_UNDETERMINED_ARGLIST); }
|
OP_F77_UNDETERMINED_ARGLIST); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
exp : UNOP_INTRINSIC '(' exp ')'
|
||||||
|
{ write_exp_elt_opcode (pstate, $1); }
|
||||||
|
;
|
||||||
|
|
||||||
arglist :
|
arglist :
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -945,7 +950,8 @@ static const struct token f77_keywords[] =
|
||||||
{ "real", REAL_KEYWORD, BINOP_END, true },
|
{ "real", REAL_KEYWORD, BINOP_END, true },
|
||||||
/* The following correspond to actual functions in Fortran and are case
|
/* The following correspond to actual functions in Fortran and are case
|
||||||
insensitive. */
|
insensitive. */
|
||||||
{ "kind", KIND, BINOP_END, false }
|
{ "kind", KIND, BINOP_END, false },
|
||||||
|
{ "abs", UNOP_INTRINSIC, UNOP_ABS, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Implementation of a dynamically expandable buffer for processing input
|
/* Implementation of a dynamically expandable buffer for processing input
|
||||||
|
|
39
gdb/f-lang.c
39
gdb/f-lang.c
|
@ -34,7 +34,9 @@
|
||||||
#include "cp-support.h"
|
#include "cp-support.h"
|
||||||
#include "charset.h"
|
#include "charset.h"
|
||||||
#include "c-lang.h"
|
#include "c-lang.h"
|
||||||
|
#include "target-float.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
/* Local functions */
|
/* Local functions */
|
||||||
|
|
||||||
|
@ -239,6 +241,20 @@ f_collect_symbol_completion_matches (completion_tracker &tracker,
|
||||||
text, word, ":", code);
|
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. */
|
/* Special expression evaluation cases for Fortran. */
|
||||||
struct value *
|
struct value *
|
||||||
evaluate_subexp_f (struct type *expect_type, struct expression *exp,
|
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;
|
*pos -= 1;
|
||||||
return evaluate_subexp_standard (expect_type, exp, pos, noside);
|
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:
|
case UNOP_KIND:
|
||||||
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
||||||
type = value_type (arg1);
|
type = value_type (arg1);
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* gdb.fortran/intrinsics.exp: Extend to cover ABS.
|
||||||
|
|
||||||
2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com>
|
2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* gdb.fortran/type-kinds.exp: Update expected results.
|
* gdb.fortran/type-kinds.exp: Update expected results.
|
||||||
|
|
|
@ -40,3 +40,12 @@ gdb_test "p kind (l2)" " = 2"
|
||||||
gdb_test "p kind (l4)" " = 4"
|
gdb_test "p kind (l4)" " = 4"
|
||||||
gdb_test "p kind (l8)" " = 8"
|
gdb_test "p kind (l8)" " = 8"
|
||||||
gdb_test "p kind (s1)" "argument to kind must be an intrinsic type"
|
gdb_test "p kind (s1)" "argument to kind must be an intrinsic type"
|
||||||
|
|
||||||
|
# Test ABS
|
||||||
|
|
||||||
|
gdb_test "p abs (-11)" " = 11"
|
||||||
|
gdb_test "p abs (11)" " = 11"
|
||||||
|
# Use `$decimal` to match here as we depend on host floating point
|
||||||
|
# rounding, which can vary.
|
||||||
|
gdb_test "p abs (-9.1)" " = 9.$decimal"
|
||||||
|
gdb_test "p abs (9.1)" " = 9.$decimal"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue