cp-tree.h (CPTI_TP_DESC_TYPE, [...]): Remove cp_tree_index enumerations.
[gcc.git] / gcc / cp / rtti.c
1 /* RunTime Type Identification
2 Copyright (C) 1995, 96-97, 1998, 1999, 2000 Free Software Foundation, Inc.
3 Mostly written by Jason Merrill (jason@cygnus.com).
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "tree.h"
26 #include "cp-tree.h"
27 #include "flags.h"
28 #include "output.h"
29 #include "assert.h"
30 #include "toplev.h"
31
32 #ifndef INT_TYPE_SIZE
33 #define INT_TYPE_SIZE BITS_PER_WORD
34 #endif
35
36 extern struct obstack permanent_obstack;
37
38 static tree call_void_fn PROTO((const char *));
39 static tree build_headof_sub PROTO((tree));
40 static tree build_headof PROTO((tree));
41 static tree get_tinfo_var PROTO((tree));
42 static tree ifnonnull PROTO((tree, tree));
43 static tree tinfo_name PROTO((tree));
44 static tree get_base_offset PROTO((tree, tree));
45 static tree build_dynamic_cast_1 PROTO((tree, tree));
46 static void expand_si_desc PROTO((tree, tree));
47 static void expand_class_desc PROTO((tree, tree));
48 static void expand_attr_desc PROTO((tree, tree));
49 static void expand_ptr_desc PROTO((tree, tree));
50 static void expand_generic_desc PROTO((tree, tree, const char *));
51 static tree throw_bad_cast PROTO((void));
52 static tree throw_bad_typeid PROTO((void));
53 static tree get_tinfo_decl_dynamic PROTO((tree));
54 static tree tinfo_from_decl PROTO((tree));
55 \f
56 void
57 init_rtti_processing ()
58 {
59 if (flag_honor_std)
60 push_namespace (get_identifier ("std"));
61 type_info_type_node = xref_tag
62 (class_type_node, get_identifier ("type_info"), 1);
63 if (flag_honor_std)
64 pop_namespace ();
65
66 tinfo_decl_id = get_identifier ("__tf");
67 tinfo_decl_type = build_function_type
68 (build_reference_type
69 (build_qualified_type
70 (type_info_type_node, TYPE_QUAL_CONST)),
71 void_list_node);
72 tinfo_var_id = get_identifier ("__ti");
73 }
74
75 /* Given a pointer to an object with at least one virtual table
76 pointer somewhere, return a pointer to a possible sub-object that
77 has a virtual table pointer in it that is the vtable parent for
78 that sub-object. */
79
80 static tree
81 build_headof_sub (exp)
82 tree exp;
83 {
84 tree type = TREE_TYPE (TREE_TYPE (exp));
85 tree basetype = CLASSTYPE_RTTI (type);
86 tree binfo = get_binfo (basetype, type, 0);
87
88 exp = convert_pointer_to_real (binfo, exp);
89 return exp;
90 }
91
92 /* Given the expression EXP of type `class *', return the head of the
93 object pointed to by EXP with type cv void*, if the class has any
94 virtual functions (TYPE_POLYMORPHIC_P), else just return the
95 expression. */
96
97 static tree
98 build_headof (exp)
99 tree exp;
100 {
101 tree type = TREE_TYPE (exp);
102 tree aref;
103 tree offset;
104
105 my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
106 type = TREE_TYPE (type);
107
108 if (!TYPE_POLYMORPHIC_P (type))
109 return exp;
110 if (CLASSTYPE_COM_INTERFACE (type))
111 {
112 cp_error ("RTTI not supported for COM interface type `%T'", type);
113 return error_mark_node;
114 }
115
116 /* If we don't have rtti stuff, get to a sub-object that does. */
117 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
118 exp = build_headof_sub (exp);
119
120 /* We use this a couple of times below, protect it. */
121 exp = save_expr (exp);
122
123 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
124
125 if (flag_vtable_thunks)
126 offset = aref;
127 else
128 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
129
130 type = build_qualified_type (ptr_type_node,
131 CP_TYPE_QUALS (TREE_TYPE (exp)));
132 return build (PLUS_EXPR, type, exp,
133 cp_convert (ptrdiff_type_node, offset));
134 }
135
136 /* Build a call to a generic entry point taking and returning void. */
137
138 static tree
139 call_void_fn (name)
140 const char *name;
141 {
142 tree d = get_identifier (name);
143 tree type;
144
145 if (IDENTIFIER_GLOBAL_VALUE (d))
146 d = IDENTIFIER_GLOBAL_VALUE (d);
147 else
148 {
149 type = build_function_type (void_type_node, void_list_node);
150 d = build_lang_decl (FUNCTION_DECL, d, type);
151 DECL_EXTERNAL (d) = 1;
152 TREE_PUBLIC (d) = 1;
153 DECL_ARTIFICIAL (d) = 1;
154 pushdecl_top_level (d);
155 make_function_rtl (d);
156 }
157
158 mark_used (d);
159 return build_call (d, void_type_node, NULL_TREE);
160 }
161
162 /* Get a bad_cast node for the program to throw...
163
164 See libstdc++/exception.cc for __throw_bad_cast */
165
166 static tree
167 throw_bad_cast ()
168 {
169 return call_void_fn ("__throw_bad_cast");
170 }
171
172 static tree
173 throw_bad_typeid ()
174 {
175 return call_void_fn ("__throw_bad_typeid");
176 }
177 \f
178 /* Return a pointer to type_info function associated with the expression EXP.
179 If EXP is a reference to a polymorphic class, return the dynamic type;
180 otherwise return the static type of the expression. */
181
182 static tree
183 get_tinfo_decl_dynamic (exp)
184 tree exp;
185 {
186 tree type;
187
188 if (exp == error_mark_node)
189 return error_mark_node;
190
191 type = TREE_TYPE (exp);
192
193 /* peel back references, so they match. */
194 if (TREE_CODE (type) == REFERENCE_TYPE)
195 type = TREE_TYPE (type);
196
197 /* Peel off cv qualifiers. */
198 type = TYPE_MAIN_VARIANT (type);
199
200 if (type != void_type_node)
201 type = complete_type_or_else (type, exp);
202
203 if (!type)
204 return error_mark_node;
205
206 /* If exp is a reference to polymorphic type, get the real type_info. */
207 if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
208 {
209 /* build reference to type_info from vtable. */
210 tree t;
211
212 if (! flag_rtti)
213 error ("taking dynamic typeid of object with -fno-rtti");
214 if (CLASSTYPE_COM_INTERFACE (type))
215 {
216 cp_error ("RTTI not supported for COM interface type `%T'", type);
217 return error_mark_node;
218 }
219
220 /* If we don't have rtti stuff, get to a sub-object that does. */
221 if (! CLASSTYPE_VFIELDS (type))
222 {
223 exp = build_unary_op (ADDR_EXPR, exp, 0);
224 exp = build_headof_sub (exp);
225 exp = build_indirect_ref (exp, NULL_PTR);
226 }
227
228 if (flag_vtable_thunks)
229 t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
230 else
231 t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
232 TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
233 return t;
234 }
235
236 /* otherwise return the type_info for the static type of the expr. */
237 exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
238 return build_unary_op (ADDR_EXPR, exp, 0);
239 }
240
241 tree
242 build_typeid (exp)
243 tree exp;
244 {
245 tree cond = NULL_TREE;
246 int nonnull = 0;
247
248 if (! flag_rtti)
249 {
250 error ("cannot use typeid with -fno-rtti");
251 return error_mark_node;
252 }
253
254 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
255 {
256 error ("must #include <typeinfo> before using typeid");
257 return error_mark_node;
258 }
259
260 if (processing_template_decl)
261 return build_min_nt (TYPEID_EXPR, exp);
262
263 if (TREE_CODE (exp) == INDIRECT_REF
264 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
265 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
266 && ! resolves_to_fixed_type_p (exp, &nonnull)
267 && ! nonnull)
268 {
269 exp = stabilize_reference (exp);
270 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
271 }
272
273 exp = get_tinfo_decl_dynamic (exp);
274
275 if (exp == error_mark_node)
276 return error_mark_node;
277
278 exp = tinfo_from_decl (exp);
279
280 if (cond)
281 {
282 tree bad = throw_bad_typeid ();
283
284 exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
285 }
286
287 return convert_from_reference (exp);
288 }
289
290 static tree
291 get_tinfo_var (type)
292 tree type;
293 {
294 tree tname = build_overload_with_type (tinfo_var_id, type);
295 tree arrtype;
296 int size;
297
298 if (IDENTIFIER_GLOBAL_VALUE (tname))
299 return IDENTIFIER_GLOBAL_VALUE (tname);
300
301 /* Figure out how much space we need to allocate for the type_info object.
302 If our struct layout or the type_info classes are changed, this will
303 need to be modified. */
304 if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
305 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
306 else if (TREE_CODE (type) == POINTER_TYPE
307 && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
308 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
309 size = 3 * POINTER_SIZE;
310 else if (IS_AGGR_TYPE (type))
311 {
312 if (CLASSTYPE_N_BASECLASSES (type) == 0)
313 size = 2 * POINTER_SIZE;
314 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
315 && (TREE_VIA_PUBLIC
316 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
317 size = 3 * POINTER_SIZE;
318 else
319 size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
320 }
321 else
322 size = 2 * POINTER_SIZE;
323
324 /* The type for a character array of the appropriate size. */
325 arrtype = build_cplus_array_type
326 (unsigned_char_type_node,
327 build_index_type (size_int (size / BITS_PER_UNIT - 1)));
328
329 return declare_global_var (tname, arrtype);
330 }
331
332 /* Generate the NTBS name of a type. */
333 static tree
334 tinfo_name (type)
335 tree type;
336 {
337 const char *name = build_overload_name (type, 1, 1);
338 tree name_string = combine_strings (build_string (strlen (name) + 1, name));
339 return name_string;
340 }
341
342 /* Returns a decl for a function or variable which can be used to obtain a
343 type_info object for TYPE. The old-abi uses functions, the new-abi will
344 use the type_info object directly. You can take the address of the
345 returned decl, to save the decl. To use the decl call
346 tinfo_from_decl. You must arrange that the decl is mark_used, if
347 actually use it --- decls in vtables are only used if the vtable is
348 output. */
349
350 tree
351 get_tinfo_decl (type)
352 tree type;
353 {
354 tree name;
355 tree d;
356
357 if (TREE_CODE (type) == OFFSET_TYPE)
358 type = TREE_TYPE (type);
359 if (TREE_CODE (type) == METHOD_TYPE)
360 type = build_function_type (TREE_TYPE (type),
361 TREE_CHAIN (TYPE_ARG_TYPES (type)));
362
363 name = build_overload_with_type (tinfo_decl_id, type);
364
365 if (IDENTIFIER_GLOBAL_VALUE (name))
366 return IDENTIFIER_GLOBAL_VALUE (name);
367
368 d = build_lang_decl (FUNCTION_DECL, name, tinfo_decl_type);
369 DECL_EXTERNAL (d) = 1;
370 TREE_PUBLIC (d) = 1;
371 DECL_ARTIFICIAL (d) = 1;
372 DECL_NOT_REALLY_EXTERN (d) = 1;
373 SET_DECL_TINFO_FN_P (d);
374 TREE_TYPE (name) = type;
375
376 pushdecl_top_level (d);
377 make_function_rtl (d);
378 mark_inline_for_output (d);
379
380 return d;
381 }
382
383 /* Given an expr produced by get_tinfo_decl, return an expr which
384 produces a reference to the type_info object. */
385
386 static tree
387 tinfo_from_decl (expr)
388 tree expr;
389 {
390 tree t = build_call (expr, TREE_TYPE (tinfo_decl_type), NULL_TREE);
391
392 return t;
393 }
394
395 tree
396 get_typeid_1 (type)
397 tree type;
398 {
399 tree t;
400
401 t = get_tinfo_decl (type);
402 t = tinfo_from_decl (t);
403 return convert_from_reference (t);
404 }
405
406 /* Return the type_info object for TYPE. */
407
408 tree
409 get_typeid (type)
410 tree type;
411 {
412 if (type == error_mark_node)
413 return error_mark_node;
414
415 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
416 {
417 error ("must #include <typeinfo> before using typeid");
418 return error_mark_node;
419 }
420
421 if (processing_template_decl)
422 return build_min_nt (TYPEID_EXPR, type);
423
424 /* If the type of the type-id is a reference type, the result of the
425 typeid expression refers to a type_info object representing the
426 referenced type. */
427 if (TREE_CODE (type) == REFERENCE_TYPE)
428 type = TREE_TYPE (type);
429
430 /* The top-level cv-qualifiers of the lvalue expression or the type-id
431 that is the operand of typeid are always ignored. */
432 type = TYPE_MAIN_VARIANT (type);
433
434 if (type != void_type_node)
435 type = complete_type_or_else (type, NULL_TREE);
436
437 if (!type)
438 return error_mark_node;
439
440 return get_typeid_1 (type);
441 }
442
443 /* Check whether TEST is null before returning RESULT. If TEST is used in
444 RESULT, it must have previously had a save_expr applied to it. */
445
446 static tree
447 ifnonnull (test, result)
448 tree test, result;
449 {
450 return build (COND_EXPR, TREE_TYPE (result),
451 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
452 cp_convert (TREE_TYPE (result), integer_zero_node),
453 result);
454 }
455
456 /* Generate the constant expression describing where direct base BINFO
457 appears within the PARENT. How to interpret this expression depends on
458 details of the ABI, which the runtime must be aware of. */
459
460 static tree
461 get_base_offset (binfo, parent)
462 tree binfo;
463 tree parent;
464 {
465 tree offset;
466
467 if (!TREE_VIA_VIRTUAL (binfo))
468 offset = BINFO_OFFSET (binfo);
469 else if (!vbase_offsets_in_vtable_p ())
470 {
471 tree t = BINFO_TYPE (binfo);
472 const char *name;
473 tree field;
474
475 FORMAT_VBASE_NAME (name, t);
476 field = lookup_field (parent, get_identifier (name), 0, 0);
477 offset = size_binop (FLOOR_DIV_EXPR,
478 DECL_FIELD_BITPOS (field),
479 size_int (BITS_PER_UNIT));
480 offset = convert (sizetype, offset);
481 }
482 else
483 {
484 /* Under the new ABI, we store the vtable offset at which
485 the virtual base offset can be found. */
486 tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), parent);
487 offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
488 }
489 return offset;
490 }
491
492 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
493 paper. */
494
495 static tree
496 build_dynamic_cast_1 (type, expr)
497 tree type, expr;
498 {
499 enum tree_code tc = TREE_CODE (type);
500 tree exprtype;
501 enum tree_code ec;
502 tree dcast_fn;
503 tree old_expr = expr;
504
505 if (TREE_CODE (expr) == OFFSET_REF)
506 expr = resolve_offset_ref (expr);
507
508 exprtype = TREE_TYPE (expr);
509 assert (exprtype != NULL_TREE);
510 ec = TREE_CODE (exprtype);
511
512 switch (tc)
513 {
514 case POINTER_TYPE:
515 if (ec == REFERENCE_TYPE)
516 {
517 expr = convert_from_reference (expr);
518 exprtype = TREE_TYPE (expr);
519 ec = TREE_CODE (exprtype);
520 }
521 if (ec != POINTER_TYPE)
522 goto fail;
523 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
524 goto fail;
525 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
526 goto fail;
527 if (!at_least_as_qualified_p (TREE_TYPE (type),
528 TREE_TYPE (exprtype)))
529 goto fail;
530 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
531 break;
532 /* else fall through */
533 case REFERENCE_TYPE:
534 if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
535 goto fail;
536 if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
537 goto fail;
538 break;
539 /* else fall through */
540 default:
541 goto fail;
542 }
543
544 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
545 if (ec == RECORD_TYPE)
546 {
547 exprtype = build_reference_type (exprtype);
548 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
549 LOOKUP_NORMAL, NULL_TREE);
550 ec = REFERENCE_TYPE;
551 }
552
553 if (tc == REFERENCE_TYPE)
554 {
555 if (ec != REFERENCE_TYPE)
556 goto fail;
557 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
558 goto fail;
559 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
560 goto fail;
561 if (!at_least_as_qualified_p (TREE_TYPE (type),
562 TREE_TYPE (exprtype)))
563 goto fail;
564 }
565
566 /* If *type is an unambiguous accessible base class of *exprtype,
567 convert statically. */
568 {
569 int distance;
570 tree path;
571
572 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
573 &path);
574
575 if (distance == -2)
576 {
577 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
578 TREE_TYPE (exprtype), TREE_TYPE (type));
579 return error_mark_node;
580 }
581 if (distance == -3)
582 {
583 cp_error ("dynamic_cast from `%T' to private base class `%T'",
584 TREE_TYPE (exprtype), TREE_TYPE (type));
585 return error_mark_node;
586 }
587
588 if (distance >= 0)
589 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
590 }
591
592 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
593 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
594 {
595 tree expr1;
596 /* if TYPE is `void *', return pointer to complete object. */
597 if (tc == POINTER_TYPE
598 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
599 {
600 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
601 if (TREE_CODE (expr) == ADDR_EXPR
602 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
603 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
604 return build1 (NOP_EXPR, type, expr);
605
606 /* Since expr is used twice below, save it. */
607 expr = save_expr (expr);
608
609 expr1 = build_headof (expr);
610 if (TREE_TYPE (expr1) != type)
611 expr1 = build1 (NOP_EXPR, type, expr1);
612 return ifnonnull (expr, expr1);
613 }
614 else
615 {
616 tree retval;
617 tree result, td1, td2, td3, elems, expr2;
618 tree static_type, target_type, boff;
619
620 /* If we got here, we can't convert statically. Therefore,
621 dynamic_cast<D&>(b) (b an object) cannot succeed. */
622 if (ec == REFERENCE_TYPE)
623 {
624 if (TREE_CODE (old_expr) == VAR_DECL
625 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
626 {
627 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
628 old_expr, type);
629 return throw_bad_cast ();
630 }
631 }
632 /* Ditto for dynamic_cast<D*>(&b). */
633 else if (TREE_CODE (expr) == ADDR_EXPR)
634 {
635 tree op = TREE_OPERAND (expr, 0);
636 if (TREE_CODE (op) == VAR_DECL
637 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
638 {
639 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
640 op, type);
641 retval = build_int_2 (0, 0);
642 TREE_TYPE (retval) = type;
643 return retval;
644 }
645 }
646
647 /* Since expr is used twice below, save it. */
648 expr = save_expr (expr);
649
650 expr1 = expr;
651 if (tc == REFERENCE_TYPE)
652 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
653
654 /* Build run-time conversion. */
655 expr2 = build_headof (expr1);
656
657 if (ec == POINTER_TYPE)
658 td1 = get_tinfo_decl_dynamic (build_indirect_ref (expr, NULL_PTR));
659 else
660 td1 = get_tinfo_decl_dynamic (expr);
661 td1 = decay_conversion (td1);
662
663 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
664 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
665 td2 = decay_conversion (get_tinfo_decl (target_type));
666 td3 = decay_conversion (get_tinfo_decl (static_type));
667
668 /* Determine how T and V are related. */
669 boff = get_dynamic_cast_base_type (static_type, target_type);
670
671 elems = tree_cons
672 (NULL_TREE, td1, tree_cons
673 (NULL_TREE, td2, tree_cons
674 (NULL_TREE, boff, tree_cons
675 (NULL_TREE, expr2, tree_cons
676 (NULL_TREE, td3, tree_cons
677 (NULL_TREE, expr1, NULL_TREE))))));
678
679 dcast_fn = get_identifier ("__dynamic_cast_2");
680 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
681 dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
682 else
683 {
684 tree tmp;
685
686 tmp = tree_cons
687 (NULL_TREE, TREE_TYPE (td1), tree_cons
688 (NULL_TREE, TREE_TYPE (td1), tree_cons
689 (NULL_TREE, integer_type_node, tree_cons
690 (NULL_TREE, ptr_type_node, tree_cons
691 (NULL_TREE, TREE_TYPE (td1), tree_cons
692 (NULL_TREE, ptr_type_node, void_list_node))))));
693 tmp = build_function_type (ptr_type_node, tmp);
694 dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
695 DECL_EXTERNAL (dcast_fn) = 1;
696 TREE_PUBLIC (dcast_fn) = 1;
697 DECL_ARTIFICIAL (dcast_fn) = 1;
698 pushdecl_top_level (dcast_fn);
699 make_function_rtl (dcast_fn);
700 }
701
702 mark_used (dcast_fn);
703 result = build_call
704 (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
705
706 if (tc == REFERENCE_TYPE)
707 {
708 expr1 = throw_bad_cast ();
709 result = save_expr (result);
710 return build (COND_EXPR, type, result, result, expr1);
711 }
712
713 /* Now back to the type we want from a void*. */
714 result = cp_convert (type, result);
715 return ifnonnull (expr, result);
716 }
717 }
718
719 cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype);
720 return error_mark_node;
721
722 fail:
723 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
724 expr, exprtype, type);
725 return error_mark_node;
726 }
727
728 tree
729 build_dynamic_cast (type, expr)
730 tree type, expr;
731 {
732 if (type == error_mark_node || expr == error_mark_node)
733 return error_mark_node;
734
735 if (processing_template_decl)
736 return build_min (DYNAMIC_CAST_EXPR, type, expr);
737
738 return convert_from_reference (build_dynamic_cast_1 (type, expr));
739 }
740 \f
741 /* Build and initialize various sorts of descriptors. Every descriptor
742 node has a name associated with it (the name created by mangling).
743 For this reason, we use the identifier as our access to the __*_desc
744 nodes, instead of sticking them directly in the types. Otherwise we
745 would burden all built-in types (and pointer types) with slots that
746 we don't necessarily want to use.
747
748 For each descriptor we build, we build a variable that contains
749 the descriptor's information. When we need this info at runtime,
750 all we need is access to these variables.
751
752 Note: these constructors always return the address of the descriptor
753 info, since that is simplest for their mutual interaction. */
754
755 /* Build an initializer for a __si_type_info node. */
756
757 static void
758 expand_si_desc (tdecl, type)
759 tree tdecl;
760 tree type;
761 {
762 tree t, elems, fn;
763 tree name_string = tinfo_name (type);
764
765 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
766 finish_expr_stmt (get_typeid_1 (type));
767 t = decay_conversion (get_tinfo_var (type));
768 elems = tree_cons
769 (NULL_TREE, decay_conversion (tdecl), tree_cons
770 (NULL_TREE, decay_conversion (name_string), tree_cons
771 (NULL_TREE, t, NULL_TREE)));
772
773 fn = get_identifier ("__rtti_si");
774 if (IDENTIFIER_GLOBAL_VALUE (fn))
775 fn = IDENTIFIER_GLOBAL_VALUE (fn);
776 else
777 {
778 tree tmp;
779 tmp = tree_cons
780 (NULL_TREE, ptr_type_node, tree_cons
781 (NULL_TREE, const_string_type_node, tree_cons
782 (NULL_TREE, build_pointer_type (type_info_type_node),
783 void_list_node)));
784 tmp = build_function_type (void_type_node, tmp);
785
786 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
787 DECL_EXTERNAL (fn) = 1;
788 TREE_PUBLIC (fn) = 1;
789 DECL_ARTIFICIAL (fn) = 1;
790 pushdecl_top_level (fn);
791 make_function_rtl (fn);
792 }
793
794 mark_used (fn);
795 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
796 finish_expr_stmt (fn);
797 }
798
799 /* Build an initializer for a __class_type_info node. */
800
801 static void
802 expand_class_desc (tdecl, type)
803 tree tdecl;
804 tree type;
805 {
806 tree name_string;
807 tree fn, tmp;
808
809 int i = CLASSTYPE_N_BASECLASSES (type);
810 int base_cnt = 0;
811 tree binfos = TYPE_BINFO_BASETYPES (type);
812 #if 0
813 /* See code below that used these. */
814 tree vb = CLASSTYPE_VBASECLASSES (type);
815 int n_base = i;
816 #endif
817 tree base, elems, access, offset, isvir;
818 tree elt, elts = NULL_TREE;
819
820 if (base_desc_type_node == NULL_TREE)
821 {
822 tree fields [4];
823
824 /* A reasonably close approximation of __class_type_info::base_info */
825
826 base_desc_type_node = make_aggr_type (RECORD_TYPE);
827
828 /* Actually const __user_type_info * */
829 fields [0] = build_lang_decl
830 (FIELD_DECL, NULL_TREE,
831 build_pointer_type (build_qualified_type
832 (type_info_type_node,
833 TYPE_QUAL_CONST)));
834 fields [1] = build_lang_decl
835 (FIELD_DECL, NULL_TREE,
836 flag_new_abi ? intSI_type_node : unsigned_intSI_type_node);
837 DECL_BIT_FIELD (fields[1]) = 1;
838 DECL_FIELD_SIZE (fields[1]) = 29;
839
840 fields [2] = build_lang_decl
841 (FIELD_DECL, NULL_TREE, boolean_type_node);
842 DECL_BIT_FIELD (fields[2]) = 1;
843 DECL_FIELD_SIZE (fields[2]) = 1;
844
845 /* Actually enum access */
846 fields [3] = build_lang_decl
847 (FIELD_DECL, NULL_TREE, integer_type_node);
848 DECL_BIT_FIELD (fields[3]) = 1;
849 DECL_FIELD_SIZE (fields[3]) = 2;
850
851 finish_builtin_type (base_desc_type_node, "__base_info", fields,
852 3, ptr_type_node);
853 }
854
855 while (--i >= 0)
856 {
857 tree binfo = TREE_VEC_ELT (binfos, i);
858
859 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
860 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
861 offset = get_base_offset (binfo, type);
862
863 if (TREE_VIA_PUBLIC (binfo))
864 access = access_public_node;
865 else if (TREE_VIA_PROTECTED (binfo))
866 access = access_protected_node;
867 else
868 access = access_private_node;
869 if (TREE_VIA_VIRTUAL (binfo))
870 isvir = boolean_true_node;
871 else
872 isvir = boolean_false_node;
873
874 elt = build
875 (CONSTRUCTOR, base_desc_type_node, NULL_TREE, tree_cons
876 (NULL_TREE, base, tree_cons
877 (NULL_TREE, offset, tree_cons
878 (NULL_TREE, isvir, tree_cons
879 (NULL_TREE, access, NULL_TREE)))));
880 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
881 elts = tree_cons (NULL_TREE, elt, elts);
882 base_cnt++;
883 }
884 #if 0
885 i = n_base;
886 while (vb)
887 {
888 tree b;
889 access = access_public_node;
890 while (--i >= 0)
891 {
892 b = TREE_VEC_ELT (binfos, i);
893 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
894 {
895 if (TREE_VIA_PUBLIC (b))
896 access = access_public_node;
897 else if (TREE_VIA_PROTECTED (b))
898 access = access_protected_node;
899 else
900 access = access_private_node;
901 break;
902 }
903 }
904 base = build_t_desc (BINFO_TYPE (vb), 1);
905 offset = BINFO_OFFSET (vb);
906 isvir = build_int_2 (1, 0);
907
908 base_list = tree_cons (NULL_TREE, base, base_list);
909 isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
910 acc_list = tree_cons (NULL_TREE, access, acc_list);
911 off_list = tree_cons (NULL_TREE, offset, off_list);
912
913 base_cnt++;
914 vb = TREE_CHAIN (vb);
915 }
916 #endif
917
918 name_string = tinfo_name (type);
919
920 {
921 tree arrtype = build_array_type (base_desc_type_node, NULL_TREE);
922 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
923 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
924 = TREE_STATIC (elts) = 1;
925 complete_array_type (arrtype, elts, 1);
926 }
927
928 elems = tree_cons
929 (NULL_TREE, decay_conversion (tdecl), tree_cons
930 (NULL_TREE, decay_conversion (name_string), tree_cons
931 (NULL_TREE, decay_conversion (elts), tree_cons
932 (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
933 NULL_TREE))));
934
935 fn = get_identifier ("__rtti_class");
936 if (IDENTIFIER_GLOBAL_VALUE (fn))
937 fn = IDENTIFIER_GLOBAL_VALUE (fn);
938 else
939 {
940 tmp = tree_cons
941 (NULL_TREE, ptr_type_node, tree_cons
942 (NULL_TREE, const_string_type_node, tree_cons
943 (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
944 (NULL_TREE, sizetype, void_list_node))));
945 tmp = build_function_type (void_type_node, tmp);
946
947 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
948 DECL_EXTERNAL (fn) = 1;
949 TREE_PUBLIC (fn) = 1;
950 DECL_ARTIFICIAL (fn) = 1;
951 pushdecl_top_level (fn);
952 make_function_rtl (fn);
953 }
954
955 mark_used (fn);
956 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
957 finish_expr_stmt (fn);
958 }
959
960 /* Build an initializer for a __pointer_type_info node. */
961
962 static void
963 expand_ptr_desc (tdecl, type)
964 tree tdecl;
965 tree type;
966 {
967 tree t, elems, fn;
968 tree name_string = tinfo_name (type);
969
970 type = TREE_TYPE (type);
971 finish_expr_stmt (get_typeid_1 (type));
972 t = decay_conversion (get_tinfo_var (type));
973 elems = tree_cons
974 (NULL_TREE, decay_conversion (tdecl), tree_cons
975 (NULL_TREE, decay_conversion (name_string), tree_cons
976 (NULL_TREE, t, NULL_TREE)));
977
978 fn = get_identifier ("__rtti_ptr");
979 if (IDENTIFIER_GLOBAL_VALUE (fn))
980 fn = IDENTIFIER_GLOBAL_VALUE (fn);
981 else
982 {
983 tree tmp;
984 tmp = tree_cons
985 (NULL_TREE, ptr_type_node, tree_cons
986 (NULL_TREE, const_string_type_node, tree_cons
987 (NULL_TREE, build_pointer_type (type_info_type_node),
988 void_list_node)));
989 tmp = build_function_type (void_type_node, tmp);
990
991 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
992 DECL_EXTERNAL (fn) = 1;
993 TREE_PUBLIC (fn) = 1;
994 DECL_ARTIFICIAL (fn) = 1;
995 pushdecl_top_level (fn);
996 make_function_rtl (fn);
997 }
998
999 mark_used (fn);
1000 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1001 finish_expr_stmt (fn);
1002 }
1003
1004 /* Build an initializer for a __attr_type_info node. */
1005
1006 static void
1007 expand_attr_desc (tdecl, type)
1008 tree tdecl;
1009 tree type;
1010 {
1011 tree elems, t, fn;
1012 tree name_string = tinfo_name (type);
1013 tree attrval = build_int_2 (TYPE_QUALS (type), 0);
1014
1015 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
1016 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
1017 elems = tree_cons
1018 (NULL_TREE, decay_conversion (tdecl), tree_cons
1019 (NULL_TREE, decay_conversion (name_string), tree_cons
1020 (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
1021
1022 fn = get_identifier ("__rtti_attr");
1023 if (IDENTIFIER_GLOBAL_VALUE (fn))
1024 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1025 else
1026 {
1027 tree tmp;
1028 tmp = tree_cons
1029 (NULL_TREE, ptr_type_node, tree_cons
1030 (NULL_TREE, const_string_type_node, tree_cons
1031 (NULL_TREE, integer_type_node, tree_cons
1032 (NULL_TREE, build_pointer_type (type_info_type_node),
1033 void_list_node))));
1034 tmp = build_function_type (void_type_node, tmp);
1035
1036 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1037 DECL_EXTERNAL (fn) = 1;
1038 TREE_PUBLIC (fn) = 1;
1039 DECL_ARTIFICIAL (fn) = 1;
1040 pushdecl_top_level (fn);
1041 make_function_rtl (fn);
1042 }
1043
1044 mark_used (fn);
1045 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1046 finish_expr_stmt (fn);
1047 }
1048
1049 /* Build an initializer for a type_info node that just has a name. */
1050
1051 static void
1052 expand_generic_desc (tdecl, type, fnname)
1053 tree tdecl;
1054 tree type;
1055 const char *fnname;
1056 {
1057 tree name_string = tinfo_name (type);
1058 tree elems = tree_cons
1059 (NULL_TREE, decay_conversion (tdecl), tree_cons
1060 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
1061
1062 tree fn = get_identifier (fnname);
1063 if (IDENTIFIER_GLOBAL_VALUE (fn))
1064 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1065 else
1066 {
1067 tree tmp;
1068 tmp = tree_cons
1069 (NULL_TREE, ptr_type_node, tree_cons
1070 (NULL_TREE, const_string_type_node, void_list_node));
1071 tmp = build_function_type (void_type_node, tmp);
1072
1073 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1074 DECL_EXTERNAL (fn) = 1;
1075 TREE_PUBLIC (fn) = 1;
1076 DECL_ARTIFICIAL (fn) = 1;
1077 pushdecl_top_level (fn);
1078 make_function_rtl (fn);
1079 }
1080
1081 mark_used (fn);
1082 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1083 finish_expr_stmt (fn);
1084 }
1085
1086 /* Generate the code for a type_info initialization function.
1087 Note that we take advantage of the passage
1088
1089 5.2.7 Type identification [expr.typeid]
1090
1091 Whether or not the destructor is called for the type_info object at the
1092 end of the program is unspecified.
1093
1094 and don't bother to arrange for these objects to be destroyed. It
1095 doesn't matter, anyway, since the destructors don't do anything.
1096
1097 This must only be called from toplevel (i.e. from finish_file)! */
1098
1099 void
1100 synthesize_tinfo_fn (fndecl)
1101 tree fndecl;
1102 {
1103 tree type = TREE_TYPE (DECL_NAME (fndecl));
1104 tree tmp, addr, tdecl;
1105 tree compound_stmt;
1106 tree if_stmt;
1107 tree then_clause;
1108
1109 if (at_eof)
1110 {
1111 import_export_decl (fndecl);
1112 if (DECL_REALLY_EXTERN (fndecl))
1113 return;
1114 }
1115
1116 /* Declare the static typeinfo variable. */
1117 tdecl = get_tinfo_var (type);
1118 DECL_EXTERNAL (tdecl) = 0;
1119 TREE_STATIC (tdecl) = 1;
1120 DECL_COMMON (tdecl) = 1;
1121 TREE_USED (tdecl) = 1;
1122 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1123 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0);
1124
1125 /* Begin processing the function. */
1126 start_function (NULL_TREE, fndecl, NULL_TREE,
1127 SF_DEFAULT | SF_PRE_PARSED);
1128 DECL_DEFER_OUTPUT (fndecl) = 1;
1129 store_parm_decls ();
1130 clear_last_expr ();
1131
1132 /* Begin the body of the function. */
1133 compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
1134
1135 /* For convenience, we save away the address of the static
1136 variable. */
1137 addr = decay_conversion (tdecl);
1138
1139 /* If the first word of the array (the vtable) is non-zero, we've already
1140 initialized the object, so don't do it again. */
1141 if_stmt = begin_if_stmt ();
1142 tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
1143 tmp = build_indirect_ref (tmp, 0);
1144 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
1145 finish_if_stmt_cond (tmp, if_stmt);
1146 then_clause = begin_compound_stmt (/*has_no_scope=*/0);
1147
1148 if (TREE_CODE (type) == FUNCTION_TYPE)
1149 expand_generic_desc (tdecl, type, "__rtti_func");
1150 else if (TREE_CODE (type) == ARRAY_TYPE)
1151 expand_generic_desc (tdecl, type, "__rtti_array");
1152 else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
1153 expand_attr_desc (tdecl, type);
1154 else if (TREE_CODE (type) == POINTER_TYPE)
1155 {
1156 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1157 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1158 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1159 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1160 else
1161 expand_ptr_desc (tdecl, type);
1162 }
1163 else if (TYPE_PTRMEMFUNC_P (type))
1164 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1165 else if (IS_AGGR_TYPE (type))
1166 {
1167 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1168 expand_generic_desc (tdecl, type, "__rtti_user");
1169 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
1170 && (TREE_VIA_PUBLIC
1171 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1172 expand_si_desc (tdecl, type);
1173 else
1174 expand_class_desc (tdecl, type);
1175 }
1176 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1177 expand_generic_desc (tdecl, type, "__rtti_user");
1178 else
1179 my_friendly_abort (252);
1180
1181 finish_compound_stmt (/*has_no_scope=*/0, then_clause);
1182 finish_then_clause (if_stmt);
1183 finish_if_stmt ();
1184
1185 /* OK, now return the type_info object. */
1186 tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
1187 tmp = build_indirect_ref (tmp, 0);
1188 finish_return_stmt (tmp);
1189 /* Finish the function body. */
1190 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
1191 expand_body (finish_function (lineno, 0));
1192 }