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