* cp-tree.h (make_temp_vec): Remove.
[official-gcc.git] / gcc / cp / rtti.c
blob2580eaa63a6b36dd45211e2e15b6704f85c2f19f
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).
5 This file is part of GNU CC.
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.
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.
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. */
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"
32 #ifndef INT_TYPE_SIZE
33 #define INT_TYPE_SIZE BITS_PER_WORD
34 #endif
36 extern struct obstack permanent_obstack;
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));
52 void
53 init_rtti_processing ()
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);
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. */
73 static tree
74 build_headof_sub (exp)
75 tree exp;
77 tree type = TREE_TYPE (TREE_TYPE (exp));
78 tree basetype = CLASSTYPE_RTTI (type);
79 tree binfo = get_binfo (basetype, type, 0);
81 exp = convert_pointer_to_real (binfo, exp);
82 return exp;
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. */
90 static tree
91 build_headof (exp)
92 tree exp;
94 tree type = TREE_TYPE (exp);
95 tree aref;
96 tree offset;
98 if (TREE_CODE (type) != POINTER_TYPE)
100 error ("`headof' applied to non-pointer type");
101 return error_mark_node;
103 type = TREE_TYPE (type);
105 if (!TYPE_VIRTUAL_P (type))
106 return exp;
107 if (CLASSTYPE_COM_INTERFACE (type))
109 cp_error ("RTTI not supported for COM interface type `%T'", type);
110 return error_mark_node;
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);
117 /* We use this a couple of times below, protect it. */
118 exp = save_expr (exp);
120 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
122 if (flag_vtable_thunks)
123 offset = aref;
124 else
125 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
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));
133 /* Build a call to a generic entry point taking and returning void. */
135 static tree
136 call_void_fn (name)
137 const char *name;
139 tree d = get_identifier (name);
140 tree type;
142 if (IDENTIFIER_GLOBAL_VALUE (d))
143 d = IDENTIFIER_GLOBAL_VALUE (d);
144 else
146 push_obstacks (&permanent_obstack, &permanent_obstack);
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 ();
158 mark_used (d);
159 return build_call (d, void_type_node, NULL_TREE);
162 /* Get a bad_cast node for the program to throw...
164 See libstdc++/exception.cc for __throw_bad_cast */
166 static tree
167 throw_bad_cast ()
169 return call_void_fn ("__throw_bad_cast");
172 static tree
173 throw_bad_typeid ()
175 return call_void_fn ("__throw_bad_typeid");
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. */
182 tree
183 get_tinfo_fn_dynamic (exp)
184 tree exp;
186 tree type;
188 if (exp == error_mark_node)
189 return error_mark_node;
191 if (type_unknown_p (exp))
193 error ("typeid of overloaded function");
194 return error_mark_node;
197 type = TREE_TYPE (exp);
199 /* peel back references, so they match. */
200 if (TREE_CODE (type) == REFERENCE_TYPE)
201 type = TREE_TYPE (type);
203 /* Peel off cv qualifiers. */
204 type = TYPE_MAIN_VARIANT (type);
206 if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
208 cp_error ("taking typeid of incomplete type `%T'", type);
209 return error_mark_node;
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))
215 /* build reference to type_info from vtable. */
216 tree t;
218 if (! flag_rtti)
219 error ("taking dynamic typeid of object with -fno-rtti");
220 if (CLASSTYPE_COM_INTERFACE (type))
222 cp_error ("RTTI not supported for COM interface type `%T'", type);
223 return error_mark_node;
226 /* If we don't have rtti stuff, get to a sub-object that does. */
227 if (! CLASSTYPE_VFIELDS (type))
229 exp = build_unary_op (ADDR_EXPR, exp, 0);
230 exp = build_headof_sub (exp);
231 exp = build_indirect_ref (exp, NULL_PTR);
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;
242 /* otherwise return the type_info for the static type of the expr. */
243 return get_tinfo_fn (TYPE_MAIN_VARIANT (type));
246 tree
247 build_typeid (exp)
248 tree exp;
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);
255 tree
256 build_x_typeid (exp)
257 tree exp;
259 tree cond = NULL_TREE;
260 tree type;
261 int nonnull;
263 if (! flag_rtti)
265 error ("cannot use typeid with -fno-rtti");
266 return error_mark_node;
269 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
271 error ("must #include <typeinfo> before using typeid");
272 return error_mark_node;
275 if (processing_template_decl)
276 return build_min_nt (TYPEID_EXPR, exp);
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)
284 exp = stabilize_reference (exp);
285 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
288 exp = get_tinfo_fn_dynamic (exp);
290 if (exp == error_mark_node)
291 return error_mark_node;
293 type = TREE_TYPE (tinfo_fn_type);
294 exp = build_call (exp, type, NULL_TREE);
296 if (cond)
298 tree bad = throw_bad_typeid ();
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);
306 return convert_from_reference (exp);
309 static tree
310 get_tinfo_var (type)
311 tree type;
313 tree tname = build_overload_with_type (get_identifier ("__ti"), type);
314 tree tdecl, arrtype;
315 int size;
317 if (IDENTIFIER_GLOBAL_VALUE (tname))
318 return IDENTIFIER_GLOBAL_VALUE (tname);
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))
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);
340 else
341 size = 2 * POINTER_SIZE;
343 push_obstacks (&permanent_obstack, &permanent_obstack);
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)));
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 ();
359 pop_obstacks ();
361 return tdecl;
364 tree
365 get_tinfo_fn (type)
366 tree type;
368 tree name;
369 tree d;
371 if (TREE_CODE (type) == OFFSET_TYPE)
372 type = TREE_TYPE (type);
373 if (TREE_CODE (type) == METHOD_TYPE)
374 type = build_function_type (TREE_TYPE (type),
375 TREE_CHAIN (TYPE_ARG_TYPES (type)));
377 name = build_overload_with_type (tinfo_fn_id, type);
379 if (IDENTIFIER_GLOBAL_VALUE (name))
380 return IDENTIFIER_GLOBAL_VALUE (name);
382 push_obstacks (&permanent_obstack, &permanent_obstack);
384 d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type);
385 DECL_EXTERNAL (d) = 1;
386 TREE_PUBLIC (d) = 1;
387 DECL_ARTIFICIAL (d) = 1;
388 DECL_NOT_REALLY_EXTERN (d) = 1;
389 SET_DECL_TINFO_FN_P (d);
390 TREE_TYPE (name) = type;
392 pushdecl_top_level (d);
393 make_function_rtl (d);
394 mark_used (d);
395 mark_inline_for_output (d);
396 pop_obstacks ();
398 return d;
401 tree
402 get_typeid_1 (type)
403 tree type;
405 tree t;
407 t = build_call
408 (get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
409 return convert_from_reference (t);
412 /* Return the type_info object for TYPE, creating it if necessary. */
414 tree
415 get_typeid (type)
416 tree type;
418 if (type == error_mark_node)
419 return error_mark_node;
421 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
423 error ("must #include <typeinfo> before using typeid");
424 return error_mark_node;
427 if (processing_template_decl)
428 return build_min_nt (TYPEID_EXPR, type);
430 /* If the type of the type-id is a reference type, the result of the
431 typeid expression refers to a type_info object representing the
432 referenced type. */
433 if (TREE_CODE (type) == REFERENCE_TYPE)
434 type = TREE_TYPE (type);
436 /* The top-level cv-qualifiers of the lvalue expression or the type-id
437 that is the operand of typeid are always ignored. */
438 type = TYPE_MAIN_VARIANT (type);
440 if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
442 cp_error ("taking typeid of incomplete type `%T'", type);
443 return error_mark_node;
446 return get_typeid_1 (type);
449 /* Check whether TEST is null before returning RESULT. If TEST is used in
450 RESULT, it must have previously had a save_expr applied to it. */
452 static tree
453 ifnonnull (test, result)
454 tree test, result;
456 return build (COND_EXPR, TREE_TYPE (result),
457 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
458 cp_convert (TREE_TYPE (result), integer_zero_node),
459 result);
462 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
463 paper. */
465 static tree
466 build_dynamic_cast_1 (type, expr)
467 tree type, expr;
469 enum tree_code tc = TREE_CODE (type);
470 tree exprtype;
471 enum tree_code ec;
472 tree dcast_fn;
473 tree old_expr = expr;
475 if (TREE_CODE (expr) == OFFSET_REF)
476 expr = resolve_offset_ref (expr);
478 exprtype = TREE_TYPE (expr);
479 assert (exprtype != NULL_TREE);
480 ec = TREE_CODE (exprtype);
482 switch (tc)
484 case POINTER_TYPE:
485 if (ec == REFERENCE_TYPE)
487 expr = convert_from_reference (expr);
488 exprtype = TREE_TYPE (expr);
489 ec = TREE_CODE (exprtype);
491 if (ec != POINTER_TYPE)
492 goto fail;
493 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
494 goto fail;
495 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
496 goto fail;
497 if (!at_least_as_qualified_p (TREE_TYPE (type),
498 TREE_TYPE (exprtype)))
499 goto fail;
500 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
501 break;
502 /* else fall through */
503 case REFERENCE_TYPE:
504 if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
505 goto fail;
506 if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
507 goto fail;
508 break;
509 /* else fall through */
510 default:
511 goto fail;
514 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
515 if (ec == RECORD_TYPE)
517 exprtype = build_reference_type (exprtype);
518 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
519 LOOKUP_NORMAL, NULL_TREE);
520 ec = REFERENCE_TYPE;
523 if (tc == REFERENCE_TYPE)
525 if (ec != REFERENCE_TYPE)
526 goto fail;
527 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
528 goto fail;
529 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
530 goto fail;
531 if (!at_least_as_qualified_p (TREE_TYPE (type),
532 TREE_TYPE (exprtype)))
533 goto fail;
536 /* If *type is an unambiguous accessible base class of *exprtype,
537 convert statically. */
539 int distance;
540 tree path;
542 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
543 &path);
545 if (distance == -2)
547 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
548 TREE_TYPE (exprtype), TREE_TYPE (type));
549 return error_mark_node;
551 if (distance == -3)
553 cp_error ("dynamic_cast from `%T' to private base class `%T'",
554 TREE_TYPE (exprtype), TREE_TYPE (type));
555 return error_mark_node;
558 if (distance >= 0)
559 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
562 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
563 if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype)))
565 tree expr1;
566 /* if TYPE is `void *', return pointer to complete object. */
567 if (tc == POINTER_TYPE
568 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
570 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
571 if (TREE_CODE (expr) == ADDR_EXPR
572 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
573 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
574 return build1 (NOP_EXPR, type, expr);
576 /* Since expr is used twice below, save it. */
577 expr = save_expr (expr);
579 expr1 = build_headof (expr);
580 if (TREE_TYPE (expr1) != type)
581 expr1 = build1 (NOP_EXPR, type, expr1);
582 return ifnonnull (expr, expr1);
584 else
586 tree retval;
587 tree result, td1, td2, td3, elems, expr2;
588 tree static_type, target_type, boff;
590 /* If we got here, we can't convert statically. Therefore,
591 dynamic_cast<D&>(b) (b an object) cannot succeed. */
592 if (ec == REFERENCE_TYPE)
594 if (TREE_CODE (old_expr) == VAR_DECL
595 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
597 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
598 old_expr, type);
599 return throw_bad_cast ();
602 /* Ditto for dynamic_cast<D*>(&b). */
603 else if (TREE_CODE (expr) == ADDR_EXPR)
605 tree op = TREE_OPERAND (expr, 0);
606 if (TREE_CODE (op) == VAR_DECL
607 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
609 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
610 op, type);
611 retval = build_int_2 (0, 0);
612 TREE_TYPE (retval) = type;
613 return retval;
617 /* Since expr is used twice below, save it. */
618 expr = save_expr (expr);
620 expr1 = expr;
621 if (tc == REFERENCE_TYPE)
622 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
624 /* Build run-time conversion. */
625 expr2 = build_headof (expr1);
627 if (ec == POINTER_TYPE)
628 td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR));
629 else
630 td1 = get_tinfo_fn_dynamic (expr);
631 td1 = decay_conversion (td1);
633 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
634 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
635 td2 = decay_conversion (get_tinfo_fn (target_type));
636 td3 = decay_conversion (get_tinfo_fn (static_type));
638 /* Determine how T and V are related. */
639 boff = get_dynamic_cast_base_type (static_type, target_type);
641 elems = tree_cons
642 (NULL_TREE, td1, tree_cons
643 (NULL_TREE, td2, tree_cons
644 (NULL_TREE, boff, tree_cons
645 (NULL_TREE, expr2, tree_cons
646 (NULL_TREE, td3, tree_cons
647 (NULL_TREE, expr1, NULL_TREE))))));
649 dcast_fn = get_identifier ("__dynamic_cast_2");
650 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
651 dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
652 else
654 tree tmp;
656 push_obstacks (&permanent_obstack, &permanent_obstack);
657 tmp = tree_cons
658 (NULL_TREE, TREE_TYPE (td1), tree_cons
659 (NULL_TREE, TREE_TYPE (td1), tree_cons
660 (NULL_TREE, integer_type_node, tree_cons
661 (NULL_TREE, ptr_type_node, tree_cons
662 (NULL_TREE, TREE_TYPE (td1), tree_cons
663 (NULL_TREE, ptr_type_node, void_list_node))))));
664 tmp = build_function_type (ptr_type_node, tmp);
665 dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
666 DECL_EXTERNAL (dcast_fn) = 1;
667 TREE_PUBLIC (dcast_fn) = 1;
668 DECL_ARTIFICIAL (dcast_fn) = 1;
669 pushdecl_top_level (dcast_fn);
670 make_function_rtl (dcast_fn);
671 pop_obstacks ();
674 mark_used (dcast_fn);
675 result = build_call
676 (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
678 if (tc == REFERENCE_TYPE)
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);
689 /* Now back to the type we want from a void*. */
690 result = cp_convert (type, result);
691 return ifnonnull (expr, result);
695 fail:
696 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
697 expr, exprtype, type);
698 return error_mark_node;
701 tree
702 build_dynamic_cast (type, expr)
703 tree type, expr;
705 if (type == error_mark_node || expr == error_mark_node)
706 return error_mark_node;
708 if (processing_template_decl)
709 return build_min (DYNAMIC_CAST_EXPR, type, expr);
711 return convert_from_reference (build_dynamic_cast_1 (type, expr));
714 /* Build and initialize various sorts of descriptors. Every descriptor
715 node has a name associated with it (the name created by mangling).
716 For this reason, we use the identifier as our access to the __*_desc
717 nodes, instead of sticking them directly in the types. Otherwise we
718 would burden all built-in types (and pointer types) with slots that
719 we don't necessarily want to use.
721 For each descriptor we build, we build a variable that contains
722 the descriptor's information. When we need this info at runtime,
723 all we need is access to these variables.
725 Note: these constructors always return the address of the descriptor
726 info, since that is simplest for their mutual interaction. */
728 /* Build an initializer for a __si_type_info node. */
730 static void
731 expand_si_desc (tdecl, type)
732 tree tdecl;
733 tree type;
735 tree t, elems, fn;
736 const char *name = build_overload_name (type, 1, 1);
737 tree name_string = combine_strings (build_string (strlen (name)+1, name));
739 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
740 finish_expr_stmt (get_typeid_1 (type));
741 t = decay_conversion (get_tinfo_var (type));
742 elems = tree_cons
743 (NULL_TREE, decay_conversion (tdecl), tree_cons
744 (NULL_TREE, decay_conversion (name_string), tree_cons
745 (NULL_TREE, t, NULL_TREE)));
747 fn = get_identifier ("__rtti_si");
748 if (IDENTIFIER_GLOBAL_VALUE (fn))
749 fn = IDENTIFIER_GLOBAL_VALUE (fn);
750 else
752 tree tmp;
753 push_obstacks (&permanent_obstack, &permanent_obstack);
754 tmp = tree_cons
755 (NULL_TREE, ptr_type_node, tree_cons
756 (NULL_TREE, const_string_type_node, tree_cons
757 (NULL_TREE, build_pointer_type (type_info_type_node),
758 void_list_node)));
759 tmp = build_function_type (void_type_node, tmp);
761 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
762 DECL_EXTERNAL (fn) = 1;
763 TREE_PUBLIC (fn) = 1;
764 DECL_ARTIFICIAL (fn) = 1;
765 pushdecl_top_level (fn);
766 make_function_rtl (fn);
767 pop_obstacks ();
770 mark_used (fn);
771 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
772 finish_expr_stmt (fn);
775 /* Build an initializer for a __class_type_info node. */
777 static void
778 expand_class_desc (tdecl, type)
779 tree tdecl;
780 tree type;
782 tree name_string;
783 tree fn, tmp;
784 const char *name;
786 int i = CLASSTYPE_N_BASECLASSES (type);
787 int base_cnt = 0;
788 tree binfos = TYPE_BINFO_BASETYPES (type);
789 #if 0
790 /* See code below that used these. */
791 tree vb = CLASSTYPE_VBASECLASSES (type);
792 int n_base = i;
793 #endif
794 tree base, elems, access, offset, isvir;
795 tree elt, elts = NULL_TREE;
796 static tree base_info_type_node;
798 if (base_info_type_node == NULL_TREE)
800 tree fields [4];
802 /* A reasonably close approximation of __class_type_info::base_info */
804 push_obstacks (&permanent_obstack, &permanent_obstack);
805 base_info_type_node = make_lang_type (RECORD_TYPE);
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, unsigned_intSI_type_node);
815 DECL_BIT_FIELD (fields[1]) = 1;
816 DECL_FIELD_SIZE (fields[1]) = 29;
818 fields [2] = build_lang_decl
819 (FIELD_DECL, NULL_TREE, boolean_type_node);
820 DECL_BIT_FIELD (fields[2]) = 1;
821 DECL_FIELD_SIZE (fields[2]) = 1;
823 /* Actually enum access */
824 fields [3] = build_lang_decl
825 (FIELD_DECL, NULL_TREE, integer_type_node);
826 DECL_BIT_FIELD (fields[3]) = 1;
827 DECL_FIELD_SIZE (fields[3]) = 2;
829 finish_builtin_type (base_info_type_node, "__base_info", fields,
830 3, ptr_type_node);
831 pop_obstacks ();
834 while (--i >= 0)
836 tree binfo = TREE_VEC_ELT (binfos, i);
838 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
839 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
841 if (TREE_VIA_VIRTUAL (binfo))
843 tree t = BINFO_TYPE (binfo);
844 const char *name;
845 tree field;
847 FORMAT_VBASE_NAME (name, t);
848 field = lookup_field (type, get_identifier (name), 0, 0);
849 offset = size_binop (FLOOR_DIV_EXPR,
850 DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT));
851 offset = convert (sizetype, offset);
853 else
854 offset = BINFO_OFFSET (binfo);
856 if (TREE_VIA_PUBLIC (binfo))
857 access = access_public_node;
858 else if (TREE_VIA_PROTECTED (binfo))
859 access = access_protected_node;
860 else
861 access = access_private_node;
862 if (TREE_VIA_VIRTUAL (binfo))
863 isvir = boolean_true_node;
864 else
865 isvir = boolean_false_node;
867 elt = build
868 (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons
869 (NULL_TREE, base, tree_cons
870 (NULL_TREE, offset, tree_cons
871 (NULL_TREE, isvir, tree_cons
872 (NULL_TREE, access, NULL_TREE)))));
873 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
874 elts = tree_cons (NULL_TREE, elt, elts);
875 base_cnt++;
877 #if 0
878 i = n_base;
879 while (vb)
881 tree b;
882 access = access_public_node;
883 while (--i >= 0)
885 b = TREE_VEC_ELT (binfos, i);
886 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
888 if (TREE_VIA_PUBLIC (b))
889 access = access_public_node;
890 else if (TREE_VIA_PROTECTED (b))
891 access = access_protected_node;
892 else
893 access = access_private_node;
894 break;
897 base = build_t_desc (BINFO_TYPE (vb), 1);
898 offset = BINFO_OFFSET (vb);
899 isvir = build_int_2 (1, 0);
901 base_list = tree_cons (NULL_TREE, base, base_list);
902 isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
903 acc_list = tree_cons (NULL_TREE, access, acc_list);
904 off_list = tree_cons (NULL_TREE, offset, off_list);
906 base_cnt++;
907 vb = TREE_CHAIN (vb);
909 #endif
911 name = build_overload_name (type, 1, 1);
912 name_string = combine_strings (build_string (strlen (name)+1, name));
915 tree arrtype = build_array_type (base_info_type_node, NULL_TREE);
916 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
917 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
918 = TREE_STATIC (elts) = 1;
919 complete_array_type (arrtype, elts, 1);
922 elems = tree_cons
923 (NULL_TREE, decay_conversion (tdecl), tree_cons
924 (NULL_TREE, decay_conversion (name_string), tree_cons
925 (NULL_TREE, decay_conversion (elts), tree_cons
926 (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
927 NULL_TREE))));
929 fn = get_identifier ("__rtti_class");
930 if (IDENTIFIER_GLOBAL_VALUE (fn))
931 fn = IDENTIFIER_GLOBAL_VALUE (fn);
932 else
934 push_obstacks (&permanent_obstack, &permanent_obstack);
935 tmp = tree_cons
936 (NULL_TREE, ptr_type_node, tree_cons
937 (NULL_TREE, const_string_type_node, tree_cons
938 (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons
939 (NULL_TREE, sizetype, void_list_node))));
940 tmp = build_function_type (void_type_node, tmp);
942 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
943 DECL_EXTERNAL (fn) = 1;
944 TREE_PUBLIC (fn) = 1;
945 DECL_ARTIFICIAL (fn) = 1;
946 pushdecl_top_level (fn);
947 make_function_rtl (fn);
948 pop_obstacks ();
951 mark_used (fn);
952 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
953 finish_expr_stmt (fn);
956 /* Build an initializer for a __pointer_type_info node. */
958 static void
959 expand_ptr_desc (tdecl, type)
960 tree tdecl;
961 tree type;
963 tree t, elems, fn;
964 const char *name = build_overload_name (type, 1, 1);
965 tree name_string = combine_strings (build_string (strlen (name)+1, name));
967 type = TREE_TYPE (type);
968 finish_expr_stmt (get_typeid_1 (type));
969 t = decay_conversion (get_tinfo_var (type));
970 elems = tree_cons
971 (NULL_TREE, decay_conversion (tdecl), tree_cons
972 (NULL_TREE, decay_conversion (name_string), tree_cons
973 (NULL_TREE, t, NULL_TREE)));
975 fn = get_identifier ("__rtti_ptr");
976 if (IDENTIFIER_GLOBAL_VALUE (fn))
977 fn = IDENTIFIER_GLOBAL_VALUE (fn);
978 else
980 tree tmp;
981 push_obstacks (&permanent_obstack, &permanent_obstack);
982 tmp = tree_cons
983 (NULL_TREE, ptr_type_node, tree_cons
984 (NULL_TREE, const_string_type_node, tree_cons
985 (NULL_TREE, build_pointer_type (type_info_type_node),
986 void_list_node)));
987 tmp = build_function_type (void_type_node, tmp);
989 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
990 DECL_EXTERNAL (fn) = 1;
991 TREE_PUBLIC (fn) = 1;
992 DECL_ARTIFICIAL (fn) = 1;
993 pushdecl_top_level (fn);
994 make_function_rtl (fn);
995 pop_obstacks ();
998 mark_used (fn);
999 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1000 finish_expr_stmt (fn);
1003 /* Build an initializer for a __attr_type_info node. */
1005 static void
1006 expand_attr_desc (tdecl, type)
1007 tree tdecl;
1008 tree type;
1010 tree elems, t, fn;
1011 const char *name = build_overload_name (type, 1, 1);
1012 tree name_string = combine_strings (build_string (strlen (name)+1, name));
1013 tree attrval = build_int_2 (TYPE_QUALS (type), 0);
1015 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
1016 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
1017 elems = tree_cons
1018 (NULL_TREE, decay_conversion (tdecl), tree_cons
1019 (NULL_TREE, decay_conversion (name_string), tree_cons
1020 (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
1022 fn = get_identifier ("__rtti_attr");
1023 if (IDENTIFIER_GLOBAL_VALUE (fn))
1024 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1025 else
1027 tree tmp;
1028 push_obstacks (&permanent_obstack, &permanent_obstack);
1029 tmp = tree_cons
1030 (NULL_TREE, ptr_type_node, tree_cons
1031 (NULL_TREE, const_string_type_node, tree_cons
1032 (NULL_TREE, integer_type_node, tree_cons
1033 (NULL_TREE, build_pointer_type (type_info_type_node),
1034 void_list_node))));
1035 tmp = build_function_type (void_type_node, tmp);
1037 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1038 DECL_EXTERNAL (fn) = 1;
1039 TREE_PUBLIC (fn) = 1;
1040 DECL_ARTIFICIAL (fn) = 1;
1041 pushdecl_top_level (fn);
1042 make_function_rtl (fn);
1043 pop_obstacks ();
1046 mark_used (fn);
1047 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1048 finish_expr_stmt (fn);
1051 /* Build an initializer for a type_info node that just has a name. */
1053 static void
1054 expand_generic_desc (tdecl, type, fnname)
1055 tree tdecl;
1056 tree type;
1057 const char *fnname;
1059 const char *name = build_overload_name (type, 1, 1);
1060 tree name_string = combine_strings (build_string (strlen (name)+1, name));
1061 tree elems = tree_cons
1062 (NULL_TREE, decay_conversion (tdecl), tree_cons
1063 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
1065 tree fn = get_identifier (fnname);
1066 if (IDENTIFIER_GLOBAL_VALUE (fn))
1067 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1068 else
1070 tree tmp;
1071 push_obstacks (&permanent_obstack, &permanent_obstack);
1072 tmp = tree_cons
1073 (NULL_TREE, ptr_type_node, tree_cons
1074 (NULL_TREE, const_string_type_node, void_list_node));
1075 tmp = build_function_type (void_type_node, tmp);
1077 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1078 DECL_EXTERNAL (fn) = 1;
1079 TREE_PUBLIC (fn) = 1;
1080 DECL_ARTIFICIAL (fn) = 1;
1081 pushdecl_top_level (fn);
1082 make_function_rtl (fn);
1083 pop_obstacks ();
1086 mark_used (fn);
1087 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1088 finish_expr_stmt (fn);
1091 /* Generate the code for a type_info initialization function.
1092 Note that we take advantage of the passage
1094 5.2.7 Type identification [expr.typeid]
1096 Whether or not the destructor is called for the type_info object at the
1097 end of the program is unspecified.
1099 and don't bother to arrange for these objects to be destroyed. It
1100 doesn't matter, anyway, since the destructors don't do anything.
1102 This must only be called from toplevel (i.e. from finish_file)! */
1104 void
1105 synthesize_tinfo_fn (fndecl)
1106 tree fndecl;
1108 tree type = TREE_TYPE (DECL_NAME (fndecl));
1109 tree tmp, addr, tdecl;
1110 tree compound_stmt;
1111 tree if_stmt;
1112 tree then_clause;
1114 if (at_eof)
1116 import_export_decl (fndecl);
1117 if (DECL_REALLY_EXTERN (fndecl))
1118 return;
1121 /* Declare the static typeinfo variable. */
1122 tdecl = get_tinfo_var (type);
1123 DECL_EXTERNAL (tdecl) = 0;
1124 TREE_STATIC (tdecl) = 1;
1125 DECL_COMMON (tdecl) = 1;
1126 TREE_USED (tdecl) = 1;
1127 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1128 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
1130 /* Begin processing the function. */
1131 start_function (NULL_TREE, fndecl, NULL_TREE,
1132 SF_DEFAULT | SF_PRE_PARSED);
1133 store_parm_decls ();
1134 clear_last_expr ();
1136 /* Begin the body of the function. */
1137 compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
1139 /* For convenience, we save away the address of the static
1140 variable. */
1141 addr = decay_conversion (tdecl);
1143 /* If the first word of the array (the vtable) is non-zero, we've already
1144 initialized the object, so don't do it again. */
1145 if_stmt = begin_if_stmt ();
1146 tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
1147 tmp = build_indirect_ref (tmp, 0);
1148 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
1149 finish_if_stmt_cond (tmp, if_stmt);
1150 then_clause = begin_compound_stmt (/*has_no_scope=*/0);
1152 if (TREE_CODE (type) == FUNCTION_TYPE)
1153 expand_generic_desc (tdecl, type, "__rtti_func");
1154 else if (TREE_CODE (type) == ARRAY_TYPE)
1155 expand_generic_desc (tdecl, type, "__rtti_array");
1156 else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
1157 expand_attr_desc (tdecl, type);
1158 else if (TREE_CODE (type) == POINTER_TYPE)
1160 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1161 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1162 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1163 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1164 else
1165 expand_ptr_desc (tdecl, type);
1167 else if (TYPE_PTRMEMFUNC_P (type))
1168 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1169 else if (IS_AGGR_TYPE (type))
1171 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1172 expand_generic_desc (tdecl, type, "__rtti_user");
1173 else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
1174 && (TREE_VIA_PUBLIC
1175 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1176 expand_si_desc (tdecl, type);
1177 else
1178 expand_class_desc (tdecl, type);
1180 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1181 expand_generic_desc (tdecl, type, "__rtti_user");
1182 else
1183 my_friendly_abort (252);
1185 finish_compound_stmt (/*has_no_scope=*/0, then_clause);
1186 finish_then_clause (if_stmt);
1187 finish_if_stmt ();
1189 /* OK, now return the type_info object. */
1190 tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
1191 tmp = build_indirect_ref (tmp, 0);
1192 finish_return_stmt (tmp);
1193 /* Finish the function body. */
1194 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
1195 expand_body (finish_function (lineno, 0));