gdb/fortran: clean-up Fortran intrinsic types
authorNils-Christian Kempke <nils-christian.kempke@intel.com>
Mon, 11 Apr 2022 12:06:56 +0000 (14:06 +0200)
committerNils-Christian Kempke <nils-christian.kempke@intel.com>
Mon, 11 Apr 2022 12:06:56 +0000 (14:06 +0200)
The currently implemented intrinsic type handling for Fortran missed some
tokens and their parsing.  While still not all Fortran type kinds are
implemented this patch at least makes the currently handled types
consistent.  As an example for what this patch does, consider the
intrinsic type INTEGER.  GDB implemented the handling of the
keywords "integer" and "integer_2" but missed "integer_4" and "integer_8"
even though their corresponding internal types were already available as
the Fortran builtin types builtin_integer and builtin_integer_s8.
Similar problems applied to LOGICAL, REAL, and COMPLEX.  This patch adds
all missing tokens and their parsing.  Whenever a section containing the
type handling was touched, it also was reordered to be in a more easy to
grasp order.  All INTEGER/REAL/LOGICAL/COMPLEX types were grouped
together and ordered ascending in their size making a missing one more
easy to spot.

Before this change GDB would print the following when tyring to use the
INTEGER keywords:

   (gdb) set language fortran
   (gdb) ptype integer*1
   unsupported kind 1 for type integer
   (gdb) ptype integer_1
   No symbol table is loaded.  Use the "file" command.
   (gdb) ptype integer*2
   type = integer*2
   (gdb) ptype integer_2
   type = integer*2
   (gdb) ptype integer*4
   type = integer
   (gdb) ptype integer_4
   No symbol table is loaded.  Use the "file" command.
   (gdb) ptype integer*8
   type = integer*8
   (gdb) ptype integer_8
   No symbol table is loaded.  Use the "file" command.
   (gdb) ptype integer
   type = integer

With this patch all keywords are available and the GDB prints:

   (gdb) set language fortran
   (gdb) ptype integer*1
   type = integer*1
   (gdb) ptype integer_1
   type = integer*1
   (gdb) ptype integer*2
   type = integer*2
   (gdb) ptype integer_2
   type = integer*2
   (gdb) ptype integer*4
   type = integer*4
   (gdb) ptype integer_4
   type = integer*4
   (gdb) ptype integer*8
   type = integer*8
   (gdb) ptype integer_8
   type = integer*8
   (gdb) ptype integer
   type = integer

The described changes have been applied to INTEGER, REAL, COMPLEX,
and LOGICAL. Existing testcases have been adapted to reflect the
new behavior.  Tests for formerly missing types have been added.

gdb/f-exp.y
gdb/f-lang.c
gdb/f-lang.h
gdb/testsuite/gdb.fortran/types.exp

index a768134983b0bc40f1e9d273b8fef5e2dceb903b..bb8e2ba64752c8dafe14676f765174b181784137 100644 (file)
@@ -167,11 +167,12 @@ static int parse_number (struct parser_state *, const char *, int,
 
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
-%token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD 
+%token INT_S1_KEYWORD INT_S2_KEYWORD INT_KEYWORD INT_S4_KEYWORD INT_S8_KEYWORD
+%token LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD LOGICAL_KEYWORD LOGICAL_S4_KEYWORD
 %token LOGICAL_S8_KEYWORD
-%token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD 
-%token COMPLEX_KEYWORD
-%token COMPLEX_S4_KEYWORD COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD
+%token REAL_KEYWORD REAL_S4_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD
+%token COMPLEX_KEYWORD COMPLEX_S4_KEYWORD COMPLEX_S8_KEYWORD
+%token COMPLEX_S16_KEYWORD
 %token BOOL_AND BOOL_OR BOOL_NOT   
 %token SINGLE DOUBLE PRECISION
 %token <lval> CHARACTER 
@@ -757,22 +758,32 @@ func_mod: '(' ')'
 typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
        :       TYPENAME
                        { $$ = $1.type; }
+       |       INT_S1_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_integer_s1; }
+       |       INT_S2_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_integer_s2; }
        |       INT_KEYWORD
                        { $$ = parse_f_type (pstate)->builtin_integer; }
-       |       INT_S2_KEYWORD 
-                       { $$ = parse_f_type (pstate)->builtin_integer_s2; }
+       |       INT_S4_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_integer; }
+       |       INT_S8_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_integer_s8; }
        |       CHARACTER 
                        { $$ = parse_f_type (pstate)->builtin_character; }
-       |       LOGICAL_S8_KEYWORD
-                       { $$ = parse_f_type (pstate)->builtin_logical_s8; }
-       |       LOGICAL_KEYWORD 
-                       { $$ = parse_f_type (pstate)->builtin_logical; }
-       |       LOGICAL_S2_KEYWORD
-                       { $$ = parse_f_type (pstate)->builtin_logical_s2; }
        |       LOGICAL_S1_KEYWORD 
                        { $$ = parse_f_type (pstate)->builtin_logical_s1; }
+       |       LOGICAL_S2_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_logical_s2; }
+       |       LOGICAL_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_logical; }
+       |       LOGICAL_S4_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_logical; }
+       |       LOGICAL_S8_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_logical_s8; }
        |       REAL_KEYWORD 
                        { $$ = parse_f_type (pstate)->builtin_real; }
+       |       REAL_S4_KEYWORD
+                       { $$ = parse_f_type (pstate)->builtin_real; }
        |       REAL_S8_KEYWORD
                        { $$ = parse_f_type (pstate)->builtin_real_s8; }
        |       REAL_S16_KEYWORD
@@ -1130,21 +1141,26 @@ static const struct f77_boolean_val boolean_values[]  =
 static const struct token f77_keywords[] =
 {
   /* Historically these have always been lowercase only in GDB.  */
+  { "character", CHARACTER, OP_NULL, true },
   { "complex", COMPLEX_KEYWORD, OP_NULL, true },
   { "complex_4", COMPLEX_S4_KEYWORD, OP_NULL, true },
   { "complex_8", COMPLEX_S8_KEYWORD, OP_NULL, true },
   { "complex_16", COMPLEX_S16_KEYWORD, OP_NULL, true },
-  { "character", CHARACTER, OP_NULL, true },
+  { "integer_1", INT_S1_KEYWORD, OP_NULL, true },
   { "integer_2", INT_S2_KEYWORD, OP_NULL, true },
+  { "integer_4", INT_S4_KEYWORD, OP_NULL, true },
+  { "integer", INT_KEYWORD, OP_NULL, true },
+  { "integer_8", INT_S8_KEYWORD, OP_NULL, true },
   { "logical_1", LOGICAL_S1_KEYWORD, OP_NULL, true },
   { "logical_2", LOGICAL_S2_KEYWORD, OP_NULL, true },
-  { "logical_8", LOGICAL_S8_KEYWORD, OP_NULL, true },
-  { "integer", INT_KEYWORD, OP_NULL, true },
   { "logical", LOGICAL_KEYWORD, OP_NULL, true },
+  { "logical_4", LOGICAL_S4_KEYWORD, OP_NULL, true },
+  { "logical_8", LOGICAL_S8_KEYWORD, OP_NULL, true },
+  { "real", REAL_KEYWORD, OP_NULL, true },
+  { "real_4", REAL_S4_KEYWORD, OP_NULL, true },
+  { "real_8", REAL_S8_KEYWORD, OP_NULL, true },
   { "real_16", REAL_S16_KEYWORD, OP_NULL, true },
   { "sizeof", SIZEOF, OP_NULL, true },
-  { "real_8", REAL_S8_KEYWORD, OP_NULL, true },
-  { "real", REAL_KEYWORD, OP_NULL, true },
   { "single", SINGLE, OP_NULL, true },
   { "double", DOUBLE, OP_NULL, true },
   { "precision", PRECISION, OP_NULL, true },
index fb28cb7a5618bff6d5f48f5874510575462fc8f7..82252bfd5dc8a22a480a87e41672204b80d7c9b2 100644 (file)
@@ -1619,28 +1619,28 @@ build_fortran_types (struct gdbarch *gdbarch)
   builtin_f_type->builtin_logical_s1
     = arch_boolean_type (gdbarch, TARGET_CHAR_BIT, 1, "logical*1");
 
-  builtin_f_type->builtin_integer_s1
-    = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "integer*1");
-
-  builtin_f_type->builtin_integer_s2
-    = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch), 0, "integer*2");
-
-  builtin_f_type->builtin_integer_s8
-    = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch), 0,
-                        "integer*8");
-
   builtin_f_type->builtin_logical_s2
     = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1, "logical*2");
 
+  builtin_f_type->builtin_logical
+    = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "logical*4");
+
   builtin_f_type->builtin_logical_s8
     = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1,
                         "logical*8");
 
+  builtin_f_type->builtin_integer_s1
+    = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "integer*1");
+
+  builtin_f_type->builtin_integer_s2
+    = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch), 0, "integer*2");
+
   builtin_f_type->builtin_integer
     = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "integer");
 
-  builtin_f_type->builtin_logical
-    = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "logical*4");
+  builtin_f_type->builtin_integer_s8
+    = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch), 0,
+                        "integer*8");
 
   builtin_f_type->builtin_real
     = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
index 4e415f21f43717f110156e5e3e0ccaf52c2667ad..aebd45db94ab5d1f76f7ad6c3382ebfe611cbb37 100644 (file)
@@ -318,13 +318,13 @@ extern int calc_f77_array_dims (struct type *);
 struct builtin_f_type
 {
   struct type *builtin_character;
-  struct type *builtin_integer;
   struct type *builtin_integer_s1;
   struct type *builtin_integer_s2;
+  struct type *builtin_integer;
   struct type *builtin_integer_s8;
-  struct type *builtin_logical;
   struct type *builtin_logical_s1;
   struct type *builtin_logical_s2;
+  struct type *builtin_logical;
   struct type *builtin_logical_s8;
   struct type *builtin_real;
   struct type *builtin_real_s8;
index 8122cbcca38b0d11cb8af0b4c45192e49ce94f3b..5ab44b10a37ee25b6ba895a63b0384bf8ce78e94 100644 (file)
@@ -71,13 +71,35 @@ proc test_float_literal_types_accepted {} {
     gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
 }
 
+# Test the default primitive Fortran types.
+proc test_default_types {} {
+    gdb_test "ptype integer*4" "type = integer"
+    gdb_test "ptype integer_4" "type = integer"
+
+    gdb_test "ptype logical" "type = logical*4"
+
+    gdb_test "ptype real*4" "type = real"
+    gdb_test "ptype real_4" "type = real"
+
+    gdb_test "ptype complex" "type = complex*4"
+}
+
 # Test the the primitive Fortran types, those that GDB should always
 # know, even if the program does not define them, are in fact, known.
 proc test_primitive_types_known {} {
-    foreach type {void character logical*1 integer*1 integer*2 integer*8 \
-                     logical*2 logical*8 integer logical*4 real \
-                     real*8 real*16 complex*4 complex*8 complex*16} {
-       gdb_test "ptype $type" [string_to_regexp "type = $type"]
+    foreach type {void character \
+                    integer*1 integer*2 integer integer*8 \
+                    integer_1 integer_2 integer_8 \
+                    logical*1 logical*2 logical*4 logical*8 \
+                    logical_1 logical_2 logical_4 logical_8 \
+                    real real*8 real*16 real_8 real_16 \
+                    complex*4 complex*8 complex*16 \
+                    complex_4 complex_8 complex_16} {
+
+       # While TYPE_KIND is allowed as input, GDB will always return the
+       # Fortran notation TYPE*KIND
+       regsub -all "_" $type "\*" type_res
+       gdb_test "ptype $type" [string_to_regexp "type = $type_res"]
     }
 }
 
@@ -91,6 +113,7 @@ gdb_test "set print sevenbit-strings" ""
 
 if [set_lang_fortran] then {
     test_primitive_types_known
+    test_default_types
     test_integer_literal_types_accepted
     test_integer_literal_types_rejected
     test_logical_literal_types_accepted