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 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_VIRTUAL_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_VIRTUAL_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_expr_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_USES_COMPLEX_INHERITANCE (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 tdecl
= build_decl (VAR_DECL
, tname
, arrtype
);
346 TREE_PUBLIC (tdecl
) = 1;
347 DECL_EXTERNAL (tdecl
) = 1;
348 DECL_ARTIFICIAL (tdecl
) = 1;
349 push_to_top_level ();
351 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0);
352 pop_from_top_level ();
357 /* Returns the decl for a function which will return a type_info node for
358 TYPE. This version does not mark the function used, for use in
359 set_rtti_entry; for the vtable case, we'll get marked in
360 finish_vtable_vardecl, when we know that we want to be emitted.
362 We do this to avoid emitting the tinfo node itself, since we don't
363 currently support DECL_DEFER_OUTPUT for variables. Also, we don't
364 associate constant pools with their functions properly, so we would
365 emit string constants and such even though we don't emit the actual
366 function. When those bugs are fixed, this function should go away. */
369 get_tinfo_fn_unused (type
)
375 if (TREE_CODE (type
) == OFFSET_TYPE
)
376 type
= TREE_TYPE (type
);
377 if (TREE_CODE (type
) == METHOD_TYPE
)
378 type
= build_function_type (TREE_TYPE (type
),
379 TREE_CHAIN (TYPE_ARG_TYPES (type
)));
381 name
= build_overload_with_type (tinfo_fn_id
, type
);
383 if (IDENTIFIER_GLOBAL_VALUE (name
))
384 return IDENTIFIER_GLOBAL_VALUE (name
);
386 d
= build_lang_decl (FUNCTION_DECL
, name
, tinfo_fn_type
);
387 DECL_EXTERNAL (d
) = 1;
389 DECL_ARTIFICIAL (d
) = 1;
390 DECL_NOT_REALLY_EXTERN (d
) = 1;
391 SET_DECL_TINFO_FN_P (d
);
392 TREE_TYPE (name
) = type
;
394 pushdecl_top_level (d
);
395 make_function_rtl (d
);
396 mark_inline_for_output (d
);
401 /* Likewise, but also mark it used. Called by various EH and RTTI code. */
407 tree d
= get_tinfo_fn_unused (type
);
419 (get_tinfo_fn (type
), TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
420 return convert_from_reference (t
);
423 /* Return the type_info object for TYPE, creating it if necessary. */
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_SIZE (complete_type (type
)) == NULL_TREE
)
453 cp_error ("taking typeid of incomplete type `%T'", type
);
454 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 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
477 build_dynamic_cast_1 (type
, expr
)
480 enum tree_code tc
= TREE_CODE (type
);
484 tree old_expr
= expr
;
486 if (TREE_CODE (expr
) == OFFSET_REF
)
487 expr
= resolve_offset_ref (expr
);
489 exprtype
= TREE_TYPE (expr
);
490 assert (exprtype
!= NULL_TREE
);
491 ec
= TREE_CODE (exprtype
);
496 if (ec
== REFERENCE_TYPE
)
498 expr
= convert_from_reference (expr
);
499 exprtype
= TREE_TYPE (expr
);
500 ec
= TREE_CODE (exprtype
);
502 if (ec
!= POINTER_TYPE
)
504 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
506 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
508 if (!at_least_as_qualified_p (TREE_TYPE (type
),
509 TREE_TYPE (exprtype
)))
511 if (TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
513 /* else fall through */
515 if (TREE_CODE (TREE_TYPE (type
)) != RECORD_TYPE
)
517 if (TYPE_SIZE (complete_type (TREE_TYPE (type
))) == NULL_TREE
)
520 /* else fall through */
525 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
526 if (ec
== RECORD_TYPE
)
528 exprtype
= build_reference_type (exprtype
);
529 expr
= convert_to_reference (exprtype
, expr
, CONV_IMPLICIT
,
530 LOOKUP_NORMAL
, NULL_TREE
);
534 if (tc
== REFERENCE_TYPE
)
536 if (ec
!= REFERENCE_TYPE
)
538 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
540 if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype
))) == NULL_TREE
)
542 if (!at_least_as_qualified_p (TREE_TYPE (type
),
543 TREE_TYPE (exprtype
)))
547 /* If *type is an unambiguous accessible base class of *exprtype,
548 convert statically. */
553 distance
= get_base_distance (TREE_TYPE (type
), TREE_TYPE (exprtype
), 1,
558 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
559 TREE_TYPE (exprtype
), TREE_TYPE (type
));
560 return error_mark_node
;
564 cp_error ("dynamic_cast from `%T' to private base class `%T'",
565 TREE_TYPE (exprtype
), TREE_TYPE (type
));
566 return error_mark_node
;
570 return build_vbase_path (PLUS_EXPR
, type
, expr
, path
, 0);
573 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
574 if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype
)))
577 /* if TYPE is `void *', return pointer to complete object. */
578 if (tc
== POINTER_TYPE
579 && TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
581 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
582 if (TREE_CODE (expr
) == ADDR_EXPR
583 && TREE_CODE (TREE_OPERAND (expr
, 0)) == VAR_DECL
584 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == RECORD_TYPE
)
585 return build1 (NOP_EXPR
, type
, expr
);
587 /* Since expr is used twice below, save it. */
588 expr
= save_expr (expr
);
590 expr1
= build_headof (expr
);
591 if (TREE_TYPE (expr1
) != type
)
592 expr1
= build1 (NOP_EXPR
, type
, expr1
);
593 return ifnonnull (expr
, expr1
);
598 tree result
, td1
, td2
, td3
, elems
, expr2
;
599 tree static_type
, target_type
, boff
;
601 /* If we got here, we can't convert statically. Therefore,
602 dynamic_cast<D&>(b) (b an object) cannot succeed. */
603 if (ec
== REFERENCE_TYPE
)
605 if (TREE_CODE (old_expr
) == VAR_DECL
606 && TREE_CODE (TREE_TYPE (old_expr
)) == RECORD_TYPE
)
608 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
610 return throw_bad_cast ();
613 /* Ditto for dynamic_cast<D*>(&b). */
614 else if (TREE_CODE (expr
) == ADDR_EXPR
)
616 tree op
= TREE_OPERAND (expr
, 0);
617 if (TREE_CODE (op
) == VAR_DECL
618 && TREE_CODE (TREE_TYPE (op
)) == RECORD_TYPE
)
620 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
622 retval
= build_int_2 (0, 0);
623 TREE_TYPE (retval
) = type
;
628 /* Since expr is used twice below, save it. */
629 expr
= save_expr (expr
);
632 if (tc
== REFERENCE_TYPE
)
633 expr1
= build_unary_op (ADDR_EXPR
, expr1
, 0);
635 /* Build run-time conversion. */
636 expr2
= build_headof (expr1
);
638 if (ec
== POINTER_TYPE
)
639 td1
= get_tinfo_fn_dynamic (build_indirect_ref (expr
, NULL_PTR
));
641 td1
= get_tinfo_fn_dynamic (expr
);
642 td1
= decay_conversion (td1
);
644 target_type
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
645 static_type
= TYPE_MAIN_VARIANT (TREE_TYPE (exprtype
));
646 td2
= decay_conversion (get_tinfo_fn (target_type
));
647 td3
= decay_conversion (get_tinfo_fn (static_type
));
649 /* Determine how T and V are related. */
650 boff
= get_dynamic_cast_base_type (static_type
, target_type
);
653 (NULL_TREE
, td1
, tree_cons
654 (NULL_TREE
, td2
, tree_cons
655 (NULL_TREE
, boff
, tree_cons
656 (NULL_TREE
, expr2
, tree_cons
657 (NULL_TREE
, td3
, tree_cons
658 (NULL_TREE
, expr1
, NULL_TREE
))))));
660 dcast_fn
= get_identifier ("__dynamic_cast_2");
661 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn
))
662 dcast_fn
= IDENTIFIER_GLOBAL_VALUE (dcast_fn
);
668 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
669 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
670 (NULL_TREE
, integer_type_node
, tree_cons
671 (NULL_TREE
, ptr_type_node
, tree_cons
672 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
673 (NULL_TREE
, ptr_type_node
, void_list_node
))))));
674 tmp
= build_function_type (ptr_type_node
, tmp
);
675 dcast_fn
= build_lang_decl (FUNCTION_DECL
, dcast_fn
, tmp
);
676 DECL_EXTERNAL (dcast_fn
) = 1;
677 TREE_PUBLIC (dcast_fn
) = 1;
678 DECL_ARTIFICIAL (dcast_fn
) = 1;
679 pushdecl_top_level (dcast_fn
);
680 make_function_rtl (dcast_fn
);
683 mark_used (dcast_fn
);
685 (dcast_fn
, TREE_TYPE (TREE_TYPE (dcast_fn
)), elems
);
687 if (tc
== REFERENCE_TYPE
)
689 expr1
= throw_bad_cast ();
690 expr1
= build_compound_expr
691 (tree_cons (NULL_TREE
, expr1
,
692 build_expr_list (NULL_TREE
, cp_convert (type
, integer_zero_node
))));
693 TREE_TYPE (expr1
) = type
;
694 result
= save_expr (result
);
695 return build (COND_EXPR
, type
, result
, result
, expr1
);
698 /* Now back to the type we want from a void*. */
699 result
= cp_convert (type
, result
);
700 return ifnonnull (expr
, result
);
704 cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype
);
705 return error_mark_node
;
708 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
709 expr
, exprtype
, type
);
710 return error_mark_node
;
714 build_dynamic_cast (type
, expr
)
717 if (type
== error_mark_node
|| expr
== error_mark_node
)
718 return error_mark_node
;
720 if (processing_template_decl
)
721 return build_min (DYNAMIC_CAST_EXPR
, type
, expr
);
723 return convert_from_reference (build_dynamic_cast_1 (type
, expr
));
726 /* Build and initialize various sorts of descriptors. Every descriptor
727 node has a name associated with it (the name created by mangling).
728 For this reason, we use the identifier as our access to the __*_desc
729 nodes, instead of sticking them directly in the types. Otherwise we
730 would burden all built-in types (and pointer types) with slots that
731 we don't necessarily want to use.
733 For each descriptor we build, we build a variable that contains
734 the descriptor's information. When we need this info at runtime,
735 all we need is access to these variables.
737 Note: these constructors always return the address of the descriptor
738 info, since that is simplest for their mutual interaction. */
740 /* Build an initializer for a __si_type_info node. */
743 expand_si_desc (tdecl
, type
)
748 const char *name
= build_overload_name (type
, 1, 1);
749 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
751 type
= BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0));
752 finish_expr_stmt (get_typeid_1 (type
));
753 t
= decay_conversion (get_tinfo_var (type
));
755 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
756 (NULL_TREE
, decay_conversion (name_string
), tree_cons
757 (NULL_TREE
, t
, NULL_TREE
)));
759 fn
= get_identifier ("__rtti_si");
760 if (IDENTIFIER_GLOBAL_VALUE (fn
))
761 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
766 (NULL_TREE
, ptr_type_node
, tree_cons
767 (NULL_TREE
, const_string_type_node
, tree_cons
768 (NULL_TREE
, build_pointer_type (type_info_type_node
),
770 tmp
= build_function_type (void_type_node
, tmp
);
772 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
773 DECL_EXTERNAL (fn
) = 1;
774 TREE_PUBLIC (fn
) = 1;
775 DECL_ARTIFICIAL (fn
) = 1;
776 pushdecl_top_level (fn
);
777 make_function_rtl (fn
);
781 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
782 finish_expr_stmt (fn
);
785 /* Build an initializer for a __class_type_info node. */
788 expand_class_desc (tdecl
, type
)
796 int i
= CLASSTYPE_N_BASECLASSES (type
);
798 tree binfos
= TYPE_BINFO_BASETYPES (type
);
800 /* See code below that used these. */
801 tree vb
= CLASSTYPE_VBASECLASSES (type
);
804 tree base
, elems
, access
, offset
, isvir
;
805 tree elt
, elts
= NULL_TREE
;
806 static tree base_info_type_node
;
808 if (base_info_type_node
== NULL_TREE
)
812 /* A reasonably close approximation of __class_type_info::base_info */
814 base_info_type_node
= make_lang_type (RECORD_TYPE
);
816 /* Actually const __user_type_info * */
817 fields
[0] = build_lang_decl
818 (FIELD_DECL
, NULL_TREE
,
819 build_pointer_type (build_qualified_type
820 (type_info_type_node
,
822 fields
[1] = build_lang_decl
823 (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
824 DECL_BIT_FIELD (fields
[1]) = 1;
825 DECL_FIELD_SIZE (fields
[1]) = 29;
827 fields
[2] = build_lang_decl
828 (FIELD_DECL
, NULL_TREE
, boolean_type_node
);
829 DECL_BIT_FIELD (fields
[2]) = 1;
830 DECL_FIELD_SIZE (fields
[2]) = 1;
832 /* Actually enum access */
833 fields
[3] = build_lang_decl
834 (FIELD_DECL
, NULL_TREE
, integer_type_node
);
835 DECL_BIT_FIELD (fields
[3]) = 1;
836 DECL_FIELD_SIZE (fields
[3]) = 2;
838 finish_builtin_type (base_info_type_node
, "__base_info", fields
,
844 tree binfo
= TREE_VEC_ELT (binfos
, i
);
846 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo
)));
847 base
= decay_conversion (get_tinfo_var (BINFO_TYPE (binfo
)));
849 if (TREE_VIA_VIRTUAL (binfo
))
851 tree t
= BINFO_TYPE (binfo
);
855 FORMAT_VBASE_NAME (name
, t
);
856 field
= lookup_field (type
, get_identifier (name
), 0, 0);
857 offset
= size_binop (FLOOR_DIV_EXPR
,
858 DECL_FIELD_BITPOS (field
), size_int (BITS_PER_UNIT
));
859 offset
= convert (sizetype
, offset
);
862 offset
= BINFO_OFFSET (binfo
);
864 if (TREE_VIA_PUBLIC (binfo
))
865 access
= access_public_node
;
866 else if (TREE_VIA_PROTECTED (binfo
))
867 access
= access_protected_node
;
869 access
= access_private_node
;
870 if (TREE_VIA_VIRTUAL (binfo
))
871 isvir
= boolean_true_node
;
873 isvir
= boolean_false_node
;
876 (CONSTRUCTOR
, base_info_type_node
, NULL_TREE
, tree_cons
877 (NULL_TREE
, base
, tree_cons
878 (NULL_TREE
, offset
, tree_cons
879 (NULL_TREE
, isvir
, tree_cons
880 (NULL_TREE
, access
, NULL_TREE
)))));
881 TREE_HAS_CONSTRUCTOR (elt
) = TREE_CONSTANT (elt
) = TREE_STATIC (elt
) = 1;
882 elts
= tree_cons (NULL_TREE
, elt
, elts
);
890 access
= access_public_node
;
893 b
= TREE_VEC_ELT (binfos
, i
);
894 if (BINFO_TYPE (vb
) == BINFO_TYPE (b
) && TREE_VIA_VIRTUAL (b
))
896 if (TREE_VIA_PUBLIC (b
))
897 access
= access_public_node
;
898 else if (TREE_VIA_PROTECTED (b
))
899 access
= access_protected_node
;
901 access
= access_private_node
;
905 base
= build_t_desc (BINFO_TYPE (vb
), 1);
906 offset
= BINFO_OFFSET (vb
);
907 isvir
= build_int_2 (1, 0);
909 base_list
= tree_cons (NULL_TREE
, base
, base_list
);
910 isvir_list
= tree_cons (NULL_TREE
, isvir
, isvir_list
);
911 acc_list
= tree_cons (NULL_TREE
, access
, acc_list
);
912 off_list
= tree_cons (NULL_TREE
, offset
, off_list
);
915 vb
= TREE_CHAIN (vb
);
919 name
= build_overload_name (type
, 1, 1);
920 name_string
= combine_strings (build_string (strlen (name
)+1, name
));
923 tree arrtype
= build_array_type (base_info_type_node
, NULL_TREE
);
924 elts
= build (CONSTRUCTOR
, arrtype
, NULL_TREE
, elts
);
925 TREE_HAS_CONSTRUCTOR (elts
) = TREE_CONSTANT (elts
)
926 = TREE_STATIC (elts
) = 1;
927 complete_array_type (arrtype
, elts
, 1);
931 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
932 (NULL_TREE
, decay_conversion (name_string
), tree_cons
933 (NULL_TREE
, decay_conversion (elts
), tree_cons
934 (NULL_TREE
, cp_convert (sizetype
, build_int_2 (base_cnt
, 0)),
937 fn
= get_identifier ("__rtti_class");
938 if (IDENTIFIER_GLOBAL_VALUE (fn
))
939 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
943 (NULL_TREE
, ptr_type_node
, tree_cons
944 (NULL_TREE
, const_string_type_node
, tree_cons
945 (NULL_TREE
, build_pointer_type (base_info_type_node
), tree_cons
946 (NULL_TREE
, sizetype
, void_list_node
))));
947 tmp
= build_function_type (void_type_node
, tmp
);
949 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
950 DECL_EXTERNAL (fn
) = 1;
951 TREE_PUBLIC (fn
) = 1;
952 DECL_ARTIFICIAL (fn
) = 1;
953 pushdecl_top_level (fn
);
954 make_function_rtl (fn
);
958 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
959 finish_expr_stmt (fn
);
962 /* Build an initializer for a __pointer_type_info node. */
965 expand_ptr_desc (tdecl
, type
)
970 const char *name
= build_overload_name (type
, 1, 1);
971 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
973 type
= TREE_TYPE (type
);
974 finish_expr_stmt (get_typeid_1 (type
));
975 t
= decay_conversion (get_tinfo_var (type
));
977 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
978 (NULL_TREE
, decay_conversion (name_string
), tree_cons
979 (NULL_TREE
, t
, NULL_TREE
)));
981 fn
= get_identifier ("__rtti_ptr");
982 if (IDENTIFIER_GLOBAL_VALUE (fn
))
983 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
988 (NULL_TREE
, ptr_type_node
, tree_cons
989 (NULL_TREE
, const_string_type_node
, tree_cons
990 (NULL_TREE
, build_pointer_type (type_info_type_node
),
992 tmp
= build_function_type (void_type_node
, tmp
);
994 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
995 DECL_EXTERNAL (fn
) = 1;
996 TREE_PUBLIC (fn
) = 1;
997 DECL_ARTIFICIAL (fn
) = 1;
998 pushdecl_top_level (fn
);
999 make_function_rtl (fn
);
1003 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1004 finish_expr_stmt (fn
);
1007 /* Build an initializer for a __attr_type_info node. */
1010 expand_attr_desc (tdecl
, type
)
1015 const char *name
= build_overload_name (type
, 1, 1);
1016 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
1017 tree attrval
= build_int_2 (TYPE_QUALS (type
), 0);
1019 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type
)));
1020 t
= decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type
)));
1022 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1023 (NULL_TREE
, decay_conversion (name_string
), tree_cons
1024 (NULL_TREE
, attrval
, tree_cons (NULL_TREE
, t
, NULL_TREE
))));
1026 fn
= get_identifier ("__rtti_attr");
1027 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1028 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1033 (NULL_TREE
, ptr_type_node
, tree_cons
1034 (NULL_TREE
, const_string_type_node
, tree_cons
1035 (NULL_TREE
, integer_type_node
, tree_cons
1036 (NULL_TREE
, build_pointer_type (type_info_type_node
),
1038 tmp
= build_function_type (void_type_node
, tmp
);
1040 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1041 DECL_EXTERNAL (fn
) = 1;
1042 TREE_PUBLIC (fn
) = 1;
1043 DECL_ARTIFICIAL (fn
) = 1;
1044 pushdecl_top_level (fn
);
1045 make_function_rtl (fn
);
1049 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1050 finish_expr_stmt (fn
);
1053 /* Build an initializer for a type_info node that just has a name. */
1056 expand_generic_desc (tdecl
, type
, fnname
)
1061 const char *name
= build_overload_name (type
, 1, 1);
1062 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
1063 tree elems
= tree_cons
1064 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1065 (NULL_TREE
, decay_conversion (name_string
), NULL_TREE
));
1067 tree fn
= get_identifier (fnname
);
1068 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1069 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1074 (NULL_TREE
, ptr_type_node
, tree_cons
1075 (NULL_TREE
, const_string_type_node
, void_list_node
));
1076 tmp
= build_function_type (void_type_node
, tmp
);
1078 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1079 DECL_EXTERNAL (fn
) = 1;
1080 TREE_PUBLIC (fn
) = 1;
1081 DECL_ARTIFICIAL (fn
) = 1;
1082 pushdecl_top_level (fn
);
1083 make_function_rtl (fn
);
1087 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1088 finish_expr_stmt (fn
);
1091 /* Generate the code for a type_info initialization function.
1092 Note that we take advantage of the passage
1094 5.2.7 Type identification [expr.typeid]
1096 Whether or not the destructor is called for the type_info object at the
1097 end of the program is unspecified.
1099 and don't bother to arrange for these objects to be destroyed. It
1100 doesn't matter, anyway, since the destructors don't do anything.
1102 This must only be called from toplevel (i.e. from finish_file)! */
1105 synthesize_tinfo_fn (fndecl
)
1108 tree type
= TREE_TYPE (DECL_NAME (fndecl
));
1109 tree tmp
, addr
, tdecl
;
1116 import_export_decl (fndecl
);
1117 if (DECL_REALLY_EXTERN (fndecl
))
1121 /* Declare the static typeinfo variable. */
1122 tdecl
= get_tinfo_var (type
);
1123 DECL_EXTERNAL (tdecl
) = 0;
1124 TREE_STATIC (tdecl
) = 1;
1125 DECL_COMMON (tdecl
) = 1;
1126 TREE_USED (tdecl
) = 1;
1127 DECL_ALIGN (tdecl
) = TYPE_ALIGN (ptr_type_node
);
1128 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0);
1130 /* Begin processing the function. */
1131 start_function (NULL_TREE
, fndecl
, NULL_TREE
,
1132 SF_DEFAULT
| SF_PRE_PARSED
);
1133 DECL_DEFER_OUTPUT (fndecl
) = 1;
1134 store_parm_decls ();
1137 /* Begin the body of the function. */
1138 compound_stmt
= begin_compound_stmt (/*has_no_scope=*/0);
1140 /* For convenience, we save away the address of the static
1142 addr
= decay_conversion (tdecl
);
1144 /* If the first word of the array (the vtable) is non-zero, we've already
1145 initialized the object, so don't do it again. */
1146 if_stmt
= begin_if_stmt ();
1147 tmp
= cp_convert (build_pointer_type (ptr_type_node
), addr
);
1148 tmp
= build_indirect_ref (tmp
, 0);
1149 tmp
= build_binary_op (EQ_EXPR
, tmp
, integer_zero_node
);
1150 finish_if_stmt_cond (tmp
, if_stmt
);
1151 then_clause
= begin_compound_stmt (/*has_no_scope=*/0);
1153 if (TREE_CODE (type
) == FUNCTION_TYPE
)
1154 expand_generic_desc (tdecl
, type
, "__rtti_func");
1155 else if (TREE_CODE (type
) == ARRAY_TYPE
)
1156 expand_generic_desc (tdecl
, type
, "__rtti_array");
1157 else if (TYPE_QUALS (type
) != TYPE_UNQUALIFIED
)
1158 expand_attr_desc (tdecl
, type
);
1159 else if (TREE_CODE (type
) == POINTER_TYPE
)
1161 if (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
)
1162 expand_generic_desc (tdecl
, type
, "__rtti_ptmd");
1163 else if (TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
)
1164 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1166 expand_ptr_desc (tdecl
, type
);
1168 else if (TYPE_PTRMEMFUNC_P (type
))
1169 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1170 else if (IS_AGGR_TYPE (type
))
1172 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
1173 expand_generic_desc (tdecl
, type
, "__rtti_user");
1174 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
1176 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
1177 expand_si_desc (tdecl
, type
);
1179 expand_class_desc (tdecl
, type
);
1181 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
1182 expand_generic_desc (tdecl
, type
, "__rtti_user");
1184 my_friendly_abort (252);
1186 finish_compound_stmt (/*has_no_scope=*/0, then_clause
);
1187 finish_then_clause (if_stmt
);
1190 /* OK, now return the type_info object. */
1191 tmp
= cp_convert (build_pointer_type (type_info_type_node
), addr
);
1192 tmp
= build_indirect_ref (tmp
, 0);
1193 finish_return_stmt (tmp
);
1194 /* Finish the function body. */
1195 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt
);
1196 expand_body (finish_function (lineno
, 0));