cxxabi.h: New header file.
[gcc.git] / gcc / cp / rtti.c
1 /* RunTime Type Identification
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
4 Mostly written by Jason Merrill (jason@cygnus.com).
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "tree.h"
27 #include "cp-tree.h"
28 #include "flags.h"
29 #include "output.h"
30 #include "assert.h"
31 #include "toplev.h"
32
33 #ifndef INT_TYPE_SIZE
34 #define INT_TYPE_SIZE BITS_PER_WORD
35 #endif
36
37 /* Accessors for the type_info objects. We need to remember several things
38 about each of the type_info types. The global tree nodes such as
39 bltn_desc_type_node are TREE_LISTs, and these macros are used to access
40 the required information. */
41 /* The RECORD_TYPE of a type_info derived class. */
42 #define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
43 /* The VAR_DECL of the vtable for the type_info derived class. */
44 #define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
45
46 extern struct obstack permanent_obstack;
47
48 static tree build_headof_sub PARAMS((tree));
49 static tree build_headof PARAMS((tree));
50 static tree get_tinfo_var PARAMS((tree));
51 static tree ifnonnull PARAMS((tree, tree));
52 static tree tinfo_name PARAMS((tree));
53 static tree get_base_offset PARAMS((tree, tree));
54 static tree build_dynamic_cast_1 PARAMS((tree, tree));
55 static void expand_si_desc PARAMS((tree, tree));
56 static void expand_class_desc PARAMS((tree, tree));
57 static void expand_attr_desc PARAMS((tree, tree));
58 static void expand_ptr_desc PARAMS((tree, tree));
59 static void expand_generic_desc PARAMS((tree, tree, const char *));
60 static tree throw_bad_cast PARAMS((void));
61 static tree throw_bad_typeid PARAMS((void));
62 static tree get_tinfo_decl_dynamic PARAMS((tree));
63 static tree tinfo_from_decl PARAMS((tree));
64 static int qualifier_flags PARAMS((tree));
65 static tree tinfo_base_init PARAMS((tree, tree));
66 static tree generic_initializer PARAMS((tree, tree));
67 static tree ptr_initializer PARAMS((tree, tree));
68 static tree ptmd_initializer PARAMS((tree, tree));
69 static int class_hint_flags PARAMS((tree));
70 static tree class_initializer PARAMS((tree, tree, tree));
71 static tree synthesize_tinfo_var PARAMS((tree, tree));
72 static tree create_real_tinfo_var PARAMS((tree, tree, tree));
73 static tree create_pseudo_type_info PARAMS((const char *, int, ...));
74 static tree get_vmi_pseudo_type_info PARAMS((int));
75 static void create_tinfo_types PARAMS((void));
76
77 static int doing_runtime = 0;
78 \f
79 void
80 init_rtti_processing ()
81 {
82 if (flag_honor_std)
83 push_namespace (get_identifier ("std"));
84 type_info_type_node = xref_tag
85 (class_type_node, get_identifier ("type_info"), 1);
86 if (flag_honor_std)
87 pop_namespace ();
88 if (!new_abi_rtti_p ())
89 {
90 tinfo_decl_id = get_identifier ("__tf");
91 tinfo_decl_type = build_function_type
92 (build_reference_type
93 (build_qualified_type
94 (type_info_type_node, TYPE_QUAL_CONST)),
95 void_list_node);
96 }
97 else
98 {
99 tinfo_decl_id = get_identifier ("__ti");
100 tinfo_decl_type = build_qualified_type
101 (type_info_type_node, TYPE_QUAL_CONST);
102 }
103 tinfo_var_id = get_identifier ("__ti");
104 }
105
106 /* Given a pointer to an object with at least one virtual table
107 pointer somewhere, return a pointer to a possible sub-object that
108 has a virtual table pointer in it that is the vtable parent for
109 that sub-object. */
110
111 static tree
112 build_headof_sub (exp)
113 tree exp;
114 {
115 tree type = TREE_TYPE (TREE_TYPE (exp));
116 tree basetype = CLASSTYPE_RTTI (type);
117 tree binfo = get_binfo (basetype, type, 0);
118
119 exp = convert_pointer_to_real (binfo, exp);
120 return exp;
121 }
122
123 /* Given the expression EXP of type `class *', return the head of the
124 object pointed to by EXP with type cv void*, if the class has any
125 virtual functions (TYPE_POLYMORPHIC_P), else just return the
126 expression. */
127
128 static tree
129 build_headof (exp)
130 tree exp;
131 {
132 tree type = TREE_TYPE (exp);
133 tree aref;
134 tree offset;
135
136 my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
137 type = TREE_TYPE (type);
138
139 if (!TYPE_POLYMORPHIC_P (type))
140 return exp;
141 if (CLASSTYPE_COM_INTERFACE (type))
142 {
143 cp_error ("RTTI not supported for COM interface type `%T'", type);
144 return error_mark_node;
145 }
146
147 /* If we don't have rtti stuff, get to a sub-object that does. */
148 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
149 exp = build_headof_sub (exp);
150
151 /* We use this a couple of times below, protect it. */
152 exp = save_expr (exp);
153
154 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
155
156 if (flag_vtable_thunks)
157 offset = aref;
158 else
159 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
160
161 type = build_qualified_type (ptr_type_node,
162 CP_TYPE_QUALS (TREE_TYPE (exp)));
163 return build (PLUS_EXPR, type, exp,
164 cp_convert (ptrdiff_type_node, offset));
165 }
166
167 /* Get a bad_cast node for the program to throw...
168
169 See libstdc++/exception.cc for __throw_bad_cast */
170
171 static tree
172 throw_bad_cast ()
173 {
174 tree fn = get_identifier ("__throw_bad_cast");
175 if (IDENTIFIER_GLOBAL_VALUE (fn))
176 fn = IDENTIFIER_GLOBAL_VALUE (fn);
177 else
178 fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
179 void_list_node));
180
181 return build_call (fn, NULL_TREE);
182 }
183
184 static tree
185 throw_bad_typeid ()
186 {
187 tree fn = get_identifier ("__throw_bad_typeid");
188 if (IDENTIFIER_GLOBAL_VALUE (fn))
189 fn = IDENTIFIER_GLOBAL_VALUE (fn);
190 else
191 {
192 tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
193 t = build_function_type (build_reference_type (t), void_list_node);
194 fn = push_throw_library_fn (fn, t);
195 }
196
197 return build_call (fn, NULL_TREE);
198 }
199 \f
200 /* Return a pointer to type_info function associated with the expression EXP.
201 If EXP is a reference to a polymorphic class, return the dynamic type;
202 otherwise return the static type of the expression. */
203
204 static tree
205 get_tinfo_decl_dynamic (exp)
206 tree exp;
207 {
208 tree type;
209
210 if (exp == error_mark_node)
211 return error_mark_node;
212
213 type = TREE_TYPE (exp);
214
215 /* peel back references, so they match. */
216 if (TREE_CODE (type) == REFERENCE_TYPE)
217 type = TREE_TYPE (type);
218
219 /* Peel off cv qualifiers. */
220 type = TYPE_MAIN_VARIANT (type);
221
222 if (type != void_type_node)
223 type = complete_type_or_else (type, exp);
224
225 if (!type)
226 return error_mark_node;
227
228 /* If exp is a reference to polymorphic type, get the real type_info. */
229 if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
230 {
231 /* build reference to type_info from vtable. */
232 tree t;
233
234 if (! flag_rtti)
235 error ("taking dynamic typeid of object with -fno-rtti");
236 if (CLASSTYPE_COM_INTERFACE (type))
237 {
238 cp_error ("RTTI not supported for COM interface type `%T'", type);
239 return error_mark_node;
240 }
241
242 /* If we don't have rtti stuff, get to a sub-object that does. */
243 if (! CLASSTYPE_VFIELDS (type))
244 {
245 exp = build_unary_op (ADDR_EXPR, exp, 0);
246 exp = build_headof_sub (exp);
247 exp = build_indirect_ref (exp, NULL_PTR);
248 }
249
250 if (flag_vtable_thunks)
251 t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
252 else
253 t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
254 TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
255 return t;
256 }
257
258 /* otherwise return the type_info for the static type of the expr. */
259 exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
260 return build_unary_op (ADDR_EXPR, exp, 0);
261 }
262
263 tree
264 build_typeid (exp)
265 tree exp;
266 {
267 tree cond = NULL_TREE;
268 int nonnull = 0;
269
270 if (! flag_rtti)
271 {
272 error ("cannot use typeid with -fno-rtti");
273 return error_mark_node;
274 }
275
276 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
277 {
278 error ("must #include <typeinfo> before using typeid");
279 return error_mark_node;
280 }
281
282 if (processing_template_decl)
283 return build_min_nt (TYPEID_EXPR, exp);
284
285 if (TREE_CODE (exp) == INDIRECT_REF
286 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
287 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
288 && ! resolves_to_fixed_type_p (exp, &nonnull)
289 && ! nonnull)
290 {
291 exp = stabilize_reference (exp);
292 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
293 }
294
295 exp = get_tinfo_decl_dynamic (exp);
296
297 if (exp == error_mark_node)
298 return error_mark_node;
299
300 exp = tinfo_from_decl (exp);
301
302 if (cond)
303 {
304 tree bad = throw_bad_typeid ();
305
306 exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
307 }
308
309 return convert_from_reference (exp);
310 }
311
312 static tree
313 get_tinfo_var (type)
314 tree type;
315 {
316 tree tname = build_overload_with_type (tinfo_var_id, type);
317 tree arrtype;
318 int size;
319
320 my_friendly_assert (!new_abi_rtti_p (), 20000118);
321 if (IDENTIFIER_GLOBAL_VALUE (tname))
322 return IDENTIFIER_GLOBAL_VALUE (tname);
323
324 /* Figure out how much space we need to allocate for the type_info object.
325 If our struct layout or the type_info classes are changed, this will
326 need to be modified. */
327 if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
328 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
329 else if (TREE_CODE (type) == POINTER_TYPE
330 && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
331 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
332 size = 3 * POINTER_SIZE;
333 else if (IS_AGGR_TYPE (type))
334 {
335 if (CLASSTYPE_N_BASECLASSES (type) == 0)
336 size = 2 * POINTER_SIZE;
337 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
338 && (TREE_VIA_PUBLIC
339 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
340 size = 3 * POINTER_SIZE;
341 else
342 size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
343 }
344 else
345 size = 2 * POINTER_SIZE;
346
347 /* The type for a character array of the appropriate size. */
348 arrtype = build_cplus_array_type
349 (unsigned_char_type_node,
350 build_index_type (size_int (size / BITS_PER_UNIT - 1)));
351
352 return declare_global_var (tname, arrtype);
353 }
354
355 /* Generate the NTBS name of a type. */
356 static tree
357 tinfo_name (type)
358 tree type;
359 {
360 const char *name = build_overload_name (type, 1, 1);
361 tree name_string = combine_strings (build_string (strlen (name) + 1, name));
362 return name_string;
363 }
364
365 /* Returns a decl for a function or variable which can be used to obtain a
366 type_info object for TYPE. The old-abi uses functions, the new-abi
367 uses the type_info object directly. You can take the address of the
368 returned decl, to save the decl. To use the decl call
369 tinfo_from_decl. You must arrange that the decl is mark_used, if
370 actually use it --- decls in vtables are only used if the vtable is
371 output. */
372
373 tree
374 get_tinfo_decl (type)
375 tree type;
376 {
377 tree name;
378 tree d;
379
380 if (TREE_CODE (type) == OFFSET_TYPE)
381 type = TREE_TYPE (type);
382 if (TREE_CODE (type) == METHOD_TYPE)
383 type = build_function_type (TREE_TYPE (type),
384 TREE_CHAIN (TYPE_ARG_TYPES (type)));
385
386 name = build_overload_with_type (tinfo_decl_id, type);
387
388 d = IDENTIFIER_GLOBAL_VALUE (name);
389 if (d)
390 /* OK */;
391 else if (!new_abi_rtti_p ())
392 {
393 /* The tinfo decl is a function returning a reference to the type_info
394 object. */
395 d = push_library_fn (name, tinfo_decl_type);
396 DECL_NOT_REALLY_EXTERN (d) = 1;
397 SET_DECL_TINFO_FN_P (d);
398 TREE_TYPE (name) = type;
399 mark_inline_for_output (d);
400 }
401 else
402 {
403 /* The tinfo decl is the type_info object itself. We make all
404 tinfo objects look as type_info, even though they will end up
405 being a subclass of that when emitted. This means the we'll
406 erroneously think we know the dynamic type -- be careful in the
407 runtime. */
408 d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
409
410 DECL_ARTIFICIAL (d) = 1;
411 DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
412 TREE_READONLY (d) = 1;
413 TREE_STATIC (d) = 1;
414 DECL_EXTERNAL (d) = 1;
415 TREE_PUBLIC (d) = 1;
416 DECL_ASSEMBLER_NAME (d) = DECL_NAME (d);
417 cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
418
419 pushdecl_top_level (d);
420 /* Remember the type it is for. */
421 TREE_TYPE (name) = type;
422 }
423 return d;
424 }
425
426 /* Given an expr produced by get_tinfo_decl, return an expr which
427 produces a reference to the type_info object. */
428
429 static tree
430 tinfo_from_decl (expr)
431 tree expr;
432 {
433 tree t;
434
435 if (!new_abi_rtti_p ())
436 t = build_call (expr, NULL_TREE);
437 else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
438 t = build_indirect_ref (expr, NULL);
439 else
440 t = expr;
441
442 return t;
443 }
444
445 tree
446 get_typeid_1 (type)
447 tree type;
448 {
449 tree t;
450
451 t = get_tinfo_decl (type);
452 t = tinfo_from_decl (t);
453 return convert_from_reference (t);
454 }
455
456 /* Return the type_info object for TYPE. */
457
458 tree
459 get_typeid (type)
460 tree type;
461 {
462 if (type == error_mark_node)
463 return error_mark_node;
464
465 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
466 {
467 error ("must #include <typeinfo> before using typeid");
468 return error_mark_node;
469 }
470
471 if (processing_template_decl)
472 return build_min_nt (TYPEID_EXPR, type);
473
474 /* If the type of the type-id is a reference type, the result of the
475 typeid expression refers to a type_info object representing the
476 referenced type. */
477 if (TREE_CODE (type) == REFERENCE_TYPE)
478 type = TREE_TYPE (type);
479
480 /* The top-level cv-qualifiers of the lvalue expression or the type-id
481 that is the operand of typeid are always ignored. */
482 type = TYPE_MAIN_VARIANT (type);
483
484 if (type != void_type_node)
485 type = complete_type_or_else (type, NULL_TREE);
486
487 if (!type)
488 return error_mark_node;
489
490 return get_typeid_1 (type);
491 }
492
493 /* Check whether TEST is null before returning RESULT. If TEST is used in
494 RESULT, it must have previously had a save_expr applied to it. */
495
496 static tree
497 ifnonnull (test, result)
498 tree test, result;
499 {
500 return build (COND_EXPR, TREE_TYPE (result),
501 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
502 cp_convert (TREE_TYPE (result), integer_zero_node),
503 result);
504 }
505
506 /* Generate the constant expression describing where direct base BINFO
507 appears within the PARENT. How to interpret this expression depends on
508 details of the ABI, which the runtime must be aware of. */
509
510 static tree
511 get_base_offset (binfo, parent)
512 tree binfo;
513 tree parent;
514 {
515 tree offset;
516
517 if (!TREE_VIA_VIRTUAL (binfo))
518 offset = BINFO_OFFSET (binfo);
519 else if (!vbase_offsets_in_vtable_p ())
520 {
521 tree t = BINFO_TYPE (binfo);
522 const char *name;
523 tree field;
524
525 FORMAT_VBASE_NAME (name, t);
526 field = lookup_field (parent, get_identifier (name), 0, 0);
527 offset = size_binop (FLOOR_DIV_EXPR, bit_position (field),
528 bitsize_int (BITS_PER_UNIT));
529 offset = convert (sizetype, offset);
530 }
531 else
532 {
533 /* Under the new ABI, we store the vtable offset at which
534 the virtual base offset can be found. */
535 tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), parent);
536 offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
537 }
538 return offset;
539 }
540
541 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
542 paper. */
543
544 static tree
545 build_dynamic_cast_1 (type, expr)
546 tree type, expr;
547 {
548 enum tree_code tc = TREE_CODE (type);
549 tree exprtype;
550 tree dcast_fn;
551 tree old_expr = expr;
552 char* errstr = NULL;
553
554 /* T shall be a pointer or reference to a complete class type, or
555 `pointer to cv void''. */
556 switch (tc)
557 {
558 case POINTER_TYPE:
559 if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
560 break;
561 case REFERENCE_TYPE:
562 if (! IS_AGGR_TYPE (TREE_TYPE (type)))
563 {
564 errstr = "target is not pointer or reference to class";
565 goto fail;
566 }
567 if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
568 {
569 errstr = "target is not pointer or reference to complete type";
570 goto fail;
571 }
572 break;
573
574 default:
575 errstr = "target is not pointer or reference";
576 goto fail;
577 }
578
579 if (TREE_CODE (expr) == OFFSET_REF)
580 expr = resolve_offset_ref (expr);
581
582 exprtype = TREE_TYPE (expr);
583 assert (exprtype != NULL_TREE);
584
585 if (tc == POINTER_TYPE)
586 expr = convert_from_reference (expr);
587 else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
588 {
589 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
590 exprtype = build_reference_type (exprtype);
591 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
592 LOOKUP_NORMAL, NULL_TREE);
593 }
594
595 exprtype = TREE_TYPE (expr);
596
597 if (tc == POINTER_TYPE)
598 {
599 /* If T is a pointer type, v shall be an rvalue of a pointer to
600 complete class type, and the result is an rvalue of type T. */
601
602 if (TREE_CODE (exprtype) != POINTER_TYPE)
603 {
604 errstr = "source is not a pointer";
605 goto fail;
606 }
607 if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
608 {
609 errstr = "source is not a pointer to class";
610 goto fail;
611 }
612 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
613 {
614 errstr = "source is a pointer to incomplete type";
615 goto fail;
616 }
617 }
618 else
619 {
620 /* T is a reference type, v shall be an lvalue of a complete class
621 type, and the result is an lvalue of the type referred to by T. */
622
623 if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
624 {
625 errstr = "source is not of class type";
626 goto fail;
627 }
628 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
629 {
630 errstr = "source is of incomplete class type";
631 goto fail;
632 }
633
634 }
635
636 /* The dynamic_cast operator shall not cast away constness. */
637 if (!at_least_as_qualified_p (TREE_TYPE (type),
638 TREE_TYPE (exprtype)))
639 {
640 errstr = "conversion casts away constness";
641 goto fail;
642 }
643
644 /* If *type is an unambiguous accessible base class of *exprtype,
645 convert statically. */
646 {
647 int distance;
648 tree path;
649
650 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
651 &path);
652
653 if (distance == -2)
654 {
655 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
656 TREE_TYPE (exprtype), TREE_TYPE (type));
657 return error_mark_node;
658 }
659 if (distance == -3)
660 {
661 cp_error ("dynamic_cast from `%T' to private base class `%T'",
662 TREE_TYPE (exprtype), TREE_TYPE (type));
663 return error_mark_node;
664 }
665
666 if (distance >= 0)
667 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
668 }
669
670 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
671 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
672 {
673 tree expr1;
674 /* if TYPE is `void *', return pointer to complete object. */
675 if (tc == POINTER_TYPE
676 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
677 {
678 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
679 if (TREE_CODE (expr) == ADDR_EXPR
680 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
681 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
682 return build1 (NOP_EXPR, type, expr);
683
684 /* Since expr is used twice below, save it. */
685 expr = save_expr (expr);
686
687 expr1 = build_headof (expr);
688 if (TREE_TYPE (expr1) != type)
689 expr1 = build1 (NOP_EXPR, type, expr1);
690 return ifnonnull (expr, expr1);
691 }
692 else
693 {
694 tree retval;
695 tree result, td2, td3, elems;
696 tree static_type, target_type, boff;
697
698 /* If we got here, we can't convert statically. Therefore,
699 dynamic_cast<D&>(b) (b an object) cannot succeed. */
700 if (tc == REFERENCE_TYPE)
701 {
702 if (TREE_CODE (old_expr) == VAR_DECL
703 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
704 {
705 tree expr = throw_bad_cast ();
706 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
707 old_expr, type);
708 /* Bash it to the expected type. */
709 TREE_TYPE (expr) = type;
710 return expr;
711 }
712 }
713 /* Ditto for dynamic_cast<D*>(&b). */
714 else if (TREE_CODE (expr) == ADDR_EXPR)
715 {
716 tree op = TREE_OPERAND (expr, 0);
717 if (TREE_CODE (op) == VAR_DECL
718 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
719 {
720 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
721 op, type);
722 retval = build_int_2 (0, 0);
723 TREE_TYPE (retval) = type;
724 return retval;
725 }
726 }
727
728 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
729 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
730 td2 = build_unary_op (ADDR_EXPR, get_tinfo_decl (target_type), 0);
731 td3 = build_unary_op (ADDR_EXPR, get_tinfo_decl (static_type), 0);
732
733 /* Determine how T and V are related. */
734 boff = get_dynamic_cast_base_type (static_type, target_type);
735
736 /* Since expr is used twice below, save it. */
737 expr = save_expr (expr);
738
739 expr1 = expr;
740 if (tc == REFERENCE_TYPE)
741 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
742
743 if (!new_abi_rtti_p ())
744 {
745 tree expr2 = build_headof (expr1);
746 tree td1 = expr;
747
748 if (tc == POINTER_TYPE)
749 td1 = build_indirect_ref (td1, NULL_PTR);
750 td1 = get_tinfo_decl_dynamic (td1);
751
752 elems = tree_cons
753 (NULL_TREE, td1, tree_cons
754 (NULL_TREE, td2, tree_cons
755 (NULL_TREE, boff, tree_cons
756 (NULL_TREE, expr2, tree_cons
757 (NULL_TREE, td3, tree_cons
758 (NULL_TREE, expr1, NULL_TREE))))));
759 }
760 else
761 elems = tree_cons
762 (NULL_TREE, expr1, tree_cons
763 (NULL_TREE, td3, tree_cons
764 (NULL_TREE, td2, tree_cons
765 (NULL_TREE, boff, NULL_TREE))));
766
767 dcast_fn = dynamic_cast_node;
768 if (!dcast_fn)
769 {
770 tree tmp;
771 tree tinfo_ptr;
772 tree ns = new_abi_rtti_p () ? abi_node : global_namespace;
773 const char *name;
774
775 push_nested_namespace (ns);
776 if (!new_abi_rtti_p ())
777 {
778 tinfo_ptr = build_pointer_type (tinfo_decl_type);
779 name = "__dynamic_cast_2";
780 tmp = tree_cons
781 (NULL_TREE, tinfo_ptr, tree_cons
782 (NULL_TREE, tinfo_ptr, tree_cons
783 (NULL_TREE, integer_type_node, tree_cons
784 (NULL_TREE, ptr_type_node, tree_cons
785 (NULL_TREE, tinfo_ptr, tree_cons
786 (NULL_TREE, ptr_type_node, void_list_node))))));
787 }
788 else
789 {
790 tinfo_ptr = xref_tag (class_type_node,
791 get_identifier ("__class_type_info"),
792 1);
793
794 tinfo_ptr = build_pointer_type
795 (build_qualified_type
796 (tinfo_ptr, TYPE_QUAL_CONST));
797 name = "__dynamic_cast";
798 tmp = tree_cons
799 (NULL_TREE, const_ptr_type_node, tree_cons
800 (NULL_TREE, tinfo_ptr, tree_cons
801 (NULL_TREE, tinfo_ptr, tree_cons
802 (NULL_TREE, ptrdiff_type_node, void_list_node))));
803 }
804 tmp = build_function_type (ptr_type_node, tmp);
805 if (new_abi_rtti_p ())
806 /* We want its name mangling. */
807 dcast_fn = build_cp_library_fn_ptr (name, tmp);
808 else
809 dcast_fn = build_library_fn_ptr (name, tmp);
810 pop_nested_namespace (ns);
811 dynamic_cast_node = dcast_fn;
812 }
813 result = build_call (dcast_fn, elems);
814
815 if (tc == REFERENCE_TYPE)
816 {
817 tree bad = throw_bad_cast ();
818
819 result = save_expr (result);
820 return build (COND_EXPR, type, result, result, bad);
821 }
822
823 /* Now back to the type we want from a void*. */
824 result = cp_convert (type, result);
825 return ifnonnull (expr, result);
826 }
827 }
828 else
829 errstr = "source type is not polymorphic";
830
831 fail:
832 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T' (%s)",
833 expr, exprtype, type, errstr);
834 return error_mark_node;
835 }
836
837 tree
838 build_dynamic_cast (type, expr)
839 tree type, expr;
840 {
841 if (type == error_mark_node || expr == error_mark_node)
842 return error_mark_node;
843
844 if (processing_template_decl)
845 return build_min (DYNAMIC_CAST_EXPR, type, expr);
846
847 return convert_from_reference (build_dynamic_cast_1 (type, expr));
848 }
849 \f
850 /* Build and initialize various sorts of descriptors. Every descriptor
851 node has a name associated with it (the name created by mangling).
852 For this reason, we use the identifier as our access to the __*_desc
853 nodes, instead of sticking them directly in the types. Otherwise we
854 would burden all built-in types (and pointer types) with slots that
855 we don't necessarily want to use.
856
857 For each descriptor we build, we build a variable that contains
858 the descriptor's information. When we need this info at runtime,
859 all we need is access to these variables.
860
861 Note: these constructors always return the address of the descriptor
862 info, since that is simplest for their mutual interaction. */
863
864 /* Build an initializer for a __si_type_info node. */
865
866 static void
867 expand_si_desc (tdecl, type)
868 tree tdecl;
869 tree type;
870 {
871 tree t, elems, fn;
872 tree name_string = tinfo_name (type);
873
874 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
875 finish_expr_stmt (get_typeid_1 (type));
876 t = decay_conversion (get_tinfo_var (type));
877 elems = tree_cons
878 (NULL_TREE, decay_conversion (tdecl), tree_cons
879 (NULL_TREE, decay_conversion (name_string), tree_cons
880 (NULL_TREE, t, NULL_TREE)));
881
882 fn = get_identifier ("__rtti_si");
883 if (IDENTIFIER_GLOBAL_VALUE (fn))
884 fn = IDENTIFIER_GLOBAL_VALUE (fn);
885 else
886 {
887 tree tmp;
888 tmp = tree_cons
889 (NULL_TREE, ptr_type_node, tree_cons
890 (NULL_TREE, const_string_type_node, tree_cons
891 (NULL_TREE, build_pointer_type (type_info_type_node),
892 void_list_node)));
893 fn = push_void_library_fn (fn, tmp);
894 }
895
896 fn = build_call (fn, elems);
897 finish_expr_stmt (fn);
898 }
899
900 /* Build an initializer for a __class_type_info node. */
901
902 static void
903 expand_class_desc (tdecl, type)
904 tree tdecl;
905 tree type;
906 {
907 tree name_string;
908 tree fn, tmp;
909
910 int i = CLASSTYPE_N_BASECLASSES (type);
911 int base_cnt = 0;
912 tree binfos = TYPE_BINFO_BASETYPES (type);
913 #if 0
914 /* See code below that used these. */
915 tree vb = CLASSTYPE_VBASECLASSES (type);
916 int n_base = i;
917 #endif
918 tree base, elems, access, offset, isvir;
919 tree elt, elts = NULL_TREE;
920
921 if (base_desc_type_node == NULL_TREE)
922 {
923 tree fields [4];
924
925 /* A reasonably close approximation of __class_type_info::base_info */
926
927 base_desc_type_node = make_aggr_type (RECORD_TYPE);
928
929 /* Actually const __user_type_info * */
930 fields [0] = build_lang_decl
931 (FIELD_DECL, NULL_TREE,
932 build_pointer_type (build_qualified_type
933 (type_info_type_node,
934 TYPE_QUAL_CONST)));
935 fields [1] = build_lang_decl
936 (FIELD_DECL, NULL_TREE,
937 flag_new_abi ? intSI_type_node : unsigned_intSI_type_node);
938 DECL_BIT_FIELD (fields[1]) = 1;
939 DECL_SIZE (fields[1]) = bitsize_int (29);
940
941 fields [2] = build_lang_decl (FIELD_DECL, NULL_TREE, boolean_type_node);
942 DECL_BIT_FIELD (fields[2]) = 1;
943 DECL_SIZE (fields[2]) = bitsize_int (1);
944
945 /* Actually enum access */
946 fields [3] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node);
947 DECL_BIT_FIELD (fields[3]) = 1;
948 DECL_SIZE (fields[3]) = bitsize_int (2);
949
950 finish_builtin_type (base_desc_type_node, "__base_info", fields,
951 3, ptr_type_node);
952 }
953
954 while (--i >= 0)
955 {
956 tree binfo = TREE_VEC_ELT (binfos, i);
957
958 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
959 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
960 offset = get_base_offset (binfo, type);
961
962 if (TREE_VIA_PUBLIC (binfo))
963 access = access_public_node;
964 else if (TREE_VIA_PROTECTED (binfo))
965 access = access_protected_node;
966 else
967 access = access_private_node;
968 if (TREE_VIA_VIRTUAL (binfo))
969 isvir = boolean_true_node;
970 else
971 isvir = boolean_false_node;
972
973 elt = build
974 (CONSTRUCTOR, base_desc_type_node, NULL_TREE, tree_cons
975 (NULL_TREE, base, tree_cons
976 (NULL_TREE, offset, tree_cons
977 (NULL_TREE, isvir, tree_cons
978 (NULL_TREE, access, NULL_TREE)))));
979 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
980 elts = tree_cons (NULL_TREE, elt, elts);
981 base_cnt++;
982 }
983 #if 0
984 i = n_base;
985 while (vb)
986 {
987 tree b;
988 access = access_public_node;
989 while (--i >= 0)
990 {
991 b = TREE_VEC_ELT (binfos, i);
992 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
993 {
994 if (TREE_VIA_PUBLIC (b))
995 access = access_public_node;
996 else if (TREE_VIA_PROTECTED (b))
997 access = access_protected_node;
998 else
999 access = access_private_node;
1000 break;
1001 }
1002 }
1003 base = build_t_desc (BINFO_TYPE (vb), 1);
1004 offset = BINFO_OFFSET (vb);
1005 isvir = build_int_2 (1, 0);
1006
1007 base_list = tree_cons (NULL_TREE, base, base_list);
1008 isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
1009 acc_list = tree_cons (NULL_TREE, access, acc_list);
1010 off_list = tree_cons (NULL_TREE, offset, off_list);
1011
1012 base_cnt++;
1013 vb = TREE_CHAIN (vb);
1014 }
1015 #endif
1016
1017 name_string = tinfo_name (type);
1018
1019 {
1020 tree arrtype = build_array_type (base_desc_type_node, NULL_TREE);
1021 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
1022 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
1023 = TREE_STATIC (elts) = 1;
1024 complete_array_type (arrtype, elts, 1);
1025 }
1026
1027 elems = tree_cons
1028 (NULL_TREE, decay_conversion (tdecl), tree_cons
1029 (NULL_TREE, decay_conversion (name_string), tree_cons
1030 (NULL_TREE, decay_conversion (elts), tree_cons
1031 (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
1032 NULL_TREE))));
1033
1034 fn = get_identifier ("__rtti_class");
1035 if (IDENTIFIER_GLOBAL_VALUE (fn))
1036 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1037 else
1038 {
1039 tmp = tree_cons
1040 (NULL_TREE, ptr_type_node, tree_cons
1041 (NULL_TREE, const_string_type_node, tree_cons
1042 (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
1043 (NULL_TREE, sizetype, void_list_node))));
1044
1045 fn = push_void_library_fn (fn, tmp);
1046 }
1047
1048 fn = build_call (fn, elems);
1049 finish_expr_stmt (fn);
1050 }
1051
1052 /* Build an initializer for a __pointer_type_info node. */
1053
1054 static void
1055 expand_ptr_desc (tdecl, type)
1056 tree tdecl;
1057 tree type;
1058 {
1059 tree t, elems, fn;
1060 tree name_string = tinfo_name (type);
1061
1062 type = TREE_TYPE (type);
1063 finish_expr_stmt (get_typeid_1 (type));
1064 t = decay_conversion (get_tinfo_var (type));
1065 elems = tree_cons
1066 (NULL_TREE, decay_conversion (tdecl), tree_cons
1067 (NULL_TREE, decay_conversion (name_string), tree_cons
1068 (NULL_TREE, t, NULL_TREE)));
1069
1070 fn = get_identifier ("__rtti_ptr");
1071 if (IDENTIFIER_GLOBAL_VALUE (fn))
1072 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1073 else
1074 {
1075 tree tmp;
1076 tmp = tree_cons
1077 (NULL_TREE, ptr_type_node, tree_cons
1078 (NULL_TREE, const_string_type_node, tree_cons
1079 (NULL_TREE, build_pointer_type (type_info_type_node),
1080 void_list_node)));
1081 fn = push_void_library_fn (fn, tmp);
1082 }
1083
1084 fn = build_call (fn, elems);
1085 finish_expr_stmt (fn);
1086 }
1087
1088 /* Build an initializer for a __attr_type_info node. */
1089
1090 static void
1091 expand_attr_desc (tdecl, type)
1092 tree tdecl;
1093 tree type;
1094 {
1095 tree elems, t, fn;
1096 tree name_string = tinfo_name (type);
1097 tree attrval = build_int_2 (TYPE_QUALS (type), 0);
1098
1099 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
1100 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
1101 elems = tree_cons
1102 (NULL_TREE, decay_conversion (tdecl), tree_cons
1103 (NULL_TREE, decay_conversion (name_string), tree_cons
1104 (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
1105
1106 fn = get_identifier ("__rtti_attr");
1107 if (IDENTIFIER_GLOBAL_VALUE (fn))
1108 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1109 else
1110 {
1111 tree tmp;
1112 tmp = tree_cons
1113 (NULL_TREE, ptr_type_node, tree_cons
1114 (NULL_TREE, const_string_type_node, tree_cons
1115 (NULL_TREE, integer_type_node, tree_cons
1116 (NULL_TREE, build_pointer_type (type_info_type_node),
1117 void_list_node))));
1118 fn = push_void_library_fn (fn, tmp);
1119 }
1120
1121 fn = build_call (fn, elems);
1122 finish_expr_stmt (fn);
1123 }
1124
1125 /* Build an initializer for a type_info node that just has a name. */
1126
1127 static void
1128 expand_generic_desc (tdecl, type, fnname)
1129 tree tdecl;
1130 tree type;
1131 const char *fnname;
1132 {
1133 tree name_string = tinfo_name (type);
1134 tree elems = tree_cons
1135 (NULL_TREE, decay_conversion (tdecl), tree_cons
1136 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
1137
1138 tree fn = get_identifier (fnname);
1139 if (IDENTIFIER_GLOBAL_VALUE (fn))
1140 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1141 else
1142 {
1143 tree tmp;
1144 tmp = tree_cons
1145 (NULL_TREE, ptr_type_node, tree_cons
1146 (NULL_TREE, const_string_type_node, void_list_node));
1147 fn = push_void_library_fn (fn, tmp);
1148 }
1149
1150 fn = build_call (fn, elems);
1151 finish_expr_stmt (fn);
1152 }
1153
1154 /* Generate the code for a type_info initialization function.
1155 Note that we take advantage of the passage
1156
1157 5.2.7 Type identification [expr.typeid]
1158
1159 Whether or not the destructor is called for the type_info object at the
1160 end of the program is unspecified.
1161
1162 and don't bother to arrange for these objects to be destroyed. It
1163 doesn't matter, anyway, since the destructors don't do anything.
1164
1165 This must only be called from toplevel (i.e. from finish_file)! */
1166
1167 void
1168 synthesize_tinfo_fn (fndecl)
1169 tree fndecl;
1170 {
1171 tree type = TREE_TYPE (DECL_NAME (fndecl));
1172 tree tmp, addr, tdecl;
1173 tree compound_stmt;
1174 tree if_stmt;
1175 tree then_clause;
1176
1177 my_friendly_assert (!new_abi_rtti_p (), 20000118);
1178 if (at_eof)
1179 {
1180 import_export_decl (fndecl);
1181 if (DECL_REALLY_EXTERN (fndecl))
1182 return;
1183 }
1184
1185 /* Declare the static typeinfo variable. */
1186 tdecl = get_tinfo_var (type);
1187 DECL_EXTERNAL (tdecl) = 0;
1188 TREE_STATIC (tdecl) = 1;
1189 DECL_COMMON (tdecl) = 1;
1190 TREE_USED (tdecl) = 1;
1191 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1192 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0);
1193
1194 /* Begin processing the function. */
1195 start_function (NULL_TREE, fndecl, NULL_TREE,
1196 SF_DEFAULT | SF_PRE_PARSED);
1197 DECL_DEFER_OUTPUT (fndecl) = 1;
1198 store_parm_decls ();
1199 clear_last_expr ();
1200
1201 /* Begin the body of the function. */
1202 compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
1203
1204 /* For convenience, we save away the address of the static
1205 variable. */
1206 addr = decay_conversion (tdecl);
1207
1208 /* If the first word of the array (the vtable) is non-zero, we've already
1209 initialized the object, so don't do it again. */
1210 if_stmt = begin_if_stmt ();
1211 tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
1212 tmp = build_indirect_ref (tmp, 0);
1213 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
1214 finish_if_stmt_cond (tmp, if_stmt);
1215 then_clause = begin_compound_stmt (/*has_no_scope=*/0);
1216
1217 if (TREE_CODE (type) == FUNCTION_TYPE)
1218 expand_generic_desc (tdecl, type, "__rtti_func");
1219 else if (TREE_CODE (type) == ARRAY_TYPE)
1220 expand_generic_desc (tdecl, type, "__rtti_array");
1221 else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
1222 expand_attr_desc (tdecl, type);
1223 else if (TREE_CODE (type) == POINTER_TYPE)
1224 {
1225 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1226 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1227 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1228 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1229 else
1230 expand_ptr_desc (tdecl, type);
1231 }
1232 else if (TYPE_PTRMEMFUNC_P (type))
1233 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1234 else if (IS_AGGR_TYPE (type))
1235 {
1236 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1237 expand_generic_desc (tdecl, type, "__rtti_user");
1238 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
1239 && (TREE_VIA_PUBLIC
1240 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1241 expand_si_desc (tdecl, type);
1242 else
1243 expand_class_desc (tdecl, type);
1244 }
1245 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1246 expand_generic_desc (tdecl, type, "__rtti_user");
1247 else
1248 my_friendly_abort (252);
1249
1250 finish_compound_stmt (/*has_no_scope=*/0, then_clause);
1251 finish_then_clause (if_stmt);
1252 finish_if_stmt ();
1253
1254 /* OK, now return the type_info object. */
1255 tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
1256 tmp = build_indirect_ref (tmp, 0);
1257 finish_return_stmt (tmp);
1258 /* Finish the function body. */
1259 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
1260 expand_body (finish_function (lineno, 0));
1261 }
1262
1263 /* Return the runtime bit mask encoding the qualifiers of TYPE. */
1264
1265 static int
1266 qualifier_flags (type)
1267 tree type;
1268 {
1269 int flags = 0;
1270 /* we want the qualifiers on this type, not any array core, it might have */
1271 int quals = TYPE_QUALS (type);
1272
1273 if (quals & TYPE_QUAL_CONST)
1274 flags |= 1;
1275 if (quals & TYPE_QUAL_VOLATILE)
1276 flags |= 2;
1277 return flags;
1278 }
1279
1280 /* Return a CONSTRUCTOR for the common part of the type_info objects. This
1281 is the vtable pointer and NTBS name. */
1282
1283 static tree
1284 tinfo_base_init (desc, target)
1285 tree desc;
1286 tree target;
1287 {
1288 tree name_string = tinfo_name (target);
1289 tree init = NULL_TREE;
1290
1291 if (TINFO_VTABLE_DECL (desc))
1292 {
1293 tree vtbl_ptr = build_unary_op (ADDR_EXPR, TINFO_VTABLE_DECL (desc), 0);
1294
1295 init = tree_cons (NULL_TREE, vtbl_ptr, init);
1296 }
1297
1298 init = tree_cons (NULL_TREE, decay_conversion (name_string), init);
1299
1300 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
1301 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1302 init = tree_cons (NULL_TREE, init, NULL_TREE);
1303
1304 return init;
1305 }
1306
1307 /* Return the CONSTRUCTOR expr for a type_info of TYPE. DESC provides the
1308 information about the particular type_info derivation, which adds no
1309 additional fields to the type_info base. */
1310
1311 static tree
1312 generic_initializer (desc, target)
1313 tree desc;
1314 tree target;
1315 {
1316 tree init = tinfo_base_init (desc, target);
1317
1318 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
1319 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1320 return init;
1321 }
1322
1323 /* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
1324 DESC provides information about the particular type_info derivation,
1325 which adds target type and qualifier flags members to the type_info base. */
1326
1327 static tree
1328 ptr_initializer (desc, target)
1329 tree desc;
1330 tree target;
1331 {
1332 tree init = tinfo_base_init (desc, target);
1333 tree to = TREE_TYPE (target);
1334 int flags = qualifier_flags (to);
1335
1336 init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
1337 init = tree_cons (NULL_TREE,
1338 build_unary_op (ADDR_EXPR,
1339 get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
1340 init);
1341
1342 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
1343 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1344 return init;
1345 }
1346
1347 /* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
1348 DESC provides information about the particular type_info derivation,
1349 which adds target type and qualifier flags members to the type_info base. */
1350
1351 static tree
1352 ptmd_initializer (desc, target)
1353 tree desc;
1354 tree target;
1355 {
1356 tree init = tinfo_base_init (desc, target);
1357 tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
1358 tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
1359 int flags = qualifier_flags (to);
1360
1361 init = tree_cons (NULL_TREE,
1362 build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
1363 init);
1364 init = tree_cons (NULL_TREE,
1365 build_unary_op (ADDR_EXPR,
1366 get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
1367 init);
1368 init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
1369
1370 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
1371 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1372 return init;
1373 }
1374
1375 /* Determine the hint flags describing the features of a class's heirarchy.
1376 FIXME: better set the hint_flags here! For now set them
1377 to safe 'don't know' values. The specification is under
1378 review. Don't forget to check the runtime dynamic_cast and
1379 catch machinery if these change. */
1380
1381 static int
1382 class_hint_flags (type)
1383 tree type;
1384 {
1385 int hint_flags = 0;
1386 hint_flags |= 0x1; /* contains multiply inherited sub object */
1387 hint_flags |= 0x4; /* has virtual bases */
1388 hint_flags |= 0x8; /* has private base */
1389 if (TYPE_POLYMORPHIC_P (type))
1390 hint_flags |= 0x2;
1391
1392 return hint_flags;
1393 }
1394
1395 /* Return the CONSTRUCTOR expr for a type_info of class TYPE.
1396 DESC provides information about the particular __class_type_info derivation,
1397 which adds hint flags and TRAIL initializers to the type_info base. */
1398
1399 static tree
1400 class_initializer (desc, target, trail)
1401 tree desc;
1402 tree target;
1403 tree trail;
1404 {
1405 tree init = tinfo_base_init (desc, target);
1406 int flags = class_hint_flags (target);
1407
1408 trail = tree_cons (NULL_TREE, build_int_2 (flags, 0), trail);
1409 TREE_CHAIN (init) = trail;
1410 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
1411 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1412 return init;
1413 }
1414
1415 /* Generate a pseudo_type_info VAR_DECL suitable for the supplied
1416 TARGET_TYPE and given the REAL_NAME. This is the structure expected by
1417 the runtime, and therefore has additional fields. If we need not emit a
1418 definition (because the runtime must contain it), return NULL_TREE,
1419 otherwise return the VAR_DECL. */
1420
1421 static tree
1422 synthesize_tinfo_var (target_type, real_name)
1423 tree target_type;
1424 tree real_name;
1425 {
1426 tree var_init = NULL_TREE;
1427 tree var_type = NULL_TREE;
1428
1429 my_friendly_assert (new_abi_rtti_p (), 20000118);
1430
1431 switch (TREE_CODE (target_type))
1432 {
1433 case POINTER_TYPE:
1434 if (TYPE_PTRMEM_P (target_type))
1435 {
1436 var_type = ptmd_desc_type_node;
1437 var_init = ptmd_initializer (var_type, target_type);
1438 }
1439 else
1440 {
1441 int code = TREE_CODE (TREE_TYPE (target_type));
1442
1443 if ((CP_TYPE_QUALS (TREE_TYPE (target_type)) | TYPE_QUAL_CONST)
1444 == TYPE_QUAL_CONST
1445 && (code == INTEGER_TYPE || code == BOOLEAN_TYPE
1446 || code == CHAR_TYPE || code == REAL_TYPE
1447 || code == VOID_TYPE)
1448 && !doing_runtime)
1449 /* These are in the runtime. */
1450 return NULL_TREE;
1451 var_type = ptr_desc_type_node;
1452 var_init = ptr_initializer (var_type, target_type);
1453 }
1454 break;
1455 case ENUMERAL_TYPE:
1456 var_type = enum_desc_type_node;
1457 var_init = generic_initializer (var_type, target_type);
1458 break;
1459 case FUNCTION_TYPE:
1460 var_type = func_desc_type_node;
1461 var_init = generic_initializer (var_type, target_type);
1462 break;
1463 case ARRAY_TYPE:
1464 var_type = ary_desc_type_node;
1465 var_init = generic_initializer (var_type, target_type);
1466 break;
1467 case UNION_TYPE:
1468 case RECORD_TYPE:
1469 if (!TYPE_SIZE (target_type))
1470 {
1471 /* FIXME: incomplete type. Awaiting specification. */
1472 return NULL_TREE;
1473 }
1474 else if (!CLASSTYPE_N_BASECLASSES (target_type))
1475 {
1476 var_type = class_desc_type_node;
1477 var_init = class_initializer (var_type, target_type, NULL_TREE);
1478 }
1479 else
1480 {
1481 /* if this has a single public non-virtual base, it's easier */
1482 tree binfo = TYPE_BINFO (target_type);
1483 int nbases = BINFO_N_BASETYPES (binfo);
1484 tree base_binfos = BINFO_BASETYPES (binfo);
1485 tree base_inits = NULL_TREE;
1486 int is_simple = nbases == 1;
1487 int ix;
1488
1489 /* Generate the base information initializer. */
1490 for (ix = nbases; ix--;)
1491 {
1492 tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
1493 tree base_init = NULL_TREE;
1494 int flags = 0;
1495 tree tinfo;
1496 tree offset;
1497
1498 if (TREE_VIA_VIRTUAL (base_binfo))
1499 flags |= 1;
1500 if (TREE_PUBLIC (base_binfo))
1501 flags |= 2;
1502 tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
1503 tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
1504 offset = get_base_offset (base_binfo, target_type);
1505
1506 /* is it a single public inheritance? */
1507 if (is_simple && flags == 2 && integer_zerop (offset))
1508 {
1509 base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
1510 break;
1511 }
1512 is_simple = 0;
1513
1514 base_init = tree_cons
1515 (NULL_TREE, build_int_2 (flags, 0), base_init);
1516 base_init = tree_cons (NULL_TREE, offset, base_init);
1517 base_init = tree_cons (NULL_TREE, tinfo, base_init);
1518 base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
1519 base_inits = tree_cons (NULL_TREE, base_init, base_inits);
1520 }
1521
1522 if (is_simple)
1523 var_type = si_class_desc_type_node;
1524 else
1525 {
1526 /* Prepend the number of bases. */
1527 base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
1528 base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
1529 base_inits = tree_cons (NULL_TREE,
1530 build_int_2 (nbases, 0), base_inits);
1531
1532 var_type = get_vmi_pseudo_type_info (nbases);
1533 }
1534 var_init = class_initializer (var_type, target_type, base_inits);
1535 }
1536 break;
1537 case INTEGER_TYPE:
1538 case BOOLEAN_TYPE:
1539 case CHAR_TYPE:
1540 case REAL_TYPE:
1541 case VOID_TYPE:
1542 if (!doing_runtime)
1543 /* These are guaranteed to be in the runtime. */
1544 return NULL_TREE;
1545 var_type = bltn_desc_type_node;
1546 var_init = generic_initializer (var_type, target_type);
1547 break;
1548 default:
1549 my_friendly_abort (20000117);
1550 }
1551
1552 return create_real_tinfo_var (real_name, TINFO_PSEUDO_TYPE (var_type), var_init);
1553 }
1554
1555 /* Create the real typeinfo variable. */
1556
1557 static tree
1558 create_real_tinfo_var (name, type, init)
1559 tree name;
1560 tree type;
1561 tree init;
1562 {
1563 tree decl;
1564
1565 decl = build_lang_decl (VAR_DECL, name,
1566 build_qualified_type (type, TYPE_QUAL_CONST));
1567 DECL_ARTIFICIAL (decl) = 1;
1568 TREE_READONLY (decl) = 1;
1569 TREE_STATIC (decl) = 1;
1570 TREE_PUBLIC (decl) = 1;
1571 DECL_EXTERNAL (decl) = 0;
1572
1573 comdat_linkage (decl);
1574 DECL_ASSEMBLER_NAME (decl) = name;
1575 DECL_INITIAL (decl) = init;
1576 cp_finish_decl (decl, init, NULL_TREE, 0);
1577
1578 return decl;
1579 }
1580
1581 /* Generate the RECORD_TYPE containing the data layout of a type_info
1582 derivative as used by the runtime. This layout must be consistent with
1583 that defined in the runtime support. Also generate the VAR_DECL for the
1584 type's vtable. We explicitly manage the vtable member, and name it for
1585 real type as used in the runtime. The RECORD type has a different name,
1586 to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
1587 is the generated type and TINFO_VTABLE_DECL is the vtable decl.
1588
1589 REAL_NAME is the runtime's name of the type. Trailing arguments are
1590 additional FIELD_DECL's for the structure. The final argument must be
1591 NULL. */
1592
1593 static tree
1594 create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
1595 {
1596 #ifndef ANSI_PROTOTYPES
1597 char const *real_name;
1598 int ident;
1599 #endif
1600 va_list ap;
1601 tree real_type, pseudo_type;
1602 char *pseudo_name;
1603 tree vtable_decl;
1604 int ix;
1605 tree fields[10];
1606 tree field_decl;
1607 tree result;
1608
1609 VA_START (ap, ident);
1610 #ifndef ANSI_PROTOTYPES
1611 real_name = va_arg (ap, char const *);
1612 ident = va_arg (app, int);
1613 #endif
1614
1615 /* Generate the pseudo type name. */
1616 pseudo_name = (char *)alloca (strlen (real_name) + 30);
1617 strcpy (pseudo_name, real_name);
1618 strcat (pseudo_name, "_pseudo");
1619 if (ident)
1620 sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
1621
1622 /* Get the vtable decl. */
1623 real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
1624 vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
1625
1626 /* First field is the pseudo type_info base class. */
1627 fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
1628
1629 /* Now add the derived fields. */
1630 for (ix = 0; (field_decl = va_arg (ap, tree));)
1631 fields[++ix] = field_decl;
1632
1633 /* Create the pseudo type. */
1634 pseudo_type = make_aggr_type (RECORD_TYPE);
1635 finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
1636 TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
1637 va_end (ap);
1638
1639 result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
1640 TINFO_VTABLE_DECL (result) = vtable_decl;
1641 TINFO_PSEUDO_TYPE (result) = pseudo_type;
1642
1643 return result;
1644 }
1645
1646 /* Return a descriptor for a vmi type with NUM_BASES bases. */
1647
1648 static tree
1649 get_vmi_pseudo_type_info (num_bases)
1650 int num_bases;
1651 {
1652 tree desc;
1653 tree array_domain, base_array;
1654
1655 if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
1656 {
1657 int ix;
1658 tree extend = make_tree_vec (num_bases + 5);
1659
1660 for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
1661 TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
1662 vmi_class_desc_type_node = extend;
1663 }
1664 desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
1665
1666 if (desc)
1667 return desc;
1668
1669 /* Add number of bases and trailing array of base_class_type_info. */
1670 array_domain = build_index_type (build_int_2 (num_bases, 0));
1671 base_array = build_array_type (base_desc_type_node, array_domain);
1672
1673 push_nested_namespace (abi_node);
1674
1675 desc = create_pseudo_type_info
1676 ("__vmi_class_type_info", num_bases,
1677 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1678 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1679 build_lang_decl (FIELD_DECL, NULL_TREE, base_array),
1680 NULL);
1681
1682 pop_nested_namespace (abi_node);
1683
1684 TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
1685 return desc;
1686 }
1687
1688 /* Make sure the required builtin types exist for generating the type_info
1689 varable definitions. */
1690
1691 static void
1692 create_tinfo_types ()
1693 {
1694 tree ptr_type_info;
1695
1696 if (bltn_desc_type_node)
1697 return;
1698 push_nested_namespace (abi_node);
1699
1700 ptr_type_info = build_pointer_type
1701 (build_qualified_type
1702 (type_info_type_node, TYPE_QUAL_CONST));
1703
1704 /* Create the internal type_info structure. This is used as a base for
1705 the other structures. */
1706 {
1707 tree fields[2];
1708
1709 ti_desc_type_node = make_aggr_type (RECORD_TYPE);
1710 fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
1711 fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
1712 finish_builtin_type (ti_desc_type_node, "__type_info_pseudo",
1713 fields, 1, ptr_type_node);
1714 TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
1715 }
1716
1717 /* Fundamental type_info */
1718 bltn_desc_type_node = create_pseudo_type_info
1719 ("__fundamental_type_info", 0,
1720 NULL);
1721
1722 /* Pointer type_info. Adds two fields, qualification mask
1723 and pointer to the pointed to type. */
1724 ptr_desc_type_node = create_pseudo_type_info
1725 ("__pointer_type_info", 0,
1726 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1727 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1728 NULL);
1729
1730 /* Array, function and enum type_info. No additional fields. */
1731 ary_desc_type_node = create_pseudo_type_info
1732 ("__array_type_info", 0,
1733 NULL);
1734 func_desc_type_node = create_pseudo_type_info
1735 ("__function_type_info", 0,
1736 NULL);
1737 enum_desc_type_node = create_pseudo_type_info
1738 ("__enum_type_info", 0,
1739 NULL);
1740
1741 /* Class type_info. Add a flags field. */
1742 class_desc_type_node = create_pseudo_type_info
1743 ("__class_type_info", 0,
1744 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1745 NULL);
1746
1747 /* Single public non-virtual base class. Add pointer to base class. */
1748 si_class_desc_type_node = create_pseudo_type_info
1749 ("__si_class_type_info", 0,
1750 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1751 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1752 NULL);
1753
1754 /* Base class internal helper. Pointer to base type, offset to base,
1755 flags. */
1756 {
1757 tree fields[3];
1758
1759 fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1760 fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, ptrdiff_type_node),
1761 fields[2] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1762 base_desc_type_node = make_aggr_type (RECORD_TYPE);
1763 finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
1764 fields, 2, ptr_type_node);
1765 TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
1766 }
1767
1768 /* General heirarchy is created as necessary in this vector. */
1769 vmi_class_desc_type_node = make_tree_vec (10);
1770
1771 /* Pointer to member data type_info. Add pointer to the class, pointer
1772 to the member's type info and qualifications flags. */
1773 ptmd_desc_type_node = create_pseudo_type_info
1774 ("__pointer_to_member_type_info", 0,
1775 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1776 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1777 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1778 NULL);
1779
1780 pop_nested_namespace (abi_node);
1781 }
1782
1783 /* Emit the type_info descriptors which are guaranteed to be in the runtime
1784 support. Generating them here guarantees consistency with the other
1785 structures. We use the following heuristic to determine when the runtime
1786 is being generated. If std::__fundamental_type_info is defined, and it's
1787 destructor is defined, then the runtime is being built. */
1788
1789 void
1790 emit_support_tinfos ()
1791 {
1792 static tree *const fundamentals[] =
1793 {
1794 &void_type_node,
1795 &boolean_type_node,
1796 &wchar_type_node,
1797 #if 0
1798 &signed_wchar_type_node, &unsigned_wchar_type_node,
1799 #endif
1800 &char_type_node, &signed_char_type_node, &unsigned_char_type_node,
1801 &short_integer_type_node, &short_unsigned_type_node,
1802 &integer_type_node, &unsigned_type_node,
1803 &long_integer_type_node, &long_unsigned_type_node,
1804 &long_long_integer_type_node, &long_long_unsigned_type_node,
1805 &float_type_node, &double_type_node, &long_double_type_node,
1806
1807 /* GCC extension types */
1808 #if 0
1809 &complex_integer_type_node,
1810 &complex_float_type_node, &complex_double_type_node,
1811 &complex_long_double_type_node,
1812 #endif
1813
1814 0
1815 };
1816 int ix;
1817 tree bltn_type, dtor;
1818
1819 push_nested_namespace (abi_node);
1820 bltn_type = xref_tag (class_type_node,
1821 get_identifier ("__fundamental_type_info"), 1);
1822 pop_nested_namespace (abi_node);
1823 if (!TYPE_SIZE (bltn_type))
1824 return;
1825 dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
1826 if (DECL_EXTERNAL (dtor))
1827 return;
1828 doing_runtime = 1;
1829 for (ix = 0; fundamentals[ix]; ix++)
1830 {
1831 tree bltn = *fundamentals[ix];
1832 tree bltn_ptr = build_pointer_type (bltn);
1833 tree bltn_const_ptr = build_pointer_type
1834 (build_qualified_type (bltn, TYPE_QUAL_CONST));
1835 tree tinfo;
1836
1837 tinfo = get_tinfo_decl (bltn);
1838 TREE_USED (tinfo) = 1;
1839 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1840
1841 tinfo = get_tinfo_decl (bltn_ptr);
1842 TREE_USED (tinfo) = 1;
1843 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1844
1845 tinfo = get_tinfo_decl (bltn_const_ptr);
1846 TREE_USED (tinfo) = 1;
1847 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1848 }
1849 }
1850
1851 /* Return non-zero, iff T is a type_info variable which has not had a
1852 definition emitted for it. */
1853
1854 int
1855 tinfo_decl_p (t, data)
1856 tree t;
1857 void *data ATTRIBUTE_UNUSED;
1858 {
1859 return TREE_CODE (t) == VAR_DECL
1860 && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
1861 && TREE_TYPE (t) == tinfo_decl_type
1862 && TREE_TYPE (DECL_NAME (t));
1863 }
1864
1865 /* Emit a suitable type_info definition for the type_info decl pointed to by
1866 DECL_PTR. We emit a completely new variable, of the correct type for the
1867 actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
1868 definition is set to that of the supplied decl, so that they can be tied
1869 up. Mark the supplied decl as having been dealt with. Emitting one
1870 definitions might cause other declarations to be emitted.
1871
1872 We need to do things this way, because we're trying to do something like
1873
1874 struct B : A {
1875 ...
1876 };
1877
1878 extern const A tinfo_var;
1879
1880 const B tinfo_var = {...};
1881
1882 which is not permitted. Also, we've not necessarily seen the definition of B.
1883 So we do something like the following,
1884
1885 extern const A tinfo_var;
1886
1887 struct pseudo_A {
1888 const void *vtable_ptr;
1889 const char *name;
1890 };
1891 struct pseudo_B {
1892 pseudo_A base;
1893 ...
1894 };
1895
1896 const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
1897 {
1898 {&B::vtable, "..."},
1899 ...
1900 };
1901
1902 pseudo_A and pseudo_B must be layout equivalent to the real definitions in
1903 the runtime. */
1904
1905 int
1906 emit_tinfo_decl (decl_ptr, data)
1907 tree *decl_ptr;
1908 void *data ATTRIBUTE_UNUSED;
1909 {
1910 tree tinfo_decl = *decl_ptr;
1911 tree tinfo_type, decl;
1912
1913 my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
1914 tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
1915 my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
1916
1917 /* Say we've dealt with it. */
1918 TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
1919
1920 if (!DECL_NEEDED_P (tinfo_decl))
1921 return 0;
1922 create_tinfo_types ();
1923 decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
1924
1925 return decl != 0;
1926 }