00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "coretypes.h"
00031 #include "tm.h"
00032 #include "tree.h"
00033 #include "cp-tree.h"
00034 #include "flags.h"
00035 #include "output.h"
00036 #include "assert.h"
00037 #include "toplev.h"
00038 #include "convert.h"
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
00075
00076
00077 #define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
00078
00079 #define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
00080
00081
00082 VEC (tree) *unemitted_tinfo_decls;
00083
00084 static tree build_headof (tree);
00085 static tree ifnonnull (tree, tree);
00086 static tree tinfo_name (tree);
00087 static tree build_dynamic_cast_1 (tree, tree);
00088 static tree throw_bad_cast (void);
00089 static tree throw_bad_typeid (void);
00090 static tree get_tinfo_decl_dynamic (tree);
00091 static tree get_tinfo_ptr (tree);
00092 static bool typeid_ok_p (void);
00093 static int qualifier_flags (tree);
00094 static bool target_incomplete_p (tree);
00095 static tree tinfo_base_init (tree, tree);
00096 static tree generic_initializer (tree, tree);
00097 static tree class_initializer (tree, tree, tree);
00098 static tree create_pseudo_type_info (const char *, int, ...);
00099 static tree get_pseudo_ti_init (tree, tree);
00100 static tree get_pseudo_ti_desc (tree);
00101 static void create_tinfo_types (void);
00102 static bool typeinfo_in_lib_p (tree);
00103
00104 static int doing_runtime = 0;
00105
00106
00107
00108
00109
00110
00111
00112
00113 void
00114 init_rtti_processing (void)
00115 {
00116 tree type_info_type;
00117
00118 push_namespace (std_identifier);
00119 type_info_type = xref_tag (class_type, get_identifier ("type_info"),
00120 ts_current, false);
00121 pop_namespace ();
00122 const_type_info_type_node
00123 = build_qualified_type (type_info_type, TYPE_QUAL_CONST);
00124 type_info_ptr_type = build_pointer_type (const_type_info_type_node);
00125
00126 unemitted_tinfo_decls = VEC_alloc (tree, 124);
00127
00128 create_tinfo_types ();
00129 }
00130
00131
00132
00133
00134
00135
00136 static tree
00137 build_headof (tree exp)
00138 {
00139 tree type = TREE_TYPE (exp);
00140 tree offset;
00141 tree index;
00142
00143 gcc_assert (TREE_CODE (type) == POINTER_TYPE);
00144 type = TREE_TYPE (type);
00145
00146 if (!TYPE_POLYMORPHIC_P (type))
00147 return exp;
00148
00149
00150 exp = save_expr (exp);
00151
00152
00153 index = build_int_cst (NULL_TREE,
00154 -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
00155
00156 offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
00157
00158 type = build_qualified_type (ptr_type_node,
00159 cp_type_quals (TREE_TYPE (exp)));
00160 return build2 (PLUS_EXPR, type, exp,
00161 convert_to_integer (ptrdiff_type_node, offset));
00162 }
00163
00164
00165
00166
00167
00168 static tree
00169 throw_bad_cast (void)
00170 {
00171 tree fn = get_identifier ("__cxa_bad_cast");
00172 if (!get_global_value_if_present (fn, &fn))
00173 fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
00174 void_list_node));
00175
00176 return build_cxx_call (fn, NULL_TREE);
00177 }
00178
00179
00180
00181
00182 static tree
00183 throw_bad_typeid (void)
00184 {
00185 tree fn = get_identifier ("__cxa_bad_typeid");
00186 if (!get_global_value_if_present (fn, &fn))
00187 {
00188 tree t;
00189
00190 t = build_reference_type (const_type_info_type_node);
00191 t = build_function_type (t, void_list_node);
00192 fn = push_throw_library_fn (fn, t);
00193 }
00194
00195 return build_cxx_call (fn, NULL_TREE);
00196 }
00197
00198
00199
00200
00201
00202
00203 static tree
00204 get_tinfo_decl_dynamic (tree exp)
00205 {
00206 tree type;
00207 tree t;
00208
00209 if (exp == error_mark_node)
00210 return error_mark_node;
00211
00212
00213 type = non_reference (TREE_TYPE (exp));
00214
00215
00216 type = TYPE_MAIN_VARIANT (type);
00217
00218 if (!VOID_TYPE_P (type))
00219 type = complete_type_or_else (type, exp);
00220
00221 if (!type)
00222 return error_mark_node;
00223
00224
00225 if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
00226 {
00227
00228 tree index;
00229
00230
00231 index = build_int_cst (NULL_TREE,
00232 -1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
00233 t = build_vtbl_ref (exp, index);
00234 t = convert (type_info_ptr_type, t);
00235 }
00236 else
00237
00238 t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
00239
00240 return build_indirect_ref (t, NULL);
00241 }
00242
00243 static bool
00244 typeid_ok_p (void)
00245 {
00246 if (! flag_rtti)
00247 {
00248 error ("cannot use typeid with -fno-rtti");
00249 return false;
00250 }
00251
00252 if (!COMPLETE_TYPE_P (const_type_info_type_node))
00253 {
00254 error ("must #include <typeinfo> before using typeid");
00255 return false;
00256 }
00257
00258 return true;
00259 }
00260
00261
00262
00263
00264 tree
00265 build_typeid (tree exp)
00266 {
00267 tree cond = NULL_TREE;
00268 int nonnull = 0;
00269
00270 if (exp == error_mark_node || !typeid_ok_p ())
00271 return error_mark_node;
00272
00273 if (processing_template_decl)
00274 return build_min (TYPEID_EXPR, const_type_info_type_node, exp);
00275
00276 if (TREE_CODE (exp) == INDIRECT_REF
00277 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
00278 && TYPE_POLYMORPHIC_P (TREE_TYPE (exp))
00279 && ! resolves_to_fixed_type_p (exp, &nonnull)
00280 && ! nonnull)
00281 {
00282 exp = stabilize_reference (exp);
00283 cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
00284 }
00285
00286 exp = get_tinfo_decl_dynamic (exp);
00287
00288 if (exp == error_mark_node)
00289 return error_mark_node;
00290
00291 if (cond)
00292 {
00293 tree bad = throw_bad_typeid ();
00294
00295 exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
00296 }
00297
00298 return exp;
00299 }
00300
00301
00302 static tree
00303 tinfo_name (tree type)
00304 {
00305 const char *name;
00306 tree name_string;
00307
00308 name = mangle_type_string (type);
00309 name_string = fix_string_type (build_string (strlen (name) + 1, name));
00310 return name_string;
00311 }
00312
00313 #ifdef KEY
00314 tree (*p_get_tinfo_decl) (tree) = get_tinfo_decl;
00315 #endif
00316
00317
00318
00319
00320
00321 tree
00322 get_tinfo_decl (tree type)
00323 {
00324 tree name;
00325 tree d;
00326
00327 if (COMPLETE_TYPE_P (type)
00328 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
00329 {
00330 error ("cannot create type information for type %qT because "
00331 "its size is variable",
00332 type);
00333 return error_mark_node;
00334 }
00335
00336 if (TREE_CODE (type) == METHOD_TYPE)
00337 type = build_function_type (TREE_TYPE (type),
00338 TREE_CHAIN (TYPE_ARG_TYPES (type)));
00339
00340
00341
00342 if (CLASS_TYPE_P (type))
00343 {
00344 d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
00345 if (d)
00346 return d;
00347 }
00348
00349 name = mangle_typeinfo_for_type (type);
00350
00351 d = IDENTIFIER_GLOBAL_VALUE (name);
00352 if (!d)
00353 {
00354 tree var_desc = get_pseudo_ti_desc (type);
00355
00356 d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
00357 SET_DECL_ASSEMBLER_NAME (d, name);
00358
00359 TREE_TYPE (name) = type;
00360 DECL_TINFO_P (d) = 1;
00361 DECL_ARTIFICIAL (d) = 1;
00362 #ifdef KEY
00363
00364 if (!flag_spin_file)
00365 #endif
00366 DECL_IGNORED_P (d) = 1;
00367 TREE_READONLY (d) = 1;
00368 TREE_STATIC (d) = 1;
00369
00370
00371 DECL_EXTERNAL (d) = 1;
00372 DECL_NOT_REALLY_EXTERN (d) = 1;
00373 if (CLASS_TYPE_P (type))
00374 CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
00375 set_linkage_according_to_type (type, d);
00376 pushdecl_top_level_and_finish (d, NULL_TREE);
00377
00378
00379 VEC_safe_push (tree, unemitted_tinfo_decls, d);
00380 }
00381
00382 return d;
00383 }
00384
00385
00386
00387
00388 static tree
00389 get_tinfo_ptr (tree type)
00390 {
00391 tree decl = get_tinfo_decl (type);
00392
00393 mark_used (decl);
00394 return build_nop (type_info_ptr_type,
00395 build_address (decl));
00396 }
00397
00398
00399
00400 tree
00401 get_typeid (tree type)
00402 {
00403 if (type == error_mark_node || !typeid_ok_p ())
00404 return error_mark_node;
00405
00406 if (processing_template_decl)
00407 return build_min (TYPEID_EXPR, const_type_info_type_node, type);
00408
00409
00410
00411
00412 type = non_reference (type);
00413
00414
00415
00416 type = TYPE_MAIN_VARIANT (type);
00417
00418 if (!VOID_TYPE_P (type))
00419 type = complete_type_or_else (type, NULL_TREE);
00420
00421 if (!type)
00422 return error_mark_node;
00423
00424 return build_indirect_ref (get_tinfo_ptr (type), NULL);
00425 }
00426
00427
00428
00429
00430 static tree
00431 ifnonnull (tree test, tree result)
00432 {
00433 return build3 (COND_EXPR, TREE_TYPE (result),
00434 build2 (EQ_EXPR, boolean_type_node, test, integer_zero_node),
00435 cp_convert (TREE_TYPE (result), integer_zero_node),
00436 result);
00437 }
00438
00439
00440
00441
00442 static tree
00443 build_dynamic_cast_1 (tree type, tree expr)
00444 {
00445 enum tree_code tc = TREE_CODE (type);
00446 tree exprtype = TREE_TYPE (expr);
00447 tree dcast_fn;
00448 tree old_expr = expr;
00449 const char *errstr = NULL;
00450
00451
00452
00453 switch (tc)
00454 {
00455 case POINTER_TYPE:
00456 if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
00457 break;
00458
00459 case REFERENCE_TYPE:
00460 if (! IS_AGGR_TYPE (TREE_TYPE (type)))
00461 {
00462 errstr = "target is not pointer or reference to class";
00463 goto fail;
00464 }
00465 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
00466 {
00467 errstr = "target is not pointer or reference to complete type";
00468 goto fail;
00469 }
00470 break;
00471
00472 default:
00473 errstr = "target is not pointer or reference";
00474 goto fail;
00475 }
00476
00477 if (tc == POINTER_TYPE)
00478 {
00479
00480
00481
00482 if (TREE_CODE (exprtype) != POINTER_TYPE)
00483 {
00484 errstr = "source is not a pointer";
00485 goto fail;
00486 }
00487 if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
00488 {
00489 errstr = "source is not a pointer to class";
00490 goto fail;
00491 }
00492 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
00493 {
00494 errstr = "source is a pointer to incomplete type";
00495 goto fail;
00496 }
00497 }
00498 else
00499 {
00500
00501 exprtype = build_reference_type (exprtype);
00502 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
00503 LOOKUP_NORMAL, NULL_TREE);
00504
00505
00506
00507
00508 if (! IS_AGGR_TYPE (TREE_TYPE (exprtype)))
00509 {
00510 errstr = "source is not of class type";
00511 goto fail;
00512 }
00513 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
00514 {
00515 errstr = "source is of incomplete class type";
00516 goto fail;
00517 }
00518
00519 }
00520
00521
00522 if (!at_least_as_qualified_p (TREE_TYPE (type),
00523 TREE_TYPE (exprtype)))
00524 {
00525 errstr = "conversion casts away constness";
00526 goto fail;
00527 }
00528
00529
00530
00531 {
00532 tree binfo;
00533
00534 binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
00535 ba_check, NULL);
00536
00537 if (binfo)
00538 {
00539 expr = build_base_path (PLUS_EXPR, convert_from_reference (expr),
00540 binfo, 0);
00541 if (TREE_CODE (exprtype) == POINTER_TYPE)
00542 expr = rvalue (expr);
00543 return expr;
00544 }
00545 }
00546
00547
00548 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
00549 {
00550 tree expr1;
00551
00552 if (tc == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type)))
00553 {
00554
00555 if (TREE_CODE (expr) == ADDR_EXPR
00556 && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL
00557 && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)
00558 return build1 (NOP_EXPR, type, expr);
00559
00560
00561 expr = save_expr (expr);
00562
00563 expr1 = build_headof (expr);
00564 if (TREE_TYPE (expr1) != type)
00565 expr1 = build1 (NOP_EXPR, type, expr1);
00566 return ifnonnull (expr, expr1);
00567 }
00568 else
00569 {
00570 tree retval;
00571 tree result, td2, td3, elems;
00572 tree static_type, target_type, boff;
00573
00574
00575
00576 if (tc == REFERENCE_TYPE)
00577 {
00578 if (TREE_CODE (old_expr) == VAR_DECL
00579 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
00580 {
00581 tree expr = throw_bad_cast ();
00582 warning ("dynamic_cast of %q#D to %q#T can never succeed",
00583 old_expr, type);
00584
00585 TREE_TYPE (expr) = type;
00586 return expr;
00587 }
00588 }
00589
00590 else if (TREE_CODE (expr) == ADDR_EXPR)
00591 {
00592 tree op = TREE_OPERAND (expr, 0);
00593 if (TREE_CODE (op) == VAR_DECL
00594 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
00595 {
00596 warning ("dynamic_cast of %q#D to %q#T can never succeed",
00597 op, type);
00598 retval = build_int_cst (type, 0);
00599 return retval;
00600 }
00601 }
00602
00603 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00604 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
00605 td2 = get_tinfo_decl (target_type);
00606 mark_used (td2);
00607 td2 = build_unary_op (ADDR_EXPR, td2, 0);
00608 td3 = get_tinfo_decl (static_type);
00609 mark_used (td3);
00610 td3 = build_unary_op (ADDR_EXPR, td3, 0);
00611
00612
00613 boff = dcast_base_hint (static_type, target_type);
00614
00615
00616 expr = save_expr (expr);
00617
00618 expr1 = expr;
00619 if (tc == REFERENCE_TYPE)
00620 expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
00621
00622 elems = tree_cons
00623 (NULL_TREE, expr1, tree_cons
00624 (NULL_TREE, td3, tree_cons
00625 (NULL_TREE, td2, tree_cons
00626 (NULL_TREE, boff, NULL_TREE))));
00627
00628 dcast_fn = dynamic_cast_node;
00629 if (!dcast_fn)
00630 {
00631 tree tmp;
00632 tree tinfo_ptr;
00633 tree ns = abi_node;
00634 const char *name;
00635
00636 push_nested_namespace (ns);
00637 tinfo_ptr = xref_tag (class_type,
00638 get_identifier ("__class_type_info"),
00639 ts_current, false);
00640
00641 tinfo_ptr = build_pointer_type
00642 (build_qualified_type
00643 (tinfo_ptr, TYPE_QUAL_CONST));
00644 name = "__dynamic_cast";
00645 tmp = tree_cons
00646 (NULL_TREE, const_ptr_type_node, tree_cons
00647 (NULL_TREE, tinfo_ptr, tree_cons
00648 (NULL_TREE, tinfo_ptr, tree_cons
00649 (NULL_TREE, ptrdiff_type_node, void_list_node))));
00650 tmp = build_function_type (ptr_type_node, tmp);
00651 dcast_fn = build_library_fn_ptr (name, tmp);
00652 DECL_IS_PURE (dcast_fn) = 1;
00653 pop_nested_namespace (ns);
00654 dynamic_cast_node = dcast_fn;
00655 }
00656 result = build_cxx_call (dcast_fn, elems);
00657
00658 if (tc == REFERENCE_TYPE)
00659 {
00660 tree bad = throw_bad_cast ();
00661
00662 result = save_expr (result);
00663 return build3 (COND_EXPR, type, result, result, bad);
00664 }
00665
00666
00667 result = cp_convert (type, result);
00668 return ifnonnull (expr, result);
00669 }
00670 }
00671 else
00672 errstr = "source type is not polymorphic";
00673
00674 fail:
00675 error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)",
00676 expr, exprtype, type, errstr);
00677 return error_mark_node;
00678 }
00679
00680 tree
00681 build_dynamic_cast (tree type, tree expr)
00682 {
00683 if (type == error_mark_node || expr == error_mark_node)
00684 return error_mark_node;
00685
00686 if (processing_template_decl)
00687 {
00688 expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
00689 TREE_SIDE_EFFECTS (expr) = 1;
00690
00691 return expr;
00692 }
00693
00694 return convert_from_reference (build_dynamic_cast_1 (type, expr));
00695 }
00696
00697
00698
00699 static int
00700 qualifier_flags (tree type)
00701 {
00702 int flags = 0;
00703 int quals = cp_type_quals (type);
00704
00705 if (quals & TYPE_QUAL_CONST)
00706 flags |= 1;
00707 if (quals & TYPE_QUAL_VOLATILE)
00708 flags |= 2;
00709 if (quals & TYPE_QUAL_RESTRICT)
00710 flags |= 4;
00711 return flags;
00712 }
00713
00714
00715
00716
00717 static bool
00718 target_incomplete_p (tree type)
00719 {
00720 while (true)
00721 if (TYPE_PTRMEM_P (type))
00722 {
00723 if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
00724 return true;
00725 type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
00726 }
00727 else if (TREE_CODE (type) == POINTER_TYPE)
00728 type = TREE_TYPE (type);
00729 else
00730 return !COMPLETE_OR_VOID_TYPE_P (type);
00731 }
00732
00733
00734
00735
00736
00737 static bool
00738 involves_incomplete_p (tree type)
00739 {
00740 switch (TREE_CODE (type))
00741 {
00742 case POINTER_TYPE:
00743 return target_incomplete_p (TREE_TYPE (type));
00744
00745 case OFFSET_TYPE:
00746 ptrmem:
00747 return
00748 (target_incomplete_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))
00749 || !COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)));
00750
00751 case RECORD_TYPE:
00752 if (TYPE_PTRMEMFUNC_P (type))
00753 goto ptrmem;
00754
00755 case UNION_TYPE:
00756 if (!COMPLETE_TYPE_P (type))
00757 return true;
00758
00759 default:
00760
00761 return false;
00762 }
00763 }
00764
00765
00766
00767
00768
00769
00770
00771 static tree
00772 tinfo_base_init (tree desc, tree target)
00773 {
00774 tree init = NULL_TREE;
00775 tree name_decl;
00776 tree vtable_ptr;
00777
00778 {
00779 tree name_name;
00780
00781
00782 tree name_type = build_cplus_array_type
00783 (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
00784 NULL_TREE);
00785 tree name_string = tinfo_name (target);
00786
00787
00788
00789 name_name = mangle_typeinfo_string_for_type (target);
00790 TREE_TYPE (name_name) = target;
00791
00792 name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
00793 SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
00794 DECL_ARTIFICIAL (name_decl) = 1;
00795 #ifdef KEY
00796 if (!flag_spin_file)
00797 #endif
00798 DECL_IGNORED_P (name_decl) = 1;
00799 TREE_READONLY (name_decl) = 1;
00800 TREE_STATIC (name_decl) = 1;
00801 DECL_EXTERNAL (name_decl) = 0;
00802 DECL_TINFO_P (name_decl) = 1;
00803 if (involves_incomplete_p (target))
00804 {
00805 TREE_PUBLIC (name_decl) = 0;
00806 DECL_INTERFACE_KNOWN (name_decl) = 1;
00807 }
00808 else
00809 set_linkage_according_to_type (target, name_decl);
00810 import_export_decl (name_decl);
00811 DECL_INITIAL (name_decl) = name_string;
00812 mark_used (name_decl);
00813 pushdecl_top_level_and_finish (name_decl, name_string);
00814 }
00815
00816 vtable_ptr = TINFO_VTABLE_DECL (desc);
00817 if (!vtable_ptr)
00818 {
00819 tree real_type;
00820
00821 push_nested_namespace (abi_node);
00822 real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
00823 ts_current, false);
00824 pop_nested_namespace (abi_node);
00825
00826 if (!COMPLETE_TYPE_P (real_type))
00827 {
00828
00829
00830
00831 SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
00832 CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
00833 }
00834
00835 vtable_ptr = get_vtable_decl (real_type, 1);
00836 vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);
00837
00838
00839 vtable_ptr = build2
00840 (PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
00841 size_binop (MULT_EXPR,
00842 size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
00843 TYPE_SIZE_UNIT (vtable_entry_type)));
00844
00845 TINFO_VTABLE_DECL (desc) = vtable_ptr;
00846 }
00847
00848 init = tree_cons (NULL_TREE, vtable_ptr, init);
00849
00850 init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
00851
00852 init = build_constructor (NULL_TREE, nreverse (init));
00853 TREE_CONSTANT (init) = 1;
00854 TREE_INVARIANT (init) = 1;
00855 TREE_STATIC (init) = 1;
00856 init = tree_cons (NULL_TREE, init, NULL_TREE);
00857
00858 return init;
00859 }
00860
00861
00862
00863
00864
00865 static tree
00866 generic_initializer (tree desc, tree target)
00867 {
00868 tree init = tinfo_base_init (desc, target);
00869
00870 init = build_constructor (NULL_TREE, init);
00871 TREE_CONSTANT (init) = 1;
00872 TREE_INVARIANT (init) = 1;
00873 TREE_STATIC (init) = 1;
00874 return init;
00875 }
00876
00877
00878
00879
00880
00881 static tree
00882 ptr_initializer (tree desc, tree target)
00883 {
00884 tree init = tinfo_base_init (desc, target);
00885 tree to = TREE_TYPE (target);
00886 int flags = qualifier_flags (to);
00887 bool incomplete = target_incomplete_p (to);
00888
00889 if (incomplete)
00890 flags |= 8;
00891 init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init);
00892 init = tree_cons (NULL_TREE,
00893 get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
00894 init);
00895
00896 init = build_constructor (NULL_TREE, nreverse (init));
00897 TREE_CONSTANT (init) = 1;
00898 TREE_INVARIANT (init) = 1;
00899 TREE_STATIC (init) = 1;
00900 return init;
00901 }
00902
00903
00904
00905
00906
00907
00908 static tree
00909 ptm_initializer (tree desc, tree target)
00910 {
00911 tree init = tinfo_base_init (desc, target);
00912 tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
00913 tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
00914 int flags = qualifier_flags (to);
00915 bool incomplete = target_incomplete_p (to);
00916
00917 if (incomplete)
00918 flags |= 0x8;
00919 if (!COMPLETE_TYPE_P (klass))
00920 flags |= 0x10;
00921 init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init);
00922 init = tree_cons (NULL_TREE,
00923 get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
00924 init);
00925 init = tree_cons (NULL_TREE,
00926 get_tinfo_ptr (klass),
00927 init);
00928
00929 init = build_constructor (NULL_TREE, nreverse (init));
00930 TREE_CONSTANT (init) = 1;
00931 TREE_INVARIANT (init) = 1;
00932 TREE_STATIC (init) = 1;
00933 return init;
00934 }
00935
00936
00937
00938
00939
00940 static tree
00941 class_initializer (tree desc, tree target, tree trail)
00942 {
00943 tree init = tinfo_base_init (desc, target);
00944
00945 TREE_CHAIN (init) = trail;
00946 init = build_constructor (NULL_TREE, init);
00947 TREE_CONSTANT (init) = 1;
00948 TREE_INVARIANT (init) = 1;
00949 TREE_STATIC (init) = 1;
00950 return init;
00951 }
00952
00953
00954
00955
00956 static bool
00957 typeinfo_in_lib_p (tree type)
00958 {
00959
00960
00961 if (TREE_CODE (type) == POINTER_TYPE
00962 && (cp_type_quals (TREE_TYPE (type)) == TYPE_QUAL_CONST
00963 || cp_type_quals (TREE_TYPE (type)) == TYPE_UNQUALIFIED))
00964 type = TREE_TYPE (type);
00965
00966 switch (TREE_CODE (type))
00967 {
00968 case INTEGER_TYPE:
00969 case BOOLEAN_TYPE:
00970 case CHAR_TYPE:
00971 case REAL_TYPE:
00972 case VOID_TYPE:
00973 return true;
00974
00975 default:
00976 return false;
00977 }
00978 }
00979
00980
00981
00982 static tree
00983 get_pseudo_ti_init (tree type, tree var_desc)
00984 {
00985 gcc_assert (at_eof);
00986 switch (TREE_CODE (type))
00987 {
00988 case OFFSET_TYPE:
00989 return ptm_initializer (var_desc, type);
00990 case POINTER_TYPE:
00991 return ptr_initializer (var_desc, type);
00992 case ENUMERAL_TYPE:
00993 return generic_initializer (var_desc, type);
00994 break;
00995 case FUNCTION_TYPE:
00996 return generic_initializer (var_desc, type);
00997 break;
00998 case ARRAY_TYPE:
00999 return generic_initializer (var_desc, type);
01000 break;
01001 case UNION_TYPE:
01002 case RECORD_TYPE:
01003 if (TYPE_PTRMEMFUNC_P (type))
01004 return ptm_initializer (var_desc, type);
01005 else if (var_desc == class_desc_type_node)
01006 return class_initializer (var_desc, type, NULL_TREE);
01007 else if (var_desc == si_class_desc_type_node)
01008 {
01009 tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0);
01010 tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
01011 tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
01012
01013 return class_initializer (var_desc, type, base_inits);
01014 }
01015 else
01016 {
01017 int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0)
01018 | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1));
01019 tree binfo = TYPE_BINFO (type);
01020 int nbases = BINFO_N_BASE_BINFOS (binfo);
01021 VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo);
01022 tree base_inits = NULL_TREE;
01023 int ix;
01024
01025
01026 for (ix = nbases; ix--;)
01027 {
01028 tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
01029 tree base_init = NULL_TREE;
01030 int flags = 0;
01031 tree tinfo;
01032 tree offset;
01033
01034 if (VEC_index (tree, base_accesses, ix) == access_public_node)
01035 flags |= 2;
01036 tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
01037 if (BINFO_VIRTUAL_P (base_binfo))
01038 {
01039
01040
01041 offset = BINFO_VPTR_FIELD (base_binfo);
01042 offset = convert (sizetype, offset);
01043 flags |= 1;
01044 }
01045 else
01046 offset = BINFO_OFFSET (base_binfo);
01047
01048
01049 offset = cp_build_binary_op (LSHIFT_EXPR, offset,
01050 build_int_cst (NULL_TREE, 8));
01051 offset = cp_build_binary_op (BIT_IOR_EXPR, offset,
01052 build_int_cst (NULL_TREE, flags));
01053 base_init = tree_cons (NULL_TREE, offset, base_init);
01054 base_init = tree_cons (NULL_TREE, tinfo, base_init);
01055 base_init = build_constructor (NULL_TREE, base_init);
01056 base_inits = tree_cons (NULL_TREE, base_init, base_inits);
01057 }
01058 base_inits = build_constructor (NULL_TREE, base_inits);
01059 base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
01060
01061 base_inits = tree_cons (NULL_TREE,
01062 build_int_cst (NULL_TREE, nbases),
01063 base_inits);
01064
01065 base_inits = tree_cons (NULL_TREE,
01066 build_int_cst (NULL_TREE, hint),
01067 base_inits);
01068
01069 return class_initializer (var_desc, type, base_inits);
01070 }
01071 break;
01072
01073 default:
01074 return generic_initializer (var_desc, type);
01075 }
01076 }
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093 static tree
01094 create_pseudo_type_info (const char *real_name, int ident, ...)
01095 {
01096 tree pseudo_type;
01097 char *pseudo_name;
01098 tree fields;
01099 tree field_decl;
01100 tree result;
01101 va_list ap;
01102
01103 va_start (ap, ident);
01104
01105
01106 pseudo_name = alloca (strlen (real_name) + 30);
01107 strcpy (pseudo_name, real_name);
01108 strcat (pseudo_name, "_pseudo");
01109 if (ident)
01110 sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
01111
01112
01113 fields = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
01114
01115
01116 while ((field_decl = va_arg (ap, tree)))
01117 {
01118 TREE_CHAIN (field_decl) = fields;
01119 fields = field_decl;
01120 }
01121
01122
01123 pseudo_type = make_aggr_type (RECORD_TYPE);
01124 finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
01125 CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
01126
01127 result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
01128 TINFO_REAL_NAME (result) = get_identifier (real_name);
01129 TINFO_PSEUDO_TYPE (result) =
01130 cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
01131
01132 va_end (ap);
01133 return result;
01134 }
01135
01136
01137
01138
01139
01140 static tree
01141 get_pseudo_ti_desc (tree type)
01142 {
01143 switch (TREE_CODE (type))
01144 {
01145 case OFFSET_TYPE:
01146 return ptm_desc_type_node;
01147 case POINTER_TYPE:
01148 return ptr_desc_type_node;
01149 case ENUMERAL_TYPE:
01150 return enum_desc_type_node;
01151 case FUNCTION_TYPE:
01152 return func_desc_type_node;
01153 case ARRAY_TYPE:
01154 return ary_desc_type_node;
01155 case UNION_TYPE:
01156 case RECORD_TYPE:
01157 if (TYPE_PTRMEMFUNC_P (type))
01158 return ptm_desc_type_node;
01159 else if (!COMPLETE_TYPE_P (type))
01160 {
01161 if (!at_eof)
01162 cxx_incomplete_type_error (NULL_TREE, type);
01163 return class_desc_type_node;
01164 }
01165 else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
01166 return class_desc_type_node;
01167 else
01168 {
01169 tree binfo = TYPE_BINFO (type);
01170 VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo);
01171 tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
01172 int num_bases = BINFO_N_BASE_BINFOS (binfo);
01173
01174 if (num_bases == 1
01175 && VEC_index (tree, base_accesses, 0) == access_public_node
01176 && !BINFO_VIRTUAL_P (base_binfo)
01177 && integer_zerop (BINFO_OFFSET (base_binfo)))
01178
01179 return si_class_desc_type_node;
01180 else
01181 {
01182 tree var_desc;
01183 tree array_domain, base_array;
01184
01185 if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
01186 {
01187 int ix;
01188 tree extend = make_tree_vec (num_bases + 5);
01189
01190 for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
01191 TREE_VEC_ELT (extend, ix)
01192 = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
01193 vmi_class_desc_type_node = extend;
01194 }
01195 var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
01196 if (var_desc)
01197 return var_desc;
01198
01199
01200
01201
01202
01203 if (abi_version_at_least (2))
01204 array_domain = build_index_type (size_int (num_bases - 1));
01205 else
01206 array_domain = build_index_type (size_int (num_bases));
01207 base_array =
01208 build_array_type (base_desc_type_node, array_domain);
01209
01210 push_nested_namespace (abi_node);
01211 var_desc = create_pseudo_type_info
01212 ("__vmi_class_type_info", num_bases,
01213 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
01214 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
01215 build_decl (FIELD_DECL, NULL_TREE, base_array),
01216 NULL);
01217 pop_nested_namespace (abi_node);
01218
01219 TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
01220 return var_desc;
01221 }
01222 }
01223 default:
01224 return bltn_desc_type_node;
01225 }
01226 }
01227
01228
01229
01230
01231 static void
01232 create_tinfo_types (void)
01233 {
01234 gcc_assert (!ti_desc_type_node);
01235
01236 push_nested_namespace (abi_node);
01237
01238
01239
01240 {
01241 tree field, fields;
01242
01243 ti_desc_type_node = make_aggr_type (RECORD_TYPE);
01244 field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
01245 fields = field;
01246
01247 field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
01248 TREE_CHAIN (field) = fields;
01249 fields = field;
01250
01251 finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo",
01252 fields, NULL_TREE);
01253 TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
01254 }
01255
01256
01257 bltn_desc_type_node = create_pseudo_type_info
01258 ("__fundamental_type_info", 0,
01259 NULL);
01260
01261
01262 ary_desc_type_node = create_pseudo_type_info
01263 ("__array_type_info", 0,
01264 NULL);
01265 func_desc_type_node = create_pseudo_type_info
01266 ("__function_type_info", 0,
01267 NULL);
01268 enum_desc_type_node = create_pseudo_type_info
01269 ("__enum_type_info", 0,
01270 NULL);
01271
01272
01273 class_desc_type_node = create_pseudo_type_info
01274 ("__class_type_info", 0,
01275 NULL);
01276
01277
01278
01279 si_class_desc_type_node = create_pseudo_type_info
01280 ("__si_class_type_info", 0,
01281 build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
01282 NULL);
01283
01284
01285
01286 {
01287 tree field, fields;
01288
01289 field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
01290 fields = field;
01291
01292 field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
01293 TREE_CHAIN (field) = fields;
01294 fields = field;
01295
01296 base_desc_type_node = make_aggr_type (RECORD_TYPE);
01297 finish_builtin_struct (base_desc_type_node, "__base_class_type_info_pseudo",
01298 fields, NULL_TREE);
01299 TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
01300 }
01301
01302
01303 vmi_class_desc_type_node = make_tree_vec (10);
01304
01305
01306
01307
01308 ptr_desc_type_node = create_pseudo_type_info
01309 ("__pointer_type_info", 0,
01310 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
01311 build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
01312 NULL);
01313
01314
01315
01316
01317 ptm_desc_type_node = create_pseudo_type_info
01318 ("__pointer_to_member_type_info", 0,
01319 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
01320 build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
01321 build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
01322 NULL);
01323
01324 pop_nested_namespace (abi_node);
01325 }
01326
01327
01328
01329
01330
01331
01332
01333 void
01334 emit_support_tinfos (void)
01335 {
01336 static tree *const fundamentals[] =
01337 {
01338 &void_type_node,
01339 &boolean_type_node,
01340 &wchar_type_node,
01341 &char_type_node, &signed_char_type_node, &unsigned_char_type_node,
01342 &short_integer_type_node, &short_unsigned_type_node,
01343 &integer_type_node, &unsigned_type_node,
01344 &long_integer_type_node, &long_unsigned_type_node,
01345 &long_long_integer_type_node, &long_long_unsigned_type_node,
01346 &float_type_node, &double_type_node, &long_double_type_node,
01347 0
01348 };
01349 int ix;
01350 tree bltn_type, dtor;
01351
01352 push_nested_namespace (abi_node);
01353 bltn_type = xref_tag (class_type,
01354 get_identifier ("__fundamental_type_info"),
01355 ts_current, false);
01356 pop_nested_namespace (abi_node);
01357 if (!COMPLETE_TYPE_P (bltn_type))
01358 return;
01359 dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
01360 if (!dtor || DECL_EXTERNAL (dtor))
01361 return;
01362 doing_runtime = 1;
01363 for (ix = 0; fundamentals[ix]; ix++)
01364 {
01365 tree bltn = *fundamentals[ix];
01366 tree types[3];
01367 int i;
01368
01369 types[0] = bltn;
01370 types[1] = build_pointer_type (bltn);
01371 types[2] = build_pointer_type (build_qualified_type (bltn,
01372 TYPE_QUAL_CONST));
01373
01374 for (i = 0; i < 3; ++i)
01375 {
01376 tree tinfo;
01377
01378 tinfo = get_tinfo_decl (types[i]);
01379 TREE_USED (tinfo) = 1;
01380 mark_needed (tinfo);
01381
01382
01383
01384
01385
01386
01387
01388 if (!flag_weak)
01389 {
01390 gcc_assert (TREE_PUBLIC (tinfo) && !DECL_COMDAT (tinfo));
01391 DECL_INTERFACE_KNOWN (tinfo) = 1;
01392 }
01393 }
01394 }
01395 }
01396
01397
01398
01399
01400
01401 bool
01402 emit_tinfo_decl (tree decl)
01403 {
01404 tree type = TREE_TYPE (DECL_NAME (decl));
01405 int in_library = typeinfo_in_lib_p (type);
01406 tree var_desc, var_init;
01407
01408 gcc_assert (DECL_TINFO_P (decl));
01409
01410 if (in_library)
01411 {
01412 if (doing_runtime)
01413 DECL_EXTERNAL (decl) = 0;
01414 else
01415 {
01416
01417
01418 DECL_INTERFACE_KNOWN (decl) = 1;
01419 return false;
01420 }
01421 }
01422 else if (involves_incomplete_p (type))
01423 {
01424 if (!decl_needed_p (decl))
01425 return false;
01426
01427
01428
01429
01430
01431 TREE_PUBLIC (decl) = 0;
01432 DECL_EXTERNAL (decl) = 0;
01433 DECL_INTERFACE_KNOWN (decl) = 1;
01434 }
01435
01436 import_export_decl (decl);
01437 #ifdef KEY
01438 if (DECL_NOT_REALLY_EXTERN (decl) &&
01439 (( flag_spin_file && decl_maybe_needed_p (decl)) ||
01440 (!flag_spin_file && decl_needed_p (decl))))
01441 #else
01442 if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
01443 #endif
01444 {
01445 DECL_EXTERNAL (decl) = 0;
01446 var_desc = get_pseudo_ti_desc (type);
01447 var_init = get_pseudo_ti_init (type, var_desc);
01448 DECL_INITIAL (decl) = var_init;
01449 mark_used (decl);
01450 cp_finish_decl (decl, var_init, NULL_TREE, 0);
01451
01452 #ifdef KEY
01453 if (flag_spin_file) {
01454 if (gspin_invoked(decl))
01455 gs_x(decl);
01456
01457 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
01458 TREE_NOT_EMITTED_BY_GXX (decl) = 0;
01459 else
01460
01461
01462 TREE_NOT_EMITTED_BY_GXX (decl) = 1;
01463 }
01464 #endif
01465
01466 return true;
01467 }
01468 else
01469 return false;
01470 }