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