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. */
31 #define INT_TYPE_SIZE BITS_PER_WORD
34 extern tree
define_function ();
35 extern tree
build_t_desc_overload ();
36 extern struct obstack
*permanent_obstack
;
38 tree type_info_type_node
;
43 init_rtti_processing ()
45 type_info_type_node
= xref_tag
46 (class_type_node
, get_identifier ("type_info"), NULL_TREE
, 1);
47 tinfo_fn_id
= get_identifier ("__tf");
48 tinfo_fn_type
= build_function_type
49 (build_reference_type (build_type_variant (type_info_type_node
, 1, 0)),
53 /* Given a pointer to an object with at least one virtual table
54 pointer somewhere, return a pointer to a possible sub-object that
55 has a virtual table pointer in it that is the vtable parent for
59 build_headof_sub (exp
)
62 tree type
= TREE_TYPE (TREE_TYPE (exp
));
63 tree basetype
= CLASSTYPE_RTTI (type
);
64 tree binfo
= get_binfo (basetype
, type
, 0);
66 exp
= convert_pointer_to_real (binfo
, exp
);
70 /* Given the expression EXP of type `class *', return the head of the
71 object pointed to by EXP with type cv void*, if the class has any
72 virtual functions (TYPE_VIRTUAL_P), else just return the
79 tree type
= TREE_TYPE (exp
);
83 if (TREE_CODE (type
) != POINTER_TYPE
)
85 error ("`headof' applied to non-pointer type");
86 return error_mark_node
;
88 type
= TREE_TYPE (type
);
90 if (!TYPE_VIRTUAL_P (type
))
93 /* If we don't have rtti stuff, get to a sub-object that does. */
94 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp
))))
95 exp
= build_headof_sub (exp
);
97 /* We use this a couple of times below, protect it. */
98 exp
= save_expr (exp
);
100 aref
= build_vtbl_ref (build_indirect_ref (exp
, NULL_PTR
), integer_zero_node
);
102 if (flag_vtable_thunks
)
105 offset
= build_component_ref (aref
, delta_identifier
, NULL_TREE
, 0);
107 type
= build_type_variant (ptr_type_node
, TREE_READONLY (exp
),
108 TREE_THIS_VOLATILE (exp
));
109 return build (PLUS_EXPR
, type
, exp
,
110 convert (ptrdiff_type_node
, offset
));
113 /* Build a call to a generic entry point taking and returning void. */
119 tree d
= get_identifier (name
);
122 if (IDENTIFIER_GLOBAL_VALUE (d
))
123 d
= IDENTIFIER_GLOBAL_VALUE (d
);
126 push_obstacks (&permanent_obstack
, &permanent_obstack
);
128 type
= build_function_type (void_type_node
, void_list_node
);
129 d
= build_lang_decl (FUNCTION_DECL
, d
, type
);
130 DECL_EXTERNAL (d
) = 1;
132 DECL_ARTIFICIAL (d
) = 1;
133 pushdecl_top_level (d
);
134 make_function_rtl (d
);
135 assemble_external (d
);
140 return build_call (d
, void_type_node
, NULL_TREE
);
143 /* Get a bad_cast node for the program to throw...
145 See libstdc++/exception.cc for __throw_bad_cast */
150 return call_void_fn ("__throw_bad_cast");
156 return call_void_fn ("__throw_bad_typeid");
159 /* Return the type_info function associated with the expression EXP. If
160 EXP is a reference to a polymorphic class, return the dynamic type;
161 otherwise return the static type of the expression. */
164 get_tinfo_fn_dynamic (exp
)
169 if (exp
== error_mark_node
)
170 return error_mark_node
;
172 if (type_unknown_p (exp
))
174 error ("typeid of overloaded function");
175 return error_mark_node
;
178 type
= TREE_TYPE (exp
);
180 /* peel back references, so they match. */
181 if (TREE_CODE (type
) == REFERENCE_TYPE
)
182 type
= TREE_TYPE (type
);
184 /* Peel off cv qualifiers. */
185 type
= TYPE_MAIN_VARIANT (type
);
187 /* If exp is a reference to polymorphic type, get the real type_info. */
188 if (TYPE_VIRTUAL_P (type
) && ! resolves_to_fixed_type_p (exp
, 0))
190 /* build reference to type_info from vtable. */
194 warning ("taking dynamic typeid of object without -frtti");
196 /* If we don't have rtti stuff, get to a sub-object that does. */
197 if (! CLASSTYPE_VFIELDS (type
))
199 exp
= build_unary_op (ADDR_EXPR
, exp
, 0);
200 exp
= build_headof_sub (exp
);
201 exp
= build_indirect_ref (exp
, NULL_PTR
);
204 if (flag_vtable_thunks
)
205 t
= build_vfn_ref ((tree
*) 0, exp
, integer_one_node
);
207 t
= build_vfn_ref ((tree
*) 0, exp
, integer_zero_node
);
208 TREE_TYPE (t
) = build_pointer_type (tinfo_fn_type
);
212 /* otherwise return the type_info for the static type of the expr. */
213 return get_tinfo_fn (TYPE_MAIN_VARIANT (type
));
220 exp
= get_tinfo_fn_dynamic (exp
);
221 exp
= build_call (exp
, TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
222 return convert_from_reference (exp
);
229 tree cond
= NULL_TREE
;
230 tree type
= TREE_TYPE (tinfo_fn_type
);
233 if (processing_template_decl
)
234 return build_min_nt (TYPEID_EXPR
, exp
);
236 if (TREE_CODE (exp
) == INDIRECT_REF
237 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp
, 0))) == POINTER_TYPE
238 && TYPE_VIRTUAL_P (TREE_TYPE (exp
))
239 && ! resolves_to_fixed_type_p (exp
, &nonnull
)
242 exp
= stabilize_reference (exp
);
243 cond
= convert (boolean_type_node
, TREE_OPERAND (exp
, 0));
246 exp
= get_tinfo_fn_dynamic (exp
);
248 if (exp
== error_mark_node
)
249 return error_mark_node
;
251 exp
= build_call (exp
, type
, NULL_TREE
);
255 tree bad
= throw_bad_typeid ();
257 bad
= build_compound_expr
258 (tree_cons (NULL_TREE
, bad
, build_tree_list
259 (NULL_TREE
, convert (type
, integer_zero_node
))));
260 exp
= build (COND_EXPR
, type
, cond
, exp
, bad
);
263 return convert_from_reference (exp
);
270 tree tname
= build_overload_with_type (get_identifier ("__ti"), type
);
274 if (IDENTIFIER_GLOBAL_VALUE (tname
))
275 return IDENTIFIER_GLOBAL_VALUE (tname
);
277 /* Figure out how much space we need to allocate for the type_info object.
278 If our struct layout or the type_info classes are changed, this will
279 need to be modified. */
280 if (TYPE_VOLATILE (type
) || TYPE_READONLY (type
))
281 size
= 3 * POINTER_SIZE
+ INT_TYPE_SIZE
;
282 else if (TREE_CODE (type
) == POINTER_TYPE
283 && ! (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
284 || TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
))
285 size
= 3 * POINTER_SIZE
;
286 else if (IS_AGGR_TYPE (type
))
288 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
289 size
= 2 * POINTER_SIZE
;
290 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
292 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
293 size
= 3 * POINTER_SIZE
;
295 size
= 3 * POINTER_SIZE
+ INT_TYPE_SIZE
;
298 size
= 2 * POINTER_SIZE
;
300 push_obstacks (&permanent_obstack
, &permanent_obstack
);
302 /* The type for a character array of the appropriate size. */
303 arrtype
= build_cplus_array_type
304 (unsigned_char_type_node
,
305 build_index_type (size_int (size
/ BITS_PER_UNIT
- 1)));
307 tdecl
= build_decl (VAR_DECL
, tname
, arrtype
);
308 TREE_PUBLIC (tdecl
) = 1;
309 DECL_EXTERNAL (tdecl
) = 1;
310 DECL_ARTIFICIAL (tdecl
) = 1;
311 pushdecl_top_level (tdecl
);
312 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
326 if (TREE_CODE (type
) == OFFSET_TYPE
)
327 type
= TREE_TYPE (type
);
328 if (TREE_CODE (type
) == METHOD_TYPE
)
329 type
= build_function_type (TREE_TYPE (type
),
330 TREE_CHAIN (TYPE_ARG_TYPES (type
)));
332 name
= build_overload_with_type (tinfo_fn_id
, type
);
334 if (IDENTIFIER_GLOBAL_VALUE (name
))
335 return IDENTIFIER_GLOBAL_VALUE (name
);
337 push_obstacks (&permanent_obstack
, &permanent_obstack
);
339 d
= build_lang_decl (FUNCTION_DECL
, name
, tinfo_fn_type
);
340 DECL_EXTERNAL (d
) = 1;
342 DECL_ARTIFICIAL (d
) = 1;
343 DECL_NOT_REALLY_EXTERN (d
) = 1;
344 DECL_MUTABLE_P (d
) = 1;
345 TREE_TYPE (name
) = copy_to_permanent (type
);
346 pushdecl_top_level (d
);
347 make_function_rtl (d
);
348 assemble_external (d
);
349 mark_inline_for_output (d
);
351 import_export_decl (d
);
363 (get_tinfo_fn (type
), TREE_TYPE (tinfo_fn_type
), NULL_TREE
);
364 return convert_from_reference (t
);
367 /* Return the type_info object for TYPE, creating it if necessary. */
373 if (type
== error_mark_node
)
374 return error_mark_node
;
376 /* If the type of the type-id is a reference type, the result of the
377 typeid expression refers to a type_info object representing the
379 if (TREE_CODE (type
) == REFERENCE_TYPE
)
380 type
= TREE_TYPE (type
);
382 /* The top-level cv-qualifiers of the lvalue expression or the type-id
383 that is the operand of typeid are always ignored. */
384 type
= TYPE_MAIN_VARIANT (type
);
386 return get_typeid_1 (type
);
389 /* Check whether TEST is null before returning RESULT. If TEST is used in
390 RESULT, it must have previously had a save_expr applied to it. */
393 ifnonnull (test
, result
)
396 return build (COND_EXPR
, TREE_TYPE (result
),
397 build (EQ_EXPR
, boolean_type_node
, test
, integer_zero_node
),
398 convert (TREE_TYPE (result
), integer_zero_node
),
402 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
406 build_dynamic_cast (type
, expr
)
409 enum tree_code tc
= TREE_CODE (type
);
410 tree exprtype
= TREE_TYPE (expr
);
414 if (type
== error_mark_node
|| expr
== error_mark_node
)
415 return error_mark_node
;
417 if (processing_template_decl
)
419 tree t
= build_min (DYNAMIC_CAST_EXPR
, type
, expr
);
423 assert (exprtype
!= NULL_TREE
);
424 ec
= TREE_CODE (exprtype
);
429 if (ec
== REFERENCE_TYPE
)
431 expr
= convert_from_reference (expr
);
432 exprtype
= TREE_TYPE (expr
);
433 ec
= TREE_CODE (exprtype
);
435 if (ec
!= POINTER_TYPE
)
437 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
439 if (TYPE_SIZE (TREE_TYPE (exprtype
)) == NULL_TREE
)
441 if (TREE_READONLY (TREE_TYPE (exprtype
)) &&
442 ! TYPE_READONLY (TREE_TYPE (type
)))
444 if (TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
446 /* else fall through */
448 if (TREE_CODE (TREE_TYPE (type
)) != RECORD_TYPE
)
450 if (TYPE_SIZE (TREE_TYPE (type
)) == NULL_TREE
)
453 /* else fall through */
458 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
459 if (ec
== RECORD_TYPE
)
461 exprtype
= build_type_variant (exprtype
, TREE_READONLY (expr
),
462 TREE_THIS_VOLATILE (expr
));
463 exprtype
= build_reference_type (exprtype
);
464 expr
= convert_to_reference (exprtype
, expr
, CONV_IMPLICIT
,
465 LOOKUP_NORMAL
, NULL_TREE
);
469 if (tc
== REFERENCE_TYPE
)
471 if (ec
!= REFERENCE_TYPE
)
473 if (TREE_CODE (TREE_TYPE (exprtype
)) != RECORD_TYPE
)
475 if (TYPE_SIZE (TREE_TYPE (exprtype
)) == NULL_TREE
)
477 if (TREE_READONLY (TREE_TYPE (exprtype
)) &&
478 ! TYPE_READONLY (TREE_TYPE (type
)))
482 /* If *type is an unambiguous accessible base class of *exprtype,
483 convert statically. */
488 distance
= get_base_distance (TREE_TYPE (type
), TREE_TYPE (exprtype
), 1,
491 return build_vbase_path (PLUS_EXPR
, type
, expr
, path
, 0);
494 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
495 if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype
)))
498 /* if TYPE is `void *', return pointer to complete object. */
499 if (tc
== POINTER_TYPE
500 && TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == void_type_node
)
502 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
503 if (TREE_CODE (expr
) == ADDR_EXPR
504 && TREE_CODE (TREE_OPERAND (expr
, 0)) == VAR_DECL
505 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == RECORD_TYPE
)
506 return build1 (NOP_EXPR
, type
, expr
);
508 /* Since expr is used twice below, save it. */
509 expr
= save_expr (expr
);
511 expr1
= build_headof (expr
);
512 if (TREE_TYPE (expr1
) != type
)
513 expr1
= build1 (NOP_EXPR
, type
, expr1
);
514 return ifnonnull (expr
, expr1
);
519 tree result
, td1
, td2
, td3
, elems
, expr2
;
521 /* If we got here, we can't convert statically. Therefore,
522 dynamic_cast<D&>(b) (b an object) cannot succeed. */
523 if (ec
== REFERENCE_TYPE
)
525 if (TREE_CODE (expr
) == VAR_DECL
526 && TREE_CODE (TREE_TYPE (expr
)) == RECORD_TYPE
)
528 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
530 return throw_bad_cast ();
533 /* Ditto for dynamic_cast<D*>(&b). */
534 else if (TREE_CODE (expr
) == ADDR_EXPR
)
536 tree op
= TREE_OPERAND (expr
, 0);
537 if (TREE_CODE (op
) == VAR_DECL
538 && TREE_CODE (TREE_TYPE (op
)) == RECORD_TYPE
)
540 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
542 retval
= build_int_2 (0, 0);
543 TREE_TYPE (retval
) = type
;
548 /* Since expr is used twice below, save it. */
549 expr
= save_expr (expr
);
552 if (tc
== REFERENCE_TYPE
)
553 expr1
= build_unary_op (ADDR_EXPR
, expr1
, 0);
555 /* Build run-time conversion. */
556 expr2
= build_headof (expr1
);
558 if (ec
== POINTER_TYPE
)
559 td1
= get_tinfo_fn_dynamic (build_indirect_ref (expr
, NULL_PTR
));
561 td1
= get_tinfo_fn_dynamic (expr
);
562 td1
= decay_conversion (td1
);
564 td2
= decay_conversion
565 (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type
))));
566 td3
= decay_conversion
567 (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype
))));
570 (NULL_TREE
, td1
, tree_cons
571 (NULL_TREE
, td2
, tree_cons
572 (NULL_TREE
, build_int_2 (1, 0), tree_cons
573 (NULL_TREE
, expr2
, tree_cons
574 (NULL_TREE
, td3
, tree_cons
575 (NULL_TREE
, expr1
, NULL_TREE
))))));
577 dcast_fn
= get_identifier ("__dynamic_cast");
578 if (IDENTIFIER_GLOBAL_VALUE (dcast_fn
))
579 dcast_fn
= IDENTIFIER_GLOBAL_VALUE (dcast_fn
);
584 push_obstacks (&permanent_obstack
, &permanent_obstack
);
586 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
587 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
588 (NULL_TREE
, integer_type_node
, tree_cons
589 (NULL_TREE
, ptr_type_node
, tree_cons
590 (NULL_TREE
, TREE_TYPE (td1
), tree_cons
591 (NULL_TREE
, ptr_type_node
, void_list_node
))))));
592 tmp
= build_function_type (ptr_type_node
, tmp
);
593 dcast_fn
= build_lang_decl (FUNCTION_DECL
, dcast_fn
, tmp
);
594 DECL_EXTERNAL (dcast_fn
) = 1;
595 TREE_PUBLIC (dcast_fn
) = 1;
596 DECL_ARTIFICIAL (dcast_fn
) = 1;
597 pushdecl_top_level (dcast_fn
);
598 make_function_rtl (dcast_fn
);
599 assemble_external (dcast_fn
);
604 (dcast_fn
, TREE_TYPE (TREE_TYPE (dcast_fn
)), elems
);
606 if (tc
== REFERENCE_TYPE
)
608 expr1
= throw_bad_cast ();
609 expr1
= build_compound_expr
610 (tree_cons (NULL_TREE
, expr1
,
611 build_tree_list (NULL_TREE
, convert
612 (type
, integer_zero_node
))));
613 TREE_TYPE (expr1
) = type
;
614 result
= save_expr (result
);
615 return build (COND_EXPR
, type
, result
, result
, expr1
);
618 /* Now back to the type we want from a void*. */
619 result
= convert (type
, result
);
620 return ifnonnull (expr
, result
);
625 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
626 expr
, exprtype
, type
);
627 return error_mark_node
;
630 /* Build and initialize various sorts of descriptors. Every descriptor
631 node has a name associated with it (the name created by mangling).
632 For this reason, we use the identifier as our access to the __*_desc
633 nodes, instead of sticking them directly in the types. Otherwise we
634 would burden all built-in types (and pointer types) with slots that
635 we don't necessarily want to use.
637 For each descriptor we build, we build a variable that contains
638 the descriptor's information. When we need this info at runtime,
639 all we need is access to these variables.
641 Note: these constructors always return the address of the descriptor
642 info, since that is simplest for their mutual interaction. */
644 extern tree const_string_type_node
;
646 /* Build an initializer for a __si_type_info node. */
649 expand_si_desc (tdecl
, type
)
654 char *name
= build_overload_name (type
, 1, 1);
655 tree name_string
= combine_strings (build_string (strlen (name
), name
));
657 type
= BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0));
658 expand_expr_stmt (get_typeid_1 (type
));
659 t
= decay_conversion (get_tinfo_var (type
));
661 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
662 (NULL_TREE
, decay_conversion (name_string
), tree_cons
663 (NULL_TREE
, t
, NULL_TREE
)));
665 fn
= get_identifier ("__rtti_si");
666 if (IDENTIFIER_GLOBAL_VALUE (fn
))
667 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
671 push_obstacks (&permanent_obstack
, &permanent_obstack
);
673 (NULL_TREE
, ptr_type_node
, tree_cons
674 (NULL_TREE
, const_string_type_node
, tree_cons
675 (NULL_TREE
, build_pointer_type (type_info_type_node
),
677 tmp
= build_function_type (void_type_node
, tmp
);
679 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
680 DECL_EXTERNAL (fn
) = 1;
681 TREE_PUBLIC (fn
) = 1;
682 DECL_ARTIFICIAL (fn
) = 1;
683 pushdecl_top_level (fn
);
684 make_function_rtl (fn
);
685 assemble_external (fn
);
689 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
690 expand_expr_stmt (fn
);
693 /* Build an initializer for a __class_type_info node. */
696 expand_class_desc (tdecl
, type
)
704 int i
= CLASSTYPE_N_BASECLASSES (type
);
706 tree binfos
= TYPE_BINFO_BASETYPES (type
);
708 /* See code below that used these. */
709 tree vb
= CLASSTYPE_VBASECLASSES (type
);
712 tree base
, elems
, access
, offset
, isvir
;
713 tree elt
, elts
= NULL_TREE
;
714 static tree base_info_type_node
;
716 if (base_info_type_node
== NULL_TREE
)
720 /* A reasonably close approximation of __class_type_info::base_info */
722 push_obstacks (&permanent_obstack
, &permanent_obstack
);
723 base_info_type_node
= make_lang_type (RECORD_TYPE
);
725 /* Actually const __user_type_info * */
726 fields
[0] = build_lang_field_decl
727 (FIELD_DECL
, NULL_TREE
,
728 build_pointer_type (build_type_variant (type_info_type_node
, 1, 0)));
729 fields
[1] = build_lang_field_decl
730 (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
731 DECL_BIT_FIELD (fields
[1]) = 1;
732 DECL_FIELD_SIZE (fields
[1]) = 29;
734 fields
[2] = build_lang_field_decl
735 (FIELD_DECL
, NULL_TREE
, boolean_type_node
);
736 DECL_BIT_FIELD (fields
[2]) = 1;
737 DECL_FIELD_SIZE (fields
[2]) = 1;
739 /* Actually enum access */
740 fields
[3] = build_lang_field_decl
741 (FIELD_DECL
, NULL_TREE
, integer_type_node
);
742 DECL_BIT_FIELD (fields
[3]) = 1;
743 DECL_FIELD_SIZE (fields
[3]) = 2;
745 finish_builtin_type (base_info_type_node
, "__base_info", fields
,
752 tree binfo
= TREE_VEC_ELT (binfos
, i
);
754 expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo
)));
755 base
= decay_conversion (get_tinfo_var (BINFO_TYPE (binfo
)));
757 if (TREE_VIA_VIRTUAL (binfo
))
759 tree t
= BINFO_TYPE (binfo
);
763 name
= (char *) alloca (TYPE_NAME_LENGTH (t
)+sizeof (VBASE_NAME
)+1);
764 sprintf (name
, VBASE_NAME_FORMAT
, TYPE_NAME_STRING (t
));
765 field
= lookup_field (type
, get_identifier (name
), 0, 0);
766 offset
= size_binop (FLOOR_DIV_EXPR
,
767 DECL_FIELD_BITPOS (field
), size_int (BITS_PER_UNIT
));
770 offset
= BINFO_OFFSET (binfo
);
772 if (TREE_VIA_PUBLIC (binfo
))
773 access
= access_public_node
;
774 else if (TREE_VIA_PROTECTED (binfo
))
775 access
= access_protected_node
;
777 access
= access_private_node
;
778 if (TREE_VIA_VIRTUAL (binfo
))
779 isvir
= boolean_true_node
;
781 isvir
= boolean_false_node
;
784 (CONSTRUCTOR
, base_info_type_node
, NULL_TREE
, tree_cons
785 (NULL_TREE
, base
, tree_cons
786 (NULL_TREE
, offset
, tree_cons
787 (NULL_TREE
, isvir
, tree_cons
788 (NULL_TREE
, access
, NULL_TREE
)))));
789 TREE_HAS_CONSTRUCTOR (elt
) = TREE_CONSTANT (elt
) = TREE_STATIC (elt
) = 1;
790 elts
= tree_cons (NULL_TREE
, elt
, elts
);
798 access
= access_public_node
;
801 b
= TREE_VEC_ELT (binfos
, i
);
802 if (BINFO_TYPE (vb
) == BINFO_TYPE (b
) && TREE_VIA_VIRTUAL (b
))
804 if (TREE_VIA_PUBLIC (b
))
805 access
= access_public_node
;
806 else if (TREE_VIA_PROTECTED (b
))
807 access
= access_protected_node
;
809 access
= access_private_node
;
813 base
= build_t_desc (BINFO_TYPE (vb
), 1);
814 offset
= BINFO_OFFSET (vb
);
815 isvir
= build_int_2 (1, 0);
817 base_list
= tree_cons (NULL_TREE
, base
, base_list
);
818 isvir_list
= tree_cons (NULL_TREE
, isvir
, isvir_list
);
819 acc_list
= tree_cons (NULL_TREE
, access
, acc_list
);
820 off_list
= tree_cons (NULL_TREE
, offset
, off_list
);
823 vb
= TREE_CHAIN (vb
);
827 name
= build_overload_name (type
, 1, 1);
828 name_string
= combine_strings (build_string (strlen (name
), name
));
831 tree arrtype
= build_array_type (base_info_type_node
, NULL_TREE
);
832 elts
= build (CONSTRUCTOR
, arrtype
, NULL_TREE
, elts
);
833 TREE_HAS_CONSTRUCTOR (elts
) = TREE_CONSTANT (elts
) =
834 TREE_STATIC (elts
) = 1;
835 complete_array_type (arrtype
, elts
, 1);
839 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
840 (NULL_TREE
, decay_conversion (name_string
), tree_cons
841 (NULL_TREE
, decay_conversion (elts
), tree_cons
842 (NULL_TREE
, build_int_2 (base_cnt
, 0), NULL_TREE
))));
844 fn
= get_identifier ("__rtti_class");
845 if (IDENTIFIER_GLOBAL_VALUE (fn
))
846 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
849 push_obstacks (&permanent_obstack
, &permanent_obstack
);
851 (NULL_TREE
, ptr_type_node
, tree_cons
852 (NULL_TREE
, const_string_type_node
, tree_cons
853 (NULL_TREE
, build_pointer_type (base_info_type_node
), tree_cons
854 (NULL_TREE
, sizetype
, void_list_node
))));
855 tmp
= build_function_type (void_type_node
, tmp
);
857 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
858 DECL_EXTERNAL (fn
) = 1;
859 TREE_PUBLIC (fn
) = 1;
860 DECL_ARTIFICIAL (fn
) = 1;
861 pushdecl_top_level (fn
);
862 make_function_rtl (fn
);
863 assemble_external (fn
);
867 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
868 expand_expr_stmt (fn
);
871 /* Build an initializer for a __pointer_type_info node. */
874 expand_ptr_desc (tdecl
, type
)
879 char *name
= build_overload_name (type
, 1, 1);
880 tree name_string
= combine_strings (build_string (strlen (name
), name
));
882 type
= TREE_TYPE (type
);
883 expand_expr_stmt (get_typeid_1 (type
));
884 t
= decay_conversion (get_tinfo_var (type
));
886 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
887 (NULL_TREE
, decay_conversion (name_string
), tree_cons
888 (NULL_TREE
, t
, NULL_TREE
)));
890 fn
= get_identifier ("__rtti_ptr");
891 if (IDENTIFIER_GLOBAL_VALUE (fn
))
892 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
896 push_obstacks (&permanent_obstack
, &permanent_obstack
);
898 (NULL_TREE
, ptr_type_node
, tree_cons
899 (NULL_TREE
, const_string_type_node
, tree_cons
900 (NULL_TREE
, build_pointer_type (type_info_type_node
),
902 tmp
= build_function_type (void_type_node
, tmp
);
904 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
905 DECL_EXTERNAL (fn
) = 1;
906 TREE_PUBLIC (fn
) = 1;
907 DECL_ARTIFICIAL (fn
) = 1;
908 pushdecl_top_level (fn
);
909 make_function_rtl (fn
);
910 assemble_external (fn
);
914 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
915 expand_expr_stmt (fn
);
918 /* Build an initializer for a __attr_type_info node. */
921 expand_attr_desc (tdecl
, type
)
926 char *name
= build_overload_name (type
, 1, 1);
927 tree name_string
= combine_strings (build_string (strlen (name
), name
));
928 tree attrval
= build_int_2
929 (TYPE_READONLY (type
) | TYPE_VOLATILE (type
) * 2, 0);
931 expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type
)));
932 t
= decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type
)));
934 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
935 (NULL_TREE
, decay_conversion (name_string
), tree_cons
936 (NULL_TREE
, attrval
, tree_cons (NULL_TREE
, t
, NULL_TREE
))));
938 fn
= get_identifier ("__rtti_attr");
939 if (IDENTIFIER_GLOBAL_VALUE (fn
))
940 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
944 push_obstacks (&permanent_obstack
, &permanent_obstack
);
946 (NULL_TREE
, ptr_type_node
, tree_cons
947 (NULL_TREE
, const_string_type_node
, tree_cons
948 (NULL_TREE
, integer_type_node
, tree_cons
949 (NULL_TREE
, build_pointer_type (type_info_type_node
),
951 tmp
= build_function_type (void_type_node
, tmp
);
953 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
954 DECL_EXTERNAL (fn
) = 1;
955 TREE_PUBLIC (fn
) = 1;
956 DECL_ARTIFICIAL (fn
) = 1;
957 pushdecl_top_level (fn
);
958 make_function_rtl (fn
);
959 assemble_external (fn
);
963 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
964 expand_expr_stmt (fn
);
967 /* Build an initializer for a type_info node that just has a name. */
970 expand_generic_desc (tdecl
, type
, fnname
)
975 char *name
= build_overload_name (type
, 1, 1);
976 tree name_string
= combine_strings (build_string (strlen (name
), name
));
977 tree elems
= tree_cons
978 (NULL_TREE
, decay_conversion (tdecl
), tree_cons
979 (NULL_TREE
, decay_conversion (name_string
), NULL_TREE
));
981 tree fn
= get_identifier (fnname
);
982 if (IDENTIFIER_GLOBAL_VALUE (fn
))
983 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
987 push_obstacks (&permanent_obstack
, &permanent_obstack
);
989 (NULL_TREE
, ptr_type_node
, tree_cons
990 (NULL_TREE
, const_string_type_node
, void_list_node
));
991 tmp
= build_function_type (void_type_node
, tmp
);
993 fn
= build_lang_decl (FUNCTION_DECL
, fn
, tmp
);
994 DECL_EXTERNAL (fn
) = 1;
995 TREE_PUBLIC (fn
) = 1;
996 DECL_ARTIFICIAL (fn
) = 1;
997 pushdecl_top_level (fn
);
998 make_function_rtl (fn
);
999 assemble_external (fn
);
1003 fn
= build_call (fn
, TREE_TYPE (TREE_TYPE (fn
)), elems
);
1004 expand_expr_stmt (fn
);
1007 /* Generate the code for a type_info initialization function.
1008 Note that we take advantage of the passage
1010 5.2.7 Type identification [expr.typeid]
1012 Whether or not the destructor is called for the type_info object at the
1013 end of the program is unspecified.
1015 and don't bother to arrange for these objects to be destroyed. It
1016 doesn't matter, anyway, since the destructors don't do anything.
1018 This must only be called from toplevel (i.e. from finish_file)! */
1021 synthesize_tinfo_fn (fndecl
)
1024 tree type
= TREE_TYPE (DECL_NAME (fndecl
));
1027 tree tdecl
= get_tinfo_var (type
);
1028 DECL_EXTERNAL (tdecl
) = 0;
1029 TREE_STATIC (tdecl
) = 1;
1030 DECL_COMMON (tdecl
) = 1;
1031 TREE_USED (tdecl
) = 1;
1032 DECL_ALIGN (tdecl
) = TYPE_ALIGN (ptr_type_node
);
1033 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
1035 start_function (NULL_TREE
, fndecl
, NULL_TREE
, 1);
1036 store_parm_decls ();
1040 /* If the first word of the array (the vtable) is non-zero, we've already
1041 initialized the object, so don't do it again. */
1042 addr
= decay_conversion (tdecl
);
1043 tmp
= convert (build_pointer_type (ptr_type_node
), addr
);
1044 tmp
= build_indirect_ref (tmp
, 0);
1045 tmp
= build_binary_op (EQ_EXPR
, tmp
, integer_zero_node
, 1);
1046 expand_start_cond (tmp
, 0);
1048 if (TREE_CODE (type
) == FUNCTION_TYPE
)
1049 expand_generic_desc (tdecl
, type
, "__rtti_func");
1050 else if (TREE_CODE (type
) == ARRAY_TYPE
)
1051 expand_generic_desc (tdecl
, type
, "__rtti_array");
1052 else if (TYPE_VOLATILE (type
) || TYPE_READONLY (type
))
1053 expand_attr_desc (tdecl
, type
);
1054 else if (TREE_CODE (type
) == POINTER_TYPE
)
1056 if (TREE_CODE (TREE_TYPE (type
)) == OFFSET_TYPE
)
1057 expand_generic_desc (tdecl
, type
, "__rtti_ptmd");
1058 else if (TREE_CODE (TREE_TYPE (type
)) == METHOD_TYPE
)
1059 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1061 expand_ptr_desc (tdecl
, type
);
1063 else if (TYPE_PTRMEMFUNC_P (type
))
1064 expand_generic_desc (tdecl
, type
, "__rtti_ptmf");
1065 else if (IS_AGGR_TYPE (type
))
1067 if (CLASSTYPE_N_BASECLASSES (type
) == 0)
1068 expand_generic_desc (tdecl
, type
, "__rtti_user");
1069 else if (! TYPE_USES_COMPLEX_INHERITANCE (type
)
1071 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type
), 0))))
1072 expand_si_desc (tdecl
, type
);
1074 expand_class_desc (tdecl
, type
);
1076 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
1077 expand_generic_desc (tdecl
, type
, "__rtti_user");
1079 my_friendly_abort (252);
1083 /* OK, now return the type_info object. */
1084 tmp
= convert (build_pointer_type (type_info_type_node
), addr
);
1085 tmp
= build_indirect_ref (tmp
, 0);
1086 c_expand_return (tmp
);
1087 finish_function (lineno
, 0, 0);
1091 /* This is the old dossier type descriptor generation code, it's much
1092 more extended than rtti. It's reserved for later use. */
1093 /* Build an initializer for a __t_desc node. So that we can take advantage
1094 of recursion, we accept NULL for TYPE.
1095 DEFINITION is greater than zero iff we must define the type descriptor
1096 (as opposed to merely referencing it). 1 means treat according to
1097 #pragma interface/#pragma implementation rules. 2 means define as
1098 global and public, no matter what. */
1101 build_t_desc (type
, definition
)
1106 tree tname
, name_string
;
1108 tree parents
, vbases
, offsets
, ivars
, methods
, target_type
;
1109 int method_count
= 0, field_count
= 0;
1111 if (type
== NULL_TREE
)
1114 tname
= build_t_desc_overload (type
);
1115 if (IDENTIFIER_AS_DESC (tname
)
1116 && (!definition
|| TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname
))))
1117 return IDENTIFIER_AS_DESC (tname
);
1119 tdecl
= lookup_name (tname
, 0);
1120 if (tdecl
== NULL_TREE
)
1122 tdecl
= build_decl (VAR_DECL
, tname
, __t_desc_type_node
);
1123 DECL_EXTERNAL (tdecl
) = 1;
1124 TREE_PUBLIC (tdecl
) = 1;
1125 tdecl
= pushdecl_top_level (tdecl
);
1127 /* If we previously defined it, return the defined result. */
1128 else if (definition
&& DECL_INITIAL (tdecl
))
1129 return IDENTIFIER_AS_DESC (tname
);
1134 /* Let T* and T& be written only when T is written (if T is an aggr).
1135 We do this for const, but not for volatile, since volatile
1136 is rare and const is not. */
1137 if (!TYPE_VOLATILE (taggr
)
1138 && (TREE_CODE (taggr
) == POINTER_TYPE
1139 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1140 && IS_AGGR_TYPE (TREE_TYPE (taggr
)))
1141 taggr
= TREE_TYPE (taggr
);
1143 /* If we know that we don't need to write out this type's
1144 vtable, then don't write out it's dossier. Somebody
1145 else will take care of that. */
1146 if (IS_AGGR_TYPE (taggr
) && CLASSTYPE_VFIELD (taggr
))
1148 if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr
))
1150 TREE_PUBLIC (tdecl
) = ! CLASSTYPE_INTERFACE_ONLY (taggr
)
1151 && CLASSTYPE_INTERFACE_KNOWN (taggr
);
1152 DECL_EXTERNAL (tdecl
) = 0;
1156 if (write_virtuals
!= 0)
1157 TREE_PUBLIC (tdecl
) = 1;
1162 DECL_EXTERNAL (tdecl
) = 0;
1163 TREE_PUBLIC (tdecl
) = (definition
> 1);
1166 SET_IDENTIFIER_AS_DESC (tname
, build_unary_op (ADDR_EXPR
, tdecl
, 0));
1168 if (!definition
|| DECL_EXTERNAL (tdecl
))
1171 cp_finish_decl (tdecl
, NULL_TREE
, NULL_TREE
, 0, 0);
1172 return IDENTIFIER_AS_DESC (tname
);
1175 /* Show that we are defining the t_desc for this type. */
1176 DECL_INITIAL (tdecl
) = error_mark_node
;
1178 parents
= build_tree_list (NULL_TREE
, integer_zero_node
);
1179 vbases
= build_tree_list (NULL_TREE
, integer_zero_node
);
1180 offsets
= build_tree_list (NULL_TREE
, integer_zero_node
);
1181 methods
= NULL_TREE
;
1184 if (TYPE_LANG_SPECIFIC (type
))
1186 int i
= CLASSTYPE_N_BASECLASSES (type
);
1187 tree method_vec
= CLASSTYPE_METHOD_VEC (type
);
1189 tree binfos
= TYPE_BINFO_BASETYPES (type
);
1190 tree vb
= CLASSTYPE_VBASECLASSES (type
);
1193 parents
= tree_cons (NULL_TREE
, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos
, i
)), 0), parents
);
1197 vbases
= tree_cons (NULL_TREE
, build_t_desc (BINFO_TYPE (vb
), 0), vbases
);
1198 offsets
= tree_cons (NULL_TREE
, BINFO_OFFSET (vb
), offsets
);
1199 vb
= TREE_CHAIN (vb
);
1203 for (meth
= TREE_VEC_END (method_vec
),
1204 end
= &TREE_VEC_ELT (method_vec
, 0); meth
-- != end
; )
1207 methods
= tree_cons (NULL_TREE
, build_m_desc (*meth
), methods
);
1212 if (IS_AGGR_TYPE (type
))
1214 for (fields
= TYPE_FIELDS (type
); fields
; fields
= TREE_CHAIN (fields
))
1215 if (TREE_CODE (fields
) == FIELD_DECL
1216 || TREE_CODE (fields
) == VAR_DECL
)
1218 ivars
= tree_cons (NULL_TREE
, build_i_desc (fields
), ivars
);
1221 ivars
= nreverse (ivars
);
1224 parents
= finish_table (NULL_TREE
, build_pointer_type (__t_desc_type_node
), parents
, 0);
1225 vbases
= finish_table (NULL_TREE
, build_pointer_type (__t_desc_type_node
), vbases
, 0);
1226 offsets
= finish_table (NULL_TREE
, integer_type_node
, offsets
, 0);
1227 if (methods
== NULL_TREE
)
1228 methods
= null_pointer_node
;
1230 methods
= build_unary_op (ADDR_EXPR
,
1231 finish_table (NULL_TREE
, __m_desc_type_node
, methods
, 0),
1233 if (ivars
== NULL_TREE
)
1234 ivars
= null_pointer_node
;
1236 ivars
= build_unary_op (ADDR_EXPR
,
1237 finish_table (NULL_TREE
, __i_desc_type_node
, ivars
, 0),
1239 if (TREE_TYPE (type
))
1240 target_type
= build_t_desc (TREE_TYPE (type
), definition
);
1242 target_type
= integer_zero_node
;
1244 name_string
= combine_strings (build_string (IDENTIFIER_LENGTH (tname
)+1, IDENTIFIER_POINTER (tname
)));
1246 elems
= tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, name_string
, 0),
1247 tree_cons (NULL_TREE
,
1248 TYPE_SIZE(type
)? size_in_bytes(type
) : integer_zero_node
,
1249 /* really should use bitfield initialization here. */
1250 tree_cons (NULL_TREE
, integer_zero_node
,
1251 tree_cons (NULL_TREE
, target_type
,
1252 tree_cons (NULL_TREE
, build_int_2 (field_count
, 2),
1253 tree_cons (NULL_TREE
, build_int_2 (method_count
, 2),
1254 tree_cons (NULL_TREE
, ivars
,
1255 tree_cons (NULL_TREE
, methods
,
1256 tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, parents
, 0),
1257 tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, vbases
, 0),
1258 build_tree_list (NULL_TREE
, build_unary_op (ADDR_EXPR
, offsets
, 0))))))))))));
1259 return build_generic_desc (tdecl
, elems
);
1262 /* Build an initializer for a __i_desc node. */
1268 tree elems
, name_string
;
1271 name_string
= DECL_NAME (decl
);
1272 name_string
= combine_strings (build_string (IDENTIFIER_LENGTH (name_string
)+1, IDENTIFIER_POINTER (name_string
)));
1274 /* Now decide whether this ivar should cause it's type to get
1275 def'd or ref'd in this file. If the type we are looking at
1276 has a proxy definition, we look at the proxy (i.e., a
1277 `foo *' is equivalent to a `foo'). */
1278 taggr
= TREE_TYPE (decl
);
1280 if ((TREE_CODE (taggr
) == POINTER_TYPE
1281 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1282 && TYPE_VOLATILE (taggr
) == 0)
1283 taggr
= TREE_TYPE (taggr
);
1285 elems
= tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, name_string
, 0),
1286 tree_cons (NULL_TREE
, DECL_FIELD_BITPOS (decl
),
1287 build_tree_list (NULL_TREE
, build_t_desc (TREE_TYPE (decl
),
1288 ! IS_AGGR_TYPE (taggr
)))));
1289 taggr
= build (CONSTRUCTOR
, __i_desc_type_node
, NULL_TREE
, elems
);
1290 TREE_CONSTANT (taggr
) = 1;
1291 TREE_STATIC (taggr
) = 1;
1292 TREE_READONLY (taggr
) = 1;
1296 /* Build an initializer for a __m_desc node. */
1302 tree taggr
, elems
, name_string
;
1303 tree parm_count
, req_count
, vindex
, vcontext
;
1305 int p_count
, r_count
;
1306 tree parm_types
= NULL_TREE
;
1308 for (parms
= TYPE_ARG_TYPES (TREE_TYPE (decl
)), p_count
= 0, r_count
= 0;
1309 parms
!= NULL_TREE
; parms
= TREE_CHAIN (parms
), p_count
++)
1311 taggr
= TREE_VALUE (parms
);
1312 if ((TREE_CODE (taggr
) == POINTER_TYPE
1313 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1314 && TYPE_VOLATILE (taggr
) == 0)
1315 taggr
= TREE_TYPE (taggr
);
1317 parm_types
= tree_cons (NULL_TREE
, build_t_desc (TREE_VALUE (parms
),
1318 ! IS_AGGR_TYPE (taggr
)),
1320 if (TREE_PURPOSE (parms
) == NULL_TREE
)
1324 parm_types
= finish_table (NULL_TREE
, build_pointer_type (__t_desc_type_node
),
1325 nreverse (parm_types
), 0);
1326 parm_count
= build_int_2 (p_count
, 0);
1327 req_count
= build_int_2 (r_count
, 0);
1329 if (DECL_VINDEX (decl
))
1330 vindex
= DECL_VINDEX (decl
);
1332 vindex
= integer_zero_node
;
1333 if (DECL_CONTEXT (decl
)
1334 && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl
))) == 't')
1335 vcontext
= build_t_desc (DECL_CONTEXT (decl
), 0);
1337 vcontext
= integer_zero_node
;
1338 name_string
= DECL_NAME (decl
);
1339 if (name_string
== NULL
)
1340 name_string
= DECL_ASSEMBLER_NAME (decl
);
1341 name_string
= combine_strings (build_string (IDENTIFIER_LENGTH (name_string
)+1, IDENTIFIER_POINTER (name_string
)));
1343 /* Now decide whether the return type of this mvar
1344 should cause it's type to get def'd or ref'd in this file.
1345 If the type we are looking at has a proxy definition,
1346 we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */
1347 taggr
= TREE_TYPE (TREE_TYPE (decl
));
1349 if ((TREE_CODE (taggr
) == POINTER_TYPE
1350 || TREE_CODE (taggr
) == REFERENCE_TYPE
)
1351 && TYPE_VOLATILE (taggr
) == 0)
1352 taggr
= TREE_TYPE (taggr
);
1354 elems
= tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, name_string
, 0),
1355 tree_cons (NULL_TREE
, vindex
,
1356 tree_cons (NULL_TREE
, vcontext
,
1357 tree_cons (NULL_TREE
, build_t_desc (TREE_TYPE (TREE_TYPE (decl
)),
1358 ! IS_AGGR_TYPE (taggr
)),
1359 tree_cons (NULL_TREE
, build_c_cast (build_pointer_type (default_function_type
), build_unary_op (ADDR_EXPR
, decl
, 0)),
1360 tree_cons (NULL_TREE
, parm_count
,
1361 tree_cons (NULL_TREE
, req_count
,
1362 build_tree_list (NULL_TREE
, build_unary_op (ADDR_EXPR
, parm_types
, 0)))))))));
1364 taggr
= build (CONSTRUCTOR
, __m_desc_type_node
, NULL_TREE
, elems
);
1365 TREE_CONSTANT (taggr
) = 1;
1366 TREE_STATIC (taggr
) = 1;
1367 TREE_READONLY (taggr
) = 1;
1370 #endif /* dossier */