aboutsummaryrefslogtreecommitdiff
path: root/gdb/f-lang.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-01-16 16:42:10 +0000
committerAndrew Burgess <andrew.burgess@embecosm.com>2019-03-06 18:11:31 +0000
commit4d00f5d8f6c4a1c9f334b1abb45b9ce05fb45b0a (patch)
tree24f8cddb29a1036f7f0f23d6a2178f593a2daeef /gdb/f-lang.c
parente454224fa82aa52a1288a3d6a2e26e8d224d732a (diff)
downloadgdb-4d00f5d8f6c4a1c9f334b1abb45b9ce05fb45b0a.zip
gdb-4d00f5d8f6c4a1c9f334b1abb45b9ce05fb45b0a.tar.gz
gdb-4d00f5d8f6c4a1c9f334b1abb45b9ce05fb45b0a.tar.bz2
gdb/fortran: Add Fortran 'kind' intrinsic and keyword
The 'kind' keyword has two uses in Fortran, it is the name of a builtin intrinsic function, and it is also a keyword used to create a type of a specific kind. This commit adds support for using kind as an intrinsic function, and also adds some initial support for using kind to create types of a specific kind. This commit only allows the creation of the type 'character(kind=1)', however, it will be easy enough to extend this in future to support more type kinds. The kind of any expression can be queried using the kind intrinsic function. At the moment the kind returned corresponds to the size of the type, this matches how gfortran handles kinds. However, the correspondence between kind and type size depends on the compiler and/or the specific target, so this might not be correct for everyone. If we want to support different compilers/targets in future the code to compute the kind from a type will need to be updated. gdb/ChangeLog: * expprint.c (dump_subexp_body_standard): Support UNOP_KIND. * f-exp.y: Define 'KIND' token. (exp): New pattern for KIND expressions. (ptype): Handle types with a kind extension. (direct_abs_decl): Extend to spot kind extensions. (f77_keywords): Add 'kind' to the list. (push_kind_type): New function. (convert_to_kind_type): New function. * f-lang.c (evaluate_subexp_f): Support UNOP_KIND. * parse.c (operator_length_standard): Likewise. * parser-defs.h (enum type_pieces): Add tp_kind. * std-operator.def: Add UNOP_KIND. gdb/testsuite/ChangeLog: * gdb.fortran/intrinsics.exp: New file. * gdb.fortran/intrinsics.f90: New file. * gdb.fortran/type-kinds.exp: New file.
Diffstat (limited to 'gdb/f-lang.c')
-rw-r--r--gdb/f-lang.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 5beb46c..34ebfd9 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -244,8 +244,43 @@ struct value *
evaluate_subexp_f (struct type *expect_type, struct expression *exp,
int *pos, enum noside noside)
{
- /* Currently no special handling is required. */
- return evaluate_subexp_standard (expect_type, exp, pos, noside);
+ struct value *arg1 = NULL;
+ enum exp_opcode op;
+ int pc;
+ struct type *type;
+
+ pc = *pos;
+ *pos += 1;
+ op = exp->elts[pc].opcode;
+
+ switch (op)
+ {
+ default:
+ *pos -= 1;
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+
+ case UNOP_KIND:
+ arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+ type = value_type (arg1);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_MODULE:
+ case TYPE_CODE_FUNC:
+ error (_("argument to kind must be an intrinsic type"));
+ }
+
+ if (!TYPE_TARGET_TYPE (type))
+ return value_from_longest (builtin_type (exp->gdbarch)->builtin_int,
+ TYPE_LENGTH (type));
+ return value_from_longest (builtin_type (exp->gdbarch)->builtin_int,
+ TYPE_LENGTH (TYPE_TARGET_TYPE(type)));
+ }
+
+ /* Should be unreachable. */
+ return nullptr;
}
static const char *f_extensions[] =