Update copyright year range in all GDB files.
[external/binutils.git] / gdb / testsuite / gdb.mi / mi-var-rtti.cc
1 /* Copyright 2012-2019 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 struct Base {
17     Base() : A(1) {}
18     virtual ~Base() {}  // Enforce type to have vtable
19     int A;
20 };
21
22 struct Derived : public Base {
23     Derived() : B(2), C(3) {}
24     int B;
25     int C;
26 };
27
28
29 void use_rtti_for_ptr_test ()
30 {
31   /*: BEGIN: use_rtti_for_ptr :*/
32         Derived d;
33         Base* ptr = &d;
34         const Base* constPtr = &d;
35         Base* const ptrConst = &d;
36         Base const* const constPtrConst = &d;
37   /*:
38         set testname use_rtti_for_ptr
39         set_print_object off $testname
40         check_new_derived_without_rtti ptr {Base \*} $testname
41         check_new_derived_without_rtti constPtr {const Base \*} $testname
42         check_new_derived_without_rtti ptrConst {Base \* const} $testname
43         check_new_derived_without_rtti constPtrConst {const Base \* const} \
44                 $testname
45
46         set_print_object on $testname
47         check_new_derived_with_rtti ptr {Derived \*} $testname
48         check_new_derived_with_rtti constPtr {const Derived \*} $testname
49         check_new_derived_with_rtti ptrConst {Derived \* const} $testname
50         check_new_derived_with_rtti constPtrConst {const Derived \* const} \
51                 $testname
52   :*/
53         return;
54   /*: END: use_rtti_for_ptr :*/
55 }
56
57
58 void use_rtti_for_ref_test ()
59 {
60   /*: BEGIN: use_rtti_for_ref :*/
61         Derived d;
62         Base& ref = d;
63         const Base& constRef = d;
64   /*: 
65         set testname use_rtti_for_ref
66         set_print_object off $testname
67         check_new_derived_without_rtti ref {Base \&} $testname
68         check_new_derived_without_rtti constRef {const Base \&} $testname
69
70         set_print_object on $testname
71         check_new_derived_with_rtti ref {Derived \&} $testname
72         check_new_derived_with_rtti constRef {const Derived \&} $testname
73   :*/
74         return;
75   /*: END: use_rtti_for_ref :*/
76 }
77
78
79 void use_rtti_for_ptr_child_test ()
80 {
81   /*: BEGIN: use_rtti_for_ptr_child :*/
82         Derived d;
83         struct S {      
84                 Base* ptr;
85                 const Base* constPtr;
86                 Base* const ptrConst;
87                 Base const* const constPtrConst;
88                 S ( Base* v ) :
89                         ptr ( v ),
90                         constPtr ( v ),
91                         ptrConst ( v ),
92                         constPtrConst ( v ) {}
93         } s ( &d );
94   /*: 
95         set testname use_rtti_for_ptr_child
96
97         set_print_object off $testname
98         mi_create_varobj VAR s "create varobj for s (without RTTI) in $testname"
99         mi_list_varobj_children VAR {
100             { VAR.public public 4 }
101         } "list children of s (without RTTI) in $testname"
102         mi_list_varobj_children VAR.public {
103             { VAR.public.ptr ptr 1 {Base \*} }
104             { VAR.public.constPtr constPtr 1 {const Base \*} }
105             { VAR.public.ptrConst ptrConst 1 {Base \* const} }
106             { VAR.public.constPtrConst constPtrConst 1 {const Base \* const} }
107         } "list children of s.public (without RTTI) in $testname"
108         check_derived_without_rtti VAR.public.ptr s.ptr $testname
109         check_derived_without_rtti VAR.public.constPtr s.constPtr $testname
110         check_derived_without_rtti VAR.public.ptrConst s.ptrConst $testname
111         check_derived_without_rtti VAR.public.constPtrConst s.constPtrConst \
112                 $testname
113         mi_delete_varobj VAR "delete varobj for s (without RTTI) in $testname"
114
115         set_print_object on $testname
116         mi_create_varobj VAR s "create varobj for s (with RTTI) in $testname"
117         mi_list_varobj_children VAR {
118             { VAR.public public 4 }
119         } "list children of s (with RTTI) in $testname"
120         mi_list_varobj_children VAR.public {
121             { VAR.public.ptr ptr 2 {Derived \*} }
122             { VAR.public.constPtr constPtr 2 {const Derived \*} }
123             { VAR.public.ptrConst ptrConst 2 {Derived \* const} }
124             { VAR.public.constPtrConst constPtrConst 2 {const Derived \* const}}
125         } "list children of s.public (with RTTI) in $testname"
126         check_derived_with_rtti VAR.public.ptr s.ptr $testname
127         check_derived_with_rtti VAR.public.constPtr s.constPtr $testname
128         check_derived_with_rtti VAR.public.ptrConst s.ptrConst $testname
129         check_derived_with_rtti VAR.public.constPtrConst s.constPtrConst \
130                 $testname
131         mi_delete_varobj VAR "delete varobj for s (with RTTI) in $testname"
132   :*/
133         return;
134   /*: END: use_rtti_for_ptr_child :*/
135 }
136
137
138 void use_rtti_for_ref_child_test ()
139 {
140   /*: BEGIN: use_rtti_for_ref_child :*/
141         Derived d;
142         struct S {      
143                 Base& ref;
144                 const Base& constRef;
145                 S ( Base& v ) :
146                         ref ( v ),
147                         constRef ( v ) {}
148         } s ( d );
149   /*: 
150         set testname use_rtti_for_ref_child
151
152         set_print_object off $testname
153         mi_create_varobj VAR s "create varobj for s (without RTTI) in $testname"
154         mi_list_varobj_children VAR {
155             { VAR.public public 2 }
156         } "list children of s (without RTTI) in $testname"
157         mi_list_varobj_children VAR.public {
158             { VAR.public.ref ref 1 {Base \&} }
159             { VAR.public.constRef constRef 1 {const Base \&} }
160         } "list children of s.public (without RTTI) in $testname"
161         check_derived_without_rtti VAR.public.ref s.ref $testname
162         check_derived_without_rtti VAR.public.constRef s.constRef  $testname
163         mi_delete_varobj VAR "delete varobj for s (without RTTI) in $testname"
164
165         set_print_object on $testname
166         mi_create_varobj VAR s "create varobj for s (with RTTI) in $testname"
167         mi_list_varobj_children VAR {
168             { VAR.public public 2 }
169         } "list children of s (with RTTI) in $testname"
170         mi_list_varobj_children VAR.public {
171             { VAR.public.ref ref 2 {Derived \&} }
172             { VAR.public.constRef constRef 2 {const Derived \&} }
173         } "list children of s.public (with RTTI) in $testname"
174         check_derived_with_rtti VAR.public.ref s.ref $testname
175         check_derived_with_rtti VAR.public.constRef s.constRef $testname
176         mi_delete_varobj VAR "delete varobj for s (with RTTI) in $testname"
177   :*/
178         return;
179   /*: END: use_rtti_for_ref_child :*/
180 }
181
182
183 struct First {
184     First() : F(-1) {}
185     int F;
186 };
187
188
189 struct MultipleDerived : public First, Base {
190     MultipleDerived() : B(2), C(3) {}
191     int B;
192     int C;
193 };
194
195
196 void use_rtti_with_multiple_inheritence_test ()
197 {
198   /*: BEGIN: use_rtti_with_multiple_inheritence :*/
199         MultipleDerived d;
200         Base* ptr = &d;
201         Base& ref = d;
202   /*:
203         set testname use_rtti_with_multiple_inheritence
204         set_print_object off $testname
205         check_new_derived_without_rtti ptr {Base \*} $testname
206         check_new_derived_without_rtti ref {Base \&} $testname
207
208         set_print_object on $testname
209         mi_create_varobj_checked VAR ptr {MultipleDerived \*} \
210             "create varobj for ptr (with RTTI) in $testname"
211         mi_list_varobj_children VAR {
212             { VAR.First First 1 First }
213             { VAR.Base Base 1 Base }
214             { VAR.public public 2 }
215         } "list children of ptr (with RTTI) in $testname"
216         mi_list_varobj_children "VAR.First" {
217             { VAR.First.public public 1 }
218         } "list children of ptr.First (with RTTI) in $testname"
219         mi_list_varobj_children "VAR.First.public" {
220             { VAR.First.public.F F 0 int }
221         } "list children of ptr.Base.public (with RTTI) in $testname"
222         mi_list_varobj_children "VAR.Base" {
223             { VAR.Base.public public 1 }
224         } "list children of ptr.Base (with RTTI) in $testname"
225         mi_list_varobj_children "VAR.Base.public" {
226             { VAR.Base.public.A A 0 int }
227         } "list children of ptr.Base.public (with RTTI) in $testname"
228         mi_list_varobj_children "VAR.public" {
229             { VAR.public.B B 0 int }
230             { VAR.public.C C 0 int }
231         } "list children of ptr.public (with RTTI) in $testname"
232
233         mi_delete_varobj VAR \
234             "delete varobj for ptr (with RTTI) in $testname"
235   :*/
236         return;
237   /*: END: use_rtti_with_multiple_inheritence :*/
238 }
239
240
241 void type_update_when_use_rtti_test ()
242 {
243   /*: BEGIN: type_update_when_use_rtti :*/
244         Base *ptr = 0;
245         struct S {
246                 Base* ptr;
247                 S ( Base* v ) :
248                         ptr ( v ) {}
249         } s ( ptr );
250         Derived d;
251   /*: 
252         set testname type_update_when_use_rtti
253
254         set_print_object on $testname
255         mi_create_varobj_checked PTR ptr {Base \*} \
256                 "create varobj for ptr in $testname"
257         check_derived_children_without_rtti PTR ptr $testname
258
259         mi_create_varobj S s "create varobj for S in $testname"
260         mi_list_varobj_children S {
261             { S.public public 1 }
262         } "list children of s in $testname"
263         mi_list_varobj_children S.public {
264             { S.public.ptr ptr 1 {Base \*} }
265         } "list children of s.public in $testname"
266         check_derived_children_without_rtti S.public.ptr s.ptr $testname
267   :*/
268
269         ptr = &d;
270         s.ptr = &d;
271   /*:
272         mi_varobj_update_with_type_change PTR {Derived \*} 2 \
273                 "update ptr to derived in $testname"
274         check_derived_with_rtti PTR ptr $testname
275
276         mi_varobj_update_with_child_type_change S S.public.ptr {Derived \*} 2 \
277                 "update s.ptr to derived in $testname"
278         check_derived_with_rtti S.public.ptr s.ptr $testname
279   :*/
280
281         ptr = 0;
282         s.ptr = 0;
283   /*:
284         mi_varobj_update_with_type_change PTR {Base \*} 1 \
285                 "update ptr back to base type in $testname"
286         mi_delete_varobj PTR "delete varobj for ptr in $testname"
287
288         mi_varobj_update_with_child_type_change S S.public.ptr {Base \*} 1 \
289                 "update s.ptr back to base type in $testname"
290         mi_delete_varobj S "delete varobj for s in $testname"
291   :*/
292         return;
293   /*: END: type_update_when_use_rtti :*/
294 }
295
296
297 void skip_type_update_when_not_use_rtti_test ()
298 {
299   /*: BEGIN: skip_type_update_when_not_use_rtti :*/
300         Base *ptr = 0;
301         struct S {
302                 Base* ptr;
303                 S ( Base* v ) :
304                         ptr ( v ) {}
305         } s ( ptr );
306         Derived d;
307   /*: 
308         set testname skip_type_update_when_not_use_rtti
309
310         set_print_object off $testname
311         mi_create_varobj_checked PTR ptr {Base \*} \
312                 "create varobj for ptr in $testname"
313         check_derived_children_without_rtti PTR ptr $testname
314
315         mi_create_varobj S s "create varobj for S in $testname"
316         mi_list_varobj_children S {
317             { S.public public 1 }
318         } "list children of s in $testname"
319         mi_list_varobj_children S.public {
320             { S.public.ptr ptr 1 {Base \*} }
321         } "list children of s.public in $testname"
322         check_derived_children_without_rtti S.public.ptr s.ptr $testname
323   :*/
324
325         ptr = &d;
326         s.ptr = &d;
327   /*: 
328         mi_varobj_update PTR {PTR PTR.public.A} \
329                 "update ptr to derived type in $testname"
330         check_derived_without_rtti PTR ptr $testname
331
332         mi_varobj_update S {S.public.ptr S.public.ptr.public.A} \
333                 "update s to derived type in $testname"
334         check_derived_without_rtti S.public.ptr s.ptr $testname
335   :*/
336
337         ptr = 0;
338         s.ptr = 0;
339   /*:
340         mi_varobj_update PTR {PTR  PTR.public.A} \
341                 "update ptr back to base type in $testname"
342         mi_delete_varobj PTR "delete varobj for ptr in $testname"
343
344         mi_varobj_update S {S.public.ptr S.public.ptr.public.A} \
345                 "update s back to base type in $testname"
346         mi_delete_varobj S "delete varobj for s in $testname"
347   :*/
348         return;
349   /*: END: skip_type_update_when_not_use_rtti :*/
350 }
351
352
353 int main ()
354 {
355         use_rtti_for_ptr_test();
356         use_rtti_for_ref_test();
357         use_rtti_for_ptr_child_test();
358         use_rtti_for_ref_child_test();
359         use_rtti_with_multiple_inheritence_test();
360         type_update_when_use_rtti_test();
361         skip_type_update_when_not_use_rtti_test();
362         return 0;
363 }