diff options
author | Weimin Pan <weimin.pan@oracle.com> | 2019-10-07 00:46:52 +0000 |
---|---|---|
committer | Weimin Pan <weimin.pan@oracle.com> | 2019-10-07 02:26:27 +0000 |
commit | 30d1f0184953478d14641c495261afd06ebfabac (patch) | |
tree | 8fde16f1b36e4bc889e54f9803d94cee835b66be /gdb/testsuite | |
parent | Renaming of ctf (the trace format) files (diff) | |
download | binutils-gdb-30d1f0184953478d14641c495261afd06ebfabac.tar.gz binutils-gdb-30d1f0184953478d14641c495261afd06ebfabac.tar.bz2 binutils-gdb-30d1f0184953478d14641c495261afd06ebfabac.zip |
gdb: CTF support
This patch adds the CTF (Compact Ansi-C Type Format) support in gdb.
Two submissions on which this gdb work depends were posted earlier
in May:
* On the binutils mailing list - adding libctf which creates, updates,
reads, and manipulates the CTF data.
* On the gcc mailing list - expanding gcc to directly emit the CFT data
with a new command line option -gt.
CTF is a reduced form of debugging information whose main purpose is to
describe the type of C entities such as structures, unions, typedefs and
function arguments at the global scope only. It does not contain debug
information about source lines, location expressions, or local variables.
For more information on CTF, see the documentation in the libdtrace-ctf
source tree, available here:
<https://raw.githubusercontent.com/oracle/libdtrace-ctf/master/doc/ctf-format>.
This patch expands struct elfinfo by adding the .ctf section, which
contains CTF debugging info, and modifies elf_symfile_read() to read it.
If both DWARF and CTF exist in a program, only DWARF will be read. CTF data
will be read only when there is no DWARF. The two-stage symbolic reading
and setting strategy, partial and full, was used.
File ctfread.c contains functions to transform CTF data into gdb's internal
symbol table structures by iterately reading entries from CTF sections
of "data objects", "function info", "variable info", and "data types"
when setting up either partial or full symbol table. If the ELF symbol table
is available, e.g. not stripped, the CTF reader will associate the found
type information with these symbol entries. Due to the proximity between DWARF
and CTF (CTF being a much simplified subset of DWARF), some DWARF implementation
was reused to support CTF.
Test cases ctf-constvars.exp, ctf-cvexpr.exp, ctf-ptype.exp, and ctf-whatis.exp
have been added to verify the correctness of this support.
This patch has missing features and limitations which we will add and
address in the future patches.
gdb/ChangeLog
+2019-10-07 Weimin Pan <weimin.pan@oracle.com>
+
+ * gdb/ctfread.c: New file.
+ * gdb/ctfread.h: New file.
+ * gdb/elfread.c: Include ctfread.h.
+ (struct elfinfo text_p): New member ctfsect.
+ (elf_locate_sections): Mark CTF section.
+ (elf_symfile_read): Call elfctf_build_psymtabs.
+ * gdb/Makefile.in (LIBCTF): Add.
+ (CLIBS): Use it.
+ (CDEPS): Likewise.
+ (DIST): Add ctfread.c.
+ * Makefile.def (dependencies): Add all-libctf to all-gdb
+ * Makefile.in: Add "all-gdb: maybe-all-libctf"
+
gdb/testsuite/ChangeLog
+2019-10-07 Weimin Pan <weimin.pan@oracle.com>
+
+ * gdb.base/ctf-whatis.exp: New file.
+ * gdb.base/ctf-whatis.c: New file.
+ * gdb.base/ctf-ptype.exp: New file.
+ * gdb.base/ctf-ptype.c: New file.
+ * gdb.base/ctf-constvars.exp: New file.
+ * gdb.base/ctf-constvars.c: New file.
+ * gdb.base/ctf-cvexpr.exp: New file.
+
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-constvars.c | 116 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-constvars.exp | 114 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-cvexpr.exp | 495 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-ptype.c | 305 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-ptype.exp | 288 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-whatis.c | 282 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/ctf-whatis.exp | 413 |
8 files changed, 2023 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0eeb8c6fbdf..0d42016edf8 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2019-10-07 Weimin Pan <weimin.pan@oracle.com> + + * gdb.base/ctf-whatis.exp: New file. + * gdb.base/ctf-whatis.c: New file. + * gdb.base/ctf-ptype.exp: New file. + * gdb.base/ctf-ptype.c: New file. + * gdb.base/ctf-constvars.exp: New file. + * gdb.base/ctf-constvars.c: New file. + * gdb.base/ctf-cvexpr.exp: New file. + 2019-10-04 Tom de Vries <tdevries@suse.de> * gdb.cp/local-static.c (main): Move declaration of int i out of the diff --git a/gdb/testsuite/gdb.base/ctf-constvars.c b/gdb/testsuite/gdb.base/ctf-constvars.c new file mode 100644 index 00000000000..75f4250d474 --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-constvars.c @@ -0,0 +1,116 @@ +/* This test program is part of GDB, the GNU debugger. + + 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/>. */ + +const char laconic = 'A'; +const char *const lewd=&laconic; + +/* volatile variables */ + +volatile char vox = 'B'; +volatile unsigned char victuals = 'C'; +volatile short vixen = 200; +volatile unsigned short vitriol = 300; +volatile long vellum = 1000; +volatile unsigned long valve = 2000; +volatile float vacuity = 3.0; +volatile double vertigo = 10; + +/* pointers to volatile variables */ + +volatile char * vampire = &vox; +volatile unsigned char * viper = &victuals; +volatile short * vigour = &vixen; +volatile unsigned short * vapour = &vitriol; +volatile long * ventricle = &vellum; +volatile unsigned long * vigintillion = &valve; +volatile float * vocation = &vacuity; +volatile double * veracity = &vertigo; + +/* volatile pointers to volatile variables */ + +volatile char * volatile vapidity = &vox; +volatile unsigned char * volatile velocity = &victuals; +volatile short * volatile veneer = &vixen; +volatile unsigned short * volatile video = &vitriol; +volatile long * volatile vacuum = &vellum; +volatile unsigned long * volatile veniality = &valve; +volatile float * volatile vitality = &vacuity; +volatile double * volatile voracity = &vertigo; + +/* volatile arrays */ + +volatile char violent[2]; +volatile unsigned char violet[2]; +volatile short vips[2]; +volatile unsigned short virgen[2]; +volatile long vulgar[2]; +volatile unsigned long vulture[2]; +volatile float vilify[2]; +volatile double villar[2]; + +/* const volatile vars */ + +const volatile char victor = 'Y'; + +/* pointers to const volatiles */ + +const volatile char * victory = &victor; + +/* const pointers to const volatile vars */ + +const volatile char * const cavern = &victor; + +/* volatile pointers to const vars */ + +const char * volatile caveat = &laconic; +const unsigned char * volatile covenant; + +/* volatile pointers to const volatile vars */ + +const volatile char * volatile vizier = &victor; +const volatile unsigned char * volatile vanadium; + +/* const volatile pointers */ + +char * const volatile vane; +unsigned char * const volatile veldt; + +/* const volatile pointers to const vars */ + +const char * const volatile cove; +const unsigned char * const volatile cavity; + +/* const volatile pointers to volatile vars */ + +volatile char * const volatile vagus; +volatile unsigned char * const volatile vagrancy; + +/* const volatile pointers to const volatile */ + +const volatile char * const volatile vagary; +const volatile unsigned char * const volatile vendor; + +/* const volatile arrays */ + +const volatile char vindictive[2]; +const volatile unsigned char vegetation[2]; + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/ctf-constvars.exp b/gdb/testsuite/gdb.base/ctf-constvars.exp new file mode 100644 index 00000000000..4a81a94ddb4 --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-constvars.exp @@ -0,0 +1,114 @@ +# 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 is a subset of constvars.exp, written by +# Elena Zannoni (elz@apollo.hp.com) +# +# This file is part of the gdb testsuite +# +# tests for const variables +# const pointers to vars +# pointers to const variables +# const pointers to const vars +# with mixed types + +# +# test running programs +# +# -gt generates full-fledged CTF. + +standard_testfile .c +set opts "additional_flags=-gt" + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile] [list $opts nowarnings]] } { + return 0 +} + +# +# set it up at a breakpoint so we can play with the variable values +# +if ![runto_main] then { + perror "couldn't run to breakpoint" + continue +} + +# test vars and pointers + +proc do_constvar_tests {} { + gdb_test "print vox" " = 66 'B'" + gdb_test "ptype vox" "type = volatile char" + gdb_test "print victuals" " = 67 'C'" + gdb_test "ptype victuals" "type = volatile unsigned char" + gdb_test "print vixen" " = 200" + gdb_test "ptype vixen" "type = volatile short.*" + gdb_test "print vitriol" " = 300" + gdb_test "ptype vitriol" "type = volatile (unsigned short|short unsigned)( int)?" + gdb_test "print vellum" " = 1000" + gdb_test "ptype vellum" "type = volatile long.*" + gdb_test "print valve" " = 2000" + gdb_test "ptype valve" "type = volatile (unsigned long|long unsigned)( int)?" + gdb_test "print vacuity" " = 3" + gdb_test "ptype vacuity" "type = volatile float" + gdb_test "print vertigo" " = 10" + gdb_test "ptype vertigo" "type = volatile double" + gdb_test "print laconic" " = 65 'A'" + + gdb_test "ptype vampire" "type = volatile char.*" + gdb_test "ptype viper" "type = volatile unsigned char.*" + gdb_test "ptype vigour" "type = volatile short.*" + gdb_test "ptype vapour" "type = volatile (unsigned short|short unsigned)( int)?.*" + gdb_test "ptype ventricle" "type = volatile long.*" + gdb_test "ptype vigintillion" "type = volatile (unsigned long|long unsigned)( int)?.*" + gdb_test "ptype vocation" "type = volatile float.*" + gdb_test "ptype veracity" "type = volatile double.*" + + gdb_test "ptype vapidity" "type = volatile char.* volatile" + gdb_test "ptype velocity" "type = volatile unsigned char.* volatile" + gdb_test "ptype veneer" "type = volatile short.* volatile" + gdb_test "ptype video" "type = volatile (unsigned short|short unsigned)( int)?.* volatile" + gdb_test "ptype vacuum" "type = volatile long.* volatile" + gdb_test "ptype veniality" "type = volatile (unsigned long|long unsigned)( int)?.* volatile" + gdb_test "ptype vitality" "type = volatile float.* volatile" + gdb_test "ptype voracity" "type = volatile double.* volatile" + + gdb_test "ptype violent" "type = volatile char \\\[2\\\]" + gdb_test "ptype violet" "type = volatile unsigned char \\\[2\\\]" + gdb_test "ptype vips" "type = volatile short.* \\\[2\\\]" + gdb_test "ptype virgen" "type = volatile unsigned short.* \\\[2\\\]" + gdb_test "ptype vulgar" "type = volatile long.* \\\[2\\\]" + gdb_test "ptype vulture" "type = volatile (unsigned long|long unsigned)( int)? \\\[2\\\]" + gdb_test "ptype vilify" "type = volatile float \\\[2\\\]" + gdb_test "ptype villar" "type = volatile double \\\[2\\\]" + + gdb_test "print victor" " = 89 'Y'" + gdb_test "ptype victor" "type = const volatile char" + gdb_test "ptype victory" "type = const volatile char.*" + gdb_test "ptype cavern" "type = const volatile char.* const" + gdb_test "ptype caveat" "type = const char.* volatile" + gdb_test "ptype covenant" "type = const unsigned char.* volatile" + gdb_test "ptype vanadium" "type = const volatile unsigned char.* volatile" + + gdb_test "ptype cove" "type = const char.* const volatile" + gdb_test "ptype cavity" "type = const unsigned char.* const volatile" + gdb_test "ptype vagus" "type = volatile char.* const volatile" + gdb_test "ptype vagrancy" "type = volatile unsigned char.* const volatile" + gdb_test "ptype vagary" "type = const volatile char.* const volatile" + gdb_test "ptype vendor" "type = const volatile unsigned char.* const volatile" + gdb_test "ptype vindictive" "type = const volatile char \\\[2\\\]" + gdb_test "ptype vegetation" "type = const volatile unsigned char \\\[2\\\]" +} + +do_constvar_tests diff --git a/gdb/testsuite/gdb.base/ctf-cvexpr.exp b/gdb/testsuite/gdb.base/ctf-cvexpr.exp new file mode 100644 index 00000000000..67ceb21f520 --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-cvexpr.exp @@ -0,0 +1,495 @@ +# Copyright (C) 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 is a subset of cvexpr.exp written by +# Michael Snyder, Red Hat, Inc., 9/20/2001 + +# This file is part of the gdb testsuite +# Tests for type expressions using const and volatile keywords. + +# +# test running programs +# +# -gt generates full-fledged CTF. + +standard_testfile cvexpr.c +set opts "additional_flags=-gt" + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "failed to compile" + return -1 +} + +clean_restart ${binfile} + +gdb_test_no_output "set print sevenbit-strings" +gdb_test_no_output "set print address off" +gdb_test_no_output "set width 0" + +set ws "\[ \t\]*" + +# +# Test casting a scalar to const +# + +gdb_test "whatis (const char) v_char" \ + "type = const char" \ + "(const char)" +gdb_test "whatis (const signed char) v_signed_char" \ + "type = const signed char" \ + "(const signed char)" +gdb_test "whatis (const unsigned char) v_unsigned_char" \ + "type = const (unsigned char|char)" \ + "(const unsigned char)" +gdb_test "whatis (const short) v_short" \ + "type = const (short|short int)" \ + "(const short)" +gdb_test "whatis (const signed short) v_signed_short" \ + "type = const (short|short int|signed short|signed short int)" \ + "(const signed short)" +gdb_test "whatis (const unsigned short) v_unsigned_short" \ + "type = const (unsigned short|short unsigned int)" \ + "(const unsigned short)" +gdb_test "whatis (const int) v_int" \ + "type = const int" \ + "(const int)" +gdb_test "whatis (const signed int) v_signed_int" \ + "type = const (signed int|int)" \ + "(const signed int)" +gdb_test "whatis (const unsigned int) v_unsigned_int" \ + "type = const unsigned int" \ + "(const unsigned int)" +gdb_test "whatis (const long) v_long" \ + "type = const (long|long int)" \ + "(const long)" +gdb_test "whatis (const signed long) v_signed_long" \ + "type = const (signed |)long( int|)" \ + "(const signed long)" +gdb_test "whatis (const unsigned long) v_unsigned_long" \ + "type = const (unsigned long|long unsigned int)" \ + "(const unsigned long)" +gdb_test "whatis (const long long) v_long_long" \ + "type = const long long( int|)" \ + "(const long long)" +gdb_test "whatis (const signed long long) v_signed_long_long" \ + "type = const (signed |)long long( int|)" \ + "(const signed long long)" +gdb_test "whatis (const unsigned long long) v_unsigned_long_long" \ + "type = const (unsigned long long|long long unsigned int)" \ + "(const unsigned long long)" +gdb_test "whatis (const float) v_float" \ + "type = const float" \ + "(const float)" +gdb_test "whatis (const double) v_double" \ + "type = const double" \ + "(const double)" + +# +# Test casting a scalar to volatile +# + +gdb_test "whatis (volatile char) v_char" \ + "type = volatile char" \ + "(volatile char)" +gdb_test "whatis (volatile signed char) v_signed_char" \ + "type = volatile signed char" \ + "(volatile signed char)" +gdb_test "whatis (volatile unsigned char) v_unsigned_char" \ + "type = volatile (unsigned char|char)" \ + "(volatile unsigned char)" +gdb_test "whatis (volatile short) v_short" \ + "type = volatile (short|short int)" \ + "(volatile short)" +gdb_test "whatis (volatile signed short) v_signed_short" \ + "type = volatile (short|short int|signed short|signed short int)" \ + "(volatile signed short)" +gdb_test "whatis (volatile unsigned short) v_unsigned_short" \ + "type = volatile (unsigned short|short unsigned int)" \ + "(volatile unsigned short)" +gdb_test "whatis (volatile int) v_int" \ + "type = volatile int" \ + "(volatile int)" +gdb_test "whatis (volatile signed int) v_signed_int" \ + "type = volatile (signed int|int)" \ + "(volatile signed int)" +gdb_test "whatis (volatile unsigned int) v_unsigned_int" \ + "type = volatile unsigned int" \ + "(volatile unsigned int)" +gdb_test "whatis (volatile long) v_long" \ + "type = volatile (long|long int)" \ + "(volatile long)" +gdb_test "whatis (volatile signed long) v_signed_long" \ + "type = volatile (signed |)long( int|)" \ + "(volatile signed long)" +gdb_test "whatis (volatile unsigned long) v_unsigned_long" \ + "type = volatile (unsigned long|long unsigned int)" \ + "(volatile unsigned long)" +gdb_test "whatis (volatile long long) v_long_long" \ + "type = volatile long long( int|)" \ + "(volatile long long)" +gdb_test "whatis (volatile signed long long) v_signed_long_long" \ + "type = volatile (signed |)long long( int|)" \ + "(volatile signed long long)" +gdb_test "whatis (volatile unsigned long long) v_unsigned_long_long" \ + "type = volatile (unsigned long long|long long unsigned int)" \ + "(volatile unsigned long long)" +gdb_test "whatis (volatile float) v_float" \ + "type = volatile float" \ + "(volatile float)" +gdb_test "whatis (volatile double) v_double" \ + "type = volatile double" \ + "(volatile double)" + +# +# Combine const and volatile +# + +gdb_test "whatis (const volatile int) v_int" \ + "type = const volatile int" \ + "(const volatile int)" +gdb_test "whatis (volatile const int) v_int" \ + "type = const volatile int" \ + "(volatile const int)" +gdb_test "whatis (const int volatile) v_int" \ + "type = const volatile int" \ + "(const int volatile)" +gdb_test "whatis (volatile int const) v_int" \ + "type = const volatile int" \ + "(volatile int const)" +gdb_test "whatis (int const volatile) v_int" \ + "type = const volatile int" \ + "(int const volatile)" +gdb_test "whatis (int volatile const) v_int" \ + "type = const volatile int" \ + "(int volatile const)" + +gdb_test "whatis (const volatile int *) v_int_pointer" \ + "type = const volatile int${ws}\\*" \ + "(const volatile int *)" +gdb_test "whatis (volatile const int *) v_int_pointer" \ + "type = const volatile int${ws}\\*" \ + "(volatile const int *)" +gdb_test "whatis (const int volatile *) v_int_pointer" \ + "type = const volatile int${ws}\\*" \ + "(const int volatile)" +gdb_test "whatis (volatile int const *) v_int_pointer" \ + "type = const volatile int${ws}\\*" \ + "(volatile int const *)" +gdb_test "whatis (int const volatile *) v_int_pointer" \ + "type = const volatile int${ws}\\*" \ + "(int const volatile *)" +gdb_test "whatis (int volatile const *) v_int_pointer" \ + "type = const volatile int${ws}\\*" \ + "(int volatile const *)" +gdb_test "whatis (int * const volatile) v_int_pointer" \ + "type = int${ws}\\*${ws}const volatile" \ + "(int * const volatile)" +gdb_test "whatis (int * volatile const) v_int_pointer" \ + "type = int${ws}\\*${ws}const volatile" \ + "(int * volatile const)" + + +# +# Put 'signed' and 'unsigned' before const/volatile (FIXME) +# + +#gdb_test "whatis (signed const char) v_signed_char" \ +# "type = const char" \ +# "(signed const char)" +#gdb_test "whatis (unsigned const char) v_unsigned_char" \ +# "type = const (unsigned char|char)" \ +# "(unsigned const char)" +#gdb_test "whatis (signed const short) v_signed_short" \ +# "type = const (short|short int|signed short|signed short int)" \ +# "(signed const short)" +#gdb_test "whatis (unsigned const short) v_unsigned_short" \ +# "type = const (unsigned short|short unsigned int)" \ +# "(unsigned const short)" +#gdb_test "whatis (signed const int) v_signed_int" \ +# "type = const (signed int|int)" \ +# "(signed const int)" +#gdb_test "whatis (unsigned const int) v_unsigned_int" \ +# "type = const unsigned int" \ +# "(unsigned const int)" +#gdb_test "whatis (signed const long) v_signed_long" \ +# "type = const (signed |)long( int|)" \ +# "(signed const long)" +#gdb_test "whatis (unsigned const long) v_unsigned_long" \ +# "type = const (unsigned long|long unsigned int)" \ +# "(unsigned const long)" +#gdb_test "whatis (signed const long long) v_signed_long_long" \ +# "type = const (signed |)long long( int|)" \ +# "(signed const long long)" +#gdb_test "whatis (unsigned const long long) v_unsigned_long_long" \ +# "type = const (unsigned long long|long long unsigned int)" \ +# "(const unsigned long long)" + +#gdb_test "whatis (signed volatile char) v_signed_char" \ +# "type = volatile char" \ +# "(signed volatile char)" +#gdb_test "whatis (unsigned volatile char) v_unsigned_char" \ +# "type = volatile (unsigned char|char)" \ +# "(unsigned volatile char)" +#gdb_test "whatis (signed volatile short) v_signed_short" \ +# "type = volatile (short|short int|signed short|signed short int)" \ +# "(signed volatile short)" +#gdb_test "whatis (unsigned volatile short) v_unsigned_short" \ +# "type = volatile (unsigned short|short unsigned int)" \ +# "(unsigned volatile short)" +#gdb_test "whatis (signed volatile int) v_signed_int" \ +# "type = volatile (signed int|int)" \ +# "(signed volatile int)" +#gdb_test "whatis (unsigned volatile int) v_unsigned_int" \ +# "type = volatile unsigned int" \ +# "(unsigned volatile int)" +#gdb_test "whatis (signed volatile long) v_signed_long" \ +# "type = volatile (signed |)long( int|)" \ +# "(signed volatile long)" +#gdb_test "whatis (unsigned volatile long) v_unsigned_long" \ +# "type = volatile (unsigned long|long unsigned int)" \ +# "(unsigned volatile long)" +#gdb_test "whatis (signed volatile long long) v_signed_long_long" \ +# "type = volatile (signed |)long long( int|)" \ +# "(signed volatile long long)" +#gdb_test "whatis (unsigned volatile long long) v_unsigned_long_long" \ +# "type = volatile (unsigned long long|long long unsigned int)" \ +# "(unsigned volatile long long)" + +# +# Now put the 'const' and 'volatile' keywords after the base type. +# + +gdb_test "whatis (char const) v_char" \ + "type = const char" \ + "(char const)" +gdb_test "whatis (signed char const) v_signed_char" \ + "type = const signed char" \ + "(signed char const)" +gdb_test "whatis (unsigned char const) v_unsigned_char" \ + "type = const (unsigned char|char)" \ + "(unsigned char const)" +gdb_test "whatis (short const) v_short" \ + "type = const (short|short int)" \ + "(short const)" +gdb_test "whatis (signed short const) v_signed_short" \ + "type = const (short|short int|signed short|signed short int)" \ + "(signed short const)" +gdb_test "whatis (unsigned short const) v_unsigned_short" \ + "type = const (unsigned short|short unsigned int)" \ + "(unsigned short const)" +gdb_test "whatis (int const) v_int" \ + "type = const int" \ + "(int const)" +gdb_test "whatis (signed int const) v_signed_int" \ + "type = const (signed int|int)" \ + "(signed int const)" +gdb_test "whatis (unsigned int const) v_unsigned_int" \ + "type = const unsigned int" \ + "(unsigned int const)" +gdb_test "whatis (long const) v_long" \ + "type = const (long|long int)" \ + "(long const)" +gdb_test "whatis (signed long const) v_signed_long" \ + "type = const (signed |)long( int|)" \ + "(signed long const)" +gdb_test "whatis (unsigned long const) v_unsigned_long" \ + "type = const (unsigned long|long unsigned int)" \ + "(unsigned long const)" +gdb_test "whatis (long long const) v_long_long" \ + "type = const long long( int|)" \ + "(long long const)" +gdb_test "whatis (signed long long const) v_signed_long_long" \ + "type = const (signed |)long long( int|)" \ + "(signed long long const)" +gdb_test "whatis (unsigned long long const) v_unsigned_long_long" \ + "type = const (unsigned long long|long long unsigned int)" \ + "(unsigned long long const)" +gdb_test "whatis (float const) v_float" \ + "type = const float" \ + "(float const)" +gdb_test "whatis (double const) v_double" \ + "type = const double" \ + "(double const)" + +gdb_test "whatis (char volatile) v_char" \ + "type = volatile char" \ + "(char volatile)" +gdb_test "whatis (signed char volatile) v_signed_char" \ + "type = volatile signed char" \ + "(signed char volatile)" +gdb_test "whatis (unsigned char volatile) v_unsigned_char" \ + "type = volatile (unsigned char|char)" \ + "(unsigned char volatile)" +gdb_test "whatis (short volatile) v_short" \ + "type = volatile (short|short int)" \ + "(short volatile)" +gdb_test "whatis (signed short volatile) v_signed_short" \ + "type = volatile (short|short int|signed short|signed short int)" \ + "(signed short volatile)" +gdb_test "whatis (unsigned short volatile) v_unsigned_short" \ + "type = volatile (unsigned short|short unsigned int)" \ + "(unsigned short volatile)" +gdb_test "whatis (int volatile) v_int" \ + "type = volatile int" \ + "(int volatile)" +gdb_test "whatis (signed int volatile) v_signed_int" \ + "type = volatile (signed int|int)" \ + "(signed int volatile)" +gdb_test "whatis (unsigned int volatile) v_unsigned_int" \ + "type = volatile unsigned int" \ + "(unsigned int volatile)" +gdb_test "whatis (long volatile) v_long" \ + "type = volatile (long|long int)" \ + "(long volatile)" +gdb_test "whatis (signed long volatile) v_signed_long" \ + "type = volatile (signed |)long( int|)" \ + "(signed long volatile)" +gdb_test "whatis (unsigned long volatile) v_unsigned_long" \ + "type = volatile (unsigned long|long unsigned int)" \ + "(unsigned long volatile)" +gdb_test "whatis (long long volatile) v_long_long" \ + "type = volatile long long( int|)" \ + "(long long volatile)" +gdb_test "whatis (signed long long volatile) v_signed_long_long" \ + "type = volatile (signed |)long long( int|)" \ + "(signed long long volatile)" +gdb_test "whatis (unsigned long long volatile) v_unsigned_long_long" \ + "type = volatile (unsigned long long|long long unsigned int)" \ + "(unsigned long long volatile)" +gdb_test "whatis (float volatile) v_float" \ + "type = volatile float" \ + "(float volatile)" +gdb_test "whatis (double volatile) v_double" \ + "type = volatile double" \ + "(double volatile)" + +# +# enums +# + +gdb_test "whatis (const enum misordered) v_misordered" \ + "type = const enum misordered" \ + "(const enum misordered)" +gdb_test "whatis (enum misordered const) v_misordered" \ + "type = const enum misordered" \ + "(enum misordered const)" +gdb_test "whatis (volatile enum misordered) v_misordered" \ + "type = volatile enum misordered" \ + "(volatile enum misordered)" +gdb_test "whatis (enum misordered volatile) v_misordered" \ + "type = volatile enum misordered" \ + "(enum misordered volatile)" + +# +# Pointers +# + +gdb_test "whatis (const int *) v_int_pointer" \ + "type = const int${ws}\\*" \ + "(const int *)" +gdb_test "whatis (int const *) v_int_pointer" \ + "type = const int${ws}\\*" \ + "(int const *)" +gdb_test "whatis (int * const) v_int_pointer" \ + "type = int \\*${ws}const" \ + "(int * const)" +gdb_test "whatis (const int * const) v_int_pointer" \ + "type = const int${ws}\\*${ws}const" \ + "(const int * const)" +gdb_test "whatis (int const * const) v_int_pointer" \ + "type = const int${ws}\\*${ws}const" \ + "(int const * const)" + +gdb_test "whatis (const int **) v_int_pointer_pointer" \ + "type = const int${ws}\\*${ws}\\*" \ + "(const int **)" +gdb_test "whatis (int const **) v_int_pointer_pointer" \ + "type = const int${ws}\\*${ws}\\*" \ + "(int const **)" +gdb_test "whatis (int ** const) v_int_pointer_pointer" \ + "type = int \\*${ws}\\*${ws}const" \ + "(int ** const)" +gdb_test "whatis (const int * const *) v_int_pointer_pointer" \ + "type = const int${ws}\\*${ws}const${ws}\\*" \ + "(const int * const *)" +gdb_test "whatis (int const * const *) v_int_pointer_pointer" \ + "type = const int${ws}\\*${ws}const${ws}\\*" \ + "(int const * const *)" +gdb_test "whatis (const int * const * const) v_int_pointer_pointer" \ + "type = const int${ws}\\*${ws}const${ws}\\*${ws}const" \ + "(const int * const * const)" +gdb_test "whatis (int const * const * const) v_int_pointer_pointer" \ + "type = const int${ws}\\*${ws}const${ws}\\*${ws}const" \ + "(int const * const * const)" + +# +# Arrays TODO +# + +# +# Pointers to arrays, arrays of pointers TODO +# + +# +# Structs and Unions +# + +gdb_test "whatis (const struct t_struct) v_struct1" \ + "type = const struct t_struct" \ + "(const struct t_struct)" +gdb_test "whatis (const union t_union) v_union" \ + "type = const union t_union" \ + "(const union t_union)" +gdb_test "whatis (struct t_struct const) v_struct1" \ + "type = const struct t_struct" \ + "(struct t_struct const)" +gdb_test "whatis (union t_union const) v_union" \ + "type = const union t_union" \ + "(union t_union const)" +gdb_test "whatis (const struct t_struct *) &v_struct1" \ + "type = const struct t_struct${ws}\\*" \ + "(const struct t_struct *)" +gdb_test "whatis (const union t_union *) &v_union" \ + "type = const union t_union${ws}\\*" \ + "(const union t_union *)" +gdb_test "whatis (struct t_struct const *) &v_struct1" \ + "type = const struct t_struct${ws}\\*" \ + "(struct t_struct const *)" +gdb_test "whatis (union t_union const *) &v_union" \ + "type = const union t_union${ws}\\*" \ + "(union t_union const *)" +gdb_test "whatis (struct t_struct * const) &v_struct1" \ + "type = struct t_struct${ws}\\*${ws}const" \ + "(struct t_struct * const)" +gdb_test "whatis (union t_union * const) &v_union" \ + "type = union t_union${ws}\\*${ws}const" \ + "(union t_union * const)" +gdb_test "whatis (const struct t_struct * const) &v_struct1" \ + "type = const struct t_struct${ws}\\*${ws}const" \ + "(const struct t_struct * const)" +gdb_test "whatis (const union t_union * const) &v_union" \ + "type = const union t_union${ws}\\*${ws}const" \ + "(const union t_union * const)" +gdb_test "whatis (struct t_struct const * const) &v_struct1" \ + "type = const struct t_struct${ws}\\*${ws}const" \ + "(struct t_struct const * const)" +gdb_test "whatis (union t_union const * const) &v_union" \ + "type = const union t_union${ws}\\*${ws}const" \ + "(union t_union const * const)" + +# +# Function pointers TODO +# + diff --git a/gdb/testsuite/gdb.base/ctf-ptype.c b/gdb/testsuite/gdb.base/ctf-ptype.c new file mode 100644 index 00000000000..2d2e881f0f5 --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-ptype.c @@ -0,0 +1,305 @@ +/* This test program is part of GDB, the GNU debugger. + + 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/>. */ + +/* + * Test file with lots of different types, for testing the + * "ptype" command on CTF data. It's devired from ptype.c. + */ + +/* + * First the basic C types. + */ + +#if !defined (__STDC__) && !defined (_AIX) +#define signed /**/ +#endif + +char v_char; +signed char v_signed_char; +unsigned char v_unsigned_char; + +short v_short; +signed short v_signed_short; +unsigned short v_unsigned_short; + +int v_int; +signed int v_signed_int; +unsigned int v_unsigned_int; + +long v_long; +signed long v_signed_long; +unsigned long v_unsigned_long; + +float v_float; +double v_double; + +/**** arrays *******/ + +char v_char_array[2]; +signed char v_signed_char_array[2]; +unsigned char v_unsigned_char_array[2]; + +short v_short_array[2]; +signed short v_signed_short_array[2]; +unsigned short v_unsigned_short_array[2]; + +int v_int_array[2]; +signed int v_signed_int_array[2]; +unsigned int v_unsigned_int_array[2]; + +long v_long_array[2]; +signed long v_signed_long_array[2]; +unsigned long v_unsigned_long_array[2]; + +float v_float_array[2]; +double v_double_array[2]; + +/* PR 3742 */ +typedef char t_char_array[]; +t_char_array *pv_char_array; + +/**** pointers *******/ + +char *v_char_pointer; +signed char *v_signed_char_pointer; +unsigned char *v_unsigned_char_pointer; + +short *v_short_pointer; +signed short *v_signed_short_pointer; +unsigned short *v_unsigned_short_pointer; + +int *v_int_pointer; +signed int *v_signed_int_pointer; +unsigned int *v_unsigned_int_pointer; + +long *v_long_pointer; +signed long *v_signed_long_pointer; +unsigned long *v_unsigned_long_pointer; + +float *v_float_pointer; +double *v_double_pointer; + +/**** structs *******/ + +struct t_struct { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; + float v_float_member; + double v_double_member; +} v_struct1; + +struct t_struct *v_t_struct_p; + +struct { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; + float v_float_member; + double v_double_member; +} v_struct2; + +/* typedef'd struct without a tag. */ +typedef struct { + double v_double_member; + int v_int_member; +} t_struct3; +/* GCC seems to want a variable of this type, or else it won't put out + a symbol. */ +t_struct3 v_struct3; + +/**** unions *******/ + +union t_union { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; + float v_float_member; + double v_double_member; +} v_union; + +union { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; + float v_float_member; + double v_double_member; +} v_union2; + +/* typedef'd union without a tag. */ +typedef union { + double v_double_member; + int v_int_member; +} t_union3; +/* GCC seems to want a variable of this type, or else it won't put out + a symbol. */ +t_union3 v_union3; + +/**** Some misc more complicated things *******/ + +struct outer_struct { + int outer_int; + struct inner_struct { + int inner_int; + long inner_long; + }inner_struct_instance; + union inner_union { + int inner_union_int; + long inner_union_long; + }inner_union_instance; + long outer_long; +} nested_su; + +struct highest +{ + int a; + struct + { + int b; + struct { int c; } anonymous_level_2; + } anonymous_level_1; +} the_highest; + +/**** Enumerations *******/ + +enum +/* Work around the bug for compilers which don't put out the right stabs. */ +#if __GNUC__ < 2 && !defined (_AIX) +primary1_tag +#endif +{red1, green1, blue1} primary1; + +enum {red, green, blue} primary; +enum colors {yellow, purple, pink} nonprimary; + +enum {chevy, ford} clunker; +enum cars {bmw, porsche} sportscar; + +#undef FALSE +#undef TRUE +typedef enum {FALSE, TRUE} boolean; +boolean v_boolean; +/*note: aCC has bool type predefined with 'false' and 'true'*/ +typedef enum bvals {my_false, my_true} boolean2; +boolean2 v_boolean2; + +enum misordered {two = 2, one = 1, zero = 0, three = 3}; + +/* Seems like we need a variable of this type to get the type to be put + in the executable, at least for AIX xlc. */ +enum misordered v_misordered = three; + +/**** Pointers to functions *******/ + +typedef int (*func_type) (int (*) (int, float), float); +double (*old_fptr) (); +double (*new_fptr) (void); +int (*fptr) (int, float); +int *(*fptr2) (int (*) (int, float), float); +int (*xptr) (int (*) (), int (*) (void), int); +int (*(*ffptr) (char)) (short); +int (*(*(*fffptr) (char)) (short)) (long); + +func_type v_func_type; + +int main () +{ + /* Ensure that malloc is a pointer type; avoid use of "void" and any include files. */ +/* extern char *malloc();*/ + + /* Some of the tests in ptype.exp require invoking malloc, so make + sure it is linked in to this program. */ + v_char_pointer = (char *) malloc (1); + + /* Some linkers (e.g. on AIX) remove unreferenced variables, + so make sure to reference them. */ + primary = blue; + primary1 = blue1; + nonprimary = pink; + sportscar = porsche; + clunker = ford; + v_struct1.v_int_member = 5; + v_struct2.v_int_member = 6; + v_struct3.v_int_member = 7; + + v_char = 0; + v_signed_char = 0; + v_unsigned_char = 0; + + v_short = 0; + v_signed_short = 0; + v_unsigned_short = 0; + + v_int = 0; + v_signed_int = 0; + v_unsigned_int = 0; + + v_long = 0; + v_signed_long = 0; + v_unsigned_long = 0; + + v_float = 0; + v_double = 0; + + v_char_array[0] = 0; + v_signed_char_array[0] = 0; + v_unsigned_char_array[0] = 0; + + v_short_array[0] = 0; + v_signed_short_array[0] = 0; + v_unsigned_short_array[0] = 0; + + v_int_array[0] = 0; + v_signed_int_array[0] = 0; + v_unsigned_int_array[0] = 0; + + v_long_array[0] = 0; + v_signed_long_array[0] = 0; + v_unsigned_long_array[0] = 0; + + v_float_array[0] = 0; + v_double_array[0] = 0; + + v_char_pointer = 0; + v_signed_char_pointer = 0; + v_unsigned_char_pointer = 0; + + v_short_pointer = 0; + v_signed_short_pointer = 0; + v_unsigned_short_pointer = 0; + + v_int_pointer = 0; + v_signed_int_pointer = 0; + v_unsigned_int_pointer = 0; + + v_long_pointer = 0; + v_signed_long_pointer = 0; + v_unsigned_long_pointer = 0; + + v_float_pointer = 0; + v_double_pointer = 0; + + nested_su.outer_int = 0; + v_t_struct_p = 0; + + the_highest.a = 0; + return 0; +} diff --git a/gdb/testsuite/gdb.base/ctf-ptype.exp b/gdb/testsuite/gdb.base/ctf-ptype.exp new file mode 100644 index 00000000000..9f545824224 --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-ptype.exp @@ -0,0 +1,288 @@ +# 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 is a subset of ptype.exp written by Rob Savoye. (rob@cygnus.com) + +# +# test running programs +# +# -gt generates full-fledged CTF. + +standard_testfile .c +set opts "additional_flags=-gt" + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile] [list $opts nowarnings]] } { + return 0 +} + +# Create and source the file that provides information about the compiler +# used to compile the test case. +if [get_compiler_info] { + return -1 +} + +# Test ptype of unnamed enumeration members before any action causes +# the partial symbol table to be expanded to full symbols. This fails +# with stabs compilers which fail to use a nameless stab (such as +# pre-2.4.5 versions of gcc and most non-gcc compilers). + +gdb_test_multiple "ptype red1" "ptype unnamed enumeration member" { + -re "type = enum primary1_tag \{red1, green1, blue1\}.*$gdb_prompt $" { + # The workaround is in effect. As this is a compiler, not GDB, + # bug, we'll make it a PASS but perhaps it should be an XFAIL. + pass "ptype unnamed enumeration member (worked around)" + } + -re "type = enum \{red1, green1, blue1\}.*$gdb_prompt $" { + pass "ptype unnamed enumeration member" + } +} + +# +# test ptype command with structures +# +# Here and elsewhere, we accept +# "long", "long int", or "int" for long variables (whatis.exp already +# has an XFAIL for "int" (Sun cc bug), so no need to fail it here). +gdb_test "ptype struct t_struct" "type = struct t_struct \{.*\[\r\n\] (unsigned |)char v_char_member;.*\[\r\n\] (short|short int) v_short_member;.*\[\r\n\] int v_int_member;.*\[\r\n\] (long|long int|int) v_long_member;.*\[\r\n\] float v_float_member;.*\[\r\n\] double v_double_member;.*\[\r\n\]\}.*" "ptype structure" + + +# Test the equivalence between '.' and '->' for struct member references. + +if [gdb_test "ptype v_t_struct_p.v_float_member" "type = float"]<0 then { + return -1 +} +if [gdb_test "ptype v_t_struct_p->v_float_member" "type = float"]<0 then { + return -1 +} +if [gdb_test "ptype v_t_struct_p.v_float_member" "type = float"]<0 then { + return -1 +} +if [gdb_test "ptype v_t_struct_p->v_float_member" "type = float"]<0 then { + return -1 +} + +# +# test ptype command with unions +# +gdb_test "ptype union t_union" "type = union t_union \{.*\[\r\n\] (unsigned |)char v_char_member;.*\[\r\n\] (short|short int) v_short_member;.*\[\r\n\] int v_int_member;.*\[\r\n\] (long|long int|int) v_long_member;.*\[\r\n\] float v_float_member;.*\[\r\n\] double v_double_member;.*\[\r\n\]\}.*" "ptype union" + +# +# test ptype command with enums +# + +gdb_test "ptype primary" "type = enum .red, green, blue.*" "ptype unnamed enumeration" + +gdb_test "ptype enum colors" "type = enum colors \{yellow, purple, pink\}.*" "ptype named enumeration" + + +# +# test ptype command with enums as typedef +# +gdb_test "ptype boolean" "type = enum (boolean |)\{FALSE, TRUE\}.*" "ptype unnamed typedef'd enumeration" + +gdb_test "list main" ".*" + +# Same thing with struct and union. +gdb_test "ptype t_struct3" "type = struct (t_struct3 |)\{.* + *double v_double_member;.* + *int v_int_member;.*\}" "printing typedef'd struct" + +gdb_test "ptype t_union3" "type = union (t_union3 |)\{.* + *double v_double_member;.* + *int v_int_member;.*\}" "printing typedef'd union" + +gdb_test "ptype enum bvals" "type = enum bvals \{my_false, my_true\}.*" "ptype named typedef'd enumf'd enum" + +# +# test ptype command with out-of-order enum values +# +gdb_test "ptype enum misordered" "type = enum misordered \{two = 2, one = 1, zero = 0, three = 3\}.*" "ptype misordered enumeration" + +# +# test ptype command with a named enum's value +# +gdb_test "ptype three" "type = enum misordered \{two = 2, one = 1, zero = 0, three = 3\}.*" "ptype named enumeration member" + +gdb_test "ptype red" "type = enum \{red, green, blue\}.*" "ptype unnamed enumeration member #2" + +# +# test ptype command with arrays +# +gdb_test "ptype v_char_array" "type = char .2..*" "ptype char array" + +gdb_test "ptype v_signed_char_array" "type = (|signed )char .2..*" "ptype signed char array" + +gdb_test "ptype v_unsigned_char_array" "type = unsigned char .2..*" "ptype unsigned char array" + +gdb_test "ptype v_int_array" "type = int .2..*" "ptype int array" + +gdb_test "ptype v_signed_int_array" "type = int .2..*" "ptype signed int array" + +gdb_test "ptype v_unsigned_int_array" "type = unsigned int .2..*" "ptype unsigned int array" + +gdb_test "ptype v_long_array" "type = (long|int|long int) .2..*" "ptype long array" + +gdb_test "ptype v_signed_long_array" "type = (long|int|long int) .2..*" "ptype signed long array" + +gdb_test "ptype v_unsigned_long_array" "type = unsigned long .2..*" "ptype unsigned long array" + +gdb_test "ptype v_float_array" "type = float .2..*" "ptype float array" + +gdb_test "ptype v_double_array" "type = double .2..*" "ptype double array" + +gdb_test "ptype pv_char_array" "type = (|unsigned )char \\(\\*\\)\\\[0?\\\]" + +# +# test ptype command with pointers +# +gdb_test "ptype v_char_pointer" "type = char \*.*" "ptype char pointer" + +gdb_test "ptype v_short_pointer" "type = short \*.*" "ptype short pointer" + +gdb_test "ptype v_long_pointer" "type = long \*.*" "ptype long pointer" + +gdb_test "ptype v_int_pointer" "type = int \*.*" "ptype int pointer" + +gdb_test "ptype v_signed_long_pointer" "type = long \*.*" "ptype signed long pointer" + +gdb_test "ptype v_unsigned_long_pointer" "type = unsigned long \*.*" "ptype unsigned long pointer" + +gdb_test "ptype v_float_pointer" "type = float \*.*" "ptype float pointer" + +gdb_test "ptype v_double_pointer" "type = double \*.*" "ptype double pointer" + +# +# test ptype command with basic C types +# +gdb_test "ptype v_short" "type = short(| int).*" "ptype short" + +gdb_test "ptype v_int" "type = int.*" "ptype int" + +# +# test ptype command with nested structure and union +# +gdb_test "ptype struct outer_struct" "type = struct outer_struct \{.*\[\r\n\]+\ +.*int outer_int;.*\[\r\n\]+\ +.*(struct|) inner_struct inner_struct_instance;.*\[\r\n\]+\ +.*(union|) inner_union inner_union_instance;.*\[\r\n\]+\ +.*(long|long int|int) outer_long;.*\[\r\n\]\}.*" "ptype outer structure" + +gdb_test "ptype struct inner_struct" "type = struct inner_struct \{.*\[\r\n\] int inner_int;.*\[\r\n\] (long|long int|int) inner_long;.*\[\r\n\]\}.*" "ptype inner structure" + +gdb_test "ptype union inner_union" "type = union inner_union \{.*\[\r\n\] int inner_union_int;.*\[\r\n\] (long|long int|int) inner_union_long;.*\[\r\n\]\}.*" "ptype inner union" + +gdb_test "ptype nested_su" "type = struct outer_struct \{.*\[\r\n\] int outer_int;.*\[\r\n\] (struct |)inner_struct inner_struct_instance;.*\[\r\n\] (union |)inner_union inner_union_instance;.*\[\r\n\] (long|long int|int) outer_long;.*\[\r\n\]\}.*" "ptype nested structure" + +gdb_test "ptype nested_su.outer_int" "type = int.*" "ptype outer int" + +gdb_test "ptype nested_su.inner_struct_instance" "type = struct inner_struct \{.*\[\r\n\] int inner_int;.*\[\r\n\] (long|long int|int) inner_long;.*\[\r\n\]\}.*" "ptype nested structure #2" + +gdb_test "ptype nested_su.inner_struct_instance.inner_int" "type = int.*" "ptype inner int" + +gdb_test "ptype nested_su.inner_union_instance" "type = union inner_union \{.*\[\r\n\] int inner_union_int;.*\[\r\n\] (long|long int|int) inner_union_long;.*\[\r\n\]\}.*" "ptype nested union" + +# Print the type description of variable the_highest, and verify that +# the type description for the fields whose type is anonymous are +# correctly printed (at nesting level 1 and 2). + +gdb_test "ptype the_highest" \ + "type = struct highest \{.*\[\r\n\] *int a;.*\[\r\n\] *struct \{.*\[\r\n\] *int b;.*\[\r\n\] *struct \{\.\.\.\} anonymous_level_2;.*\[\r\n\] *\} anonymous_level_1;.*\[\r\n\]}.*" \ + "ptype the_highest" + +# Print the type descrption for one of the fields of variable the_highest. +# The purpose is to verify that the type of a field that was printed above +# as "struct {...}" is now printed in a more descriptive way (because the +# nesting level is now one level less). + +gdb_test "ptype the_highest.anonymous_level_1" \ + "type = struct \{.*\[\r\n\] *int b;.*\[\r\n\] *struct \{.*\[\r\n\] *int c;.*\[\r\n\] *\} anonymous_level_2;.*\[\r\n\]}.*" \ + "ptype the_highest" + +# Print the type of the identifier ID, and check the response: +# - Expect to see PROTOTYPED as the type. PROTOTYPED is not a regular +# expression; it's a literal string. +# - If we instead see the unprototyped type PLAIN, and we're using STABS +# generated by GCC, that's an xfail; as of 9 Feb 2002, GCC never emits +# prototyped function types in STABS. Like PROTOTYPED, PLAIN is a +# literal string, not a regular expression. +# - If we see OVERPROTOTYPED, it's an xfail for RealView; RealView +# does not distinguish prototyped and unprototyped functions, and +# GDB defaults to prototyped. +# - Otherwise, it's a failure. +proc ptype_maybe_prototyped { id prototyped plain { overprototyped "NO-MATCH" } } { + global gdb_prompt + global gcc_compiled + + # Turn the arguments, which are literal strings, into + # regular expressions by quoting any special characters they contain. + foreach var { prototyped plain overprototyped } { + eval "set val \$$var" + regsub -all "\[\]\[*()\]" $val "\\\\&" val + regsub -all "short int" $val "short( int)?" val + regsub -all "long int" $val "long( int)?" val + eval "set $var \$val" + } + + gdb_test_multiple "ptype $id" "ptype $id" { + -re "type = $prototyped\[\r\n\]+$gdb_prompt $" { + pass "ptype $id" + } + -re "type = $plain\[\r\n\]+$gdb_prompt $" { + if {$gcc_compiled} { setup_xfail_format "stabs" } + fail "ptype $id (compiler doesn't emit prototyped types)" + } + -re "type = $overprototyped\[\r\n\]+$gdb_prompt $" { + if { [test_compiler_info "armcc-*"] } { + setup_xfail "*-*-*" + } + fail "ptype $id (compiler doesn't emit unprototyped types)" + } + } +} + +ptype_maybe_prototyped "old_fptr" "double (*)()" "double (*)()" \ + "double (*)(void)" + +# Test printing type of string constants and array constants, but +# requires a running process. These call malloc, and can take a long +# time to execute over a slow serial link, so increase the timeout. + +if [runto_main] then { + + if [target_info exists gdb,cannot_call_functions] { + unsupported "this target can not call functions" + continue + } + + # We need to up this because this can be really slow on some boards. + # (malloc() is called as part of the test). + set prev_timeout $timeout + set timeout 60 + + gdb_test "ptype \"abc\"" "type = char \\\[4\\\]" + gdb_test "ptype {'a','b','c'}" "type = char \\\[3\\\]" + gdb_test "ptype {0,1,2}" "type = int \\\[3\\\]" + gdb_test "ptype {(long)0,(long)1,(long)2}" "type = long \\\[3\\\]" + gdb_test "ptype {(float)0,(float)1,(float)2}" "type = float \\\[3\\\]" + gdb_test "ptype {{0,1,2},{3,4,5}}" "type = int \\\[2\\\]\\\[3\\\]" + gdb_test "ptype {4,5,6}\[2\]" "type = int" + gdb_test "ptype *&{4,5,6}\[1\]" "Attempt to take address of value not located in memory." + + set timeout $prev_timeout + + # Test ptype of user register + gdb_test "ptype \$pc" "void \\(\\*\\)\\(\\)" "ptype \$pc" +} diff --git a/gdb/testsuite/gdb.base/ctf-whatis.c b/gdb/testsuite/gdb.base/ctf-whatis.c new file mode 100644 index 00000000000..548dcbb7afd --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-whatis.c @@ -0,0 +1,282 @@ +/* This test program is part of GDB, the GNU debugger. + + 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/>. */ + +/* + * Test file with lots of different types, for testing the + * "whatis" command on CTF data. It's derived from whatis.c. + */ + +/* + * First the basic C types. + */ + +char v_char; +signed char v_signed_char; +unsigned char v_unsigned_char; + +short v_short; +signed short v_signed_short; +unsigned short v_unsigned_short; + +int v_int; +signed int v_signed_int; +unsigned int v_unsigned_int; + +long v_long; +signed long v_signed_long; +unsigned long v_unsigned_long; + +#ifndef NO_LONG_LONG +long long v_long_long; +signed long long v_signed_long_long; +unsigned long long v_unsigned_long_long; +#endif + +float v_float; +double v_double; + +/* + * Now some derived types, which are arrays, functions-returning, + * pointers, structures, unions, and enumerations. + */ + +/**** arrays *******/ + +char v_char_array[2]; +signed char v_signed_char_array[2]; +unsigned char v_unsigned_char_array[2]; + +short v_short_array[2]; +signed short v_signed_short_array[2]; +unsigned short v_unsigned_short_array[2]; + +int v_int_array[2]; +signed int v_signed_int_array[2]; +unsigned int v_unsigned_int_array[2]; + +long v_long_array[2]; +signed long v_signed_long_array[2]; +unsigned long v_unsigned_long_array[2]; + +#ifndef NO_LONG_LONG +long long v_long_long_array[2]; +signed long long v_signed_long_long_array[2]; +unsigned long long v_unsigned_long_long_array[2]; +#endif + +float v_float_array[2]; +double v_double_array[2]; + +/**** pointers *******/ + +/* Make sure they still print as pointer to foo even there is a typedef + for that type. Test this not just for char *, which might be + a special case kludge in GDB (Unix system include files like to define + caddr_t), but for a variety of types. */ +typedef char *char_addr; +char_addr a_char_addr; +typedef unsigned short *ushort_addr; +ushort_addr a_ushort_addr; +typedef signed long *slong_addr; +slong_addr a_slong_addr; +#ifndef NO_LONG_LONG +typedef signed long long *slong_long_addr; +slong_long_addr a_slong_long_addr; +#endif + +char *v_char_pointer; +signed char *v_signed_char_pointer; +unsigned char *v_unsigned_char_pointer; + +short *v_short_pointer; +signed short *v_signed_short_pointer; +unsigned short *v_unsigned_short_pointer; + +int *v_int_pointer; +signed int *v_signed_int_pointer; +unsigned int *v_unsigned_int_pointer; + +long *v_long_pointer; +signed long *v_signed_long_pointer; +unsigned long *v_unsigned_long_pointer; + +#ifndef NO_LONG_LONG +long long *v_long_long_pointer; +signed long long *v_signed_long_long_pointer; +unsigned long long *v_unsigned_long_long_pointer; +#endif + +float *v_float_pointer; +double *v_double_pointer; + +/**** structs *******/ + +struct t_struct { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; +#ifndef NO_LONG_LONG + long long v_long_long_member; +#endif + float v_float_member; + double v_double_member; +} v_struct1, *v_struct_ptr1; + +struct { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; +#ifndef NO_LONG_LONG + long long v_long_long_member; +#endif + float v_float_member; + double v_double_member; +} v_struct2, *v_struct_ptr2; + +/**** unions *******/ + +union t_union { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; +#ifndef NO_LONG_LONG + long long v_long_long_member; +#endif + float v_float_member; + double v_double_member; +} v_union, *v_union_ptr; + +union { + char v_char_member; + short v_short_member; + int v_int_member; + long v_long_member; +#ifndef NO_LONG_LONG + long long v_long_long_member; +#endif + float v_float_member; + double v_double_member; +} v_union2, *v_union_ptr2; + +/**** Some misc more complicated things *******/ + +struct outer_struct { + int outer_int; + struct inner_struct { + int inner_int; + long inner_long; + }inner_struct_instance; + union inner_union { + int inner_union_int; + long inner_union_long; + }inner_union_instance; + long outer_long; +} nested_su; + +/***********/ + +int main () +{ + /* Some linkers (e.g. on AIX) remove unreferenced variables, + so make sure to reference them. */ + v_char = 0; + v_signed_char = 1; + v_unsigned_char = 2; + + v_short = 3; + v_signed_short = 4; + v_unsigned_short = 5; + + v_int = 6; + v_signed_int = 7; + v_unsigned_int = 8; + + v_long = 9; + v_signed_long = 10; + v_unsigned_long = 11; + +#ifndef NO_LONG_LONG + v_long_long = 12; + v_signed_long_long = 13; + v_unsigned_long_long = 14; +#endif + + v_float = 100.0; + v_double = 200.0; + + + v_char_array[0] = v_char; + v_signed_char_array[0] = v_signed_char; + v_unsigned_char_array[0] = v_unsigned_char; + + v_short_array[0] = v_short; + v_signed_short_array[0] = v_signed_short; + v_unsigned_short_array[0] = v_unsigned_short; + + v_int_array[0] = v_int; + v_signed_int_array[0] = v_signed_int; + v_unsigned_int_array[0] = v_unsigned_int; + + v_long_array[0] = v_long; + v_signed_long_array[0] = v_signed_long; + v_unsigned_long_array[0] = v_unsigned_long; + +#ifndef NO_LONG_LONG + v_long_long_array[0] = v_long_long; + v_signed_long_long_array[0] = v_signed_long_long; + v_unsigned_long_long_array[0] = v_unsigned_long_long; +#endif + + v_float_array[0] = v_float; + v_double_array[0] = v_double; + + v_char_pointer = &v_char; + v_signed_char_pointer = &v_signed_char; + v_unsigned_char_pointer = &v_unsigned_char; + + v_short_pointer = &v_short; + v_signed_short_pointer = &v_signed_short; + v_unsigned_short_pointer = &v_unsigned_short; + + v_int_pointer = &v_int; + v_signed_int_pointer = &v_signed_int; + v_unsigned_int_pointer = &v_unsigned_int; + + v_long_pointer = &v_long; + v_signed_long_pointer = &v_signed_long; + v_unsigned_long_pointer = &v_unsigned_long; + +#ifndef NO_LONG_LONG + v_long_long_pointer = &v_long_long; + v_signed_long_long_pointer = &v_signed_long_long; + v_unsigned_long_long_pointer = &v_unsigned_long_long; +#endif + + v_float_pointer = &v_float; + v_double_pointer = &v_double; + + v_union2.v_short_member = v_union.v_short_member; + + v_struct1.v_char_member = 0; + v_struct2.v_char_member = 0; + + nested_su.outer_int = 0; + return 0; +} diff --git a/gdb/testsuite/gdb.base/ctf-whatis.exp b/gdb/testsuite/gdb.base/ctf-whatis.exp new file mode 100644 index 00000000000..3f26fc326e3 --- /dev/null +++ b/gdb/testsuite/gdb.base/ctf-whatis.exp @@ -0,0 +1,413 @@ +# 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 is a subset of whatis.exp written by Rob Savoye. (rob@cygnus.com) + +# +# test running programs +# +# -gt generates full-fledged CTF. + +standard_testfile .c +set opts "additional_flags=-gt" + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile] [list $opts nowarnings]] } { + return 0 +} + +# Create and source the file that provides information about the compiler +# used to compile the test case. +if [get_compiler_info] { + return -1 +} + +# Start with a fresh gdb. + +clean_restart $binfile + +# Define a procedure to set up an xfail for all targets that put out a +# `long' type as an `int' type. +# Sun cc has this problem. +# It was said that COFF targets can not distinguish int from long either. + +proc setup_xfail_on_long_vs_int {} { + global gcc_compiled + + if {!$gcc_compiled} { + setup_xfail "*-sun-sunos4*" "i*86-sequent-bsd*" + } +} + +# +# Test whatis command with basic C types +# +# The name printed now (as of 23 May 1993) is whatever name the compiler +# uses in the stabs. So we need to deal with names both from gcc and +# native compilers. +# + +gdb_test "whatis v_char" \ + "type = (unsigned char|char)" \ + "whatis char" + +gdb_test "whatis v_signed_char" \ + "type = (signed char|char)" \ + "whatis signed char" + +gdb_test "whatis v_unsigned_char" \ + "type = unsigned char" \ + "whatis unsigned char" + +gdb_test "whatis v_short" \ + "type = (short|short int)" \ + "whatis short" + +gdb_test "whatis v_signed_short" \ + "type = (short|short int|signed short|signed short int)" \ + "whatis signed short" + +gdb_test "whatis v_unsigned_short" \ + "type = (unsigned short|short unsigned int)" \ + "whatis unsigned short" + +gdb_test "whatis v_int" \ + "type = int" \ + "whatis int" + +gdb_test "whatis v_signed_int" \ + "type = (signed |)int" \ + "whatis signed int" + +gdb_test "whatis v_unsigned_int" \ + "type = unsigned int" \ + "whatis unsigned int" + +setup_xfail_on_long_vs_int +# AIX xlc gets this wrong and unsigned long right. Go figure. +if {!$gcc_compiled} then {setup_xfail "rs6000-*-aix*"} +gdb_test "whatis v_long" \ + "type = (long|long int)" \ + "whatis long" + +setup_xfail_on_long_vs_int +# AIX xlc gets this wrong and unsigned long right. Go figure. +if {!$gcc_compiled} then {setup_xfail "rs6000-*-aix*"} +gdb_test "whatis v_signed_long" \ + "type = (signed |)(long|long int)" \ + "whatis signed long" + +setup_xfail_on_long_vs_int +gdb_test "whatis v_unsigned_long" \ + "type = (unsigned long|long unsigned int)" \ + "whatis unsigned long" + + +if ![target_info exists no_long_long] { + gdb_test "whatis v_unsigned_long_long" \ + "type = (unsigned long long|long long unsigned int)" \ + "whatis unsigned long long" +} + +gdb_test "whatis v_float" \ + "type = float" \ + "whatis float" + +gdb_test "whatis v_double" \ + "type = double" \ + "whatis double" + + +# test whatis command with arrays +# +# We already tested whether char prints as "char", so here we accept +# "unsigned char", "signed char", and other perversions. No need for more +# than one xfail for the same thing. +gdb_test "whatis v_char_array" \ + "type = (signed |unsigned |)char \\\[2\\\]" \ + "whatis char array" + +gdb_test "whatis v_signed_char_array" \ + "type = (signed |unsigned |)char \\\[2\\\]" \ + "whatis signed char array" + +gdb_test "whatis v_unsigned_char_array" \ + "type = unsigned char \\\[2\\\]" \ + "whatis unsigned char array" + +gdb_test "whatis v_short_array" \ + "type = (short|short int) \\\[2\\\]" \ + "whatis short array" + +gdb_test "whatis v_signed_short_array" \ + "type = (signed |)(short|short int) \\\[2\\\]" \ + "whatis signed short array" + +gdb_test "whatis v_unsigned_short_array" \ + "type = (unsigned short|short unsigned int) \\\[2\\\]" \ + "whatis unsigned short array" + +gdb_test "whatis v_int_array" \ + "type = int \\\[2\\\]" \ + "whatis int array" + +gdb_test "whatis v_signed_int_array" \ + "type = (signed |)int \\\[2\\\]" \ + "whatis signed int array" + +gdb_test "whatis v_unsigned_int_array" \ + "type = unsigned int \\\[2\\\]" \ + "whatis unsigned int array" + +# We already tested whether long prints as long, so here we accept int +# No need for more than one xfail for the same thing. +gdb_test "whatis v_long_array" \ + "type = (int|long|long int) \\\[2\\\]" \ + "whatis long array" + +gdb_test "whatis v_signed_long_array" \ + "type = (signed |)(int|long|long int) \\\[2\\\]" \ + "whatis signed long array" + +gdb_test "whatis v_unsigned_long_array" \ + "type = (unsigned (int|long|long int)|long unsigned int) \\\[2\\\]" \ + "whatis unsigned long array" + +if ![target_info exists no_long_long] { + gdb_test "whatis v_unsigned_long_long_array" \ + "type = (unsigned long long|long long unsigned int) \\\[2\\\]" \ + "whatis unsigned long array" +} + +gdb_test "whatis v_float_array" \ + "type = float \\\[2\\\]" \ + "whatis float array" + +gdb_test "whatis v_double_array" \ + "type = double \\\[2\\\]" \ + "whatis double array" + + +# test whatis command with pointers +# +# We already tested whether char prints as char, so accept various perversions +# here. We especially want to make sure we test that it doesn't print as +# caddr_t. +gdb_test "whatis v_char_pointer" \ + "type = (unsigned |signed |)char \\*" \ + "whatis char pointer" + +gdb_test "whatis v_signed_char_pointer" \ + "type = (unsigned |signed |)char \\*" \ + "whatis signed char pointer" + +gdb_test "whatis v_unsigned_char_pointer" \ + "type = unsigned char \\*" \ + "whatis unsigned char pointer" + +gdb_test "whatis v_short_pointer" \ + "type = (short|short int) \\*" \ + "whatis short pointer" + +gdb_test "whatis v_signed_short_pointer" \ + "type = (signed |)(short|short int) \\*" \ + "whatis signed short pointer" + +gdb_test "whatis v_unsigned_short_pointer" \ + "type = (unsigned short|short unsigned int) \\*" \ + "whatis unsigned short pointer" + +gdb_test "whatis v_int_pointer" \ + "type = int \\*" \ + "whatis int pointer" + +gdb_test "whatis v_signed_int_pointer" \ + "type = (signed |)int \\*" \ + "whatis signed int pointer" + +gdb_test "whatis v_unsigned_int_pointer" \ + "type = unsigned int \\*" \ + "whatis unsigned int pointer" + +# We already tested whether long prints as long, so here we accept int +gdb_test "whatis v_long_pointer" \ + "type = (long|int|long int) \\*" \ + "whatis long pointer" + +gdb_test "whatis v_signed_long_pointer" \ + "type = (signed |)(long|int|long int) \\*" \ + "whatis signed long pointer" + +gdb_test "whatis v_unsigned_long_pointer" \ + "type = (unsigned (int|long|long int)|long unsigned int) \\*" \ + "whatis unsigned long pointer" + +if ![target_info exists no_long_long] { + gdb_test "whatis v_long_long_pointer" \ + "type = long long(| int) \\*" \ + "whatis long long pointer" + + gdb_test "whatis v_signed_long_long_pointer" \ + "type = (signed |)long long(| int) \\*" \ + "whatis signed long long pointer" + + gdb_test "whatis v_unsigned_long_long_pointer" \ + "type = (unsigned long long|long long unsigned int) \\*" \ + "whatis unsigned long long pointer" +} + +gdb_test "whatis v_float_pointer" \ + "type = float \\*" \ + "whatis float pointer" + +gdb_test "whatis v_double_pointer" \ + "type = double \\*" \ + "whatis double pointer" + + +# test whatis command with structure types + +# First with a type argument, with both "set print object" set to "on" +# and "off", ending with "off" for the following tests. +foreach_with_prefix print_object {"on" "off"} { + gdb_test_no_output "set print object $print_object" + + gdb_test "whatis struct t_struct" \ + "type = struct t_struct" \ + "whatis named structure using type name" + + gdb_test "whatis struct t_struct *" \ + "type = struct t_struct \\*" \ + "whatis named structure using type name and pointer" + + gdb_test "whatis struct t_struct &" \ + "type = struct t_struct &" \ + "whatis named structure using type name and reference" +} + +# Now with an expression argument. + +gdb_test "whatis v_struct_ptr1" \ + "type = struct t_struct \\*" + +gdb_test "whatis &v_struct_ptr1" \ + "type = struct t_struct \\*\\*" + +gdb_test "whatis v_struct_ptr1->v_char_member" \ + "type = char" + +gdb_test "whatis v_struct_ptr2->v_char_member" \ + "type = char" + +gdb_test "whatis &(v_struct_ptr1->v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_struct_ptr2->v_char_member)" \ + "type = char \\*" + +# test whatis command with union types + +gdb_test "whatis union t_union" \ + "type = union t_union" \ + "whatis named union using type name" + +gdb_test "whatis v_union_ptr" \ + "type = union t_union \\*" + +gdb_test "whatis &v_union_ptr" \ + "type = union t_union \\*\\*" + +gdb_test "whatis v_union_ptr->v_char_member" \ + "type = char" + +gdb_test "whatis v_union_ptr2->v_char_member" \ + "type = char" + +gdb_test "whatis &(v_union_ptr->v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_union_ptr2->v_char_member)" \ + "type = char \\*" + +# test whatis command with nested struct and union +gdb_test "whatis nested_su" \ + "type = struct outer_struct" \ + "whatis outer structure" + +gdb_test "whatis nested_su.outer_int" \ + "type = int" \ + "whatis outer structure member" + +gdb_test "whatis nested_su.inner_struct_instance" \ + "type = struct inner_struct" \ + "whatis inner structure" + +gdb_test "whatis nested_su.inner_struct_instance.inner_int" \ + "type = int" \ + "whatis inner structure member" + +gdb_test "whatis nested_su.inner_union_instance" \ + "type = union inner_union" \ + "whatis inner union" + +gdb_test "whatis nested_su.inner_union_instance.inner_union_int" \ + "type = int" \ + "whatis inner union member" + +# Using stabs we will mark these functions as prototyped. This +# is harmless but causes an extra VOID to be printed. +set void "(void|)" + +# Regression tests for PR 9514. + +gdb_test "whatis void (**)()" \ + "type = void \\(\\*\\*\\)\\(\\)" \ + "whatis applied to pointer to pointer to function" + +gdb_test "whatis void (** const)()" \ + "type = void \\(\\*\\* const\\)\\(\\)" \ + "whatis applied to const pointer to pointer to function" + +gdb_test "whatis void (* const *)()" \ + "type = void \\(\\* const \\*\\)\\(\\)" \ + "whatis applied to pointer to const pointer to function" + +gdb_test "whatis int *(*)()" \ + "type = int \\*\\(\\*\\)\\(\\)" \ + "whatis applied to pointer to function returning pointer to int" + +gdb_test "whatis int *(**)()" \ + "type = int \\*\\(\\*\\*\\)\\(\\)" \ + "whatis applied to pointer to pointer to function returning pointer to int" + +gdb_test "whatis char (*(*)())\[23\]" \ + "type = char \\(\\*\\(\\*\\)\\(\\)\\)\\\[23\\\]" \ + "whatis applied to pointer to function returning pointer to array" + +gdb_test "whatis int (*)(int, int)" \ + "type = int \\(\\*\\)\\(int, int\\)" \ + "whatis applied to pointer to function taking int,int and returning int" + +gdb_test "whatis int (*)(const int *, ...)" \ + "type = int \\(\\*\\)\\(const int \\*, \\.\\.\\.\\)" \ + "whatis applied to pointer to function taking const int ptr and varargs and returning int" + +gdb_test "whatis int (*)(void, int, int)" \ + "parameter types following 'void'" \ + "whatis applied to function with types trailing 'void'" + +gdb_test "whatis int (*)(int, void, int)" \ + "'void' invalid as parameter type" \ + "whatis applied to function with 'void' parameter type" |