OSDN Git Service

2001-07-30 H.J. Lu (hjl@gnu.org)
[pf3gnuchains/gcc-fork.git] / gcc / cp / rtti.c
1 /* RunTime Type Identification
2    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
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 /* Accessors for the type_info objects. We need to remember several things
34    about each of the type_info types. The global tree nodes such as
35    bltn_desc_type_node are TREE_LISTs, and these macros are used to access
36    the required information. */
37 /* The RECORD_TYPE of a type_info derived class. */
38 #define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
39 /* The VAR_DECL of the vtable for the type_info derived class. */
40 #define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
41
42 extern struct obstack permanent_obstack;
43
44 static tree build_headof_sub PARAMS((tree));
45 static tree build_headof PARAMS((tree));
46 static tree ifnonnull PARAMS((tree, tree));
47 static tree tinfo_name PARAMS((tree));
48 static tree build_dynamic_cast_1 PARAMS((tree, tree));
49 static tree throw_bad_cast PARAMS((void));
50 static tree throw_bad_typeid PARAMS((void));
51 static tree get_tinfo_decl_dynamic PARAMS((tree));
52 static bool typeid_ok_p PARAMS ((void));
53 static int qualifier_flags PARAMS((tree));
54 static int target_incomplete_p PARAMS((tree));
55 static tree tinfo_base_init PARAMS((tree, tree));
56 static tree generic_initializer PARAMS((tree, tree));
57 static tree ptr_initializer PARAMS((tree, tree, int *));
58 static tree ptm_initializer PARAMS((tree, tree, int *));
59 static tree dfs_class_hint_mark PARAMS ((tree, void *));
60 static tree dfs_class_hint_unmark PARAMS ((tree, void *));
61 static int class_hint_flags PARAMS((tree));
62 static tree class_initializer PARAMS((tree, tree, tree));
63 static tree synthesize_tinfo_var PARAMS((tree, tree));
64 static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int));
65 static tree create_pseudo_type_info PARAMS((const char *, int, ...));
66 static tree get_vmi_pseudo_type_info PARAMS((int));
67 static void create_tinfo_types PARAMS((void));
68 static int typeinfo_in_lib_p PARAMS((tree));
69
70 static int doing_runtime = 0;
71 \f
72 void
73 init_rtti_processing ()
74 {
75   if (flag_honor_std)
76     push_namespace (std_identifier);
77   type_info_type_node = xref_tag
78     (class_type_node, get_identifier ("type_info"), 1);
79   if (flag_honor_std)
80     pop_namespace ();
81   tinfo_decl_type = 
82     build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
83 }
84
85 /* Given a pointer to an object with at least one virtual table
86    pointer somewhere, return a pointer to a possible sub-object that
87    has a virtual table pointer in it that is the vtable parent for
88    that sub-object.  */
89
90 static tree
91 build_headof_sub (exp)
92      tree exp;
93 {
94   tree type = TREE_TYPE (TREE_TYPE (exp));
95   tree basetype = CLASSTYPE_RTTI (type);
96   tree binfo = get_binfo (basetype, type, 0);
97
98   exp = convert_pointer_to_real (binfo, exp);
99   return exp;
100 }
101
102 /* Given the expression EXP of type `class *', return the head of the
103    object pointed to by EXP with type cv void*, if the class has any
104    virtual functions (TYPE_POLYMORPHIC_P), else just return the
105    expression.  */
106
107 static tree
108 build_headof (exp)
109      tree exp;
110 {
111   tree type = TREE_TYPE (exp);
112   tree offset;
113   tree index;
114
115   my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
116   type = TREE_TYPE (type);
117
118   if (!TYPE_POLYMORPHIC_P (type))
119     return exp;
120
121   /* If we don't have rtti stuff, get to a sub-object that does.  */
122   if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
123     exp = build_headof_sub (exp);
124
125   /* We use this a couple of times below, protect it.  */
126   exp = save_expr (exp);
127
128   /* The offset-to-top field is at index -2 from the vptr.  */
129   index = build_int_2 (-2, -1);
130
131   offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
132
133   type = build_qualified_type (ptr_type_node, 
134                                CP_TYPE_QUALS (TREE_TYPE (exp)));
135   return build (PLUS_EXPR, type, exp,
136                 cp_convert (ptrdiff_type_node, offset));
137 }
138
139 /* Get a bad_cast node for the program to throw...
140
141    See libstdc++/exception.cc for __throw_bad_cast */
142
143 static tree
144 throw_bad_cast ()
145 {
146   tree fn = get_identifier ("__cxa_bad_cast");
147   if (IDENTIFIER_GLOBAL_VALUE (fn))
148     fn = IDENTIFIER_GLOBAL_VALUE (fn);
149   else
150     fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
151                                                          void_list_node));
152   
153   return build_call (fn, NULL_TREE);
154 }
155
156 static tree
157 throw_bad_typeid ()
158 {
159   tree fn = get_identifier ("__cxa_bad_typeid");
160   if (IDENTIFIER_GLOBAL_VALUE (fn))
161     fn = IDENTIFIER_GLOBAL_VALUE (fn);
162   else
163     {
164       tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
165       t = build_function_type (build_reference_type (t), void_list_node);
166       fn = push_throw_library_fn (fn, t);
167     }
168
169   return build_call (fn, NULL_TREE);
170 }
171 \f
172 /* Return a pointer to type_info function associated with the expression EXP.
173    If EXP is a reference to a polymorphic class, return the dynamic type;
174    otherwise return the static type of the expression.  */
175
176 static tree
177 get_tinfo_decl_dynamic (exp)
178      tree exp;
179 {
180   tree type;
181   
182   if (exp == error_mark_node)
183     return error_mark_node;
184
185   type = TREE_TYPE (exp);
186
187   /* peel back references, so they match.  */
188   if (TREE_CODE (type) == REFERENCE_TYPE)
189     type = TREE_TYPE (type);
190
191   /* Peel off cv qualifiers.  */
192   type = TYPE_MAIN_VARIANT (type);
193   
194   if (!VOID_TYPE_P (type))
195     type = complete_type_or_else (type, exp);
196   
197   if (!type)
198     return error_mark_node;
199
200   /* If exp is a reference to polymorphic type, get the real type_info.  */
201   if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
202     {
203       /* build reference to type_info from vtable.  */
204       tree t;
205       tree index;
206
207       if (! flag_rtti)
208         error ("taking dynamic typeid of object with -fno-rtti");
209
210       /* If we don't have rtti stuff, get to a sub-object that does.  */
211       if (! CLASSTYPE_VFIELDS (type))
212         {
213           exp = build_unary_op (ADDR_EXPR, exp, 0);
214           exp = build_headof_sub (exp);
215           exp = build_indirect_ref (exp, NULL);
216         }
217
218       /* The RTTI information is at index -1.  */
219       index = integer_minus_one_node;
220       t = build_vfn_ref (exp, index);
221       TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
222       return t;
223     }
224
225   /* otherwise return the type_info for the static type of the expr.  */
226   exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
227   return build_unary_op (ADDR_EXPR, exp, 0);
228 }
229
230 static bool
231 typeid_ok_p ()
232 {
233   if (! flag_rtti)
234     {
235       error ("cannot use typeid with -fno-rtti");
236       return false;
237     }
238   
239   if (!COMPLETE_TYPE_P (type_info_type_node))
240     {
241       error ("must #include <typeinfo> before using typeid");
242       return false;
243     }
244   
245   return true;
246 }
247
248 tree
249 build_typeid (exp)
250      tree exp;
251 {
252   tree cond = NULL_TREE;
253   int nonnull = 0;
254
255   if (exp == error_mark_node || !typeid_ok_p ())
256     return error_mark_node;
257
258   if (processing_template_decl)
259     return build_min_nt (TYPEID_EXPR, exp);
260
261   if (TREE_CODE (exp) == INDIRECT_REF
262       && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
263       && TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
264       && ! resolves_to_fixed_type_p (exp, &nonnull)
265       && ! nonnull)
266     {
267       exp = stabilize_reference (exp);
268       cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
269     }
270
271   exp = get_tinfo_decl_dynamic (exp);
272
273   if (exp == error_mark_node)
274     return error_mark_node;
275
276   exp = build_indirect_ref (exp, NULL);
277
278   if (cond)
279     {
280       tree bad = throw_bad_typeid ();
281
282       exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
283     }
284
285   return convert_from_reference (exp);
286 }
287
288 /* Generate the NTBS name of a type.  */
289 static tree
290 tinfo_name (type)
291      tree type;
292 {
293   const char *name;
294   tree name_string;
295
296   name = mangle_type_string (type);
297   name_string = combine_strings (build_string (strlen (name) + 1, name));
298   return name_string;
299 }
300
301 /* Returns a decl for the type_info variable for TYPE.  You must
302    arrange that the decl is mark_used, if actually use it --- decls in
303    vtables are only used if the vtable is output.  */ 
304
305 tree
306 get_tinfo_decl (type)
307      tree type;
308 {
309   tree name;
310   tree d;
311
312   if (COMPLETE_TYPE_P (type) 
313       && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
314     {
315       cp_error ("cannot create type information for type `%T' because its size is variable", 
316                 type);
317       return error_mark_node;
318     }
319
320   if (TREE_CODE (type) == OFFSET_TYPE)
321     type = TREE_TYPE (type);
322   if (TREE_CODE (type) == METHOD_TYPE)
323     type = build_function_type (TREE_TYPE (type),
324                                 TREE_CHAIN (TYPE_ARG_TYPES (type)));
325
326   name = mangle_typeinfo_for_type (type);
327
328   d = IDENTIFIER_GLOBAL_VALUE (name);
329   if (d)
330     /* OK */;
331   else
332     {
333       /* The tinfo decl is the type_info object itself.  We make all
334          tinfo objects look as type_info, even though they will end up
335          being a subclass of that when emitted.  This means that we'll
336          erroneously think we know the dynamic type -- be careful in the
337          runtime.  */
338       d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
339       
340       DECL_ARTIFICIAL (d) = 1;
341       DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
342       DECL_USER_ALIGN (d) = 0;
343       TREE_READONLY (d) = 1;
344       TREE_STATIC (d) = 1;
345       DECL_EXTERNAL (d) = 1;
346       TREE_PUBLIC (d) = 1;
347       if (flag_weak || !typeinfo_in_lib_p (d))
348         comdat_linkage (d);
349       SET_DECL_ASSEMBLER_NAME (d, name);
350       cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
351
352       pushdecl_top_level (d);
353       /* Remember the type it is for.  */
354       TREE_TYPE (name) = type;
355       TREE_USED (name) = 1;
356     }
357   return d;
358 }
359
360 /* Return the type_info object for TYPE.  */
361
362 tree
363 get_typeid (type)
364      tree type;
365 {
366   if (type == error_mark_node || !typeid_ok_p ())
367     return error_mark_node;
368   
369   if (processing_template_decl)
370     return build_min_nt (TYPEID_EXPR, type);
371
372   /* If the type of the type-id is a reference type, the result of the
373      typeid expression refers to a type_info object representing the
374      referenced type.  */
375   if (TREE_CODE (type) == REFERENCE_TYPE)
376     type = TREE_TYPE (type);
377
378   /* The top-level cv-qualifiers of the lvalue expression or the type-id
379      that is the operand of typeid are always ignored.  */
380   type = TYPE_MAIN_VARIANT (type);
381
382   if (!VOID_TYPE_P (type))
383     type = complete_type_or_else (type, NULL_TREE);
384   
385   if (!type)
386     return error_mark_node;
387
388   return get_tinfo_decl (type);
389 }
390
391 /* Check whether TEST is null before returning RESULT.  If TEST is used in
392    RESULT, it must have previously had a save_expr applied to it.  */
393
394 static tree
395 ifnonnull (test, result)
396      tree test, result;
397 {
398   return build (COND_EXPR, TREE_TYPE (result),
399                 build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
400                 cp_convert (TREE_TYPE (result), integer_zero_node),
401                 result);
402 }
403
404 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
405    paper.  */
406
407 static tree
408 build_dynamic_cast_1 (type, expr)
409      tree type, expr;
410 {
411   enum tree_code tc = TREE_CODE (type);
412   tree exprtype = TREE_TYPE (expr);
413   tree dcast_fn;
414   tree old_expr = expr;
415   const char *errstr = NULL;
416
417   /* T shall be a pointer or reference to a complete class type, or
418      `pointer to cv void''.  */
419   switch (tc)
420     {
421     case POINTER_TYPE:
422       if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
423         break;
424     case REFERENCE_TYPE:
425       if (! IS_AGGR_TYPE (TREE_TYPE (type)))
426         {
427           errstr = "target is not pointer or reference to class";
428           goto fail;
429         }
430       if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
431         {
432           errstr = "target is not pointer or reference to complete type";
433           goto fail;
434         }
435       break;
436
437     default:
438       errstr = "target is not pointer or reference";
439       goto fail;
440     }
441
442   if (TREE_CODE (expr) == OFFSET_REF)
443     {
444       expr = resolve_offset_ref (expr);
445       exprtype = TREE_TYPE (expr);
446     }
447
448   if (tc == POINTER_TYPE)
449     expr = convert_from_reference (expr);
450   else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
451     {
452       /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
453       exprtype = build_reference_type (exprtype);
454       expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
455                                    LOOKUP_NORMAL, NULL_TREE);
456     }
457
458   exprtype = TREE_TYPE (expr);
459
460   if (tc == POINTER_TYPE)
461     {
462       /* If T is a pointer type, v shall be an rvalue of a pointer to
463          complete class type, and the result is an rvalue of type T.  */
464
465       if (TREE_CODE (exprtype) != POINTER_TYPE)
466         {
467           errstr = "source is not a pointer";
468           goto fail;
469         }
470       if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
471         {
472           errstr = "source is not a pointer to class";
473           goto fail;
474         }
475       if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
476         {
477           errstr = "source is a pointer to incomplete type";
478           goto fail;
479         }
480     }
481   else
482     {
483       /* T is a reference type, v shall be an lvalue of a complete class
484          type, and the result is an lvalue of the type referred to by T.  */
485
486       if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
487         {
488           errstr = "source is not of class type";
489           goto fail;
490         }
491       if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
492         {
493           errstr = "source is of incomplete class type";
494           goto fail;
495         }
496       
497     }
498
499   /* The dynamic_cast operator shall not cast away constness.  */
500   if (!at_least_as_qualified_p (TREE_TYPE (type),
501                                 TREE_TYPE (exprtype)))
502     {
503       errstr = "conversion casts away constness";
504       goto fail;
505     }
506
507   /* If *type is an unambiguous accessible base class of *exprtype,
508      convert statically.  */
509   {
510     int distance;
511     tree path;
512
513     distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
514                                   &path);
515
516     if (distance == -2)
517       {
518         cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
519                   TREE_TYPE (exprtype), TREE_TYPE (type));
520         return error_mark_node;
521       }
522     if (distance == -3)
523       {
524         cp_error ("dynamic_cast from `%T' to private base class `%T'",
525                   TREE_TYPE (exprtype), TREE_TYPE (type));
526         return error_mark_node;
527       }
528
529     if (distance >= 0)
530       {
531         expr = build_vbase_path (PLUS_EXPR, type, expr, path, 0);
532         if (TREE_CODE (exprtype) == POINTER_TYPE)
533           expr = non_lvalue (expr);
534         return expr;
535       }
536   }
537
538   /* Otherwise *exprtype must be a polymorphic class (have a vtbl).  */
539   if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
540     {
541       tree expr1;
542       /* if TYPE is `void *', return pointer to complete object.  */
543       if (tc == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type)))
544         {
545           /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b.  */
546           if (TREE_CODE (expr) == ADDR_EXPR
547               && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
548               && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
549             return build1 (NOP_EXPR, type, expr);
550
551           /* Since expr is used twice below, save it.  */
552           expr = save_expr (expr);
553
554           expr1 = build_headof (expr);
555           if (TREE_TYPE (expr1) != type)
556             expr1 = build1 (NOP_EXPR, type, expr1);
557           return ifnonnull (expr, expr1);
558         }
559       else
560         {
561           tree retval;
562           tree result, td2, td3, elems;
563           tree static_type, target_type, boff;
564
565           /* If we got here, we can't convert statically.  Therefore,
566              dynamic_cast<D&>(b) (b an object) cannot succeed.  */
567           if (tc == REFERENCE_TYPE)
568             {
569               if (TREE_CODE (old_expr) == VAR_DECL
570                   && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
571                 {
572                   tree expr = throw_bad_cast ();
573                   cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
574                               old_expr, type);
575                   /* Bash it to the expected type.  */
576                   TREE_TYPE (expr) = type;
577                   return expr;
578                 }
579             }
580           /* Ditto for dynamic_cast<D*>(&b).  */
581           else if (TREE_CODE (expr) == ADDR_EXPR)
582             {
583               tree op = TREE_OPERAND (expr, 0);
584               if (TREE_CODE (op) == VAR_DECL
585                   && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
586                 {
587                   cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
588                               op, type);
589                   retval = build_int_2 (0, 0); 
590                   TREE_TYPE (retval) = type; 
591                   return retval;
592                 }
593             }
594
595           target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
596           static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
597           td2 = build_unary_op (ADDR_EXPR, get_tinfo_decl (target_type), 0);
598           td3 = build_unary_op (ADDR_EXPR, get_tinfo_decl (static_type), 0);
599
600           /* Determine how T and V are related.  */
601           boff = get_dynamic_cast_base_type (static_type, target_type);
602           
603           /* Since expr is used twice below, save it.  */
604           expr = save_expr (expr);
605
606           expr1 = expr;
607           if (tc == REFERENCE_TYPE)
608             expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
609
610           elems = tree_cons
611             (NULL_TREE, expr1, tree_cons
612              (NULL_TREE, td3, tree_cons
613               (NULL_TREE, td2, tree_cons
614                (NULL_TREE, boff, NULL_TREE))));
615
616           dcast_fn = dynamic_cast_node;
617           if (!dcast_fn)
618             {
619               tree tmp;
620               tree tinfo_ptr;
621               tree ns = abi_node;
622               const char *name;
623               
624               push_nested_namespace (ns);
625               tinfo_ptr = xref_tag (class_type_node,
626                                     get_identifier ("__class_type_info"),
627                                     1);
628               
629               tinfo_ptr = build_pointer_type
630                 (build_qualified_type
631                  (tinfo_ptr, TYPE_QUAL_CONST));
632               name = "__dynamic_cast";
633               tmp = tree_cons
634                 (NULL_TREE, const_ptr_type_node, tree_cons
635                  (NULL_TREE, tinfo_ptr, tree_cons
636                   (NULL_TREE, tinfo_ptr, tree_cons
637                    (NULL_TREE, ptrdiff_type_node, void_list_node))));
638               tmp = build_function_type (ptr_type_node, tmp);
639               dcast_fn = build_library_fn_ptr (name, tmp);
640               pop_nested_namespace (ns);
641               dynamic_cast_node = dcast_fn;
642             }
643           result = build_call (dcast_fn, elems);
644
645           if (tc == REFERENCE_TYPE)
646             {
647               tree bad = throw_bad_cast ();
648               
649               result = save_expr (result);
650               return build (COND_EXPR, type, result, result, bad);
651             }
652
653           /* Now back to the type we want from a void*.  */
654           result = cp_convert (type, result);
655           return ifnonnull (expr, result);
656         }
657     }
658   else
659     errstr = "source type is not polymorphic";
660
661  fail:
662   cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T' (%s)",
663             expr, exprtype, type, errstr);
664   return error_mark_node;
665 }
666
667 tree
668 build_dynamic_cast (type, expr)
669      tree type, expr;
670 {
671   if (type == error_mark_node || expr == error_mark_node)
672     return error_mark_node;
673   
674   if (processing_template_decl)
675     return build_min (DYNAMIC_CAST_EXPR, type, expr);
676
677   return convert_from_reference (build_dynamic_cast_1 (type, expr));
678 }
679 \f
680 /* Return the runtime bit mask encoding the qualifiers of TYPE.  */
681
682 static int
683 qualifier_flags (type)
684      tree type;
685 {
686   int flags = 0;
687   /* we want the qualifiers on this type, not any array core, it might have */
688   int quals = TYPE_QUALS (type);
689   
690   if (quals & TYPE_QUAL_CONST)
691     flags |= 1;
692   if (quals & TYPE_QUAL_VOLATILE)
693     flags |= 2;
694   if (quals & TYPE_QUAL_RESTRICT)
695     flags |= 4;
696   return flags;
697 }
698
699 /* Return non-zero, if the pointer chain TYPE ends at an incomplete type, or
700    contains a pointer to member of an incomplete class.  */
701
702 static int
703 target_incomplete_p (type)
704      tree type;
705 {
706   while (TREE_CODE (type) == POINTER_TYPE)
707     if (TYPE_PTRMEM_P (type))
708       {
709         if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
710           return 1;
711         type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
712       }
713     else
714       type = TREE_TYPE (type);
715   if (!COMPLETE_OR_VOID_TYPE_P (type))
716     return 1;
717   
718   return 0;
719 }
720
721 /* Return a CONSTRUCTOR for the common part of the type_info objects. This
722    is the vtable pointer and NTBS name.  The NTBS name is emitted as a
723    comdat const char array, so it becomes a unique key for the type. Generate
724    and emit that VAR_DECL here.  (We can't always emit the type_info itself
725    as comdat, because of pointers to incomplete.) */
726
727 static tree
728 tinfo_base_init (desc, target)
729      tree desc;
730      tree target;
731 {
732   tree init = NULL_TREE;
733   tree name_decl;
734   
735   {
736     tree name_name;
737     
738     /* Generate the NTBS array variable.  */
739     tree name_type = build_cplus_array_type
740                      (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
741                      NULL_TREE);
742     tree name_string = tinfo_name (target);
743
744     name_name = mangle_typeinfo_string_for_type (target);
745     name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
746     
747     DECL_ARTIFICIAL (name_decl) = 1;
748     TREE_READONLY (name_decl) = 1;
749     TREE_STATIC (name_decl) = 1;
750     DECL_EXTERNAL (name_decl) = 0;
751     TREE_PUBLIC (name_decl) = 1;
752     comdat_linkage (name_decl);
753     /* External name of the string containing the type's name has a
754        special name.  */
755     SET_DECL_ASSEMBLER_NAME (name_decl,
756                              mangle_typeinfo_string_for_type (target));
757     DECL_INITIAL (name_decl) = name_string;
758     cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
759     pushdecl_top_level (name_decl);
760   }
761   
762   if (TINFO_VTABLE_DECL (desc))
763     {
764       tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
765       init = tree_cons (NULL_TREE, vtbl_ptr, init);
766     }
767   
768   init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
769   
770   init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
771   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
772   init = tree_cons (NULL_TREE, init, NULL_TREE);
773   
774   return init;
775 }
776
777 /* Return the CONSTRUCTOR expr for a type_info of TYPE. DESC provides the
778    information about the particular type_info derivation, which adds no
779    additional fields to the type_info base.  */
780
781 static tree
782 generic_initializer (desc, target)
783      tree desc;
784      tree target;
785 {
786   tree init = tinfo_base_init (desc, target);
787   
788   init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
789   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
790   return init;
791 }
792
793 /* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
794    DESC provides information about the particular type_info derivation,
795    which adds target type and qualifier flags members to the type_info base.  */
796
797 static tree
798 ptr_initializer (desc, target, non_public_ptr)
799      tree desc;
800      tree target;
801      int *non_public_ptr;
802 {
803   tree init = tinfo_base_init (desc, target);
804   tree to = TREE_TYPE (target);
805   int flags = qualifier_flags (to);
806   int incomplete = target_incomplete_p (to);
807   
808   if (incomplete)
809     {
810       flags |= 8;
811       *non_public_ptr = 1;
812     }
813   init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
814   init = tree_cons (NULL_TREE,
815                     build_unary_op (ADDR_EXPR,
816                                     get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
817                     init);
818   
819   init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
820   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
821   return init;
822 }
823
824 /* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
825    DESC provides information about the particular type_info derivation,
826    which adds class, target type and qualifier flags members to the type_info
827    base.  */
828
829 static tree
830 ptm_initializer (desc, target, non_public_ptr)
831      tree desc;
832      tree target;
833      int *non_public_ptr;
834 {
835   tree init = tinfo_base_init (desc, target);
836   tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
837   tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
838   int flags = qualifier_flags (to);
839   int incomplete = target_incomplete_p (to);
840   
841   if (incomplete)
842     {
843       flags |= 0x8;
844       *non_public_ptr = 1;
845     }
846   if (!COMPLETE_TYPE_P (klass))
847     {
848       flags |= 0x10;
849       *non_public_ptr = 1;
850     }
851   init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
852   init = tree_cons (NULL_TREE,
853                     build_unary_op (ADDR_EXPR,
854                                     get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
855                     init);
856   init = tree_cons (NULL_TREE,
857                     build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
858                     init);  
859   
860   init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
861   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
862   return init;  
863 }
864
865 /* Check base BINFO to set hint flags in *DATA, which is really an int.
866    We use CLASSTYPE_MARKED to tag types we've found as non-virtual bases and
867    CLASSTYPE_MARKED2 to tag those which are virtual bases. Remember it is
868    possible for a type to be both a virtual and non-virtual base.  */
869
870 static tree
871 dfs_class_hint_mark (binfo, data)
872      tree binfo;
873      void *data;
874 {
875   tree basetype = BINFO_TYPE (binfo);
876   int *hint = (int *) data;
877   
878   if (TREE_VIA_VIRTUAL (binfo))
879     {
880       if (CLASSTYPE_MARKED (basetype))
881         *hint |= 1;
882       if (CLASSTYPE_MARKED2 (basetype))
883         *hint |= 2;
884       SET_CLASSTYPE_MARKED2 (basetype);
885     }
886   else
887     {
888       if (CLASSTYPE_MARKED (basetype) || CLASSTYPE_MARKED2 (basetype))
889         *hint |= 1;
890       SET_CLASSTYPE_MARKED (basetype);
891     }
892   if (!TREE_VIA_PUBLIC (binfo) && TYPE_BINFO (basetype) != binfo)
893     *hint |= 4;
894   return NULL_TREE;
895 };
896
897 /* Clear the base's dfs marks, after searching for duplicate bases. */
898
899 static tree
900 dfs_class_hint_unmark (binfo, data)
901      tree binfo;
902      void *data ATTRIBUTE_UNUSED;
903 {
904   tree basetype = BINFO_TYPE (binfo);
905   
906   CLEAR_CLASSTYPE_MARKED (basetype);
907   CLEAR_CLASSTYPE_MARKED2 (basetype);
908   return NULL_TREE;
909 }
910
911 /* Determine the hint flags describing the features of a class's heirarchy.  */
912
913 static int
914 class_hint_flags (type)
915      tree type;
916 {
917   int hint_flags = 0;
918   int i;
919   
920   dfs_walk (TYPE_BINFO (type), dfs_class_hint_mark, NULL, &hint_flags);
921   dfs_walk (TYPE_BINFO (type), dfs_class_hint_unmark, NULL, NULL);
922   
923   for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i)
924     {
925       tree base_binfo = BINFO_BASETYPE (TYPE_BINFO (type), i);
926       
927       if (TREE_VIA_PUBLIC (base_binfo))
928         hint_flags |= 0x8;
929     }
930   return hint_flags;
931 }
932         
933 /* Return the CONSTRUCTOR expr for a type_info of class TYPE.
934    DESC provides information about the particular __class_type_info derivation,
935    which adds hint flags and TRAIL initializers to the type_info base.  */
936
937 static tree
938 class_initializer (desc, target, trail)
939      tree desc;
940      tree target;
941      tree trail;
942 {
943   tree init = tinfo_base_init (desc, target);
944   
945   TREE_CHAIN (init) = trail;
946   init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
947   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
948   return init;  
949 }
950
951 /* Returns non-zero if the typeinfo for type should be placed in 
952    the runtime library.  */
953
954 static int
955 typeinfo_in_lib_p (type)
956      tree type;
957 {
958   /* The typeinfo objects for `T*' and `const T*' are in the runtime
959      library for simple types T.  */
960   if (TREE_CODE (type) == POINTER_TYPE
961       && (CP_TYPE_QUALS (TREE_TYPE (type)) == TYPE_QUAL_CONST
962           || CP_TYPE_QUALS (TREE_TYPE (type)) == TYPE_UNQUALIFIED))
963     type = TREE_TYPE (type);
964
965   switch (TREE_CODE (type))
966     {
967     case INTEGER_TYPE:
968     case BOOLEAN_TYPE:
969     case CHAR_TYPE:
970     case REAL_TYPE:
971     case VOID_TYPE:
972       return 1;
973     
974     default:
975       return 0;
976     }
977 }
978
979 /* Generate a pseudo_type_info VAR_DECL suitable for the supplied
980    TARGET_TYPE and given the REAL_NAME. This is the structure expected by
981    the runtime, and therefore has additional fields.  If we need not emit a
982    definition (because the runtime must contain it), return NULL_TREE,
983    otherwise return the VAR_DECL.  */
984
985 static tree
986 synthesize_tinfo_var (target_type, real_name)
987      tree target_type;
988      tree real_name;
989 {
990   tree var_init = NULL_TREE;
991   tree var_type = NULL_TREE;
992   int non_public = 0;
993   
994   switch (TREE_CODE (target_type))
995     {
996     case POINTER_TYPE:
997       if (TYPE_PTRMEM_P (target_type))
998         {
999           var_type = ptm_desc_type_node;
1000           var_init = ptm_initializer (var_type, target_type, &non_public);
1001         }
1002       else
1003         {
1004           if (typeinfo_in_lib_p (target_type) && !doing_runtime)
1005             /* These are in the runtime.  */
1006             return NULL_TREE;
1007           var_type = ptr_desc_type_node;
1008           var_init = ptr_initializer (var_type, target_type, &non_public);
1009         }
1010       break;
1011     case ENUMERAL_TYPE:
1012       var_type = enum_desc_type_node;
1013       var_init = generic_initializer (var_type, target_type);
1014       break;
1015     case FUNCTION_TYPE:
1016       var_type = func_desc_type_node;
1017       var_init = generic_initializer (var_type, target_type);
1018       break;
1019     case ARRAY_TYPE:
1020       var_type = ary_desc_type_node;
1021       var_init = generic_initializer (var_type, target_type);
1022       break;
1023     case UNION_TYPE:
1024     case RECORD_TYPE:
1025       if (TYPE_PTRMEMFUNC_P (target_type))
1026         {
1027           var_type = ptm_desc_type_node;
1028           var_init = ptm_initializer (var_type, target_type, &non_public);
1029         }
1030       else if (!COMPLETE_TYPE_P (target_type))
1031         {
1032           /* Emit a non-public class_type_info.  */
1033           non_public = 1;
1034           var_type = class_desc_type_node;
1035           var_init = class_initializer (var_type, target_type, NULL_TREE);
1036         }
1037       else if (!CLASSTYPE_N_BASECLASSES (target_type))
1038         {
1039           var_type = class_desc_type_node;
1040           var_init = class_initializer (var_type, target_type, NULL_TREE);
1041         }
1042       else
1043         {
1044           /* if this has a single public non-virtual base, it's easier */
1045           tree binfo = TYPE_BINFO (target_type);
1046           int nbases = BINFO_N_BASETYPES (binfo);
1047           tree base_binfos = BINFO_BASETYPES (binfo);
1048           tree base_inits = NULL_TREE;
1049           int is_simple = nbases == 1;
1050           int ix;
1051           
1052           /* Generate the base information initializer.  */
1053           for (ix = nbases; ix--;)
1054             {
1055               tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
1056               tree base_init = NULL_TREE;
1057               int flags = 0;
1058               tree tinfo;
1059               tree offset;
1060               
1061               if (TREE_PUBLIC (base_binfo))
1062                 flags |= 2;
1063               tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
1064               tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
1065               if (TREE_VIA_VIRTUAL (base_binfo))
1066                 {
1067                    /* We store the vtable offset at which the virtual
1068                       base offset can be found.  */
1069                   offset = BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (base_binfo),
1070                                                               target_type));
1071                   offset = convert (sizetype, offset);
1072                   flags |= 1;
1073                 }
1074               else
1075                 offset = BINFO_OFFSET (base_binfo);
1076               
1077               /* is it a single public inheritance? */
1078               if (is_simple && flags == 2 && integer_zerop (offset))
1079                 {
1080                   base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
1081                   break;
1082                 }
1083               is_simple = 0;
1084               
1085               /* combine offset and flags into one field */
1086               offset = cp_build_binary_op (LSHIFT_EXPR, offset,
1087                                            build_int_2 (8, 0));
1088               offset = cp_build_binary_op (BIT_IOR_EXPR, offset,
1089                                            build_int_2 (flags, 0));
1090               base_init = tree_cons (NULL_TREE, offset, base_init);
1091               base_init = tree_cons (NULL_TREE, tinfo, base_init);
1092               base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
1093               base_inits = tree_cons (NULL_TREE, base_init, base_inits);
1094             }
1095           
1096           if (is_simple)
1097             var_type = si_class_desc_type_node;
1098           else
1099             {
1100               int hint = class_hint_flags (target_type);
1101               
1102               base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
1103               base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
1104               /* Prepend the number of bases.  */
1105               base_inits = tree_cons (NULL_TREE,
1106                                       build_int_2 (nbases, 0), base_inits);
1107               /* Prepend the hint flags. */
1108               base_inits = tree_cons (NULL_TREE,
1109                                       build_int_2 (hint, 0), base_inits);
1110               var_type = get_vmi_pseudo_type_info (nbases);
1111             }
1112           var_init = class_initializer (var_type, target_type, base_inits);
1113         }
1114       break;
1115
1116     default:
1117       if (typeinfo_in_lib_p (target_type))
1118         {
1119           if (!doing_runtime)
1120             /* These are guaranteed to be in the runtime.  */
1121             return NULL_TREE;
1122           var_type = bltn_desc_type_node;
1123           var_init = generic_initializer (var_type, target_type);
1124           break;
1125         }
1126       my_friendly_abort (20000117);
1127     }
1128   
1129   return create_real_tinfo_var (target_type,
1130                                 real_name, TINFO_PSEUDO_TYPE (var_type),
1131                                 var_init, non_public);
1132 }
1133
1134 /* Create the real typeinfo variable.  NON_PUBLIC indicates that we cannot
1135    make this variable public (comdat). */
1136
1137 static tree
1138 create_real_tinfo_var (target_type, name, type, init, non_public)
1139      tree target_type;
1140      tree name;
1141      tree type;
1142      tree init;
1143      int non_public;
1144 {
1145   static int count = 0;
1146   tree decl;
1147   tree hidden_name;
1148   char hidden[30];
1149   
1150   sprintf (hidden, "__ti_%d", count++);
1151   hidden_name = get_identifier (hidden);
1152   
1153   decl = build_lang_decl (VAR_DECL, hidden_name,
1154                           build_qualified_type (type, TYPE_QUAL_CONST));
1155   DECL_ARTIFICIAL (decl) = 1;
1156   TREE_READONLY (decl) = 1;
1157   TREE_STATIC (decl) = 1;
1158   DECL_EXTERNAL (decl) = 0;
1159   
1160   if (!non_public)
1161     {
1162       TREE_PUBLIC (decl) = 1;
1163       if (flag_weak || !typeinfo_in_lib_p (target_type))
1164         comdat_linkage (decl);
1165     }
1166   SET_DECL_ASSEMBLER_NAME (decl, name);
1167   DECL_INITIAL (decl) = init;
1168   cp_finish_decl (decl, init, NULL_TREE, 0);
1169   pushdecl_top_level (decl);
1170   TREE_USED (decl) = 1;
1171   return decl;
1172 }
1173
1174 /* Generate the RECORD_TYPE containing the data layout of a type_info
1175    derivative as used by the runtime. This layout must be consistent with
1176    that defined in the runtime support. Also generate the VAR_DECL for the
1177    type's vtable. We explicitly manage the vtable member, and name it for
1178    real type as used in the runtime. The RECORD type has a different name,
1179    to avoid collisions.  Return a TREE_LIST who's TINFO_PSEUDO_TYPE
1180    is the generated type and TINFO_VTABLE_DECL is the vtable decl.
1181    
1182    REAL_NAME is the runtime's name of the type. Trailing arguments are
1183    additional FIELD_DECL's for the structure. The final argument must be
1184    NULL.  */
1185
1186 static tree
1187 create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
1188 {
1189 #ifndef ANSI_PROTOTYPES
1190   char const *real_name;
1191   int ident;
1192 #endif
1193   va_list ap;
1194   tree real_type, pseudo_type;
1195   char *pseudo_name;
1196   tree vtable_decl;
1197   int ix;
1198   tree fields[10];
1199   tree field_decl;
1200   tree result;
1201   
1202   VA_START (ap, ident);
1203 #ifndef ANSI_PROTOTYPES
1204   real_name = va_arg (ap, char const *);
1205   ident = va_arg (app, int);
1206 #endif
1207
1208   /* Generate the pseudo type name. */
1209   pseudo_name = (char *)alloca (strlen (real_name) + 30);
1210   strcpy (pseudo_name, real_name);
1211   strcat (pseudo_name, "_pseudo");
1212   if (ident)
1213     sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
1214   
1215   /* Get the vtable decl. */
1216   real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
1217   vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
1218   vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
1219
1220   /* We need to point into the middle of the vtable.  */
1221   vtable_decl = build (PLUS_EXPR,
1222                        TREE_TYPE (vtable_decl),
1223                        vtable_decl,
1224                        size_binop (MULT_EXPR,
1225                                    size_int (2),
1226                                    TYPE_SIZE_UNIT (vtable_entry_type)));
1227   TREE_CONSTANT (vtable_decl) = 1;
1228
1229   /* First field is the pseudo type_info base class. */
1230   fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
1231   
1232   /* Now add the derived fields.  */
1233   for (ix = 0; (field_decl = va_arg (ap, tree));)
1234     fields[++ix] = field_decl;
1235   
1236   /* Create the pseudo type. */
1237   pseudo_type = make_aggr_type (RECORD_TYPE);
1238   finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
1239   TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
1240   va_end (ap);
1241   
1242   result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
1243   TINFO_VTABLE_DECL (result) = vtable_decl;
1244   TINFO_PSEUDO_TYPE (result) = pseudo_type;
1245   
1246   return result;
1247 }
1248
1249 /* Return a descriptor for a vmi type with NUM_BASES bases.  */
1250
1251 static tree
1252 get_vmi_pseudo_type_info (num_bases)
1253      int num_bases;
1254 {
1255   tree desc;
1256   tree array_domain, base_array;
1257   
1258   if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
1259     {
1260       int ix;
1261       tree extend = make_tree_vec (num_bases + 5);
1262       
1263       for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
1264         TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
1265       vmi_class_desc_type_node = extend;
1266     }
1267   desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
1268   
1269   if (desc)
1270     return desc;
1271   
1272   /* Add number of bases and trailing array of base_class_type_info.  */
1273   array_domain = build_index_type (size_int (num_bases));
1274   base_array = build_array_type (base_desc_type_node, array_domain);
1275
1276   push_nested_namespace (abi_node);
1277
1278   desc = create_pseudo_type_info
1279             ("__vmi_class_type_info", num_bases,
1280              build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1281              build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1282              build_decl (FIELD_DECL, NULL_TREE, base_array),
1283              NULL);
1284
1285   pop_nested_namespace (abi_node);
1286
1287   TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
1288   return desc;
1289 }
1290
1291 /* Make sure the required builtin types exist for generating the type_info
1292    varable definitions.  */
1293
1294 static void
1295 create_tinfo_types ()
1296 {
1297   tree ptr_type_info;
1298   
1299   if (bltn_desc_type_node)
1300     return;
1301   push_nested_namespace (abi_node);
1302
1303   ptr_type_info = build_pointer_type
1304                     (build_qualified_type
1305                       (type_info_type_node, TYPE_QUAL_CONST));
1306   
1307   /* Create the internal type_info structure. This is used as a base for
1308      the other structures.  */
1309   {
1310     tree fields[2];
1311
1312     ti_desc_type_node = make_aggr_type (RECORD_TYPE);
1313     fields[0] = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
1314     fields[1] = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
1315     finish_builtin_type (ti_desc_type_node, "__type_info_pseudo",
1316                          fields, 1, ptr_type_node);
1317     TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
1318   }
1319   
1320   /* Fundamental type_info */
1321   bltn_desc_type_node = create_pseudo_type_info
1322       ("__fundamental_type_info", 0,
1323        NULL);
1324
1325   /* Array, function and enum type_info. No additional fields. */
1326   ary_desc_type_node = create_pseudo_type_info
1327       ("__array_type_info", 0,
1328        NULL);
1329   func_desc_type_node = create_pseudo_type_info
1330        ("__function_type_info", 0,
1331         NULL);
1332   enum_desc_type_node = create_pseudo_type_info
1333        ("__enum_type_info", 0,
1334         NULL);
1335   
1336   /* Class type_info. Add a flags field.  */
1337   class_desc_type_node = create_pseudo_type_info
1338         ("__class_type_info", 0,
1339          NULL);
1340   
1341   /* Single public non-virtual base class. Add pointer to base class. 
1342      This is really a descendant of __class_type_info.  */
1343   si_class_desc_type_node = create_pseudo_type_info
1344            ("__si_class_type_info", 0,
1345             build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1346             NULL);
1347   
1348   /* Base class internal helper. Pointer to base type, offset to base,
1349      flags. */
1350   {
1351     tree fields[2];
1352     
1353     fields[0] = build_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
1354     fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
1355     base_desc_type_node = make_aggr_type (RECORD_TYPE);
1356     finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
1357                          fields, 1, ptr_type_node);
1358     TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
1359   }
1360   
1361   /* General heirarchy is created as necessary in this vector. */
1362   vmi_class_desc_type_node = make_tree_vec (10);
1363   
1364   /* Pointer type_info. Adds two fields, qualification mask
1365      and pointer to the pointed to type.  This is really a descendant of
1366      __pbase_type_info. */
1367   ptr_desc_type_node = create_pseudo_type_info
1368       ("__pointer_type_info", 0,
1369        build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1370        build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1371        NULL);
1372
1373   /* Pointer to member data type_info.  Add qualifications flags,
1374      pointer to the member's type info and pointer to the class.
1375      This is really a descendant of __pbase_type_info.  */
1376   ptm_desc_type_node = create_pseudo_type_info
1377        ("__pointer_to_member_type_info", 0,
1378         build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
1379         build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1380         build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
1381         NULL);
1382
1383   pop_nested_namespace (abi_node);
1384 }
1385
1386 /* Emit the type_info descriptors which are guaranteed to be in the runtime
1387    support.  Generating them here guarantees consistency with the other
1388    structures.  We use the following heuristic to determine when the runtime
1389    is being generated.  If std::__fundamental_type_info is defined, and its
1390    destructor is defined, then the runtime is being built.  */
1391
1392 void
1393 emit_support_tinfos ()
1394 {
1395   static tree *const fundamentals[] =
1396   {
1397     &void_type_node,
1398     &boolean_type_node,
1399     &wchar_type_node,
1400     &char_type_node, &signed_char_type_node, &unsigned_char_type_node,
1401     &short_integer_type_node, &short_unsigned_type_node,
1402     &integer_type_node, &unsigned_type_node,
1403     &long_integer_type_node, &long_unsigned_type_node,
1404     &long_long_integer_type_node, &long_long_unsigned_type_node,
1405     &float_type_node, &double_type_node, &long_double_type_node,
1406     0
1407   };
1408   int ix;
1409   tree bltn_type, dtor;
1410   
1411   push_nested_namespace (abi_node);
1412   bltn_type = xref_tag (class_type_node,
1413                         get_identifier ("__fundamental_type_info"), 1);
1414   pop_nested_namespace (abi_node);
1415   if (!COMPLETE_TYPE_P (bltn_type))
1416     return;
1417   dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
1418   if (DECL_EXTERNAL (dtor))
1419     return;
1420   doing_runtime = 1;
1421   for (ix = 0; fundamentals[ix]; ix++)
1422     {
1423       tree bltn = *fundamentals[ix];
1424       tree bltn_ptr = build_pointer_type (bltn);
1425       tree bltn_const_ptr = build_pointer_type
1426               (build_qualified_type (bltn, TYPE_QUAL_CONST));
1427       tree tinfo;
1428       
1429       tinfo = get_tinfo_decl (bltn);
1430       TREE_USED (tinfo) = 1;
1431       TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1432       
1433       tinfo = get_tinfo_decl (bltn_ptr);
1434       TREE_USED (tinfo) = 1;
1435       TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1436       
1437       tinfo = get_tinfo_decl (bltn_const_ptr);
1438       TREE_USED (tinfo) = 1;
1439       TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
1440     }
1441 }
1442
1443 /* Return non-zero, iff T is a type_info variable which has not had a
1444    definition emitted for it.  */
1445
1446 int
1447 tinfo_decl_p (t, data)
1448      tree t;
1449      void *data ATTRIBUTE_UNUSED;
1450 {
1451   return TREE_CODE (t) == VAR_DECL
1452          && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
1453          && TREE_TYPE (t) == tinfo_decl_type
1454          && TREE_TYPE (DECL_NAME (t));
1455 }
1456
1457 /* Emit a suitable type_info definition for the type_info decl pointed to by
1458    DECL_PTR. We emit a completely new variable, of the correct type for the
1459    actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
1460    definition is set to that of the supplied decl, so that they can be tied
1461    up. Mark the supplied decl as having been dealt with. Emitting one
1462    definition might cause other definitions to be required.
1463    
1464    We need to do things this way, because we're trying to do something like
1465    
1466       struct B : A {
1467         ...
1468       };
1469    
1470       extern const A tinfo_var;
1471    
1472       const B tinfo_var = {...};
1473    
1474    which is not permitted. Also, we've not necessarily seen the definition of B.
1475    So we do something like the following,
1476    
1477       extern const A tinfo_var;
1478    
1479       struct pseudo_A {
1480         const void *vtable_ptr;
1481         const char *name;
1482       };
1483       struct pseudo_B {
1484         pseudo_A base;
1485         ...
1486       };
1487       
1488       const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
1489       {
1490         {&B::vtable, "..."},
1491         ...
1492       };
1493    
1494    pseudo_A and pseudo_B must be layout equivalent to the real definitions in
1495    the runtime.  */
1496
1497 int
1498 emit_tinfo_decl (decl_ptr, data)
1499      tree *decl_ptr;
1500      void *data ATTRIBUTE_UNUSED;
1501 {
1502   tree tinfo_decl = *decl_ptr;
1503   tree tinfo_type, decl;
1504   
1505   my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
1506   tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
1507   my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
1508   
1509   if (!DECL_NEEDED_P (tinfo_decl))
1510     return 0;
1511   /* Say we've dealt with it.  */
1512   TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
1513   
1514   create_tinfo_types ();
1515   decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
1516   
1517   return decl != 0;
1518 }