OSDN Git Service

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