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. */
32 #define INT_TYPE_SIZE BITS_PER_WORD
35 extern struct obstack permanent_obstack
;
37 static tree call_void_fn
PROTO((char *));
38 static tree build_headof_sub
PROTO((tree
));
39 static tree build_headof
PROTO((tree
));
40 static tree get_tinfo_var
PROTO((tree
));
41 static tree get_typeid_1
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
, char *));
49 static tree throw_bad_cast
PROTO((void));
50 static tree throw_bad_typeid
PROTO((void));
52 tree type_info_type_node
;
57 init_rtti_processing ()
59 type_info_type_node
= xref_tag
60 (class_type_node
, get_identifier ("type_info"), NULL_TREE
, 1);
61 tinfo_fn_id
= get_identifier ("__tf");
62 tinfo_fn_type
= build_function_type
63 (build_reference_type (build_type_variant (type_info_type_node
, 1, 0)),
67 /* Given a pointer to an object with at least one virtual table
68 pointer somewhere, return a pointer to a possible sub-object that
69 has a virtual table pointer in it that is the vtable parent for
73 build_headof_sub (exp
)
76 tree type
= TREE_TYPE (TREE_TYPE (exp
));
77 tree basetype
= CLASSTYPE_RTTI (type
);
78 tree binfo
= get_binfo (basetype
, type
, 0);
80 exp
= convert_pointer_to_real (binfo
, exp
);
84 /* Given the expression EXP of type `class *', return the head of the
85 object pointed to by EXP with type cv void*, if the class has any
86 virtual functions (TYPE_VIRTUAL_P), else just return the
93 tree type
= TREE_TYPE (exp
);
97 if (TREE_CODE (type
) != POINTER_TYPE
)
99 error ("`headof' applied to non-pointer type");
100 return error_mark_node
;
102 type
= TREE_TYPE (type
);
104 if (!TYPE_VIRTUAL_P (type
))
107 /* If we don't have rtti stuff, get to a sub-object that does. */
108 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp
))))
109 exp
= build_headof_sub (exp
);
111 /* We use this a couple of times below, protect it. */
112 exp
= save_expr (exp
);
114 aref
= build_vtbl_ref (build_indirect_ref (exp
, NULL_PTR
), integer_zero_node
);
116 if (flag_vtable_thunks
)
119 offset
= build_component_ref (aref
, delta_identifier
, NULL_TREE
, 0);
121 type
= build_type_variant (ptr_type_node
, TREE_READONLY (exp
),
122 TREE_THIS_VOLATILE (exp
));
123 return build (PLUS_EXPR
, type
, exp
,
124 cp_convert (ptrdiff_type_node
, offset
));
127 /* Build a call to a generic entry point taking and returning void. */
133 tree d
= get_identifier (name
);
136 if (IDENTIFIER_GLOBAL_VALUE (d
))
137 d
= IDENTIFIER_GLOBAL_VALUE (d
);
140 push_obstacks (&permanent_obstack
, &permanent_obstack
);
142 type
= build_function_type (void_type_node
, void_list_node
);
143 d
= build_lang_decl (FUNCTION_DECL
, d
, type
);
144 DECL_EXTERNAL (d
) = 1;
146 DECL_ARTIFICIAL (d
) = 1;
147 pushdecl_top_level (d
);
148 make_function_rtl (d
);
149 assemble_external (d
);
154 return build_call (d
, void_type_node
, NULL_TREE
);
157 /* Get a bad_cast node for the program to throw...
159 See libstdc++/exception.cc for __throw_bad_cast */
164 return call_void_fn ("__throw_bad_cast");
170 return call_void_fn ("__throw_bad_typeid");
173 /* Return the type_info function associated with the expression EXP. If
174 EXP is a reference to a polymorphic class, return the dynamic type;
175 otherwise return the static type of the expression. */
178 get_tinfo_fn_dynamic (exp
)
183 if (exp
== error_mark_node
)
184 return error_mark_node
;
186 if (type_unknown_p (exp
))
188 error ("typeid of overloaded function");
189 return error_mark_node
;
192 type
= TREE_TYPE (exp
);
194 /* peel back references, so they match. */
195 if (TREE_CODE (type
) == REFERENCE_TYPE
)
196 type
= TREE_TYPE (type
);
198 /* Peel off cv qualifiers. */
199 type
= TYPE_MAIN_VARIANT (type
);
201 /* If exp is a reference to polymorphic type, get the real type_info. */
202 if (TYPE_VIRTUAL_P (type
) && ! resolves_to_fixed_type_p (exp
, 0))
204 /* build reference to type_info from vtable. */
208 warning ("taking dynamic typeid of object without -frtti");
210 /* If we don't have rtti stuff, get to a sub-object that does. */
211 if (! CLASSTYPE_VFIELDS (type
))
213 exp
= build_unary_op (ADDR_EXPR
, exp
, 0);
214 exp
= build_headof_sub (exp
);
215 exp
= build_indirect_ref (exp
, NULL_PTR
);
218 if (flag_vtable_thunks
)
219 t
= build_vfn_ref ((tree
*) 0, exp
, integer_one_node
);
221 t
= build_vfn_ref ((tree
*) 0, exp
, integer_zero_node
);
222 TREE_TYPE (t
) = build_pointer_type (tinfo_fn_type
);
226 /* otherwise return the type_info for the static type of the expr. */
227 return get_tinfo_fn (TYPE_MAIN_VARIANT (type
));
234 exp
= get_tinfo_fn_dynamic (exp
);
235 exp
= build_call (exp
, TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
236 return convert_from_reference (exp
);
243 tree cond
= NULL_TREE
;
244 tree type
= TREE_TYPE (tinfo_fn_type
);
247 if (processing_template_decl
)
248 return build_min_nt (TYPEID_EXPR
, exp
);
250 if (TREE_CODE (exp
) == INDIRECT_REF
251 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp
, 0))) == POINTER_TYPE
252 && TYPE_VIRTUAL_P (TREE_TYPE (exp
))
253 && ! resolves_to_fixed_type_p (exp
, &nonnull
)
256 exp
= stabilize_reference (exp
);
257 cond
= cp_convert (boolean_type_node
, TREE_OPERAND (exp
, 0));
260 exp
= get_tinfo_fn_dynamic (exp
);
262 if (exp
== error_mark_node
)
263 return error_mark_node
;
265 exp
= build_call (exp
, type
, NULL_TREE
);
269 tree bad
= throw_bad_typeid ();
271 bad
= build_compound_expr
272 (expr_tree_cons (NULL_TREE
, bad
, build_expr_list
273 (NULL_TREE
, cp_convert (type
, integer_zero_node
))));
274 exp
= build (COND_EXPR
, type
, cond
, exp
, bad
);
277 return convert_from_reference (exp
);
284 tree tname
= build_overload_with_type (get_identifier ("__ti"), type
);
288 if (IDENTIFIER_GLOBAL_VALUE (tname
))
289 return IDENTIFIER_GLOBAL_VALUE (tname
);
291 /* Figure out how much space we need to allocate for the type_info object.
292 If our struct layout or the type_info classes are changed, this will
293 need to be modified. */
294 if (TYPE_VOLATILE (type
) || TYPE_READONLY (type
))
295 size
= 3 * POINTER_SIZE
+ INT_TYPE_SIZE
;
296 else if (TREE_CODE (type
) == POINTER_TYPE
297 && ! (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
298 || TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
))
299 size
= 3 * POINTER_SIZE
;
300 else if (IS_AGGR_TYPE (type
))
302 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
303 size
= 2 * POINTER_SIZE
;
304 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
306 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
307 size
= 3 * POINTER_SIZE
;
309 size
= 3 * POINTER_SIZE
+ TYPE_PRECISION (sizetype
);
312 size
= 2 * POINTER_SIZE
;
314 push_obstacks (&permanent_obstack
, &permanent_obstack
);
316 /* The type for a character array of the appropriate size. */
317 arrtype
= build_cplus_array_type
318 (unsigned_char_type_node
,
319 build_index_type (size_int (size
/ BITS_PER_UNIT
- 1)));
321 tdecl
= build_decl (VAR_DECL
, tname
, arrtype
);
322 TREE_PUBLIC (tdecl
) = 1;
323 DECL_EXTERNAL (tdecl
) = 1;
324 DECL_ARTIFICIAL (tdecl
) = 1;
325 pushdecl_top_level (tdecl
);
326 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
340 if (TREE_CODE (type
) == OFFSET_TYPE
)
341 type
= TREE_TYPE (type
);
342 if (TREE_CODE (type
) == METHOD_TYPE
)
343 type
= build_function_type (TREE_TYPE (type
),
344 TREE_CHAIN (TYPE_ARG_TYPES (type
)));
346 name
= build_overload_with_type (tinfo_fn_id
, type
);
348 if (IDENTIFIER_GLOBAL_VALUE (name
))
349 return IDENTIFIER_GLOBAL_VALUE (name
);
351 push_obstacks (&permanent_obstack
, &permanent_obstack
);
353 d
= build_lang_decl (FUNCTION_DECL
, name
, tinfo_fn_type
);
354 DECL_EXTERNAL (d
) = 1;
356 DECL_ARTIFICIAL (d
) = 1;
357 DECL_NOT_REALLY_EXTERN (d
) = 1;
358 DECL_MUTABLE_P (d
) = 1;
359 TREE_TYPE (name
) = copy_to_permanent (type
);
360 pushdecl_top_level (d
);
361 make_function_rtl (d
);
362 assemble_external (d
);
363 mark_inline_for_output (d
);
365 import_export_decl (d
);
377 (get_tinfo_fn (type
), TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
378 return convert_from_reference (t
);
381 /* Return the type_info object for TYPE, creating it if necessary. */
387 if (type
== error_mark_node
)
388 return error_mark_node
;
390 if (processing_template_decl
)
391 return build_min_nt (TYPEID_EXPR
, type
);
393 /* If the type of the type-id is a reference type, the result of the
394 typeid expression refers to a type_info object representing the
396 if (TREE_CODE (type
) == REFERENCE_TYPE
)
397 type
= TREE_TYPE (type
);
399 /* The top-level cv-qualifiers of the lvalue expression or the type-id
400 that is the operand of typeid are always ignored. */
401 type
= TYPE_MAIN_VARIANT (type
);
403 return get_typeid_1 (type
);
406 /* Check whether TEST is null before returning RESULT. If TEST is used in
407 RESULT, it must have previously had a save_expr applied to it. */
410 ifnonnull (test
, result
)
413 return build (COND_EXPR
, TREE_TYPE (result
),
414 build (EQ_EXPR
, boolean_type_node
, test
, integer_zero_node
),
415 cp_convert (TREE_TYPE (result
), integer_zero_node
),
419 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
423 build_dynamic_cast_1 (type
, expr
)
426 enum tree_code tc
= TREE_CODE (type
);
427 tree exprtype
= TREE_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 (complete_type (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 (complete_type (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 (complete_type (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 (expr_tree_cons (NULL_TREE
, expr1
,
619 build_expr_list (NULL_TREE
, cp_convert (type
, integer_zero_node
))));
620 TREE_TYPE (expr1
) = type
;
621 result
= save_expr (result
);
622 return build (COND_EXPR
, type
, result
, result
, expr1
);
625 /* Now back to the type we want from a void*. */
626 result
= cp_convert (type
, result
);
627 return ifnonnull (expr
, result
);
632 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
633 expr
, exprtype
, type
);
634 return error_mark_node
;
638 build_dynamic_cast (type
, expr
)
641 if (type
== error_mark_node
|| expr
== error_mark_node
)
642 return error_mark_node
;
644 if (processing_template_decl
)
645 return build_min (DYNAMIC_CAST_EXPR
, type
, expr
);
647 return convert_from_reference (build_dynamic_cast_1 (type
, expr
));
650 /* Build and initialize various sorts of descriptors. Every descriptor
651 node has a name associated with it (the name created by mangling).
652 For this reason, we use the identifier as our access to the __*_desc
653 nodes, instead of sticking them directly in the types. Otherwise we
654 would burden all built-in types (and pointer types) with slots that
655 we don't necessarily want to use.
657 For each descriptor we build, we build a variable that contains
658 the descriptor's information. When we need this info at runtime,
659 all we need is access to these variables.
661 Note: these constructors always return the address of the descriptor
662 info, since that is simplest for their mutual interaction. */
664 extern tree const_string_type_node
;
666 /* Build an initializer for a __si_type_info node. */
669 expand_si_desc (tdecl
, type
)
674 char *name
= build_overload_name (type
, 1, 1);
675 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
677 type
= BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0));
678 expand_expr_stmt (get_typeid_1 (type
));
679 t
= decay_conversion (get_tinfo_var (type
));
681 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
682 (NULL_TREE
, decay_conversion (name_string
), tree_cons
683 (NULL_TREE
, t
, NULL_TREE
)));
685 fn
= get_identifier ("__rtti_si");
686 if (IDENTIFIER_GLOBAL_VALUE (fn
))
687 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
691 push_obstacks (&permanent_obstack
, &permanent_obstack
);
693 (NULL_TREE
, ptr_type_node
, tree_cons
694 (NULL_TREE
, const_string_type_node
, tree_cons
695 (NULL_TREE
, build_pointer_type (type_info_type_node
),
697 tmp
= build_function_type (void_type_node
, tmp
);
699 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
700 DECL_EXTERNAL (fn
) = 1;
701 TREE_PUBLIC (fn
) = 1;
702 DECL_ARTIFICIAL (fn
) = 1;
703 pushdecl_top_level (fn
);
704 make_function_rtl (fn
);
705 assemble_external (fn
);
709 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
710 expand_expr_stmt (fn
);
713 /* Build an initializer for a __class_type_info node. */
716 expand_class_desc (tdecl
, type
)
724 int i
= CLASSTYPE_N_BASECLASSES (type
);
726 tree binfos
= TYPE_BINFO_BASETYPES (type
);
728 /* See code below that used these. */
729 tree vb
= CLASSTYPE_VBASECLASSES (type
);
732 tree base
, elems
, access
, offset
, isvir
;
733 tree elt
, elts
= NULL_TREE
;
734 static tree base_info_type_node
;
736 if (base_info_type_node
== NULL_TREE
)
740 /* A reasonably close approximation of __class_type_info::base_info */
742 push_obstacks (&permanent_obstack
, &permanent_obstack
);
743 base_info_type_node
= make_lang_type (RECORD_TYPE
);
745 /* Actually const __user_type_info * */
746 fields
[0] = build_lang_field_decl
747 (FIELD_DECL
, NULL_TREE
,
748 build_pointer_type (build_type_variant (type_info_type_node
, 1, 0)));
749 fields
[1] = build_lang_field_decl
750 (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
751 DECL_BIT_FIELD (fields
[1]) = 1;
752 DECL_FIELD_SIZE (fields
[1]) = 29;
754 fields
[2] = build_lang_field_decl
755 (FIELD_DECL
, NULL_TREE
, boolean_type_node
);
756 DECL_BIT_FIELD (fields
[2]) = 1;
757 DECL_FIELD_SIZE (fields
[2]) = 1;
759 /* Actually enum access */
760 fields
[3] = build_lang_field_decl
761 (FIELD_DECL
, NULL_TREE
, integer_type_node
);
762 DECL_BIT_FIELD (fields
[3]) = 1;
763 DECL_FIELD_SIZE (fields
[3]) = 2;
765 finish_builtin_type (base_info_type_node
, "__base_info", fields
,
772 tree binfo
= TREE_VEC_ELT (binfos
, i
);
774 expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo
)));
775 base
= decay_conversion (get_tinfo_var (BINFO_TYPE (binfo
)));
777 if (TREE_VIA_VIRTUAL (binfo
))
779 tree t
= BINFO_TYPE (binfo
);
783 name
= (char *) alloca (TYPE_NAME_LENGTH (t
)+sizeof (VBASE_NAME
)+1);
784 sprintf (name
, VBASE_NAME_FORMAT
, TYPE_NAME_STRING (t
));
785 field
= lookup_field (type
, get_identifier (name
), 0, 0);
786 offset
= size_binop (FLOOR_DIV_EXPR
,
787 DECL_FIELD_BITPOS (field
), size_int (BITS_PER_UNIT
));
790 offset
= BINFO_OFFSET (binfo
);
792 if (TREE_VIA_PUBLIC (binfo
))
793 access
= access_public_node
;
794 else if (TREE_VIA_PROTECTED (binfo
))
795 access
= access_protected_node
;
797 access
= access_private_node
;
798 if (TREE_VIA_VIRTUAL (binfo
))
799 isvir
= boolean_true_node
;
801 isvir
= boolean_false_node
;
804 (CONSTRUCTOR
, base_info_type_node
, NULL_TREE
, tree_cons
805 (NULL_TREE
, base
, tree_cons
806 (NULL_TREE
, offset
, tree_cons
807 (NULL_TREE
, isvir
, tree_cons
808 (NULL_TREE
, access
, NULL_TREE
)))));
809 TREE_HAS_CONSTRUCTOR (elt
) = TREE_CONSTANT (elt
) = TREE_STATIC (elt
) = 1;
810 elts
= expr_tree_cons (NULL_TREE
, elt
, elts
);
818 access
= access_public_node
;
821 b
= TREE_VEC_ELT (binfos
, i
);
822 if (BINFO_TYPE (vb
) == BINFO_TYPE (b
) && TREE_VIA_VIRTUAL (b
))
824 if (TREE_VIA_PUBLIC (b
))
825 access
= access_public_node
;
826 else if (TREE_VIA_PROTECTED (b
))
827 access
= access_protected_node
;
829 access
= access_private_node
;
833 base
= build_t_desc (BINFO_TYPE (vb
), 1);
834 offset
= BINFO_OFFSET (vb
);
835 isvir
= build_int_2 (1, 0);
837 base_list
= expr_tree_cons (NULL_TREE
, base
, base_list
);
838 isvir_list
= expr_tree_cons (NULL_TREE
, isvir
, isvir_list
);
839 acc_list
= expr_tree_cons (NULL_TREE
, access
, acc_list
);
840 off_list
= expr_tree_cons (NULL_TREE
, offset
, off_list
);
843 vb
= TREE_CHAIN (vb
);
847 name
= build_overload_name (type
, 1, 1);
848 name_string
= combine_strings (build_string (strlen (name
)+1, name
));
851 tree arrtype
= build_array_type (base_info_type_node
, NULL_TREE
);
852 elts
= build (CONSTRUCTOR
, arrtype
, NULL_TREE
, elts
);
853 TREE_HAS_CONSTRUCTOR (elts
) = TREE_CONSTANT (elts
)
854 = TREE_STATIC (elts
) = 1;
855 complete_array_type (arrtype
, elts
, 1);
859 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
860 (NULL_TREE
, decay_conversion (name_string
), tree_cons
861 (NULL_TREE
, decay_conversion (elts
), tree_cons
862 (NULL_TREE
, cp_convert (sizetype
, build_int_2 (base_cnt
, 0)),
865 fn
= get_identifier ("__rtti_class");
866 if (IDENTIFIER_GLOBAL_VALUE (fn
))
867 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
870 push_obstacks (&permanent_obstack
, &permanent_obstack
);
872 (NULL_TREE
, ptr_type_node
, tree_cons
873 (NULL_TREE
, const_string_type_node
, tree_cons
874 (NULL_TREE
, build_pointer_type (base_info_type_node
), tree_cons
875 (NULL_TREE
, sizetype
, void_list_node
))));
876 tmp
= build_function_type (void_type_node
, tmp
);
878 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
879 DECL_EXTERNAL (fn
) = 1;
880 TREE_PUBLIC (fn
) = 1;
881 DECL_ARTIFICIAL (fn
) = 1;
882 pushdecl_top_level (fn
);
883 make_function_rtl (fn
);
884 assemble_external (fn
);
888 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
889 expand_expr_stmt (fn
);
892 /* Build an initializer for a __pointer_type_info node. */
895 expand_ptr_desc (tdecl
, type
)
900 char *name
= build_overload_name (type
, 1, 1);
901 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
903 type
= TREE_TYPE (type
);
904 expand_expr_stmt (get_typeid_1 (type
));
905 t
= decay_conversion (get_tinfo_var (type
));
907 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
908 (NULL_TREE
, decay_conversion (name_string
), tree_cons
909 (NULL_TREE
, t
, NULL_TREE
)));
911 fn
= get_identifier ("__rtti_ptr");
912 if (IDENTIFIER_GLOBAL_VALUE (fn
))
913 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
917 push_obstacks (&permanent_obstack
, &permanent_obstack
);
919 (NULL_TREE
, ptr_type_node
, tree_cons
920 (NULL_TREE
, const_string_type_node
, tree_cons
921 (NULL_TREE
, build_pointer_type (type_info_type_node
),
923 tmp
= build_function_type (void_type_node
, tmp
);
925 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
926 DECL_EXTERNAL (fn
) = 1;
927 TREE_PUBLIC (fn
) = 1;
928 DECL_ARTIFICIAL (fn
) = 1;
929 pushdecl_top_level (fn
);
930 make_function_rtl (fn
);
931 assemble_external (fn
);
935 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
936 expand_expr_stmt (fn
);
939 /* Build an initializer for a __attr_type_info node. */
942 expand_attr_desc (tdecl
, type
)
947 char *name
= build_overload_name (type
, 1, 1);
948 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
949 tree attrval
= build_int_2
950 (TYPE_READONLY (type
) | TYPE_VOLATILE (type
) * 2, 0);
952 expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type
)));
953 t
= decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type
)));
955 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
956 (NULL_TREE
, decay_conversion (name_string
), tree_cons
957 (NULL_TREE
, attrval
, expr_tree_cons (NULL_TREE
, t
, NULL_TREE
))));
959 fn
= get_identifier ("__rtti_attr");
960 if (IDENTIFIER_GLOBAL_VALUE (fn
))
961 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
965 push_obstacks (&permanent_obstack
, &permanent_obstack
);
967 (NULL_TREE
, ptr_type_node
, tree_cons
968 (NULL_TREE
, const_string_type_node
, tree_cons
969 (NULL_TREE
, integer_type_node
, tree_cons
970 (NULL_TREE
, build_pointer_type (type_info_type_node
),
972 tmp
= build_function_type (void_type_node
, tmp
);
974 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
975 DECL_EXTERNAL (fn
) = 1;
976 TREE_PUBLIC (fn
) = 1;
977 DECL_ARTIFICIAL (fn
) = 1;
978 pushdecl_top_level (fn
);
979 make_function_rtl (fn
);
980 assemble_external (fn
);
984 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
985 expand_expr_stmt (fn
);
988 /* Build an initializer for a type_info node that just has a name. */
991 expand_generic_desc (tdecl
, type
, fnname
)
996 char *name
= build_overload_name (type
, 1, 1);
997 tree name_string
= combine_strings (build_string (strlen (name
)+1, name
));
998 tree elems
= tree_cons
999 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
1000 (NULL_TREE
, decay_conversion (name_string
), NULL_TREE
));
1002 tree fn
= get_identifier (fnname
);
1003 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1004 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1008 push_obstacks (&permanent_obstack
, &permanent_obstack
);
1010 (NULL_TREE
, ptr_type_node
, tree_cons
1011 (NULL_TREE
, const_string_type_node
, void_list_node
));
1012 tmp
= build_function_type (void_type_node
, tmp
);
1014 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
1015 DECL_EXTERNAL (fn
) = 1;
1016 TREE_PUBLIC (fn
) = 1;
1017 DECL_ARTIFICIAL (fn
) = 1;
1018 pushdecl_top_level (fn
);
1019 make_function_rtl (fn
);
1020 assemble_external (fn
);
1024 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1025 expand_expr_stmt (fn
);
1028 /* Generate the code for a type_info initialization function.
1029 Note that we take advantage of the passage
1031 5.2.7 Type identification [expr.typeid]
1033 Whether or not the destructor is called for the type_info object at the
1034 end of the program is unspecified.
1036 and don't bother to arrange for these objects to be destroyed. It
1037 doesn't matter, anyway, since the destructors don't do anything.
1039 This must only be called from toplevel (i.e. from finish_file)! */
1042 synthesize_tinfo_fn (fndecl
)
1045 tree type
= TREE_TYPE (DECL_NAME (fndecl
));
1048 tree tdecl
= get_tinfo_var (type
);
1049 DECL_EXTERNAL (tdecl
) = 0;
1050 TREE_STATIC (tdecl
) = 1;
1051 DECL_COMMON (tdecl
) = 1;
1052 TREE_USED (tdecl
) = 1;
1053 DECL_ALIGN (tdecl
) = TYPE_ALIGN (ptr_type_node
);
1054 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
1056 start_function (NULL_TREE
, fndecl
, NULL_TREE
, 1);
1057 store_parm_decls ();
1061 /* If the first word of the array (the vtable) is non-zero, we've already
1062 initialized the object, so don't do it again. */
1063 addr
= decay_conversion (tdecl
);
1064 tmp
= cp_convert (build_pointer_type (ptr_type_node
), addr
);
1065 tmp
= build_indirect_ref (tmp
, 0);
1066 tmp
= build_binary_op (EQ_EXPR
, tmp
, integer_zero_node
, 1);
1067 expand_start_cond (tmp
, 0);
1069 if (TREE_CODE (type
) == FUNCTION_TYPE
)
1070 expand_generic_desc (tdecl
, type
, "__rtti_func");
1071 else if (TREE_CODE (type
) == ARRAY_TYPE
)
1072 expand_generic_desc (tdecl
, type
, "__rtti_array");
1073 else if (TYPE_VOLATILE (type
) || TYPE_READONLY (type
))
1074 expand_attr_desc (tdecl
, type
);
1075 else if (TREE_CODE (type
) == POINTER_TYPE
)
1077 if (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
)
1078 expand_generic_desc (tdecl
, type
, "__rtti_ptmd");
1079 else if (TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
)
1080 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1082 expand_ptr_desc (tdecl
, type
);
1084 else if (TYPE_PTRMEMFUNC_P (type
))
1085 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1086 else if (IS_AGGR_TYPE (type
))
1088 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
1089 expand_generic_desc (tdecl
, type
, "__rtti_user");
1090 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
1092 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
1093 expand_si_desc (tdecl
, type
);
1095 expand_class_desc (tdecl
, type
);
1097 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
1098 expand_generic_desc (tdecl
, type
, "__rtti_user");
1100 my_friendly_abort (252);
1104 /* OK, now return the type_info object. */
1105 tmp
= cp_convert (build_pointer_type (type_info_type_node
), addr
);
1106 tmp
= build_indirect_ref (tmp
, 0);
1107 c_expand_return (tmp
);
1108 finish_function (lineno
, 0, 0);
1112 /* This is the old dossier type descriptor generation code, it's much
1113 more extended than rtti. It's reserved for later use. */
1114 /* Build an initializer for a __t_desc node. So that we can take advantage
1115 of recursion, we accept NULL for TYPE.
1116 DEFINITION is greater than zero iff we must define the type descriptor
1117 (as opposed to merely referencing it). 1 means treat according to
1118 #pragma interface/#pragma implementation rules. 2 means define as
1119 global and public, no matter what. */
1122 build_t_desc (type
, definition
)
1127 tree tname
, name_string
;
1129 tree parents
, vbases
, offsets
, ivars
, methods
, target_type
;
1130 int method_count
= 0, field_count
= 0;
1132 if (type
== NULL_TREE
)
1135 tname
= build_t_desc_overload (type
);
1136 if (IDENTIFIER_AS_DESC (tname
)
1137 && (!definition
|| TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname
))))
1138 return IDENTIFIER_AS_DESC (tname
);
1140 tdecl
= lookup_name (tname
, 0);
1141 if (tdecl
== NULL_TREE
)
1143 tdecl
= build_decl (VAR_DECL
, tname
, __t_desc_type_node
);
1144 DECL_EXTERNAL (tdecl
) = 1;
1145 TREE_PUBLIC (tdecl
) = 1;
1146 tdecl
= pushdecl_top_level (tdecl
);
1148 /* If we previously defined it, return the defined result. */
1149 else if (definition
&& DECL_INITIAL (tdecl
))
1150 return IDENTIFIER_AS_DESC (tname
);
1155 /* Let T* and T& be written only when T is written (if T is an aggr).
1156 We do this for const, but not for volatile, since volatile
1157 is rare and const is not. */
1158 if (!TYPE_VOLATILE (taggr
)
1159 && (TREE_CODE (taggr
) == POINTER_TYPE
1160 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1161 && IS_AGGR_TYPE (TREE_TYPE (taggr
)))
1162 taggr
= TREE_TYPE (taggr
);
1164 /* If we know that we don't need to write out this type's
1165 vtable, then don't write out it's dossier. Somebody
1166 else will take care of that. */
1167 if (IS_AGGR_TYPE (taggr
) && CLASSTYPE_VFIELD (taggr
))
1169 if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr
))
1171 TREE_PUBLIC (tdecl
) = ! CLASSTYPE_INTERFACE_ONLY (taggr
)
1172 && CLASSTYPE_INTERFACE_KNOWN (taggr
);
1173 DECL_EXTERNAL (tdecl
) = 0;
1177 if (write_virtuals
!= 0)
1178 TREE_PUBLIC (tdecl
) = 1;
1183 DECL_EXTERNAL (tdecl
) = 0;
1184 TREE_PUBLIC (tdecl
) = (definition
> 1);
1187 SET_IDENTIFIER_AS_DESC (tname
, build_unary_op (ADDR_EXPR
, tdecl
, 0));
1189 if (!definition
|| DECL_EXTERNAL (tdecl
))
1192 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
1193 return IDENTIFIER_AS_DESC (tname
);
1196 /* Show that we are defining the t_desc for this type. */
1197 DECL_INITIAL (tdecl
) = error_mark_node
;
1199 parents
= build_expr_list (NULL_TREE
, integer_zero_node
);
1200 vbases
= build_expr_list (NULL_TREE
, integer_zero_node
);
1201 offsets
= build_expr_list (NULL_TREE
, integer_zero_node
);
1202 methods
= NULL_TREE
;
1205 if (TYPE_LANG_SPECIFIC (type
))
1207 int i
= CLASSTYPE_N_BASECLASSES (type
);
1208 tree method_vec
= CLASSTYPE_METHOD_VEC (type
);
1210 tree binfos
= TYPE_BINFO_BASETYPES (type
);
1211 tree vb
= CLASSTYPE_VBASECLASSES (type
);
1214 parents
= tree_cons (NULL_TREE
, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos
, i
)), 0), parents
);
1218 vbases
= tree_cons (NULL_TREE
, build_t_desc (BINFO_TYPE (vb
), 0), vbases
);
1219 offsets
= tree_cons (NULL_TREE
, BINFO_OFFSET (vb
), offsets
);
1220 vb
= TREE_CHAIN (vb
);
1224 for (meth
= TREE_VEC_END (method_vec
),
1225 end
= &TREE_VEC_ELT (method_vec
, 0); meth
-- != end
; )
1228 methods
= tree_cons (NULL_TREE
, build_m_desc (*meth
), methods
);
1233 if (IS_AGGR_TYPE (type
))
1235 for (fields
= TYPE_FIELDS (type
); fields
; fields
= TREE_CHAIN (fields
))
1236 if (TREE_CODE (fields
) == FIELD_DECL
1237 || TREE_CODE (fields
) == VAR_DECL
)
1239 ivars
= tree_cons (NULL_TREE
, build_i_desc (fields
), ivars
);
1242 ivars
= nreverse (ivars
);
1245 parents
= finish_table (NULL_TREE
, build_pointer_type (__t_desc_type_node
), parents
, 0);
1246 vbases
= finish_table (NULL_TREE
, build_pointer_type (__t_desc_type_node
), vbases
, 0);
1247 offsets
= finish_table (NULL_TREE
, integer_type_node
, offsets
, 0);
1248 if (methods
== NULL_TREE
)
1249 methods
= null_pointer_node
;
1251 methods
= build_unary_op (ADDR_EXPR
,
1252 finish_table (NULL_TREE
, __m_desc_type_node
, methods
, 0),
1254 if (ivars
== NULL_TREE
)
1255 ivars
= null_pointer_node
;
1257 ivars
= build_unary_op (ADDR_EXPR
,
1258 finish_table (NULL_TREE
, __i_desc_type_node
, ivars
, 0),
1260 if (TREE_TYPE (type
))
1261 target_type
= build_t_desc (TREE_TYPE (type
), definition
);
1263 target_type
= integer_zero_node
;
1265 name_string
= combine_strings (build_string (IDENTIFIER_LENGTH (tname
)+1, IDENTIFIER_POINTER (tname
)));
1267 elems
= tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, name_string
, 0),
1268 tree_cons (NULL_TREE
,
1269 TYPE_SIZE(type
)? size_in_bytes(type
) : integer_zero_node
,
1270 /* really should use bitfield initialization here. */
1271 tree_cons (NULL_TREE
, integer_zero_node
,
1272 tree_cons (NULL_TREE
, target_type
,
1273 tree_cons (NULL_TREE
, build_int_2 (field_count
, 2),
1274 tree_cons (NULL_TREE
, build_int_2 (method_count
, 2),
1275 tree_cons (NULL_TREE
, ivars
,
1276 tree_cons (NULL_TREE
, methods
,
1277 tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, parents
, 0),
1278 tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, vbases
, 0),
1279 build_tree_list (NULL_TREE
, build_unary_op (ADDR_EXPR
, offsets
, 0))))))))))));
1280 return build_generic_desc (tdecl
, elems
);
1283 /* Build an initializer for a __i_desc node. */
1289 tree elems
, name_string
;
1292 name_string
= DECL_NAME (decl
);
1293 name_string
= combine_strings (build_string (IDENTIFIER_LENGTH (name_string
)+1, IDENTIFIER_POINTER (name_string
)));
1295 /* Now decide whether this ivar should cause it's type to get
1296 def'd or ref'd in this file. If the type we are looking at
1297 has a proxy definition, we look at the proxy (i.e., a
1298 `foo *' is equivalent to a `foo'). */
1299 taggr
= TREE_TYPE (decl
);
1301 if ((TREE_CODE (taggr
) == POINTER_TYPE
1302 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1303 && TYPE_VOLATILE (taggr
) == 0)
1304 taggr
= TREE_TYPE (taggr
);
1306 elems
= tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, name_string
, 0),
1307 tree_cons (NULL_TREE
, DECL_FIELD_BITPOS (decl
),
1308 build_tree_list (NULL_TREE
, build_t_desc (TREE_TYPE (decl
),
1309 ! IS_AGGR_TYPE (taggr
)))));
1310 taggr
= build (CONSTRUCTOR
, __i_desc_type_node
, NULL_TREE
, elems
);
1311 TREE_CONSTANT (taggr
) = 1;
1312 TREE_STATIC (taggr
) = 1;
1313 TREE_READONLY (taggr
) = 1;
1317 /* Build an initializer for a __m_desc node. */
1323 tree taggr
, elems
, name_string
;
1324 tree parm_count
, req_count
, vindex
, vcontext
;
1326 int p_count
, r_count
;
1327 tree parm_types
= NULL_TREE
;
1329 for (parms
= TYPE_ARG_TYPES (TREE_TYPE (decl
)), p_count
= 0, r_count
= 0;
1330 parms
!= NULL_TREE
; parms
= TREE_CHAIN (parms
), p_count
++)
1332 taggr
= TREE_VALUE (parms
);
1333 if ((TREE_CODE (taggr
) == POINTER_TYPE
1334 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1335 && TYPE_VOLATILE (taggr
) == 0)
1336 taggr
= TREE_TYPE (taggr
);
1338 parm_types
= tree_cons (NULL_TREE
, build_t_desc (TREE_VALUE (parms
),
1339 ! IS_AGGR_TYPE (taggr
)),
1341 if (TREE_PURPOSE (parms
) == NULL_TREE
)
1345 parm_types
= finish_table (NULL_TREE
, build_pointer_type (__t_desc_type_node
),
1346 nreverse (parm_types
), 0);
1347 parm_count
= build_int_2 (p_count
, 0);
1348 req_count
= build_int_2 (r_count
, 0);
1350 if (DECL_VINDEX (decl
))
1351 vindex
= DECL_VINDEX (decl
);
1353 vindex
= integer_zero_node
;
1354 if (DECL_CONTEXT (decl
)
1355 && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl
))) == 't')
1356 vcontext
= build_t_desc (DECL_CONTEXT (decl
), 0);
1358 vcontext
= integer_zero_node
;
1359 name_string
= DECL_NAME (decl
);
1360 if (name_string
== NULL
)
1361 name_string
= DECL_ASSEMBLER_NAME (decl
);
1362 name_string
= combine_strings (build_string (IDENTIFIER_LENGTH (name_string
)+1, IDENTIFIER_POINTER (name_string
)));
1364 /* Now decide whether the return type of this mvar
1365 should cause it's type to get def'd or ref'd in this file.
1366 If the type we are looking at has a proxy definition,
1367 we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */
1368 taggr
= TREE_TYPE (TREE_TYPE (decl
));
1370 if ((TREE_CODE (taggr
) == POINTER_TYPE
1371 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1372 && TYPE_VOLATILE (taggr
) == 0)
1373 taggr
= TREE_TYPE (taggr
);
1375 elems
= tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, name_string
, 0),
1376 tree_cons (NULL_TREE
, vindex
,
1377 tree_cons (NULL_TREE
, vcontext
,
1378 tree_cons (NULL_TREE
, build_t_desc (TREE_TYPE (TREE_TYPE (decl
)),
1379 ! IS_AGGR_TYPE (taggr
)),
1380 tree_cons (NULL_TREE
, build_c_cast (build_pointer_type (default_function_type
), build_unary_op (ADDR_EXPR
, decl
, 0)),
1381 tree_cons (NULL_TREE
, parm_count
,
1382 tree_cons (NULL_TREE
, req_count
,
1383 build_tree_list (NULL_TREE
, build_unary_op (ADDR_EXPR
, parm_types
, 0)))))))));
1385 taggr
= build (CONSTRUCTOR
, __m_desc_type_node
, NULL_TREE
, elems
);
1386 TREE_CONSTANT (taggr
) = 1;
1387 TREE_STATIC (taggr
) = 1;
1388 TREE_READONLY (taggr
) = 1;
1391 #endif /* dossier */