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 build_runtime_decl
PARAMS ((const char *, tree
));
39 static tree build_headof_sub
PARAMS ((tree
));
40 static tree build_headof
PARAMS ((tree
));
41 static tree get_tinfo_var
PARAMS ((tree
));
42 static tree ifnonnull
PARAMS ((tree
, tree
));
43 static tree tinfo_name
PARAMS ((tree
));
44 static tree get_base_offset
PARAMS ((tree
, tree
));
45 static tree build_dynamic_cast_1
PARAMS ((tree
, tree
));
46 static void expand_si_desc
PARAMS ((tree
, tree
));
47 static void expand_class_desc
PARAMS ((tree
, tree
));
48 static void expand_attr_desc
PARAMS ((tree
, tree
));
49 static void expand_ptr_desc
PARAMS ((tree
, tree
));
50 static void expand_generic_desc
PARAMS ((tree
, tree
, const char *));
51 static tree throw_bad_cast
PARAMS ((void));
52 static tree throw_bad_typeid
PARAMS ((void));
53 static tree get_tinfo_decl_dynamic
PARAMS ((tree
));
54 static tree tinfo_from_decl
PARAMS ((tree
));
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);
66 tinfo_decl_id
= get_identifier ("__tf");
67 tinfo_decl_type
= build_function_type
70 (type_info_type_node
, TYPE_QUAL_CONST
)),
72 tinfo_var_id
= get_identifier ("__ti");
75 /* Given a pointer to an object with at least one virtual table
76 pointer somewhere, return a pointer to a possible sub-object that
77 has a virtual table pointer in it that is the vtable parent for
81 build_headof_sub (exp
)
84 tree type
= TREE_TYPE (TREE_TYPE (exp
));
85 tree basetype
= CLASSTYPE_RTTI (type
);
86 tree binfo
= get_binfo (basetype
, type
, 0);
88 exp
= convert_pointer_to_real (binfo
, exp
);
92 /* Given the expression EXP of type `class *', return the head of the
93 object pointed to by EXP with type cv void*, if the class has any
94 virtual functions (TYPE_POLYMORPHIC_P), else just return the
101 tree type
= TREE_TYPE (exp
);
105 my_friendly_assert (TREE_CODE (type
) == POINTER_TYPE
, 20000112);
106 type
= TREE_TYPE (type
);
108 if (!TYPE_POLYMORPHIC_P (type
))
110 if (CLASSTYPE_COM_INTERFACE (type
))
112 cp_error ("RTTI not supported for COM interface type `%T'", type
);
113 return error_mark_node
;
116 /* If we don't have rtti stuff, get to a sub-object that does. */
117 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp
))))
118 exp
= build_headof_sub (exp
);
120 /* We use this a couple of times below, protect it. */
121 exp
= save_expr (exp
);
123 aref
= build_vtbl_ref (build_indirect_ref (exp
, NULL_PTR
), integer_zero_node
);
125 if (flag_vtable_thunks
)
128 offset
= build_component_ref (aref
, delta_identifier
, NULL_TREE
, 0);
130 type
= build_qualified_type (ptr_type_node
,
131 CP_TYPE_QUALS (TREE_TYPE (exp
)));
132 return build (PLUS_EXPR
, type
, exp
,
133 cp_convert (ptrdiff_type_node
, offset
));
136 /* Build a decl to a runtime entry point taking void and returning TYPE.
137 Although the entry point may never return, making its return type
138 consistent is necessary. */
141 build_runtime_decl (name
, type
)
145 tree d
= get_identifier (name
);
147 if (IDENTIFIER_GLOBAL_VALUE (d
))
148 d
= IDENTIFIER_GLOBAL_VALUE (d
);
151 type
= build_function_type (type
, void_list_node
);
152 d
= build_lang_decl (FUNCTION_DECL
, d
, type
);
153 DECL_EXTERNAL (d
) = 1;
155 DECL_ARTIFICIAL (d
) = 1;
156 pushdecl_top_level (d
);
157 make_function_rtl (d
);
164 /* Get a bad_cast node for the program to throw...
166 See libstdc++/exception.cc for __throw_bad_cast */
171 if (!throw_bad_cast_node
)
172 throw_bad_cast_node
= build_runtime_decl
173 ("__throw_bad_cast", ptr_type_node
);
175 return build_call (throw_bad_cast_node
,
176 TREE_TYPE (TREE_TYPE (throw_bad_cast_node
)),
183 if (!throw_bad_typeid_node
)
184 throw_bad_typeid_node
= build_runtime_decl
185 ("__throw_bad_typeid",
187 (build_qualified_type
188 (type_info_type_node
, TYPE_QUAL_CONST
)));
190 return build_call (throw_bad_typeid_node
,
191 TREE_TYPE (TREE_TYPE (throw_bad_typeid_node
)),
195 /* Return a pointer to type_info function associated with the expression EXP.
196 If EXP is a reference to a polymorphic class, return the dynamic type;
197 otherwise return the static type of the expression. */
200 get_tinfo_decl_dynamic (exp
)
205 if (exp
== error_mark_node
)
206 return error_mark_node
;
208 type
= TREE_TYPE (exp
);
210 /* peel back references, so they match. */
211 if (TREE_CODE (type
) == REFERENCE_TYPE
)
212 type
= TREE_TYPE (type
);
214 /* Peel off cv qualifiers. */
215 type
= TYPE_MAIN_VARIANT (type
);
217 if (type
!= void_type_node
)
218 type
= complete_type_or_else (type
, exp
);
221 return error_mark_node
;
223 /* If exp is a reference to polymorphic type, get the real type_info. */
224 if (TYPE_POLYMORPHIC_P (type
) && ! resolves_to_fixed_type_p (exp
, 0))
226 /* build reference to type_info from vtable. */
230 error ("taking dynamic typeid of object with -fno-rtti");
231 if (CLASSTYPE_COM_INTERFACE (type
))
233 cp_error ("RTTI not supported for COM interface type `%T'", type
);
234 return error_mark_node
;
237 /* If we don't have rtti stuff, get to a sub-object that does. */
238 if (! CLASSTYPE_VFIELDS (type
))
240 exp
= build_unary_op (ADDR_EXPR
, exp
, 0);
241 exp
= build_headof_sub (exp
);
242 exp
= build_indirect_ref (exp
, NULL_PTR
);
245 if (flag_vtable_thunks
)
246 t
= build_vfn_ref ((tree
*) 0, exp
, integer_one_node
);
248 t
= build_vfn_ref ((tree
*) 0, exp
, integer_zero_node
);
249 TREE_TYPE (t
) = build_pointer_type (tinfo_decl_type
);
253 /* otherwise return the type_info for the static type of the expr. */
254 exp
= get_tinfo_decl (TYPE_MAIN_VARIANT (type
));
255 return build_unary_op (ADDR_EXPR
, exp
, 0);
262 tree cond
= NULL_TREE
;
267 error ("cannot use typeid with -fno-rtti");
268 return error_mark_node
;
271 if (TYPE_SIZE (type_info_type_node
) == NULL_TREE
)
273 error ("must #include <typeinfo> before using typeid");
274 return error_mark_node
;
277 if (processing_template_decl
)
278 return build_min_nt (TYPEID_EXPR
, exp
);
280 if (TREE_CODE (exp
) == INDIRECT_REF
281 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp
, 0))) == POINTER_TYPE
282 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp
))
283 && ! resolves_to_fixed_type_p (exp
, &nonnull
)
286 exp
= stabilize_reference (exp
);
287 cond
= cp_convert (boolean_type_node
, TREE_OPERAND (exp
, 0));
290 exp
= get_tinfo_decl_dynamic (exp
);
292 if (exp
== error_mark_node
)
293 return error_mark_node
;
295 exp
= tinfo_from_decl (exp
);
299 tree bad
= throw_bad_typeid ();
301 exp
= build (COND_EXPR
, TREE_TYPE (exp
), cond
, exp
, bad
);
304 return convert_from_reference (exp
);
311 tree tname
= build_overload_with_type (tinfo_var_id
, type
);
315 if (IDENTIFIER_GLOBAL_VALUE (tname
))
316 return IDENTIFIER_GLOBAL_VALUE (tname
);
318 /* Figure out how much space we need to allocate for the type_info object.
319 If our struct layout or the type_info classes are changed, this will
320 need to be modified. */
321 if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
322 size
= 3 * POINTER_SIZE
+ INT_TYPE_SIZE
;
323 else if (TREE_CODE (type
) == POINTER_TYPE
324 && ! (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
325 || TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
))
326 size
= 3 * POINTER_SIZE
;
327 else if (IS_AGGR_TYPE (type
))
329 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
330 size
= 2 * POINTER_SIZE
;
331 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type
)
333 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
334 size
= 3 * POINTER_SIZE
;
336 size
= 3 * POINTER_SIZE
+ TYPE_PRECISION (sizetype
);
339 size
= 2 * POINTER_SIZE
;
341 /* The type for a character array of the appropriate size. */
342 arrtype
= build_cplus_array_type
343 (unsigned_char_type_node
,
344 build_index_type (size_int (size
/ BITS_PER_UNIT
- 1)));
346 return declare_global_var (tname
, arrtype
);
349 /* Generate the NTBS name of a type. */
354 const char *name
= build_overload_name (type
, 1, 1);
355 tree name_string
= combine_strings (build_string (strlen (name
) + 1, name
));
359 /* Returns a decl for a function or variable which can be used to obtain a
360 type_info object for TYPE. The old-abi uses functions, the new-abi will
361 use the type_info object directly. You can take the address of the
362 returned decl, to save the decl. To use the decl call
363 tinfo_from_decl. You must arrange that the decl is mark_used, if
364 actually use it --- decls in vtables are only used if the vtable is
368 get_tinfo_decl (type
)
374 if (TREE_CODE (type
) == OFFSET_TYPE
)
375 type
= TREE_TYPE (type
);
376 if (TREE_CODE (type
) == METHOD_TYPE
)
377 type
= build_function_type (TREE_TYPE (type
),
378 TREE_CHAIN (TYPE_ARG_TYPES (type
)));
380 name
= build_overload_with_type (tinfo_decl_id
, type
);
382 if (IDENTIFIER_GLOBAL_VALUE (name
))
383 return IDENTIFIER_GLOBAL_VALUE (name
);
385 d
= build_lang_decl (FUNCTION_DECL
, name
, tinfo_decl_type
);
386 DECL_EXTERNAL (d
) = 1;
388 DECL_ARTIFICIAL (d
) = 1;
389 DECL_NOT_REALLY_EXTERN (d
) = 1;
390 SET_DECL_TINFO_FN_P (d
);
391 TREE_TYPE (name
) = type
;
393 pushdecl_top_level (d
);
394 make_function_rtl (d
);
395 mark_inline_for_output (d
);
400 /* Given an expr produced by get_tinfo_decl, return an expr which
401 produces a reference to the type_info object. */
404 tinfo_from_decl (expr
)
407 tree t
= build_call (expr
, TREE_TYPE (tinfo_decl_type
), NULL_TREE
);
418 t
= get_tinfo_decl (type
);
419 t
= tinfo_from_decl (t
);
420 return convert_from_reference (t
);
423 /* Return the type_info object for TYPE. */
429 if (type
== error_mark_node
)
430 return error_mark_node
;
432 if (TYPE_SIZE (type_info_type_node
) == NULL_TREE
)
434 error ("must #include <typeinfo> before using typeid");
435 return error_mark_node
;
438 if (processing_template_decl
)
439 return build_min_nt (TYPEID_EXPR
, type
);
441 /* If the type of the type-id is a reference type, the result of the
442 typeid expression refers to a type_info object representing the
444 if (TREE_CODE (type
) == REFERENCE_TYPE
)
445 type
= TREE_TYPE (type
);
447 /* The top-level cv-qualifiers of the lvalue expression or the type-id
448 that is the operand of typeid are always ignored. */
449 type
= TYPE_MAIN_VARIANT (type
);
451 if (type
!= void_type_node
)
452 type
= complete_type_or_else (type
, NULL_TREE
);
455 return error_mark_node
;
457 return get_typeid_1 (type
);
460 /* Check whether TEST is null before returning RESULT. If TEST is used in
461 RESULT, it must have previously had a save_expr applied to it. */
464 ifnonnull (test
, result
)
467 return build (COND_EXPR
, TREE_TYPE (result
),
468 build (EQ_EXPR
, boolean_type_node
, test
, integer_zero_node
),
469 cp_convert (TREE_TYPE (result
), integer_zero_node
),
473 /* Generate the constant expression describing where direct base BINFO
474 appears within the PARENT. How to interpret this expression depends on
475 details of the ABI, which the runtime must be aware of. */
478 get_base_offset (binfo
, parent
)
484 if (!TREE_VIA_VIRTUAL (binfo
))
485 offset
= BINFO_OFFSET (binfo
);
486 else if (!vbase_offsets_in_vtable_p ())
488 tree t
= BINFO_TYPE (binfo
);
492 FORMAT_VBASE_NAME (name
, t
);
493 field
= lookup_field (parent
, get_identifier (name
), 0, 0);
494 offset
= size_binop (FLOOR_DIV_EXPR
,
495 DECL_FIELD_BITPOS (field
),
496 size_int (BITS_PER_UNIT
));
497 offset
= convert (sizetype
, offset
);
501 /* Under the new ABI, we store the vtable offset at which
502 the virtual base offset can be found. */
503 tree vbase
= BINFO_FOR_VBASE (BINFO_TYPE (binfo
), parent
);
504 offset
= convert (sizetype
, BINFO_VPTR_FIELD (vbase
));
509 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
513 build_dynamic_cast_1 (type
, expr
)
516 enum tree_code tc
= TREE_CODE (type
);
520 tree old_expr
= expr
;
522 if (TREE_CODE (expr
) == OFFSET_REF
)
523 expr
= resolve_offset_ref (expr
);
525 exprtype
= TREE_TYPE (expr
);
526 assert (exprtype
!= NULL_TREE
);
527 ec
= TREE_CODE (exprtype
);
532 if (ec
== REFERENCE_TYPE
)
534 expr
= convert_from_reference (expr
);
535 exprtype
= TREE_TYPE (expr
);
536 ec
= TREE_CODE (exprtype
);
538 if (ec
!= POINTER_TYPE
)
540 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
542 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
544 if (!at_least_as_qualified_p (TREE_TYPE (type
),
545 TREE_TYPE (exprtype
)))
547 if (TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
549 /* else fall through */
551 if (TREE_CODE (TREE_TYPE (type
)) != RECORD_TYPE
)
553 if (TYPE_SIZE (complete_type (TREE_TYPE (type
))) == NULL_TREE
)
556 /* else fall through */
561 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
562 if (ec
== RECORD_TYPE
)
564 exprtype
= build_reference_type (exprtype
);
565 expr
= convert_to_reference (exprtype
, expr
, CONV_IMPLICIT
,
566 LOOKUP_NORMAL
, NULL_TREE
);
570 if (tc
== REFERENCE_TYPE
)
572 if (ec
!= REFERENCE_TYPE
)
574 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
576 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
578 if (!at_least_as_qualified_p (TREE_TYPE (type
),
579 TREE_TYPE (exprtype
)))
583 /* If *type is an unambiguous accessible base class of *exprtype,
584 convert statically. */
589 distance
= get_base_distance (TREE_TYPE (type
), TREE_TYPE (exprtype
), 1,
594 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
595 TREE_TYPE (exprtype
), TREE_TYPE (type
));
596 return error_mark_node
;
600 cp_error ("dynamic_cast from `%T' to private base class `%T'",
601 TREE_TYPE (exprtype
), TREE_TYPE (type
));
602 return error_mark_node
;
606 return build_vbase_path (PLUS_EXPR
, type
, expr
, path
, 0);
609 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
610 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype
)))
613 /* if TYPE is `void *', return pointer to complete object. */
614 if (tc
== POINTER_TYPE
615 && TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
617 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
618 if (TREE_CODE (expr
) == ADDR_EXPR
619 && TREE_CODE (TREE_OPERAND (expr
, 0)) == VAR_DECL
620 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == RECORD_TYPE
)
621 return build1 (NOP_EXPR
, type
, expr
);
623 /* Since expr is used twice below, save it. */
624 expr
= save_expr (expr
);
626 expr1
= build_headof (expr
);
627 if (TREE_TYPE (expr1
) != type
)
628 expr1
= build1 (NOP_EXPR
, type
, expr1
);
629 return ifnonnull (expr
, expr1
);
634 tree result
, td1
, td2
, td3
, elems
, expr2
;
635 tree static_type
, target_type
, boff
;
637 /* If we got here, we can't convert statically. Therefore,
638 dynamic_cast<D&>(b) (b an object) cannot succeed. */
639 if (ec
== REFERENCE_TYPE
)
641 if (TREE_CODE (old_expr
) == VAR_DECL
642 && TREE_CODE (TREE_TYPE (old_expr
)) == RECORD_TYPE
)
644 tree expr
= throw_bad_cast ();
645 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
647 /* Bash it to the expected type. */
648 TREE_TYPE (expr
) = type
;
652 /* Ditto for dynamic_cast<D*>(&b). */
653 else if (TREE_CODE (expr
) == ADDR_EXPR
)
655 tree op
= TREE_OPERAND (expr
, 0);
656 if (TREE_CODE (op
) == VAR_DECL
657 && TREE_CODE (TREE_TYPE (op
)) == RECORD_TYPE
)
659 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
661 retval
= build_int_2 (0, 0);
662 TREE_TYPE (retval
) = type
;
667 /* Since expr is used twice below, save it. */
668 expr
= save_expr (expr
);
671 if (tc
== REFERENCE_TYPE
)
672 expr1
= build_unary_op (ADDR_EXPR
, expr1
, 0);
674 /* Build run-time conversion. */
675 expr2
= build_headof (expr1
);
677 if (ec
== POINTER_TYPE
)
678 td1
= get_tinfo_decl_dynamic (build_indirect_ref (expr
, NULL_PTR
));
680 td1
= get_tinfo_decl_dynamic (expr
);
682 target_type
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
683 static_type
= TYPE_MAIN_VARIANT (TREE_TYPE (exprtype
));
684 td2
= build_unary_op (ADDR_EXPR
, get_tinfo_decl (target_type
), 0);
685 td3
= build_unary_op (ADDR_EXPR
, get_tinfo_decl (static_type
), 0);
687 /* Determine how T and V are related. */
688 boff
= get_dynamic_cast_base_type (static_type
, target_type
);
691 (NULL_TREE
, td1
, tree_cons
692 (NULL_TREE
, td2
, tree_cons
693 (NULL_TREE
, boff
, tree_cons
694 (NULL_TREE
, expr2
, tree_cons
695 (NULL_TREE
, td3
, tree_cons
696 (NULL_TREE
, expr1
, NULL_TREE
))))));
698 dcast_fn
= dynamic_cast_node
;
702 tree tinfo_ptr
= build_pointer_type (tinfo_decl_type
);
705 (NULL_TREE
, tinfo_ptr
, tree_cons
706 (NULL_TREE
, tinfo_ptr
, tree_cons
707 (NULL_TREE
, integer_type_node
, tree_cons
708 (NULL_TREE
, ptr_type_node
, tree_cons
709 (NULL_TREE
, tinfo_ptr
, tree_cons
710 (NULL_TREE
, ptr_type_node
, void_list_node
))))));
712 tmp
= build_function_type (ptr_type_node
, tmp
);
713 dcast_fn
= build_lang_decl (FUNCTION_DECL
,
714 get_identifier ("__dynamic_cast_2"),
716 DECL_EXTERNAL (dcast_fn
) = 1;
717 TREE_PUBLIC (dcast_fn
) = 1;
718 DECL_ARTIFICIAL (dcast_fn
) = 1;
719 pushdecl_top_level (dcast_fn
);
720 make_function_rtl (dcast_fn
);
722 dynamic_cast_node
= dcast_fn
;
724 mark_used (dcast_fn
);
726 (dcast_fn
, TREE_TYPE (TREE_TYPE (dcast_fn
)), elems
);
728 if (tc
== REFERENCE_TYPE
)
730 expr1
= throw_bad_cast ();
731 result
= save_expr (result
);
732 return build (COND_EXPR
, type
, result
, result
, expr1
);
735 /* Now back to the type we want from a void*. */
736 result
= cp_convert (type
, result
);
737 return ifnonnull (expr
, result
);
741 cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype
);
742 return error_mark_node
;
745 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
746 expr
, exprtype
, type
);
747 return error_mark_node
;
751 build_dynamic_cast (type
, expr
)
754 if (type
== error_mark_node
|| expr
== error_mark_node
)
755 return error_mark_node
;
757 if (processing_template_decl
)
758 return build_min (DYNAMIC_CAST_EXPR
, type
, expr
);
760 return convert_from_reference (build_dynamic_cast_1 (type
, expr
));
763 /* Build and initialize various sorts of descriptors. Every descriptor
764 node has a name associated with it (the name created by mangling).
765 For this reason, we use the identifier as our access to the __*_desc
766 nodes, instead of sticking them directly in the types. Otherwise we
767 would burden all built-in types (and pointer types) with slots that
768 we don't necessarily want to use.
770 For each descriptor we build, we build a variable that contains
771 the descriptor's information. When we need this info at runtime,
772 all we need is access to these variables.
774 Note: these constructors always return the address of the descriptor
775 info, since that is simplest for their mutual interaction. */
777 /* Build an initializer for a __si_type_info node. */
780 expand_si_desc (tdecl
, type
)
785 tree name_string
= tinfo_name (type
);
787 type
= BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0));
788 finish_expr_stmt (get_typeid_1 (type
));
789 t
= decay_conversion (get_tinfo_var (type
));
791 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
792 (NULL_TREE
, decay_conversion (name_string
), tree_cons
793 (NULL_TREE
, t
, NULL_TREE
)));
795 fn
= get_identifier ("__rtti_si");
796 if (IDENTIFIER_GLOBAL_VALUE (fn
))
797 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
802 (NULL_TREE
, ptr_type_node
, tree_cons
803 (NULL_TREE
, const_string_type_node
, tree_cons
804 (NULL_TREE
, build_pointer_type (type_info_type_node
),
806 tmp
= build_function_type (void_type_node
, tmp
);
808 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
809 DECL_EXTERNAL (fn
) = 1;
810 TREE_PUBLIC (fn
) = 1;
811 DECL_ARTIFICIAL (fn
) = 1;
812 pushdecl_top_level (fn
);
813 make_function_rtl (fn
);
817 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
818 finish_expr_stmt (fn
);
821 /* Build an initializer for a __class_type_info node. */
824 expand_class_desc (tdecl
, type
)
831 int i
= CLASSTYPE_N_BASECLASSES (type
);
833 tree binfos
= TYPE_BINFO_BASETYPES (type
);
835 /* See code below that used these. */
836 tree vb
= CLASSTYPE_VBASECLASSES (type
);
839 tree base
, elems
, access
, offset
, isvir
;
840 tree elt
, elts
= NULL_TREE
;
842 if (base_desc_type_node
== NULL_TREE
)
846 /* A reasonably close approximation of __class_type_info::base_info */
848 base_desc_type_node
= make_aggr_type (RECORD_TYPE
);
850 /* Actually const __user_type_info * */
851 fields
[0] = build_lang_decl
852 (FIELD_DECL
, NULL_TREE
,
853 build_pointer_type (build_qualified_type
854 (type_info_type_node
,
856 fields
[1] = build_lang_decl
857 (FIELD_DECL
, NULL_TREE
,
858 flag_new_abi
? intSI_type_node
: unsigned_intSI_type_node
);
859 DECL_BIT_FIELD (fields
[1]) = 1;
860 DECL_FIELD_SIZE (fields
[1]) = 29;
862 fields
[2] = build_lang_decl
863 (FIELD_DECL
, NULL_TREE
, boolean_type_node
);
864 DECL_BIT_FIELD (fields
[2]) = 1;
865 DECL_FIELD_SIZE (fields
[2]) = 1;
867 /* Actually enum access */
868 fields
[3] = build_lang_decl
869 (FIELD_DECL
, NULL_TREE
, integer_type_node
);
870 DECL_BIT_FIELD (fields
[3]) = 1;
871 DECL_FIELD_SIZE (fields
[3]) = 2;
873 finish_builtin_type (base_desc_type_node
, "__base_info", fields
,
879 tree binfo
= TREE_VEC_ELT (binfos
, i
);
881 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo
)));
882 base
= decay_conversion (get_tinfo_var (BINFO_TYPE (binfo
)));
883 offset
= get_base_offset (binfo
, type
);
885 if (TREE_VIA_PUBLIC (binfo
))
886 access
= access_public_node
;
887 else if (TREE_VIA_PROTECTED (binfo
))
888 access
= access_protected_node
;
890 access
= access_private_node
;
891 if (TREE_VIA_VIRTUAL (binfo
))
892 isvir
= boolean_true_node
;
894 isvir
= boolean_false_node
;
897 (CONSTRUCTOR
, base_desc_type_node
, NULL_TREE
, tree_cons
898 (NULL_TREE
, base
, tree_cons
899 (NULL_TREE
, offset
, tree_cons
900 (NULL_TREE
, isvir
, tree_cons
901 (NULL_TREE
, access
, NULL_TREE
)))));
902 TREE_HAS_CONSTRUCTOR (elt
) = TREE_CONSTANT (elt
) = TREE_STATIC (elt
) = 1;
903 elts
= tree_cons (NULL_TREE
, elt
, elts
);
911 access
= access_public_node
;
914 b
= TREE_VEC_ELT (binfos
, i
);
915 if (BINFO_TYPE (vb
) == BINFO_TYPE (b
) && TREE_VIA_VIRTUAL (b
))
917 if (TREE_VIA_PUBLIC (b
))
918 access
= access_public_node
;
919 else if (TREE_VIA_PROTECTED (b
))
920 access
= access_protected_node
;
922 access
= access_private_node
;
926 base
= build_t_desc (BINFO_TYPE (vb
), 1);
927 offset
= BINFO_OFFSET (vb
);
928 isvir
= build_int_2 (1, 0);
930 base_list
= tree_cons (NULL_TREE
, base
, base_list
);
931 isvir_list
= tree_cons (NULL_TREE
, isvir
, isvir_list
);
932 acc_list
= tree_cons (NULL_TREE
, access
, acc_list
);
933 off_list
= tree_cons (NULL_TREE
, offset
, off_list
);
936 vb
= TREE_CHAIN (vb
);
940 name_string
= tinfo_name (type
);
943 tree arrtype
= build_array_type (base_desc_type_node
, NULL_TREE
);
944 elts
= build (CONSTRUCTOR
, arrtype
, NULL_TREE
, elts
);
945 TREE_HAS_CONSTRUCTOR (elts
) = TREE_CONSTANT (elts
)
946 = TREE_STATIC (elts
) = 1;
947 complete_array_type (arrtype
, elts
, 1);
951 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
952 (NULL_TREE
, decay_conversion (name_string
), tree_cons
953 (NULL_TREE
, decay_conversion (elts
), tree_cons
954 (NULL_TREE
, cp_convert (sizetype
, build_int_2 (base_cnt
, 0)),
957 fn
= get_identifier ("__rtti_class");
958 if (IDENTIFIER_GLOBAL_VALUE (fn
))
959 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
963 (NULL_TREE
, ptr_type_node
, tree_cons
964 (NULL_TREE
, const_string_type_node
, tree_cons
965 (NULL_TREE
, build_pointer_type (base_desc_type_node
), tree_cons
966 (NULL_TREE
, sizetype
, void_list_node
))));
967 tmp
= build_function_type (void_type_node
, tmp
);
969 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
970 DECL_EXTERNAL (fn
) = 1;
971 TREE_PUBLIC (fn
) = 1;
972 DECL_ARTIFICIAL (fn
) = 1;
973 pushdecl_top_level (fn
);
974 make_function_rtl (fn
);
978 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
979 finish_expr_stmt (fn
);
982 /* Build an initializer for a __pointer_type_info node. */
985 expand_ptr_desc (tdecl
, type
)
990 tree name_string
= tinfo_name (type
);
992 type
= TREE_TYPE (type
);
993 finish_expr_stmt (get_typeid_1 (type
));
994 t
= decay_conversion (get_tinfo_var (type
));
996 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
997 (NULL_TREE
, decay_conversion (name_string
), tree_cons
998 (NULL_TREE
, t
, NULL_TREE
)));
1000 fn
= get_identifier ("__rtti_ptr");
1001 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1002 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
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
);
1022 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1023 finish_expr_stmt (fn
);
1026 /* Build an initializer for a __attr_type_info node. */
1029 expand_attr_desc (tdecl
, type
)
1034 tree name_string
= tinfo_name (type
);
1035 tree attrval
= build_int_2 (TYPE_QUALS (type
), 0);
1037 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type
)));
1038 t
= decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type
)));
1040 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1041 (NULL_TREE
, decay_conversion (name_string
), tree_cons
1042 (NULL_TREE
, attrval
, tree_cons (NULL_TREE
, t
, NULL_TREE
))));
1044 fn
= get_identifier ("__rtti_attr");
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
, tree_cons
1053 (NULL_TREE
, integer_type_node
, tree_cons
1054 (NULL_TREE
, build_pointer_type (type_info_type_node
),
1056 tmp
= build_function_type (void_type_node
, tmp
);
1058 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1059 DECL_EXTERNAL (fn
) = 1;
1060 TREE_PUBLIC (fn
) = 1;
1061 DECL_ARTIFICIAL (fn
) = 1;
1062 pushdecl_top_level (fn
);
1063 make_function_rtl (fn
);
1067 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1068 finish_expr_stmt (fn
);
1071 /* Build an initializer for a type_info node that just has a name. */
1074 expand_generic_desc (tdecl
, type
, fnname
)
1079 tree name_string
= tinfo_name (type
);
1080 tree elems
= tree_cons
1081 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1082 (NULL_TREE
, decay_conversion (name_string
), NULL_TREE
));
1084 tree fn
= get_identifier (fnname
);
1085 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1086 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1091 (NULL_TREE
, ptr_type_node
, tree_cons
1092 (NULL_TREE
, const_string_type_node
, void_list_node
));
1093 tmp
= build_function_type (void_type_node
, tmp
);
1095 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1096 DECL_EXTERNAL (fn
) = 1;
1097 TREE_PUBLIC (fn
) = 1;
1098 DECL_ARTIFICIAL (fn
) = 1;
1099 pushdecl_top_level (fn
);
1100 make_function_rtl (fn
);
1104 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1105 finish_expr_stmt (fn
);
1108 /* Generate the code for a type_info initialization function.
1109 Note that we take advantage of the passage
1111 5.2.7 Type identification [expr.typeid]
1113 Whether or not the destructor is called for the type_info object at the
1114 end of the program is unspecified.
1116 and don't bother to arrange for these objects to be destroyed. It
1117 doesn't matter, anyway, since the destructors don't do anything.
1119 This must only be called from toplevel (i.e. from finish_file)! */
1122 synthesize_tinfo_fn (fndecl
)
1125 tree type
= TREE_TYPE (DECL_NAME (fndecl
));
1126 tree tmp
, addr
, tdecl
;
1133 import_export_decl (fndecl
);
1134 if (DECL_REALLY_EXTERN (fndecl
))
1138 /* Declare the static typeinfo variable. */
1139 tdecl
= get_tinfo_var (type
);
1140 DECL_EXTERNAL (tdecl
) = 0;
1141 TREE_STATIC (tdecl
) = 1;
1142 DECL_COMMON (tdecl
) = 1;
1143 TREE_USED (tdecl
) = 1;
1144 DECL_ALIGN (tdecl
) = TYPE_ALIGN (ptr_type_node
);
1145 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0);
1147 /* Begin processing the function. */
1148 start_function (NULL_TREE
, fndecl
, NULL_TREE
,
1149 SF_DEFAULT
| SF_PRE_PARSED
);
1150 DECL_DEFER_OUTPUT (fndecl
) = 1;
1151 store_parm_decls ();
1154 /* Begin the body of the function. */
1155 compound_stmt
= begin_compound_stmt (/*has_no_scope=*/0);
1157 /* For convenience, we save away the address of the static
1159 addr
= decay_conversion (tdecl
);
1161 /* If the first word of the array (the vtable) is non-zero, we've already
1162 initialized the object, so don't do it again. */
1163 if_stmt
= begin_if_stmt ();
1164 tmp
= cp_convert (build_pointer_type (ptr_type_node
), addr
);
1165 tmp
= build_indirect_ref (tmp
, 0);
1166 tmp
= build_binary_op (EQ_EXPR
, tmp
, integer_zero_node
);
1167 finish_if_stmt_cond (tmp
, if_stmt
);
1168 then_clause
= begin_compound_stmt (/*has_no_scope=*/0);
1170 if (TREE_CODE (type
) == FUNCTION_TYPE
)
1171 expand_generic_desc (tdecl
, type
, "__rtti_func");
1172 else if (TREE_CODE (type
) == ARRAY_TYPE
)
1173 expand_generic_desc (tdecl
, type
, "__rtti_array");
1174 else if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
1175 expand_attr_desc (tdecl
, type
);
1176 else if (TREE_CODE (type
) == POINTER_TYPE
)
1178 if (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
)
1179 expand_generic_desc (tdecl
, type
, "__rtti_ptmd");
1180 else if (TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
)
1181 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1183 expand_ptr_desc (tdecl
, type
);
1185 else if (TYPE_PTRMEMFUNC_P (type
))
1186 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1187 else if (IS_AGGR_TYPE (type
))
1189 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
1190 expand_generic_desc (tdecl
, type
, "__rtti_user");
1191 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type
)
1193 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
1194 expand_si_desc (tdecl
, type
);
1196 expand_class_desc (tdecl
, type
);
1198 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
1199 expand_generic_desc (tdecl
, type
, "__rtti_user");
1201 my_friendly_abort (252);
1203 finish_compound_stmt (/*has_no_scope=*/0, then_clause
);
1204 finish_then_clause (if_stmt
);
1207 /* OK, now return the type_info object. */
1208 tmp
= cp_convert (build_pointer_type (type_info_type_node
), addr
);
1209 tmp
= build_indirect_ref (tmp
, 0);
1210 finish_return_stmt (tmp
);
1211 /* Finish the function body. */
1212 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt
);
1213 expand_body (finish_function (lineno
, 0));