xref: /netbsd-src/external/gpl3/gdb/dist/gdb/testsuite/gdb.cp/cpexprs.exp.tcl (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
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.
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.*" \
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 -
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
681if {![allow_cplus_tests]} { continue }
682
683#
684# test running programs
685#
686
687standard_testfile cpexprs.cc
688
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'"
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.
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
759