1/* Copyright 2012-2020 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
16struct Base {
17    Base() : A(1) {}
18    virtual ~Base() {}  // Enforce type to have vtable
19    int A;
20};
21
22struct Derived : public Base {
23    Derived() : B(2), C(3) {}
24    int B;
25    int C;
26};
27
28
29void 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
58void 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
79void 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
138void 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
183struct First {
184    First() : F(-1) {}
185    int F;
186};
187
188
189struct MultipleDerived : public First, Base {
190    MultipleDerived() : B(2), C(3) {}
191    int B;
192    int C;
193};
194
195
196void 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
241void 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
297void 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
353int 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}
364