📄 gc.c
字号:
0, 0); else if (type == wchar_type_node) t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_WCHAR"), 0, 0); else if (type == void_type_node) t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_VOID"), 0, 0); else { cp_compiler_error ("type `%T' not handled as a built-in type"); } elems = tree_cons (NULL_TREE, t, NULL_TREE); return build_generic_desc (tdecl, __bltn_desc_type_node, elems);}/* Build an initializer for a __user_desc node. */static treebuild_user_desc (tdecl) tree tdecl;{ tree elems, name_string, t; tree tname = DECL_NAME (tdecl); name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname))); elems = name_string; return build_generic_desc (tdecl, __user_desc_type_node, elems);}/* Build an initializer for a __class_type_info node. */static treebuild_class_desc (tdecl, type) tree tdecl; tree type;{ tree tname = DECL_NAME (tdecl); tree name_string; int i = CLASSTYPE_N_BASECLASSES (type); int n_base = i; int base_cnt = 0; tree binfos = TYPE_BINFO_BASETYPES (type); tree vb = CLASSTYPE_VBASECLASSES (type); tree base, elems, access, offset, isvir; tree base_list, off_list, acc_list, isvir_list; tree t; static tree acc_pub = NULL_TREE; static tree acc_pro = NULL_TREE; static tree acc_pri = NULL_TREE; if (acc_pub == NULL_TREE) { acc_pub = lookup_field (__class_desc_type_node, get_identifier("_RTTI_ACCESS_PUBLIC"), 0, 0); acc_pro = lookup_field (__class_desc_type_node, get_identifier("_RTTI_ACCESS_PROTECTED"), 0, 0); acc_pri = lookup_field (__class_desc_type_node, get_identifier("_RTTI_ACCESS_PRIVATE"), 0, 0); } base_list = build_tree_list (NULL_TREE, integer_zero_node); off_list = build_tree_list (NULL_TREE, integer_zero_node); acc_list = build_tree_list (NULL_TREE, integer_zero_node); isvir_list = build_tree_list (NULL_TREE, integer_zero_node); while (--i >= 0) { tree binfo = TREE_VEC_ELT (binfos, i); base = build_t_desc (BINFO_TYPE (binfo), 1); if (TREE_VIA_VIRTUAL (binfo)) { tree t = BINFO_TYPE (binfo); char *name; tree field; int off; name = (char *) alloca (TYPE_NAME_LENGTH (t)+sizeof (VBASE_NAME)+1); sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (t)); field = lookup_field (type, get_identifier (name), 0, 0); offset = size_binop (FLOOR_DIV_EXPR, DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT)); } else offset = BINFO_OFFSET (binfo); if (TREE_VIA_PUBLIC (binfo)) access = acc_pub; else if (TREE_VIA_PROTECTED (binfo)) access = acc_pro; else access = acc_pri; if (TREE_VIA_VIRTUAL (binfo)) isvir = build_int_2 (1, 0); else isvir = build_int_2 (0, 0); base_list = tree_cons (NULL_TREE, base, base_list); isvir_list = tree_cons (NULL_TREE, isvir, isvir_list); acc_list = tree_cons (NULL_TREE, access, acc_list); off_list = tree_cons (NULL_TREE, offset, off_list); base_cnt++; }#if 0 i = n_base; while (vb) { tree b; access = acc_pub; while (--i >= 0) { b = TREE_VEC_ELT (binfos, i); if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b)) { if (TREE_VIA_PUBLIC (b)) access = acc_pub; else if (TREE_VIA_PROTECTED (b)) access = acc_pro; else access = acc_pri; break; } } base = build_t_desc (BINFO_TYPE (vb), 1); offset = BINFO_OFFSET (vb); isvir = build_int_2 (1, 0); base_list = tree_cons (NULL_TREE, base, base_list); isvir_list = tree_cons (NULL_TREE, isvir, isvir_list); acc_list = tree_cons (NULL_TREE, access, acc_list); off_list = tree_cons (NULL_TREE, offset, off_list); base_cnt++; vb = TREE_CHAIN (vb); }#endif base_list = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), base_list, 0); off_list = finish_table (NULL_TREE, integer_type_node, off_list, 0); isvir_list = finish_table (NULL_TREE, integer_type_node, isvir_list, 0); acc_list = finish_table (NULL_TREE, __access_mode_type_node, acc_list, 0); name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname))); elems = tree_cons (NULL_TREE, name_string, tree_cons (NULL_TREE, default_conversion (base_list), tree_cons (NULL_TREE, default_conversion (off_list), tree_cons (NULL_TREE, default_conversion (isvir_list), tree_cons (NULL_TREE, default_conversion (acc_list), tree_cons (NULL_TREE, build_int_2 (base_cnt, 0), NULL_TREE)))))); return build_generic_desc (tdecl, __class_desc_type_node, elems);}/* Build an initializer for a __pointer_type_info node. */static treebuild_ptr_desc (tdecl, type) tree tdecl; tree type;{ tree t, elems; t = TREE_TYPE (type); t = build_t_desc (t, 1); t = build_indirect_ref (t, NULL); elems = tree_cons (NULL_TREE, t, NULL_TREE); return build_generic_desc (tdecl, __ptr_desc_type_node, elems);}/* Build an initializer for a __attr_type_info node. */static treebuild_attr_desc (tdecl, type) tree tdecl; tree type;{ tree elems, t, attrval; if (TYPE_READONLY (type)) { if (TYPE_VOLATILE (type)) attrval = lookup_field (__attr_desc_type_node, get_identifier("_RTTI_ATTR_CONSTVOL"), 0, 0); else attrval = lookup_field (__attr_desc_type_node, get_identifier("_RTTI_ATTR_CONST"), 0, 0); } else { if (TYPE_VOLATILE (type)) attrval = lookup_field (__attr_desc_type_node, get_identifier("_RTTI_ATTR_VOLATILE"), 0, 0); } t = build_t_desc (TYPE_MAIN_VARIANT (type), 1); t = build_indirect_ref (t , NULL); elems = tree_cons (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE)); return build_generic_desc (tdecl, __attr_desc_type_node, elems);}/* Build an initializer for a __func_type_info node. */static treebuild_func_desc (tdecl) tree tdecl;{ tree elems, name_string; tree tname = DECL_NAME (tdecl); name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname))); elems = name_string; return build_generic_desc (tdecl, __func_desc_type_node, elems);}/* Build an initializer for a __ptmf_type_info node. */static treebuild_ptmf_desc (tdecl, type) tree tdecl; tree type;{ tree elems, name_string; tree tname = DECL_NAME (tdecl); name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname))); elems = name_string; return build_generic_desc (tdecl, __ptmf_desc_type_node, elems);}/* Build an initializer for a __ptmd_type_info node. */static treebuild_ptmd_desc (tdecl, type) tree tdecl; tree type;{ tree tc, t, elems; tc = build_t_desc (TYPE_OFFSET_BASETYPE (type), 1); tc = build_indirect_ref (tc , NULL); t = build_t_desc (TREE_TYPE (type), 1); t = build_indirect_ref (t , NULL); elems = tree_cons (NULL_TREE, tc, tree_cons (NULL_TREE, t, NULL_TREE)); return build_generic_desc (tdecl, __ptmd_desc_type_node, elems);}struct uninst_st { tree type; struct uninst_st *next;};typedef struct uninst_st uninst_node;static uninst_node * uninst_desc = (uninst_node *)NULL;static voidadd_uninstantiated_desc (type) tree type;{ uninst_node *t; t = (uninst_node *) xmalloc (sizeof (struct uninst_st)); t->type = type; t->next = uninst_desc; uninst_desc = t;}/* We may choose to link the emitting of certain high use TDs for certain objects, we do that here. Return the type to link against if such a link exists, otherwise just return TYPE. */treeget_def_to_follow (type) tree type;{#if 0 /* For now we don't lay out T&, T* TDs with the main TD for the object. */ /* Let T* and T& be written only when T is written (if T is an aggr). We do this for const, but not for volatile, since volatile is rare and const is not. */ if (!TYPE_VOLATILE (taggr) && (TREE_CODE (taggr) == POINTER_TYPE || TREE_CODE (taggr) == REFERENCE_TYPE) && IS_AGGR_TYPE (TREE_TYPE (taggr))) taggr = TREE_TYPE (taggr);#endif return type;}/* build a general type_info node. */treebuild_t_desc (type, definition) tree type; int definition;{ tree tdecl; tree tname, name_string; tree elems; tree t, tt, taggr; if (__ptmd_desc_type_node == NULL_TREE) { init_type_desc(); if (__ptmd_desc_type_node) { for ( ; uninst_desc; uninst_desc = uninst_desc->next ) build_t_desc (uninst_desc->type, 1); } } if (__t_desc_type_node == NULL_TREE) { static int warned = 0; if (! warned) { cp_error ("failed to build type descriptor node of '%T', maybe typeinfo.h not included", type); } warned = 1; return error_mark_node; } if (__ptmd_desc_type_node == NULL_TREE) { add_uninstantiated_desc (type); definition = 0; } push_obstacks (&permanent_obstack, &permanent_obstack); tname = build_t_desc_overload (type); if (!IDENTIFIER_AS_DESC (tname)) { tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node); DECL_EXTERNAL (tdecl) = 1; TREE_PUBLIC (tdecl) = 1; tdecl = pushdecl_top_level (tdecl); SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0)); if (!definition) cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0); } else tdecl = TREE_OPERAND (IDENTIFIER_AS_DESC (tname), 0); /* If it's not a definition, don't do anything more. */ if (!definition) return IDENTIFIER_AS_DESC (tname); /* If it has already been written, don't to anything more. */ /* Should this be on tdecl? */ if (TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname))) return IDENTIFIER_AS_DESC (tname); /* If we previously defined it, return the defined result. */ if (DECL_INITIAL (tdecl)) return IDENTIFIER_AS_DESC (tname); taggr = get_def_to_follow (type); /* If we know that we don't need to write out this type's vtable, then don't write out it's type_info. Somebody else will take care of that. */ if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr)) { /* Let's play follow the vtable. */ TREE_PUBLIC (tdecl) = CLASSTYPE_INTERFACE_KNOWN (taggr); DECL_EXTERNAL (tdecl) = CLASSTYPE_INTERFACE_ONLY (taggr); } else { DECL_EXTERNAL (tdecl) = 0; TREE_PUBLIC (tdecl) = (definition > 1); } if (DECL_EXTERNAL (tdecl)) return IDENTIFIER_AS_DESC (tname); /* Show that we are defining the t_desc for this type. */ DECL_INITIAL (tdecl) = error_mark_node; t = DECL_CONTEXT (tdecl); if ( t && TREE_CODE_CLASS (TREE_CODE (t)) == 't') pushclass (t, 2); if (TYPE_VOLATILE (type) || TYPE_READONLY (type)) t = build_attr_desc (tdecl, type); else if (TREE_CODE (type) == ARRAY_TYPE) t = build_ptr_desc (tdecl, type); else if (TREE_CODE (type) == POINTER_TYPE) { if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE) { type = TREE_TYPE (type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -