OSDN Git Service

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