# Copyright 2021 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/>.

if [skip_ctf_tests] {
    unsupported "no CTF debug format support, or CTF disabled in GDB"
    return 0
}

if [target_info exists no_long_long] {
    set exec_opts [list debug additional_flags=-DNO_LONG_LONG]
} else {
    set exec_opts [list debug]
}

standard_testfile whatis.c

# Using `-gctf` generates full-fledged CTF debug information.
set opts "additional_flags=-gctf -Wl,--export-dynamic"

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 print command with functions return type
set void "(void|)"
gdb_test "print v_char_func" \
    "$decimal = \{char \\(\\)\} 0x\[0-9a-z\]+ <v_char_func>.*" \
    "print char function"

gdb_test "print v_signed_char_func" \
    "$decimal = \{signed char \\(\\)\} 0x\[0-9a-z\]+ <v_signed_char_func>.*" \
    "print signed char function"

gdb_test "print v_unsigned_char_func" \
    "$decimal = \{unsigned char \\(\\)\} 0x\[0-9a-z\]+ <v_unsigned_char_func>.*" \
    "print unsigned char function"

gdb_test "print v_short_func" \
    "$decimal = \{short \\(\\)\} 0x\[0-9a-z\]+ <v_short_func>.*" \
    "print short function"

gdb_test "print v_signed_short_func" \
    "$decimal = \{signed short|short \\(\\)\} 0x\[0-9a-z\]+ <v_signed_short_func>.*" \
    "print signed short function"

gdb_test "print v_unsigned_short_func" \
    "$decimal = \{unsigned short \\(\\)\} 0x\[0-9a-z\]+ <v_unsigned_short_func>.*" \
    "print unsigned short function"

gdb_test "print v_int_func" \
    "$decimal = \{int \\(\\)\} 0x\[0-9a-z\]+ <v_int_func>.*" \
    "print int function"

gdb_test "print v_signed_int_func" \
    "$decimal = \{signed int|int \\(\\)\} 0x\[0-9a-z\]+ <v_signed_int_func>.*" \
    "print signed int function"

gdb_test "print v_unsigned_int_func" \
    "$decimal = \{unsigned int \\(\\)\} 0x\[0-9a-z\]+ <v_unsigned_int_func>.*" \
    "print unsigned int function"

gdb_test "print v_long_func" \
    "$decimal = \{long \\(\\)\} 0x\[0-9a-z\]+ <v_long_func>.*" \
    "print long function"

gdb_test "print v_signed_long_func" \
    "$decimal = \{signed long|long \\(\\)\} 0x\[0-9a-z\]+ <v_signed_long_func>.*" \
    "print signed long function"

gdb_test "print v_unsigned_long_func" \
    "$decimal = \{unsigned long|long \\(\\)\} 0x\[0-9a-z\]+ <v_unsigned_long_func>.*" \
    "print unsigned long function"

if ![target_info exists no_long_long] {
    gdb_test "print v_long_long_func" \
	    "$decimal = \{long long \\(\\)\} 0x\[0-9a-z\]+ <v_long_long_func>.*" \
		"print long long function"

    gdb_test "print v_signed_long_long_func" \
	    "$decimal = \{long long \\(\\)\} 0x\[0-9a-z\]+ <v_signed_long_long_func>.*" \
		"print signed long long function"

    gdb_test "print v_unsigned_long_long_func" \
	    "$decimal = \{unsigned long long \\(\\)\} 0x\[0-9a-z\]+ <v_unsigned_long_long_func>.*" \
		"print unsigned long long function"
}

# Sun /bin/cc calls this a function returning double.
if {!$gcc_compiled} then {setup_xfail "*-sun-sunos4*"}
	gdb_test "print v_float_func" \
	    "$decimal = \{float \\(\\)\} 0x\[0-9a-z\]+.*" \
	    "print float function"

	gdb_test "print v_double_func" \
	    "$decimal = \{double \\(\\)\} 0x\[0-9a-z\]+.*" \
	    "print double function" \
}

# test whatis command with functions return type
gdb_test "whatis v_char_func" \
    "type = (signed |unsigned |)char \\($void\\)" \
    "whatis char function"

gdb_test "whatis v_signed_char_func" \
    "type = (signed |unsigned |)char \\($void\\)" \
    "whatis signed char function"

gdb_test "whatis v_unsigned_char_func" \
    "type = unsigned char \\($void\\)"	\
    "whatis unsigned char function"

gdb_test "whatis v_short_func" \
    "type = short (int |)\\($void\\)" \
    "whatis short function"

gdb_test "whatis v_signed_short_func" \
    "type = (signed |)short (int |)\\($void\\)" \
    "whatis signed short function"

gdb_test "whatis v_unsigned_short_func" \
    "type = (unsigned short|short unsigned int) \\($void\\)" \
    "whatis unsigned short function"

gdb_test "whatis v_int_func" \
    "type = int \\($void\\)" \
    "whatis int function"

gdb_test "whatis v_signed_int_func" \
    "type = (signed |)int \\($void\\)" \
    "whatis signed int function"

gdb_test "whatis v_unsigned_int_func" \
    "type = unsigned int \\($void\\)" \
    "whatis unsigned int function"

gdb_test "whatis v_long_func" \
    "type = (long|int|long int) \\($void\\)" \
    "whatis long function"

gdb_test "whatis v_signed_long_func" \
    "type = (signed |)(int|long|long int) \\($void\\)" \
    "whatis signed long function"

gdb_test "whatis v_unsigned_long_func" \
    "type = (unsigned (int|long|long int)|long unsigned int) \\($void\\)" \
    "whatis unsigned long function"

if ![target_info exists no_long_long] {
    gdb_test "whatis v_long_long_func" \
	"type = long long(| int) \\($void\\)" \
	"whatis long long function"

    gdb_test "whatis v_signed_long_long_func" \
	"type = (signed |)long long(| int) \\($void\\)" \
	"whatis signed long long function"

    gdb_test "whatis v_unsigned_long_long_func" \
	"type = (unsigned long long(| int)|long long unsigned int) \\($void\\)" \
	"whatis unsigned long long function"
}

# Sun /bin/cc calls this a function returning double.
if {!$gcc_compiled} then {setup_xfail "*-sun-sunos4*"}
	gdb_test "whatis v_float_func" \
	    "type = float \\($void\\)" \
	    "whatis float function"

	gdb_test "whatis v_double_func" \
	    "type = double \\($void\\)" \
	    "whatis double function" \
}
