OSDN Git Service

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