]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - 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
1 # cpexprs.exp - C++ expressions tests
2 #
3 # Copyright 2008-2024 Free Software Foundation, Inc.
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.
24 proc 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.*" \
33 "continue to test_function for $func"] != 0 } {
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 -
56 proc 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
76 proc add {func type print lst} {
77 add_type_regexp $func [string_to_regexp $type] $print $lst
78 }
79
80 proc 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
86 proc 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
102 set DEC {[0-9]}; # a decimal number
103 set HEX {[0-9a-fA-F]}; # a hexidecimal number
104 set CONVAR "\\\$$DEC+"; # convenience variable regexp
105 set 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 "//")
121 array set all_functions {}
122
123 # "Normal" functions/methods
124 add {test_function} \
125 {int (int, char **)} \
126 - \
127 -
128 add {derived::a_function} \
129 {void (const derived * const)} \
130 - \
131 -
132 add {base1::a_function} \
133 {void (const base1 * const)} \
134 - \
135 -
136 add {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".
145 proc ctor_ret { type } {
146 if { [istarget arm*-*eabi*] || [is_aarch32_target] } {
147 return "$type *"
148 } else {
149 return "void "
150 }
151 }
152
153 proc ctor_prefix { type } {
154 set ret [ctor_ret $type]
155 return "${ret}($type * const"
156 }
157
158 proc ctor { type arglist } {
159 if { $arglist != "" } {
160 set arglist ", $arglist"
161 }
162 return "[ctor_prefix $type]$arglist)"
163 }
164
165 add {derived::derived} \
166 [ctor derived ""] \
167 - \
168 -
169 add_type_regexp {base1::base1(void)} \
170 "[string_to_regexp [ctor_prefix base1]], (const )?void \\*\\*( const)?\\)" \
171 - \
172 -
173 add {base1::base1(int)} \
174 [ctor base1 "int"] \
175 - \
176 -
177 add_type_regexp {base2::base2} \
178 "[string_to_regexp [ctor_prefix base2]], (const )?void \\*\\*( const)?\\)" \
179 - \
180 -
181 add {base::base(void)} \
182 [ctor base ""] \
183 - \
184 -
185 add {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.
196 proc 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
205 add {base::~base} \
206 [dtor base] \
207 - \
208 -
209
210 # Overloaded methods (all are const)
211 add {base::overload(void) const} \
212 {int (const base * const)} \
213 - \
214 {base::overload(void) const}
215 add {base::overload(int) const} \
216 {int (const base * const, int)} \
217 - \
218 -
219 add {base::overload(short) const} \
220 {int (const base * const, short)} \
221 - \
222 -
223 add {base::overload(long) const} \
224 {int (const base * const, long)} \
225 - \
226 -
227 add {base::overload(char*) const} \
228 {int (const base * const, char *)} \
229 - \
230 -
231 add {base::overload(base&) const} \
232 {int (const base * const, base &)} \
233 - \
234 -
235
236 # Operators
237 add {base::operator+} \
238 {int (const base * const, const base &)} \
239 - \
240 -
241 add {base::operator++} \
242 {base (base * const)} \
243 - \
244 -
245 add {base::operator+=} \
246 {base (base * const, const base &)} \
247 - \
248 -
249 add {base::operator-} \
250 {int (const base * const, const base &)} \
251 - \
252 -
253 add {base::operator--} \
254 {base (base * const)} \
255 - \
256 -
257 add {base::operator-=} \
258 {base (base * const, const base &)} \
259 - \
260 -
261 add {base::operator*} \
262 {int (const base * const, const base &)} \
263 - \
264 -
265 add {base::operator*=} \
266 {base (base * const, const base &)} \
267 - \
268 -
269 add {base::operator/} \
270 {int (const base * const, const base &)} \
271 - \
272 -
273 add {base::operator/=} \
274 {base (base * const, const base &)} \
275 - \
276 -
277 add {base::operator%} \
278 {int (const base * const, const base &)} \
279 - \
280 -
281 add {base::operator%=} \
282 {base (base * const, const base &)} \
283 - \
284 -
285 add {base::operator<} \
286 {bool (const base * const, const base &)} \
287 - \
288 -
289 add {base::operator<=} \
290 {bool (const base * const, const base &)} \
291 - \
292 -
293 add {base::operator>} \
294 {bool (const base * const, const base &)} \
295 - \
296 -
297 add {base::operator>=} \
298 {bool (const base * const, const base &)} \
299 - \
300 -
301 add {base::operator!=} \
302 {bool (const base * const, const base &)} \
303 - \
304 -
305 add {base::operator==} \
306 {bool (const base * const, const base &)} \
307 - \
308 -
309 add {base::operator!} \
310 {bool (const base * const)} \
311 - \
312 -
313 add {base::operator&&} \
314 {bool (const base * const, const base &)} \
315 - \
316 -
317 add {base::operator||} \
318 {bool (const base * const, const base &)} \
319 - \
320 -
321 add {base::operator<<} \
322 {int (const base * const, int)} \
323 - \
324 -
325 add {base::operator<<=} \
326 {base (base * const, int)} \
327 - \
328 -
329 add {base::operator>>} \
330 {int (const base * const, int)} \
331 - \
332 -
333 add {base::operator>>=} \
334 {base (base * const, int)} \
335 - \
336 -
337 add {base::operator~} \
338 {int (const base * const)} \
339 - \
340 -
341 add {base::operator&} \
342 {int (const base * const, const base &)} \
343 - \
344 -
345 add {base::operator&=} \
346 {base (base * const, const base &)} \
347 - \
348 -
349 add {base::operator|} \
350 {int (const base * const, const base &)} \
351 - \
352 -
353 add {base::operator|=} \
354 {base (base * const, const base &)} \
355 - \
356 -
357 add {base::operator^} \
358 {int (const base * const, const base &)} \
359 - \
360 -
361 add {base::operator^=} \
362 {base (base * const, const base &)} \
363 - \
364 -
365 add {base::operator=} \
366 {base (base * const, const base &)} \
367 - \
368 -
369 add {base::operator()} \
370 {void (const base * const)} \
371 - \
372 -
373 add {base::operator[]} \
374 {int (const base * const, int)} \
375 - \
376 -
377 add {base::operator new} \
378 {void *(size_t)} \
379 - \
380 -
381 add {base::operator delete} \
382 {void (void *)} \
383 - \
384 -
385 add {base::operator new[]} \
386 {void *(size_t)} \
387 - \
388 -
389 add {base::operator delete[]} \
390 {void (void *)} \
391 - \
392 -
393 add {base::operator char*} \
394 {char *(const base * const)} \
395 - \
396 -
397 add {base::operator fluff*} \
398 {fluff *(const base * const)} \
399 - \
400 -
401 add {base::operator fluff**} \
402 {fluff **(const base * const)} \
403 - \
404 -
405 add {base::operator int} \
406 {int (const base * const)} \
407 - \
408 -
409 add {base::operator fluff const* const*} \
410 {const fluff * const *(const base * const)} \
411 - \
412 -
413
414 # Templates
415 add {tclass<char>::do_something} \
416 {void (tclass<char> * const)} \
417 - \
418 -
419 add {tclass<int>::do_something} \
420 {void (tclass<int> * const)} \
421 - \
422 -
423 add {tclass<long>::do_something} \
424 {void (tclass<long> * const)} \
425 - \
426 -
427 add {tclass<short>::do_something} \
428 {void (tclass<short> * const)} \
429 - \
430 -
431 add {tclass<base>::do_something} \
432 {void (tclass<base> * const)} \
433 - \
434 -
435 add {flubber<int, int, int, int, int>} \
436 {void (void)} \
437 - \
438 flubber
439 add {flubber<int, int, int, int, short>} \
440 {void (void)} \
441 - \
442 flubber
443 add {flubber<int, int, int, int, long>} \
444 {void (void)} \
445 - \
446 flubber
447 add {flubber<int, int, int, int, char>} \
448 {void (void)} \
449 - \
450 flubber
451 add {flubber<int, int, int, short, int>} \
452 {void (void)} \
453 - \
454 flubber
455 add {flubber<int, int, int, short, short>} \
456 {void (void)} \
457 - \
458 flubber
459 add {flubber<int, int, int, short, long>} \
460 {void (void)} \
461 - \
462 flubber
463 add {flubber<int, int, int, short, char>} \
464 {void (void)} \
465 - \
466 flubber
467 add {flubber<int, int, int, long, int>} \
468 {void (void)} \
469 - \
470 flubber
471 add {flubber<int, int, int, long, short>} \
472 {void (void)} \
473 - \
474 flubber
475 add {flubber<int, int, int, long, long>} \
476 {void (void)} \
477 - \
478 flubber
479 add {flubber<int, int, int, long, char>} \
480 {void (void)} \
481 - \
482 flubber
483 add {flubber<int, int, int, char, int>} \
484 {void (void)} \
485 - \
486 flubber
487 add {flubber<int, int, int, char, short>} \
488 {void (void)} \
489 - \
490 flubber
491 add {flubber<int, int, int, char, long>} \
492 {void (void)} \
493 - \
494 flubber
495 add {flubber<int, int, int, char, char>} \
496 {void (void)} \
497 - \
498 flubber
499 add {flubber<int, int, short, int, int>} \
500 {void (void)} \
501 - \
502 flubber
503 add {flubber<int, int, short, int, short>} \
504 {void (void)} \
505 - \
506 flubber
507 add {flubber<int, int, short, int, long>} \
508 {void (void)} \
509 - \
510 flubber
511 add {flubber<int, int, short, int, char>} \
512 {void (void)} \
513 - \
514 flubber
515 add {flubber<int, int, short, short, int>} \
516 {void (void)} \
517 - \
518 flubber
519 add {flubber<short, int, short, int, short>} \
520 {void (void)} \
521 - \
522 flubber
523 add {flubber<long, short, long, short, long>} \
524 {void (void)} \
525 - \
526 flubber
527 add {tclass<base>::do_something} \
528 {void (tclass<base> * const)} \
529 - \
530 {tclass<T>::do_something}
531 add {policy1::policy} \
532 [ctor "policy<int, operation_1<void*> >" "int"] \
533 {policy<int, operation_1<void*> >::policy} \
534 {policy<T, Policy>::policy}
535 add {policy2::policy} \
536 [ctor "policy<int, operation_2<void*> >" int] \
537 {policy<int, operation_2<void*> >::policy} \
538 {policy<T, Policy>::policy}
539 add {policy3::policy} \
540 [ctor "policy<int, operation_3<void*> >" "int"] \
541 {policy<int, operation_3<void*> >::policy} \
542 {policy<T, Policy>::policy}
543 add {policy4::policy} \
544 [ctor "policy<int, operation_4<void*> >" "int"] \
545 {policy<int, operation_4<void*> >::policy} \
546 {policy<T, Policy>::policy}
547 add {policy1::function} \
548 {void (void)} \
549 {operation_1<void*>::function} \
550 {operation_1<T>::function}
551 add {policy2::function} \
552 {void (void)} \
553 {operation_2<void*>::function} \
554 {operation_2<T>::function}
555 add {policy3::function} \
556 {void (void)} \
557 {operation_3<void*>::function} \
558 {operation_3<T>::function}
559 add {policy4::function} \
560 {void (void)} \
561 {operation_4<void*>::function} \
562 {operation_4<T>::function}
563 add {policyd<int, operation_1<int> >::policyd} \
564 [ctor "policyd<int, operation_1<int> >" "int"] \
565 - \
566 {policyd<T, Policy>::policyd}
567 add {policyd1::policyd} \
568 [ctor "policyd<int, operation_1<int> >" "int"] \
569 {policyd<int, operation_1<int> >::policyd} \
570 {policyd<T, Policy>::policyd}
571 add {policyd<int, operation_1<int> >::~policyd} \
572 [dtor "policyd<int, operation_1<int> >"] \
573 - \
574 {policyd<T, Policy>::~policyd}
575 add {policyd1::~policyd} \
576 [dtor "policyd<int, operation_1<int> >"] \
577 {policyd<int, operation_1<int> >::~policyd} \
578 {policyd<T, Policy>::~policyd}
579 add {policyd<long, operation_1<long> >::policyd} \
580 [ctor "policyd<long, operation_1<long> >" "long"] \
581 - \
582 {policyd<T, Policy>::policyd}
583 add {policyd2::policyd} \
584 [ctor "policyd<long, operation_1<long> >" "long"] \
585 {policyd<long, operation_1<long> >::policyd} \
586 {policyd<T, Policy>::policyd}
587 add {policyd<long, operation_1<long> >::~policyd} \
588 [dtor "policyd<long, operation_1<long> >"] \
589 - \
590 {policyd<T, Policy>::~policyd}
591 add {policyd2::~policyd} \
592 [dtor "policyd<long, operation_1<long> >"] \
593 {policyd<long, operation_1<long> >::~policyd} \
594 {policyd<T, Policy>::~policyd}
595 add {policyd<char, operation_1<char> >::policyd} \
596 [ctor "policyd<char, operation_1<char> >" "char"] \
597 - \
598 {policyd<T, Policy>::policyd}
599 add {policyd3::policyd} \
600 [ctor "policyd<char, operation_1<char> >" "char"] \
601 {policyd<char, operation_1<char> >::policyd} \
602 {policyd<T, Policy>::policyd}
603 add {policyd<char, operation_1<char> >::~policyd} \
604 [dtor "policyd<char, operation_1<char> >"] \
605 - \
606 {policyd<T, Policy>::~policyd}
607 add {policyd3::~policyd} \
608 [dtor "policyd<char, operation_1<char> >"] \
609 {policyd<char, operation_1<char> >::~policyd} \
610 {policyd<T, Policy>::~policyd}
611 add {policyd<base, operation_1<base> >::policyd} \
612 [ctor "policyd<base, operation_1<base> >" "base"] \
613 - \
614 {policyd<T, Policy>::policyd}
615 add {policyd4::policyd} \
616 [ctor "policyd<base, operation_1<base> >" "base"] \
617 {policyd<base, operation_1<base> >::policyd} \
618 {policyd<T, Policy>::policyd}
619 add {policyd<base, operation_1<base> >::~policyd} \
620 [dtor "policyd<base, operation_1<base> >"] \
621 - \
622 {policyd<T, Policy>::~policyd}
623 add {policyd4::~policyd} \
624 [dtor "policyd<base, operation_1<base> >"] \
625 {policyd<base, operation_1<base> >::~policyd} \
626 {policyd<T, Policy>::~policyd}
627 add {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}
631 add {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}
635 add {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
636 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
637 - \
638 {policyd<T, Policy>::~policyd}
639 add {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}
643 add {policyd<int, operation_1<int> >::function} \
644 {void (void)} \
645 {operation_1<int>::function}\
646 {operation_1<T>::function}
647 add {policyd1::function} \
648 {void (void)} \
649 {operation_1<int>::function} \
650 {operation_1<T>::function}
651 add {policyd2::function} \
652 {void (void)} \
653 {operation_1<long>::function} \
654 {operation_1<T>::function}
655 add {policyd<char, operation_1<char> >::function} \
656 {void (void)} \
657 {operation_1<char>::function} \
658 {operation_1<T>::function}
659 add {policyd3::function} \
660 {void (void)} \
661 {operation_1<char>::function} \
662 {operation_1<T>::function}
663 add {policyd<base, operation_1<base> >::function} \
664 {void (void)} \
665 {operation_1<base>::function} \
666 {operation_1<T>::function}
667 add {policyd4::function} \
668 {void (void)} \
669 {operation_1<base>::function} \
670 {operation_1<T>::function}
671 add {policyd<tclass<int>, operation_1<tclass<int> > >::function} \
672 {void (void)} \
673 {operation_1<tclass<int> >::function} \
674 {operation_1<T>::function}
675 add {policyd5::function} \
676 {void (void)} \
677 {operation_1<tclass<int> >::function} \
678 {operation_1<T>::function}
679
680 # Start the test
681 if {![allow_cplus_tests]} { continue }
682
683 #
684 # test running programs
685 #
686
687 standard_testfile cpexprs.cc
688
689 # Include required flags.
690 set flags "$flags debug c++"
691
692 if {[prepare_for_testing "failed to prepare" $testfile $srcfile "$flags"]} {
693 return -1
694 }
695
696 if {![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".
702 gdb_test "set listsize 1"
703
704 # "print METHOD"
705 foreach name [get_functions print] {
706 gdb_test "print $name" [get $name print]
707 }
708
709 # "list METHOD"
710 foreach name [get_functions list] {
711 gdb_test "list $name" [get $name list]
712 }
713
714 # Running to breakpoint -- use any function we can "list"
715 foreach 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.
723 foreach cv {{} { const} { volatile} { const volatile}} {
724 set test "p 'CV::m(int)$cv'"
725 set correct dummy_value
726
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.
738 gdb_test "p CV_f(int)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
739 gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
740 gdb_test "p CV_f(CV::i)" " = 43"
741
742 gdb_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."
747 gdb_test "p base::operator const fluff * const *" \
748 [get "base::operator fluff const* const*" print] \
749 "canonicalized conversion operator name 1"
750 gdb_test "p base::operator const fluff* const*" \
751 [get "base::operator fluff const* const*" print] \
752 "canonicalized conversion operator name 2"
753 gdb_test "p base::operator derived*" \
754 "There is no field named operator derived\\*" \
755 "undefined conversion operator"
756
757 gdb_exit
758 return 0