OSDN Git Service

Correct many new ABI issues regarding vbase and vcall offset
[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   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   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 }