diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/NEWS | 4 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 11 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 36 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/complex-parts.c | 50 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/complex-parts.exp | 62 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/default.exp | 2 | ||||
-rw-r--r-- | gdb/value.c | 52 |
10 files changed, 234 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ce9c573..35a9550 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2019-04-01 Andrew Burgess <andrew.burgess@embecosm.com> + + * NEWS: Mention new internal functions. + * dwarf2read.c (dwarf2_init_complex_target_type): New function. + (read_base_type): Use dwarf2_init_complex_target_type. + * value.c (creal_internal_fn): New function. + (cimag_internal_fn): New function. + (_initialize_values): Register new internal functions. + 2019-04-01 Philippe Waroquiers <philippe.waroquiers@skynet.be> * infrun.c (stop_all_threads): If debug_infrun, always @@ -16,6 +16,9 @@ * Support for Pointer Authentication on AArch64 Linux. +* Two new convernience functions $_cimag and $_creal that extract the + imaginary and real parts respectively from complex numbers. + * Python API ** The gdb.Value type has a new method 'format_string' which returns a @@ -24,7 +27,6 @@ 'array_indexes', 'symbols', 'unions', 'deref_refs', 'actual_objects', 'static_members', 'max_elements', 'repeat_threshold', and 'format'. - *** Changes in GDB 8.3 * GDB and GDBserver now support access to additional registers on diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index c0d5aac..ea5fafd 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2019-04-01 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.texinfo (Convenience Funs): Document '$_creal' and + '$_cimag'. + 2019-03-30 Eli Zaretskii <eliz@gnu.org> * gdb.texinfo (Convenience Vars): Document $_gdb_major and diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index bb958cf..f410d02 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -11401,6 +11401,17 @@ an enumerated type: Visiting node of type NODE_INTEGER @end smallexample +@item $_cimag(@var{value}) +@itemx $_creal(@var{value}) +@findex $_cimag@r{, convenience function} +@findex $_creal@r{, convenience function} +Return the imaginary (@code{$_cimag}) or real (@code{$_creal}) part of +the complex number @var{value}. + +The type of the imaginary or real part depends on the type of the +complex number, e.g., using @code{$_cimag} on a @code{float complex} +will return an imaginary part of type @code{float}. + @end table @value{GDBN} provides the ability to list and get help on diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a5e953b..8881a1e 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -17530,6 +17530,40 @@ dwarf2_init_integer_type (struct dwarf2_cu *cu, struct objfile *objfile, return type; } +/* Initialise and return a floating point type of size BITS suitable for + use as a component of a complex number. The NAME_HINT is passed through + when initialising the floating point type and is the name of the complex + type. + + As DWARF doesn't currently provide an explicit name for the components + of a complex number, but it can be helpful to have these components + named, we try to select a suitable name based on the size of the + component. */ +static struct type * +dwarf2_init_complex_target_type (struct dwarf2_cu *cu, + struct objfile *objfile, + int bits, const char *name_hint) +{ + gdbarch *gdbarch = get_objfile_arch (objfile); + struct type *tt = nullptr; + + switch (bits) + { + case 32: + tt = builtin_type (gdbarch)->builtin_float; + break; + case 64: + tt = builtin_type (gdbarch)->builtin_double; + break; + case 128: + tt = builtin_type (gdbarch)->builtin_long_double; + break; + } + + const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt); + return dwarf2_init_float_type (objfile, bits, name, name_hint); +} + /* Find a representation of a given base type and install it in the TYPE field of the die. */ @@ -17569,7 +17603,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) type = init_boolean_type (objfile, bits, 1, name); break; case DW_ATE_complex_float: - type = dwarf2_init_float_type (objfile, bits / 2, NULL, name); + type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name); type = init_complex_type (objfile, name, type); break; case DW_ATE_decimal_float: diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index b429149..7d603ad 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-01 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.base/complex-parts.c: New file. + * gdb.base/complex-parts.exp: New file. + 2019-04-01 Tom Tromey <tromey@adacore.com> PR symtab/23331: diff --git a/gdb/testsuite/gdb.base/complex-parts.c b/gdb/testsuite/gdb.base/complex-parts.c new file mode 100644 index 0000000..243caee --- /dev/null +++ b/gdb/testsuite/gdb.base/complex-parts.c @@ -0,0 +1,50 @@ +/* Copyright 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + 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/>. */ + +/* Unlike the other 'complex.c' test, this one uses the "standard" header + file to pull in the complex types. The testing is around printing the + complex numbers, and using the convenience function $_cimag and $_creal + to extract the parts of the complex numbers. */ + +#include <complex.h> + +void +keep_around (volatile void *ptr) +{ + asm ("" ::: "memory"); +} + +int +main (void) +{ + double complex z1 = 1.5 + 4.5 * I; + float complex z2 = 2.5 - 5.5 * I; + long double complex z3 = 3.5 + 6.5 * I; + + double d1 = 1.5; + float f1 = 2.5; + int i1 = 3; + + keep_around (&z1); + keep_around (&z2); + keep_around (&z3); + keep_around (&d1); + keep_around (&f1); + keep_around (&i1); + + return 0; /* Break Here. */ +} diff --git a/gdb/testsuite/gdb.base/complex-parts.exp b/gdb/testsuite/gdb.base/complex-parts.exp new file mode 100644 index 0000000..ce8f427 --- /dev/null +++ b/gdb/testsuite/gdb.base/complex-parts.exp @@ -0,0 +1,62 @@ +# 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/>. + +standard_testfile + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +if { ![runto_main] } then { + fail "can't run to main" + return 0 +} + +gdb_breakpoint [gdb_get_line_number "Break Here"] +gdb_continue_to_breakpoint "breakpt" ".* Break Here\\. .*" + +gdb_test "p z1" " = 1.5 \\+ 4.5 \\* I" +gdb_test "p z2" " = 2.5 \\+ -5.5 \\* I" +gdb_test "p z3" " = 3.5 \\+ 6.5 \\* I" + +gdb_test "ptype z1" " = complex double" +gdb_test "ptype z2" " = complex float" +gdb_test "ptype z3" " = complex long double" + +gdb_test "p \$_cimag (z1)" " = 4.5" +gdb_test "ptype \$" " = double" + +gdb_test "p \$_cimag (z2)" " = -5.5" +gdb_test "ptype \$" " = float" + +gdb_test "p \$_cimag (z3)" " = 6.5" +gdb_test "ptype \$" " = long double" + +gdb_test "p \$_creal (z1)" " = 1.5" +gdb_test "ptype \$" " = double" + +gdb_test "p \$_creal (z2)" " = 2.5" +gdb_test "ptype \$" " = float" + +gdb_test "p \$_creal (z3)" " = 3.5" +gdb_test "ptype \$" " = long double" + +gdb_test "p \$_cimag (d1)" "expected a complex number" +gdb_test "p \$_cimag (f1)" "expected a complex number" +gdb_test "p \$_cimag (i1)" "expected a complex number" + +gdb_test "p \$_creal (d1)" "expected a complex number" +gdb_test "p \$_creal (f1)" "expected a complex number" +gdb_test "p \$_creal (i1)" "expected a complex number" diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 9ff5144..56ec917 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -601,6 +601,8 @@ set show_conv_list \ {$_probe_arg9 = <error: No frame selected>} \ {$_probe_arg10 = <error: No frame selected>} \ {$_probe_arg11 = <error: No frame selected>} \ + {$_cimag = <internal function _cimag>} \ + {$_creal = <internal function _creal>} \ {$_isvoid = <internal function _isvoid>} \ {$_gdb_major = 8} \ {$_gdb_minor = 4} \ diff --git a/gdb/value.c b/gdb/value.c index bcfc084..c0f8a58 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3933,6 +3933,44 @@ isvoid_internal_fn (struct gdbarch *gdbarch, return value_from_longest (builtin_type (gdbarch)->builtin_int, ret); } +/* Implementation of the convenience function $_cimag. Extracts the + real part from a complex number. */ + +static struct value * +creal_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, struct value **argv) +{ + if (argc != 1) + error (_("You must provide one argument for $_creal.")); + + value *cval = argv[0]; + type *ctype = check_typedef (value_type (cval)); + if (TYPE_CODE (ctype) != TYPE_CODE_COMPLEX) + error (_("expected a complex number")); + return value_from_component (cval, TYPE_TARGET_TYPE (ctype), 0); +} + +/* Implementation of the convenience function $_cimag. Extracts the + imaginary part from a complex number. */ + +static struct value * +cimag_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, + struct value **argv) +{ + if (argc != 1) + error (_("You must provide one argument for $_cimag.")); + + value *cval = argv[0]; + type *ctype = check_typedef (value_type (cval)); + if (TYPE_CODE (ctype) != TYPE_CODE_COMPLEX) + error (_("expected a complex number")); + return value_from_component (cval, TYPE_TARGET_TYPE (ctype), + TYPE_LENGTH (TYPE_TARGET_TYPE (ctype))); +} + #if GDB_SELF_TEST namespace selftests { @@ -4114,6 +4152,20 @@ Usage: $_isvoid (expression)\n\ Return 1 if the expression is void, zero otherwise."), isvoid_internal_fn, NULL); + add_internal_function ("_creal", _("\ +Extract the real part of a complex number.\n\ +Usage: $_creal (expression)\n\ +Return the real part of a complex number, the type depends on the\n\ +type of a complex number."), + creal_internal_fn, NULL); + + add_internal_function ("_cimag", _("\ +Extract the imaginary part of a complex number.\n\ +Usage: $_cimag (expression)\n\ +Return the imaginary part of a complex number, the type depends on the\n\ +type of a complex number."), + cimag_internal_fn, NULL); + add_setshow_zuinteger_unlimited_cmd ("max-value-size", class_support, &max_value_size, _("\ Set maximum sized value gdb will load from the inferior."), _("\ |