cfns.gperf (hash, [...]): Prototype.
[gcc.git] / gcc / cp / rtti.c
1 /* RunTime Type Identification
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
4 Mostly written by Jason Merrill (jason@cygnus.com).
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "tree.h"
27 #include "cp-tree.h"
28 #include "flags.h"
29 #include "output.h"
30 #include "assert.h"
31 #include "toplev.h"
32
33 #ifndef INT_TYPE_SIZE
34 #define INT_TYPE_SIZE BITS_PER_WORD
35 #endif
36
37 /* Accessors for the type_info objects. We need to remember several things
38 about each of the type_info types. The global tree nodes such as
39 bltn_desc_type_node are TREE_LISTs, and these macros are used to access
40 the required information. */
41 /* The RECORD_TYPE of a type_info derived class. */
42 #define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
43 /* The VAR_DECL of the vtable for the type_info derived class. */
44 #define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
45
46 extern struct obstack permanent_obstack;
47
48 static tree build_headof_sub PARAMS((tree));
49 static tree build_headof PARAMS((tree));
50 static tree get_tinfo_var PARAMS((tree));
51 static tree ifnonnull PARAMS((tree, tree));
52 static tree tinfo_name PARAMS((tree));
53 static tree get_base_offset PARAMS((tree, tree));
54 static tree build_dynamic_cast_1 PARAMS((tree, tree));
55 static void expand_si_desc PARAMS((tree, tree));
56 static void expand_class_desc PARAMS((tree, tree));
57 static void expand_attr_desc PARAMS((tree, tree));
58 static void expand_ptr_desc PARAMS((tree, tree));
59 static void expand_generic_desc PARAMS((tree, tree, const char *));
60 static tree throw_bad_cast PARAMS((void));
61 static tree throw_bad_typeid PARAMS((void));
62 static tree get_tinfo_decl_dynamic PARAMS((tree));
63 static tree tinfo_from_decl PARAMS((tree));
64 static int qualifier_flags PARAMS((tree));
65 static tree tinfo_base_init PARAMS((tree, tree));
66 static tree generic_initializer PARAMS((tree, tree));
67 static tree ptr_initializer PARAMS((tree, tree));
68 static tree ptmd_initializer PARAMS((tree, tree));
69 static int class_hint_flags PARAMS((tree));
70 static tree class_initializer PARAMS((tree, tree, tree));
71 static tree synthesize_tinfo_var PARAMS((tree, tree));
72 static tree create_real_tinfo_var PARAMS((tree, tree, tree));
73 static tree create_pseudo_type_info PARAMS((const char *, int, ...));
74 static tree get_vmi_pseudo_type_info PARAMS((int));
75 static void create_tinfo_types PARAMS((void));
76
77 static int doing_runtime = 0;
78 \f
79 void
80 init_rtti_processing ()
81 {
82 if (flag_honor_std)
83 push_namespace (get_identifier ("std"));
84 type_info_type_node = xref_tag
85 (class_type_node, get_identifier ("type_info"), 1);
86 if (flag_honor_std)
87 pop_namespace ();
88 if (!new_abi_rtti_p ())
89 {
90 tinfo_decl_id = get_identifier ("__tf");
91 tinfo_decl_type = build_function_type
92 (build_reference_type
93 (build_qualified_type
94 (type_info_type_node, TYPE_QUAL_CONST)),
95 void_list_node);
96 }
97 else
98 {
99 tinfo_decl_id = get_identifier ("__ti");
100 tinfo_decl_type = build_qualified_type
101 (type_info_type_node, TYPE_QUAL_CONST);
102 }
103 tinfo_var_id = get_identifier ("__ti");
104 }
105
106 /* Given a pointer to an object with at least one virtual table
107 pointer somewhere, return a pointer to a possible sub-object that
108 has a virtual table pointer in it that is the vtable parent for
109 that sub-object. */
110
111 static tree
112 build_headof_sub (exp)
113 tree exp;
114 {
115 tree type = TREE_TYPE (TREE_TYPE (exp));
116 tree basetype = CLASSTYPE_RTTI (type);
117 tree binfo = get_binfo (basetype, type, 0);
118
119 exp = convert_pointer_to_real (binfo, exp);
120 return exp;
121 }
122
123 /* Given the expression EXP of type `class *', return the head of the
124 object pointed to by EXP with type cv void*, if the class has any
125 virtual functions (TYPE_POLYMORPHIC_P), else just return the
126 expression. */
127
128 static tree
129 build_headof (exp)
130 tree exp;
131 {
132 tree type = TREE_TYPE (exp);
133 tree aref;
134 tree offset;
135 tree index;
136
137 my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
138 type = TREE_TYPE (type);
139
140 if (!TYPE_POLYMORPHIC_P (type))
141 return exp;
142 if (CLASSTYPE_COM_INTERFACE (type))
143 {
144 cp_error ("RTTI not supported for COM interface type `%T'", type);
145 return error_mark_node;
146 }
147
148 /* If we don't have rtti stuff, get to a sub-object that does. */
149 if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
150 exp = build_headof_sub (exp);
151
152 /* We use this a couple of times below, protect it. */
153 exp = save_expr (exp);
154
155 /* Under the new ABI, the offset-to-top field is at index -2 from
156 the vptr. */
157 if (new_abi_rtti_p ())
158 index = build_int_2 (-2, -1);
159 /* But under the old ABI, it is at offset zero. */
160 else
161 index = integer_zero_node;
162
163 aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), index);
164
165 if (flag_vtable_thunks)
166 offset = aref;
167 else
168 offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
169
170 type = build_qualified_type (ptr_type_node,
171 CP_TYPE_QUALS (TREE_TYPE (exp)));
172 return build (PLUS_EXPR, type, exp,
173 cp_convert (ptrdiff_type_node, offset));
174 }
175
176 /* Get a bad_cast node for the program to throw...
177
178 See libstdc++/exception.cc for __throw_bad_cast */
179
180 static tree
181 throw_bad_cast ()
182 {
183 tree fn = get_identifier ("__throw_bad_cast");
184 if (IDENTIFIER_GLOBAL_VALUE (fn))
185 fn = IDENTIFIER_GLOBAL_VALUE (fn);
186 else
187 fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
188 void_list_node));
189
190 return build_call (fn, NULL_TREE);
191 }
192
193 static tree
194 throw_bad_typeid ()
195 {
196 tree fn = get_identifier ("__throw_bad_typeid");
197 if (IDENTIFIER_GLOBAL_VALUE (fn))
198 fn = IDENTIFIER_GLOBAL_VALUE (fn);
199 else
200 {
201 tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
202 t = build_function_type (build_reference_type (t), void_list_node);
203 fn = push_throw_library_fn (fn, t);
204 }
205
206 return build_call (fn, NULL_TREE);
207 }
208 \f
209 /* Return a pointer to type_info function associated with the expression EXP.
210 If EXP is a reference to a polymorphic class, return the dynamic type;
211 otherwise return the static type of the expression. */
212
213 static tree
214 get_tinfo_decl_dynamic (exp)
215 tree exp;
216 {
217 tree type;
218
219 if (exp == error_mark_node)
220 return error_mark_node;
221
222 type = TREE_TYPE (exp);
223
224 /* peel back references, so they match. */
225 if (TREE_CODE (type) == REFERENCE_TYPE)
226 type = TREE_TYPE (type);
227
228 /* Peel off cv qualifiers. */
229 type = TYPE_MAIN_VARIANT (type);
230
231 if (type != void_type_node)
232 type = complete_type_or_else (type, exp);
233
234 if (!type)
235 return error_mark_node;
236
237 /* If exp is a reference to polymorphic type, get the real type_info. */
238 if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
239 {
240 /* build reference to type_info from vtable. */
241 tree t;
242 tree index;
243
244 if (! flag_rtti)
245 error ("taking dynamic typeid of object with -fno-rtti");
246 if (CLASSTYPE_COM_INTERFACE (type))
247 {
248 cp_error ("RTTI not supported for COM interface type `%T'", type);
249 return error_mark_node;
250 }
251
252 /* If we don't have rtti stuff, get to a sub-object that does. */
253 if (! CLASSTYPE_VFIELDS (type))
254 {
255 exp = build_unary_op (ADDR_EXPR, exp, 0);
256 exp = build_headof_sub (exp);
257 exp = build_indirect_ref (exp, NULL_PTR);
258 }
259
260 /* The RTTI information is always in the vtable, but it's at
261 different indices depending on the ABI. */
262 if (new_abi_rtti_p ())
263 index = minus_one_node;
264 else if (flag_vtable_thunks)
265 index = integer_one_node;
266 else
267 index = integer_zero_node;
268 t = build_vfn_ref ((tree *) 0, exp, index);
269 TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
270 return t;
271 }
272
273 /* otherwise return the type_info for the static type of the expr. */
274 exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
275 return build_unary_op (ADDR_EXPR, exp, 0);
276 }
277
278 tree
279 build_typeid (exp)
280 tree exp;
281 {
282 tree cond = NULL_TREE;
283 int nonnull = 0;
284
285 if (! flag_rtti)
286 {
287 error ("cannot use typeid with -fno-rtti");
288 return error_mark_node;
289 }
290
291 if (!COMPLETE_TYPE_P (type_info_type_node))
292 {
293 error ("must #include <typeinfo> before using typeid");
294 return error_mark_node;
295 }
296
297 if (processing_template_decl)
298 return build_min_nt (TYPEID_EXPR, exp);
299
300 if (TREE_CODE (exp) == INDIRECT_REF
301 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
302 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
303 && ! resolves_to_fixed_type_p (exp, &nonnull)
304 && ! nonnull)
305 {
306 exp = stabilize_reference (exp);
307 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
308 }
309
310 exp = get_tinfo_decl_dynamic (exp);
311
312 if (exp == error_mark_node)
313 return error_mark_node;
314
315 exp = tinfo_from_decl (exp);
316
317 if (cond)
318 {
319 tree bad = throw_bad_typeid ();
320
321 exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
322 }
323
324 return convert_from_reference (exp);
325 }
326
327 static tree
328 get_tinfo_var (type)
329 tree type;
330 {
331 tree tname = build_overload_with_type (tinfo_var_id, type);
332 tree arrtype;
333 int size;
334
335 my_friendly_assert (!new_abi_rtti_p (), 20000118);
336 if (IDENTIFIER_GLOBAL_VALUE (tname))
337 return IDENTIFIER_GLOBAL_VALUE (tname);
338
339 /* Figure out how much space we need to allocate for the type_info object.
340 If our struct layout or the type_info classes are changed, this will
341 need to be modified. */
342 if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
343 size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
344 else if (TREE_CODE (type) == POINTER_TYPE
345 && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
346 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
347 size = 3 * POINTER_SIZE;
348 else if (IS_AGGR_TYPE (type))
349 {
350 if (CLASSTYPE_N_BASECLASSES (type) == 0)
351 size = 2 * POINTER_SIZE;
352 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
353 && (TREE_VIA_PUBLIC
354 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
355 size = 3 * POINTER_SIZE;
356 else
357 size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
358 }
359 else
360 size = 2 * POINTER_SIZE;
361
362 /* The type for a character array of the appropriate size. */
363 arrtype = build_cplus_array_type
364 (unsigned_char_type_node,
365 build_index_type (size_int (size / BITS_PER_UNIT - 1)));
366
367 return declare_global_var (tname, arrtype);
368 }
369
370 /* Generate the NTBS name of a type. */
371 static tree
372 tinfo_name (type)
373 tree type;
374 {
375 const char *name = build_overload_name (type, 1, 1);
376 tree name_string = combine_strings (build_string (strlen (name) + 1, name));
377 return name_string;
378 }
379
380 /* Returns a decl for a function or variable which can be used to obtain a
381 type_info object for TYPE. The old-abi uses functions, the new-abi
382 uses the type_info object directly. You can take the address of the
383 returned decl, to save the decl. To use the decl call
384 tinfo_from_decl. You must arrange that the decl is mark_used, if
385 actually use it --- decls in vtables are only used if the vtable is
386 output. */
387
388 tree
389 get_tinfo_decl (type)
390 tree type;
391 {
392 tree name;
393 tree d;
394
395 if (TREE_CODE (type) == OFFSET_TYPE)
396 type = TREE_TYPE (type);
397 if (TREE_CODE (type) == METHOD_TYPE)
398 type = build_function_type (TREE_TYPE (type),
399 TREE_CHAIN (TYPE_ARG_TYPES (type)));
400
401 name = build_overload_with_type (tinfo_decl_id, type);
402
403 d = IDENTIFIER_GLOBAL_VALUE (name);
404 if (d)
405 /* OK */;
406 else if (!new_abi_rtti_p ())
407 {
408 /* The tinfo decl is a function returning a reference to the type_info
409 object. */
410 d = push_library_fn (name, tinfo_decl_type);
411 DECL_NOT_REALLY_EXTERN (d) = 1;
412 SET_DECL_TINFO_FN_P (d);
413 TREE_TYPE (name) = type;
414 mark_inline_for_output (d);
415 }
416 else
417 {
418 /* The tinfo decl is the type_info object itself. We make all
419 tinfo objects look as type_info, even though they will end up
420 being a subclass of that when emitted. This means the we'll
421 erroneously think we know the dynamic type -- be careful in the
422 runtime. */
423 d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
424
425 DECL_ARTIFICIAL (d) = 1;
426 DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
427 TREE_READONLY (d) = 1;
428 TREE_STATIC (d) = 1;
429 DECL_EXTERNAL (d) = 1;
430 TREE_PUBLIC (d) = 1;
431 comdat_linkage (d);
432 DECL_ASSEMBLER_NAME (d) = DECL_NAME (d);
433 cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
434
435 pushdecl_top_level (d);
436 /* Remember the type it is for. */
437 TREE_TYPE (name) = type;
438 TREE_USED (name) = 1;
439 }
440 return d;
441 }
442
443 /* Given an expr produced by get_tinfo_decl, return an expr which
444 produces a reference to the type_info object. */
445
446 static tree
447 tinfo_from_decl (expr)
448 tree expr;
449 {
450 tree t;
451
452 if (!new_abi_rtti_p ())
453 t = build_call (expr, NULL_TREE);
454 else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
455 t = build_indirect_ref (expr, NULL);
456 else
457 t = expr;
458
459 return t;
460 }
461
462 tree
463 get_typeid_1 (type)
464 tree type;
465 {
466 tree t;
467
468 t = get_tinfo_decl (type);
469 t = tinfo_from_decl (t);
470 return convert_from_reference (t);
471 }
472
473 /* Return the type_info object for TYPE. */
474
475 tree
476 get_typeid (type)
477 tree type;
478 {
479 if (type == error_mark_node)
480 return error_mark_node;
481
482 if (!COMPLETE_TYPE_P (type_info_type_node))
483 {
484 error ("must #include <typeinfo> before using typeid");
485 return error_mark_node;
486 }
487
488 if (processing_template_decl)
489 return build_min_nt (TYPEID_EXPR, type);
490
491 /* If the type of the type-id is a reference type, the result of the
492 typeid expression refers to a type_info object representing the
493 referenced type. */
494 if (TREE_CODE (type) == REFERENCE_TYPE)
495 type = TREE_TYPE (type);
496
497 /* The top-level cv-qualifiers of the lvalue expression or the type-id
498 that is the operand of typeid are always ignored. */
499 type = TYPE_MAIN_VARIANT (type);
500
501 if (type != void_type_node)
502 type = complete_type_or_else (type, NULL_TREE);
503
504 if (!type)
505 return error_mark_node;
506
507 return get_typeid_1 (type);
508 }
509
510 /* Check whether TEST is null before returning RESULT. If TEST is used in
511 RESULT, it must have previously had a save_expr applied to it. */
512
513 static tree
514 ifnonnull (test, result)
515 tree test, result;
516 {
517 return build (COND_EXPR, TREE_TYPE (result),
518 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
519 cp_convert (TREE_TYPE (result), integer_zero_node),
520 result);
521 }
522
523 /* Generate the constant expression describing where direct base BINFO
524 appears within the PARENT. How to interpret this expression depends on
525 details of the ABI, which the runtime must be aware of. */
526
527 static tree
528 get_base_offset (binfo, parent)
529 tree binfo;
530 tree parent;
531 {
532 if (! TREE_VIA_VIRTUAL (binfo))
533 return BINFO_OFFSET (binfo);
534 else if (! vbase_offsets_in_vtable_p ())
535 {
536 const char *name;
537
538 FORMAT_VBASE_NAME (name, BINFO_TYPE (binfo));
539 return byte_position (lookup_field (parent, get_identifier (name),
540 0, 0));
541 }
542 else
543 /* Under the new ABI, we store the vtable offset at which
544 the virtual base offset can be found. */
545 return convert (sizetype,
546 BINFO_VPTR_FIELD (BINFO_FOR_VBASE (BINFO_TYPE (binfo),
547 parent)));
548
549 }
550
551 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
552 paper. */
553
554 static tree
555 build_dynamic_cast_1 (type, expr)
556 tree type, expr;
557 {
558 enum tree_code tc = TREE_CODE (type);
559 tree exprtype;
560 tree dcast_fn;
561 tree old_expr = expr;
562 const char *errstr = NULL;
563
564 /* T shall be a pointer or reference to a complete class type, or
565 `pointer to cv void''. */
566 switch (tc)
567 {
568 case POINTER_TYPE:
569 if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
570 break;
571 case REFERENCE_TYPE:
572 if (! IS_AGGR_TYPE (TREE_TYPE (type)))
573 {
574 errstr = "target is not pointer or reference to class";
575 goto fail;
576 }
577 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
578 {
579 errstr = "target is not pointer or reference to complete type";
580 goto fail;
581 }
582 break;
583
584 default:
585 errstr = "target is not pointer or reference";
586 goto fail;
587 }
588
589 if (TREE_CODE (expr) == OFFSET_REF)
590 expr = resolve_offset_ref (expr);
591
592 exprtype = TREE_TYPE (expr);
593 assert (exprtype != NULL_TREE);
594
595 if (tc == POINTER_TYPE)
596 expr = convert_from_reference (expr);
597 else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
598 {
599 /* Apply trivial conversion T -> T& for dereferenced ptrs. */
600 exprtype = build_reference_type (exprtype);
601 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
602 LOOKUP_NORMAL, NULL_TREE);
603 }
604
605 exprtype = TREE_TYPE (expr);
606
607 if (tc == POINTER_TYPE)
608 {
609 /* If T is a pointer type, v shall be an rvalue of a pointer to
610 complete class type, and the result is an rvalue of type T. */
611
612 if (TREE_CODE (exprtype) != POINTER_TYPE)
613 {
614 errstr = "source is not a pointer";
615 goto fail;
616 }
617 if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
618 {
619 errstr = "source is not a pointer to class";
620 goto fail;
621 }
622 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
623 {
624 errstr = "source is a pointer to incomplete type";
625 goto fail;
626 }
627 }
628 else
629 {
630 /* T is a reference type, v shall be an lvalue of a complete class
631 type, and the result is an lvalue of the type referred to by T. */
632
633 if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
634 {
635 errstr = "source is not of class type";
636 goto fail;
637 }
638 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
639 {
640 errstr = "source is of incomplete class type";
641 goto fail;
642 }
643
644 }
645
646 /* The dynamic_cast operator shall not cast away constness. */
647 if (!at_least_as_qualified_p (TREE_TYPE (type),
648 TREE_TYPE (exprtype)))
649 {
650 errstr = "conversion casts away constness";
651 goto fail;
652 }
653
654 /* If *type is an unambiguous accessible base class of *exprtype,
655 convert statically. */
656 {
657 int distance;
658 tree path;
659
660 distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
661 &path);
662
663 if (distance == -2)
664 {
665 cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
666 TREE_TYPE (exprtype), TREE_TYPE (type));
667 return error_mark_node;
668 }
669 if (distance == -3)
670 {
671 cp_error ("dynamic_cast from `%T' to private base class `%T'",
672 TREE_TYPE (exprtype), TREE_TYPE (type));
673 return error_mark_node;
674 }
675
676 if (distance >= 0)
677 return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
678 }
679
680 /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
681 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
682 {
683 tree expr1;
684 /* if TYPE is `void *', return pointer to complete object. */
685 if (tc == POINTER_TYPE
686 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
687 {
688 /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */
689 if (TREE_CODE (expr) == ADDR_EXPR
690 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
691 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
692 return build1 (NOP_EXPR, type, expr);
693
694 /* Since expr is used twice below, save it. */
695 expr = save_expr (expr);
696
697 expr1 = build_headof (expr);
698 if (TREE_TYPE (expr1) != type)
699 expr1 = build1 (NOP_EXPR, type, expr1);
700 return ifnonnull (expr, expr1);
701 }
702 else
703 {
704 tree retval;
705 tree result, td2, td3, elems;
706 tree static_type, target_type, boff;
707
708 /* If we got here, we can't convert statically. Therefore,
709 dynamic_cast<D&>(b) (b an object) cannot succeed. */
710 if (tc == REFERENCE_TYPE)
711 {
712 if (TREE_CODE (old_expr) == VAR_DECL
713 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
714 {
715 tree expr = throw_bad_cast ();
716 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
717 old_expr, type);
718 /* Bash it to the expected type. */
719 TREE_TYPE (expr) = type;
720 return expr;
721 }
722 }
723 /* Ditto for dynamic_cast<D*>(&b). */
724 else if (TREE_CODE (expr) == ADDR_EXPR)
725 {
726 tree op = TREE_OPERAND (expr, 0);
727 if (TREE_CODE (op) == VAR_DECL
728 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
729 {
730 cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
731 op, type);
732 retval = build_int_2 (0, 0);
733 TREE_TYPE (retval) = type;
734 return retval;
735 }
736 }
737
738 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
739 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
740 td2 = build_unary_op (ADDR_EXPR, get_tinfo_decl (target_type), 0);
741 td3 = build_unary_op (ADDR_EXPR, get_tinfo_decl (static_type), 0);
742
743 /* Determine how T and V are related. */
744 boff = get_dynamic_cast_base_type (static_type, target_type);
745
746 /* Since expr is used twice below, save it. */
747 expr = save_expr (expr);
748
749 expr1 = expr;
750 if (tc == REFERENCE_TYPE)
751 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
752
753 if (!new_abi_rtti_p ())
754 {
755 tree expr2 = build_headof (expr1);
756 tree td1 = expr;
757
758 if (tc == POINTER_TYPE)
759 td1 = build_indirect_ref (td1, NULL_PTR);
760 td1 = get_tinfo_decl_dynamic (td1);
761
762 elems = tree_cons
763 (NULL_TREE, td1, tree_cons
764 (NULL_TREE, td2, tree_cons
765 (NULL_TREE, boff, tree_cons
766 (NULL_TREE, expr2, tree_cons
767 (NULL_TREE, td3, tree_cons
768 (NULL_TREE, expr1, NULL_TREE))))));
769 }
770 else
771 elems = tree_cons
772 (NULL_TREE, expr1, tree_cons
773 (NULL_TREE, td3, tree_cons
774 (NULL_TREE, td2, tree_cons
775 (NULL_TREE, boff, NULL_TREE))));
776
777 dcast_fn = dynamic_cast_node;
778 if (!dcast_fn)
779 {
780 tree tmp;
781 tree tinfo_ptr;
782 tree ns = new_abi_rtti_p () ? abi_node : global_namespace;
783 const char *name;
784
785 push_nested_namespace (ns);
786 if (!new_abi_rtti_p ())
787 {
788 tinfo_ptr = build_pointer_type (tinfo_decl_type);
789 name = "__dynamic_cast_2";
790 tmp = tree_cons
791 (NULL_TREE, tinfo_ptr, tree_cons
792 (NULL_TREE, tinfo_ptr, tree_cons
793 (NULL_TREE, integer_type_node, tree_cons
794 (NULL_TREE, ptr_type_node, tree_cons
795 (NULL_TREE, tinfo_ptr, tree_cons
796 (NULL_TREE, ptr_type_node, void_list_node))))));
797 }
798 else
799 {
800 tinfo_ptr = xref_tag (class_type_node,
801 get_identifier ("__class_type_info"),
802 1);
803
804 tinfo_ptr = build_pointer_type
805 (build_qualified_type
806 (tinfo_ptr, TYPE_QUAL_CONST));
807 name = "__dynamic_cast";
808 tmp = tree_cons
809 (NULL_TREE, const_ptr_type_node, tree_cons
810 (NULL_TREE, tinfo_ptr, tree_cons
811 (NULL_TREE, tinfo_ptr, tree_cons
812 (NULL_TREE, ptrdiff_type_node, void_list_node))));
813 }
814 tmp = build_function_type (ptr_type_node, tmp);
815 if (new_abi_rtti_p ())
816 /* We want its name mangling. */
817 dcast_fn = build_cp_library_fn_ptr (name, tmp);
818 else
819 dcast_fn = build_library_fn_ptr (name, tmp);
820 pop_nested_namespace (ns);
821 dynamic_cast_node = dcast_fn;
822 }
823 result = build_call (dcast_fn, elems);
824
825 if (tc == REFERENCE_TYPE)
826 {
827 tree bad = throw_bad_cast ();
828
829 result = save_expr (result);
830 return build (COND_EXPR, type, result, result, bad);
831 }
832
833 /* Now back to the type we want from a void*. */
834 result = cp_convert (type, result);
835 return ifnonnull (expr, result);
836 }
837 }
838 else
839 errstr = "source type is not polymorphic";
840
841 fail:
842 cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T' (%s)",
843 expr, exprtype, type, errstr);
844 return error_mark_node;
845 }
846
847 tree
848 build_dynamic_cast (type, expr)
849 tree type, expr;
850 {
851 if (type == error_mark_node || expr == error_mark_node)
852 return error_mark_node;
853
854 if (processing_template_decl)
855 return build_min (DYNAMIC_CAST_EXPR, type, expr);
856
857 return convert_from_reference (build_dynamic_cast_1 (type, expr));
858 }
859 \f
860 /* Build and initialize various sorts of descriptors. Every descriptor
861 node has a name associated with it (the name created by mangling).
862 For this reason, we use the identifier as our access to the __*_desc
863 nodes, instead of sticking them directly in the types. Otherwise we
864 would burden all built-in types (and pointer types) with slots that
865 we don't necessarily want to use.
866
867 For each descriptor we build, we build a variable that contains
868 the descriptor's information. When we need this info at runtime,
869 all we need is access to these variables.
870
871 Note: these constructors always return the address of the descriptor
872 info, since that is simplest for their mutual interaction. */
873
874 /* Build an initializer for a __si_type_info node. */
875
876 static void
877 expand_si_desc (tdecl, type)
878 tree tdecl;
879 tree type;
880 {
881 tree t, elems, fn;
882 tree name_string = tinfo_name (type);
883
884 type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
885 finish_expr_stmt (get_typeid_1 (type));
886 t = decay_conversion (get_tinfo_var (type));
887 elems = tree_cons
888 (NULL_TREE, decay_conversion (tdecl), tree_cons
889 (NULL_TREE, decay_conversion (name_string), tree_cons
890 (NULL_TREE, t, NULL_TREE)));
891
892 fn = get_identifier ("__rtti_si");
893 if (IDENTIFIER_GLOBAL_VALUE (fn))
894 fn = IDENTIFIER_GLOBAL_VALUE (fn);
895 else
896 {
897 tree tmp;
898 tmp = tree_cons
899 (NULL_TREE, ptr_type_node, tree_cons
900 (NULL_TREE, const_string_type_node, tree_cons
901 (NULL_TREE, build_pointer_type (type_info_type_node),
902 void_list_node)));
903 fn = push_void_library_fn (fn, tmp);
904 }
905
906 fn = build_call (fn, elems);
907 finish_expr_stmt (fn);
908 }
909
910 /* Build an initializer for a __class_type_info node. */
911
912 static void
913 expand_class_desc (tdecl, type)
914 tree tdecl;
915 tree type;
916 {
917 tree name_string;
918 tree fn, tmp;
919
920 int i = CLASSTYPE_N_BASECLASSES (type);
921 int base_cnt = 0;
922 tree binfos = TYPE_BINFO_BASETYPES (type);
923 #if 0
924 /* See code below that used these. */
925 tree vb = CLASSTYPE_VBASECLASSES (type);
926 int n_base = i;
927 #endif
928 tree base, elems, access, offset, isvir;
929 tree elt, elts = NULL_TREE;
930
931 if (base_desc_type_node == NULL_TREE)
932 {
933 tree fields [4];
934
935 /* A reasonably close approximation of __class_type_info::base_info */
936
937 base_desc_type_node = make_aggr_type (RECORD_TYPE);
938
939 /* Actually const __user_type_info * */
940 fields [0] = build_lang_decl
941 (FIELD_DECL, NULL_TREE,
942 build_pointer_type (build_qualified_type
943 (type_info_type_node,
944 TYPE_QUAL_CONST)));
945 fields [1] = build_lang_decl
946 (FIELD_DECL, NULL_TREE,
947 flag_new_abi ? intSI_type_node : unsigned_intSI_type_node);
948 DECL_BIT_FIELD (fields[1]) = 1;
949 DECL_SIZE (fields[1]) = bitsize_int (29);
950
951 fields [2] = build_lang_decl (FIELD_DECL, NULL_TREE, boolean_type_node);
952 DECL_BIT_FIELD (fields[2]) = 1;
953 DECL_SIZE (fields[2]) = bitsize_one_node;
954
955 /* Actually enum access */
956 fields [3] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node);
957 DECL_BIT_FIELD (fields[3]) = 1;
958 DECL_SIZE (fields[3]) = bitsize_int (2);
959
960 finish_builtin_type (base_desc_type_node, "__base_info", fields,
961 3, ptr_type_node);
962 }
963
964 while (--i >= 0)
965 {
966 tree binfo = TREE_VEC_ELT (binfos, i);
967
968 finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
969 base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
970 offset = get_base_offset (binfo, type);
971
972 if (TREE_VIA_PUBLIC (binfo))
973 access = access_public_node;
974 else if (TREE_VIA_PROTECTED (binfo))
975 access = access_protected_node;
976 else
977 access = access_private_node;
978 if (TREE_VIA_VIRTUAL (binfo))
979 isvir = boolean_true_node;
980 else
981 isvir = boolean_false_node;
982
983 elt = build
984 (CONSTRUCTOR, base_desc_type_node, NULL_TREE, tree_cons
985 (NULL_TREE, base, tree_cons
986 (NULL_TREE, offset, tree_cons
987 (NULL_TREE, isvir, tree_cons
988 (NULL_TREE, access, NULL_TREE)))));
989 TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
990 elts = tree_cons (NULL_TREE, elt, elts);
991 base_cnt++;
992 }
993 #if 0
994 i = n_base;
995 while (vb)
996 {
997 tree b;
998 access = access_public_node;
999 while (--i >= 0)
1000 {
1001 b = TREE_VEC_ELT (binfos, i);
1002 if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
1003 {
1004 if (TREE_VIA_PUBLIC (b))
1005 access = access_public_node;
1006 else if (TREE_VIA_PROTECTED (b))
1007 access = access_protected_node;
1008 else
1009 access = access_private_node;
1010 break;
1011 }
1012 }
1013 base = build_t_desc (BINFO_TYPE (vb), 1);
1014 offset = BINFO_OFFSET (vb);
1015 isvir = build_int_2 (1, 0);
1016
1017 base_list = tree_cons (NULL_TREE, base, base_list);
1018 isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
1019 acc_list = tree_cons (NULL_TREE, access, acc_list);
1020 off_list = tree_cons (NULL_TREE, offset, off_list);
1021
1022 base_cnt++;
1023 vb = TREE_CHAIN (vb);
1024 }
1025 #endif
1026
1027 name_string = tinfo_name (type);
1028
1029 {
1030 tree arrtype = build_array_type (base_desc_type_node, NULL_TREE);
1031 elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
1032 TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
1033 = TREE_STATIC (elts) = 1;
1034 complete_array_type (arrtype, elts, 1);
1035 }
1036
1037 elems = tree_cons
1038 (NULL_TREE, decay_conversion (tdecl), tree_cons
1039 (NULL_TREE, decay_conversion (name_string), tree_cons
1040 (NULL_TREE, decay_conversion (elts), tree_cons
1041 (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
1042 NULL_TREE))));
1043
1044 fn = get_identifier ("__rtti_class");
1045 if (IDENTIFIER_GLOBAL_VALUE (fn))
1046 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1047 else
1048 {
1049 tmp = tree_cons
1050 (NULL_TREE, ptr_type_node, tree_cons
1051 (NULL_TREE, const_string_type_node, tree_cons
1052 (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
1053 (NULL_TREE, sizetype, void_list_node))));
1054
1055 fn = push_void_library_fn (fn, tmp);
1056 }
1057
1058 fn = build_call (fn, elems);
1059 finish_expr_stmt (fn);
1060 }
1061
1062 /* Build an initializer for a __pointer_type_info node. */
1063
1064 static void
1065 expand_ptr_desc (tdecl, type)
1066 tree tdecl;
1067 tree type;
1068 {
1069 tree t, elems, fn;
1070 tree name_string = tinfo_name (type);
1071
1072 type = TREE_TYPE (type);
1073 finish_expr_stmt (get_typeid_1 (type));
1074 t = decay_conversion (get_tinfo_var (type));
1075 elems = tree_cons
1076 (NULL_TREE, decay_conversion (tdecl), tree_cons
1077 (NULL_TREE, decay_conversion (name_string), tree_cons
1078 (NULL_TREE, t, NULL_TREE)));
1079
1080 fn = get_identifier ("__rtti_ptr");
1081 if (IDENTIFIER_GLOBAL_VALUE (fn))
1082 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1083 else
1084 {
1085 tree tmp;
1086 tmp = tree_cons
1087 (NULL_TREE, ptr_type_node, tree_cons
1088 (NULL_TREE, const_string_type_node, tree_cons
1089 (NULL_TREE, build_pointer_type (type_info_type_node),
1090 void_list_node)));
1091 fn = push_void_library_fn (fn, tmp);
1092 }
1093
1094 fn = build_call (fn, elems);
1095 finish_expr_stmt (fn);
1096 }
1097
1098 /* Build an initializer for a __attr_type_info node. */
1099
1100 static void
1101 expand_attr_desc (tdecl, type)
1102 tree tdecl;
1103 tree type;
1104 {
1105 tree elems, t, fn;
1106 tree name_string = tinfo_name (type);
1107 tree attrval = build_int_2 (TYPE_QUALS (type), 0);
1108
1109 finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
1110 t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
1111 elems = tree_cons
1112 (NULL_TREE, decay_conversion (tdecl), tree_cons
1113 (NULL_TREE, decay_conversion (name_string), tree_cons
1114 (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
1115
1116 fn = get_identifier ("__rtti_attr");
1117 if (IDENTIFIER_GLOBAL_VALUE (fn))
1118 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1119 else
1120 {
1121 tree tmp;
1122 tmp = tree_cons
1123 (NULL_TREE, ptr_type_node, tree_cons
1124 (NULL_TREE, const_string_type_node, tree_cons
1125 (NULL_TREE, integer_type_node, tree_cons
1126 (NULL_TREE, build_pointer_type (type_info_type_node),
1127 void_list_node))));
1128 fn = push_void_library_fn (fn, tmp);
1129 }
1130
1131 fn = build_call (fn, elems);
1132 finish_expr_stmt (fn);
1133 }
1134
1135 /* Build an initializer for a type_info node that just has a name. */
1136
1137 static void
1138 expand_generic_desc (tdecl, type, fnname)
1139 tree tdecl;
1140 tree type;
1141 const char *fnname;
1142 {
1143 tree name_string = tinfo_name (type);
1144 tree elems = tree_cons
1145 (NULL_TREE, decay_conversion (tdecl), tree_cons
1146 (NULL_TREE, decay_conversion (name_string), NULL_TREE));
1147
1148 tree fn = get_identifier (fnname);
1149 if (IDENTIFIER_GLOBAL_VALUE (fn))
1150 fn = IDENTIFIER_GLOBAL_VALUE (fn);
1151 else
1152 {
1153 tree tmp;
1154 tmp = tree_cons
1155 (NULL_TREE, ptr_type_node, tree_cons
1156 (NULL_TREE, const_string_type_node, void_list_node));
1157 fn = push_void_library_fn (fn, tmp);
1158 }
1159
1160 fn = build_call (fn, elems);
1161 finish_expr_stmt (fn);
1162 }
1163
1164 /* Generate the code for a type_info initialization function.
1165 Note that we take advantage of the passage
1166
1167 5.2.7 Type identification [expr.typeid]
1168
1169 Whether or not the destructor is called for the type_info object at the
1170 end of the program is unspecified.
1171
1172 and don't bother to arrange for these objects to be destroyed. It
1173 doesn't matter, anyway, since the destructors don't do anything.
1174
1175 This must only be called from toplevel (i.e. from finish_file)! */
1176
1177 void
1178 synthesize_tinfo_fn (fndecl)
1179 tree fndecl;
1180 {
1181 tree type = TREE_TYPE (DECL_NAME (fndecl));
1182 tree tmp, addr, tdecl;
1183 tree compound_stmt;
1184 tree if_stmt;
1185 tree then_clause;
1186
1187 my_friendly_assert (!new_abi_rtti_p (), 20000118);
1188 if (at_eof)
1189 {
1190 import_export_decl (fndecl);
1191 if (DECL_REALLY_EXTERN (fndecl))
1192 return;
1193 }
1194
1195 /* Declare the static typeinfo variable. */
1196 tdecl = get_tinfo_var (type);
1197 DECL_EXTERNAL (tdecl) = 0;
1198 TREE_STATIC (tdecl) = 1;
1199 DECL_COMMON (tdecl) = 1;
1200 TREE_USED (tdecl) = 1;
1201 DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
1202 cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0);
1203
1204 /* Begin processing the function. */
1205 start_function (NULL_TREE, fndecl, NULL_TREE,
1206 SF_DEFAULT | SF_PRE_PARSED);
1207 DECL_DEFER_OUTPUT (fndecl) = 1;
1208 store_parm_decls ();
1209 clear_last_expr ();
1210
1211 /* Begin the body of the function. */
1212 compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
1213
1214 /* For convenience, we save away the address of the static
1215 variable. */
1216 addr = decay_conversion (tdecl);
1217
1218 /* If the first word of the array (the vtable) is non-zero, we've already
1219 initialized the object, so don't do it again. */
1220 if_stmt = begin_if_stmt ();
1221 tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
1222 tmp = build_indirect_ref (tmp, 0);
1223 tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
1224 finish_if_stmt_cond (tmp, if_stmt);
1225 then_clause = begin_compound_stmt (/*has_no_scope=*/0);
1226
1227 if (TREE_CODE (type) == FUNCTION_TYPE)
1228 expand_generic_desc (tdecl, type, "__rtti_func");
1229 else if (TREE_CODE (type) == ARRAY_TYPE)
1230 expand_generic_desc (tdecl, type, "__rtti_array");
1231 else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
1232 expand_attr_desc (tdecl, type);
1233 else if (TREE_CODE (type) == POINTER_TYPE)
1234 {
1235 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
1236 expand_generic_desc (tdecl, type, "__rtti_ptmd");
1237 else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
1238 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1239 else
1240 expand_ptr_desc (tdecl, type);
1241 }
1242 else if (TYPE_PTRMEMFUNC_P (type))
1243 expand_generic_desc (tdecl, type, "__rtti_ptmf");
1244 else if (IS_AGGR_TYPE (type))
1245 {
1246 if (CLASSTYPE_N_BASECLASSES (type) == 0)
1247 expand_generic_desc (tdecl, type, "__rtti_user");
1248 else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
1249 && (TREE_VIA_PUBLIC
1250 (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
1251 expand_si_desc (tdecl, type);
1252 else
1253 expand_class_desc (tdecl, type);
1254 }
1255 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1256 expand_generic_desc (tdecl, type, "__rtti_user");
1257 else
1258 my_friendly_abort (252);
1259
1260 finish_compound_stmt (/*has_no_scope=*/0, then_clause);
1261 finish_then_clause (if_stmt);
1262 finish_if_stmt ();
1263
1264 /* OK, now return the type_info object. */
1265 tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
1266 tmp = build_indirect_ref (tmp, 0);
1267 finish_return_stmt (tmp);
1268 /* Finish the function body. */
1269 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
1270 expand_body (finish_function (lineno, 0));
1271 }
1272
1273 /* Return the runtime bit mask encoding the qualifiers of TYPE. */
1274
1275 static int
1276 qualifier_flags (type)
1277 tree type;
1278 {
1279 int flags = 0;
1280 /* we want the qualifiers on this type, not any array core, it might have */
1281 int quals = TYPE_QUALS (type);
1282
1283 if (quals & TYPE_QUAL_CONST)
1284 flags |= 1;
1285 if (quals & TYPE_QUAL_VOLATILE)
1286 flags |= 2;
1287 return flags;
1288 }
1289
1290 /* Return a CONSTRUCTOR for the common part of the type_info objects. This
1291 is the vtable pointer and NTBS name. */
1292
1293 static tree
1294 tinfo_base_init (desc, target)
1295 tree desc;
1296 tree target;
1297 {
1298 tree name_string = tinfo_name (target);
1299 tree init = NULL_TREE;
1300
1301 if (TINFO_VTABLE_DECL (desc))
1302 {
1303 tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
1304 init = tree_cons (NULL_TREE, vtbl_ptr, init);
1305 }
1306
1307 init = tree_cons (NULL_TREE, decay_conversion (name_string), init);
1308
1309 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
1310 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1311 init = tree_cons (NULL_TREE, init, NULL_TREE);
1312
1313 return init;
1314 }
1315
1316 /* Return the CONSTRUCTOR expr for a type_info of TYPE. DESC provides the
1317 information about the particular type_info derivation, which adds no
1318 additional fields to the type_info base. */
1319
1320 static tree
1321 generic_initializer (desc, target)
1322 tree desc;
1323 tree target;
1324 {
1325 tree init = tinfo_base_init (desc, target);
1326
1327 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
1328 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1329 return init;
1330 }
1331
1332 /* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
1333 DESC provides information about the particular type_info derivation,
1334 which adds target type and qualifier flags members to the type_info base. */
1335
1336 static tree
1337 ptr_initializer (desc, target)
1338 tree desc;
1339 tree target;
1340 {
1341 tree init = tinfo_base_init (desc, target);
1342 tree to = TREE_TYPE (target);
1343 int flags = qualifier_flags (to);
1344
1345 init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
1346 init = tree_cons (NULL_TREE,
1347 build_unary_op (ADDR_EXPR,
1348 get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
1349 init);
1350
1351 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
1352 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1353 return init;
1354 }
1355
1356 /* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
1357 DESC provides information about the particular type_info derivation,
1358 which adds target type and qualifier flags members to the type_info base. */
1359
1360 static tree
1361 ptmd_initializer (desc, target)
1362 tree desc;
1363 tree target;
1364 {
1365 tree init = tinfo_base_init (desc, target);
1366 tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
1367 tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
1368 int flags = qualifier_flags (to);
1369
1370 init = tree_cons (NULL_TREE,
1371 build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
1372 init);
1373 init = tree_cons (NULL_TREE,
1374 build_unary_op (ADDR_EXPR,
1375 get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
1376 init);
1377 init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
1378
1379 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
1380 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1381 return init;
1382 }
1383
1384 /* Determine the hint flags describing the features of a class's heirarchy.
1385 FIXME: better set the hint_flags here! For now set them
1386 to safe 'don't know' values. The specification is under
1387 review. Don't forget to check the runtime dynamic_cast and
1388 catch machinery if these change. */
1389
1390 static int
1391 class_hint_flags (type)
1392 tree type;
1393 {
1394 int hint_flags = 0;
1395
1396 hint_flags |= 0x1; /* non-diamond shaped repeated base */
1397 hint_flags |= 0x2; /* diamond shaped */
1398 hint_flags |= 0x4; /* non-public base */
1399 hint_flags |= 0x8; /* public base */
1400 type = 0; /* FIXME: Use it! */
1401 return hint_flags;
1402 }
1403
1404 /* Return the CONSTRUCTOR expr for a type_info of class TYPE.
1405 DESC provides information about the particular __class_type_info derivation,
1406 which adds hint flags and TRAIL initializers to the type_info base. */
1407
1408 static tree
1409 class_initializer (desc, target, trail)
1410 tree desc;
1411 tree target;
1412 tree trail;
1413 {
1414 tree init = tinfo_base_init (desc, target);
1415
1416 TREE_CHAIN (init) = trail;
1417 init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
1418 TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
1419 return init;
1420 }
1421
1422 /* Generate a pseudo_type_info VAR_DECL suitable for the supplied
1423 TARGET_TYPE and given the REAL_NAME. This is the structure expected by
1424 the runtime, and therefore has additional fields. If we need not emit a
1425 definition (because the runtime must contain it), return NULL_TREE,
1426 otherwise return the VAR_DECL. */
1427
1428 static tree
1429 synthesize_tinfo_var (target_type, real_name)
1430 tree target_type;
1431 tree real_name;
1432 {
1433 tree var_init = NULL_TREE;
1434 tree var_type = NULL_TREE;
1435
1436 my_friendly_assert (new_abi_rtti_p (), 20000118);
1437
1438 switch (TREE_CODE (target_type))
1439 {
1440 case POINTER_TYPE:
1441 if (TYPE_PTRMEM_P (target_type))
1442 {
1443 var_type = ptmd_desc_type_node;
1444 var_init = ptmd_initializer (var_type, target_type);
1445 }
1446 else
1447 {
1448 int code = TREE_CODE (TREE_TYPE (target_type));
1449
1450 if ((CP_TYPE_QUALS (TREE_TYPE (target_type)) | TYPE_QUAL_CONST)
1451 == TYPE_QUAL_CONST
1452 && (code == INTEGER_TYPE || code == BOOLEAN_TYPE
1453 || code == CHAR_TYPE || code == REAL_TYPE
1454 || code == VOID_TYPE)
1455 && !doing_runtime)
1456 /* These are in the runtime. */
1457 return NULL_TREE;
1458 var_type = ptr_desc_type_node;
1459 var_init = ptr_initializer (var_type, target_type);
1460 }
1461 break;
1462 case ENUMERAL_TYPE:
1463 var_type = enum_desc_type_node;
1464 var_init = generic_initializer (var_type, target_type);
1465 break;
1466 case FUNCTION_TYPE:
1467 var_type = func_desc_type_node;
1468 var_init = generic_initializer (var_type, target_type);
1469 break;
1470 case ARRAY_TYPE:
1471 var_type = ary_desc_type_node;
1472 var_init = generic_initializer (var_type, target_type);
1473 break;
1474 case UNION_TYPE:
1475 case RECORD_TYPE:
1476 if (!COMPLETE_TYPE_P (target_type))
1477 {
1478 /* FIXME: incomplete type. Awaiting specification. */
1479 return NULL_TREE;
1480 }
1481 else if (!CLASSTYPE_N_BASECLASSES (target_type))
1482 {
1483 var_type = class_desc_type_node;
1484 var_init = class_initializer (var_type, target_type, NULL_TREE);
1485 }
1486 else
1487 {
1488 /* if this has a single public non-virtual base, it's easier */
1489 tree binfo = TYPE_BINFO (target_type);
1490 int nbases = BINFO_N_BASETYPES (binfo);
1491 tree base_binfos = BINFO_BASETYPES (binfo);
1492 tree base_inits = NULL_TREE;
1493 int is_simple = nbases == 1;
1494 int ix;
1495
1496 /* Generate the base information initializer. */
1497 for (ix = nbases; ix--;)
1498 {
1499 tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
1500 tree base_init = NULL_TREE;
1501 int flags = 0;
1502 tree tinfo;
1503 tree offset;
1504
1505 if (TREE_VIA_VIRTUAL (base_binfo))
1506 flags |= 1;
1507 if (TREE_PUBLIC (base_binfo))
1508 flags |= 2;
1509 tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
1510 tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
1511 offset = get_base_offset (base_binfo, target_type);
1512
1513 /* is it a single public inheritance? */
1514 if (is_simple && flags == 2 && integer_zerop (offset))
1515 {
1516 base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
1517 break;
1518 }
1519 is_simple = 0;
1520
1521 /* combine offset and flags into one field */
1522 offset = build_binary_op (LSHIFT_EXPR, offset,
1523 build_int_2 (8, 0));
1524 offset = build_binary_op (BIT_IOR_EXPR, offset,
1525 build_int_2 (flags, 0));
1526 base_init = tree_cons (NULL_TREE, offset, base_init);
1527 base_init = tree_cons (NULL_TREE, tinfo, base_init);
1528 base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
1529 base_inits = tree_cons (NULL_TREE, base_init, base_inits);
1530 }
1531
1532 if (is_simple)
1533 var_type = si_class_desc_type_node;
1534 else
1535 {
1536 int hint = class_hint_flags (target_type);
1537
1538 base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
1539 base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
1540 /* Prepend the number of bases. */
1541 base_inits = tree_cons (NULL_TREE,
1542 build_int_2 (nbases, 0), base_inits);
1543 /* Prepend the hint flags. */
1544 base_inits = tree_cons (NULL_TREE,
1545 build_int_2 (hint, 0), base_inits);
1546 var_type = get_vmi_pseudo_type_info (nbases);
1547 }
1548 var_init = class_initializer (var_type, target_type, base_inits);
1549 }
1550 break;
1551 case INTEGER_TYPE:
1552 case BOOLEAN_TYPE:
1553 case CHAR_TYPE:
1554 case REAL_TYPE:
1555 case VOID_TYPE:
1556 if (!doing_runtime)
1557 /* These are guaranteed to be in the runtime. */
1558 return NULL_TREE;
1559 var_type = bltn_desc_type_node;
1560 var_init = generic_initializer (var_type, target_type);
1561 break;
1562 default:
1563 my_friendly_abort (20000117);
1564 }
1565
1566 return create_real_tinfo_var (real_name, TINFO_PSEUDO_TYPE (var_type), var_init);
1567 }
1568
1569 /* Create the real typeinfo variable. */
1570
1571 static tree
1572 create_real_tinfo_var (name, type, init)
1573 tree name;
1574 tree type;
1575 tree init;
1576 {
1577 tree decl;
1578
1579 decl = build_lang_decl (VAR_DECL, name,
1580 build_qualified_type (type, TYPE_QUAL_CONST));
1581 DECL_ARTIFICIAL (decl) = 1;
1582 TREE_READONLY (decl) = 1;
1583 TREE_STATIC (decl) = 1;
1584 TREE_PUBLIC (decl) = 1;
1585 DECL_EXTERNAL (decl) = 0;
1586
1587 comdat_linkage (decl);
1588 DECL_ASSEMBLER_NAME (decl) = name;
1589 DECL_INITIAL (decl) = init;
1590 cp_finish_decl (decl, init, NULL_TREE, 0);
1591
1592 return decl;
1593 }
1594
1595 /* Generate the RECORD_TYPE containing the data layout of a type_info
1596 derivative as used by the runtime. This layout must be consistent with
1597 that defined in the runtime support. Also generate the VAR_DECL for the
1598 type's vtable. We explicitly manage the vtable member, and name it for
1599 real type as used in the runtime. The RECORD type has a different name,
1600 to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
1601 is the generated type and TINFO_VTABLE_DECL is the vtable decl.
1602
1603 REAL_NAME is the runtime's name of the type. Trailing arguments are
1604 additional FIELD_DECL's for the structure. The final argument must be
1605 NULL. */
1606
1607 static tree
1608 create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
1609 {
1610 #ifndef ANSI_PROTOTYPES
1611 char const *real_name;
1612 int ident;
1613 #endif
1614 va_list ap;
1615 tree real_type, pseudo_type;
1616 char *pseudo_name;
1617 tree vtable_decl;
1618 int ix;
1619 tree fields[10];
1620 tree field_decl;
1621 tree result;
1622
1623 VA_START (ap, ident);
1624 #ifndef ANSI_PROTOTYPES
1625 real_name = va_arg (ap, char const *);
1626 ident = va_arg (app, int);
1627 #endif
1628
1629 /* Generate the pseudo type name. */
1630 pseudo_name = (char *)alloca (strlen (real_name) + 30);
1631 strcpy (pseudo_name, real_name);
1632 strcat (pseudo_name, "_pseudo");
1633 if (ident)
1634 sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
1635
1636 /* Get the vtable decl. */
1637 real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
1638 vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
1639 vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
1640
1641 /* Under the new ABI, we need to point into the middle of the
1642 vtable. */
1643 if (flag_new_abi)
1644 {
1645 vtable_decl = build (PLUS_EXPR,
1646 TREE_TYPE (vtable_decl),
1647 vtable_decl,
1648 size_binop (MULT_EXPR,
1649 size_int (2),
1650 TYPE_SIZE_UNIT (vtable_entry_type)));
1651 TREE_CONSTANT (vtable_decl) = 1;
1652 }
1653
1654 /* First field is the pseudo type_info base class. */
1655 fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
1656
1657 /* Now add the derived fields. */
1658 for (ix = 0; (field_decl = va_arg (ap, tree));)
1659 fields[++ix] = field_decl;
1660
1661 /* Create the pseudo type. */
1662 pseudo_type = make_aggr_type (RECORD_TYPE);
1663 finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
1664 TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
1665 va_end (ap);
1666
1667 result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
1668 TINFO_VTABLE_DECL (result) = vtable_decl;
1669 TINFO_PSEUDO_TYPE (result) = pseudo_type;
1670
1671 return result;
1672 }
1673
1674 /* Return a descriptor for a vmi type with NUM_BASES bases. */
1675
1676 static tree
1677 get_vmi_pseudo_type_info (num_bases)
1678 int num_bases;
1679 {
1680 tree desc;
1681 tree array_domain, base_array;
1682
1683 if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
1684 {
1685 int ix;
1686 tree extend = make_tree_vec (num_bases + 5);
1687
1688 for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
1689 TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
1690 vmi_class_desc_type_node = extend;
1691 }
1692 desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
1693
1694 if (desc)
1695 return desc;
1696
1697 /* Add number of bases and trailing array of base_class_type_info. */
1698 array_domain = build_index_type (build_int_2 (num_bases, 0));
1699 base_array = build_array_type (base_desc_type_node, array_domain);
1700
1701 push_nested_namespace (abi_node);
1702
1703 desc = create_pseudo_type_info
1704 ("__vmi_class_type_info", num_bases,
1705 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1706 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1707 build_lang_decl (FIELD_DECL, NULL_TREE, base_array),
1708 NULL);
1709
1710 pop_nested_namespace (abi_node);
1711
1712 TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
1713 return desc;
1714 }
1715
1716 /* Make sure the required builtin types exist for generating the type_info
1717 varable definitions. */
1718
1719 static void
1720 create_tinfo_types ()
1721 {
1722 tree ptr_type_info;
1723
1724 if (bltn_desc_type_node)
1725 return;
1726 push_nested_namespace (abi_node);
1727
1728 ptr_type_info = build_pointer_type
1729 (build_qualified_type
1730 (type_info_type_node, TYPE_QUAL_CONST));
1731
1732 /* Create the internal type_info structure. This is used as a base for
1733 the other structures. */
1734 {
1735 tree fields[2];
1736
1737 ti_desc_type_node = make_aggr_type (RECORD_TYPE);
1738 fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
1739 fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
1740 finish_builtin_type (ti_desc_type_node, "__type_info_pseudo",
1741 fields, 1, ptr_type_node);
1742 TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
1743 }
1744
1745 /* Fundamental type_info */
1746 bltn_desc_type_node = create_pseudo_type_info
1747 ("__fundamental_type_info", 0,
1748 NULL);
1749
1750 /* Pointer type_info. Adds two fields, qualification mask
1751 and pointer to the pointed to type. */
1752 ptr_desc_type_node = create_pseudo_type_info
1753 ("__pointer_type_info", 0,
1754 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1755 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1756 NULL);
1757
1758 /* Array, function and enum type_info. No additional fields. */
1759 ary_desc_type_node = create_pseudo_type_info
1760 ("__array_type_info", 0,
1761 NULL);
1762 func_desc_type_node = create_pseudo_type_info
1763 ("__function_type_info", 0,
1764 NULL);
1765 enum_desc_type_node = create_pseudo_type_info
1766 ("__enum_type_info", 0,
1767 NULL);
1768
1769 /* Class type_info. Add a flags field. */
1770 class_desc_type_node = create_pseudo_type_info
1771 ("__class_type_info", 0,
1772 NULL);
1773
1774 /* Single public non-virtual base class. Add pointer to base class. */
1775 si_class_desc_type_node = create_pseudo_type_info
1776 ("__si_class_type_info", 0,
1777 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1778 NULL);
1779
1780 /* Base class internal helper. Pointer to base type, offset to base,
1781 flags. */
1782 {
1783 tree fields[2];
1784
1785 fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
1786 fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
1787 base_desc_type_node = make_aggr_type (RECORD_TYPE);
1788 finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
1789 fields, 1, ptr_type_node);
1790 TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
1791 }
1792
1793 /* General heirarchy is created as necessary in this vector. */
1794 vmi_class_desc_type_node = make_tree_vec (10);
1795
1796 /* Pointer to member data type_info. Add pointer to the class, pointer
1797 to the member's type info and qualifications flags. */
1798 ptmd_desc_type_node = create_pseudo_type_info
1799 ("__pointer_to_member_type_info", 0,
1800 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1801 build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1802 build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1803 NULL);
1804
1805 pop_nested_namespace (abi_node);
1806 }
1807
1808 /* Emit the type_info descriptors which are guaranteed to be in the runtime
1809 support. Generating them here guarantees consistency with the other
1810 structures. We use the following heuristic to determine when the runtime
1811 is being generated. If std::__fundamental_type_info is defined, and it's
1812 destructor is defined, then the runtime is being built. */
1813
1814 void
1815 emit_support_tinfos ()
1816 {
1817 static tree *const fundamentals[] =
1818 {
1819 &void_type_node,
1820 &boolean_type_node,
1821 &wchar_type_node,
1822 #if 0
1823 &signed_wchar_type_node, &unsigned_wchar_type_node,
1824 #endif
1825 &char_type_node, &signed_char_type_node, &unsigned_char_type_node,
1826 &short_integer_type_node, &short_unsigned_type_node,
1827 &integer_type_node, &unsigned_type_node,
1828 &long_integer_type_node, &long_unsigned_type_node,
1829 &long_long_integer_type_node, &long_long_unsigned_type_node,
1830 &float_type_node, &double_type_node, &long_double_type_node,
1831
1832 /* GCC extension types */
1833 #if 0
1834 &complex_integer_type_node,
1835 &complex_float_type_node, &complex_double_type_node,
1836 &complex_long_double_type_node,
1837 #endif
1838
1839 0
1840 };
1841 int ix;
1842 tree bltn_type, dtor;
1843
1844 push_nested_namespace (abi_node);
1845 bltn_type = xref_tag (class_type_node,
1846 get_identifier ("__fundamental_type_info"), 1);
1847 pop_nested_namespace (abi_node);
1848 if (!COMPLETE_TYPE_P (bltn_type))
1849 return;
1850 dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
1851 if (DECL_EXTERNAL (dtor))
1852 return;
1853 doing_runtime = 1;
1854 for (ix = 0; fundamentals[ix]; ix++)
1855 {
1856 tree bltn = *fundamentals[ix];
1857 tree bltn_ptr = build_pointer_type (bltn);
1858 tree bltn_const_ptr = build_pointer_type
1859 (build_qualified_type (bltn, TYPE_QUAL_CONST));
1860 tree tinfo;
1861
1862 tinfo = get_tinfo_decl (bltn);
1863 TREE_USED (tinfo) = 1;
1864 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1865
1866 tinfo = get_tinfo_decl (bltn_ptr);
1867 TREE_USED (tinfo) = 1;
1868 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1869
1870 tinfo = get_tinfo_decl (bltn_const_ptr);
1871 TREE_USED (tinfo) = 1;
1872 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1873 }
1874 }
1875
1876 /* Return non-zero, iff T is a type_info variable which has not had a
1877 definition emitted for it. */
1878
1879 int
1880 tinfo_decl_p (t, data)
1881 tree t;
1882 void *data ATTRIBUTE_UNUSED;
1883 {
1884 return TREE_CODE (t) == VAR_DECL
1885 && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
1886 && TREE_TYPE (t) == tinfo_decl_type
1887 && TREE_TYPE (DECL_NAME (t));
1888 }
1889
1890 /* Emit a suitable type_info definition for the type_info decl pointed to by
1891 DECL_PTR. We emit a completely new variable, of the correct type for the
1892 actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
1893 definition is set to that of the supplied decl, so that they can be tied
1894 up. Mark the supplied decl as having been dealt with. Emitting one
1895 definitions might cause other declarations to be emitted.
1896
1897 We need to do things this way, because we're trying to do something like
1898
1899 struct B : A {
1900 ...
1901 };
1902
1903 extern const A tinfo_var;
1904
1905 const B tinfo_var = {...};
1906
1907 which is not permitted. Also, we've not necessarily seen the definition of B.
1908 So we do something like the following,
1909
1910 extern const A tinfo_var;
1911
1912 struct pseudo_A {
1913 const void *vtable_ptr;
1914 const char *name;
1915 };
1916 struct pseudo_B {
1917 pseudo_A base;
1918 ...
1919 };
1920
1921 const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
1922 {
1923 {&B::vtable, "..."},
1924 ...
1925 };
1926
1927 pseudo_A and pseudo_B must be layout equivalent to the real definitions in
1928 the runtime. */
1929
1930 int
1931 emit_tinfo_decl (decl_ptr, data)
1932 tree *decl_ptr;
1933 void *data ATTRIBUTE_UNUSED;
1934 {
1935 tree tinfo_decl = *decl_ptr;
1936 tree tinfo_type, decl;
1937
1938 my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
1939 tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
1940 my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
1941
1942 if (!DECL_NEEDED_P (tinfo_decl))
1943 return 0;
1944 /* Say we've dealt with it. */
1945 TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
1946
1947 create_tinfo_types ();
1948 decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
1949
1950 return decl != 0;
1951 }