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