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