]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.cp/cpexprs.exp.tcl
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.cp / cpexprs.exp.tcl
CommitLineData
113ee09a
TV
1# cpexprs.exp - C++ expressions tests
2#
1d506c26 3# Copyright 2008-2024 Free Software Foundation, Inc.
113ee09a
TV
4#
5# Contributed by Red Hat, originally written by Keith Seitz.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20# This file is part of the gdb testsuite.
21
22# A helper proc which sets a breakpoint at FUNC and attempts to
23# run to the breakpoint.
24proc test_breakpoint {func} {
25 global DEC
26
27 # Return to the top of the test function every time.
28 delete_breakpoints
29 if { ! [gdb_breakpoint test_function] } {
30 fail "set test_function breakpoint for $func"
31 } elseif { [gdb_test "continue" \
32 "Continuing.\r\n\r\nBreakpoint $DEC+,.*test_function.*" \
cce0ae56 33 "continue to test_function for $func"] != 0 } {
113ee09a
TV
34 } else {
35 gdb_breakpoint "$func"
36 set i [expr {[string last : $func] + 1}]
37 set efunc [string_to_regexp [string range $func $i end]]
38 gdb_test "continue" \
39 "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
40 "continue to $func"
41 }
42}
43
44# Add a function to the list of tested functions
45# FUNC is the name of the function (which will be passed to gdb commands)
46# TYPE is the type of the function, as expected from the "print" command
47# PRINT is the name of the function, as expected result of the print command
48# *OR* "-", indicating that FUNC should be used (needed for virtual/inherited
49# funcs)
50# LST is either the expected result of the list command (the comment from
51# the source code) *OR* "-", in which case FUNC will be used
52#
53# Usage:
54# add NAME TYPE PRINT LST
55# add NAME TYPE PRINT -
56proc add_type_regexp {func type print lst} {
57 global all_functions CONVAR ADDR
58
59 set all_functions($func,type) $type
60 if {$print == "-"} {
61 set print $func
62 }
63
64 # An exception: since gdb canonicalizes C++ output,
65 # "(void)" must be mutated to "()".
66 regsub {\(void\)} $print {()} print
67
68 set all_functions($func,print) \
69 "$CONVAR = {$type} $ADDR <[string_to_regexp $print].*>"
70 if {$lst == "-"} {
71 set lst "$func"
72 }
73 set all_functions($func,list) ".*// [string_to_regexp $lst]"
74}
75
76proc add {func type print lst} {
77 add_type_regexp $func [string_to_regexp $type] $print $lst
78}
79
80proc get {func cmd} {
81 global all_functions
82 return $all_functions($func,$cmd)
83}
84
85# Returns a list of function names for a given command
86proc get_functions {cmd} {
87 global all_functions
88 set result {}
89 foreach i [array names all_functions *,$cmd] {
90 if {$all_functions($i) != ""} {
91 set idx [string last , $i]
92 if {$idx != -1} {
93 lappend result [string range $i 0 [expr {$idx - 1}]]
94 }
95 }
96 }
97
98 return [lsort $result]
99}
100
101# Some convenience variables for this test
102set DEC {[0-9]}; # a decimal number
103set HEX {[0-9a-fA-F]}; # a hexidecimal number
104set CONVAR "\\\$$DEC+"; # convenience variable regexp
105set ADDR "0x$HEX+"; # address
106
107# An array of functions/methods that we are testing...
108# Each element consists is indexed by NAME,COMMAND, where
109# NAME is the function name and COMMAND is the gdb command that
110# we are testing. The value of the array for any index pair is
111# the expected result of running COMMAND with the NAME as argument.
112
113# The array holding all functions/methods to test. Valid subindexes
114# are (none need character escaping -- "add" will take care of that):
115
116# add name type print_name list
117# NAME,type: value is type of function
118# NAME,print: value is print name of function (careful w/inherited/virtual!)
119# NAME,list: value is comment in source code on first line of function
120# (without the leading "//")
121array set all_functions {}
122
123# "Normal" functions/methods
124add {test_function} \
125 {int (int, char **)} \
126 - \
127 -
128add {derived::a_function} \
129 {void (const derived * const)} \
130 - \
131 -
132add {base1::a_function} \
133 {void (const base1 * const)} \
134 - \
135 -
136add {base2::a_function} \
137 {void (const base2 * const)} \
138 - \
139 -
140
141# Constructors
142
143# On targets using the ARM EABI, the constructor is expected to return
144# "this".
145proc ctor_ret { type } {
146 if { [istarget arm*-*eabi*] || [is_aarch32_target] } {
147 return "$type *"
148 } else {
149 return "void "
150 }
151}
152
153proc ctor_prefix { type } {
154 set ret [ctor_ret $type]
155 return "${ret}($type * const"
156}
157
158proc ctor { type arglist } {
159 if { $arglist != "" } {
160 set arglist ", $arglist"
161 }
162 return "[ctor_prefix $type]$arglist)"
163}
164
165add {derived::derived} \
166 [ctor derived ""] \
167 - \
168 -
169add_type_regexp {base1::base1(void)} \
170 "[string_to_regexp [ctor_prefix base1]], (const )?void \\*\\*( const)?\\)" \
171 - \
172 -
173add {base1::base1(int)} \
174 [ctor base1 "int"] \
175 - \
176 -
177add_type_regexp {base2::base2} \
178 "[string_to_regexp [ctor_prefix base2]], (const )?void \\*\\*( const)?\\)" \
179 - \
180 -
181add {base::base(void)} \
182 [ctor base ""] \
183 - \
184 -
185add {base::base(int)} \
186 [ctor base "int"] \
187 - \
188 -
189
190# Destructors
191
192# On targets using the ARM EABI, some destructors are expected
193# to return "this". Others are void. For internal reasons,
194# GCC returns void * instead of $type *; RealView appears to do
195# the same.
196proc dtor { type } {
197 if { [istarget arm*-*eabi*] || [is_aarch32_target] } {
198 set ret "void *"
199 } else {
200 set ret "void "
201 }
202 return "${ret}($type * const)"
203}
204
205add {base::~base} \
206 [dtor base] \
207 - \
208 -
209
210# Overloaded methods (all are const)
211add {base::overload(void) const} \
212 {int (const base * const)} \
213 - \
214 {base::overload(void) const}
215add {base::overload(int) const} \
216 {int (const base * const, int)} \
217 - \
218 -
219add {base::overload(short) const} \
220 {int (const base * const, short)} \
221 - \
222 -
223add {base::overload(long) const} \
224 {int (const base * const, long)} \
225 - \
226 -
227add {base::overload(char*) const} \
228 {int (const base * const, char *)} \
229 - \
230 -
231add {base::overload(base&) const} \
232 {int (const base * const, base &)} \
233 - \
234 -
235
236# Operators
237add {base::operator+} \
238 {int (const base * const, const base &)} \
239 - \
240 -
241add {base::operator++} \
242 {base (base * const)} \
243 - \
244 -
245add {base::operator+=} \
246 {base (base * const, const base &)} \
247 - \
248 -
249add {base::operator-} \
250 {int (const base * const, const base &)} \
251 - \
252 -
253add {base::operator--} \
254 {base (base * const)} \
255 - \
256 -
257add {base::operator-=} \
258 {base (base * const, const base &)} \
259 - \
260 -
261add {base::operator*} \
262 {int (const base * const, const base &)} \
263 - \
264 -
265add {base::operator*=} \
266 {base (base * const, const base &)} \
267 - \
268 -
269add {base::operator/} \
270 {int (const base * const, const base &)} \
271 - \
272 -
273add {base::operator/=} \
274 {base (base * const, const base &)} \
275 - \
276 -
277add {base::operator%} \
278 {int (const base * const, const base &)} \
279 - \
280 -
281add {base::operator%=} \
282 {base (base * const, const base &)} \
283 - \
284 -
285add {base::operator<} \
286 {bool (const base * const, const base &)} \
287 - \
288 -
289add {base::operator<=} \
290 {bool (const base * const, const base &)} \
291 - \
292 -
293add {base::operator>} \
294 {bool (const base * const, const base &)} \
295 - \
296 -
297add {base::operator>=} \
298 {bool (const base * const, const base &)} \
299 - \
300 -
301add {base::operator!=} \
302 {bool (const base * const, const base &)} \
303 - \
304 -
305add {base::operator==} \
306 {bool (const base * const, const base &)} \
307 - \
308 -
309add {base::operator!} \
310 {bool (const base * const)} \
311 - \
312 -
313add {base::operator&&} \
314 {bool (const base * const, const base &)} \
315 - \
316 -
317add {base::operator||} \
318 {bool (const base * const, const base &)} \
319 - \
320 -
321add {base::operator<<} \
322 {int (const base * const, int)} \
323 - \
324 -
325add {base::operator<<=} \
326 {base (base * const, int)} \
327 - \
328 -
329add {base::operator>>} \
330 {int (const base * const, int)} \
331 - \
332 -
333add {base::operator>>=} \
334 {base (base * const, int)} \
335 - \
336 -
337add {base::operator~} \
338 {int (const base * const)} \
339 - \
340 -
341add {base::operator&} \
342 {int (const base * const, const base &)} \
343 - \
344 -
345add {base::operator&=} \
346 {base (base * const, const base &)} \
347 - \
348 -
349add {base::operator|} \
350 {int (const base * const, const base &)} \
351 - \
352 -
353add {base::operator|=} \
354 {base (base * const, const base &)} \
355 - \
356 -
357add {base::operator^} \
358 {int (const base * const, const base &)} \
359 - \
360 -
361add {base::operator^=} \
362 {base (base * const, const base &)} \
363 - \
364 -
365add {base::operator=} \
366 {base (base * const, const base &)} \
367 - \
368 -
369add {base::operator()} \
370 {void (const base * const)} \
371 - \
372 -
373add {base::operator[]} \
374 {int (const base * const, int)} \
375 - \
376 -
377add {base::operator new} \
378 {void *(size_t)} \
379 - \
380 -
381add {base::operator delete} \
382 {void (void *)} \
383 - \
384 -
385add {base::operator new[]} \
386 {void *(size_t)} \
387 - \
388 -
389add {base::operator delete[]} \
390 {void (void *)} \
391 - \
392 -
393add {base::operator char*} \
394 {char *(const base * const)} \
395 - \
396 -
397add {base::operator fluff*} \
398 {fluff *(const base * const)} \
399 - \
400 -
401add {base::operator fluff**} \
402 {fluff **(const base * const)} \
403 - \
404 -
405add {base::operator int} \
406 {int (const base * const)} \
407 - \
408 -
409add {base::operator fluff const* const*} \
410 {const fluff * const *(const base * const)} \
411 - \
412 -
413
414# Templates
415add {tclass<char>::do_something} \
416 {void (tclass<char> * const)} \
417 - \
418 -
419add {tclass<int>::do_something} \
420 {void (tclass<int> * const)} \
421 - \
422 -
423add {tclass<long>::do_something} \
424 {void (tclass<long> * const)} \
425 - \
426 -
427add {tclass<short>::do_something} \
428 {void (tclass<short> * const)} \
429 - \
430 -
431add {tclass<base>::do_something} \
432 {void (tclass<base> * const)} \
433 - \
434 -
435add {flubber<int, int, int, int, int>} \
436 {void (void)} \
437 - \
438 flubber
439add {flubber<int, int, int, int, short>} \
440 {void (void)} \
441 - \
442 flubber
443add {flubber<int, int, int, int, long>} \
444 {void (void)} \
445 - \
446 flubber
447add {flubber<int, int, int, int, char>} \
448 {void (void)} \
449 - \
450 flubber
451add {flubber<int, int, int, short, int>} \
452 {void (void)} \
453 - \
454 flubber
455add {flubber<int, int, int, short, short>} \
456 {void (void)} \
457 - \
458 flubber
459add {flubber<int, int, int, short, long>} \
460 {void (void)} \
461 - \
462 flubber
463add {flubber<int, int, int, short, char>} \
464 {void (void)} \
465 - \
466 flubber
467add {flubber<int, int, int, long, int>} \
468 {void (void)} \
469 - \
470 flubber
471add {flubber<int, int, int, long, short>} \
472 {void (void)} \
473 - \
474 flubber
475add {flubber<int, int, int, long, long>} \
476 {void (void)} \
477 - \
478 flubber
479add {flubber<int, int, int, long, char>} \
480 {void (void)} \
481 - \
482 flubber
483add {flubber<int, int, int, char, int>} \
484 {void (void)} \
485 - \
486 flubber
487add {flubber<int, int, int, char, short>} \
488 {void (void)} \
489 - \
490 flubber
491add {flubber<int, int, int, char, long>} \
492 {void (void)} \
493 - \
494 flubber
495add {flubber<int, int, int, char, char>} \
496 {void (void)} \
497 - \
498 flubber
499add {flubber<int, int, short, int, int>} \
500 {void (void)} \
501 - \
502 flubber
503add {flubber<int, int, short, int, short>} \
504 {void (void)} \
505 - \
506 flubber
507add {flubber<int, int, short, int, long>} \
508 {void (void)} \
509 - \
510 flubber
511add {flubber<int, int, short, int, char>} \
512 {void (void)} \
513 - \
514 flubber
515add {flubber<int, int, short, short, int>} \
516 {void (void)} \
517 - \
518 flubber
519add {flubber<short, int, short, int, short>} \
520 {void (void)} \
521 - \
522 flubber
523add {flubber<long, short, long, short, long>} \
524 {void (void)} \
525 - \
526 flubber
527add {tclass<base>::do_something} \
528 {void (tclass<base> * const)} \
529 - \
530 {tclass<T>::do_something}
531add {policy1::policy} \
532 [ctor "policy<int, operation_1<void*> >" "int"] \
533 {policy<int, operation_1<void*> >::policy} \
534 {policy<T, Policy>::policy}
535add {policy2::policy} \
536 [ctor "policy<int, operation_2<void*> >" int] \
537 {policy<int, operation_2<void*> >::policy} \
538 {policy<T, Policy>::policy}
539add {policy3::policy} \
540 [ctor "policy<int, operation_3<void*> >" "int"] \
541 {policy<int, operation_3<void*> >::policy} \
542 {policy<T, Policy>::policy}
543add {policy4::policy} \
544 [ctor "policy<int, operation_4<void*> >" "int"] \
545 {policy<int, operation_4<void*> >::policy} \
546 {policy<T, Policy>::policy}
547add {policy1::function} \
548 {void (void)} \
549 {operation_1<void*>::function} \
550 {operation_1<T>::function}
551add {policy2::function} \
552 {void (void)} \
553 {operation_2<void*>::function} \
554 {operation_2<T>::function}
555add {policy3::function} \
556 {void (void)} \
557 {operation_3<void*>::function} \
558 {operation_3<T>::function}
559add {policy4::function} \
560 {void (void)} \
561 {operation_4<void*>::function} \
562 {operation_4<T>::function}
563add {policyd<int, operation_1<int> >::policyd} \
564 [ctor "policyd<int, operation_1<int> >" "int"] \
565 - \
566 {policyd<T, Policy>::policyd}
567add {policyd1::policyd} \
568 [ctor "policyd<int, operation_1<int> >" "int"] \
569 {policyd<int, operation_1<int> >::policyd} \
570 {policyd<T, Policy>::policyd}
571add {policyd<int, operation_1<int> >::~policyd} \
572 [dtor "policyd<int, operation_1<int> >"] \
573 - \
574 {policyd<T, Policy>::~policyd}
575add {policyd1::~policyd} \
576 [dtor "policyd<int, operation_1<int> >"] \
577 {policyd<int, operation_1<int> >::~policyd} \
578 {policyd<T, Policy>::~policyd}
579add {policyd<long, operation_1<long> >::policyd} \
580 [ctor "policyd<long, operation_1<long> >" "long"] \
581 - \
582 {policyd<T, Policy>::policyd}
583add {policyd2::policyd} \
584 [ctor "policyd<long, operation_1<long> >" "long"] \
585 {policyd<long, operation_1<long> >::policyd} \
586 {policyd<T, Policy>::policyd}
587add {policyd<long, operation_1<long> >::~policyd} \
588 [dtor "policyd<long, operation_1<long> >"] \
589 - \
590 {policyd<T, Policy>::~policyd}
591add {policyd2::~policyd} \
592 [dtor "policyd<long, operation_1<long> >"] \
593 {policyd<long, operation_1<long> >::~policyd} \
594 {policyd<T, Policy>::~policyd}
595add {policyd<char, operation_1<char> >::policyd} \
596 [ctor "policyd<char, operation_1<char> >" "char"] \
597 - \
598 {policyd<T, Policy>::policyd}
599add {policyd3::policyd} \
600 [ctor "policyd<char, operation_1<char> >" "char"] \
601 {policyd<char, operation_1<char> >::policyd} \
602 {policyd<T, Policy>::policyd}
603add {policyd<char, operation_1<char> >::~policyd} \
604 [dtor "policyd<char, operation_1<char> >"] \
605 - \
606 {policyd<T, Policy>::~policyd}
607add {policyd3::~policyd} \
608 [dtor "policyd<char, operation_1<char> >"] \
609 {policyd<char, operation_1<char> >::~policyd} \
610 {policyd<T, Policy>::~policyd}
611add {policyd<base, operation_1<base> >::policyd} \
612 [ctor "policyd<base, operation_1<base> >" "base"] \
613 - \
614 {policyd<T, Policy>::policyd}
615add {policyd4::policyd} \
616 [ctor "policyd<base, operation_1<base> >" "base"] \
617 {policyd<base, operation_1<base> >::policyd} \
618 {policyd<T, Policy>::policyd}
619add {policyd<base, operation_1<base> >::~policyd} \
620 [dtor "policyd<base, operation_1<base> >"] \
621 - \
622 {policyd<T, Policy>::~policyd}
623add {policyd4::~policyd} \
624 [dtor "policyd<base, operation_1<base> >"] \
625 {policyd<base, operation_1<base> >::~policyd} \
626 {policyd<T, Policy>::~policyd}
627add {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
628 [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
629 - \
630 {policyd<T, Policy>::policyd}
631add {policyd5::policyd} \
632 [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
633 {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
634 {policyd<T, Policy>::policyd}
635add {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
636 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
637 - \
638 {policyd<T, Policy>::~policyd}
639add {policyd5::~policyd} \
640 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
641 {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
642 {policyd<T, Policy>::~policyd}
643add {policyd<int, operation_1<int> >::function} \
644 {void (void)} \
645 {operation_1<int>::function}\
646 {operation_1<T>::function}
647add {policyd1::function} \
648 {void (void)} \
649 {operation_1<int>::function} \
650 {operation_1<T>::function}
651add {policyd2::function} \
652 {void (void)} \
653 {operation_1<long>::function} \
654 {operation_1<T>::function}
655add {policyd<char, operation_1<char> >::function} \
656 {void (void)} \
657 {operation_1<char>::function} \
658 {operation_1<T>::function}
659add {policyd3::function} \
660 {void (void)} \
661 {operation_1<char>::function} \
662 {operation_1<T>::function}
663add {policyd<base, operation_1<base> >::function} \
664 {void (void)} \
665 {operation_1<base>::function} \
666 {operation_1<T>::function}
667add {policyd4::function} \
668 {void (void)} \
669 {operation_1<base>::function} \
670 {operation_1<T>::function}
671add {policyd<tclass<int>, operation_1<tclass<int> > >::function} \
672 {void (void)} \
673 {operation_1<tclass<int> >::function} \
674 {operation_1<T>::function}
675add {policyd5::function} \
676 {void (void)} \
677 {operation_1<tclass<int> >::function} \
678 {operation_1<T>::function}
679
680# Start the test
0b94d2b9 681if {![allow_cplus_tests]} { continue }
113ee09a
TV
682
683#
684# test running programs
685#
686
687standard_testfile cpexprs.cc
688
113ee09a
TV
689# Include required flags.
690set flags "$flags debug c++"
691
692if {[prepare_for_testing "failed to prepare" $testfile $srcfile "$flags"]} {
693 return -1
694}
695
696if {![runto_main]} {
697 perror "couldn't run to breakpoint"
698 continue
699}
700
701# Set the listsize to one. This will help with testing "list".
702gdb_test "set listsize 1"
703
704# "print METHOD"
705foreach name [get_functions print] {
706 gdb_test "print $name" [get $name print]
707}
708
709# "list METHOD"
710foreach name [get_functions list] {
711 gdb_test "list $name" [get $name list]
712}
713
714# Running to breakpoint -- use any function we can "list"
715foreach name [get_functions list] {
716 # Skip "test_function", since test_breakpoint uses it
717 if {[string compare $name "test_function"] != 0} {
718 test_breakpoint $name
719 }
720}
721
722# Test c/v gets recognized even without quoting.
723foreach cv {{} { const} { volatile} { const volatile}} {
724 set test "p 'CV::m(int)$cv'"
4707199b
SM
725 set correct dummy_value
726
113ee09a
TV
727 gdb_test_multiple $test $test {
728 -re "( = {.*} 0x\[0-9a-f\]+ <CV::m.*>)\r\n$gdb_prompt $" {
729 # = {void (CV * const, CV::t)} 0x400944 <CV::m(int)>
730 set correct $expect_out(1,string)
731 pass $test
732 }
733 }
734 gdb_test "p CV::m(int)$cv" [string_to_regexp $correct]
735}
736
737# Test TYPENAME:: gets recognized even in parentheses.
738gdb_test "p CV_f(int)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
739gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
740gdb_test "p CV_f(CV::i)" " = 43"
741
742gdb_test "p CV_f('cpexprs.cc'::CV::t)" \
743 { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
744
745# Make sure conversion operator names are canonicalized and properly
746# "spelled."
747gdb_test "p base::operator const fluff * const *" \
748 [get "base::operator fluff const* const*" print] \
749 "canonicalized conversion operator name 1"
750gdb_test "p base::operator const fluff* const*" \
751 [get "base::operator fluff const* const*" print] \
752 "canonicalized conversion operator name 2"
753gdb_test "p base::operator derived*" \
754 "There is no field named operator derived\\*" \
755 "undefined conversion operator"
756
757gdb_exit
758return 0