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