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