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));
53 init_rtti_processing ()
56 push_namespace (get_identifier ("std"));
57 type_info_type_node
= xref_tag
58 (class_type_node
, get_identifier ("type_info"), 1);
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
,
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
74 build_headof_sub (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
);
85 /* Given the expression EXP of type `class *', return the head of the
86 object pointed to by EXP with type cv void*, if the class has any
87 virtual functions (TYPE_POLYMORPHIC_P), else just return the
94 tree type
= TREE_TYPE (exp
);
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_POLYMORPHIC_P (type
))
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
)
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. */
139 tree d
= get_identifier (name
);
142 if (IDENTIFIER_GLOBAL_VALUE (d
))
143 d
= IDENTIFIER_GLOBAL_VALUE (d
);
146 type
= build_function_type (void_type_node
, void_list_node
);
147 d
= build_lang_decl (FUNCTION_DECL
, d
, type
);
148 DECL_EXTERNAL (d
) = 1;
150 DECL_ARTIFICIAL (d
) = 1;
151 pushdecl_top_level (d
);
152 make_function_rtl (d
);
156 return build_call (d
, void_type_node
, NULL_TREE
);
159 /* Get a bad_cast node for the program to throw...
161 See libstdc++/exception.cc for __throw_bad_cast */
166 return call_void_fn ("__throw_bad_cast");
172 return call_void_fn ("__throw_bad_typeid");
175 /* Return the type_info function associated with the expression EXP. If
176 EXP is a reference to a polymorphic class, return the dynamic type;
177 otherwise return the static type of the expression. */
180 get_tinfo_fn_dynamic (exp
)
185 if (exp
== error_mark_node
)
186 return error_mark_node
;
188 if (type_unknown_p (exp
))
190 error ("typeid of overloaded function");
191 return error_mark_node
;
194 type
= TREE_TYPE (exp
);
196 /* peel back references, so they match. */
197 if (TREE_CODE (type
) == REFERENCE_TYPE
)
198 type
= TREE_TYPE (type
);
200 /* Peel off cv qualifiers. */
201 type
= TYPE_MAIN_VARIANT (type
);
203 if (TYPE_SIZE (complete_type (type
)) == NULL_TREE
)
205 cp_error ("taking typeid of incomplete type `%T'", type
);
206 return error_mark_node
;
209 /* If exp is a reference to polymorphic type, get the real type_info. */
210 if (TYPE_POLYMORPHIC_P (type
) && ! resolves_to_fixed_type_p (exp
, 0))
212 /* build reference to type_info from vtable. */
216 error ("taking dynamic typeid of object with -fno-rtti");
217 if (CLASSTYPE_COM_INTERFACE (type
))
219 cp_error ("RTTI not supported for COM interface type `%T'", type
);
220 return error_mark_node
;
223 /* If we don't have rtti stuff, get to a sub-object that does. */
224 if (! CLASSTYPE_VFIELDS (type
))
226 exp
= build_unary_op (ADDR_EXPR
, exp
, 0);
227 exp
= build_headof_sub (exp
);
228 exp
= build_indirect_ref (exp
, NULL_PTR
);
231 if (flag_vtable_thunks
)
232 t
= build_vfn_ref ((tree
*) 0, exp
, integer_one_node
);
234 t
= build_vfn_ref ((tree
*) 0, exp
, integer_zero_node
);
235 TREE_TYPE (t
) = build_pointer_type (tinfo_fn_type
);
239 /* otherwise return the type_info for the static type of the expr. */
240 return get_tinfo_fn (TYPE_MAIN_VARIANT (type
));
247 exp
= get_tinfo_fn_dynamic (exp
);
248 exp
= build_call (exp
, TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
249 return convert_from_reference (exp
);
256 tree cond
= NULL_TREE
;
262 error ("cannot use typeid with -fno-rtti");
263 return error_mark_node
;
266 if (TYPE_SIZE (type_info_type_node
) == NULL_TREE
)
268 error ("must #include <typeinfo> before using typeid");
269 return error_mark_node
;
272 if (processing_template_decl
)
273 return build_min_nt (TYPEID_EXPR
, exp
);
275 if (TREE_CODE (exp
) == INDIRECT_REF
276 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp
, 0))) == POINTER_TYPE
277 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp
))
278 && ! resolves_to_fixed_type_p (exp
, &nonnull
)
281 exp
= stabilize_reference (exp
);
282 cond
= cp_convert (boolean_type_node
, TREE_OPERAND (exp
, 0));
285 exp
= get_tinfo_fn_dynamic (exp
);
287 if (exp
== error_mark_node
)
288 return error_mark_node
;
290 type
= TREE_TYPE (tinfo_fn_type
);
291 exp
= build_call (exp
, type
, NULL_TREE
);
295 tree bad
= throw_bad_typeid ();
297 bad
= build_compound_expr
298 (tree_cons (NULL_TREE
, bad
, build_tree_list
299 (NULL_TREE
, cp_convert (type
, integer_zero_node
))));
300 exp
= build (COND_EXPR
, type
, cond
, exp
, bad
);
303 return convert_from_reference (exp
);
310 tree tname
= build_overload_with_type (get_identifier ("__ti"), type
);
314 if (IDENTIFIER_GLOBAL_VALUE (tname
))
315 return IDENTIFIER_GLOBAL_VALUE (tname
);
317 /* Figure out how much space we need to allocate for the type_info object.
318 If our struct layout or the type_info classes are changed, this will
319 need to be modified. */
320 if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
321 size
= 3 * POINTER_SIZE
+ INT_TYPE_SIZE
;
322 else if (TREE_CODE (type
) == POINTER_TYPE
323 && ! (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
324 || TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
))
325 size
= 3 * POINTER_SIZE
;
326 else if (IS_AGGR_TYPE (type
))
328 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
329 size
= 2 * POINTER_SIZE
;
330 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type
)
332 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
333 size
= 3 * POINTER_SIZE
;
335 size
= 3 * POINTER_SIZE
+ TYPE_PRECISION (sizetype
);
338 size
= 2 * POINTER_SIZE
;
340 /* The type for a character array of the appropriate size. */
341 arrtype
= build_cplus_array_type
342 (unsigned_char_type_node
,
343 build_index_type (size_int (size
/ BITS_PER_UNIT
- 1)));
345 return declare_global_var (tname
, arrtype
);
348 /* Returns the decl for a function which will return a type_info node for
349 TYPE. This version does not mark the function used, for use in
350 set_rtti_entry; for the vtable case, we'll get marked in
351 finish_vtable_vardecl, when we know that we want to be emitted.
353 We do this to avoid emitting the tinfo node itself, since we don't
354 currently support DECL_DEFER_OUTPUT for variables. Also, we don't
355 associate constant pools with their functions properly, so we would
356 emit string constants and such even though we don't emit the actual
357 function. When those bugs are fixed, this function should go away. */
360 get_tinfo_fn_unused (type
)
366 if (TREE_CODE (type
) == OFFSET_TYPE
)
367 type
= TREE_TYPE (type
);
368 if (TREE_CODE (type
) == METHOD_TYPE
)
369 type
= build_function_type (TREE_TYPE (type
),
370 TREE_CHAIN (TYPE_ARG_TYPES (type
)));
372 name
= build_overload_with_type (tinfo_fn_id
, type
);
374 if (IDENTIFIER_GLOBAL_VALUE (name
))
375 return IDENTIFIER_GLOBAL_VALUE (name
);
377 d
= build_lang_decl (FUNCTION_DECL
, name
, tinfo_fn_type
);
378 DECL_EXTERNAL (d
) = 1;
380 DECL_ARTIFICIAL (d
) = 1;
381 DECL_NOT_REALLY_EXTERN (d
) = 1;
382 SET_DECL_TINFO_FN_P (d
);
383 TREE_TYPE (name
) = type
;
385 pushdecl_top_level (d
);
386 make_function_rtl (d
);
387 mark_inline_for_output (d
);
392 /* Likewise, but also mark it used. Called by various EH and RTTI code. */
398 tree d
= get_tinfo_fn_unused (type
);
410 (get_tinfo_fn (type
), TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
411 return convert_from_reference (t
);
414 /* Return the type_info object for TYPE, creating it if necessary. */
420 if (type
== error_mark_node
)
421 return error_mark_node
;
423 if (TYPE_SIZE (type_info_type_node
) == NULL_TREE
)
425 error ("must #include <typeinfo> before using typeid");
426 return error_mark_node
;
429 if (processing_template_decl
)
430 return build_min_nt (TYPEID_EXPR
, type
);
432 /* If the type of the type-id is a reference type, the result of the
433 typeid expression refers to a type_info object representing the
435 if (TREE_CODE (type
) == REFERENCE_TYPE
)
436 type
= TREE_TYPE (type
);
438 /* The top-level cv-qualifiers of the lvalue expression or the type-id
439 that is the operand of typeid are always ignored. */
440 type
= TYPE_MAIN_VARIANT (type
);
442 if (TYPE_SIZE (complete_type (type
)) == NULL_TREE
)
444 cp_error ("taking typeid of incomplete type `%T'", type
);
445 return error_mark_node
;
448 return get_typeid_1 (type
);
451 /* Check whether TEST is null before returning RESULT. If TEST is used in
452 RESULT, it must have previously had a save_expr applied to it. */
455 ifnonnull (test
, result
)
458 return build (COND_EXPR
, TREE_TYPE (result
),
459 build (EQ_EXPR
, boolean_type_node
, test
, integer_zero_node
),
460 cp_convert (TREE_TYPE (result
), integer_zero_node
),
464 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
468 build_dynamic_cast_1 (type
, expr
)
471 enum tree_code tc
= TREE_CODE (type
);
475 tree old_expr
= expr
;
477 if (TREE_CODE (expr
) == OFFSET_REF
)
478 expr
= resolve_offset_ref (expr
);
480 exprtype
= TREE_TYPE (expr
);
481 assert (exprtype
!= NULL_TREE
);
482 ec
= TREE_CODE (exprtype
);
487 if (ec
== REFERENCE_TYPE
)
489 expr
= convert_from_reference (expr
);
490 exprtype
= TREE_TYPE (expr
);
491 ec
= TREE_CODE (exprtype
);
493 if (ec
!= POINTER_TYPE
)
495 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
497 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
499 if (!at_least_as_qualified_p (TREE_TYPE (type
),
500 TREE_TYPE (exprtype
)))
502 if (TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
504 /* else fall through */
506 if (TREE_CODE (TREE_TYPE (type
)) != RECORD_TYPE
)
508 if (TYPE_SIZE (complete_type (TREE_TYPE (type
))) == NULL_TREE
)
511 /* else fall through */
516 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
517 if (ec
== RECORD_TYPE
)
519 exprtype
= build_reference_type (exprtype
);
520 expr
= convert_to_reference (exprtype
, expr
, CONV_IMPLICIT
,
521 LOOKUP_NORMAL
, NULL_TREE
);
525 if (tc
== REFERENCE_TYPE
)
527 if (ec
!= REFERENCE_TYPE
)
529 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
531 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
533 if (!at_least_as_qualified_p (TREE_TYPE (type
),
534 TREE_TYPE (exprtype
)))
538 /* If *type is an unambiguous accessible base class of *exprtype,
539 convert statically. */
544 distance
= get_base_distance (TREE_TYPE (type
), TREE_TYPE (exprtype
), 1,
549 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
550 TREE_TYPE (exprtype
), TREE_TYPE (type
));
551 return error_mark_node
;
555 cp_error ("dynamic_cast from `%T' to private base class `%T'",
556 TREE_TYPE (exprtype
), TREE_TYPE (type
));
557 return error_mark_node
;
561 return build_vbase_path (PLUS_EXPR
, type
, expr
, path
, 0);
564 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
565 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype
)))
568 /* if TYPE is `void *', return pointer to complete object. */
569 if (tc
== POINTER_TYPE
570 && TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
572 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
573 if (TREE_CODE (expr
) == ADDR_EXPR
574 && TREE_CODE (TREE_OPERAND (expr
, 0)) == VAR_DECL
575 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == RECORD_TYPE
)
576 return build1 (NOP_EXPR
, type
, expr
);
578 /* Since expr is used twice below, save it. */
579 expr
= save_expr (expr
);
581 expr1
= build_headof (expr
);
582 if (TREE_TYPE (expr1
) != type
)
583 expr1
= build1 (NOP_EXPR
, type
, expr1
);
584 return ifnonnull (expr
, expr1
);
589 tree result
, td1
, td2
, td3
, elems
, expr2
;
590 tree static_type
, target_type
, boff
;
592 /* If we got here, we can't convert statically. Therefore,
593 dynamic_cast<D&>(b) (b an object) cannot succeed. */
594 if (ec
== REFERENCE_TYPE
)
596 if (TREE_CODE (old_expr
) == VAR_DECL
597 && TREE_CODE (TREE_TYPE (old_expr
)) == RECORD_TYPE
)
599 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
601 return throw_bad_cast ();
604 /* Ditto for dynamic_cast<D*>(&b). */
605 else if (TREE_CODE (expr
) == ADDR_EXPR
)
607 tree op
= TREE_OPERAND (expr
, 0);
608 if (TREE_CODE (op
) == VAR_DECL
609 && TREE_CODE (TREE_TYPE (op
)) == RECORD_TYPE
)
611 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
613 retval
= build_int_2 (0, 0);
614 TREE_TYPE (retval
) = type
;
619 /* Since expr is used twice below, save it. */
620 expr
= save_expr (expr
);
623 if (tc
== REFERENCE_TYPE
)
624 expr1
= build_unary_op (ADDR_EXPR
, expr1
, 0);
626 /* Build run-time conversion. */
627 expr2
= build_headof (expr1
);
629 if (ec
== POINTER_TYPE
)
630 td1
= get_tinfo_fn_dynamic (build_indirect_ref (expr
, NULL_PTR
));
632 td1
= get_tinfo_fn_dynamic (expr
);
633 td1
= decay_conversion (td1
);
635 target_type
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
636 static_type
= TYPE_MAIN_VARIANT (TREE_TYPE (exprtype
));
637 td2
= decay_conversion (get_tinfo_fn (target_type
));
638 td3
= decay_conversion (get_tinfo_fn (static_type
));
640 /* Determine how T and V are related. */
641 boff
= get_dynamic_cast_base_type (static_type
, target_type
);
644 (NULL_TREE
, td1
, tree_cons
645 (NULL_TREE
, td2
, tree_cons
646 (NULL_TREE
, boff
, tree_cons
647 (NULL_TREE
, expr2
, tree_cons
648 (NULL_TREE
, td3
, tree_cons
649 (NULL_TREE
, expr1
, NULL_TREE
))))));
651 dcast_fn
= get_identifier ("__dynamic_cast_2");
652 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn
))
653 dcast_fn
= IDENTIFIER_GLOBAL_VALUE (dcast_fn
);
659 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
660 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
661 (NULL_TREE
, integer_type_node
, tree_cons
662 (NULL_TREE
, ptr_type_node
, tree_cons
663 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
664 (NULL_TREE
, ptr_type_node
, void_list_node
))))));
665 tmp
= build_function_type (ptr_type_node
, tmp
);
666 dcast_fn
= build_lang_decl (FUNCTION_DECL
, dcast_fn
, tmp
);
667 DECL_EXTERNAL (dcast_fn
) = 1;
668 TREE_PUBLIC (dcast_fn
) = 1;
669 DECL_ARTIFICIAL (dcast_fn
) = 1;
670 pushdecl_top_level (dcast_fn
);
671 make_function_rtl (dcast_fn
);
674 mark_used (dcast_fn
);
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_tree_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 cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype
);
696 return error_mark_node
;
699 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
700 expr
, exprtype
, type
);
701 return error_mark_node
;
705 build_dynamic_cast (type
, expr
)
708 if (type
== error_mark_node
|| expr
== error_mark_node
)
709 return error_mark_node
;
711 if (processing_template_decl
)
712 return build_min (DYNAMIC_CAST_EXPR
, type
, expr
);
714 return convert_from_reference (build_dynamic_cast_1 (type
, expr
));
717 /* Build and initialize various sorts of descriptors. Every descriptor
718 node has a name associated with it (the name created by mangling).
719 For this reason, we use the identifier as our access to the __*_desc
720 nodes, instead of sticking them directly in the types. Otherwise we
721 would burden all built-in types (and pointer types) with slots that
722 we don't necessarily want to use.
724 For each descriptor we build, we build a variable that contains
725 the descriptor's information. When we need this info at runtime,
726 all we need is access to these variables.
728 Note: these constructors always return the address of the descriptor
729 info, since that is simplest for their mutual interaction. */
731 /* Build an initializer for a __si_type_info node. */
734 expand_si_desc (tdecl
, type
)
739 const char *name
= build_overload_name (type
, 1, 1);
740 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
742 type
= BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0));
743 finish_expr_stmt (get_typeid_1 (type
));
744 t
= decay_conversion (get_tinfo_var (type
));
746 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
747 (NULL_TREE
, decay_conversion (name_string
), tree_cons
748 (NULL_TREE
, t
, NULL_TREE
)));
750 fn
= get_identifier ("__rtti_si");
751 if (IDENTIFIER_GLOBAL_VALUE (fn
))
752 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
757 (NULL_TREE
, ptr_type_node
, tree_cons
758 (NULL_TREE
, const_string_type_node
, tree_cons
759 (NULL_TREE
, build_pointer_type (type_info_type_node
),
761 tmp
= build_function_type (void_type_node
, tmp
);
763 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
764 DECL_EXTERNAL (fn
) = 1;
765 TREE_PUBLIC (fn
) = 1;
766 DECL_ARTIFICIAL (fn
) = 1;
767 pushdecl_top_level (fn
);
768 make_function_rtl (fn
);
772 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
773 finish_expr_stmt (fn
);
776 /* Build an initializer for a __class_type_info node. */
779 expand_class_desc (tdecl
, type
)
787 int i
= CLASSTYPE_N_BASECLASSES (type
);
789 tree binfos
= TYPE_BINFO_BASETYPES (type
);
791 /* See code below that used these. */
792 tree vb
= CLASSTYPE_VBASECLASSES (type
);
795 tree base
, elems
, access
, offset
, isvir
;
796 tree elt
, elts
= NULL_TREE
;
797 static tree base_info_type_node
;
799 if (base_info_type_node
== NULL_TREE
)
803 /* A reasonably close approximation of __class_type_info::base_info */
805 base_info_type_node
= make_aggr_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
,
813 fields
[1] = build_lang_decl
814 (FIELD_DECL
, NULL_TREE
,
815 flag_new_abi
? intSI_type_node
: unsigned_intSI_type_node
);
816 DECL_BIT_FIELD (fields
[1]) = 1;
817 DECL_FIELD_SIZE (fields
[1]) = 29;
819 fields
[2] = build_lang_decl
820 (FIELD_DECL
, NULL_TREE
, boolean_type_node
);
821 DECL_BIT_FIELD (fields
[2]) = 1;
822 DECL_FIELD_SIZE (fields
[2]) = 1;
824 /* Actually enum access */
825 fields
[3] = build_lang_decl
826 (FIELD_DECL
, NULL_TREE
, integer_type_node
);
827 DECL_BIT_FIELD (fields
[3]) = 1;
828 DECL_FIELD_SIZE (fields
[3]) = 2;
830 finish_builtin_type (base_info_type_node
, "__base_info", fields
,
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 if (!vbase_offsets_in_vtable_p ())
845 tree t
= BINFO_TYPE (binfo
);
849 FORMAT_VBASE_NAME (name
, t
);
850 field
= lookup_field (type
, get_identifier (name
), 0, 0);
851 offset
= size_binop (FLOOR_DIV_EXPR
,
852 DECL_FIELD_BITPOS (field
),
853 size_int (BITS_PER_UNIT
));
854 offset
= convert (sizetype
, offset
);
858 /* Under the new ABI, we store the vtable offset at which
859 the virtual base offset can be found. */
860 tree vbase
= BINFO_FOR_VBASE (BINFO_TYPE (binfo
), type
);
861 offset
= convert (sizetype
, BINFO_VPTR_FIELD (vbase
));
865 offset
= BINFO_OFFSET (binfo
);
867 if (TREE_VIA_PUBLIC (binfo
))
868 access
= access_public_node
;
869 else if (TREE_VIA_PROTECTED (binfo
))
870 access
= access_protected_node
;
872 access
= access_private_node
;
873 if (TREE_VIA_VIRTUAL (binfo
))
874 isvir
= boolean_true_node
;
876 isvir
= boolean_false_node
;
879 (CONSTRUCTOR
, base_info_type_node
, NULL_TREE
, tree_cons
880 (NULL_TREE
, base
, tree_cons
881 (NULL_TREE
, offset
, tree_cons
882 (NULL_TREE
, isvir
, tree_cons
883 (NULL_TREE
, access
, NULL_TREE
)))));
884 TREE_HAS_CONSTRUCTOR (elt
) = TREE_CONSTANT (elt
) = TREE_STATIC (elt
) = 1;
885 elts
= tree_cons (NULL_TREE
, elt
, elts
);
893 access
= access_public_node
;
896 b
= TREE_VEC_ELT (binfos
, i
);
897 if (BINFO_TYPE (vb
) == BINFO_TYPE (b
) && TREE_VIA_VIRTUAL (b
))
899 if (TREE_VIA_PUBLIC (b
))
900 access
= access_public_node
;
901 else if (TREE_VIA_PROTECTED (b
))
902 access
= access_protected_node
;
904 access
= access_private_node
;
908 base
= build_t_desc (BINFO_TYPE (vb
), 1);
909 offset
= BINFO_OFFSET (vb
);
910 isvir
= build_int_2 (1, 0);
912 base_list
= tree_cons (NULL_TREE
, base
, base_list
);
913 isvir_list
= tree_cons (NULL_TREE
, isvir
, isvir_list
);
914 acc_list
= tree_cons (NULL_TREE
, access
, acc_list
);
915 off_list
= tree_cons (NULL_TREE
, offset
, off_list
);
918 vb
= TREE_CHAIN (vb
);
922 name
= build_overload_name (type
, 1, 1);
923 name_string
= combine_strings (build_string (strlen (name
)+1, name
));
926 tree arrtype
= build_array_type (base_info_type_node
, NULL_TREE
);
927 elts
= build (CONSTRUCTOR
, arrtype
, NULL_TREE
, elts
);
928 TREE_HAS_CONSTRUCTOR (elts
) = TREE_CONSTANT (elts
)
929 = TREE_STATIC (elts
) = 1;
930 complete_array_type (arrtype
, elts
, 1);
934 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
935 (NULL_TREE
, decay_conversion (name_string
), tree_cons
936 (NULL_TREE
, decay_conversion (elts
), tree_cons
937 (NULL_TREE
, cp_convert (sizetype
, build_int_2 (base_cnt
, 0)),
940 fn
= get_identifier ("__rtti_class");
941 if (IDENTIFIER_GLOBAL_VALUE (fn
))
942 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
946 (NULL_TREE
, ptr_type_node
, tree_cons
947 (NULL_TREE
, const_string_type_node
, tree_cons
948 (NULL_TREE
, build_pointer_type (base_info_type_node
), tree_cons
949 (NULL_TREE
, sizetype
, void_list_node
))));
950 tmp
= build_function_type (void_type_node
, tmp
);
952 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
953 DECL_EXTERNAL (fn
) = 1;
954 TREE_PUBLIC (fn
) = 1;
955 DECL_ARTIFICIAL (fn
) = 1;
956 pushdecl_top_level (fn
);
957 make_function_rtl (fn
);
961 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
962 finish_expr_stmt (fn
);
965 /* Build an initializer for a __pointer_type_info node. */
968 expand_ptr_desc (tdecl
, type
)
973 const char *name
= build_overload_name (type
, 1, 1);
974 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
976 type
= TREE_TYPE (type
);
977 finish_expr_stmt (get_typeid_1 (type
));
978 t
= decay_conversion (get_tinfo_var (type
));
980 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
981 (NULL_TREE
, decay_conversion (name_string
), tree_cons
982 (NULL_TREE
, t
, NULL_TREE
)));
984 fn
= get_identifier ("__rtti_ptr");
985 if (IDENTIFIER_GLOBAL_VALUE (fn
))
986 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
991 (NULL_TREE
, ptr_type_node
, tree_cons
992 (NULL_TREE
, const_string_type_node
, tree_cons
993 (NULL_TREE
, build_pointer_type (type_info_type_node
),
995 tmp
= build_function_type (void_type_node
, tmp
);
997 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
998 DECL_EXTERNAL (fn
) = 1;
999 TREE_PUBLIC (fn
) = 1;
1000 DECL_ARTIFICIAL (fn
) = 1;
1001 pushdecl_top_level (fn
);
1002 make_function_rtl (fn
);
1006 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1007 finish_expr_stmt (fn
);
1010 /* Build an initializer for a __attr_type_info node. */
1013 expand_attr_desc (tdecl
, type
)
1018 const char *name
= build_overload_name (type
, 1, 1);
1019 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
1020 tree attrval
= build_int_2 (TYPE_QUALS (type
), 0);
1022 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type
)));
1023 t
= decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type
)));
1025 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1026 (NULL_TREE
, decay_conversion (name_string
), tree_cons
1027 (NULL_TREE
, attrval
, tree_cons (NULL_TREE
, t
, NULL_TREE
))));
1029 fn
= get_identifier ("__rtti_attr");
1030 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1031 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1036 (NULL_TREE
, ptr_type_node
, tree_cons
1037 (NULL_TREE
, const_string_type_node
, tree_cons
1038 (NULL_TREE
, integer_type_node
, tree_cons
1039 (NULL_TREE
, build_pointer_type (type_info_type_node
),
1041 tmp
= build_function_type (void_type_node
, tmp
);
1043 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1044 DECL_EXTERNAL (fn
) = 1;
1045 TREE_PUBLIC (fn
) = 1;
1046 DECL_ARTIFICIAL (fn
) = 1;
1047 pushdecl_top_level (fn
);
1048 make_function_rtl (fn
);
1052 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1053 finish_expr_stmt (fn
);
1056 /* Build an initializer for a type_info node that just has a name. */
1059 expand_generic_desc (tdecl
, type
, fnname
)
1064 const char *name
= build_overload_name (type
, 1, 1);
1065 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
1066 tree elems
= tree_cons
1067 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1068 (NULL_TREE
, decay_conversion (name_string
), NULL_TREE
));
1070 tree fn
= get_identifier (fnname
);
1071 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1072 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1077 (NULL_TREE
, ptr_type_node
, tree_cons
1078 (NULL_TREE
, const_string_type_node
, void_list_node
));
1079 tmp
= build_function_type (void_type_node
, tmp
);
1081 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1082 DECL_EXTERNAL (fn
) = 1;
1083 TREE_PUBLIC (fn
) = 1;
1084 DECL_ARTIFICIAL (fn
) = 1;
1085 pushdecl_top_level (fn
);
1086 make_function_rtl (fn
);
1090 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1091 finish_expr_stmt (fn
);
1094 /* Generate the code for a type_info initialization function.
1095 Note that we take advantage of the passage
1097 5.2.7 Type identification [expr.typeid]
1099 Whether or not the destructor is called for the type_info object at the
1100 end of the program is unspecified.
1102 and don't bother to arrange for these objects to be destroyed. It
1103 doesn't matter, anyway, since the destructors don't do anything.
1105 This must only be called from toplevel (i.e. from finish_file)! */
1108 synthesize_tinfo_fn (fndecl
)
1111 tree type
= TREE_TYPE (DECL_NAME (fndecl
));
1112 tree tmp
, addr
, tdecl
;
1119 import_export_decl (fndecl
);
1120 if (DECL_REALLY_EXTERN (fndecl
))
1124 /* Declare the static typeinfo variable. */
1125 tdecl
= get_tinfo_var (type
);
1126 DECL_EXTERNAL (tdecl
) = 0;
1127 TREE_STATIC (tdecl
) = 1;
1128 DECL_COMMON (tdecl
) = 1;
1129 TREE_USED (tdecl
) = 1;
1130 DECL_ALIGN (tdecl
) = TYPE_ALIGN (ptr_type_node
);
1131 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0);
1133 /* Begin processing the function. */
1134 start_function (NULL_TREE
, fndecl
, NULL_TREE
,
1135 SF_DEFAULT
| SF_PRE_PARSED
);
1136 DECL_DEFER_OUTPUT (fndecl
) = 1;
1137 store_parm_decls ();
1140 /* Begin the body of the function. */
1141 compound_stmt
= begin_compound_stmt (/*has_no_scope=*/0);
1143 /* For convenience, we save away the address of the static
1145 addr
= decay_conversion (tdecl
);
1147 /* If the first word of the array (the vtable) is non-zero, we've already
1148 initialized the object, so don't do it again. */
1149 if_stmt
= begin_if_stmt ();
1150 tmp
= cp_convert (build_pointer_type (ptr_type_node
), addr
);
1151 tmp
= build_indirect_ref (tmp
, 0);
1152 tmp
= build_binary_op (EQ_EXPR
, tmp
, integer_zero_node
);
1153 finish_if_stmt_cond (tmp
, if_stmt
);
1154 then_clause
= begin_compound_stmt (/*has_no_scope=*/0);
1156 if (TREE_CODE (type
) == FUNCTION_TYPE
)
1157 expand_generic_desc (tdecl
, type
, "__rtti_func");
1158 else if (TREE_CODE (type
) == ARRAY_TYPE
)
1159 expand_generic_desc (tdecl
, type
, "__rtti_array");
1160 else if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
1161 expand_attr_desc (tdecl
, type
);
1162 else if (TREE_CODE (type
) == POINTER_TYPE
)
1164 if (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
)
1165 expand_generic_desc (tdecl
, type
, "__rtti_ptmd");
1166 else if (TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
)
1167 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1169 expand_ptr_desc (tdecl
, type
);
1171 else if (TYPE_PTRMEMFUNC_P (type
))
1172 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1173 else if (IS_AGGR_TYPE (type
))
1175 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
1176 expand_generic_desc (tdecl
, type
, "__rtti_user");
1177 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type
)
1179 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
1180 expand_si_desc (tdecl
, type
);
1182 expand_class_desc (tdecl
, type
);
1184 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
1185 expand_generic_desc (tdecl
, type
, "__rtti_user");
1187 my_friendly_abort (252);
1189 finish_compound_stmt (/*has_no_scope=*/0, then_clause
);
1190 finish_then_clause (if_stmt
);
1193 /* OK, now return the type_info object. */
1194 tmp
= cp_convert (build_pointer_type (type_info_type_node
), addr
);
1195 tmp
= build_indirect_ref (tmp
, 0);
1196 finish_return_stmt (tmp
);
1197 /* Finish the function body. */
1198 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt
);
1199 expand_body (finish_function (lineno
, 0));