1 /* RunTime Type Identification
2 Copyright (C) 1995, 96-97, 1998, 1999 Free Software Foundation, Inc.
3 Mostly written by Jason Merrill (jason@cygnus.com).
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
33 #define INT_TYPE_SIZE BITS_PER_WORD
36 extern struct obstack permanent_obstack
;
38 static tree call_void_fn
PROTO((const char *));
39 static tree build_headof_sub
PROTO((tree
));
40 static tree build_headof
PROTO((tree
));
41 static tree get_tinfo_var
PROTO((tree
));
42 static tree ifnonnull
PROTO((tree
, tree
));
43 static tree build_dynamic_cast_1
PROTO((tree
, tree
));
44 static void expand_si_desc
PROTO((tree
, tree
));
45 static void expand_class_desc
PROTO((tree
, tree
));
46 static void expand_attr_desc
PROTO((tree
, tree
));
47 static void expand_ptr_desc
PROTO((tree
, tree
));
48 static void expand_generic_desc
PROTO((tree
, tree
, const char *));
49 static tree throw_bad_cast
PROTO((void));
50 static tree throw_bad_typeid
PROTO((void));
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_VIRTUAL_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_VIRTUAL_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 push_obstacks (&permanent_obstack
, &permanent_obstack
);
148 type
= build_function_type (void_type_node
, void_list_node
);
149 d
= build_lang_decl (FUNCTION_DECL
, d
, type
);
150 DECL_EXTERNAL (d
) = 1;
152 DECL_ARTIFICIAL (d
) = 1;
153 pushdecl_top_level (d
);
154 make_function_rtl (d
);
159 return build_call (d
, void_type_node
, NULL_TREE
);
162 /* Get a bad_cast node for the program to throw...
164 See libstdc++/exception.cc for __throw_bad_cast */
169 return call_void_fn ("__throw_bad_cast");
175 return call_void_fn ("__throw_bad_typeid");
178 /* Return the type_info function associated with the expression EXP. If
179 EXP is a reference to a polymorphic class, return the dynamic type;
180 otherwise return the static type of the expression. */
183 get_tinfo_fn_dynamic (exp
)
188 if (exp
== error_mark_node
)
189 return error_mark_node
;
191 if (type_unknown_p (exp
))
193 error ("typeid of overloaded function");
194 return error_mark_node
;
197 type
= TREE_TYPE (exp
);
199 /* peel back references, so they match. */
200 if (TREE_CODE (type
) == REFERENCE_TYPE
)
201 type
= TREE_TYPE (type
);
203 /* Peel off cv qualifiers. */
204 type
= TYPE_MAIN_VARIANT (type
);
206 if (TYPE_SIZE (complete_type (type
)) == NULL_TREE
)
208 cp_error ("taking typeid of incomplete type `%T'", type
);
209 return error_mark_node
;
212 /* If exp is a reference to polymorphic type, get the real type_info. */
213 if (TYPE_VIRTUAL_P (type
) && ! resolves_to_fixed_type_p (exp
, 0))
215 /* build reference to type_info from vtable. */
219 error ("taking dynamic typeid of object with -fno-rtti");
220 if (CLASSTYPE_COM_INTERFACE (type
))
222 cp_error ("RTTI not supported for COM interface type `%T'", type
);
223 return error_mark_node
;
226 /* If we don't have rtti stuff, get to a sub-object that does. */
227 if (! CLASSTYPE_VFIELDS (type
))
229 exp
= build_unary_op (ADDR_EXPR
, exp
, 0);
230 exp
= build_headof_sub (exp
);
231 exp
= build_indirect_ref (exp
, NULL_PTR
);
234 if (flag_vtable_thunks
)
235 t
= build_vfn_ref ((tree
*) 0, exp
, integer_one_node
);
237 t
= build_vfn_ref ((tree
*) 0, exp
, integer_zero_node
);
238 TREE_TYPE (t
) = build_pointer_type (tinfo_fn_type
);
242 /* otherwise return the type_info for the static type of the expr. */
243 return get_tinfo_fn (TYPE_MAIN_VARIANT (type
));
250 exp
= get_tinfo_fn_dynamic (exp
);
251 exp
= build_call (exp
, TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
252 return convert_from_reference (exp
);
259 tree cond
= NULL_TREE
;
265 error ("cannot use typeid with -fno-rtti");
266 return error_mark_node
;
269 if (TYPE_SIZE (type_info_type_node
) == NULL_TREE
)
271 error ("must #include <typeinfo> before using typeid");
272 return error_mark_node
;
275 if (processing_template_decl
)
276 return build_min_nt (TYPEID_EXPR
, exp
);
278 if (TREE_CODE (exp
) == INDIRECT_REF
279 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp
, 0))) == POINTER_TYPE
280 && TYPE_VIRTUAL_P (TREE_TYPE (exp
))
281 && ! resolves_to_fixed_type_p (exp
, &nonnull
)
284 exp
= stabilize_reference (exp
);
285 cond
= cp_convert (boolean_type_node
, TREE_OPERAND (exp
, 0));
288 exp
= get_tinfo_fn_dynamic (exp
);
290 if (exp
== error_mark_node
)
291 return error_mark_node
;
293 type
= TREE_TYPE (tinfo_fn_type
);
294 exp
= build_call (exp
, type
, NULL_TREE
);
298 tree bad
= throw_bad_typeid ();
300 bad
= build_compound_expr
301 (tree_cons (NULL_TREE
, bad
, build_expr_list
302 (NULL_TREE
, cp_convert (type
, integer_zero_node
))));
303 exp
= build (COND_EXPR
, type
, cond
, exp
, bad
);
306 return convert_from_reference (exp
);
313 tree tname
= build_overload_with_type (get_identifier ("__ti"), type
);
317 if (IDENTIFIER_GLOBAL_VALUE (tname
))
318 return IDENTIFIER_GLOBAL_VALUE (tname
);
320 /* Figure out how much space we need to allocate for the type_info object.
321 If our struct layout or the type_info classes are changed, this will
322 need to be modified. */
323 if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
324 size
= 3 * POINTER_SIZE
+ INT_TYPE_SIZE
;
325 else if (TREE_CODE (type
) == POINTER_TYPE
326 && ! (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
327 || TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
))
328 size
= 3 * POINTER_SIZE
;
329 else if (IS_AGGR_TYPE (type
))
331 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
332 size
= 2 * POINTER_SIZE
;
333 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
335 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
336 size
= 3 * POINTER_SIZE
;
338 size
= 3 * POINTER_SIZE
+ TYPE_PRECISION (sizetype
);
341 size
= 2 * POINTER_SIZE
;
343 push_obstacks (&permanent_obstack
, &permanent_obstack
);
345 /* The type for a character array of the appropriate size. */
346 arrtype
= build_cplus_array_type
347 (unsigned_char_type_node
,
348 build_index_type (size_int (size
/ BITS_PER_UNIT
- 1)));
350 tdecl
= build_decl (VAR_DECL
, tname
, arrtype
);
351 TREE_PUBLIC (tdecl
) = 1;
352 DECL_EXTERNAL (tdecl
) = 1;
353 DECL_ARTIFICIAL (tdecl
) = 1;
354 push_to_top_level ();
356 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
357 pop_from_top_level ();
364 /* Returns the decl for a function which will return a type_info node for
365 TYPE. This version does not mark the function used, for use in
366 set_rtti_entry; for the vtable case, we'll get marked in
367 finish_vtable_vardecl, when we know that we want to be emitted.
369 We do this to avoid emitting the tinfo node itself, since we don't
370 currently support DECL_DEFER_OUTPUT for variables. Also, we don't
371 associate constant pools with their functions properly, so we would
372 emit string constants and such even though we don't emit the actual
373 function. When those bugs are fixed, this function should go away. */
376 get_tinfo_fn_unused (type
)
382 if (TREE_CODE (type
) == OFFSET_TYPE
)
383 type
= TREE_TYPE (type
);
384 if (TREE_CODE (type
) == METHOD_TYPE
)
385 type
= build_function_type (TREE_TYPE (type
),
386 TREE_CHAIN (TYPE_ARG_TYPES (type
)));
388 name
= build_overload_with_type (tinfo_fn_id
, type
);
390 if (IDENTIFIER_GLOBAL_VALUE (name
))
391 return IDENTIFIER_GLOBAL_VALUE (name
);
393 push_obstacks (&permanent_obstack
, &permanent_obstack
);
395 d
= build_lang_decl (FUNCTION_DECL
, name
, tinfo_fn_type
);
396 DECL_EXTERNAL (d
) = 1;
398 DECL_ARTIFICIAL (d
) = 1;
399 DECL_NOT_REALLY_EXTERN (d
) = 1;
400 SET_DECL_TINFO_FN_P (d
);
401 TREE_TYPE (name
) = type
;
403 pushdecl_top_level (d
);
404 make_function_rtl (d
);
405 mark_inline_for_output (d
);
411 /* Likewise, but also mark it used. Called by various EH and RTTI code. */
417 tree d
= get_tinfo_fn_unused (type
);
429 (get_tinfo_fn (type
), TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
430 return convert_from_reference (t
);
433 /* Return the type_info object for TYPE, creating it if necessary. */
439 if (type
== error_mark_node
)
440 return error_mark_node
;
442 if (TYPE_SIZE (type_info_type_node
) == NULL_TREE
)
444 error ("must #include <typeinfo> before using typeid");
445 return error_mark_node
;
448 if (processing_template_decl
)
449 return build_min_nt (TYPEID_EXPR
, type
);
451 /* If the type of the type-id is a reference type, the result of the
452 typeid expression refers to a type_info object representing the
454 if (TREE_CODE (type
) == REFERENCE_TYPE
)
455 type
= TREE_TYPE (type
);
457 /* The top-level cv-qualifiers of the lvalue expression or the type-id
458 that is the operand of typeid are always ignored. */
459 type
= TYPE_MAIN_VARIANT (type
);
461 if (TYPE_SIZE (complete_type (type
)) == NULL_TREE
)
463 cp_error ("taking typeid of incomplete type `%T'", type
);
464 return error_mark_node
;
467 return get_typeid_1 (type
);
470 /* Check whether TEST is null before returning RESULT. If TEST is used in
471 RESULT, it must have previously had a save_expr applied to it. */
474 ifnonnull (test
, result
)
477 return build (COND_EXPR
, TREE_TYPE (result
),
478 build (EQ_EXPR
, boolean_type_node
, test
, integer_zero_node
),
479 cp_convert (TREE_TYPE (result
), integer_zero_node
),
483 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
487 build_dynamic_cast_1 (type
, expr
)
490 enum tree_code tc
= TREE_CODE (type
);
494 tree old_expr
= expr
;
496 if (TREE_CODE (expr
) == OFFSET_REF
)
497 expr
= resolve_offset_ref (expr
);
499 exprtype
= TREE_TYPE (expr
);
500 assert (exprtype
!= NULL_TREE
);
501 ec
= TREE_CODE (exprtype
);
506 if (ec
== REFERENCE_TYPE
)
508 expr
= convert_from_reference (expr
);
509 exprtype
= TREE_TYPE (expr
);
510 ec
= TREE_CODE (exprtype
);
512 if (ec
!= POINTER_TYPE
)
514 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
516 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
518 if (!at_least_as_qualified_p (TREE_TYPE (type
),
519 TREE_TYPE (exprtype
)))
521 if (TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
523 /* else fall through */
525 if (TREE_CODE (TREE_TYPE (type
)) != RECORD_TYPE
)
527 if (TYPE_SIZE (complete_type (TREE_TYPE (type
))) == NULL_TREE
)
530 /* else fall through */
535 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
536 if (ec
== RECORD_TYPE
)
538 exprtype
= build_reference_type (exprtype
);
539 expr
= convert_to_reference (exprtype
, expr
, CONV_IMPLICIT
,
540 LOOKUP_NORMAL
, NULL_TREE
);
544 if (tc
== REFERENCE_TYPE
)
546 if (ec
!= REFERENCE_TYPE
)
548 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
550 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
552 if (!at_least_as_qualified_p (TREE_TYPE (type
),
553 TREE_TYPE (exprtype
)))
557 /* If *type is an unambiguous accessible base class of *exprtype,
558 convert statically. */
563 distance
= get_base_distance (TREE_TYPE (type
), TREE_TYPE (exprtype
), 1,
568 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
569 TREE_TYPE (exprtype
), TREE_TYPE (type
));
570 return error_mark_node
;
574 cp_error ("dynamic_cast from `%T' to private base class `%T'",
575 TREE_TYPE (exprtype
), TREE_TYPE (type
));
576 return error_mark_node
;
580 return build_vbase_path (PLUS_EXPR
, type
, expr
, path
, 0);
583 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
584 if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype
)))
587 /* if TYPE is `void *', return pointer to complete object. */
588 if (tc
== POINTER_TYPE
589 && TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
591 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
592 if (TREE_CODE (expr
) == ADDR_EXPR
593 && TREE_CODE (TREE_OPERAND (expr
, 0)) == VAR_DECL
594 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == RECORD_TYPE
)
595 return build1 (NOP_EXPR
, type
, expr
);
597 /* Since expr is used twice below, save it. */
598 expr
= save_expr (expr
);
600 expr1
= build_headof (expr
);
601 if (TREE_TYPE (expr1
) != type
)
602 expr1
= build1 (NOP_EXPR
, type
, expr1
);
603 return ifnonnull (expr
, expr1
);
608 tree result
, td1
, td2
, td3
, elems
, expr2
;
609 tree static_type
, target_type
, boff
;
611 /* If we got here, we can't convert statically. Therefore,
612 dynamic_cast<D&>(b) (b an object) cannot succeed. */
613 if (ec
== REFERENCE_TYPE
)
615 if (TREE_CODE (old_expr
) == VAR_DECL
616 && TREE_CODE (TREE_TYPE (old_expr
)) == RECORD_TYPE
)
618 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
620 return throw_bad_cast ();
623 /* Ditto for dynamic_cast<D*>(&b). */
624 else if (TREE_CODE (expr
) == ADDR_EXPR
)
626 tree op
= TREE_OPERAND (expr
, 0);
627 if (TREE_CODE (op
) == VAR_DECL
628 && TREE_CODE (TREE_TYPE (op
)) == RECORD_TYPE
)
630 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
632 retval
= build_int_2 (0, 0);
633 TREE_TYPE (retval
) = type
;
638 /* Since expr is used twice below, save it. */
639 expr
= save_expr (expr
);
642 if (tc
== REFERENCE_TYPE
)
643 expr1
= build_unary_op (ADDR_EXPR
, expr1
, 0);
645 /* Build run-time conversion. */
646 expr2
= build_headof (expr1
);
648 if (ec
== POINTER_TYPE
)
649 td1
= get_tinfo_fn_dynamic (build_indirect_ref (expr
, NULL_PTR
));
651 td1
= get_tinfo_fn_dynamic (expr
);
652 td1
= decay_conversion (td1
);
654 target_type
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
655 static_type
= TYPE_MAIN_VARIANT (TREE_TYPE (exprtype
));
656 td2
= decay_conversion (get_tinfo_fn (target_type
));
657 td3
= decay_conversion (get_tinfo_fn (static_type
));
659 /* Determine how T and V are related. */
660 boff
= get_dynamic_cast_base_type (static_type
, target_type
);
663 (NULL_TREE
, td1
, tree_cons
664 (NULL_TREE
, td2
, tree_cons
665 (NULL_TREE
, boff
, tree_cons
666 (NULL_TREE
, expr2
, tree_cons
667 (NULL_TREE
, td3
, tree_cons
668 (NULL_TREE
, expr1
, NULL_TREE
))))));
670 dcast_fn
= get_identifier ("__dynamic_cast_2");
671 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn
))
672 dcast_fn
= IDENTIFIER_GLOBAL_VALUE (dcast_fn
);
677 push_obstacks (&permanent_obstack
, &permanent_obstack
);
679 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
680 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
681 (NULL_TREE
, integer_type_node
, tree_cons
682 (NULL_TREE
, ptr_type_node
, tree_cons
683 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
684 (NULL_TREE
, ptr_type_node
, void_list_node
))))));
685 tmp
= build_function_type (ptr_type_node
, tmp
);
686 dcast_fn
= build_lang_decl (FUNCTION_DECL
, dcast_fn
, tmp
);
687 DECL_EXTERNAL (dcast_fn
) = 1;
688 TREE_PUBLIC (dcast_fn
) = 1;
689 DECL_ARTIFICIAL (dcast_fn
) = 1;
690 pushdecl_top_level (dcast_fn
);
691 make_function_rtl (dcast_fn
);
695 mark_used (dcast_fn
);
697 (dcast_fn
, TREE_TYPE (TREE_TYPE (dcast_fn
)), elems
);
699 if (tc
== REFERENCE_TYPE
)
701 expr1
= throw_bad_cast ();
702 expr1
= build_compound_expr
703 (tree_cons (NULL_TREE
, expr1
,
704 build_expr_list (NULL_TREE
, cp_convert (type
, integer_zero_node
))));
705 TREE_TYPE (expr1
) = type
;
706 result
= save_expr (result
);
707 return build (COND_EXPR
, type
, result
, result
, expr1
);
710 /* Now back to the type we want from a void*. */
711 result
= cp_convert (type
, result
);
712 return ifnonnull (expr
, result
);
716 cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype
);
717 return error_mark_node
;
720 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
721 expr
, exprtype
, type
);
722 return error_mark_node
;
726 build_dynamic_cast (type
, expr
)
729 if (type
== error_mark_node
|| expr
== error_mark_node
)
730 return error_mark_node
;
732 if (processing_template_decl
)
733 return build_min (DYNAMIC_CAST_EXPR
, type
, expr
);
735 return convert_from_reference (build_dynamic_cast_1 (type
, expr
));
738 /* Build and initialize various sorts of descriptors. Every descriptor
739 node has a name associated with it (the name created by mangling).
740 For this reason, we use the identifier as our access to the __*_desc
741 nodes, instead of sticking them directly in the types. Otherwise we
742 would burden all built-in types (and pointer types) with slots that
743 we don't necessarily want to use.
745 For each descriptor we build, we build a variable that contains
746 the descriptor's information. When we need this info at runtime,
747 all we need is access to these variables.
749 Note: these constructors always return the address of the descriptor
750 info, since that is simplest for their mutual interaction. */
752 /* Build an initializer for a __si_type_info node. */
755 expand_si_desc (tdecl
, type
)
760 const char *name
= build_overload_name (type
, 1, 1);
761 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
763 type
= BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0));
764 finish_expr_stmt (get_typeid_1 (type
));
765 t
= decay_conversion (get_tinfo_var (type
));
767 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
768 (NULL_TREE
, decay_conversion (name_string
), tree_cons
769 (NULL_TREE
, t
, NULL_TREE
)));
771 fn
= get_identifier ("__rtti_si");
772 if (IDENTIFIER_GLOBAL_VALUE (fn
))
773 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
777 push_obstacks (&permanent_obstack
, &permanent_obstack
);
779 (NULL_TREE
, ptr_type_node
, tree_cons
780 (NULL_TREE
, const_string_type_node
, tree_cons
781 (NULL_TREE
, build_pointer_type (type_info_type_node
),
783 tmp
= build_function_type (void_type_node
, tmp
);
785 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
786 DECL_EXTERNAL (fn
) = 1;
787 TREE_PUBLIC (fn
) = 1;
788 DECL_ARTIFICIAL (fn
) = 1;
789 pushdecl_top_level (fn
);
790 make_function_rtl (fn
);
795 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
796 finish_expr_stmt (fn
);
799 /* Build an initializer for a __class_type_info node. */
802 expand_class_desc (tdecl
, type
)
810 int i
= CLASSTYPE_N_BASECLASSES (type
);
812 tree binfos
= TYPE_BINFO_BASETYPES (type
);
814 /* See code below that used these. */
815 tree vb
= CLASSTYPE_VBASECLASSES (type
);
818 tree base
, elems
, access
, offset
, isvir
;
819 tree elt
, elts
= NULL_TREE
;
820 static tree base_info_type_node
;
822 if (base_info_type_node
== NULL_TREE
)
826 /* A reasonably close approximation of __class_type_info::base_info */
828 push_obstacks (&permanent_obstack
, &permanent_obstack
);
829 base_info_type_node
= make_lang_type (RECORD_TYPE
);
831 /* Actually const __user_type_info * */
832 fields
[0] = build_lang_decl
833 (FIELD_DECL
, NULL_TREE
,
834 build_pointer_type (build_qualified_type
835 (type_info_type_node
,
837 fields
[1] = build_lang_decl
838 (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
839 DECL_BIT_FIELD (fields
[1]) = 1;
840 DECL_FIELD_SIZE (fields
[1]) = 29;
842 fields
[2] = build_lang_decl
843 (FIELD_DECL
, NULL_TREE
, boolean_type_node
);
844 DECL_BIT_FIELD (fields
[2]) = 1;
845 DECL_FIELD_SIZE (fields
[2]) = 1;
847 /* Actually enum access */
848 fields
[3] = build_lang_decl
849 (FIELD_DECL
, NULL_TREE
, integer_type_node
);
850 DECL_BIT_FIELD (fields
[3]) = 1;
851 DECL_FIELD_SIZE (fields
[3]) = 2;
853 finish_builtin_type (base_info_type_node
, "__base_info", fields
,
860 tree binfo
= TREE_VEC_ELT (binfos
, i
);
862 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo
)));
863 base
= decay_conversion (get_tinfo_var (BINFO_TYPE (binfo
)));
865 if (TREE_VIA_VIRTUAL (binfo
))
867 tree t
= BINFO_TYPE (binfo
);
871 FORMAT_VBASE_NAME (name
, t
);
872 field
= lookup_field (type
, get_identifier (name
), 0, 0);
873 offset
= size_binop (FLOOR_DIV_EXPR
,
874 DECL_FIELD_BITPOS (field
), size_int (BITS_PER_UNIT
));
875 offset
= convert (sizetype
, offset
);
878 offset
= BINFO_OFFSET (binfo
);
880 if (TREE_VIA_PUBLIC (binfo
))
881 access
= access_public_node
;
882 else if (TREE_VIA_PROTECTED (binfo
))
883 access
= access_protected_node
;
885 access
= access_private_node
;
886 if (TREE_VIA_VIRTUAL (binfo
))
887 isvir
= boolean_true_node
;
889 isvir
= boolean_false_node
;
892 (CONSTRUCTOR
, base_info_type_node
, NULL_TREE
, tree_cons
893 (NULL_TREE
, base
, tree_cons
894 (NULL_TREE
, offset
, tree_cons
895 (NULL_TREE
, isvir
, tree_cons
896 (NULL_TREE
, access
, NULL_TREE
)))));
897 TREE_HAS_CONSTRUCTOR (elt
) = TREE_CONSTANT (elt
) = TREE_STATIC (elt
) = 1;
898 elts
= tree_cons (NULL_TREE
, elt
, elts
);
906 access
= access_public_node
;
909 b
= TREE_VEC_ELT (binfos
, i
);
910 if (BINFO_TYPE (vb
) == BINFO_TYPE (b
) && TREE_VIA_VIRTUAL (b
))
912 if (TREE_VIA_PUBLIC (b
))
913 access
= access_public_node
;
914 else if (TREE_VIA_PROTECTED (b
))
915 access
= access_protected_node
;
917 access
= access_private_node
;
921 base
= build_t_desc (BINFO_TYPE (vb
), 1);
922 offset
= BINFO_OFFSET (vb
);
923 isvir
= build_int_2 (1, 0);
925 base_list
= tree_cons (NULL_TREE
, base
, base_list
);
926 isvir_list
= tree_cons (NULL_TREE
, isvir
, isvir_list
);
927 acc_list
= tree_cons (NULL_TREE
, access
, acc_list
);
928 off_list
= tree_cons (NULL_TREE
, offset
, off_list
);
931 vb
= TREE_CHAIN (vb
);
935 name
= build_overload_name (type
, 1, 1);
936 name_string
= combine_strings (build_string (strlen (name
)+1, name
));
939 tree arrtype
= build_array_type (base_info_type_node
, NULL_TREE
);
940 elts
= build (CONSTRUCTOR
, arrtype
, NULL_TREE
, elts
);
941 TREE_HAS_CONSTRUCTOR (elts
) = TREE_CONSTANT (elts
)
942 = TREE_STATIC (elts
) = 1;
943 complete_array_type (arrtype
, elts
, 1);
947 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
948 (NULL_TREE
, decay_conversion (name_string
), tree_cons
949 (NULL_TREE
, decay_conversion (elts
), tree_cons
950 (NULL_TREE
, cp_convert (sizetype
, build_int_2 (base_cnt
, 0)),
953 fn
= get_identifier ("__rtti_class");
954 if (IDENTIFIER_GLOBAL_VALUE (fn
))
955 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
958 push_obstacks (&permanent_obstack
, &permanent_obstack
);
960 (NULL_TREE
, ptr_type_node
, tree_cons
961 (NULL_TREE
, const_string_type_node
, tree_cons
962 (NULL_TREE
, build_pointer_type (base_info_type_node
), tree_cons
963 (NULL_TREE
, sizetype
, void_list_node
))));
964 tmp
= build_function_type (void_type_node
, tmp
);
966 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
967 DECL_EXTERNAL (fn
) = 1;
968 TREE_PUBLIC (fn
) = 1;
969 DECL_ARTIFICIAL (fn
) = 1;
970 pushdecl_top_level (fn
);
971 make_function_rtl (fn
);
976 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
977 finish_expr_stmt (fn
);
980 /* Build an initializer for a __pointer_type_info node. */
983 expand_ptr_desc (tdecl
, type
)
988 const char *name
= build_overload_name (type
, 1, 1);
989 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
991 type
= TREE_TYPE (type
);
992 finish_expr_stmt (get_typeid_1 (type
));
993 t
= decay_conversion (get_tinfo_var (type
));
995 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
996 (NULL_TREE
, decay_conversion (name_string
), tree_cons
997 (NULL_TREE
, t
, NULL_TREE
)));
999 fn
= get_identifier ("__rtti_ptr");
1000 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1001 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1005 push_obstacks (&permanent_obstack
, &permanent_obstack
);
1007 (NULL_TREE
, ptr_type_node
, tree_cons
1008 (NULL_TREE
, const_string_type_node
, tree_cons
1009 (NULL_TREE
, build_pointer_type (type_info_type_node
),
1011 tmp
= build_function_type (void_type_node
, tmp
);
1013 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1014 DECL_EXTERNAL (fn
) = 1;
1015 TREE_PUBLIC (fn
) = 1;
1016 DECL_ARTIFICIAL (fn
) = 1;
1017 pushdecl_top_level (fn
);
1018 make_function_rtl (fn
);
1023 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1024 finish_expr_stmt (fn
);
1027 /* Build an initializer for a __attr_type_info node. */
1030 expand_attr_desc (tdecl
, type
)
1035 const char *name
= build_overload_name (type
, 1, 1);
1036 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
1037 tree attrval
= build_int_2 (TYPE_QUALS (type
), 0);
1039 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type
)));
1040 t
= decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type
)));
1042 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1043 (NULL_TREE
, decay_conversion (name_string
), tree_cons
1044 (NULL_TREE
, attrval
, tree_cons (NULL_TREE
, t
, NULL_TREE
))));
1046 fn
= get_identifier ("__rtti_attr");
1047 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1048 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1052 push_obstacks (&permanent_obstack
, &permanent_obstack
);
1054 (NULL_TREE
, ptr_type_node
, tree_cons
1055 (NULL_TREE
, const_string_type_node
, tree_cons
1056 (NULL_TREE
, integer_type_node
, tree_cons
1057 (NULL_TREE
, build_pointer_type (type_info_type_node
),
1059 tmp
= build_function_type (void_type_node
, tmp
);
1061 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1062 DECL_EXTERNAL (fn
) = 1;
1063 TREE_PUBLIC (fn
) = 1;
1064 DECL_ARTIFICIAL (fn
) = 1;
1065 pushdecl_top_level (fn
);
1066 make_function_rtl (fn
);
1071 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1072 finish_expr_stmt (fn
);
1075 /* Build an initializer for a type_info node that just has a name. */
1078 expand_generic_desc (tdecl
, type
, fnname
)
1083 const char *name
= build_overload_name (type
, 1, 1);
1084 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
1085 tree elems
= tree_cons
1086 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1087 (NULL_TREE
, decay_conversion (name_string
), NULL_TREE
));
1089 tree fn
= get_identifier (fnname
);
1090 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1091 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1095 push_obstacks (&permanent_obstack
, &permanent_obstack
);
1097 (NULL_TREE
, ptr_type_node
, tree_cons
1098 (NULL_TREE
, const_string_type_node
, void_list_node
));
1099 tmp
= build_function_type (void_type_node
, tmp
);
1101 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1102 DECL_EXTERNAL (fn
) = 1;
1103 TREE_PUBLIC (fn
) = 1;
1104 DECL_ARTIFICIAL (fn
) = 1;
1105 pushdecl_top_level (fn
);
1106 make_function_rtl (fn
);
1111 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1112 finish_expr_stmt (fn
);
1115 /* Generate the code for a type_info initialization function.
1116 Note that we take advantage of the passage
1118 5.2.7 Type identification [expr.typeid]
1120 Whether or not the destructor is called for the type_info object at the
1121 end of the program is unspecified.
1123 and don't bother to arrange for these objects to be destroyed. It
1124 doesn't matter, anyway, since the destructors don't do anything.
1126 This must only be called from toplevel (i.e. from finish_file)! */
1129 synthesize_tinfo_fn (fndecl
)
1132 tree type
= TREE_TYPE (DECL_NAME (fndecl
));
1133 tree tmp
, addr
, tdecl
;
1140 import_export_decl (fndecl
);
1141 if (DECL_REALLY_EXTERN (fndecl
))
1145 /* Declare the static typeinfo variable. */
1146 tdecl
= get_tinfo_var (type
);
1147 DECL_EXTERNAL (tdecl
) = 0;
1148 TREE_STATIC (tdecl
) = 1;
1149 DECL_COMMON (tdecl
) = 1;
1150 TREE_USED (tdecl
) = 1;
1151 DECL_ALIGN (tdecl
) = TYPE_ALIGN (ptr_type_node
);
1152 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
1154 /* Begin processing the function. */
1155 start_function (NULL_TREE
, fndecl
, NULL_TREE
,
1156 SF_DEFAULT
| SF_PRE_PARSED
);
1157 DECL_DEFER_OUTPUT (fndecl
) = 1;
1158 store_parm_decls ();
1161 /* Begin the body of the function. */
1162 compound_stmt
= begin_compound_stmt (/*has_no_scope=*/0);
1164 /* For convenience, we save away the address of the static
1166 addr
= decay_conversion (tdecl
);
1168 /* If the first word of the array (the vtable) is non-zero, we've already
1169 initialized the object, so don't do it again. */
1170 if_stmt
= begin_if_stmt ();
1171 tmp
= cp_convert (build_pointer_type (ptr_type_node
), addr
);
1172 tmp
= build_indirect_ref (tmp
, 0);
1173 tmp
= build_binary_op (EQ_EXPR
, tmp
, integer_zero_node
);
1174 finish_if_stmt_cond (tmp
, if_stmt
);
1175 then_clause
= begin_compound_stmt (/*has_no_scope=*/0);
1177 if (TREE_CODE (type
) == FUNCTION_TYPE
)
1178 expand_generic_desc (tdecl
, type
, "__rtti_func");
1179 else if (TREE_CODE (type
) == ARRAY_TYPE
)
1180 expand_generic_desc (tdecl
, type
, "__rtti_array");
1181 else if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
1182 expand_attr_desc (tdecl
, type
);
1183 else if (TREE_CODE (type
) == POINTER_TYPE
)
1185 if (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
)
1186 expand_generic_desc (tdecl
, type
, "__rtti_ptmd");
1187 else if (TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
)
1188 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1190 expand_ptr_desc (tdecl
, type
);
1192 else if (TYPE_PTRMEMFUNC_P (type
))
1193 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1194 else if (IS_AGGR_TYPE (type
))
1196 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
1197 expand_generic_desc (tdecl
, type
, "__rtti_user");
1198 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
1200 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
1201 expand_si_desc (tdecl
, type
);
1203 expand_class_desc (tdecl
, type
);
1205 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
1206 expand_generic_desc (tdecl
, type
, "__rtti_user");
1208 my_friendly_abort (252);
1210 finish_compound_stmt (/*has_no_scope=*/0, then_clause
);
1211 finish_then_clause (if_stmt
);
1214 /* OK, now return the type_info object. */
1215 tmp
= cp_convert (build_pointer_type (type_info_type_node
), addr
);
1216 tmp
= build_indirect_ref (tmp
, 0);
1217 finish_return_stmt (tmp
);
1218 /* Finish the function body. */
1219 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt
);
1220 expand_body (finish_function (lineno
, 0));