1 /* RunTime Type Identification
2 Copyright (C) 1995, 1996 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. */
34 #define INT_TYPE_SIZE BITS_PER_WORD
37 extern tree define_function ();
38 extern tree build_t_desc_overload ();
39 extern struct obstack *permanent_obstack;
41 tree type_info_type_node;
46 extern tree combine_strings PROTO((tree));
49 init_rtti_processing ()
51 type_info_type_node = xref_tag
52 (class_type_node, get_identifier ("type_info"), NULL_TREE, 1);
53 tinfo_fn_id = get_identifier ("__tf");
54 tinfo_fn_type = build_function_type
55 (build_reference_type (build_type_variant (type_info_type_node, 1, 0)),
59 /* Given a pointer to an object with at least one virtual table
60 pointer somewhere, return a pointer to a possible sub-object that
61 has a virtual table pointer in it that is the vtable parent for
65 build_headof_sub (exp)
68 tree type = TREE_TYPE (TREE_TYPE (exp));
69 tree basetype = CLASSTYPE_RTTI (type);
70 tree binfo = get_binfo (basetype, type, 0);
72 exp = convert_pointer_to_real (binfo, exp);
76 /* Given the expression EXP of type `class *', return the head of the
77 object pointed to by EXP with type cv void*, if the class has any
78 virtual functions (TYPE_VIRTUAL_P), else just return the
85 tree type = TREE_TYPE (exp);
89 if (TREE_CODE (type) != POINTER_TYPE)
91 error ("`headof' applied to non-pointer type");
92 return error_mark_node;
94 type = TREE_TYPE (type);
96 if (!TYPE_VIRTUAL_P (type))
99 /* If we don't have rtti stuff, get to a sub-object that does. */
100 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
101 exp = build_headof_sub (exp);
103 /* We use this a couple of times below, protect it. */
104 exp = save_expr (exp);
106 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
108 if (flag_vtable_thunks)
111 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
113 type = build_type_variant (ptr_type_node, TREE_READONLY (exp),
114 TREE_THIS_VOLATILE (exp));
115 return build (PLUS_EXPR, type, exp,
116 convert (ptrdiff_type_node, offset));
119 /* Build a call to a generic entry point taking and returning void. */
125 tree d = get_identifier (name);
128 if (IDENTIFIER_GLOBAL_VALUE (d))
129 d = IDENTIFIER_GLOBAL_VALUE (d);
132 push_obstacks (&permanent_obstack, &permanent_obstack);
134 type = build_function_type (void_type_node, void_list_node);
135 d = build_lang_decl (FUNCTION_DECL, d, type);
136 DECL_EXTERNAL (d) = 1;
138 DECL_ARTIFICIAL (d) = 1;
139 pushdecl_top_level (d);
140 make_function_rtl (d);
141 assemble_external (d);
146 return build_call (d, void_type_node, NULL_TREE);
149 /* Get a bad_cast node for the program to throw...
151 See libstdc++/exception.cc for __throw_bad_cast */
156 return call_void_fn ("__throw_bad_cast");
162 return call_void_fn ("__throw_bad_typeid");
165 /* Return the type_info function associated with the expression EXP. If
166 EXP is a reference to a polymorphic class, return the dynamic type;
167 otherwise return the static type of the expression. */
170 get_tinfo_fn_dynamic (exp)
175 if (exp == error_mark_node)
176 return error_mark_node;
178 if (type_unknown_p (exp))
180 error ("typeid of overloaded function");
181 return error_mark_node;
184 type = TREE_TYPE (exp);
186 /* peel back references, so they match. */
187 if (TREE_CODE (type) == REFERENCE_TYPE)
188 type = TREE_TYPE (type);
190 /* Peel off cv qualifiers. */
191 type = TYPE_MAIN_VARIANT (type);
193 /* If exp is a reference to polymorphic type, get the real type_info. */
194 if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
196 /* build reference to type_info from vtable. */
200 warning ("taking dynamic typeid of object without -frtti");
202 /* If we don't have rtti stuff, get to a sub-object that does. */
203 if (! CLASSTYPE_VFIELDS (type))
205 exp = build_unary_op (ADDR_EXPR, exp, 0);
206 exp = build_headof_sub (exp);
207 exp = build_indirect_ref (exp, NULL_PTR);
210 if (flag_vtable_thunks)
211 t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
213 t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
214 TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
218 /* otherwise return the type_info for the static type of the expr. */
219 return get_tinfo_fn (TYPE_MAIN_VARIANT (type));
226 exp = get_tinfo_fn_dynamic (exp);
227 exp = build_call (exp, TREE_TYPE (tinfo_fn_type), NULL_TREE);
228 return convert_from_reference (exp);
235 tree cond = NULL_TREE;
236 tree type = TREE_TYPE (tinfo_fn_type);
239 if (processing_template_decl)
240 return build_min_nt (TYPEID_EXPR, exp);
242 if (TREE_CODE (exp) == INDIRECT_REF
243 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
244 && TYPE_VIRTUAL_P (TREE_TYPE (exp))
245 && ! resolves_to_fixed_type_p (exp, &nonnull)
248 exp = stabilize_reference (exp);
249 cond = convert (boolean_type_node, TREE_OPERAND (exp, 0));
252 exp = get_tinfo_fn_dynamic (exp);
254 if (exp == error_mark_node)
255 return error_mark_node;
257 exp = build_call (exp, type, NULL_TREE);
261 tree bad = throw_bad_typeid ();
263 bad = build_compound_expr
264 (tree_cons (NULL_TREE, bad, build_tree_list
265 (NULL_TREE, convert (type, integer_zero_node))));
266 exp = build (COND_EXPR, type, cond, exp, bad);
269 return convert_from_reference (exp);
276 tree tname = build_overload_with_type (get_identifier ("__ti"), type);
280 if (IDENTIFIER_GLOBAL_VALUE (tname))
281 return IDENTIFIER_GLOBAL_VALUE (tname);
283 /* Figure out how much space we need to allocate for the type_info object.
284 If our struct layout or the type_info classes are changed, this will
285 need to be modified. */
286 if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
287 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
288 else if (TREE_CODE (type) == POINTER_TYPE
289 && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
290 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
291 size = 3 * POINTER_SIZE;
292 else if (IS_AGGR_TYPE (type))
294 if (CLASSTYPE_N_BASECLASSES (type) == 0)
295 size = 2 * POINTER_SIZE;
296 else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
298 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
299 size = 3 * POINTER_SIZE;
301 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
304 size = 2 * POINTER_SIZE;
306 push_obstacks (&permanent_obstack, &permanent_obstack);
308 /* The type for a character array of the appropriate size. */
309 arrtype = build_cplus_array_type
310 (unsigned_char_type_node,
311 build_index_type (size_int (size / BITS_PER_UNIT - 1)));
313 tdecl = build_decl (VAR_DECL, tname, arrtype);
314 TREE_PUBLIC (tdecl) = 1;
315 DECL_EXTERNAL (tdecl) = 1;
316 DECL_ARTIFICIAL (tdecl) = 1;
317 pushdecl_top_level (tdecl);
318 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
332 if (TREE_CODE (type) == OFFSET_TYPE)
333 type = TREE_TYPE (type);
334 if (TREE_CODE (type) == METHOD_TYPE)
335 type = build_function_type (TREE_TYPE (type),
336 TREE_CHAIN (TYPE_ARG_TYPES (type)));
338 name = build_overload_with_type (tinfo_fn_id, type);
340 if (IDENTIFIER_GLOBAL_VALUE (name))
341 return IDENTIFIER_GLOBAL_VALUE (name);
343 push_obstacks (&permanent_obstack, &permanent_obstack);
345 d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type);
346 DECL_EXTERNAL (d) = 1;
348 DECL_ARTIFICIAL (d) = 1;
349 DECL_NOT_REALLY_EXTERN (d) = 1;
350 DECL_MUTABLE_P (d) = 1;
351 TREE_TYPE (name) = copy_to_permanent (type);
352 pushdecl_top_level (d);
353 make_function_rtl (d);
354 assemble_external (d);
355 mark_inline_for_output (d);
357 import_export_decl (d);
369 (get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
370 return convert_from_reference (t);
373 /* Return the type_info object for TYPE, creating it if necessary. */
381 if (type == error_mark_node)
382 return error_mark_node;
384 /* If the type of the type-id is a reference type, the result of the
385 typeid expression refers to a type_info object representing the
387 if (TREE_CODE (type) == REFERENCE_TYPE)
388 type = TREE_TYPE (type);
390 /* The top-level cv-qualifiers of the lvalue expression or the type-id
391 that is the operand of typeid are always ignored. */
392 type = TYPE_MAIN_VARIANT (type);
394 return get_typeid_1 (type);
397 /* Check whether TEST is null before returning RESULT. If TEST is used in
398 RESULT, it must have previously had a save_expr applied to it. */
401 ifnonnull (test, result)
404 return build (COND_EXPR, TREE_TYPE (result),
405 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
406 convert (TREE_TYPE (result), integer_zero_node),
410 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
414 build_dynamic_cast (type, expr)
417 enum tree_code tc = TREE_CODE (type);
418 tree exprtype = TREE_TYPE (expr);
422 if (type == error_mark_node || expr == error_mark_node)
423 return error_mark_node;
425 if (processing_template_decl)
427 tree t = build_min (DYNAMIC_CAST_EXPR, type, expr);
431 assert (exprtype != NULL_TREE);
432 ec = TREE_CODE (exprtype);
437 if (ec == REFERENCE_TYPE)
439 expr = convert_from_reference (expr);
440 exprtype = TREE_TYPE (expr);
441 ec = TREE_CODE (exprtype);
443 if (ec != POINTER_TYPE)
445 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
447 if (TYPE_SIZE (TREE_TYPE (exprtype)) == NULL_TREE)
449 if (TREE_READONLY (TREE_TYPE (exprtype)) &&
450 ! TYPE_READONLY (TREE_TYPE (type)))
452 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
454 /* else fall through */
456 if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
458 if (TYPE_SIZE (TREE_TYPE (type)) == NULL_TREE)
461 /* else fall through */
466 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
467 if (ec == RECORD_TYPE)
469 exprtype = build_type_variant (exprtype, TREE_READONLY (expr),
470 TREE_THIS_VOLATILE (expr));
471 exprtype = build_reference_type (exprtype);
472 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
473 LOOKUP_NORMAL, NULL_TREE);
477 if (tc == REFERENCE_TYPE)
479 if (ec != REFERENCE_TYPE)
481 if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
483 if (TYPE_SIZE (TREE_TYPE (exprtype)) == NULL_TREE)
485 if (TREE_READONLY (TREE_TYPE (exprtype)) &&
486 ! TYPE_READONLY (TREE_TYPE (type)))
490 /* If *type is an unambiguous accessible base class of *exprtype,
491 convert statically. */
496 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
499 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
502 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
503 if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype)))
506 /* if TYPE is `void *', return pointer to complete object. */
507 if (tc == POINTER_TYPE
508 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
510 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
511 if (TREE_CODE (expr) == ADDR_EXPR
512 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
513 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
514 return build1 (NOP_EXPR, type, expr);
516 /* Since expr is used twice below, save it. */
517 expr = save_expr (expr);
519 expr1 = build_headof (expr);
520 if (TREE_TYPE (expr1) != type)
521 expr1 = build1 (NOP_EXPR, type, expr1);
522 return ifnonnull (expr, expr1);
527 tree result, td1, td2, td3, elems, expr2;
529 /* If we got here, we can't convert statically. Therefore,
530 dynamic_cast<D&>(b) (b an object) cannot succeed. */
531 if (ec == REFERENCE_TYPE)
533 if (TREE_CODE (expr) == VAR_DECL
534 && TREE_CODE (TREE_TYPE (expr)) == RECORD_TYPE)
536 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
538 return throw_bad_cast ();
541 /* Ditto for dynamic_cast<D*>(&b). */
542 else if (TREE_CODE (expr) == ADDR_EXPR)
544 tree op = TREE_OPERAND (expr, 0);
545 if (TREE_CODE (op) == VAR_DECL
546 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
548 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
550 retval = build_int_2 (0, 0);
551 TREE_TYPE (retval) = type;
556 /* Since expr is used twice below, save it. */
557 expr = save_expr (expr);
560 if (tc == REFERENCE_TYPE)
561 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
563 /* Build run-time conversion. */
564 expr2 = build_headof (expr1);
566 if (ec == POINTER_TYPE)
567 td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR));
569 td1 = get_tinfo_fn_dynamic (expr);
570 td1 = decay_conversion (td1);
572 td2 = decay_conversion
573 (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
574 td3 = decay_conversion
575 (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
578 (NULL_TREE, td1, tree_cons
579 (NULL_TREE, td2, tree_cons
580 (NULL_TREE, build_int_2 (1, 0), tree_cons
581 (NULL_TREE, expr2, tree_cons
582 (NULL_TREE, td3, tree_cons
583 (NULL_TREE, expr1, NULL_TREE))))));
585 dcast_fn = get_identifier ("__dynamic_cast");
586 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
587 dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
592 push_obstacks (&permanent_obstack, &permanent_obstack);
594 (NULL_TREE, TREE_TYPE (td1), tree_cons
595 (NULL_TREE, TREE_TYPE (td1), tree_cons
596 (NULL_TREE, integer_type_node, tree_cons
597 (NULL_TREE, ptr_type_node, tree_cons
598 (NULL_TREE, TREE_TYPE (td1), tree_cons
599 (NULL_TREE, ptr_type_node, void_list_node))))));
600 tmp = build_function_type (ptr_type_node, tmp);
601 dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
602 DECL_EXTERNAL (dcast_fn) = 1;
603 TREE_PUBLIC (dcast_fn) = 1;
604 DECL_ARTIFICIAL (dcast_fn) = 1;
605 pushdecl_top_level (dcast_fn);
606 make_function_rtl (dcast_fn);
607 assemble_external (dcast_fn);
612 (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
614 if (tc == REFERENCE_TYPE)
616 expr1 = throw_bad_cast ();
617 expr1 = build_compound_expr
618 (tree_cons (NULL_TREE, expr1,
619 build_tree_list (NULL_TREE, convert
620 (type, integer_zero_node))));
621 TREE_TYPE (expr1) = type;
622 result = save_expr (result);
623 return build (COND_EXPR, type, result, result, expr1);
626 /* Now back to the type we want from a void*. */
627 result = convert (type, result);
628 return ifnonnull (expr, result);
633 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
634 expr, exprtype, type);
635 return error_mark_node;
638 /* Build and initialize various sorts of descriptors. Every descriptor
639 node has a name associated with it (the name created by mangling).
640 For this reason, we use the identifier as our access to the __*_desc
641 nodes, instead of sticking them directly in the types. Otherwise we
642 would burden all built-in types (and pointer types) with slots that
643 we don't necessarily want to use.
645 For each descriptor we build, we build a variable that contains
646 the descriptor's information. When we need this info at runtime,
647 all we need is access to these variables.
649 Note: these constructors always return the address of the descriptor
650 info, since that is simplest for their mutual interaction. */
652 extern tree const_string_type_node;
654 /* Build an initializer for a __si_type_info node. */
657 expand_si_desc (tdecl, type)
662 char *name = build_overload_name (type, 1, 1);
663 tree name_string = combine_strings (build_string (strlen (name), name));
665 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
666 expand_expr_stmt (get_typeid_1 (type));
667 t = decay_conversion (get_tinfo_var (type));
669 (NULL_TREE, decay_conversion (tdecl), tree_cons
670 (NULL_TREE, decay_conversion (name_string), tree_cons
671 (NULL_TREE, t, NULL_TREE)));
673 fn = get_identifier ("__rtti_si");
674 if (IDENTIFIER_GLOBAL_VALUE (fn))
675 fn = IDENTIFIER_GLOBAL_VALUE (fn);
679 push_obstacks (&permanent_obstack, &permanent_obstack);
681 (NULL_TREE, ptr_type_node, tree_cons
682 (NULL_TREE, const_string_type_node, tree_cons
683 (NULL_TREE, build_pointer_type (type_info_type_node),
685 tmp = build_function_type (void_type_node, tmp);
687 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
688 DECL_EXTERNAL (fn) = 1;
689 TREE_PUBLIC (fn) = 1;
690 DECL_ARTIFICIAL (fn) = 1;
691 pushdecl_top_level (fn);
692 make_function_rtl (fn);
693 assemble_external (fn);
697 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
698 expand_expr_stmt (fn);
701 /* Build an initializer for a __class_type_info node. */
704 expand_class_desc (tdecl, type)
712 int i = CLASSTYPE_N_BASECLASSES (type);
714 tree binfos = TYPE_BINFO_BASETYPES (type);
716 /* See code below that used these. */
717 tree vb = CLASSTYPE_VBASECLASSES (type);
720 tree base, elems, access, offset, isvir;
721 tree elt, elts = NULL_TREE;
722 static tree base_info_type_node;
724 if (base_info_type_node == NULL_TREE)
728 /* A reasonably close approximation of __class_type_info::base_info */
730 push_obstacks (&permanent_obstack, &permanent_obstack);
731 base_info_type_node = make_lang_type (RECORD_TYPE);
733 /* Actually const __user_type_info * */
734 fields [0] = build_lang_field_decl
735 (FIELD_DECL, NULL_TREE,
736 build_pointer_type (build_type_variant (type_info_type_node, 1, 0)));
737 fields [1] = build_lang_field_decl
738 (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
739 DECL_BIT_FIELD (fields[1]) = 1;
740 DECL_FIELD_SIZE (fields[1]) = 29;
742 fields [2] = build_lang_field_decl
743 (FIELD_DECL, NULL_TREE, boolean_type_node);
744 DECL_BIT_FIELD (fields[2]) = 1;
745 DECL_FIELD_SIZE (fields[2]) = 1;
747 /* Actually enum access */
748 fields [3] = build_lang_field_decl
749 (FIELD_DECL, NULL_TREE, integer_type_node);
750 DECL_BIT_FIELD (fields[3]) = 1;
751 DECL_FIELD_SIZE (fields[3]) = 2;
753 finish_builtin_type (base_info_type_node, "__base_info", fields,
760 tree binfo = TREE_VEC_ELT (binfos, i);
762 expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
763 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
765 if (TREE_VIA_VIRTUAL (binfo))
767 tree t = BINFO_TYPE (binfo);
771 name = (char *) alloca (TYPE_NAME_LENGTH (t)+sizeof (VBASE_NAME)+1);
772 sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (t));
773 field = lookup_field (type, get_identifier (name), 0, 0);
774 offset = size_binop (FLOOR_DIV_EXPR,
775 DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT));
778 offset = BINFO_OFFSET (binfo);
780 if (TREE_VIA_PUBLIC (binfo))
781 access = access_public_node;
782 else if (TREE_VIA_PROTECTED (binfo))
783 access = access_protected_node;
785 access = access_private_node;
786 if (TREE_VIA_VIRTUAL (binfo))
787 isvir = boolean_true_node;
789 isvir = boolean_false_node;
792 (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons
793 (NULL_TREE, base, tree_cons
794 (NULL_TREE, offset, tree_cons
795 (NULL_TREE, isvir, tree_cons
796 (NULL_TREE, access, NULL_TREE)))));
797 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
798 elts = tree_cons (NULL_TREE, elt, elts);
806 access = access_public_node;
809 b = TREE_VEC_ELT (binfos, i);
810 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
812 if (TREE_VIA_PUBLIC (b))
813 access = access_public_node;
814 else if (TREE_VIA_PROTECTED (b))
815 access = access_protected_node;
817 access = access_private_node;
821 base = build_t_desc (BINFO_TYPE (vb), 1);
822 offset = BINFO_OFFSET (vb);
823 isvir = build_int_2 (1, 0);
825 base_list = tree_cons (NULL_TREE, base, base_list);
826 isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
827 acc_list = tree_cons (NULL_TREE, access, acc_list);
828 off_list = tree_cons (NULL_TREE, offset, off_list);
831 vb = TREE_CHAIN (vb);
835 name = build_overload_name (type, 1, 1);
836 name_string = combine_strings (build_string (strlen (name), name));
839 tree arrtype = build_array_type (base_info_type_node, NULL_TREE);
840 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
841 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts) =
842 TREE_STATIC (elts) = 1;
843 complete_array_type (arrtype, elts, 1);
847 (NULL_TREE, decay_conversion (tdecl), tree_cons
848 (NULL_TREE, decay_conversion (name_string), tree_cons
849 (NULL_TREE, decay_conversion (elts), tree_cons
850 (NULL_TREE, build_int_2 (base_cnt, 0), NULL_TREE))));
852 fn = get_identifier ("__rtti_class");
853 if (IDENTIFIER_GLOBAL_VALUE (fn))
854 fn = IDENTIFIER_GLOBAL_VALUE (fn);
857 push_obstacks (&permanent_obstack, &permanent_obstack);
859 (NULL_TREE, ptr_type_node, tree_cons
860 (NULL_TREE, const_string_type_node, tree_cons
861 (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons
862 (NULL_TREE, sizetype, void_list_node))));
863 tmp = build_function_type (void_type_node, tmp);
865 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
866 DECL_EXTERNAL (fn) = 1;
867 TREE_PUBLIC (fn) = 1;
868 DECL_ARTIFICIAL (fn) = 1;
869 pushdecl_top_level (fn);
870 make_function_rtl (fn);
871 assemble_external (fn);
875 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
876 expand_expr_stmt (fn);
879 /* Build an initializer for a __pointer_type_info node. */
882 expand_ptr_desc (tdecl, type)
887 char *name = build_overload_name (type, 1, 1);
888 tree name_string = combine_strings (build_string (strlen (name), name));
890 type = TREE_TYPE (type);
891 expand_expr_stmt (get_typeid_1 (type));
892 t = decay_conversion (get_tinfo_var (type));
894 (NULL_TREE, decay_conversion (tdecl), tree_cons
895 (NULL_TREE, decay_conversion (name_string), tree_cons
896 (NULL_TREE, t, NULL_TREE)));
898 fn = get_identifier ("__rtti_ptr");
899 if (IDENTIFIER_GLOBAL_VALUE (fn))
900 fn = IDENTIFIER_GLOBAL_VALUE (fn);
904 push_obstacks (&permanent_obstack, &permanent_obstack);
906 (NULL_TREE, ptr_type_node, tree_cons
907 (NULL_TREE, const_string_type_node, tree_cons
908 (NULL_TREE, build_pointer_type (type_info_type_node),
910 tmp = build_function_type (void_type_node, tmp);
912 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
913 DECL_EXTERNAL (fn) = 1;
914 TREE_PUBLIC (fn) = 1;
915 DECL_ARTIFICIAL (fn) = 1;
916 pushdecl_top_level (fn);
917 make_function_rtl (fn);
918 assemble_external (fn);
922 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
923 expand_expr_stmt (fn);
926 /* Build an initializer for a __attr_type_info node. */
929 expand_attr_desc (tdecl, type)
934 char *name = build_overload_name (type, 1, 1);
935 tree name_string = combine_strings (build_string (strlen (name), name));
936 tree attrval = build_int_2
937 (TYPE_READONLY (type) | TYPE_VOLATILE (type) * 2, 0);
939 expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
940 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
942 (NULL_TREE, decay_conversion (tdecl), tree_cons
943 (NULL_TREE, decay_conversion (name_string), tree_cons
944 (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
946 fn = get_identifier ("__rtti_attr");
947 if (IDENTIFIER_GLOBAL_VALUE (fn))
948 fn = IDENTIFIER_GLOBAL_VALUE (fn);
952 push_obstacks (&permanent_obstack, &permanent_obstack);
954 (NULL_TREE, ptr_type_node, tree_cons
955 (NULL_TREE, const_string_type_node, tree_cons
956 (NULL_TREE, integer_type_node, tree_cons
957 (NULL_TREE, build_pointer_type (type_info_type_node),
959 tmp = build_function_type (void_type_node, tmp);
961 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
962 DECL_EXTERNAL (fn) = 1;
963 TREE_PUBLIC (fn) = 1;
964 DECL_ARTIFICIAL (fn) = 1;
965 pushdecl_top_level (fn);
966 make_function_rtl (fn);
967 assemble_external (fn);
971 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
972 expand_expr_stmt (fn);
975 /* Build an initializer for a type_info node that just has a name. */
978 expand_generic_desc (tdecl, type, fnname)
983 char *name = build_overload_name (type, 1, 1);
984 tree name_string = combine_strings (build_string (strlen (name), name));
985 tree elems = tree_cons
986 (NULL_TREE, decay_conversion (tdecl), tree_cons
987 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
989 tree fn = get_identifier (fnname);
990 if (IDENTIFIER_GLOBAL_VALUE (fn))
991 fn = IDENTIFIER_GLOBAL_VALUE (fn);
995 push_obstacks (&permanent_obstack, &permanent_obstack);
997 (NULL_TREE, ptr_type_node, tree_cons
998 (NULL_TREE, const_string_type_node, void_list_node));
999 tmp = build_function_type (void_type_node, tmp);
1001 fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
1002 DECL_EXTERNAL (fn) = 1;
1003 TREE_PUBLIC (fn) = 1;
1004 DECL_ARTIFICIAL (fn) = 1;
1005 pushdecl_top_level (fn);
1006 make_function_rtl (fn);
1007 assemble_external (fn);
1011 fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
1012 expand_expr_stmt (fn);
1015 /* Generate the code for a type_info initialization function.
1016 Note that we take advantage of the passage
1018 5.2.7 Type identification [expr.typeid]
1020 Whether or not the destructor is called for the type_info object at the
1021 end of the program is unspecified.
1023 and don't bother to arrange for these objects to be destroyed. It
1024 doesn't matter, anyway, since the destructors don't do anything.
1026 This must only be called from toplevel (i.e. from finish_file)! */
1029 synthesize_tinfo_fn (fndecl)
1032 tree type = TREE_TYPE (DECL_NAME (fndecl));
1035 tree tdecl = get_tinfo_var (type);
1036 DECL_EXTERNAL (tdecl) = 0;
1037 TREE_STATIC (tdecl) = 1;
1038 DECL_COMMON (tdecl) = 1;
1039 TREE_USED (tdecl) = 1;
1040 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1041 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
1043 start_function (NULL_TREE, fndecl, NULL_TREE, 1);
1044 store_parm_decls ();
1048 /* If the first word of the array (the vtable) is non-zero, we've already
1049 initialized the object, so don't do it again. */
1050 addr = decay_conversion (tdecl);
1051 tmp = convert (build_pointer_type (ptr_type_node), addr);
1052 tmp = build_indirect_ref (tmp, 0);
1053 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1);
1054 expand_start_cond (tmp, 0);
1056 if (TREE_CODE (type) == FUNCTION_TYPE)
1057 expand_generic_desc (tdecl, type, "__rtti_func");
1058 else if (TREE_CODE (type) == ARRAY_TYPE)
1059 expand_generic_desc (tdecl, type, "__rtti_array");
1060 else if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
1061 expand_attr_desc (tdecl, type);
1062 else if (TREE_CODE (type) == POINTER_TYPE)
1064 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1065 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1066 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1067 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1069 expand_ptr_desc (tdecl, type);
1071 else if (TYPE_PTRMEMFUNC_P (type))
1072 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1073 else if (IS_AGGR_TYPE (type))
1075 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1076 expand_generic_desc (tdecl, type, "__rtti_user");
1077 else if (! TYPE_USES_COMPLEX_INHERITANCE (type)
1079 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1080 expand_si_desc (tdecl, type);
1082 expand_class_desc (tdecl, type);
1084 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1085 expand_generic_desc (tdecl, type, "__rtti_user");
1087 my_friendly_abort (252);
1091 /* OK, now return the type_info object. */
1092 tmp = convert (build_pointer_type (type_info_type_node), addr);
1093 tmp = build_indirect_ref (tmp, 0);
1094 c_expand_return (tmp);
1095 finish_function (lineno, 0, 0);
1099 /* This is the old dossier type descriptor generation code, it's much
1100 more extended than rtti. It's reserved for later use. */
1101 /* Build an initializer for a __t_desc node. So that we can take advantage
1102 of recursion, we accept NULL for TYPE.
1103 DEFINITION is greater than zero iff we must define the type descriptor
1104 (as opposed to merely referencing it). 1 means treat according to
1105 #pragma interface/#pragma implementation rules. 2 means define as
1106 global and public, no matter what. */
1109 build_t_desc (type, definition)
1114 tree tname, name_string;
1116 tree parents, vbases, offsets, ivars, methods, target_type;
1117 int method_count = 0, field_count = 0;
1119 if (type == NULL_TREE)
1122 tname = build_t_desc_overload (type);
1123 if (IDENTIFIER_AS_DESC (tname)
1124 && (!definition || TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname))))
1125 return IDENTIFIER_AS_DESC (tname);
1127 tdecl = lookup_name (tname, 0);
1128 if (tdecl == NULL_TREE)
1130 tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node);
1131 DECL_EXTERNAL (tdecl) = 1;
1132 TREE_PUBLIC (tdecl) = 1;
1133 tdecl = pushdecl_top_level (tdecl);
1135 /* If we previously defined it, return the defined result. */
1136 else if (definition && DECL_INITIAL (tdecl))
1137 return IDENTIFIER_AS_DESC (tname);
1142 /* Let T* and T& be written only when T is written (if T is an aggr).
1143 We do this for const, but not for volatile, since volatile
1144 is rare and const is not. */
1145 if (!TYPE_VOLATILE (taggr)
1146 && (TREE_CODE (taggr) == POINTER_TYPE
1147 || TREE_CODE (taggr) == REFERENCE_TYPE)
1148 && IS_AGGR_TYPE (TREE_TYPE (taggr)))
1149 taggr = TREE_TYPE (taggr);
1151 /* If we know that we don't need to write out this type's
1152 vtable, then don't write out it's dossier. Somebody
1153 else will take care of that. */
1154 if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr))
1156 if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr))
1158 TREE_PUBLIC (tdecl) = ! CLASSTYPE_INTERFACE_ONLY (taggr)
1159 && CLASSTYPE_INTERFACE_KNOWN (taggr);
1160 DECL_EXTERNAL (tdecl) = 0;
1164 if (write_virtuals != 0)
1165 TREE_PUBLIC (tdecl) = 1;
1170 DECL_EXTERNAL (tdecl) = 0;
1171 TREE_PUBLIC (tdecl) = (definition > 1);
1174 SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0));
1176 if (!definition || DECL_EXTERNAL (tdecl))
1179 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
1180 return IDENTIFIER_AS_DESC (tname);
1183 /* Show that we are defining the t_desc for this type. */
1184 DECL_INITIAL (tdecl) = error_mark_node;
1186 parents = build_tree_list (NULL_TREE, integer_zero_node);
1187 vbases = build_tree_list (NULL_TREE, integer_zero_node);
1188 offsets = build_tree_list (NULL_TREE, integer_zero_node);
1189 methods = NULL_TREE;
1192 if (TYPE_LANG_SPECIFIC (type))
1194 int i = CLASSTYPE_N_BASECLASSES (type);
1195 tree method_vec = CLASSTYPE_METHOD_VEC (type);
1197 tree binfos = TYPE_BINFO_BASETYPES (type);
1198 tree vb = CLASSTYPE_VBASECLASSES (type);
1201 parents = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0), parents);
1205 vbases = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (vb), 0), vbases);
1206 offsets = tree_cons (NULL_TREE, BINFO_OFFSET (vb), offsets);
1207 vb = TREE_CHAIN (vb);
1211 for (meth = TREE_VEC_END (method_vec),
1212 end = &TREE_VEC_ELT (method_vec, 0); meth-- != end; )
1215 methods = tree_cons (NULL_TREE, build_m_desc (*meth), methods);
1220 if (IS_AGGR_TYPE (type))
1222 for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
1223 if (TREE_CODE (fields) == FIELD_DECL
1224 || TREE_CODE (fields) == VAR_DECL)
1226 ivars = tree_cons (NULL_TREE, build_i_desc (fields), ivars);
1229 ivars = nreverse (ivars);
1232 parents = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), parents, 0);
1233 vbases = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), vbases, 0);
1234 offsets = finish_table (NULL_TREE, integer_type_node, offsets, 0);
1235 if (methods == NULL_TREE)
1236 methods = null_pointer_node;
1238 methods = build_unary_op (ADDR_EXPR,
1239 finish_table (NULL_TREE, __m_desc_type_node, methods, 0),
1241 if (ivars == NULL_TREE)
1242 ivars = null_pointer_node;
1244 ivars = build_unary_op (ADDR_EXPR,
1245 finish_table (NULL_TREE, __i_desc_type_node, ivars, 0),
1247 if (TREE_TYPE (type))
1248 target_type = build_t_desc (TREE_TYPE (type), definition);
1250 target_type = integer_zero_node;
1252 name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname)));
1254 elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
1255 tree_cons (NULL_TREE,
1256 TYPE_SIZE(type)? size_in_bytes(type) : integer_zero_node,
1257 /* really should use bitfield initialization here. */
1258 tree_cons (NULL_TREE, integer_zero_node,
1259 tree_cons (NULL_TREE, target_type,
1260 tree_cons (NULL_TREE, build_int_2 (field_count, 2),
1261 tree_cons (NULL_TREE, build_int_2 (method_count, 2),
1262 tree_cons (NULL_TREE, ivars,
1263 tree_cons (NULL_TREE, methods,
1264 tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, parents, 0),
1265 tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, vbases, 0),
1266 build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, offsets, 0))))))))))));
1267 return build_generic_desc (tdecl, elems);
1270 /* Build an initializer for a __i_desc node. */
1276 tree elems, name_string;
1279 name_string = DECL_NAME (decl);
1280 name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
1282 /* Now decide whether this ivar should cause it's type to get
1283 def'd or ref'd in this file. If the type we are looking at
1284 has a proxy definition, we look at the proxy (i.e., a
1285 `foo *' is equivalent to a `foo'). */
1286 taggr = TREE_TYPE (decl);
1288 if ((TREE_CODE (taggr) == POINTER_TYPE
1289 || TREE_CODE (taggr) == REFERENCE_TYPE)
1290 && TYPE_VOLATILE (taggr) == 0)
1291 taggr = TREE_TYPE (taggr);
1293 elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
1294 tree_cons (NULL_TREE, DECL_FIELD_BITPOS (decl),
1295 build_tree_list (NULL_TREE, build_t_desc (TREE_TYPE (decl),
1296 ! IS_AGGR_TYPE (taggr)))));
1297 taggr = build (CONSTRUCTOR, __i_desc_type_node, NULL_TREE, elems);
1298 TREE_CONSTANT (taggr) = 1;
1299 TREE_STATIC (taggr) = 1;
1300 TREE_READONLY (taggr) = 1;
1304 /* Build an initializer for a __m_desc node. */
1310 tree taggr, elems, name_string;
1311 tree parm_count, req_count, vindex, vcontext;
1313 int p_count, r_count;
1314 tree parm_types = NULL_TREE;
1316 for (parms = TYPE_ARG_TYPES (TREE_TYPE (decl)), p_count = 0, r_count = 0;
1317 parms != NULL_TREE; parms = TREE_CHAIN (parms), p_count++)
1319 taggr = TREE_VALUE (parms);
1320 if ((TREE_CODE (taggr) == POINTER_TYPE
1321 || TREE_CODE (taggr) == REFERENCE_TYPE)
1322 && TYPE_VOLATILE (taggr) == 0)
1323 taggr = TREE_TYPE (taggr);
1325 parm_types = tree_cons (NULL_TREE, build_t_desc (TREE_VALUE (parms),
1326 ! IS_AGGR_TYPE (taggr)),
1328 if (TREE_PURPOSE (parms) == NULL_TREE)
1332 parm_types = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node),
1333 nreverse (parm_types), 0);
1334 parm_count = build_int_2 (p_count, 0);
1335 req_count = build_int_2 (r_count, 0);
1337 if (DECL_VINDEX (decl))
1338 vindex = DECL_VINDEX (decl);
1340 vindex = integer_zero_node;
1341 if (DECL_CONTEXT (decl)
1342 && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
1343 vcontext = build_t_desc (DECL_CONTEXT (decl), 0);
1345 vcontext = integer_zero_node;
1346 name_string = DECL_NAME (decl);
1347 if (name_string == NULL)
1348 name_string = DECL_ASSEMBLER_NAME (decl);
1349 name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
1351 /* Now decide whether the return type of this mvar
1352 should cause it's type to get def'd or ref'd in this file.
1353 If the type we are looking at has a proxy definition,
1354 we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */
1355 taggr = TREE_TYPE (TREE_TYPE (decl));
1357 if ((TREE_CODE (taggr) == POINTER_TYPE
1358 || TREE_CODE (taggr) == REFERENCE_TYPE)
1359 && TYPE_VOLATILE (taggr) == 0)
1360 taggr = TREE_TYPE (taggr);
1362 elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
1363 tree_cons (NULL_TREE, vindex,
1364 tree_cons (NULL_TREE, vcontext,
1365 tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)),
1366 ! IS_AGGR_TYPE (taggr)),
1367 tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0), 0),
1368 tree_cons (NULL_TREE, parm_count,
1369 tree_cons (NULL_TREE, req_count,
1370 build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0)))))))));
1372 taggr = build (CONSTRUCTOR, __m_desc_type_node, NULL_TREE, elems);
1373 TREE_CONSTANT (taggr) = 1;
1374 TREE_STATIC (taggr) = 1;
1375 TREE_READONLY (taggr) = 1;
1378 #endif /* dossier */