public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 02/11] gdb/fortran: Cleanup code for parsing logical constants
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (4 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 11/11] gdb/fortran: Handle older TYPE*SIZE typenames Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

This patch cleans up the code used for parsing the Fortran logical
constants '.TRUE.' and '.FALSE.'.  Instead of listing both upper and
lowercase versions of these strings we now use strncasecmp.

I've also switched to use ARRAY_SIZE for the array iteration, and I've
cleaned up whitespace in the vicinity of the code I've changed.

Finally, I've added a test to ensure that both the upper and lower
case versions of the logical constants are understood by GDB,
something that was missing previously.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* f-exp.y (struct f77_boolean_val): Add comments.
	(boolean_values): Remove uppercase versions, and end marker.
	(yylex): Use ARRAY_SIZE for iterating over boolean_values array,
	and use strncasecmp to achieve case insensitivity.  Additionally,
	perform whitespace cleanup around this code.

gdb/testsuite/ChangeLog:

	* gdb.fortran/types.exp (test_logical_literal_types_accepted):
	Check upper and lower case logical literals.
---
 gdb/ChangeLog                       |  8 ++++++++
 gdb/f-exp.y                         | 35 +++++++++++++++++++----------------
 gdb/testsuite/ChangeLog             |  5 +++++
 gdb/testsuite/gdb.fortran/types.exp |  5 ++++-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index d70c66474c0..704585e63ae 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -807,19 +807,22 @@ static const struct token dot_ops[] =
   { NULL, 0, BINOP_END }
 };
 
-struct f77_boolean_val 
+/* Holds the Fortran representation of a boolean, and the integer value we
+   substitute in when one of the matching strings is parsed.  */
+struct f77_boolean_val
 {
+  /* The string representing a Fortran boolean.  */
   const char *name;
+
+  /* The integer value to replace it with.  */
   int value;
-}; 
+};
 
-static const struct f77_boolean_val boolean_values[]  = 
+/* The set of Fortran booleans.  These are matched case insensitively.  */
+static const struct f77_boolean_val boolean_values[]  =
 {
   { ".true.", 1 },
-  { ".TRUE.", 1 },
-  { ".false.", 0 },
-  { ".FALSE.", 0 },
-  { NULL, 0 }
+  { ".false.", 0 }
 };
 
 static const struct token f77_keywords[] = 
@@ -931,19 +934,19 @@ yylex (void)
   prev_lexptr = lexptr;
  
   tokstart = lexptr;
-  
-  /* First of all, let us make sure we are not dealing with the 
+
+  /* First of all, let us make sure we are not dealing with the
      special tokens .true. and .false. which evaluate to 1 and 0.  */
-  
+
   if (*lexptr == '.')
-    { 
-      for (int i = 0; boolean_values[i].name != NULL; i++)
+    {
+      for (int i = 0; i < ARRAY_SIZE (boolean_values); i++)
 	{
-	  if (strncmp (tokstart, boolean_values[i].name,
-		       strlen (boolean_values[i].name)) == 0)
+	  if (strncasecmp (tokstart, boolean_values[i].name,
+			   strlen (boolean_values[i].name)) == 0)
 	    {
-	      lexptr += strlen (boolean_values[i].name); 
-	      yylval.lval = boolean_values[i].value; 
+	      lexptr += strlen (boolean_values[i].name);
+	      yylval.lval = boolean_values[i].value;
 	      return BOOLEAN_LITERAL;
 	    }
 	}
diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp
index f786bd30eb0..0e28691d90e 100644
--- a/gdb/testsuite/gdb.fortran/types.exp
+++ b/gdb/testsuite/gdb.fortran/types.exp
@@ -45,10 +45,13 @@ proc test_integer_literal_types_rejected {} {
 proc test_logical_literal_types_accepted {} {
     global gdb_prompt
 
-    # Test the only possible values for a logical, TRUE and FALSE.
+    # Test the only possible values for a logical, TRUE and FALSE (and
+    # also true and false).
 
     gdb_test "pt .TRUE." "type = logical\\*2"
     gdb_test "pt .FALSE." "type = logical\\*2"
+    gdb_test "pt .true." "type = logical\\*2"
+    gdb_test "pt .false." "type = logical\\*2"
 }
 
 proc test_float_literal_types_accepted {} {
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 11/11] gdb/fortran: Handle older TYPE*SIZE typenames
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (3 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 04/11] gdb/fortran: Add new function to evaluate Fortran expressions Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 02/11] gdb/fortran: Cleanup code for parsing logical constants Andrew Burgess
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

This patch adds support for the older TYPE*SIZE typenames that are
still around in older code.

For implementation this currently reuses the kind mechanism, as under
gFortran the kind number is equivalent to the size, however, this is
not necessarily true for all compilers.  If the rules for other
compilers are better understood then this code might need to be
improved slightly to allow for a distinction between size and kind,
however, adding this extra complexity now seems pointless.

gdb/ChangeLog:

	* f-exp.y (direct_abs_decl): Handle TYPE*SIZE type names.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp: Extend to cover TYPE*SIZE cases.
---
 gdb/ChangeLog                            |  4 ++++
 gdb/f-exp.y                              |  2 ++
 gdb/testsuite/ChangeLog                  |  4 ++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 23 +++++++++++++++++++++++
 4 files changed, 33 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 88c685a0af3..7e838b0a93a 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -570,6 +570,8 @@ direct_abs_decl: '(' abs_decl ')'
 			{ $$ = $2; }
 	| 	'(' KIND '=' INT ')'
 			{ push_kind_type ($4.val, $4.type); }
+	|	'*' INT
+			{ push_kind_type ($2.val, $2.type); }
 	| 	direct_abs_decl func_mod
 			{ push_type (tp_function); }
 	|	func_mod
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index 0daa1ec6b12..291749a1541 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -50,11 +50,34 @@ proc test_parsing_invalid_type_kinds {} {
     }
 }
 
+# Perform some basic checks that GDB can parse the older style
+# TYPE*SIZE type names.
+proc test_old_star_type_sizes {} {
+    gdb_test "p ((character*1) 1)" " = 1 '\\\\001'"
+
+    gdb_test "p ((complex*4) 1)" " = \\(1,0\\)"
+    gdb_test "p ((complex*8) 1)" " = \\(1,0\\)"
+    gdb_test "p ((complex*16) 1)" " = \\(1,0\\)"
+
+    gdb_test "p ((real*4) 1)" " = 1"
+    gdb_test "p ((real*8) 1)" " = 1"
+    gdb_test "p ((real*16) 1)" " = 1"
+
+    gdb_test "p ((logical*1) 1)" " = \\.TRUE\\."
+    gdb_test "p ((logical*4) 1)" " = \\.TRUE\\."
+    gdb_test "p ((logical*8) 1)" " = \\.TRUE\\."
+
+    gdb_test "p ((integer*2) 1)" " = 1"
+    gdb_test "p ((integer*4) 1)" " = 1"
+    gdb_test "p ((integer*8) 1)" " = 1"
+}
+
 clean_restart
 
 if [set_lang_fortran] then {
     test_basic_parsing_of_type_kinds
     test_parsing_invalid_type_kinds
+    test_old_star_type_sizes
 } else {
     warning "$test_name tests suppressed." 0
 }
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 07/11] gdb/fortran: Expand the set of types that support (kind=N) Andrew Burgess
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

Switch to using TYPE_CODE_CHAR for character types.  This appears to
have little impact on the test results as gFortran uses the
DW_TAG_string_type to represent all character variables (as far as I
can see).  The only place this has an impact is when the user casts a
variable to a character type, in which case GDB does now use the CHAR
type, and prints the variable as both a value and a character, for
example, before:

    (gdb) p ((character) 97)
    $1 = 97

and after:

    (gdb) p ((character) 97)
    $1 = 97 'a'

gdb/ChangeLog:

	* f-lang.c (build_fortran_types): Use TYPE_CODE_CHAR for character
	types.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp: Update expected results.
---
 gdb/ChangeLog                            | 5 +++++
 gdb/f-lang.c                             | 2 +-
 gdb/testsuite/ChangeLog                  | 4 ++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 2 +-
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 7bed3189283..cbb3ad0f8a6 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -365,7 +365,7 @@ build_fortran_types (struct gdbarch *gdbarch)
     = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "VOID");
 
   builtin_f_type->builtin_character
-    = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "character");
+    = arch_type (gdbarch, TYPE_CODE_CHAR, TARGET_CHAR_BIT, "character");
 
   builtin_f_type->builtin_logical_s1
     = arch_boolean_type (gdbarch, TARGET_CHAR_BIT, 1, "logical*1");
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index 129997e4f66..0daa1ec6b12 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -23,7 +23,7 @@ if { [skip_fortran_tests] } { continue }
 
 # Test parsing of `(kind=N)` type modifiers.
 proc test_basic_parsing_of_type_kinds {} {
-    gdb_test "p ((character (kind=1)) 1)" " = 1"
+    gdb_test "p ((character (kind=1)) 1)" " = 1 '\\\\001'"
 
     gdb_test "p ((complex (kind=4)) 1)" " = \\(1,0\\)"
     gdb_test "p ((complex (kind=8)) 1)" " = \\(1,0\\)"
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 05/11] gdb/fortran: Enable debugging of the Fortran parser
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
  2019-02-12 16:11 ` [PATCH 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
  2019-02-12 16:11 ` [PATCH 07/11] gdb/fortran: Expand the set of types that support (kind=N) Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 04/11] gdb/fortran: Add new function to evaluate Fortran expressions Andrew Burgess
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

This commit allows 'set debug parser on' to work for the Fortran
parser.

gdb/ChangeLog:

	* f-exp.y (f_parse): Set yydebug.
---
 gdb/ChangeLog | 4 ++++
 gdb/f-exp.y   | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 5e980944b19..c223d366db3 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -1211,6 +1211,8 @@ f_parse (struct parser_state *par_state)
 {
   /* Setting up the parser state.  */
   scoped_restore pstate_restore = make_scoped_restore (&pstate);
+  scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+							parser_debug);
   gdb_assert (par_state != NULL);
   pstate = par_state;
 
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 04/11] gdb/fortran: Add new function to evaluate Fortran expressions
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (2 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 05/11] gdb/fortran: Enable debugging of the Fortran parser Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 11/11] gdb/fortran: Handle older TYPE*SIZE typenames Andrew Burgess
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

This is an initial restructure, it adds a new function in which
Fortran specific expressions can be evaluated.  No Fortran specific
expressions are added with this commit though, so for now, the new
function just forwards all expressions to the default expression
handler, as such, there should be no user visible changes after this
commit.  However, the new function will be useful in later commits.

gdb/ChangeLog:

	* f-lang.c (evaluate_subexp_f): New function.
	(exp_descriptor_f): New global.
	(f_language_defn): Use exp_descriptor_f instead of
	exp_descriptor_standard.
---
 gdb/ChangeLog |  7 +++++++
 gdb/f-lang.c  | 22 +++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 4ff828ba753..779fb1e67fb 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -238,6 +238,15 @@ f_collect_symbol_completion_matches (completion_tracker &tracker,
 						      text, word, ":", code);
 }
 
+/* Special expression evaluation cases for Fortran.  */
+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);
+}
+
 static const char *f_extensions[] =
 {
   ".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
@@ -245,6 +254,17 @@ static const char *f_extensions[] =
   NULL
 };
 
+/* Expression processing for Fortran.  */
+static const struct exp_descriptor exp_descriptor_f =
+{
+  print_subexp_standard,
+  operator_length_standard,
+  operator_check_standard,
+  op_name_standard,
+  dump_subexp_body_standard,
+  evaluate_subexp_f
+};
+
 extern const struct language_defn f_language_defn =
 {
   "fortran",
@@ -255,7 +275,7 @@ extern const struct language_defn f_language_defn =
   array_column_major,
   macro_expansion_no,
   f_extensions,
-  &exp_descriptor_standard,
+  &exp_descriptor_f,
   f_parse,			/* parser */
   null_post_parser,
   f_printchar,			/* Print character constant */
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 01/11] gdb/fortran: Remove some duplicate tests
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (8 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword Andrew Burgess
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

Make the test names unique in gdb.fortran/types.exp by removing a few
duplicate tests.

gdb/testsuite/ChangeLog:

	* gdb.fortran/types.exp (test_float_literal_types_accepted):
	Remove duplicate tests.
---
 gdb/testsuite/ChangeLog             | 5 +++++
 gdb/testsuite/gdb.fortran/types.exp | 4 ----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp
index 2e1f2e1efd1..f786bd30eb0 100644
--- a/gdb/testsuite/gdb.fortran/types.exp
+++ b/gdb/testsuite/gdb.fortran/types.exp
@@ -63,12 +63,8 @@ proc test_float_literal_types_accepted {} {
     gdb_test "pt .44" "type = real\\*\[0-9\]+"
     gdb_test "pt 44.0" "type = real\\*\[0-9\]+"
     gdb_test "pt 10D20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10D20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10d20" "type = real\\*\[0-9\]+"
     gdb_test "pt 10d20" "type = real\\*\[0-9\]+"
     gdb_test "pt 10E20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10E20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
     gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
 }
 
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions
@ 2019-02-12 16:11 Andrew Burgess
  2019-02-12 16:11 ` [PATCH 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
                   ` (22 more replies)
  0 siblings, 23 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

A series of patches all relating to GDB's Fortran support, though
there's a range of different features worked on in this series they do
all build on each other.

  #1, #2, #3, #4, #5 - Are clean up and restructuring commits.

  #6, #7, #8, #9, #11 - All relate to type creation in the Fortran parser.

  #10 - Adds an intrinsic function

All tested on X86-64 GNU/Linux with 'GNU Fortran (GCC) 7.3.1 20180712
(Red Hat 7.3.1-6)' installed.

Thanks,
Andrew

---

Andrew Burgess (11):
  gdb/fortran: Remove some duplicate tests
  gdb/fortran: Cleanup code for parsing logical constants
  gdb/fortran: Simplify handling of Fortran dot operations and keywords
  gdb/fortran: Add new function to evaluate Fortran expressions
  gdb/fortran: Enable debugging of the Fortran parser
  gdb/fortran: Add Fortran 'kind' intrinsic and keyword
  gdb/fortran: Expand the set of types that support (kind=N)
  gdb/fortran: Add builtin 8-byte integer type with (kind=8) support
  gdb/fortran: Use TYPE_CODE_CHAR for character types
  gdb/fortran: Add support for the ABS intrinsic function
  gdb/fortran: Handle older TYPE*SIZE typenames

 gdb/ChangeLog                            |  76 +++++++++
 gdb/expprint.c                           |   1 +
 gdb/f-exp.y                              | 256 ++++++++++++++++++++++---------
 gdb/f-lang.c                             | 102 +++++++++++-
 gdb/f-lang.h                             |   1 +
 gdb/parse.c                              |   1 +
 gdb/parser-defs.h                        |   3 +-
 gdb/std-operator.def                     |   1 +
 gdb/testsuite/ChangeLog                  |  42 +++++
 gdb/testsuite/gdb.fortran/dot-ops.exp    | 123 +++++++++++++++
 gdb/testsuite/gdb.fortran/intrinsics.exp |  51 ++++++
 gdb/testsuite/gdb.fortran/intrinsics.f90 |  39 +++++
 gdb/testsuite/gdb.fortran/type-kinds.exp |  83 ++++++++++
 gdb/testsuite/gdb.fortran/types.exp      |   9 +-
 14 files changed, 711 insertions(+), 77 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/dot-ops.exp
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.exp
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.f90
 create mode 100644 gdb/testsuite/gdb.fortran/type-kinds.exp

-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 07/11] gdb/fortran: Expand the set of types that support (kind=N)
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
  2019-02-12 16:11 ` [PATCH 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 05/11] gdb/fortran: Enable debugging of the Fortran parser Andrew Burgess
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

Expand the number of types that can be adjusted with a (kind=N) type
extension.

gdb/ChangeLog:

	* f-exp.y (convert_to_kind_type): Handle more type kinds.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp (test_basic_parsing_of_type_kinds):
	Expand types tested.
	(test_parsing_invalid_type_kinds): New function.
---
 gdb/ChangeLog                            |  4 ++++
 gdb/f-exp.y                              | 36 ++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                  |  6 ++++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 24 +++++++++++++++++++++
 4 files changed, 70 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 327f13736bd..980ee4b4adb 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -830,6 +830,42 @@ convert_to_kind_type (struct type *basetype, int kind)
       if (kind == 1)
 	return parse_f_type (pstate)->builtin_character;
     }
+  else if (basetype == parse_f_type (pstate)->builtin_complex_s8)
+    {
+      if (kind == 4)
+	return parse_f_type (pstate)->builtin_complex_s8;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_complex_s16;
+      else if (kind == 16)
+	return parse_f_type (pstate)->builtin_complex_s32;
+    }
+  else if (basetype == parse_f_type (pstate)->builtin_real)
+    {
+      if (kind == 4)
+	return parse_f_type (pstate)->builtin_real;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_real_s8;
+      else if (kind == 16)
+	return parse_f_type (pstate)->builtin_real_s16;
+    }
+  else if (basetype == parse_f_type (pstate)->builtin_logical)
+    {
+      if (kind == 1)
+	return parse_f_type (pstate)->builtin_logical_s1;
+      else if (kind == 2)
+	return parse_f_type (pstate)->builtin_logical_s2;
+      else if (kind == 4)
+	return parse_f_type (pstate)->builtin_logical;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_logical_s8;
+    }
+  else if (basetype == parse_f_type (pstate)->builtin_integer)
+    {
+      if (kind == 2)
+	return parse_f_type (pstate)->builtin_integer_s2;
+      else if (kind == 4)
+	return parse_f_type (pstate)->builtin_integer;
+    }
 
   error (_("unsupported kind %d for type %s"),
 	 kind, TYPE_SAFE_NAME (basetype));
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index b60b8044110..b2e64d77081 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -24,12 +24,36 @@ if { [skip_fortran_tests] } { continue }
 # Test parsing of `(kind=N)` type modifiers.
 proc test_basic_parsing_of_type_kinds {} {
     gdb_test "p ((character (kind=1)) 1)" " = 1"
+
+    gdb_test "p ((complex (kind=4)) 1)" " = \\(1,0\\)"
+    gdb_test "p ((complex (kind=8)) 1)" " = \\(1,0\\)"
+    gdb_test "p ((complex (kind=16)) 1)" " = \\(1,0\\)"
+
+    gdb_test "p ((real (kind=4)) 1)" " = 1"
+    gdb_test "p ((real (kind=8)) 1)" " = 1"
+    gdb_test "p ((real (kind=16)) 1)" " = 1"
+
+    gdb_test "p ((logical (kind=1)) 1)" " = \\.TRUE\\."
+    gdb_test "p ((logical (kind=4)) 1)" " = \\.TRUE\\."
+    gdb_test "p ((logical (kind=8)) 1)" " = \\.TRUE\\."
+
+    gdb_test "p ((integer (kind=2)) 1)" " = 1"
+    gdb_test "p ((integer (kind=4)) 1)" " = 1"
+}
+
+proc test_parsing_invalid_type_kinds {} {
+    foreach typename {complex real logical integer} {
+	foreach typesize {3 5 7 9} {
+	    gdb_test "p (($typename (kind=$typesize)) 1)" "unsupported kind $typesize for type $typename.*"
+	}
+    }
 }
 
 clean_restart
 
 if [set_lang_fortran] then {
     test_basic_parsing_of_type_kinds
+    test_parsing_invalid_type_kinds
 } else {
     warning "$test_name tests suppressed." 0
 }
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (7 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 01/11] gdb/fortran: Remove some duplicate tests Andrew Burgess
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

Use strncasecmp to compare Fortran dot operations (like .AND.) and for
the keywords list.  This allows for some duplication to be removed
from the token arrays.  I've also performed whitespace cleanup around
the code I've changed.

I have added some tests to ensure that upper and lowercase dot
operations are correctly tested.  The keywords list remains always
lowercase for now.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* f-exp.y (struct token): Add comments.
	(dot_ops): Remove uppercase versions and the end marker.
	(f77_keywords): Likewise.
	(yylex): Use ARRAY_SIZE to iterate over dot_ops, assert all
	entries in the dot_ops array are case insensitive, and use
	strncasecmp to compare strings.  Also some whitespace cleanup in
	this area.  Similar for the f77_keywords array, except entries in
	this list might be case sensitive.

gdb/testsuite/ChangeLog:

	* gdb.fortran/dot-ops.exp: New file.
---
 gdb/ChangeLog                         |  11 +++
 gdb/f-exp.y                           | 103 ++++++++++++++--------------
 gdb/testsuite/ChangeLog               |   4 ++
 gdb/testsuite/gdb.fortran/dot-ops.exp | 123 ++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 52 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/dot-ops.exp

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 704585e63ae..5e980944b19 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -775,36 +775,33 @@ parse_number (struct parser_state *par_state,
 
 struct token
 {
+  /* The string to match against.  */
   const char *oper;
+
+  /* The lexer token to return.  */
   int token;
+
+  /* The expression opcode to embed within the token.  */
   enum exp_opcode opcode;
+
+  /* When this is true the string in OPER is matched exactly including
+     case, when this is false OPER is matched case insensitively.  */
+  bool case_sensitive;
 };
 
 static const struct token dot_ops[] =
 {
-  { ".and.", BOOL_AND, BINOP_END },
-  { ".AND.", BOOL_AND, BINOP_END },
-  { ".or.", BOOL_OR, BINOP_END },
-  { ".OR.", BOOL_OR, BINOP_END },
-  { ".not.", BOOL_NOT, BINOP_END },
-  { ".NOT.", BOOL_NOT, BINOP_END },
-  { ".eq.", EQUAL, BINOP_END },
-  { ".EQ.", EQUAL, BINOP_END },
-  { ".eqv.", EQUAL, BINOP_END },
-  { ".NEQV.", NOTEQUAL, BINOP_END },
-  { ".neqv.", NOTEQUAL, BINOP_END },
-  { ".EQV.", EQUAL, BINOP_END },
-  { ".ne.", NOTEQUAL, BINOP_END },
-  { ".NE.", NOTEQUAL, BINOP_END },
-  { ".le.", LEQ, BINOP_END },
-  { ".LE.", LEQ, BINOP_END },
-  { ".ge.", GEQ, BINOP_END },
-  { ".GE.", GEQ, BINOP_END },
-  { ".gt.", GREATERTHAN, BINOP_END },
-  { ".GT.", GREATERTHAN, BINOP_END },
-  { ".lt.", LESSTHAN, BINOP_END },
-  { ".LT.", LESSTHAN, BINOP_END },
-  { NULL, 0, BINOP_END }
+  { ".and.", BOOL_AND, BINOP_END, false },
+  { ".or.", BOOL_OR, BINOP_END, false },
+  { ".not.", BOOL_NOT, BINOP_END, false },
+  { ".eq.", EQUAL, BINOP_END, false },
+  { ".eqv.", EQUAL, BINOP_END, false },
+  { ".neqv.", NOTEQUAL, BINOP_END, false },
+  { ".ne.", NOTEQUAL, BINOP_END, false },
+  { ".le.", LEQ, BINOP_END, false },
+  { ".ge.", GEQ, BINOP_END, false },
+  { ".gt.", GREATERTHAN, BINOP_END, false },
+  { ".lt.", LESSTHAN, BINOP_END, false },
 };
 
 /* Holds the Fortran representation of a boolean, and the integer value we
@@ -825,25 +822,25 @@ static const struct f77_boolean_val boolean_values[]  =
   { ".false.", 0 }
 };
 
-static const struct token f77_keywords[] = 
+static const struct token f77_keywords[] =
 {
-  { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END },
-  { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END },
-  { "character", CHARACTER, BINOP_END },
-  { "integer_2", INT_S2_KEYWORD, BINOP_END },
-  { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END },
-  { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END },
-  { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END },
-  { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END },
-  { "integer", INT_KEYWORD, BINOP_END },
-  { "logical", LOGICAL_KEYWORD, BINOP_END },
-  { "real_16", REAL_S16_KEYWORD, BINOP_END },
-  { "complex", COMPLEX_S8_KEYWORD, BINOP_END },
-  { "sizeof", SIZEOF, BINOP_END },
-  { "real_8", REAL_S8_KEYWORD, BINOP_END },
-  { "real", REAL_KEYWORD, BINOP_END },
-  { NULL, 0, BINOP_END }
-}; 
+  /* Historically these have always been lowercase only in GDB.  */
+  { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END, true },
+  { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END, true },
+  { "character", CHARACTER, BINOP_END, true },
+  { "integer_2", INT_S2_KEYWORD, BINOP_END, true },
+  { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END, true },
+  { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END, true },
+  { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END, true },
+  { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END, true },
+  { "integer", INT_KEYWORD, BINOP_END, true },
+  { "logical", LOGICAL_KEYWORD, BINOP_END, true },
+  { "real_16", REAL_S16_KEYWORD, BINOP_END, true },
+  { "complex", COMPLEX_S8_KEYWORD, BINOP_END, true },
+  { "sizeof", SIZEOF, BINOP_END, true },
+  { "real_8", REAL_S8_KEYWORD, BINOP_END, true },
+  { "real", REAL_KEYWORD, BINOP_END, true },
+};
 
 /* Implementation of a dynamically expandable buffer for processing input
    characters acquired through lexptr and building a value to return in
@@ -951,18 +948,18 @@ yylex (void)
 	    }
 	}
     }
-  
+
   /* See if it is a special .foo. operator.  */
-  
-  for (int i = 0; dot_ops[i].oper != NULL; i++)
-    if (strncmp (tokstart, dot_ops[i].oper,
-		 strlen (dot_ops[i].oper)) == 0)
+  for (int i = 0; i < ARRAY_SIZE (dot_ops); i++)
+    if (strncasecmp (tokstart, dot_ops[i].oper,
+		     strlen (dot_ops[i].oper)) == 0)
       {
+	gdb_assert (!dot_ops[i].case_sensitive);
 	lexptr += strlen (dot_ops[i].oper);
 	yylval.opcode = dot_ops[i].opcode;
 	return dot_ops[i].token;
       }
-  
+
   /* See if it is an exponentiation operator.  */
 
   if (strncmp (tokstart, "**", 2) == 0)
@@ -1122,16 +1119,18 @@ yylex (void)
   lexptr += namelen;
   
   /* Catch specific keywords.  */
-  
-  for (int i = 0; f77_keywords[i].oper != NULL; i++)
+
+  for (int i = 0; i < ARRAY_SIZE (f77_keywords); i++)
     if (strlen (f77_keywords[i].oper) == namelen
-	&& strncmp (tokstart, f77_keywords[i].oper, namelen) == 0)
+	&& ((!f77_keywords[i].case_sensitive
+	     && strncasecmp (tokstart, f77_keywords[i].oper, namelen) == 0)
+	    || (f77_keywords[i].case_sensitive
+		&& strncmp (tokstart, f77_keywords[i].oper, namelen) == 0)))
       {
-	/* 	lexptr += strlen(f77_keywords[i].operator); */ 
 	yylval.opcode = f77_keywords[i].opcode;
 	return f77_keywords[i].token;
       }
-  
+
   yylval.sval.ptr = tokstart;
   yylval.sval.length = namelen;
   
diff --git a/gdb/testsuite/gdb.fortran/dot-ops.exp b/gdb/testsuite/gdb.fortran/dot-ops.exp
new file mode 100644
index 00000000000..787471db918
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/dot-ops.exp
@@ -0,0 +1,123 @@
+# Copyright 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file tests GDB's handling of some of the builtin logical and
+# arithmetic dot operators in Fortran, for example `.AND.` and `.LE.`.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+proc test_dot_operations {} {
+
+    foreach_with_prefix format { "uppercase" "lowercase" } {
+	if {$format == "uppercase"} {
+	    set true ".TRUE."
+	    set false ".FALSE."
+	    set and ".AND."
+	    set or ".OR."
+	    set not ".NOT."
+	    set eqv ".EQV."
+	    set neqv ".NEQV."
+	    set eq ".EQ."
+	    set ne ".NE."
+	    set le ".LE."
+	    set ge ".GE."
+	    set lt ".LT."
+	    set gt ".GT."
+	} else {
+	    set true ".true."
+	    set false ".false."
+	    set and ".and."
+	    set or ".or."
+	    set not ".not."
+	    set eqv ".eqv."
+	    set neqv ".neqv."
+	    set eq ".eq."
+	    set ne ".ne."
+	    set le ".le."
+	    set ge ".ge."
+	    set lt ".lt."
+	    set gt ".gt."
+	}
+
+	# Logical AND
+	gdb_test "p $true $and $true" " = .TRUE."
+	gdb_test "p $true $and $false" " = .FALSE."
+	gdb_test "p $false $and $true" " = .FALSE."
+	gdb_test "p $false $and $false" " = .FALSE."
+
+	# Logical OR
+	gdb_test "p $true $or $true" " = .TRUE."
+	gdb_test "p $true $or $false" " = .TRUE."
+	gdb_test "p $false $or $true" " = .TRUE."
+	gdb_test "p $false $or $false" " = .FALSE."
+
+	# Logical NOT
+	gdb_test "p $not $true" " = .FALSE."
+	gdb_test "p $not $false" " = .TRUE."
+
+	# Logical EQV
+	gdb_test "p $true $eqv $true" " = .TRUE."
+	gdb_test "p $true $eqv $false" " = .FALSE."
+	gdb_test "p $false $eqv $true" " = .FALSE."
+	gdb_test "p $false $eqv $false" " = .TRUE."
+
+	# Logical NEQV
+	gdb_test "p $true $neqv $true" " = .FALSE."
+	gdb_test "p $true $neqv $false" " = .TRUE."
+	gdb_test "p $false $neqv $true" " = .TRUE."
+	gdb_test "p $false $neqv $false" " = .FALSE."
+
+	# Arithmetic EQ
+	gdb_test "p 5 $eq 4" " = .FALSE."
+	gdb_test "p 4 $eq 4" " = .TRUE."
+
+	# Arithmetic NE
+	gdb_test "p 5 $ne 4" " = .TRUE."
+	gdb_test "p 4 $ne 4" " = .FALSE."
+
+	# Arithmetic LE
+	gdb_test "p 5 $le 4" " = .FALSE."
+	gdb_test "p 4 $le 4" " = .TRUE."
+	gdb_test "p 3 $le 4" " = .TRUE."
+
+	# Arithmetic LT
+	gdb_test "p 5 $lt 4" " = .FALSE."
+	gdb_test "p 4 $lt 4" " = .FALSE."
+	gdb_test "p 3 $lt 4" " = .TRUE."
+
+	# Arithmetic GE
+	gdb_test "p 5 $ge 4" " = .TRUE."
+	gdb_test "p 4 $ge 4" " = .TRUE."
+	gdb_test "p 3 $ge 4" " = .FALSE."
+
+	# Arithmetic GT
+	gdb_test "p 5 $gt 4" " = .TRUE."
+	gdb_test "p 4 $gt 4" " = .FALSE."
+	gdb_test "p 3 $gt 4" " = .FALSE."
+    }
+}
+
+# Start of test script.
+
+clean_restart
+
+if [set_lang_fortran] then {
+    test_dot_operations
+} else {
+    warning "$test_name tests suppressed." 0
+}
+
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 10/11] gdb/fortran: Add support for the ABS intrinsic function
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (5 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 02/11] gdb/fortran: Cleanup code for parsing logical constants Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support Andrew Burgess
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

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.
---
 gdb/ChangeLog                            | 11 +++++++++
 gdb/f-exp.y                              |  8 ++++++-
 gdb/f-lang.c                             | 39 ++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                  |  4 ++++
 gdb/testsuite/gdb.fortran/intrinsics.exp |  9 ++++++++
 5 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index d256ff14c1e..88c685a0af3 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -168,6 +168,7 @@ static int parse_number (struct parser_state *, const char *, int,
 %token <voidval> DOLLAR_VARIABLE
 
 %token <opcode> ASSIGN_MODIFY
+%token <opcode> UNOP_INTRINSIC
 
 %left ','
 %left ABOVE_COMMA
@@ -252,6 +253,10 @@ exp	:	exp '('
 					      OP_F77_UNDETERMINED_ARGLIST); }
 	;
 
+exp	:	UNOP_INTRINSIC '(' exp ')'
+			{ write_exp_elt_opcode (pstate, $1); }
+	;
+
 arglist	:
 	;
 
@@ -945,7 +950,8 @@ static const struct token f77_keywords[] =
   { "real", REAL_KEYWORD, BINOP_END, true },
   /* The following correspond to actual functions in Fortran and are case
      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
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index cbb3ad0f8a6..7aced533bce 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -33,7 +33,9 @@
 #include "cp-support.h"
 #include "charset.h"
 #include "c-lang.h"
+#include "target-float.h"
 
+#include <math.h>
 
 /* Local functions */
 
@@ -238,6 +240,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,
@@ -258,6 +274,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);
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp
index 674f299c428..00396c74c2f 100644
--- a/gdb/testsuite/gdb.fortran/intrinsics.exp
+++ b/gdb/testsuite/gdb.fortran/intrinsics.exp
@@ -40,3 +40,12 @@ gdb_test "p kind (l2)" " = 2"
 gdb_test "p kind (l4)" " = 4"
 gdb_test "p kind (l8)" " = 8"
 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"
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (9 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 01/11] gdb/fortran: Remove some duplicate tests Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-03-06 18:15 ` [PUSHED 02/11] gdb/fortran: Cleanup code for parsing logical constants Andrew Burgess
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

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.
---
 gdb/ChangeLog                            | 16 ++++++++
 gdb/expprint.c                           |  1 +
 gdb/f-exp.y                              | 70 +++++++++++++++++++++++++++++++-
 gdb/f-lang.c                             | 39 +++++++++++++++++-
 gdb/parse.c                              |  1 +
 gdb/parser-defs.h                        |  3 +-
 gdb/std-operator.def                     |  1 +
 gdb/testsuite/ChangeLog                  |  6 +++
 gdb/testsuite/gdb.fortran/intrinsics.exp | 42 +++++++++++++++++++
 gdb/testsuite/gdb.fortran/intrinsics.f90 | 39 ++++++++++++++++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 35 ++++++++++++++++
 11 files changed, 249 insertions(+), 4 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.exp
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.f90
 create mode 100644 gdb/testsuite/gdb.fortran/type-kinds.exp

diff --git a/gdb/expprint.c b/gdb/expprint.c
index d7ad1a71878..a22499f4833 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -869,6 +869,7 @@ dump_subexp_body_standard (struct expression *exp,
     case UNOP_MIN:
     case UNOP_ODD:
     case UNOP_TRUNC:
+    case UNOP_KIND:
       elt = dump_subexp (exp, stream, elt);
       break;
     case OP_LONG:
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index c223d366db3..327f13736bd 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -78,6 +78,10 @@ static void growbuf_by_size (int);
 
 static int match_string_literal (void);
 
+static void push_kind_type (LONGEST val, struct type *type);
+
+static struct type *convert_to_kind_type (struct type *basetype, int kind);
+
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -149,7 +153,7 @@ static int parse_number (struct parser_state *, const char *, int,
 
 %token <ssym> NAME_OR_INT 
 
-%token  SIZEOF 
+%token SIZEOF KIND
 %token ERROR
 
 /* Special type cases, put in to allow the parser to distinguish different
@@ -228,6 +232,10 @@ exp	:	SIZEOF exp       %prec UNARY
 			{ write_exp_elt_opcode (pstate, UNOP_SIZEOF); }
 	;
 
+exp	:	KIND '(' exp ')'       %prec UNARY
+			{ write_exp_elt_opcode (pstate, UNOP_KIND); }
+	;
+
 /* No more explicit array operators, we treat everything in F77 as 
    a function call.  The disambiguation as to whether we are 
    doing a subscript operation or a function call is done 
@@ -530,6 +538,13 @@ ptype	:	typebase
 		      case tp_function:
 			follow_type = lookup_function_type (follow_type);
 			break;
+		      case tp_kind:
+			{
+			  int kind_val = pop_type_int ();
+			  follow_type
+			    = convert_to_kind_type (follow_type, kind_val);
+			}
+			break;
 		      }
 		  $$ = follow_type;
 		}
@@ -548,6 +563,8 @@ abs_decl:	'*'
 
 direct_abs_decl: '(' abs_decl ')'
 			{ $$ = $2; }
+	| 	'(' KIND '=' INT ')'
+			{ push_kind_type ($4.val, $4.type); }
 	| 	direct_abs_decl func_mod
 			{ push_type (tp_function); }
 	|	func_mod
@@ -773,6 +790,54 @@ parse_number (struct parser_state *par_state,
   return INT;
 }
 
+/* Called to setup the type stack when we encounter a '(kind=N)' type
+   modifier, performs some bounds checking on 'N' and then pushes this to
+   the type stack followed by the 'tp_kind' marker.  */
+static void
+push_kind_type (LONGEST val, struct type *type)
+{
+  int ival;
+
+  if (TYPE_UNSIGNED (type))
+    {
+      ULONGEST uval = static_cast <ULONGEST> (val);
+      if (uval > INT_MAX)
+	error (_("kind value out of range"));
+      ival = static_cast <int> (uval);
+    }
+  else
+    {
+      if (val > INT_MAX || val < 0)
+	error (_("kind value out of range"));
+      ival = static_cast <int> (val);
+    }
+
+  push_type_int (ival);
+  push_type (tp_kind);
+}
+
+/* Called when a type has a '(kind=N)' modifier after it, for example
+   'character(kind=1)'.  The BASETYPE is the type described by 'character'
+   in our example, and KIND is the integer '1'.  This function returns a
+   new type that represents the basetype of a specific kind.  */
+static struct type *
+convert_to_kind_type (struct type *basetype, int kind)
+{
+  if (basetype == parse_f_type (pstate)->builtin_character)
+    {
+      /* Character of kind 1 is a special case, this is the same as the
+	 base character type.  */
+      if (kind == 1)
+	return parse_f_type (pstate)->builtin_character;
+    }
+
+  error (_("unsupported kind %d for type %s"),
+	 kind, TYPE_SAFE_NAME (basetype));
+
+  /* Should never get here.  */
+  return nullptr;
+}
+
 struct token
 {
   /* The string to match against.  */
@@ -840,6 +905,9 @@ static const struct token f77_keywords[] =
   { "sizeof", SIZEOF, BINOP_END, true },
   { "real_8", REAL_S8_KEYWORD, BINOP_END, true },
   { "real", REAL_KEYWORD, BINOP_END, true },
+  /* The following correspond to actual functions in Fortran and are case
+     insensitive.  */
+  { "kind", KIND, BINOP_END, false }
 };
 
 /* Implementation of a dynamically expandable buffer for processing input
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 779fb1e67fb..72dafe6d66f 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -243,8 +243,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[] =
diff --git a/gdb/parse.c b/gdb/parse.c
index e7168acf7ab..661574e544e 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -927,6 +927,7 @@ operator_length_standard (const struct expression *expr, int endpos,
     case UNOP_CHR:
     case UNOP_FLOAT:
     case UNOP_HIGH:
+    case UNOP_KIND:
     case UNOP_ODD:
     case UNOP_ORD:
     case UNOP_TRUNC:
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 0d4bb820d7b..2730f5a7d12 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -214,7 +214,8 @@ enum type_pieces
     tp_const, 
     tp_volatile, 
     tp_space_identifier,
-    tp_type_stack
+    tp_type_stack,
+    tp_kind
   };
 /* The stack can contain either an enum type_pieces or an int.  */
 union type_stack_elt
diff --git a/gdb/std-operator.def b/gdb/std-operator.def
index 102c17715ad..e26861bd131 100644
--- a/gdb/std-operator.def
+++ b/gdb/std-operator.def
@@ -244,6 +244,7 @@ OP (UNOP_ORD)
 OP (UNOP_ABS)
 OP (UNOP_FLOAT)
 OP (UNOP_HIGH)
+OP (UNOP_KIND)			/* Fortran KIND function.  */
 OP (UNOP_MAX)
 OP (UNOP_MIN)
 OP (UNOP_ODD)
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp
new file mode 100644
index 00000000000..674f299c428
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/intrinsics.exp
@@ -0,0 +1,42 @@
+# Copyright 2019 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file tests GDB's handling of Fortran builtin intrinsic functions.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+standard_testfile .f90
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
+    return -1
+}
+
+if { ![runto MAIN__] } {
+    perror "Could not run to breakpoint `MAIN__'."
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "stop-here"]
+gdb_continue_to_breakpoint "stop-here" ".*stop-here.*"
+
+# Test KIND
+
+gdb_test "p kind (l1)" " = 1"
+gdb_test "p kind (l2)" " = 2"
+gdb_test "p kind (l4)" " = 4"
+gdb_test "p kind (l8)" " = 8"
+gdb_test "p kind (s1)" "argument to kind must be an intrinsic type"
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.f90 b/gdb/testsuite/gdb.fortran/intrinsics.f90
new file mode 100644
index 00000000000..1be22ba4643
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/intrinsics.f90
@@ -0,0 +1,39 @@
+! Copyright 2019 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+program test
+  logical :: l
+  logical (kind=1) :: l1
+  logical (kind=2) :: l2
+  logical (kind=4) :: l4
+  logical (kind=8) :: l8
+
+  type :: a_struct
+     logical :: a1
+     logical :: a2
+  end type a_struct
+
+  type (a_struct) :: s1
+
+  s1%a1 = .TRUE.
+  s1%a2 = .FALSE.
+
+  l1 = .TRUE.
+  l2 = .TRUE.
+  l4 = .TRUE.
+  l8 = .TRUE.
+
+  l = .FALSE.					! stop-here
+end
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
new file mode 100644
index 00000000000..b60b8044110
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -0,0 +1,35 @@
+# Copyright 2019 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This is a set of tests related to GDB's ability to parse and
+# correctly handle the (kind=N) type adjustment mechanism within
+# Fortran.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+# Test parsing of `(kind=N)` type modifiers.
+proc test_basic_parsing_of_type_kinds {} {
+    gdb_test "p ((character (kind=1)) 1)" " = 1"
+}
+
+clean_restart
+
+if [set_lang_fortran] then {
+    test_basic_parsing_of_type_kinds
+} else {
+    warning "$test_name tests suppressed." 0
+}
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (6 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
@ 2019-02-12 16:11 ` Andrew Burgess
  2019-02-12 16:11 ` [PATCH 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords Andrew Burgess
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-02-12 16:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt, Andrew Burgess

Add a new builtin type, an 8-byte integer, and allow GDB to parse
'integer (kind=8)', returning the new 8-byte integer.

gdb/ChangeLog:

	* f-exp.y (convert_to_kind_type): Handle integer (kind=8).
	* f-lang.c (build_fortran_types): Setup builtin_integer_s8.
	* f-lang.h (struct builtin_f_type): Add builtin_integer_s8 field.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp: Test new integer type kind.
---
 gdb/ChangeLog                            | 6 ++++++
 gdb/f-exp.y                              | 2 ++
 gdb/f-lang.c                             | 4 ++++
 gdb/f-lang.h                             | 1 +
 gdb/testsuite/ChangeLog                  | 4 ++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 1 +
 6 files changed, 18 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 980ee4b4adb..d256ff14c1e 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -865,6 +865,8 @@ convert_to_kind_type (struct type *basetype, int kind)
 	return parse_f_type (pstate)->builtin_integer_s2;
       else if (kind == 4)
 	return parse_f_type (pstate)->builtin_integer;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_integer_s8;
     }
 
   error (_("unsupported kind %d for type %s"),
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 72dafe6d66f..7bed3189283 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -374,6 +374,10 @@ build_fortran_types (struct gdbarch *gdbarch)
     = 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");
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
index a4ae6a726d9..7164585f9ea 100644
--- a/gdb/f-lang.h
+++ b/gdb/f-lang.h
@@ -66,6 +66,7 @@ struct builtin_f_type
   struct type *builtin_character;
   struct type *builtin_integer;
   struct type *builtin_integer_s2;
+  struct type *builtin_integer_s8;
   struct type *builtin_logical;
   struct type *builtin_logical_s1;
   struct type *builtin_logical_s2;
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index b2e64d77081..129997e4f66 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -39,6 +39,7 @@ proc test_basic_parsing_of_type_kinds {} {
 
     gdb_test "p ((integer (kind=2)) 1)" " = 1"
     gdb_test "p ((integer (kind=4)) 1)" " = 1"
+    gdb_test "p ((integer (kind=8)) 1)" " = 1"
 }
 
 proc test_parsing_invalid_type_kinds {} {
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (11 preceding siblings ...)
  2019-03-06 18:15 ` [PUSHED 02/11] gdb/fortran: Cleanup code for parsing logical constants Andrew Burgess
@ 2019-03-06 18:15 ` Andrew Burgess
  2019-03-06 18:15 ` [PUSHED 04/11] gdb/fortran: Add new function to evaluate Fortran expressions Andrew Burgess
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

I've now pushed this series as its just minor cleanup and some small
additions to the Fortran parser.

The only changes in the version I pushed from the earlier version is
some additional tests in some of the later patches.

--

Andrew Burgess (11):
  gdb/fortran: Remove some duplicate tests
  gdb/fortran: Cleanup code for parsing logical constants
  gdb/fortran: Simplify handling of Fortran dot operations and keywords
  gdb/fortran: Add new function to evaluate Fortran expressions
  gdb/fortran: Enable debugging of the Fortran parser
  gdb/fortran: Add Fortran 'kind' intrinsic and keyword
  gdb/fortran: Expand the set of types that support (kind=N)
  gdb/fortran: Add builtin 8-byte integer type with (kind=8) support
  gdb/fortran: Use TYPE_CODE_CHAR for character types
  gdb/fortran: Add support for the ABS intrinsic function
  gdb/fortran: Handle older TYPE*SIZE typenames

 gdb/ChangeLog                            |  76 +++++++++
 gdb/expprint.c                           |   1 +
 gdb/f-exp.y                              | 256 ++++++++++++++++++++++---------
 gdb/f-lang.c                             | 102 +++++++++++-
 gdb/f-lang.h                             |   1 +
 gdb/parse.c                              |   1 +
 gdb/parser-defs.h                        |   3 +-
 gdb/std-operator.def                     |   1 +
 gdb/testsuite/ChangeLog                  |  43 ++++++
 gdb/testsuite/gdb.fortran/dot-ops.exp    | 123 +++++++++++++++
 gdb/testsuite/gdb.fortran/intrinsics.exp |  51 ++++++
 gdb/testsuite/gdb.fortran/intrinsics.f90 |  39 +++++
 gdb/testsuite/gdb.fortran/type-kinds.exp |  98 ++++++++++++
 gdb/testsuite/gdb.fortran/types.exp      |   9 +-
 14 files changed, 727 insertions(+), 77 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/dot-ops.exp
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.exp
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.f90
 create mode 100644 gdb/testsuite/gdb.fortran/type-kinds.exp

-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 01/11] gdb/fortran: Remove some duplicate tests
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (13 preceding siblings ...)
  2019-03-06 18:15 ` [PUSHED 04/11] gdb/fortran: Add new function to evaluate Fortran expressions Andrew Burgess
@ 2019-03-06 18:15 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Make the test names unique in gdb.fortran/types.exp by removing a few
duplicate tests.

gdb/testsuite/ChangeLog:

	* gdb.fortran/types.exp (test_float_literal_types_accepted):
	Remove duplicate tests.
---
 gdb/testsuite/ChangeLog             | 5 +++++
 gdb/testsuite/gdb.fortran/types.exp | 4 ----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp
index 2e1f2e1efd1..f786bd30eb0 100644
--- a/gdb/testsuite/gdb.fortran/types.exp
+++ b/gdb/testsuite/gdb.fortran/types.exp
@@ -63,12 +63,8 @@ proc test_float_literal_types_accepted {} {
     gdb_test "pt .44" "type = real\\*\[0-9\]+"
     gdb_test "pt 44.0" "type = real\\*\[0-9\]+"
     gdb_test "pt 10D20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10D20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10d20" "type = real\\*\[0-9\]+"
     gdb_test "pt 10d20" "type = real\\*\[0-9\]+"
     gdb_test "pt 10E20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10E20" "type = real\\*\[0-9\]+"
-    gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
     gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
 }
 
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 04/11] gdb/fortran: Add new function to evaluate Fortran expressions
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (12 preceding siblings ...)
  2019-03-06 18:15 ` [PUSHED 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
@ 2019-03-06 18:15 ` Andrew Burgess
  2019-03-06 18:15 ` [PUSHED 01/11] gdb/fortran: Remove some duplicate tests Andrew Burgess
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This is an initial restructure, it adds a new function in which
Fortran specific expressions can be evaluated.  No Fortran specific
expressions are added with this commit though, so for now, the new
function just forwards all expressions to the default expression
handler, as such, there should be no user visible changes after this
commit.  However, the new function will be useful in later commits.

gdb/ChangeLog:

	* f-lang.c (evaluate_subexp_f): New function.
	(exp_descriptor_f): New global.
	(f_language_defn): Use exp_descriptor_f instead of
	exp_descriptor_standard.
---
 gdb/ChangeLog |  7 +++++++
 gdb/f-lang.c  | 22 +++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 6eb9b230eb7..5beb46c5f31 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -239,6 +239,15 @@ f_collect_symbol_completion_matches (completion_tracker &tracker,
 						      text, word, ":", code);
 }
 
+/* Special expression evaluation cases for Fortran.  */
+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);
+}
+
 static const char *f_extensions[] =
 {
   ".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
@@ -246,6 +255,17 @@ static const char *f_extensions[] =
   NULL
 };
 
+/* Expression processing for Fortran.  */
+static const struct exp_descriptor exp_descriptor_f =
+{
+  print_subexp_standard,
+  operator_length_standard,
+  operator_check_standard,
+  op_name_standard,
+  dump_subexp_body_standard,
+  evaluate_subexp_f
+};
+
 extern const struct language_defn f_language_defn =
 {
   "fortran",
@@ -256,7 +276,7 @@ extern const struct language_defn f_language_defn =
   array_column_major,
   macro_expansion_no,
   f_extensions,
-  &exp_descriptor_standard,
+  &exp_descriptor_f,
   f_parse,			/* parser */
   null_post_parser,
   f_printchar,			/* Print character constant */
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 02/11] gdb/fortran: Cleanup code for parsing logical constants
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (10 preceding siblings ...)
  2019-02-12 16:11 ` [PATCH 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword Andrew Burgess
@ 2019-03-06 18:15 ` Andrew Burgess
  2019-03-06 18:15 ` [PUSHED 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This patch cleans up the code used for parsing the Fortran logical
constants '.TRUE.' and '.FALSE.'.  Instead of listing both upper and
lowercase versions of these strings we now use strncasecmp.

I've also switched to use ARRAY_SIZE for the array iteration, and I've
cleaned up whitespace in the vicinity of the code I've changed.

Finally, I've added a test to ensure that both the upper and lower
case versions of the logical constants are understood by GDB,
something that was missing previously.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* f-exp.y (struct f77_boolean_val): Add comments.
	(boolean_values): Remove uppercase versions, and end marker.
	(yylex): Use ARRAY_SIZE for iterating over boolean_values array,
	and use strncasecmp to achieve case insensitivity.  Additionally,
	perform whitespace cleanup around this code.

gdb/testsuite/ChangeLog:

	* gdb.fortran/types.exp (test_logical_literal_types_accepted):
	Check upper and lower case logical literals.
---
 gdb/ChangeLog                       |  8 ++++++++
 gdb/f-exp.y                         | 35 +++++++++++++++++++----------------
 gdb/testsuite/ChangeLog             |  5 +++++
 gdb/testsuite/gdb.fortran/types.exp |  5 ++++-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index d70c66474c0..704585e63ae 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -807,19 +807,22 @@ static const struct token dot_ops[] =
   { NULL, 0, BINOP_END }
 };
 
-struct f77_boolean_val 
+/* Holds the Fortran representation of a boolean, and the integer value we
+   substitute in when one of the matching strings is parsed.  */
+struct f77_boolean_val
 {
+  /* The string representing a Fortran boolean.  */
   const char *name;
+
+  /* The integer value to replace it with.  */
   int value;
-}; 
+};
 
-static const struct f77_boolean_val boolean_values[]  = 
+/* The set of Fortran booleans.  These are matched case insensitively.  */
+static const struct f77_boolean_val boolean_values[]  =
 {
   { ".true.", 1 },
-  { ".TRUE.", 1 },
-  { ".false.", 0 },
-  { ".FALSE.", 0 },
-  { NULL, 0 }
+  { ".false.", 0 }
 };
 
 static const struct token f77_keywords[] = 
@@ -931,19 +934,19 @@ yylex (void)
   prev_lexptr = lexptr;
  
   tokstart = lexptr;
-  
-  /* First of all, let us make sure we are not dealing with the 
+
+  /* First of all, let us make sure we are not dealing with the
      special tokens .true. and .false. which evaluate to 1 and 0.  */
-  
+
   if (*lexptr == '.')
-    { 
-      for (int i = 0; boolean_values[i].name != NULL; i++)
+    {
+      for (int i = 0; i < ARRAY_SIZE (boolean_values); i++)
 	{
-	  if (strncmp (tokstart, boolean_values[i].name,
-		       strlen (boolean_values[i].name)) == 0)
+	  if (strncasecmp (tokstart, boolean_values[i].name,
+			   strlen (boolean_values[i].name)) == 0)
 	    {
-	      lexptr += strlen (boolean_values[i].name); 
-	      yylval.lval = boolean_values[i].value; 
+	      lexptr += strlen (boolean_values[i].name);
+	      yylval.lval = boolean_values[i].value;
 	      return BOOLEAN_LITERAL;
 	    }
 	}
diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp
index f786bd30eb0..0e28691d90e 100644
--- a/gdb/testsuite/gdb.fortran/types.exp
+++ b/gdb/testsuite/gdb.fortran/types.exp
@@ -45,10 +45,13 @@ proc test_integer_literal_types_rejected {} {
 proc test_logical_literal_types_accepted {} {
     global gdb_prompt
 
-    # Test the only possible values for a logical, TRUE and FALSE.
+    # Test the only possible values for a logical, TRUE and FALSE (and
+    # also true and false).
 
     gdb_test "pt .TRUE." "type = logical\\*2"
     gdb_test "pt .FALSE." "type = logical\\*2"
+    gdb_test "pt .true." "type = logical\\*2"
+    gdb_test "pt .false." "type = logical\\*2"
 }
 
 proc test_float_literal_types_accepted {} {
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (15 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword Andrew Burgess
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Add a new builtin type, an 8-byte integer, and allow GDB to parse
'integer (kind=8)', returning the new 8-byte integer.

gdb/ChangeLog:

	* f-exp.y (convert_to_kind_type): Handle integer (kind=8).
	* f-lang.c (build_fortran_types): Setup builtin_integer_s8.
	* f-lang.h (struct builtin_f_type): Add builtin_integer_s8 field.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp: Test new integer type kind.
---
 gdb/ChangeLog                            | 6 ++++++
 gdb/f-exp.y                              | 2 ++
 gdb/f-lang.c                             | 4 ++++
 gdb/f-lang.h                             | 1 +
 gdb/testsuite/ChangeLog                  | 4 ++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 1 +
 6 files changed, 18 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 980ee4b4adb..d256ff14c1e 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -865,6 +865,8 @@ convert_to_kind_type (struct type *basetype, int kind)
 	return parse_f_type (pstate)->builtin_integer_s2;
       else if (kind == 4)
 	return parse_f_type (pstate)->builtin_integer;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_integer_s8;
     }
 
   error (_("unsupported kind %d for type %s"),
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 34ebfd9de6b..f27eb0d45da 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -375,6 +375,10 @@ build_fortran_types (struct gdbarch *gdbarch)
     = 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");
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
index 5afafb1a051..746c11fd9f1 100644
--- a/gdb/f-lang.h
+++ b/gdb/f-lang.h
@@ -66,6 +66,7 @@ struct builtin_f_type
   struct type *builtin_character;
   struct type *builtin_integer;
   struct type *builtin_integer_s2;
+  struct type *builtin_integer_s8;
   struct type *builtin_logical;
   struct type *builtin_logical_s1;
   struct type *builtin_logical_s2;
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index c679bc504f9..198ac58baf4 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -54,6 +54,7 @@ proc test_basic_parsing_of_type_kinds {} {
 
     test_cast_1_to_type_kind "integer" "2" "1" "2"
     test_cast_1_to_type_kind "integer" "4" "1" "4"
+    test_cast_1_to_type_kind "integer" "8" "1" "8"
 }
 
 proc test_parsing_invalid_type_kinds {} {
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 07/11] gdb/fortran: Expand the set of types that support (kind=N)
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (20 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 05/11] gdb/fortran: Enable debugging of the Fortran parser Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords Andrew Burgess
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Expand the number of types that can be adjusted with a (kind=N) type
extension.

gdb/ChangeLog:

	* f-exp.y (convert_to_kind_type): Handle more type kinds.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp (test_cast_1_to_type_kind): New
	function.
	(test_basic_parsing_of_type_kinds): Expand types tested.
	(test_parsing_invalid_type_kinds): New function.
---
 gdb/ChangeLog                            |  4 ++++
 gdb/f-exp.y                              | 36 ++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                  |  7 ++++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 41 +++++++++++++++++++++++++++++++-
 4 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 327f13736bd..980ee4b4adb 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -830,6 +830,42 @@ convert_to_kind_type (struct type *basetype, int kind)
       if (kind == 1)
 	return parse_f_type (pstate)->builtin_character;
     }
+  else if (basetype == parse_f_type (pstate)->builtin_complex_s8)
+    {
+      if (kind == 4)
+	return parse_f_type (pstate)->builtin_complex_s8;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_complex_s16;
+      else if (kind == 16)
+	return parse_f_type (pstate)->builtin_complex_s32;
+    }
+  else if (basetype == parse_f_type (pstate)->builtin_real)
+    {
+      if (kind == 4)
+	return parse_f_type (pstate)->builtin_real;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_real_s8;
+      else if (kind == 16)
+	return parse_f_type (pstate)->builtin_real_s16;
+    }
+  else if (basetype == parse_f_type (pstate)->builtin_logical)
+    {
+      if (kind == 1)
+	return parse_f_type (pstate)->builtin_logical_s1;
+      else if (kind == 2)
+	return parse_f_type (pstate)->builtin_logical_s2;
+      else if (kind == 4)
+	return parse_f_type (pstate)->builtin_logical;
+      else if (kind == 8)
+	return parse_f_type (pstate)->builtin_logical_s8;
+    }
+  else if (basetype == parse_f_type (pstate)->builtin_integer)
+    {
+      if (kind == 2)
+	return parse_f_type (pstate)->builtin_integer_s2;
+      else if (kind == 4)
+	return parse_f_type (pstate)->builtin_integer;
+    }
 
   error (_("unsupported kind %d for type %s"),
 	 kind, TYPE_SAFE_NAME (basetype));
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index b60b8044110..c679bc504f9 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -21,15 +21,54 @@ load_lib "fortran.exp"
 
 if { [skip_fortran_tests] } { continue }
 
+# Cast the value 1 to the type 'BASE_TYPE (kind=TYPE_KIND)'.  The
+# expected result of the cast is CAST_RESULT, and the size of the
+# value returned by the cast should be SIZE_RESULT.
+proc test_cast_1_to_type_kind {base_type type_kind cast_result size_result} {
+    set type_string "$base_type (kind=$type_kind)"
+    gdb_test "p (($type_string) 1)" " = $cast_result"
+
+    if {($base_type == "real" || $base_type == "complex")
+	&& $type_kind == 16} {
+	setup_kfail gdb/18644 "*-*-*"
+    }
+
+    gdb_test "p sizeof (($type_string) 1)" " = $size_result"
+}
+
 # Test parsing of `(kind=N)` type modifiers.
 proc test_basic_parsing_of_type_kinds {} {
-    gdb_test "p ((character (kind=1)) 1)" " = 1"
+    test_cast_1_to_type_kind "character" "1" "1" "1"
+
+    test_cast_1_to_type_kind "complex" "4" "\\(1,0\\)" "8"
+    test_cast_1_to_type_kind "complex" "8" "\\(1,0\\)" "16"
+    test_cast_1_to_type_kind "complex" "16" "\\(1,0\\)" "32"
+
+    test_cast_1_to_type_kind "real" "4" "1" "4"
+    test_cast_1_to_type_kind "real" "8" "1" "8"
+    test_cast_1_to_type_kind "real" "16" "1" "16"
+
+    test_cast_1_to_type_kind "logical" "1" "\\.TRUE\\." "1"
+    test_cast_1_to_type_kind "logical" "4" "\\.TRUE\\." "4"
+    test_cast_1_to_type_kind "logical" "8" "\\.TRUE\\." "8"
+
+    test_cast_1_to_type_kind "integer" "2" "1" "2"
+    test_cast_1_to_type_kind "integer" "4" "1" "4"
+}
+
+proc test_parsing_invalid_type_kinds {} {
+    foreach typename {complex real logical integer} {
+	foreach typesize {3 5 7 9} {
+	    gdb_test "p (($typename (kind=$typesize)) 1)" "unsupported kind $typesize for type $typename.*"
+	}
+    }
 }
 
 clean_restart
 
 if [set_lang_fortran] then {
     test_basic_parsing_of_type_kinds
+    test_parsing_invalid_type_kinds
 } else {
     warning "$test_name tests suppressed." 0
 }
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 10/11] gdb/fortran: Add support for the ABS intrinsic function
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (14 preceding siblings ...)
  2019-03-06 18:15 ` [PUSHED 01/11] gdb/fortran: Remove some duplicate tests Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 19:11   ` Tom Tromey
  2019-03-06 18:16 ` [PUSHED 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support Andrew Burgess
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

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.
---
 gdb/ChangeLog                            | 11 +++++++++
 gdb/f-exp.y                              |  8 ++++++-
 gdb/f-lang.c                             | 39 ++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                  |  4 ++++
 gdb/testsuite/gdb.fortran/intrinsics.exp |  9 ++++++++
 5 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index d256ff14c1e..88c685a0af3 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -168,6 +168,7 @@ static int parse_number (struct parser_state *, const char *, int,
 %token <voidval> DOLLAR_VARIABLE
 
 %token <opcode> ASSIGN_MODIFY
+%token <opcode> UNOP_INTRINSIC
 
 %left ','
 %left ABOVE_COMMA
@@ -252,6 +253,10 @@ exp	:	exp '('
 					      OP_F77_UNDETERMINED_ARGLIST); }
 	;
 
+exp	:	UNOP_INTRINSIC '(' exp ')'
+			{ write_exp_elt_opcode (pstate, $1); }
+	;
+
 arglist	:
 	;
 
@@ -945,7 +950,8 @@ static const struct token f77_keywords[] =
   { "real", REAL_KEYWORD, BINOP_END, true },
   /* The following correspond to actual functions in Fortran and are case
      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
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index c329d602e24..24f0e61a46b 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -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);
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp
index 674f299c428..00396c74c2f 100644
--- a/gdb/testsuite/gdb.fortran/intrinsics.exp
+++ b/gdb/testsuite/gdb.fortran/intrinsics.exp
@@ -40,3 +40,12 @@ gdb_test "p kind (l2)" " = 2"
 gdb_test "p kind (l4)" " = 4"
 gdb_test "p kind (l8)" " = 8"
 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"
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (16 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 11/11] gdb/fortran: Handle older TYPE*SIZE typenames Andrew Burgess
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

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.
---
 gdb/ChangeLog                            | 16 ++++++++
 gdb/expprint.c                           |  1 +
 gdb/f-exp.y                              | 70 +++++++++++++++++++++++++++++++-
 gdb/f-lang.c                             | 39 +++++++++++++++++-
 gdb/parse.c                              |  1 +
 gdb/parser-defs.h                        |  3 +-
 gdb/std-operator.def                     |  1 +
 gdb/testsuite/ChangeLog                  |  6 +++
 gdb/testsuite/gdb.fortran/intrinsics.exp | 42 +++++++++++++++++++
 gdb/testsuite/gdb.fortran/intrinsics.f90 | 39 ++++++++++++++++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 35 ++++++++++++++++
 11 files changed, 249 insertions(+), 4 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.exp
 create mode 100644 gdb/testsuite/gdb.fortran/intrinsics.f90
 create mode 100644 gdb/testsuite/gdb.fortran/type-kinds.exp

diff --git a/gdb/expprint.c b/gdb/expprint.c
index d7ad1a71878..a22499f4833 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -869,6 +869,7 @@ dump_subexp_body_standard (struct expression *exp,
     case UNOP_MIN:
     case UNOP_ODD:
     case UNOP_TRUNC:
+    case UNOP_KIND:
       elt = dump_subexp (exp, stream, elt);
       break;
     case OP_LONG:
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index c223d366db3..327f13736bd 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -78,6 +78,10 @@ static void growbuf_by_size (int);
 
 static int match_string_literal (void);
 
+static void push_kind_type (LONGEST val, struct type *type);
+
+static struct type *convert_to_kind_type (struct type *basetype, int kind);
+
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -149,7 +153,7 @@ static int parse_number (struct parser_state *, const char *, int,
 
 %token <ssym> NAME_OR_INT 
 
-%token  SIZEOF 
+%token SIZEOF KIND
 %token ERROR
 
 /* Special type cases, put in to allow the parser to distinguish different
@@ -228,6 +232,10 @@ exp	:	SIZEOF exp       %prec UNARY
 			{ write_exp_elt_opcode (pstate, UNOP_SIZEOF); }
 	;
 
+exp	:	KIND '(' exp ')'       %prec UNARY
+			{ write_exp_elt_opcode (pstate, UNOP_KIND); }
+	;
+
 /* No more explicit array operators, we treat everything in F77 as 
    a function call.  The disambiguation as to whether we are 
    doing a subscript operation or a function call is done 
@@ -530,6 +538,13 @@ ptype	:	typebase
 		      case tp_function:
 			follow_type = lookup_function_type (follow_type);
 			break;
+		      case tp_kind:
+			{
+			  int kind_val = pop_type_int ();
+			  follow_type
+			    = convert_to_kind_type (follow_type, kind_val);
+			}
+			break;
 		      }
 		  $$ = follow_type;
 		}
@@ -548,6 +563,8 @@ abs_decl:	'*'
 
 direct_abs_decl: '(' abs_decl ')'
 			{ $$ = $2; }
+	| 	'(' KIND '=' INT ')'
+			{ push_kind_type ($4.val, $4.type); }
 	| 	direct_abs_decl func_mod
 			{ push_type (tp_function); }
 	|	func_mod
@@ -773,6 +790,54 @@ parse_number (struct parser_state *par_state,
   return INT;
 }
 
+/* Called to setup the type stack when we encounter a '(kind=N)' type
+   modifier, performs some bounds checking on 'N' and then pushes this to
+   the type stack followed by the 'tp_kind' marker.  */
+static void
+push_kind_type (LONGEST val, struct type *type)
+{
+  int ival;
+
+  if (TYPE_UNSIGNED (type))
+    {
+      ULONGEST uval = static_cast <ULONGEST> (val);
+      if (uval > INT_MAX)
+	error (_("kind value out of range"));
+      ival = static_cast <int> (uval);
+    }
+  else
+    {
+      if (val > INT_MAX || val < 0)
+	error (_("kind value out of range"));
+      ival = static_cast <int> (val);
+    }
+
+  push_type_int (ival);
+  push_type (tp_kind);
+}
+
+/* Called when a type has a '(kind=N)' modifier after it, for example
+   'character(kind=1)'.  The BASETYPE is the type described by 'character'
+   in our example, and KIND is the integer '1'.  This function returns a
+   new type that represents the basetype of a specific kind.  */
+static struct type *
+convert_to_kind_type (struct type *basetype, int kind)
+{
+  if (basetype == parse_f_type (pstate)->builtin_character)
+    {
+      /* Character of kind 1 is a special case, this is the same as the
+	 base character type.  */
+      if (kind == 1)
+	return parse_f_type (pstate)->builtin_character;
+    }
+
+  error (_("unsupported kind %d for type %s"),
+	 kind, TYPE_SAFE_NAME (basetype));
+
+  /* Should never get here.  */
+  return nullptr;
+}
+
 struct token
 {
   /* The string to match against.  */
@@ -840,6 +905,9 @@ static const struct token f77_keywords[] =
   { "sizeof", SIZEOF, BINOP_END, true },
   { "real_8", REAL_S8_KEYWORD, BINOP_END, true },
   { "real", REAL_KEYWORD, BINOP_END, true },
+  /* The following correspond to actual functions in Fortran and are case
+     insensitive.  */
+  { "kind", KIND, BINOP_END, false }
 };
 
 /* Implementation of a dynamically expandable buffer for processing input
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 5beb46c5f31..34ebfd9de6b 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[] =
diff --git a/gdb/parse.c b/gdb/parse.c
index e7168acf7ab..661574e544e 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -927,6 +927,7 @@ operator_length_standard (const struct expression *expr, int endpos,
     case UNOP_CHR:
     case UNOP_FLOAT:
     case UNOP_HIGH:
+    case UNOP_KIND:
     case UNOP_ODD:
     case UNOP_ORD:
     case UNOP_TRUNC:
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 5d2ee331c05..a607eea2493 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -214,7 +214,8 @@ enum type_pieces
     tp_const, 
     tp_volatile, 
     tp_space_identifier,
-    tp_type_stack
+    tp_type_stack,
+    tp_kind
   };
 /* The stack can contain either an enum type_pieces or an int.  */
 union type_stack_elt
diff --git a/gdb/std-operator.def b/gdb/std-operator.def
index 102c17715ad..e26861bd131 100644
--- a/gdb/std-operator.def
+++ b/gdb/std-operator.def
@@ -244,6 +244,7 @@ OP (UNOP_ORD)
 OP (UNOP_ABS)
 OP (UNOP_FLOAT)
 OP (UNOP_HIGH)
+OP (UNOP_KIND)			/* Fortran KIND function.  */
 OP (UNOP_MAX)
 OP (UNOP_MIN)
 OP (UNOP_ODD)
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp
new file mode 100644
index 00000000000..674f299c428
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/intrinsics.exp
@@ -0,0 +1,42 @@
+# Copyright 2019 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file tests GDB's handling of Fortran builtin intrinsic functions.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+standard_testfile .f90
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
+    return -1
+}
+
+if { ![runto MAIN__] } {
+    perror "Could not run to breakpoint `MAIN__'."
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "stop-here"]
+gdb_continue_to_breakpoint "stop-here" ".*stop-here.*"
+
+# Test KIND
+
+gdb_test "p kind (l1)" " = 1"
+gdb_test "p kind (l2)" " = 2"
+gdb_test "p kind (l4)" " = 4"
+gdb_test "p kind (l8)" " = 8"
+gdb_test "p kind (s1)" "argument to kind must be an intrinsic type"
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.f90 b/gdb/testsuite/gdb.fortran/intrinsics.f90
new file mode 100644
index 00000000000..1be22ba4643
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/intrinsics.f90
@@ -0,0 +1,39 @@
+! Copyright 2019 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+program test
+  logical :: l
+  logical (kind=1) :: l1
+  logical (kind=2) :: l2
+  logical (kind=4) :: l4
+  logical (kind=8) :: l8
+
+  type :: a_struct
+     logical :: a1
+     logical :: a2
+  end type a_struct
+
+  type (a_struct) :: s1
+
+  s1%a1 = .TRUE.
+  s1%a2 = .FALSE.
+
+  l1 = .TRUE.
+  l2 = .TRUE.
+  l4 = .TRUE.
+  l8 = .TRUE.
+
+  l = .FALSE.					! stop-here
+end
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
new file mode 100644
index 00000000000..b60b8044110
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -0,0 +1,35 @@
+# Copyright 2019 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This is a set of tests related to GDB's ability to parse and
+# correctly handle the (kind=N) type adjustment mechanism within
+# Fortran.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+# Test parsing of `(kind=N)` type modifiers.
+proc test_basic_parsing_of_type_kinds {} {
+    gdb_test "p ((character (kind=1)) 1)" " = 1"
+}
+
+clean_restart
+
+if [set_lang_fortran] then {
+    test_basic_parsing_of_type_kinds
+} else {
+    warning "$test_name tests suppressed." 0
+}
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 11/11] gdb/fortran: Handle older TYPE*SIZE typenames
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (17 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This patch adds support for the older TYPE*SIZE typenames that are
still around in older code.

For implementation this currently reuses the kind mechanism, as under
gFortran the kind number is equivalent to the size, however, this is
not necessarily true for all compilers.  If the rules for other
compilers are better understood then this code might need to be
improved slightly to allow for a distinction between size and kind,
however, adding this extra complexity now seems pointless.

gdb/ChangeLog:

	* f-exp.y (direct_abs_decl): Handle TYPE*SIZE type names.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp: Extend to cover TYPE*SIZE cases.
---
 gdb/ChangeLog                            |  4 ++++
 gdb/f-exp.y                              |  2 ++
 gdb/testsuite/ChangeLog                  |  4 ++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 23 +++++++++++++++++++++++
 4 files changed, 33 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 88c685a0af3..7e838b0a93a 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -570,6 +570,8 @@ direct_abs_decl: '(' abs_decl ')'
 			{ $$ = $2; }
 	| 	'(' KIND '=' INT ')'
 			{ push_kind_type ($4.val, $4.type); }
+	|	'*' INT
+			{ push_kind_type ($2.val, $2.type); }
 	| 	direct_abs_decl func_mod
 			{ push_type (tp_function); }
 	|	func_mod
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index b5d4e7b5816..1ae15b96f1a 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -65,11 +65,34 @@ proc test_parsing_invalid_type_kinds {} {
     }
 }
 
+# Perform some basic checks that GDB can parse the older style
+# TYPE*SIZE type names.
+proc test_old_star_type_sizes {} {
+    gdb_test "p ((character*1) 1)" " = 1 '\\\\001'"
+
+    gdb_test "p ((complex*4) 1)" " = \\(1,0\\)"
+    gdb_test "p ((complex*8) 1)" " = \\(1,0\\)"
+    gdb_test "p ((complex*16) 1)" " = \\(1,0\\)"
+
+    gdb_test "p ((real*4) 1)" " = 1"
+    gdb_test "p ((real*8) 1)" " = 1"
+    gdb_test "p ((real*16) 1)" " = 1"
+
+    gdb_test "p ((logical*1) 1)" " = \\.TRUE\\."
+    gdb_test "p ((logical*4) 1)" " = \\.TRUE\\."
+    gdb_test "p ((logical*8) 1)" " = \\.TRUE\\."
+
+    gdb_test "p ((integer*2) 1)" " = 1"
+    gdb_test "p ((integer*4) 1)" " = 1"
+    gdb_test "p ((integer*8) 1)" " = 1"
+}
+
 clean_restart
 
 if [set_lang_fortran] then {
     test_basic_parsing_of_type_kinds
     test_parsing_invalid_type_kinds
+    test_old_star_type_sizes
 } else {
     warning "$test_name tests suppressed." 0
 }
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 05/11] gdb/fortran: Enable debugging of the Fortran parser
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (19 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 07/11] gdb/fortran: Expand the set of types that support (kind=N) Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords Andrew Burgess
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This commit allows 'set debug parser on' to work for the Fortran
parser.

gdb/ChangeLog:

	* f-exp.y (f_parse): Set yydebug.
---
 gdb/ChangeLog | 4 ++++
 gdb/f-exp.y   | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 5e980944b19..c223d366db3 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -1211,6 +1211,8 @@ f_parse (struct parser_state *par_state)
 {
   /* Setting up the parser state.  */
   scoped_restore pstate_restore = make_scoped_restore (&pstate);
+  scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+							parser_debug);
   gdb_assert (par_state != NULL);
   pstate = par_state;
 
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (18 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 11/11] gdb/fortran: Handle older TYPE*SIZE typenames Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  2019-03-06 18:16 ` [PUSHED 05/11] gdb/fortran: Enable debugging of the Fortran parser Andrew Burgess
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Switch to using TYPE_CODE_CHAR for character types.  This appears to
have little impact on the test results as gFortran uses the
DW_TAG_string_type to represent all character variables (as far as I
can see).  The only place this has an impact is when the user casts a
variable to a character type, in which case GDB does now use the CHAR
type, and prints the variable as both a value and a character, for
example, before:

    (gdb) p ((character) 97)
    $1 = 97

and after:

    (gdb) p ((character) 97)
    $1 = 97 'a'

gdb/ChangeLog:

	* f-lang.c (build_fortran_types): Use TYPE_CODE_CHAR for character
	types.

gdb/testsuite/ChangeLog:

	* gdb.fortran/type-kinds.exp: Update expected results.
---
 gdb/ChangeLog                            | 5 +++++
 gdb/f-lang.c                             | 2 +-
 gdb/testsuite/ChangeLog                  | 4 ++++
 gdb/testsuite/gdb.fortran/type-kinds.exp | 2 +-
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index f27eb0d45da..c329d602e24 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -366,7 +366,7 @@ build_fortran_types (struct gdbarch *gdbarch)
     = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "VOID");
 
   builtin_f_type->builtin_character
-    = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "character");
+    = arch_type (gdbarch, TYPE_CODE_CHAR, TARGET_CHAR_BIT, "character");
 
   builtin_f_type->builtin_logical_s1
     = arch_boolean_type (gdbarch, TARGET_CHAR_BIT, 1, "logical*1");
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index 198ac58baf4..b5d4e7b5816 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -38,7 +38,7 @@ proc test_cast_1_to_type_kind {base_type type_kind cast_result size_result} {
 
 # Test parsing of `(kind=N)` type modifiers.
 proc test_basic_parsing_of_type_kinds {} {
-    test_cast_1_to_type_kind "character" "1" "1" "1"
+    test_cast_1_to_type_kind "character" "1" "1 '\\\\001'" "1"
 
     test_cast_1_to_type_kind "complex" "4" "\\(1,0\\)" "8"
     test_cast_1_to_type_kind "complex" "8" "\\(1,0\\)" "16"
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PUSHED 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords
  2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
                   ` (21 preceding siblings ...)
  2019-03-06 18:16 ` [PUSHED 07/11] gdb/fortran: Expand the set of types that support (kind=N) Andrew Burgess
@ 2019-03-06 18:16 ` Andrew Burgess
  22 siblings, 0 replies; 27+ messages in thread
From: Andrew Burgess @ 2019-03-06 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Use strncasecmp to compare Fortran dot operations (like .AND.) and for
the keywords list.  This allows for some duplication to be removed
from the token arrays.  I've also performed whitespace cleanup around
the code I've changed.

I have added some tests to ensure that upper and lowercase dot
operations are correctly tested.  The keywords list remains always
lowercase for now.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* f-exp.y (struct token): Add comments.
	(dot_ops): Remove uppercase versions and the end marker.
	(f77_keywords): Likewise.
	(yylex): Use ARRAY_SIZE to iterate over dot_ops, assert all
	entries in the dot_ops array are case insensitive, and use
	strncasecmp to compare strings.  Also some whitespace cleanup in
	this area.  Similar for the f77_keywords array, except entries in
	this list might be case sensitive.

gdb/testsuite/ChangeLog:

	* gdb.fortran/dot-ops.exp: New file.
---
 gdb/ChangeLog                         |  11 +++
 gdb/f-exp.y                           | 103 ++++++++++++++--------------
 gdb/testsuite/ChangeLog               |   4 ++
 gdb/testsuite/gdb.fortran/dot-ops.exp | 123 ++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 52 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/dot-ops.exp

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 704585e63ae..5e980944b19 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -775,36 +775,33 @@ parse_number (struct parser_state *par_state,
 
 struct token
 {
+  /* The string to match against.  */
   const char *oper;
+
+  /* The lexer token to return.  */
   int token;
+
+  /* The expression opcode to embed within the token.  */
   enum exp_opcode opcode;
+
+  /* When this is true the string in OPER is matched exactly including
+     case, when this is false OPER is matched case insensitively.  */
+  bool case_sensitive;
 };
 
 static const struct token dot_ops[] =
 {
-  { ".and.", BOOL_AND, BINOP_END },
-  { ".AND.", BOOL_AND, BINOP_END },
-  { ".or.", BOOL_OR, BINOP_END },
-  { ".OR.", BOOL_OR, BINOP_END },
-  { ".not.", BOOL_NOT, BINOP_END },
-  { ".NOT.", BOOL_NOT, BINOP_END },
-  { ".eq.", EQUAL, BINOP_END },
-  { ".EQ.", EQUAL, BINOP_END },
-  { ".eqv.", EQUAL, BINOP_END },
-  { ".NEQV.", NOTEQUAL, BINOP_END },
-  { ".neqv.", NOTEQUAL, BINOP_END },
-  { ".EQV.", EQUAL, BINOP_END },
-  { ".ne.", NOTEQUAL, BINOP_END },
-  { ".NE.", NOTEQUAL, BINOP_END },
-  { ".le.", LEQ, BINOP_END },
-  { ".LE.", LEQ, BINOP_END },
-  { ".ge.", GEQ, BINOP_END },
-  { ".GE.", GEQ, BINOP_END },
-  { ".gt.", GREATERTHAN, BINOP_END },
-  { ".GT.", GREATERTHAN, BINOP_END },
-  { ".lt.", LESSTHAN, BINOP_END },
-  { ".LT.", LESSTHAN, BINOP_END },
-  { NULL, 0, BINOP_END }
+  { ".and.", BOOL_AND, BINOP_END, false },
+  { ".or.", BOOL_OR, BINOP_END, false },
+  { ".not.", BOOL_NOT, BINOP_END, false },
+  { ".eq.", EQUAL, BINOP_END, false },
+  { ".eqv.", EQUAL, BINOP_END, false },
+  { ".neqv.", NOTEQUAL, BINOP_END, false },
+  { ".ne.", NOTEQUAL, BINOP_END, false },
+  { ".le.", LEQ, BINOP_END, false },
+  { ".ge.", GEQ, BINOP_END, false },
+  { ".gt.", GREATERTHAN, BINOP_END, false },
+  { ".lt.", LESSTHAN, BINOP_END, false },
 };
 
 /* Holds the Fortran representation of a boolean, and the integer value we
@@ -825,25 +822,25 @@ static const struct f77_boolean_val boolean_values[]  =
   { ".false.", 0 }
 };
 
-static const struct token f77_keywords[] = 
+static const struct token f77_keywords[] =
 {
-  { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END },
-  { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END },
-  { "character", CHARACTER, BINOP_END },
-  { "integer_2", INT_S2_KEYWORD, BINOP_END },
-  { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END },
-  { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END },
-  { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END },
-  { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END },
-  { "integer", INT_KEYWORD, BINOP_END },
-  { "logical", LOGICAL_KEYWORD, BINOP_END },
-  { "real_16", REAL_S16_KEYWORD, BINOP_END },
-  { "complex", COMPLEX_S8_KEYWORD, BINOP_END },
-  { "sizeof", SIZEOF, BINOP_END },
-  { "real_8", REAL_S8_KEYWORD, BINOP_END },
-  { "real", REAL_KEYWORD, BINOP_END },
-  { NULL, 0, BINOP_END }
-}; 
+  /* Historically these have always been lowercase only in GDB.  */
+  { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END, true },
+  { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END, true },
+  { "character", CHARACTER, BINOP_END, true },
+  { "integer_2", INT_S2_KEYWORD, BINOP_END, true },
+  { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END, true },
+  { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END, true },
+  { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END, true },
+  { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END, true },
+  { "integer", INT_KEYWORD, BINOP_END, true },
+  { "logical", LOGICAL_KEYWORD, BINOP_END, true },
+  { "real_16", REAL_S16_KEYWORD, BINOP_END, true },
+  { "complex", COMPLEX_S8_KEYWORD, BINOP_END, true },
+  { "sizeof", SIZEOF, BINOP_END, true },
+  { "real_8", REAL_S8_KEYWORD, BINOP_END, true },
+  { "real", REAL_KEYWORD, BINOP_END, true },
+};
 
 /* Implementation of a dynamically expandable buffer for processing input
    characters acquired through lexptr and building a value to return in
@@ -951,18 +948,18 @@ yylex (void)
 	    }
 	}
     }
-  
+
   /* See if it is a special .foo. operator.  */
-  
-  for (int i = 0; dot_ops[i].oper != NULL; i++)
-    if (strncmp (tokstart, dot_ops[i].oper,
-		 strlen (dot_ops[i].oper)) == 0)
+  for (int i = 0; i < ARRAY_SIZE (dot_ops); i++)
+    if (strncasecmp (tokstart, dot_ops[i].oper,
+		     strlen (dot_ops[i].oper)) == 0)
       {
+	gdb_assert (!dot_ops[i].case_sensitive);
 	lexptr += strlen (dot_ops[i].oper);
 	yylval.opcode = dot_ops[i].opcode;
 	return dot_ops[i].token;
       }
-  
+
   /* See if it is an exponentiation operator.  */
 
   if (strncmp (tokstart, "**", 2) == 0)
@@ -1122,16 +1119,18 @@ yylex (void)
   lexptr += namelen;
   
   /* Catch specific keywords.  */
-  
-  for (int i = 0; f77_keywords[i].oper != NULL; i++)
+
+  for (int i = 0; i < ARRAY_SIZE (f77_keywords); i++)
     if (strlen (f77_keywords[i].oper) == namelen
-	&& strncmp (tokstart, f77_keywords[i].oper, namelen) == 0)
+	&& ((!f77_keywords[i].case_sensitive
+	     && strncasecmp (tokstart, f77_keywords[i].oper, namelen) == 0)
+	    || (f77_keywords[i].case_sensitive
+		&& strncmp (tokstart, f77_keywords[i].oper, namelen) == 0)))
       {
-	/* 	lexptr += strlen(f77_keywords[i].operator); */ 
 	yylval.opcode = f77_keywords[i].opcode;
 	return f77_keywords[i].token;
       }
-  
+
   yylval.sval.ptr = tokstart;
   yylval.sval.length = namelen;
   
diff --git a/gdb/testsuite/gdb.fortran/dot-ops.exp b/gdb/testsuite/gdb.fortran/dot-ops.exp
new file mode 100644
index 00000000000..787471db918
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/dot-ops.exp
@@ -0,0 +1,123 @@
+# Copyright 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file tests GDB's handling of some of the builtin logical and
+# arithmetic dot operators in Fortran, for example `.AND.` and `.LE.`.
+
+load_lib "fortran.exp"
+
+if { [skip_fortran_tests] } { continue }
+
+proc test_dot_operations {} {
+
+    foreach_with_prefix format { "uppercase" "lowercase" } {
+	if {$format == "uppercase"} {
+	    set true ".TRUE."
+	    set false ".FALSE."
+	    set and ".AND."
+	    set or ".OR."
+	    set not ".NOT."
+	    set eqv ".EQV."
+	    set neqv ".NEQV."
+	    set eq ".EQ."
+	    set ne ".NE."
+	    set le ".LE."
+	    set ge ".GE."
+	    set lt ".LT."
+	    set gt ".GT."
+	} else {
+	    set true ".true."
+	    set false ".false."
+	    set and ".and."
+	    set or ".or."
+	    set not ".not."
+	    set eqv ".eqv."
+	    set neqv ".neqv."
+	    set eq ".eq."
+	    set ne ".ne."
+	    set le ".le."
+	    set ge ".ge."
+	    set lt ".lt."
+	    set gt ".gt."
+	}
+
+	# Logical AND
+	gdb_test "p $true $and $true" " = .TRUE."
+	gdb_test "p $true $and $false" " = .FALSE."
+	gdb_test "p $false $and $true" " = .FALSE."
+	gdb_test "p $false $and $false" " = .FALSE."
+
+	# Logical OR
+	gdb_test "p $true $or $true" " = .TRUE."
+	gdb_test "p $true $or $false" " = .TRUE."
+	gdb_test "p $false $or $true" " = .TRUE."
+	gdb_test "p $false $or $false" " = .FALSE."
+
+	# Logical NOT
+	gdb_test "p $not $true" " = .FALSE."
+	gdb_test "p $not $false" " = .TRUE."
+
+	# Logical EQV
+	gdb_test "p $true $eqv $true" " = .TRUE."
+	gdb_test "p $true $eqv $false" " = .FALSE."
+	gdb_test "p $false $eqv $true" " = .FALSE."
+	gdb_test "p $false $eqv $false" " = .TRUE."
+
+	# Logical NEQV
+	gdb_test "p $true $neqv $true" " = .FALSE."
+	gdb_test "p $true $neqv $false" " = .TRUE."
+	gdb_test "p $false $neqv $true" " = .TRUE."
+	gdb_test "p $false $neqv $false" " = .FALSE."
+
+	# Arithmetic EQ
+	gdb_test "p 5 $eq 4" " = .FALSE."
+	gdb_test "p 4 $eq 4" " = .TRUE."
+
+	# Arithmetic NE
+	gdb_test "p 5 $ne 4" " = .TRUE."
+	gdb_test "p 4 $ne 4" " = .FALSE."
+
+	# Arithmetic LE
+	gdb_test "p 5 $le 4" " = .FALSE."
+	gdb_test "p 4 $le 4" " = .TRUE."
+	gdb_test "p 3 $le 4" " = .TRUE."
+
+	# Arithmetic LT
+	gdb_test "p 5 $lt 4" " = .FALSE."
+	gdb_test "p 4 $lt 4" " = .FALSE."
+	gdb_test "p 3 $lt 4" " = .TRUE."
+
+	# Arithmetic GE
+	gdb_test "p 5 $ge 4" " = .TRUE."
+	gdb_test "p 4 $ge 4" " = .TRUE."
+	gdb_test "p 3 $ge 4" " = .FALSE."
+
+	# Arithmetic GT
+	gdb_test "p 5 $gt 4" " = .TRUE."
+	gdb_test "p 4 $gt 4" " = .FALSE."
+	gdb_test "p 3 $gt 4" " = .FALSE."
+    }
+}
+
+# Start of test script.
+
+clean_restart
+
+if [set_lang_fortran] then {
+    test_dot_operations
+} else {
+    warning "$test_name tests suppressed." 0
+}
+
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PUSHED 10/11] gdb/fortran: Add support for the ABS intrinsic function
  2019-03-06 18:16 ` [PUSHED 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
@ 2019-03-06 19:11   ` Tom Tromey
  2019-03-07 15:23     ` [PATCH] gdb: Move value_from_host_double into value.c and make more use of it Andrew Burgess
  0 siblings, 1 reply; 27+ messages in thread
From: Tom Tromey @ 2019-03-06 19:11 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:

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

Sorry for not looking at these earlier...

Andrew> +/* Create and return a value object of TYPE containing the value D.  The
Andrew> +   TYPE must be of TYPE_CODE_FLT, and must be large enough to hold D once
Andrew> +   it is converted to target format.  */
Andrew> +
Andrew> +static struct value *
Andrew> +value_from_host_double (struct type *type, double d)
Andrew> +{
Andrew> +  struct value *value = allocate_value (type);
Andrew> +  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
Andrew> +  target_float_from_host_double (value_contents_raw (value),
Andrew> +                                 value_type (value), d);
Andrew> +  return value;

This seems reasonable to move to value.c.  At least py-value.c could use it.
I can do that if you also think it's worthwhile.

Tom

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH] gdb: Move value_from_host_double into value.c and make more use of it
  2019-03-06 19:11   ` Tom Tromey
@ 2019-03-07 15:23     ` Andrew Burgess
  2019-03-07 15:49       ` Tom Tromey
  0 siblings, 1 reply; 27+ messages in thread
From: Andrew Burgess @ 2019-03-07 15:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey, Andrew Burgess

Something like this?

---

The function value_from_host_double can be moved from f-lang.c into
value.c as a generally useful function, and then used more widely.

Tested on X86-64/GNU Linux with no regressions.

gdb/ChangeLog:

	* f-lang.c (value_from_host_double): Moved to...
	* value.c (value_from_host_double): ...here.
	* value.h (value_from_host_double): Declare.
	* guile/scm-math.c (vlscm_convert_typed_number): Use
	value_from_host_double.
	(vlscm_convert_number): Likewise.
	* guile/scm-value.c (gdbscm_value_to_real): Likewise.
	* python/py-value.c (convert_value_from_python): Likewise.
---
 gdb/ChangeLog         | 11 +++++++++++
 gdb/f-lang.c          | 14 --------------
 gdb/guile/scm-math.c  | 16 ++--------------
 gdb/guile/scm-value.c |  3 +--
 gdb/python/py-value.c |  6 +-----
 gdb/value.c           | 13 +++++++++++++
 gdb/value.h           |  1 +
 7 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 24f0e61a46b..7bd119690b4 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -241,20 +241,6 @@ 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,
diff --git a/gdb/guile/scm-math.c b/gdb/guile/scm-math.c
index a31a1455487..d351ed0522c 100644
--- a/gdb/guile/scm-math.c
+++ b/gdb/guile/scm-math.c
@@ -559,13 +559,7 @@ vlscm_convert_typed_number (const char *func_name, int obj_arg_pos, SCM obj,
 	}
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    {
-      struct value *value = allocate_value (type);
-      target_float_from_host_double (value_contents_raw (value),
-				     value_type (value),
-				     scm_to_double (obj));
-      return value;
-    }
+    return value_from_host_double (type, scm_to_double (obj));
   else
     {
       *except_scmp = gdbscm_make_type_error (func_name, obj_arg_pos, obj,
@@ -645,13 +639,7 @@ vlscm_convert_number (const char *func_name, int obj_arg_pos, SCM obj,
 				   gdbscm_scm_to_ulongest (obj));
     }
   else if (scm_is_real (obj))
-    {
-      struct value *value = allocate_value (bt->builtin_double);
-      target_float_from_host_double (value_contents_raw (value),
-				     value_type (value),
-				     scm_to_double (obj));
-      return value;
-    }
+    return value_from_host_double (bt->builtin_double, scm_to_double (obj));
 
   *except_scmp = gdbscm_make_out_of_range_error (func_name, obj_arg_pos, obj,
 			_("value not a number representable on the target"));
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 294e3e7cafc..658924b1197 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -903,8 +903,7 @@ gdbscm_value_to_real (SCM self)
       if (is_floating_value (value))
 	{
 	  d = target_float_to_host_double (value_contents (value), type);
-	  check = allocate_value (type);
-	  target_float_from_host_double (value_contents_raw (check), type, d);
+	  check = value_from_host_double (type, d);
 	}
       else if (TYPE_UNSIGNED (type))
 	{
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 63a9952e513..dd6a536b6ad 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1739,11 +1739,7 @@ convert_value_from_python (PyObject *obj)
 	  double d = PyFloat_AsDouble (obj);
 
 	  if (! PyErr_Occurred ())
-	    {
-	      value = allocate_value (builtin_type_pyfloat);
-	      target_float_from_host_double (value_contents_raw (value),
-					     value_type (value), d);
-	    }
+	    value = value_from_host_double (builtin_type_pyfloat, d);
 	}
       else if (gdbpy_is_string (obj))
 	{
diff --git a/gdb/value.c b/gdb/value.c
index 50e47a936aa..dc297dfe0f9 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3430,6 +3430,19 @@ value_from_pointer (struct type *type, CORE_ADDR addr)
   return val;
 }
 
+/* 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.  */
+
+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;
+}
 
 /* Create a value of type TYPE whose contents come from VALADDR, if it
    is non-null, and whose memory address (in the inferior) is
diff --git a/gdb/value.h b/gdb/value.h
index 1ca91e041a1..d3905cc354a 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -669,6 +669,7 @@ extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num);
 extern struct value *value_from_longest (struct type *type, LONGEST num);
 extern struct value *value_from_ulongest (struct type *type, ULONGEST num);
 extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr);
+extern struct value *value_from_host_double (struct type *type, double d);
 extern struct value *value_from_history_ref (const char *, const char **);
 extern struct value *value_from_component (struct value *, struct type *,
 					   LONGEST);
-- 
2.14.5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] gdb: Move value_from_host_double into value.c and make more use of it
  2019-03-07 15:23     ` [PATCH] gdb: Move value_from_host_double into value.c and make more use of it Andrew Burgess
@ 2019-03-07 15:49       ` Tom Tromey
  0 siblings, 0 replies; 27+ messages in thread
From: Tom Tromey @ 2019-03-07 15:49 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches, Tom Tromey

>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:

Andrew> Something like this?

Yes, thank you.

Tom

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2019-03-07 15:49 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-12 16:11 [PATCH 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
2019-02-12 16:11 ` [PATCH 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
2019-02-12 16:11 ` [PATCH 07/11] gdb/fortran: Expand the set of types that support (kind=N) Andrew Burgess
2019-02-12 16:11 ` [PATCH 05/11] gdb/fortran: Enable debugging of the Fortran parser Andrew Burgess
2019-02-12 16:11 ` [PATCH 04/11] gdb/fortran: Add new function to evaluate Fortran expressions Andrew Burgess
2019-02-12 16:11 ` [PATCH 11/11] gdb/fortran: Handle older TYPE*SIZE typenames Andrew Burgess
2019-02-12 16:11 ` [PATCH 02/11] gdb/fortran: Cleanup code for parsing logical constants Andrew Burgess
2019-02-12 16:11 ` [PATCH 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
2019-02-12 16:11 ` [PATCH 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support Andrew Burgess
2019-02-12 16:11 ` [PATCH 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords Andrew Burgess
2019-02-12 16:11 ` [PATCH 01/11] gdb/fortran: Remove some duplicate tests Andrew Burgess
2019-02-12 16:11 ` [PATCH 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword Andrew Burgess
2019-03-06 18:15 ` [PUSHED 02/11] gdb/fortran: Cleanup code for parsing logical constants Andrew Burgess
2019-03-06 18:15 ` [PUSHED 00/11] Fortran Parser Cleanup, KIND Support, and Intrinsic Functions Andrew Burgess
2019-03-06 18:15 ` [PUSHED 04/11] gdb/fortran: Add new function to evaluate Fortran expressions Andrew Burgess
2019-03-06 18:15 ` [PUSHED 01/11] gdb/fortran: Remove some duplicate tests Andrew Burgess
2019-03-06 18:16 ` [PUSHED 10/11] gdb/fortran: Add support for the ABS intrinsic function Andrew Burgess
2019-03-06 19:11   ` Tom Tromey
2019-03-07 15:23     ` [PATCH] gdb: Move value_from_host_double into value.c and make more use of it Andrew Burgess
2019-03-07 15:49       ` Tom Tromey
2019-03-06 18:16 ` [PUSHED 08/11] gdb/fortran: Add builtin 8-byte integer type with (kind=8) support Andrew Burgess
2019-03-06 18:16 ` [PUSHED 06/11] gdb/fortran: Add Fortran 'kind' intrinsic and keyword Andrew Burgess
2019-03-06 18:16 ` [PUSHED 11/11] gdb/fortran: Handle older TYPE*SIZE typenames Andrew Burgess
2019-03-06 18:16 ` [PUSHED 09/11] gdb/fortran: Use TYPE_CODE_CHAR for character types Andrew Burgess
2019-03-06 18:16 ` [PUSHED 05/11] gdb/fortran: Enable debugging of the Fortran parser Andrew Burgess
2019-03-06 18:16 ` [PUSHED 07/11] gdb/fortran: Expand the set of types that support (kind=N) Andrew Burgess
2019-03-06 18:16 ` [PUSHED 03/11] gdb/fortran: Simplify handling of Fortran dot operations and keywords Andrew Burgess

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).