1 # cpexprs.exp - C++ expressions tests
3 # Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
5 # Contributed by Red Hat, originally written by Keith Seitz.
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.
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.
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/>.
20 # This file is part of the gdb testsuite.
22 # A helper proc which sets a breakpoint at FUNC and attempts to
23 # run to the breakpoint.
24 proc test_breakpoint {func} {
27 # Return to the top of the test function every time.
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.*" \
34 fail "continue to test_function for $func"
36 gdb_breakpoint "$func"
37 set i [expr {[string last : $func] + 1}]
38 set efunc [string_to_regexp [string range $func $i end]]
40 "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
45 # Add a function to the list of tested functions
46 # FUNC is the name of the function (which will be passed to gdb commands)
47 # TYPE is the type of the function, as expected from the "print" command
48 # PRINT is the name of the function, as expected result of the print command
49 # *OR* "-", indicating that FUNC should be used (needed for virtual/inherited
51 # LST is either the expected result of the list command (the comment from
52 # the source code) *OR* "-", in which case FUNC will be used
55 # add NAME TYPE PRINT LST
56 # add NAME TYPE PRINT -
57 proc add {func type print lst} {
58 global all_functions CONVAR ADDR
60 set all_functions($func,type) $type
65 # An exception: since gdb canonicalizes C++ output,
66 # "(void)" must be mutated to "()".
67 regsub {\(void\)} $print {()} print
69 set all_functions($func,print) \
70 "$CONVAR = {[string_to_regexp $type]} $ADDR <[string_to_regexp $print].*>"
74 set all_functions($func,list) ".*// [string_to_regexp $lst]"
79 return $all_functions($func,$cmd)
82 # Returns a list of function names for a given command
83 proc get_functions {cmd} {
86 foreach i [array names all_functions *,$cmd] {
87 if {$all_functions($i) != ""} {
88 set idx [string last , $i]
90 lappend result [string range $i 0 [expr {$idx - 1}]]
95 return [lsort $result]
98 # Some convenience variables for this test
99 set DEC {[0-9]}; # a decimal number
100 set HEX {[0-9a-fA-F]}; # a hexidecimal number
101 set CONVAR "\\\$$DEC+"; # convenience variable regexp
102 set ADDR "0x$HEX+"; # address
104 # An array of functions/methods that we are testing...
105 # Each element consists is indexed by NAME,COMMAND, where
106 # NAME is the function name and COMMAND is the gdb command that
107 # we are testing. The value of the array for any index pair is
108 # the expected result of running COMMAND with the NAME as argument.
110 # The array holding all functions/methods to test. Valid subindexes
111 # are (none need character escaping -- "add" will take care of that):
113 # add name type print_name list
114 # NAME,type: value is type of function
115 # NAME,print: value is print name of function (careful w/inherited/virtual!)
116 # NAME,list: value is comment in source code on first line of function
117 # (without the leading "//")
118 array set all_functions {}
120 # "Normal" functions/methods
121 add {test_function} \
122 {int (int, char **)} \
125 add {derived::a_function} \
126 {void (const derived * const)} \
129 add {base1::a_function} \
130 {void (const base1 * const)} \
133 add {base2::a_function} \
134 {void (const base2 * const)} \
140 # On targets using the ARM EABI, the constructor is expected to return
142 proc ctor { type arglist } {
143 if { [istarget arm*-*eabi*] } {
148 if { $arglist != "" } {
149 set arglist ", $arglist"
151 return "${ret}($type * const$arglist)"
154 add {derived::derived} \
158 add {base1::base1(void)} \
159 [ctor base1 "const void ** const"] \
162 add {base1::base1(int)} \
167 [ctor base2 "const void ** const"] \
170 add {base::base(void)} \
174 add {base::base(int)} \
181 # On targets using the ARM EABI, some destructors are expected
182 # to return "this". Others are void. For internal reasons,
183 # GCC returns void * instead of $type *; RealView appears to do
186 if { [istarget arm*-*eabi*] } {
191 return "${ret}($type * const)"
199 # Overloaded methods (all are const -- we try to use the void
200 # method with and without specifying "const")
201 add {base::overload(void)} \
202 {int (const base * const)} \
204 {base::overload(void) const}
205 add {base::overload(void) const} \
206 {int (const base * const)} \
208 {base::overload(void) const}
209 add {base::overload(int) const} \
210 {int (const base * const, int)} \
213 add {base::overload(short) const} \
214 {int (const base * const, short)} \
217 add {base::overload(long) const} \
218 {int (const base * const, long)} \
221 add {base::overload(char*) const} \
222 {int (const base * const, char *)} \
225 add {base::overload(base&) const} \
226 {int (const base * const, base &)} \
231 add {base::operator+} \
232 {int (const base * const, const base &)} \
235 add {base::operator++} \
236 {base (base * const)} \
239 add {base::operator+=} \
240 {base (base * const, const base &)} \
243 add {base::operator-} \
244 {int (const base * const, const base &)} \
247 add {base::operator--} \
248 {base (base * const)} \
251 add {base::operator-=} \
252 {base (base * const, const base &)} \
255 add {base::operator*} \
256 {int (const base * const, const base &)} \
259 add {base::operator*=} \
260 {base (base * const, const base &)} \
263 add {base::operator/} \
264 {int (const base * const, const base &)} \
267 add {base::operator/=} \
268 {base (base * const, const base &)} \
271 add {base::operator%} \
272 {int (const base * const, const base &)} \
275 add {base::operator%=} \
276 {base (base * const, const base &)} \
279 add {base::operator<} \
280 {bool (const base * const, const base &)} \
283 add {base::operator<=} \
284 {bool (const base * const, const base &)} \
287 add {base::operator>} \
288 {bool (const base * const, const base &)} \
291 add {base::operator>=} \
292 {bool (const base * const, const base &)} \
295 add {base::operator!=} \
296 {bool (const base * const, const base &)} \
299 add {base::operator==} \
300 {bool (const base * const, const base &)} \
303 add {base::operator!} \
304 {bool (const base * const)} \
307 add {base::operator&&} \
308 {bool (const base * const, const base &)} \
311 add {base::operator||} \
312 {bool (const base * const, const base &)} \
315 add {base::operator<<} \
316 {int (const base * const, int)} \
319 add {base::operator<<=} \
320 {base (base * const, int)} \
323 add {base::operator>>} \
324 {int (const base * const, int)} \
327 add {base::operator>>=} \
328 {base (base * const, int)} \
331 add {base::operator~} \
332 {int (const base * const)} \
335 add {base::operator&} \
336 {int (const base * const, const base &)} \
339 add {base::operator&=} \
340 {base (base * const, const base &)} \
343 add {base::operator|} \
344 {int (const base * const, const base &)} \
347 add {base::operator|=} \
348 {base (base * const, const base &)} \
351 add {base::operator^} \
352 {int (const base * const, const base &)} \
355 add {base::operator^=} \
356 {base (base * const, const base &)} \
359 add {base::operator=} \
360 {base (base * const, const base &)} \
363 add {base::operator()} \
364 {void (const base * const)} \
367 add {base::operator[]} \
368 {int (const base * const, int)} \
371 add {base::operator new} \
375 add {base::operator delete} \
379 add {base::operator new[]} \
383 add {base::operator delete[]} \
387 add {base::operator char*} \
388 {char *(const base * const)} \
391 add {base::operator fluff*} \
392 {fluff *(const base * const)} \
395 add {base::operator fluff**} \
396 {fluff **(const base * const)} \
399 add {base::operator int} \
400 {int (const base * const)} \
405 add {tclass<char>::do_something} \
406 {void (tclass<char> * const)} \
409 add {tclass<int>::do_something} \
410 {void (tclass<int> * const)} \
413 add {tclass<long>::do_something} \
414 {void (tclass<long> * const)} \
417 add {tclass<short>::do_something} \
418 {void (tclass<short> * const)} \
421 add {tclass<base>::do_something} \
422 {void (tclass<base> * const)} \
425 add {flubber<int, int, int, int, int>} \
429 add {flubber<int, int, int, int, short>} \
433 add {flubber<int, int, int, int, long>} \
437 add {flubber<int, int, int, int, char>} \
441 add {flubber<int, int, int, short, int>} \
445 add {flubber<int, int, int, short, short>} \
449 add {flubber<int, int, int, short, long>} \
453 add {flubber<int, int, int, short, char>} \
457 add {flubber<int, int, int, long, int>} \
461 add {flubber<int, int, int, long, short>} \
465 add {flubber<int, int, int, long, long>} \
469 add {flubber<int, int, int, long, char>} \
473 add {flubber<int, int, int, char, int>} \
477 add {flubber<int, int, int, char, short>} \
481 add {flubber<int, int, int, char, long>} \
485 add {flubber<int, int, int, char, char>} \
489 add {flubber<int, int, short, int, int>} \
493 add {flubber<int, int, short, int, short>} \
497 add {flubber<int, int, short, int, long>} \
501 add {flubber<int, int, short, int, char>} \
505 add {flubber<int, int, short, short, int>} \
509 add {flubber<short, int, short, int, short>} \
513 add {flubber<long, short, long, short, long>} \
517 add {tclass<base>::do_something} \
518 {void (tclass<base> * const)} \
520 {tclass<T>::do_something}
521 add {policy1::policy} \
522 [ctor "policy<int, operation_1<void*> >" "int"] \
523 {policy<int, operation_1<void*> >::policy} \
524 {policy<T, Policy>::policy}
525 add {policy2::policy} \
526 [ctor "policy<int, operation_2<void*> >" int] \
527 {policy<int, operation_2<void*> >::policy} \
528 {policy<T, Policy>::policy}
529 add {policy3::policy} \
530 [ctor "policy<int, operation_3<void*> >" "int"] \
531 {policy<int, operation_3<void*> >::policy} \
532 {policy<T, Policy>::policy}
533 add {policy4::policy} \
534 [ctor "policy<int, operation_4<void*> >" "int"] \
535 {policy<int, operation_4<void*> >::policy} \
536 {policy<T, Policy>::policy}
537 add {policy1::function} \
539 {operation_1<void*>::function} \
540 {operation_1<T>::function}
541 add {policy2::function} \
543 {operation_2<void*>::function} \
544 {operation_2<T>::function}
545 add {policy3::function} \
547 {operation_3<void*>::function} \
548 {operation_3<T>::function}
549 add {policy4::function} \
551 {operation_4<void*>::function} \
552 {operation_4<T>::function}
553 add {policyd<int, operation_1<int> >::policyd} \
554 [ctor "policyd<int, operation_1<int> >" "int"] \
556 {policyd<T, Policy>::policyd}
557 add {policyd1::policyd} \
558 [ctor "policyd<int, operation_1<int> >" "int"] \
559 {policyd<int, operation_1<int> >::policyd} \
560 {policyd<T, Policy>::policyd}
561 add {policyd<int, operation_1<int> >::~policyd} \
562 [dtor "policyd<int, operation_1<int> >"] \
564 {policyd<T, Policy>::~policyd}
565 add {policyd1::~policyd} \
566 [dtor "policyd<int, operation_1<int> >"] \
567 {policyd<int, operation_1<int> >::~policyd} \
568 {policyd<T, Policy>::~policyd}
569 add {policyd<long, operation_1<long> >::policyd} \
570 [ctor "policyd<long, operation_1<long> >" "long"] \
572 {policyd<T, Policy>::policyd}
573 add {policyd2::policyd} \
574 [ctor "policyd<long, operation_1<long> >" "long"] \
575 {policyd<long, operation_1<long> >::policyd} \
576 {policyd<T, Policy>::policyd}
577 add {policyd<long, operation_1<long> >::~policyd} \
578 [dtor "policyd<long, operation_1<long> >"] \
580 {policyd<T, Policy>::~policyd}
581 add {policyd2::~policyd} \
582 [dtor "policyd<long, operation_1<long> >"] \
583 {policyd<long, operation_1<long> >::~policyd} \
584 {policyd<T, Policy>::~policyd}
585 add {policyd<char, operation_1<char> >::policyd} \
586 [ctor "policyd<char, operation_1<char> >" "char"] \
588 {policyd<T, Policy>::policyd}
589 add {policyd3::policyd} \
590 [ctor "policyd<char, operation_1<char> >" "char"] \
591 {policyd<char, operation_1<char> >::policyd} \
592 {policyd<T, Policy>::policyd}
593 add {policyd<char, operation_1<char> >::~policyd} \
594 [dtor "policyd<char, operation_1<char> >"] \
596 {policyd<T, Policy>::~policyd}
597 add {policyd3::~policyd} \
598 [dtor "policyd<char, operation_1<char> >"] \
599 {policyd<char, operation_1<char> >::~policyd} \
600 {policyd<T, Policy>::~policyd}
601 add {policyd<base, operation_1<base> >::policyd} \
602 [ctor "policyd<base, operation_1<base> >" "base"] \
604 {policyd<T, Policy>::policyd}
605 add {policyd4::policyd} \
606 [ctor "policyd<base, operation_1<base> >" "base"] \
607 {policyd<base, operation_1<base> >::policyd} \
608 {policyd<T, Policy>::policyd}
609 add {policyd<base, operation_1<base> >::~policyd} \
610 [dtor "policyd<base, operation_1<base> >"] \
612 {policyd<T, Policy>::~policyd}
613 add {policyd4::~policyd} \
614 [dtor "policyd<base, operation_1<base> >"] \
615 {policyd<base, operation_1<base> >::~policyd} \
616 {policyd<T, Policy>::~policyd}
617 add {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
618 [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
620 {policyd<T, Policy>::policyd}
621 add {policyd5::policyd} \
622 [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
623 {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
624 {policyd<T, Policy>::policyd}
625 add {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
626 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
628 {policyd<T, Policy>::~policyd}
629 add {policyd5::~policyd} \
630 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
631 {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
632 {policyd<T, Policy>::~policyd}
633 add {policyd<int, operation_1<int> >::function} \
635 {operation_1<int>::function}\
636 {operation_1<T>::function}
637 add {policyd1::function} \
639 {operation_1<int>::function} \
640 {operation_1<T>::function}
641 add {policyd2::function} \
643 {operation_1<long>::function} \
644 {operation_1<T>::function}
645 add {policyd<char, operation_1<char> >::function} \
647 {operation_1<char>::function} \
648 {operation_1<T>::function}
649 add {policyd3::function} \
651 {operation_1<char>::function} \
652 {operation_1<T>::function}
653 add {policyd<base, operation_1<base> >::function} \
655 {operation_1<base>::function} \
656 {operation_1<T>::function}
657 add {policyd4::function} \
659 {operation_1<base>::function} \
660 {operation_1<T>::function}
661 add {policyd<tclass<int>, operation_1<tclass<int> > >::function} \
663 {operation_1<tclass<int> >::function} \
664 {operation_1<T>::function}
665 add {policyd5::function} \
667 {operation_1<tclass<int> >::function} \
668 {operation_1<T>::function}
675 if {[skip_cplus_tests]} { continue }
677 # On SPU this test fails because the executable exceeds local storage size.
678 if { [istarget "spu*-*-*"] } {
683 # test running programs
686 set testfile "cpexprs"
687 set srcfile "${testfile}.cc"
688 set binfile [file join $objdir $subdir $testfile]
690 if {[gdb_compile [file join $srcdir $subdir $srcfile] $binfile \
691 executable {debug c++}] != "" } {
692 untested "$testfile.exp"
696 if {[get_compiler_info $binfile "c++"]} {
702 gdb_reinitialize_dir [file join $srcdir $subdir]
706 perror "couldn't run to breakpoint"
710 # Set the listsize to one. This will help with testing "list".
711 gdb_test "set listsize 1"
714 foreach name [get_functions print] {
715 gdb_test "print $name" [get $name print] "print $name"
719 foreach name [get_functions list] {
720 gdb_test "list $name" [get $name list] "list $name"
723 # Running to breakpoint -- use any function we can "list"
724 foreach name [get_functions list] {
725 # Skip "test_function", since test_breakpoint uses it
726 if {[string compare $name "test_function"] != 0} {
727 test_breakpoint $name