Clarify "list" output when specified lines are ambiguous
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / whatis-ptype-typedefs.exp
1 # Copyright 2017 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # Test "whatis"/"ptype" of different typedef types, and of expressions
17 # involving casts to/from different typedefs.
18 #
19 # Particularly, when "whatis" is given a type name directly, it should
20 # strip one (and only one) typedef level. Otherwise, it should not
21 # strip any typedef at all. GDB used to incorrectly strip typedefs of
22 # expressions involving casts to typedef types. E.g., (gdb) print
23 # (int_typedef)0" shall result in a value of type "int_typedef", not
24 # "int".
25
26 standard_testfile
27
28 # Prepare for testing in language LANG. Lang can be "c" or "c++".
29
30 proc prepare {lang} {
31 global srcfile testfile
32
33 if [target_info exists no_long_long] {
34 set options [list debug additional_flags=-DNO_LONG_LONG]
35 } else {
36 set options [list debug]
37 }
38
39 if {$lang == "c++"} {
40 lappend options c++
41 set out $testfile-cxx
42 } else {
43 set out $testfile-c
44 }
45
46 if { [prepare_for_testing "failed to prepare" \
47 ${out} [list $srcfile] $options] } {
48 return -1
49 }
50
51 if ![runto_main] then {
52 fail "can't run to main"
53 return 0
54 }
55 }
56
57 # The following list is layed out as a table. It is composed by
58 # sub-lists (lines), with each line representing one whatis/ptype
59 # test. The sub-list (line) elements (columns) are (in order):
60 #
61 # EXP - The user expression passed to whatis/ptype.
62 #
63 # WHATIS - What "whatis" should print.
64 #
65 # If the EXP column is a type name, then this will be the same type,
66 # with one (and only one) typedef level removed. Otherwise, this is
67 # the type of the expression on the first column, with all typedefs
68 # preserved.
69 #
70 # PTYPE - What "ptype" should print.
71 #
72 # This is always the type of the input type/expression stripped from
73 # all typedefs.
74 #
75 # LANGUAGE - If the line is language-specific, which language.
76 #
77 # This can be "c" or "c++".
78 #
79 # Columns in the table represent:
80 # EXP # whatis # ptype # language
81 set table {
82 {"void_typedef" "void" "void"}
83 {"void_typedef2" "void_typedef" "void"}
84
85 {"int_typedef" "int" "int"}
86 {"int_typedef2" "int_typedef" "int"}
87 {"v_int_typedef" "int_typedef" "int"}
88 {"v_int_typedef2" "int_typedef2" "int"}
89
90 {"float_typedef" "float" "float"}
91 {"float_typedef2" "float_typedef" "float"}
92 {"v_float_typedef" "float_typedef" "float"}
93 {"v_float_typedef2" "float_typedef2" "float"}
94
95 {"colors_typedef" "(enum )?colors" "enum colors( : unsigned int)? {red, green, blue}"}
96 {"colors_typedef2" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
97 {"v_colors_typedef" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
98 {"v_colors_typedef2" "colors_typedef2" "enum colors( : unsigned int)? {red, green, blue}"}
99
100 {"func_ftype" "void \\(void\\)" "void \\(void\\)"}
101 {"func_ftype2" "func_ftype" "void \\(void\\)"}
102
103 {"func_ftype *" "func_ftype \\*" "void \\(\\*\\)\\(void\\)"}
104 {"func_ftype2 *" "func_ftype2 \\*" "void \\(\\*\\)\\(void\\)"}
105 {"v_func_ftype" "func_ftype \\*" "void \\(\\*\\)\\(void\\)"}
106 {"v_func_ftype2" "func_ftype2 \\*" "void \\(\\*\\)\\(void\\)"}
107
108 {"v_t_struct_typedef" "t_struct_typedef" "struct t_struct {.* member;.*}"}
109 {"v_t_struct_typedef2" "t_struct_typedef2" "struct t_struct {.* member;.*}"}
110 {"v_t_struct_union_wrapper_typedef" "t_struct_union_wrapper_typedef" "union t_struct_union_wrapper {.*base;.*}"}
111 {"v_t_struct_union_wrapper_typedef2" "t_struct_union_wrapper_typedef2" "union t_struct_union_wrapper {.*base;.*}"}
112 {"v_uchar_array_t_struct_typedef" "uchar_array_t_struct_typedef" "unsigned char \\[.*\\]"}
113 {"v_uchar_array_t_struct_typedef2" "uchar_array_t_struct_typedef2" "unsigned char \\[.*\\]"}
114
115 {"v_ns_Struct_typedef" "ns_Struct_typedef" "struct ns::Struct {.* method.*}" "c++"}
116
117 {"ns_method_ptr_typedef"
118 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
119 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
120 "c++"}
121
122 {"ns::method_ptr_typedef"
123 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
124 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
125 "c++"}
126
127 {"ns_method_ptr_typedef2"
128 "ns_method_ptr_typedef"
129 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
130 "c++"}
131
132 {"ns::method_ptr_typedef2"
133 "ns::method_ptr_typedef"
134 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
135 "c++"}
136
137 {"ns::Struct::method"
138 "void \\(ns::Struct \\* const\\)"
139 "void \\(ns::Struct \\* const\\)"
140 "c++"}
141 }
142
143 # The 4th column above is optional. If present, it indicates that the
144 # line should only be tested in the specified language. This is a
145 # helper function that checks whether LINE's language matches LANG.
146 proc line_lang_match {line lang} {
147 if {[llength $line] <= 3} {
148 return true
149 }
150
151 set line_lang [lindex $line 3]
152 if {$line_lang == "" || $lang == $line_lang} {
153 return true
154 }
155
156 return false
157 }
158
159 # Run tests in language LANG.
160
161 proc run_tests {lang} {
162 global table
163 global gdb_prompt
164
165 # Test passing all EXP in the list/table above to whatis/ptype,
166 # and check what comes out.
167 with_test_prefix "whatis/ptype" {
168 foreach line $table {
169 set type [lindex $line 0]
170 set whatis [lindex $line 1]
171 set ptype [lindex $line 2]
172
173 if {![line_lang_match $line $lang]} {
174 continue
175 }
176
177 # GCC doesn't record the target type of "typedef of
178 # typedef of void" types in the DWARF. See
179 # <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81267>.
180 # Handle that case manually in order to be able to xfail
181 # it.
182 if {$type == "void_typedef2"} {
183 set test "whatis $type"
184 gdb_test_multiple $test $test {
185 -re "type = void\r\n$gdb_prompt $" {
186 # gcc/81267.
187 setup_xfail "*-*-*"
188 fail "$test (void)"
189 }
190 -re "type = void_typedef\r\n$gdb_prompt $" {
191 pass $test
192 }
193 }
194 } else {
195 gdb_test "whatis $type" "type = $whatis"
196 }
197
198 gdb_test "ptype $type" "type = $ptype"
199 }
200 }
201
202 # Test converting/casting all variables in the first column of the
203 # table to all types (found in the first column of the table).
204 # The aggregates are all defined to be the same size so that
205 # casting actually works. (GDB's casting operator is more general
206 # than a C cast.)
207 #
208 # The main idea here is testing all the different paths in the
209 # value casting code in GDB (value_cast), making sure typedefs are
210 # preserved.
211 with_test_prefix "cast" {
212 foreach line1 $table {
213 set from [lindex $line1 0]
214
215 if {![line_lang_match $line1 $lang]} {
216 continue
217 }
218
219 foreach line2 $table {
220 set to [lindex $line2 0]
221 set whatis [lindex $line2 1]
222 set ptype [lindex $line2 2]
223
224 if {![line_lang_match $line2 $lang]} {
225 continue
226 }
227
228 # We try all combinations, even those that don't
229 # parse, or are invalid, to catch the case of a
230 # regression making them inadvertently valid. For
231 # example, these convertions are invalid:
232 #
233 # float <-> array
234 # array -> function (not function pointer)
235 # array -> member_ptr
236 #
237 # while these are invalid syntax:
238 #
239 # (anything) type
240 # (var) anything
241 # (method) anything [not method pointer]
242 # (float) method
243 #
244 if {([string match "v_*" $to]
245 || (![string match "v_*" $from] && ![string match "*method" $from])
246 || [string match "*method" $to])} {
247 gdb_test "whatis ($to) $from" "syntax error.*" "whatis ($to) $from (syntax)"
248 gdb_test "ptype ($to) $from" "syntax error.*" "ptype ($to) $from (syntax)"
249 } elseif {([string match "*float*" $from] && [string match "*array*" $to])
250 || ([string match "float*" $to] && [string match "*array*" $from])
251 || ([string match "float*" $to] && [string match "*method" $from])
252 || ([string match "*ftype" $to] && [string match "*array*" $from])
253 || ([string match "*ftype2" $to] && [string match "*array*" $from])
254 || ([string match "*ftype" $to] && [string match "*method" $from])
255 || ([string match "*ftype2" $to] && [string match "*method" $from])
256 || ([string match "*method_ptr*" $to] && [string match "*method" $from])
257 || ([string match "*method_ptr*" $to] && [string match "*array*" $from])} {
258 gdb_test "whatis ($to) $from" "Invalid cast." "whatis ($to) $from (invalid)"
259 gdb_test "ptype ($to) $from" "Invalid cast." "ptype ($to) $from (invalid)"
260 } else {
261 gdb_test "whatis ($to) $from" "type = [string_to_regexp $to]"
262 gdb_test "ptype ($to) $from" "type = $ptype"
263 }
264 }
265 }
266 }
267 }
268
269 foreach_with_prefix lang {"c" "c++"} {
270 prepare $lang
271 run_tests $lang
272 }
This page took 0.042746 seconds and 4 git commands to generate.