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