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)
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. */
33 #define INT_TYPE_SIZE BITS_PER_WORD
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 tree type_info_type_node;
57 init_rtti_processing ()
60 push_namespace (get_identifier ("std"));
61 type_info_type_node = xref_tag
62 (class_type_node, get_identifier ("type_info"), 1);
65 tinfo_fn_id = get_identifier ("__tf");
66 tinfo_fn_type = build_function_type
67 (build_reference_type (build_qualified_type (type_info_type_node,
72 /* Given a pointer to an object with at least one virtual table
73 pointer somewhere, return a pointer to a possible sub-object that
74 has a virtual table pointer in it that is the vtable parent for
78 build_headof_sub (exp)
81 tree type = TREE_TYPE (TREE_TYPE (exp));
82 tree basetype = CLASSTYPE_RTTI (type);
83 tree binfo = get_binfo (basetype, type, 0);
85 exp = convert_pointer_to_real (binfo, exp);
89 /* Given the expression EXP of type `class *', return the head of the
90 object pointed to by EXP with type cv void*, if the class has any
91 virtual functions (TYPE_VIRTUAL_P), else just return the
98 tree type = TREE_TYPE (exp);
102 if (TREE_CODE (type) != POINTER_TYPE)
104 error ("`headof' applied to non-pointer type");
105 return error_mark_node;
107 type = TREE_TYPE (type);
109 if (!TYPE_VIRTUAL_P (type))
111 if (CLASSTYPE_COM_INTERFACE (type))
113 cp_error ("RTTI not supported for COM interface type `%T'", type);
114 return error_mark_node;
117 /* If we don't have rtti stuff, get to a sub-object that does. */
118 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
119 exp = build_headof_sub (exp);
121 /* We use this a couple of times below, protect it. */
122 exp = save_expr (exp);
124 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
126 if (flag_vtable_thunks)
129 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
131 type = build_qualified_type (ptr_type_node,
132 CP_TYPE_QUALS (TREE_TYPE (exp)));
133 return build (PLUS_EXPR, type, exp,
134 cp_convert (ptrdiff_type_node, offset));
137 /* Build a call to a generic entry point taking and returning void. */
143 tree d = get_identifier (name);
146 if (IDENTIFIER_GLOBAL_VALUE (d))
147 d = IDENTIFIER_GLOBAL_VALUE (d);
150 push_obstacks (&permanent_obstack, &permanent_obstack);
152 type = build_function_type (void_type_node, void_list_node);
153 d = build_lang_decl (FUNCTION_DECL, d, type);
154 DECL_EXTERNAL (d) = 1;
156 DECL_ARTIFICIAL (d) = 1;
157 pushdecl_top_level (d);
158 make_function_rtl (d);
163 return build_call (d, void_type_node, NULL_TREE);
166 /* Get a bad_cast node for the program to throw...
168 See libstdc++/exception.cc for __throw_bad_cast */
173 return call_void_fn ("__throw_bad_cast");
179 return call_void_fn ("__throw_bad_typeid");
182 /* Return the type_info function associated with the expression EXP. If
183 EXP is a reference to a polymorphic class, return the dynamic type;
184 otherwise return the static type of the expression. */
187 get_tinfo_fn_dynamic (exp)
192 if (exp == error_mark_node)
193 return error_mark_node;
195 if (type_unknown_p (exp))
197 error ("typeid of overloaded function");
198 return error_mark_node;
201 type = TREE_TYPE (exp);
203 /* peel back references, so they match. */
204 if (TREE_CODE (type) == REFERENCE_TYPE)
205 type = TREE_TYPE (type);
207 /* Peel off cv qualifiers. */
208 type = TYPE_MAIN_VARIANT (type);
210 if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
212 cp_error ("taking typeid of incomplete type `%T'", type);
213 return error_mark_node;
216 /* If exp is a reference to polymorphic type, get the real type_info. */
217 if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
219 /* build reference to type_info from vtable. */
223 error ("taking dynamic typeid of object with -fno-rtti");
224 if (CLASSTYPE_COM_INTERFACE (type))
226 cp_error ("RTTI not supported for COM interface type `%T'", type);
227 return error_mark_node;
230 /* If we don't have rtti stuff, get to a sub-object that does. */
231 if (! CLASSTYPE_VFIELDS (type))
233 exp = build_unary_op (ADDR_EXPR, exp, 0);
234 exp = build_headof_sub (exp);
235 exp = build_indirect_ref (exp, NULL_PTR);
238 if (flag_vtable_thunks)
239 t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
241 t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
242 TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
246 /* otherwise return the type_info for the static type of the expr. */
247 return get_tinfo_fn (TYPE_MAIN_VARIANT (type));
254 exp = get_tinfo_fn_dynamic (exp);
255 exp = build_call (exp, TREE_TYPE (tinfo_fn_type), NULL_TREE);
256 return convert_from_reference (exp);
263 tree cond = NULL_TREE;
269 error ("cannot use typeid with -fno-rtti");
270 return error_mark_node;
273 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
275 error ("must #include <typeinfo> before using typeid");
276 return error_mark_node;
279 if (processing_template_decl)
280 return build_min_nt (TYPEID_EXPR, exp);
282 if (TREE_CODE (exp) == INDIRECT_REF
283 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
284 && TYPE_VIRTUAL_P (TREE_TYPE (exp))
285 && ! resolves_to_fixed_type_p (exp, &nonnull)
288 exp = stabilize_reference (exp);
289 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
292 exp = get_tinfo_fn_dynamic (exp);
294 if (exp == error_mark_node)
295 return error_mark_node;
297 type = TREE_TYPE (tinfo_fn_type);
298 exp = build_call (exp, type, NULL_TREE);
302 tree bad = throw_bad_typeid ();
304 bad = build_compound_expr
305 (expr_tree_cons (NULL_TREE, bad, build_expr_list
306 (NULL_TREE, cp_convert (type, integer_zero_node))));
307 exp = build (COND_EXPR, type, cond, exp, bad);
310 return convert_from_reference (exp);
317 tree tname = build_overload_with_type (get_identifier ("__ti"), type);
321 if (IDENTIFIER_GLOBAL_VALUE (tname))
322 return IDENTIFIER_GLOBAL_VALUE (tname);
324 /* Figure out how much space we need to allocate for the type_info object.
325 If our struct layout or the type_info classes are changed, this will
326 need to be modified. */
327 if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
328 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
329 else if (TREE_CODE (type) == POINTER_TYPE
330 && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
331 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
332 size = 3 * POINTER_SIZE;
333 else if (IS_AGGR_TYPE (type))
335 if (CLASSTYPE_N_BASECLASSES (type) == 0)
336 size = 2 * POINTER_SIZE;
337 else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
339 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
340 size = 3 * POINTER_SIZE;
342 size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
345 size = 2 * POINTER_SIZE;
347 push_obstacks (&permanent_obstack, &permanent_obstack);
349 /* The type for a character array of the appropriate size. */
350 arrtype = build_cplus_array_type
351 (unsigned_char_type_node,
352 build_index_type (size_int (size / BITS_PER_UNIT - 1)));
354 tdecl = build_decl (VAR_DECL, tname, arrtype);
355 TREE_PUBLIC (tdecl) = 1;
356 DECL_EXTERNAL (tdecl) = 1;
357 DECL_ARTIFICIAL (tdecl) = 1;
358 pushdecl_top_level (tdecl);
359 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
366 /* Returns the decl for a function which will return a type_info node for
367 TYPE. This version does not mark the function used, for use in
368 set_rtti_entry; for the vtable case, we'll get marked in
369 finish_vtable_vardecl, when we know that we want to be emitted.
371 We do this to avoid emitting the tinfo node itself, since we don't
372 currently support DECL_DEFER_OUTPUT for variables. Also, we don't
373 associate constant pools with their functions properly, so we would
374 emit string constants and such even though we don't emit the actual
375 function. When those bugs are fixed, this function should go away. */
378 get_tinfo_fn_unused (type)
384 if (TREE_CODE (type) == OFFSET_TYPE)
385 type = TREE_TYPE (type);
386 if (TREE_CODE (type) == METHOD_TYPE)
387 type = build_function_type (TREE_TYPE (type),
388 TREE_CHAIN (TYPE_ARG_TYPES (type)));
390 name = build_overload_with_type (tinfo_fn_id, type);
392 if (IDENTIFIER_GLOBAL_VALUE (name))
393 return IDENTIFIER_GLOBAL_VALUE (name);
395 push_obstacks (&permanent_obstack, &permanent_obstack);
397 d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type);
398 DECL_EXTERNAL (d) = 1;
400 DECL_ARTIFICIAL (d) = 1;
401 DECL_NOT_REALLY_EXTERN (d) = 1;
402 SET_DECL_TINFO_FN_P (d);
403 TREE_TYPE (name) = copy_to_permanent (type);
405 pushdecl_top_level (d);
406 make_function_rtl (d);
407 mark_inline_for_output (d);
413 /* Likewise, but also mark it used. Called by various EH and RTTI code. */
419 tree d = get_tinfo_fn_unused (type);
431 (get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
432 return convert_from_reference (t);
435 /* Return the type_info object for TYPE, creating it if necessary. */
441 if (type == error_mark_node)
442 return error_mark_node;
444 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
446 error ("must #include <typeinfo> before using typeid");
447 return error_mark_node;
451 error ("requesting typeid with -fno-rtti");
453 if (processing_template_decl)
454 return build_min_nt (TYPEID_EXPR, type);
456 /* If the type of the type-id is a reference type, the result of the
457 typeid expression refers to a type_info object representing the
459 if (TREE_CODE (type) == REFERENCE_TYPE)
460 type = TREE_TYPE (type);
462 /* The top-level cv-qualifiers of the lvalue expression or the type-id
463 that is the operand of typeid are always ignored. */
464 type = TYPE_MAIN_VARIANT (type);
466 if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
468 cp_error ("taking typeid of incomplete type `%T'", type);
469 return error_mark_node;
472 return get_typeid_1 (type);
475 /* Check whether TEST is null before returning RESULT. If TEST is used in
476 RESULT, it must have previously had a save_expr applied to it. */
479 ifnonnull (test, result)
482 return build (COND_EXPR, TREE_TYPE (result),
483 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
484 cp_convert (TREE_TYPE (result), integer_zero_node),
488 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
492 build_dynamic_cast_1 (type, expr)
495 enum tree_code tc = TREE_CODE (type);
499 tree old_expr = expr;
501 if (TREE_CODE (expr) == OFFSET_REF)
502 expr = resolve_offset_ref (expr);
504 exprtype = TREE_TYPE (expr);
505 assert (exprtype != NULL_TREE);
506 ec = TREE_CODE (exprtype);
511 if (ec == REFERENCE_TYPE)
513 expr = convert_from_reference (expr);
514 exprtype = TREE_TYPE (expr);
515 ec = TREE_CODE (exprtype);
517 if (ec != POINTER_TYPE)
519 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
521 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
523 if (!at_least_as_qualified_p (TREE_TYPE (type),
524 TREE_TYPE (exprtype)))
526 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
528 /* else fall through */
530 if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
532 if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
535 /* else fall through */
540 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
541 if (ec == RECORD_TYPE)
543 exprtype = build_reference_type (exprtype);
544 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
545 LOOKUP_NORMAL, NULL_TREE);
549 if (tc == REFERENCE_TYPE)
551 if (ec != REFERENCE_TYPE)
553 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
555 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
557 if (!at_least_as_qualified_p (TREE_TYPE (type),
558 TREE_TYPE (exprtype)))
562 /* If *type is an unambiguous accessible base class of *exprtype,
563 convert statically. */
568 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
573 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
574 TREE_TYPE (exprtype), TREE_TYPE (type));
575 return error_mark_node;
579 cp_error ("dynamic_cast from `%T' to private base class `%T'",
580 TREE_TYPE (exprtype), TREE_TYPE (type));
581 return error_mark_node;
585 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
588 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
589 if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype)))
592 /* if TYPE is `void *', return pointer to complete object. */
593 if (tc == POINTER_TYPE
594 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
596 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
597 if (TREE_CODE (expr) == ADDR_EXPR
598 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
599 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
600 return build1 (NOP_EXPR, type, expr);
602 /* Since expr is used twice below, save it. */
603 expr = save_expr (expr);
605 expr1 = build_headof (expr);
606 if (TREE_TYPE (expr1) != type)
607 expr1 = build1 (NOP_EXPR, type, expr1);
608 return ifnonnull (expr, expr1);
613 tree result, td1, td2, td3, elems, expr2;
615 /* If we got here, we can't convert statically. Therefore,
616 dynamic_cast<D&>(b) (b an object) cannot succeed. */
617 if (ec == REFERENCE_TYPE)
619 if (TREE_CODE (old_expr) == VAR_DECL
620 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
622 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
624 return throw_bad_cast ();
627 /* Ditto for dynamic_cast<D*>(&b). */
628 else if (TREE_CODE (expr) == ADDR_EXPR)
630 tree op = TREE_OPERAND (expr, 0);
631 if (TREE_CODE (op) == VAR_DECL
632 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
634 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
636 retval = build_int_2 (0, 0);
637 TREE_TYPE (retval) = type;
642 /* Since expr is used twice below, save it. */
643 expr = save_expr (expr);
646 if (tc == REFERENCE_TYPE)
647 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
649 /* Build run-time conversion. */
650 expr2 = build_headof (expr1);
652 if (ec == POINTER_TYPE)
653 td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR));
655 td1 = get_tinfo_fn_dynamic (expr);
656 td1 = decay_conversion (td1);
658 td2 = decay_conversion
659 (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
660 td3 = decay_conversion
661 (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
664 (NULL_TREE, td1, tree_cons
665 (NULL_TREE, td2, tree_cons
666 (NULL_TREE, build_int_2 (1, 0), tree_cons
667 (NULL_TREE, expr2, tree_cons
668 (NULL_TREE, td3, tree_cons
669 (NULL_TREE, expr1, NULL_TREE))))));
671 dcast_fn = get_identifier ("__dynamic_cast");
672 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
673 dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
678 push_obstacks (&permanent_obstack, &permanent_obstack);
680 (NULL_TREE, TREE_TYPE (td1), tree_cons
681 (NULL_TREE, TREE_TYPE (td1), tree_cons
682 (NULL_TREE, integer_type_node, tree_cons
683 (NULL_TREE, ptr_type_node, tree_cons
684 (NULL_TREE, TREE_TYPE (td1), tree_cons
685 (NULL_TREE, ptr_type_node, void_list_node))))));
686 tmp = build_function_type (ptr_type_node, tmp);
687 dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
688 DECL_EXTERNAL (dcast_fn) = 1;
689 TREE_PUBLIC (dcast_fn) = 1;
690 DECL_ARTIFICIAL (dcast_fn) = 1;
691 pushdecl_top_level (dcast_fn);
692 make_function_rtl (dcast_fn);
696 mark_used (dcast_fn);
698 (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
700 if (tc == REFERENCE_TYPE)
702 expr1 = throw_bad_cast ();
703 expr1 = build_compound_expr
704 (expr_tree_cons (NULL_TREE, expr1,
705 build_expr_list (NULL_TREE, cp_convert (type, integer_zero_node))));
706 TREE_TYPE (expr1) = type;
707 result = save_expr (result);
708 return build (COND_EXPR, type, result, result, expr1);
711 /* Now back to the type we want from a void*. */
712 result = cp_convert (type, result);
713 return ifnonnull (expr, result);
718 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
719 expr, exprtype, type);
720 return error_mark_node;
724 build_dynamic_cast (type, expr)
727 if (type == error_mark_node || expr == error_mark_node)
728 return error_mark_node;
730 if (processing_template_decl)
731 return build_min (DYNAMIC_CAST_EXPR, copy_to_permanent (type), expr);
733 return convert_from_reference (build_dynamic_cast_1 (type, expr));
736 /* Build and initialize various sorts of descriptors. Every descriptor
737 node has a name associated with it (the name created by mangling).
738 For this reason, we use the identifier as our access to the __*_desc
739 nodes, instead of sticking them directly in the types. Otherwise we
740 would burden all built-in types (and pointer types) with slots that
741 we don't necessarily want to use.
743 For each descriptor we build, we build a variable that contains
744 the descriptor's information. When we need this info at runtime,
745 all we need is access to these variables.
747 Note: these constructors always return the address of the descriptor
748 info, since that is simplest for their mutual interaction. */
750 extern tree const_string_type_node;
752 /* Build an initializer for a __si_type_info node. */
755 expand_si_desc (tdecl, type)
760 const char *name = build_overload_name (type, 1, 1);
761 tree name_string = combine_strings (build_string (strlen (name)+1, name));
763 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
764 expand_expr_stmt (get_typeid_1 (type));
765 t = decay_conversion (get_tinfo_var (type));
767 (NULL_TREE, decay_conversion (tdecl), tree_cons
768 (NULL_TREE, decay_conversion (name_string), tree_cons
769 (NULL_TREE, t, NULL_TREE)));
771 fn = get_identifier ("__rtti_si");
772 if (IDENTIFIER_GLOBAL_VALUE (fn))
773 fn = IDENTIFIER_GLOBAL_VALUE (fn);
777 push_obstacks (&permanent_obstack, &permanent_obstack);
779 (NULL_TREE, ptr_type_node, tree_cons
780 (NULL_TREE, const_string_type_node, tree_cons
781 (NULL_TREE, build_pointer_type (type_info_type_node),
783 tmp = build_function_type (void_type_node, tmp);
785 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
786 DECL_EXTERNAL (fn) = 1;
787 TREE_PUBLIC (fn) = 1;
788 DECL_ARTIFICIAL (fn) = 1;
789 pushdecl_top_level (fn);
790 make_function_rtl (fn);
795 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
796 expand_expr_stmt (fn);
799 /* Build an initializer for a __class_type_info node. */
802 expand_class_desc (tdecl, type)
810 int i = CLASSTYPE_N_BASECLASSES (type);
812 tree binfos = TYPE_BINFO_BASETYPES (type);
814 /* See code below that used these. */
815 tree vb = CLASSTYPE_VBASECLASSES (type);
818 tree base, elems, access, offset, isvir;
819 tree elt, elts = NULL_TREE;
820 static tree base_info_type_node;
822 if (base_info_type_node == NULL_TREE)
826 /* A reasonably close approximation of __class_type_info::base_info */
828 push_obstacks (&permanent_obstack, &permanent_obstack);
829 base_info_type_node = make_lang_type (RECORD_TYPE);
831 /* Actually const __user_type_info * */
832 fields [0] = build_lang_field_decl
833 (FIELD_DECL, NULL_TREE,
834 build_pointer_type (build_qualified_type
835 (type_info_type_node,
837 fields [1] = build_lang_field_decl
838 (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
839 DECL_BIT_FIELD (fields[1]) = 1;
840 DECL_FIELD_SIZE (fields[1]) = 29;
842 fields [2] = build_lang_field_decl
843 (FIELD_DECL, NULL_TREE, boolean_type_node);
844 DECL_BIT_FIELD (fields[2]) = 1;
845 DECL_FIELD_SIZE (fields[2]) = 1;
847 /* Actually enum access */
848 fields [3] = build_lang_field_decl
849 (FIELD_DECL, NULL_TREE, integer_type_node);
850 DECL_BIT_FIELD (fields[3]) = 1;
851 DECL_FIELD_SIZE (fields[3]) = 2;
853 finish_builtin_type (base_info_type_node, "__base_info", fields,
860 tree binfo = TREE_VEC_ELT (binfos, i);
862 expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
863 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
865 if (TREE_VIA_VIRTUAL (binfo))
867 tree t = BINFO_TYPE (binfo);
871 FORMAT_VBASE_NAME (name, t);
872 field = lookup_field (type, get_identifier (name), 0, 0);
873 offset = size_binop (FLOOR_DIV_EXPR,
874 DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT));
875 offset = convert (sizetype, offset);
878 offset = BINFO_OFFSET (binfo);
880 if (TREE_VIA_PUBLIC (binfo))
881 access = access_public_node;
882 else if (TREE_VIA_PROTECTED (binfo))
883 access = access_protected_node;
885 access = access_private_node;
886 if (TREE_VIA_VIRTUAL (binfo))
887 isvir = boolean_true_node;
889 isvir = boolean_false_node;
892 (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons
893 (NULL_TREE, base, tree_cons
894 (NULL_TREE, offset, tree_cons
895 (NULL_TREE, isvir, tree_cons
896 (NULL_TREE, access, NULL_TREE)))));
897 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
898 elts = expr_tree_cons (NULL_TREE, elt, elts);
906 access = access_public_node;
909 b = TREE_VEC_ELT (binfos, i);
910 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
912 if (TREE_VIA_PUBLIC (b))
913 access = access_public_node;
914 else if (TREE_VIA_PROTECTED (b))
915 access = access_protected_node;
917 access = access_private_node;
921 base = build_t_desc (BINFO_TYPE (vb), 1);
922 offset = BINFO_OFFSET (vb);
923 isvir = build_int_2 (1, 0);
925 base_list = expr_tree_cons (NULL_TREE, base, base_list);
926 isvir_list = expr_tree_cons (NULL_TREE, isvir, isvir_list);
927 acc_list = expr_tree_cons (NULL_TREE, access, acc_list);
928 off_list = expr_tree_cons (NULL_TREE, offset, off_list);
931 vb = TREE_CHAIN (vb);
935 name = build_overload_name (type, 1, 1);
936 name_string = combine_strings (build_string (strlen (name)+1, name));
939 tree arrtype = build_array_type (base_info_type_node, NULL_TREE);
940 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
941 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
942 = TREE_STATIC (elts) = 1;
943 complete_array_type (arrtype, elts, 1);
947 (NULL_TREE, decay_conversion (tdecl), tree_cons
948 (NULL_TREE, decay_conversion (name_string), tree_cons
949 (NULL_TREE, decay_conversion (elts), tree_cons
950 (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
953 fn = get_identifier ("__rtti_class");
954 if (IDENTIFIER_GLOBAL_VALUE (fn))
955 fn = IDENTIFIER_GLOBAL_VALUE (fn);
958 push_obstacks (&permanent_obstack, &permanent_obstack);
960 (NULL_TREE, ptr_type_node, tree_cons
961 (NULL_TREE, const_string_type_node, tree_cons
962 (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons
963 (NULL_TREE, sizetype, void_list_node))));
964 tmp = build_function_type (void_type_node, tmp);
966 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
967 DECL_EXTERNAL (fn) = 1;
968 TREE_PUBLIC (fn) = 1;
969 DECL_ARTIFICIAL (fn) = 1;
970 pushdecl_top_level (fn);
971 make_function_rtl (fn);
976 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
977 expand_expr_stmt (fn);
980 /* Build an initializer for a __pointer_type_info node. */
983 expand_ptr_desc (tdecl, type)
988 const char *name = build_overload_name (type, 1, 1);
989 tree name_string = combine_strings (build_string (strlen (name)+1, name));
991 type = TREE_TYPE (type);
992 expand_expr_stmt (get_typeid_1 (type));
993 t = decay_conversion (get_tinfo_var (type));
995 (NULL_TREE, decay_conversion (tdecl), tree_cons
996 (NULL_TREE, decay_conversion (name_string), tree_cons
997 (NULL_TREE, t, NULL_TREE)));
999 fn = get_identifier ("__rtti_ptr");
1000 if (IDENTIFIER_GLOBAL_VALUE (fn))
1001 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1005 push_obstacks (&permanent_obstack, &permanent_obstack);
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),
1011 tmp = build_function_type (void_type_node, tmp);
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);
1023 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1024 expand_expr_stmt (fn);
1027 /* Build an initializer for a __attr_type_info node. */
1030 expand_attr_desc (tdecl, type)
1035 const char *name = build_overload_name (type, 1, 1);
1036 tree name_string = combine_strings (build_string (strlen (name)+1, name));
1037 tree attrval = build_int_2 (TYPE_QUALS (type), 0);
1039 expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
1040 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
1042 (NULL_TREE, decay_conversion (tdecl), tree_cons
1043 (NULL_TREE, decay_conversion (name_string), tree_cons
1044 (NULL_TREE, attrval, expr_tree_cons (NULL_TREE, t, NULL_TREE))));
1046 fn = get_identifier ("__rtti_attr");
1047 if (IDENTIFIER_GLOBAL_VALUE (fn))
1048 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1052 push_obstacks (&permanent_obstack, &permanent_obstack);
1054 (NULL_TREE, ptr_type_node, tree_cons
1055 (NULL_TREE, const_string_type_node, tree_cons
1056 (NULL_TREE, integer_type_node, tree_cons
1057 (NULL_TREE, build_pointer_type (type_info_type_node),
1059 tmp = build_function_type (void_type_node, tmp);
1061 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1062 DECL_EXTERNAL (fn) = 1;
1063 TREE_PUBLIC (fn) = 1;
1064 DECL_ARTIFICIAL (fn) = 1;
1065 pushdecl_top_level (fn);
1066 make_function_rtl (fn);
1071 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1072 expand_expr_stmt (fn);
1075 /* Build an initializer for a type_info node that just has a name. */
1078 expand_generic_desc (tdecl, type, fnname)
1083 const char *name = build_overload_name (type, 1, 1);
1084 tree name_string = combine_strings (build_string (strlen (name)+1, name));
1085 tree elems = tree_cons
1086 (NULL_TREE, decay_conversion (tdecl), tree_cons
1087 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
1089 tree fn = get_identifier (fnname);
1090 if (IDENTIFIER_GLOBAL_VALUE (fn))
1091 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1095 push_obstacks (&permanent_obstack, &permanent_obstack);
1097 (NULL_TREE, ptr_type_node, tree_cons
1098 (NULL_TREE, const_string_type_node, void_list_node));
1099 tmp = build_function_type (void_type_node, tmp);
1101 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1102 DECL_EXTERNAL (fn) = 1;
1103 TREE_PUBLIC (fn) = 1;
1104 DECL_ARTIFICIAL (fn) = 1;
1105 pushdecl_top_level (fn);
1106 make_function_rtl (fn);
1111 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1112 expand_expr_stmt (fn);
1115 /* Generate the code for a type_info initialization function.
1116 Note that we take advantage of the passage
1118 5.2.7 Type identification [expr.typeid]
1120 Whether or not the destructor is called for the type_info object at the
1121 end of the program is unspecified.
1123 and don't bother to arrange for these objects to be destroyed. It
1124 doesn't matter, anyway, since the destructors don't do anything.
1126 This must only be called from toplevel (i.e. from finish_file)! */
1129 synthesize_tinfo_fn (fndecl)
1132 tree type = TREE_TYPE (DECL_NAME (fndecl));
1133 tree tmp, addr, tdecl;
1137 import_export_decl (fndecl);
1138 if (DECL_REALLY_EXTERN (fndecl))
1142 tdecl = get_tinfo_var (type);
1143 DECL_EXTERNAL (tdecl) = 0;
1144 TREE_STATIC (tdecl) = 1;
1145 DECL_COMMON (tdecl) = 1;
1146 TREE_USED (tdecl) = 1;
1147 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1148 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
1150 start_function (NULL_TREE, fndecl, NULL_TREE, 1);
1151 store_parm_decls ();
1155 /* If the first word of the array (the vtable) is non-zero, we've already
1156 initialized the object, so don't do it again. */
1157 addr = decay_conversion (tdecl);
1158 tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
1159 tmp = build_indirect_ref (tmp, 0);
1160 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
1161 expand_start_cond (tmp, 0);
1163 if (TREE_CODE (type) == FUNCTION_TYPE)
1164 expand_generic_desc (tdecl, type, "__rtti_func");
1165 else if (TREE_CODE (type) == ARRAY_TYPE)
1166 expand_generic_desc (tdecl, type, "__rtti_array");
1167 else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
1168 expand_attr_desc (tdecl, type);
1169 else if (TREE_CODE (type) == POINTER_TYPE)
1171 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1172 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1173 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1174 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1176 expand_ptr_desc (tdecl, type);
1178 else if (TYPE_PTRMEMFUNC_P (type))
1179 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1180 else if (IS_AGGR_TYPE (type))
1182 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1183 expand_generic_desc (tdecl, type, "__rtti_user");
1184 else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
1186 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1187 expand_si_desc (tdecl, type);
1189 expand_class_desc (tdecl, type);
1191 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1192 expand_generic_desc (tdecl, type, "__rtti_user");
1194 my_friendly_abort (252);
1198 /* OK, now return the type_info object. */
1199 tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
1200 tmp = build_indirect_ref (tmp, 0);
1201 c_expand_return (tmp);
1202 finish_function (lineno, 0, 0);