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).
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));
51 static tree get_tinfo_decl_dynamic PROTO((tree));
52 static tree tinfo_from_decl PROTO((tree));
55 init_rtti_processing ()
58 push_namespace (get_identifier ("std"));
59 type_info_type_node = xref_tag
60 (class_type_node, get_identifier ("type_info"), 1);
63 tinfo_fn_id = get_identifier ("__tf");
64 tinfo_fn_type = build_function_type
65 (build_reference_type (build_qualified_type (type_info_type_node,
70 /* Given a pointer to an object with at least one virtual table
71 pointer somewhere, return a pointer to a possible sub-object that
72 has a virtual table pointer in it that is the vtable parent for
76 build_headof_sub (exp)
79 tree type = TREE_TYPE (TREE_TYPE (exp));
80 tree basetype = CLASSTYPE_RTTI (type);
81 tree binfo = get_binfo (basetype, type, 0);
83 exp = convert_pointer_to_real (binfo, exp);
87 /* Given the expression EXP of type `class *', return the head of the
88 object pointed to by EXP with type cv void*, if the class has any
89 virtual functions (TYPE_POLYMORPHIC_P), else just return the
96 tree type = TREE_TYPE (exp);
100 my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
101 type = TREE_TYPE (type);
103 if (!TYPE_POLYMORPHIC_P (type))
105 if (CLASSTYPE_COM_INTERFACE (type))
107 cp_error ("RTTI not supported for COM interface type `%T'", type);
108 return error_mark_node;
111 /* If we don't have rtti stuff, get to a sub-object that does. */
112 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
113 exp = build_headof_sub (exp);
115 /* We use this a couple of times below, protect it. */
116 exp = save_expr (exp);
118 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
120 if (flag_vtable_thunks)
123 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
125 type = build_qualified_type (ptr_type_node,
126 CP_TYPE_QUALS (TREE_TYPE (exp)));
127 return build (PLUS_EXPR, type, exp,
128 cp_convert (ptrdiff_type_node, offset));
131 /* Build a call to a generic entry point taking and returning void. */
137 tree d = get_identifier (name);
140 if (IDENTIFIER_GLOBAL_VALUE (d))
141 d = IDENTIFIER_GLOBAL_VALUE (d);
144 type = build_function_type (void_type_node, void_list_node);
145 d = build_lang_decl (FUNCTION_DECL, d, type);
146 DECL_EXTERNAL (d) = 1;
148 DECL_ARTIFICIAL (d) = 1;
149 pushdecl_top_level (d);
150 make_function_rtl (d);
154 return build_call (d, void_type_node, NULL_TREE);
157 /* Get a bad_cast node for the program to throw...
159 See libstdc++/exception.cc for __throw_bad_cast */
164 return call_void_fn ("__throw_bad_cast");
170 return call_void_fn ("__throw_bad_typeid");
173 /* Return a pointer to type_info function associated with the expression EXP.
174 If EXP is a reference to a polymorphic class, return the dynamic type;
175 otherwise return the static type of the expression. */
178 get_tinfo_decl_dynamic (exp)
183 if (exp == error_mark_node)
184 return error_mark_node;
186 type = TREE_TYPE (exp);
188 /* peel back references, so they match. */
189 if (TREE_CODE (type) == REFERENCE_TYPE)
190 type = TREE_TYPE (type);
192 /* Peel off cv qualifiers. */
193 type = TYPE_MAIN_VARIANT (type);
195 if (type != void_type_node)
196 type = complete_type_or_else (type, exp);
199 return error_mark_node;
201 /* If exp is a reference to polymorphic type, get the real type_info. */
202 if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
204 /* build reference to type_info from vtable. */
208 error ("taking dynamic typeid of object with -fno-rtti");
209 if (CLASSTYPE_COM_INTERFACE (type))
211 cp_error ("RTTI not supported for COM interface type `%T'", type);
212 return error_mark_node;
215 /* If we don't have rtti stuff, get to a sub-object that does. */
216 if (! CLASSTYPE_VFIELDS (type))
218 exp = build_unary_op (ADDR_EXPR, exp, 0);
219 exp = build_headof_sub (exp);
220 exp = build_indirect_ref (exp, NULL_PTR);
223 if (flag_vtable_thunks)
224 t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
226 t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
227 TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
231 /* otherwise return the type_info for the static type of the expr. */
232 exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
233 return build_unary_op (ADDR_EXPR, exp, 0);
240 tree cond = NULL_TREE;
246 error ("cannot use typeid with -fno-rtti");
247 return error_mark_node;
250 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
252 error ("must #include <typeinfo> before using typeid");
253 return error_mark_node;
256 if (processing_template_decl)
257 return build_min_nt (TYPEID_EXPR, exp);
259 if (TREE_CODE (exp) == INDIRECT_REF
260 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
261 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
262 && ! resolves_to_fixed_type_p (exp, &nonnull)
265 exp = stabilize_reference (exp);
266 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
269 exp = get_tinfo_decl_dynamic (exp);
271 if (exp == error_mark_node)
272 return error_mark_node;
274 exp = tinfo_from_decl (exp);
278 tree bad = throw_bad_typeid ();
280 exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
283 return convert_from_reference (exp);
290 tree tname = build_overload_with_type (get_identifier ("__ti"), type);
294 if (IDENTIFIER_GLOBAL_VALUE (tname))
295 return IDENTIFIER_GLOBAL_VALUE (tname);
297 /* Figure out how much space we need to allocate for the type_info object.
298 If our struct layout or the type_info classes are changed, this will
299 need to be modified. */
300 if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
301 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
302 else if (TREE_CODE (type) == POINTER_TYPE
303 && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
304 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
305 size = 3 * POINTER_SIZE;
306 else if (IS_AGGR_TYPE (type))
308 if (CLASSTYPE_N_BASECLASSES (type) == 0)
309 size = 2 * POINTER_SIZE;
310 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
312 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
313 size = 3 * POINTER_SIZE;
315 size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
318 size = 2 * POINTER_SIZE;
320 /* The type for a character array of the appropriate size. */
321 arrtype = build_cplus_array_type
322 (unsigned_char_type_node,
323 build_index_type (size_int (size / BITS_PER_UNIT - 1)));
325 return declare_global_var (tname, arrtype);
328 /* Returns a decl for a function or variable which can be used to obtain a
329 type_info object for TYPE. The old-abi uses functions, the new-abi will
330 use the type_info object directly. You can take the address of the
331 returned decl, to save the decl. To use the generator call
332 tinfo_from_generator. You must arrange that the decl is mark_used, if
333 actually use it --- decls in vtables are only used if the vtable is
337 get_tinfo_decl (type)
343 if (TREE_CODE (type) == OFFSET_TYPE)
344 type = TREE_TYPE (type);
345 if (TREE_CODE (type) == METHOD_TYPE)
346 type = build_function_type (TREE_TYPE (type),
347 TREE_CHAIN (TYPE_ARG_TYPES (type)));
349 name = build_overload_with_type (tinfo_fn_id, type);
351 if (IDENTIFIER_GLOBAL_VALUE (name))
352 return IDENTIFIER_GLOBAL_VALUE (name);
354 d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type);
355 DECL_EXTERNAL (d) = 1;
357 DECL_ARTIFICIAL (d) = 1;
358 DECL_NOT_REALLY_EXTERN (d) = 1;
359 SET_DECL_TINFO_FN_P (d);
360 TREE_TYPE (name) = type;
362 pushdecl_top_level (d);
363 make_function_rtl (d);
364 mark_inline_for_output (d);
369 /* Given an expr produced by get_tinfo_decl, return an expr which
370 produces a reference to the type_info object. */
373 tinfo_from_decl (expr)
376 tree t = build_call (expr, TREE_TYPE (tinfo_fn_type), NULL_TREE);
387 t = get_tinfo_decl (type);
388 t = tinfo_from_decl (t);
389 return convert_from_reference (t);
392 /* Return the type_info object for TYPE. */
398 if (type == error_mark_node)
399 return error_mark_node;
401 if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
403 error ("must #include <typeinfo> before using typeid");
404 return error_mark_node;
407 if (processing_template_decl)
408 return build_min_nt (TYPEID_EXPR, type);
410 /* If the type of the type-id is a reference type, the result of the
411 typeid expression refers to a type_info object representing the
413 if (TREE_CODE (type) == REFERENCE_TYPE)
414 type = TREE_TYPE (type);
416 /* The top-level cv-qualifiers of the lvalue expression or the type-id
417 that is the operand of typeid are always ignored. */
418 type = TYPE_MAIN_VARIANT (type);
420 if (type != void_type_node)
421 type = complete_type_or_else (type, NULL_TREE);
424 return error_mark_node;
426 return get_typeid_1 (type);
429 /* Check whether TEST is null before returning RESULT. If TEST is used in
430 RESULT, it must have previously had a save_expr applied to it. */
433 ifnonnull (test, result)
436 return build (COND_EXPR, TREE_TYPE (result),
437 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
438 cp_convert (TREE_TYPE (result), integer_zero_node),
442 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
446 build_dynamic_cast_1 (type, expr)
449 enum tree_code tc = TREE_CODE (type);
453 tree old_expr = expr;
455 if (TREE_CODE (expr) == OFFSET_REF)
456 expr = resolve_offset_ref (expr);
458 exprtype = TREE_TYPE (expr);
459 assert (exprtype != NULL_TREE);
460 ec = TREE_CODE (exprtype);
465 if (ec == REFERENCE_TYPE)
467 expr = convert_from_reference (expr);
468 exprtype = TREE_TYPE (expr);
469 ec = TREE_CODE (exprtype);
471 if (ec != POINTER_TYPE)
473 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
475 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
477 if (!at_least_as_qualified_p (TREE_TYPE (type),
478 TREE_TYPE (exprtype)))
480 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
482 /* else fall through */
484 if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
486 if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
489 /* else fall through */
494 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
495 if (ec == RECORD_TYPE)
497 exprtype = build_reference_type (exprtype);
498 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
499 LOOKUP_NORMAL, NULL_TREE);
503 if (tc == REFERENCE_TYPE)
505 if (ec != REFERENCE_TYPE)
507 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
509 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
511 if (!at_least_as_qualified_p (TREE_TYPE (type),
512 TREE_TYPE (exprtype)))
516 /* If *type is an unambiguous accessible base class of *exprtype,
517 convert statically. */
522 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
527 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
528 TREE_TYPE (exprtype), TREE_TYPE (type));
529 return error_mark_node;
533 cp_error ("dynamic_cast from `%T' to private base class `%T'",
534 TREE_TYPE (exprtype), TREE_TYPE (type));
535 return error_mark_node;
539 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
542 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
543 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
546 /* if TYPE is `void *', return pointer to complete object. */
547 if (tc == POINTER_TYPE
548 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
550 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
551 if (TREE_CODE (expr) == ADDR_EXPR
552 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
553 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
554 return build1 (NOP_EXPR, type, expr);
556 /* Since expr is used twice below, save it. */
557 expr = save_expr (expr);
559 expr1 = build_headof (expr);
560 if (TREE_TYPE (expr1) != type)
561 expr1 = build1 (NOP_EXPR, type, expr1);
562 return ifnonnull (expr, expr1);
567 tree result, td1, td2, td3, elems, expr2;
568 tree static_type, target_type, boff;
570 /* If we got here, we can't convert statically. Therefore,
571 dynamic_cast<D&>(b) (b an object) cannot succeed. */
572 if (ec == REFERENCE_TYPE)
574 if (TREE_CODE (old_expr) == VAR_DECL
575 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
577 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
579 return throw_bad_cast ();
582 /* Ditto for dynamic_cast<D*>(&b). */
583 else if (TREE_CODE (expr) == ADDR_EXPR)
585 tree op = TREE_OPERAND (expr, 0);
586 if (TREE_CODE (op) == VAR_DECL
587 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
589 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
591 retval = build_int_2 (0, 0);
592 TREE_TYPE (retval) = type;
597 /* Since expr is used twice below, save it. */
598 expr = save_expr (expr);
601 if (tc == REFERENCE_TYPE)
602 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
604 /* Build run-time conversion. */
605 expr2 = build_headof (expr1);
607 if (ec == POINTER_TYPE)
608 td1 = get_tinfo_decl_dynamic (build_indirect_ref (expr, NULL_PTR));
610 td1 = get_tinfo_decl_dynamic (expr);
611 td1 = decay_conversion (td1);
613 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
614 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
615 td2 = decay_conversion (get_tinfo_decl (target_type));
616 td3 = decay_conversion (get_tinfo_decl (static_type));
618 /* Determine how T and V are related. */
619 boff = get_dynamic_cast_base_type (static_type, target_type);
622 (NULL_TREE, td1, tree_cons
623 (NULL_TREE, td2, tree_cons
624 (NULL_TREE, boff, tree_cons
625 (NULL_TREE, expr2, tree_cons
626 (NULL_TREE, td3, tree_cons
627 (NULL_TREE, expr1, NULL_TREE))))));
629 dcast_fn = get_identifier ("__dynamic_cast_2");
630 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
631 dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
637 (NULL_TREE, TREE_TYPE (td1), tree_cons
638 (NULL_TREE, TREE_TYPE (td1), tree_cons
639 (NULL_TREE, integer_type_node, tree_cons
640 (NULL_TREE, ptr_type_node, tree_cons
641 (NULL_TREE, TREE_TYPE (td1), tree_cons
642 (NULL_TREE, ptr_type_node, void_list_node))))));
643 tmp = build_function_type (ptr_type_node, tmp);
644 dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
645 DECL_EXTERNAL (dcast_fn) = 1;
646 TREE_PUBLIC (dcast_fn) = 1;
647 DECL_ARTIFICIAL (dcast_fn) = 1;
648 pushdecl_top_level (dcast_fn);
649 make_function_rtl (dcast_fn);
652 mark_used (dcast_fn);
654 (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
656 if (tc == REFERENCE_TYPE)
658 expr1 = throw_bad_cast ();
659 result = save_expr (result);
660 return build (COND_EXPR, type, result, result, expr1);
663 /* Now back to the type we want from a void*. */
664 result = cp_convert (type, result);
665 return ifnonnull (expr, result);
669 cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype);
670 return error_mark_node;
673 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
674 expr, exprtype, type);
675 return error_mark_node;
679 build_dynamic_cast (type, expr)
682 if (type == error_mark_node || expr == error_mark_node)
683 return error_mark_node;
685 if (processing_template_decl)
686 return build_min (DYNAMIC_CAST_EXPR, type, expr);
688 return convert_from_reference (build_dynamic_cast_1 (type, expr));
691 /* Build and initialize various sorts of descriptors. Every descriptor
692 node has a name associated with it (the name created by mangling).
693 For this reason, we use the identifier as our access to the __*_desc
694 nodes, instead of sticking them directly in the types. Otherwise we
695 would burden all built-in types (and pointer types) with slots that
696 we don't necessarily want to use.
698 For each descriptor we build, we build a variable that contains
699 the descriptor's information. When we need this info at runtime,
700 all we need is access to these variables.
702 Note: these constructors always return the address of the descriptor
703 info, since that is simplest for their mutual interaction. */
705 /* Build an initializer for a __si_type_info node. */
708 expand_si_desc (tdecl, type)
713 const char *name = build_overload_name (type, 1, 1);
714 tree name_string = combine_strings (build_string (strlen (name)+1, name));
716 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
717 finish_expr_stmt (get_typeid_1 (type));
718 t = decay_conversion (get_tinfo_var (type));
720 (NULL_TREE, decay_conversion (tdecl), tree_cons
721 (NULL_TREE, decay_conversion (name_string), tree_cons
722 (NULL_TREE, t, NULL_TREE)));
724 fn = get_identifier ("__rtti_si");
725 if (IDENTIFIER_GLOBAL_VALUE (fn))
726 fn = IDENTIFIER_GLOBAL_VALUE (fn);
731 (NULL_TREE, ptr_type_node, tree_cons
732 (NULL_TREE, const_string_type_node, tree_cons
733 (NULL_TREE, build_pointer_type (type_info_type_node),
735 tmp = build_function_type (void_type_node, tmp);
737 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
738 DECL_EXTERNAL (fn) = 1;
739 TREE_PUBLIC (fn) = 1;
740 DECL_ARTIFICIAL (fn) = 1;
741 pushdecl_top_level (fn);
742 make_function_rtl (fn);
746 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
747 finish_expr_stmt (fn);
750 /* Build an initializer for a __class_type_info node. */
753 expand_class_desc (tdecl, type)
761 int i = CLASSTYPE_N_BASECLASSES (type);
763 tree binfos = TYPE_BINFO_BASETYPES (type);
765 /* See code below that used these. */
766 tree vb = CLASSTYPE_VBASECLASSES (type);
769 tree base, elems, access, offset, isvir;
770 tree elt, elts = NULL_TREE;
771 static tree base_info_type_node;
773 if (base_info_type_node == NULL_TREE)
777 /* A reasonably close approximation of __class_type_info::base_info */
779 base_info_type_node = make_aggr_type (RECORD_TYPE);
781 /* Actually const __user_type_info * */
782 fields [0] = build_lang_decl
783 (FIELD_DECL, NULL_TREE,
784 build_pointer_type (build_qualified_type
785 (type_info_type_node,
787 fields [1] = build_lang_decl
788 (FIELD_DECL, NULL_TREE,
789 flag_new_abi ? intSI_type_node : unsigned_intSI_type_node);
790 DECL_BIT_FIELD (fields[1]) = 1;
791 DECL_FIELD_SIZE (fields[1]) = 29;
793 fields [2] = build_lang_decl
794 (FIELD_DECL, NULL_TREE, boolean_type_node);
795 DECL_BIT_FIELD (fields[2]) = 1;
796 DECL_FIELD_SIZE (fields[2]) = 1;
798 /* Actually enum access */
799 fields [3] = build_lang_decl
800 (FIELD_DECL, NULL_TREE, integer_type_node);
801 DECL_BIT_FIELD (fields[3]) = 1;
802 DECL_FIELD_SIZE (fields[3]) = 2;
804 finish_builtin_type (base_info_type_node, "__base_info", fields,
810 tree binfo = TREE_VEC_ELT (binfos, i);
812 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
813 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
815 if (TREE_VIA_VIRTUAL (binfo))
817 if (!vbase_offsets_in_vtable_p ())
819 tree t = BINFO_TYPE (binfo);
823 FORMAT_VBASE_NAME (name, t);
824 field = lookup_field (type, get_identifier (name), 0, 0);
825 offset = size_binop (FLOOR_DIV_EXPR,
826 DECL_FIELD_BITPOS (field),
827 size_int (BITS_PER_UNIT));
828 offset = convert (sizetype, offset);
832 /* Under the new ABI, we store the vtable offset at which
833 the virtual base offset can be found. */
834 tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), type);
835 offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
839 offset = BINFO_OFFSET (binfo);
841 if (TREE_VIA_PUBLIC (binfo))
842 access = access_public_node;
843 else if (TREE_VIA_PROTECTED (binfo))
844 access = access_protected_node;
846 access = access_private_node;
847 if (TREE_VIA_VIRTUAL (binfo))
848 isvir = boolean_true_node;
850 isvir = boolean_false_node;
853 (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons
854 (NULL_TREE, base, tree_cons
855 (NULL_TREE, offset, tree_cons
856 (NULL_TREE, isvir, tree_cons
857 (NULL_TREE, access, NULL_TREE)))));
858 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
859 elts = tree_cons (NULL_TREE, elt, elts);
867 access = access_public_node;
870 b = TREE_VEC_ELT (binfos, i);
871 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
873 if (TREE_VIA_PUBLIC (b))
874 access = access_public_node;
875 else if (TREE_VIA_PROTECTED (b))
876 access = access_protected_node;
878 access = access_private_node;
882 base = build_t_desc (BINFO_TYPE (vb), 1);
883 offset = BINFO_OFFSET (vb);
884 isvir = build_int_2 (1, 0);
886 base_list = tree_cons (NULL_TREE, base, base_list);
887 isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
888 acc_list = tree_cons (NULL_TREE, access, acc_list);
889 off_list = tree_cons (NULL_TREE, offset, off_list);
892 vb = TREE_CHAIN (vb);
896 name = build_overload_name (type, 1, 1);
897 name_string = combine_strings (build_string (strlen (name)+1, name));
900 tree arrtype = build_array_type (base_info_type_node, NULL_TREE);
901 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
902 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
903 = TREE_STATIC (elts) = 1;
904 complete_array_type (arrtype, elts, 1);
908 (NULL_TREE, decay_conversion (tdecl), tree_cons
909 (NULL_TREE, decay_conversion (name_string), tree_cons
910 (NULL_TREE, decay_conversion (elts), tree_cons
911 (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
914 fn = get_identifier ("__rtti_class");
915 if (IDENTIFIER_GLOBAL_VALUE (fn))
916 fn = IDENTIFIER_GLOBAL_VALUE (fn);
920 (NULL_TREE, ptr_type_node, tree_cons
921 (NULL_TREE, const_string_type_node, tree_cons
922 (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons
923 (NULL_TREE, sizetype, void_list_node))));
924 tmp = build_function_type (void_type_node, tmp);
926 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
927 DECL_EXTERNAL (fn) = 1;
928 TREE_PUBLIC (fn) = 1;
929 DECL_ARTIFICIAL (fn) = 1;
930 pushdecl_top_level (fn);
931 make_function_rtl (fn);
935 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
936 finish_expr_stmt (fn);
939 /* Build an initializer for a __pointer_type_info node. */
942 expand_ptr_desc (tdecl, type)
947 const char *name = build_overload_name (type, 1, 1);
948 tree name_string = combine_strings (build_string (strlen (name)+1, name));
950 type = TREE_TYPE (type);
951 finish_expr_stmt (get_typeid_1 (type));
952 t = decay_conversion (get_tinfo_var (type));
954 (NULL_TREE, decay_conversion (tdecl), tree_cons
955 (NULL_TREE, decay_conversion (name_string), tree_cons
956 (NULL_TREE, t, NULL_TREE)));
958 fn = get_identifier ("__rtti_ptr");
959 if (IDENTIFIER_GLOBAL_VALUE (fn))
960 fn = IDENTIFIER_GLOBAL_VALUE (fn);
965 (NULL_TREE, ptr_type_node, tree_cons
966 (NULL_TREE, const_string_type_node, tree_cons
967 (NULL_TREE, build_pointer_type (type_info_type_node),
969 tmp = build_function_type (void_type_node, tmp);
971 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
972 DECL_EXTERNAL (fn) = 1;
973 TREE_PUBLIC (fn) = 1;
974 DECL_ARTIFICIAL (fn) = 1;
975 pushdecl_top_level (fn);
976 make_function_rtl (fn);
980 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
981 finish_expr_stmt (fn);
984 /* Build an initializer for a __attr_type_info node. */
987 expand_attr_desc (tdecl, type)
992 const char *name = build_overload_name (type, 1, 1);
993 tree name_string = combine_strings (build_string (strlen (name)+1, name));
994 tree attrval = build_int_2 (TYPE_QUALS (type), 0);
996 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
997 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
999 (NULL_TREE, decay_conversion (tdecl), tree_cons
1000 (NULL_TREE, decay_conversion (name_string), tree_cons
1001 (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
1003 fn = get_identifier ("__rtti_attr");
1004 if (IDENTIFIER_GLOBAL_VALUE (fn))
1005 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1010 (NULL_TREE, ptr_type_node, tree_cons
1011 (NULL_TREE, const_string_type_node, tree_cons
1012 (NULL_TREE, integer_type_node, tree_cons
1013 (NULL_TREE, build_pointer_type (type_info_type_node),
1015 tmp = build_function_type (void_type_node, tmp);
1017 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1018 DECL_EXTERNAL (fn) = 1;
1019 TREE_PUBLIC (fn) = 1;
1020 DECL_ARTIFICIAL (fn) = 1;
1021 pushdecl_top_level (fn);
1022 make_function_rtl (fn);
1026 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1027 finish_expr_stmt (fn);
1030 /* Build an initializer for a type_info node that just has a name. */
1033 expand_generic_desc (tdecl, type, fnname)
1038 const char *name = build_overload_name (type, 1, 1);
1039 tree name_string = combine_strings (build_string (strlen (name)+1, name));
1040 tree elems = tree_cons
1041 (NULL_TREE, decay_conversion (tdecl), tree_cons
1042 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
1044 tree fn = get_identifier (fnname);
1045 if (IDENTIFIER_GLOBAL_VALUE (fn))
1046 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1051 (NULL_TREE, ptr_type_node, tree_cons
1052 (NULL_TREE, const_string_type_node, void_list_node));
1053 tmp = build_function_type (void_type_node, tmp);
1055 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1056 DECL_EXTERNAL (fn) = 1;
1057 TREE_PUBLIC (fn) = 1;
1058 DECL_ARTIFICIAL (fn) = 1;
1059 pushdecl_top_level (fn);
1060 make_function_rtl (fn);
1064 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1065 finish_expr_stmt (fn);
1068 /* Generate the code for a type_info initialization function.
1069 Note that we take advantage of the passage
1071 5.2.7 Type identification [expr.typeid]
1073 Whether or not the destructor is called for the type_info object at the
1074 end of the program is unspecified.
1076 and don't bother to arrange for these objects to be destroyed. It
1077 doesn't matter, anyway, since the destructors don't do anything.
1079 This must only be called from toplevel (i.e. from finish_file)! */
1082 synthesize_tinfo_fn (fndecl)
1085 tree type = TREE_TYPE (DECL_NAME (fndecl));
1086 tree tmp, addr, tdecl;
1093 import_export_decl (fndecl);
1094 if (DECL_REALLY_EXTERN (fndecl))
1098 /* Declare the static typeinfo variable. */
1099 tdecl = get_tinfo_var (type);
1100 DECL_EXTERNAL (tdecl) = 0;
1101 TREE_STATIC (tdecl) = 1;
1102 DECL_COMMON (tdecl) = 1;
1103 TREE_USED (tdecl) = 1;
1104 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1105 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0);
1107 /* Begin processing the function. */
1108 start_function (NULL_TREE, fndecl, NULL_TREE,
1109 SF_DEFAULT | SF_PRE_PARSED);
1110 DECL_DEFER_OUTPUT (fndecl) = 1;
1111 store_parm_decls ();
1114 /* Begin the body of the function. */
1115 compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
1117 /* For convenience, we save away the address of the static
1119 addr = decay_conversion (tdecl);
1121 /* If the first word of the array (the vtable) is non-zero, we've already
1122 initialized the object, so don't do it again. */
1123 if_stmt = begin_if_stmt ();
1124 tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
1125 tmp = build_indirect_ref (tmp, 0);
1126 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
1127 finish_if_stmt_cond (tmp, if_stmt);
1128 then_clause = begin_compound_stmt (/*has_no_scope=*/0);
1130 if (TREE_CODE (type) == FUNCTION_TYPE)
1131 expand_generic_desc (tdecl, type, "__rtti_func");
1132 else if (TREE_CODE (type) == ARRAY_TYPE)
1133 expand_generic_desc (tdecl, type, "__rtti_array");
1134 else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
1135 expand_attr_desc (tdecl, type);
1136 else if (TREE_CODE (type) == POINTER_TYPE)
1138 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1139 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1140 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1141 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1143 expand_ptr_desc (tdecl, type);
1145 else if (TYPE_PTRMEMFUNC_P (type))
1146 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1147 else if (IS_AGGR_TYPE (type))
1149 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1150 expand_generic_desc (tdecl, type, "__rtti_user");
1151 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
1153 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1154 expand_si_desc (tdecl, type);
1156 expand_class_desc (tdecl, type);
1158 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1159 expand_generic_desc (tdecl, type, "__rtti_user");
1161 my_friendly_abort (252);
1163 finish_compound_stmt (/*has_no_scope=*/0, then_clause);
1164 finish_then_clause (if_stmt);
1167 /* OK, now return the type_info object. */
1168 tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
1169 tmp = build_indirect_ref (tmp, 0);
1170 finish_return_stmt (tmp);
1171 /* Finish the function body. */
1172 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
1173 expand_body (finish_function (lineno, 0));