summaryrefslogtreecommitdiff
path: root/gcc/cp/rtti.c
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-24 10:23:26 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-24 10:23:26 +0000
commit73a07fbcfec4a0b7cc66c523eff37403197a1033 (patch)
tree21bfd0e3b183e40fad70bf7ba0161733857f0ff0 /gcc/cp/rtti.c
parent4b6b373f9115749e140cb97c2c742d2cd29835e9 (diff)
downloadgcc-73a07fbcfec4a0b7cc66c523eff37403197a1033.tar.gz
* cp-tree.h (CPTI_TP_DESC_TYPE, CPTI_ACCESS_MODE_TYPE,
CPTI_USER_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_ATTR_DESC_TYPE, CPTI_PTMF_DESC_TYPE): Remove cp_tree_index enumerations. (CPTI_TI_DESC_TYPE, CPTI_REF_DESC_TYPE, CPTI_ARY_DESC_TYPE, CPTI_ENUM_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_SI_CLASS_DESC_TYPE, CPTI_VMI_CLASS_DESC_TYPE, CPTI_BASE_DESC_TYPE): New enumerations. (CPTI_TINFO_FN_ID, CPTI_TINFO_FN_TYPE): Rename to ... (CPTI_TINFO_DECL_ID, CPTI_TINFO_DECL_TYPE): ... here. (CPTI_TINFO_VAR_ID): New enumeration. (__tp_desc_type_node, __access_mode_type_node, __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node, __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node, __ptmf_desc_type_node, __ptmd_desc_type_node): Remove #defines. (ti_desc_type_node, bltn_desc_type_node, ptr_desc_type_node, ref_desc_type_node, ary_desc_type_node, func_desc_type_node, enum_desc_type_node, class_desc_type_node, si_class_desc_type_node, vmi_class_desc_type_node, ptmd_desc_type_node, base_desc_type_node): New #defines. (tinfo_fn_id, tinfo_fn_type): Rename to ... (tinfo_decl_id, tinfo_decl_type): ... here. Adjust. (tinfo_var_id): New enumeration. (DECL_TINFO_FN_P): Augment comment. * decl.c (cp_global_trees): Adjust documentation. * rtti.c (init_rtti_processing): Adjust for tinfo_decl_id, tinfo_decl_type and tinfo_var_id. (get_tinfo_decl_dynamic): Adjust for tinfo_decl_type. (build_typeid): Remove unused variable. (get_tinfo_var): Use tinfo_var_id. (tinfo_name): New static function. (get_tinfo_decl): Adjust for tinfo_decl_id and tinfo_decl_type. (tinfo_from_decl): Likewise. (get_base_offset): New static function, broken out of expand_class_desc. (expand_si_desc): Use tinfo_name. (expand_class_desc): Likewise. Lose local static variable. Use base_desc_type_node. Use get_base_offset. (expand_ptr_desc): Use tinfo_name. (expand_attr_desc): Likewise. (expand_generic_desc): Likewise. * tinfo.cc (__GXX_ABI_VERSION): Test value and existance. * tinfo.h (__GXX_ABI_VERSION): Test value and existance. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31582 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/rtti.c')
-rw-r--r--gcc/cp/rtti.c134
1 files changed, 76 insertions, 58 deletions
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 079d5b481ed..71a54c544c3 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -40,6 +40,8 @@ static tree build_headof_sub PROTO((tree));
static tree build_headof PROTO((tree));
static tree get_tinfo_var PROTO((tree));
static tree ifnonnull PROTO((tree, tree));
+static tree tinfo_name PROTO((tree));
+static tree get_base_offset PROTO((tree, tree));
static tree build_dynamic_cast_1 PROTO((tree, tree));
static void expand_si_desc PROTO((tree, tree));
static void expand_class_desc PROTO((tree, tree));
@@ -60,11 +62,14 @@ init_rtti_processing ()
(class_type_node, get_identifier ("type_info"), 1);
if (flag_honor_std)
pop_namespace ();
- tinfo_fn_id = get_identifier ("__tf");
- tinfo_fn_type = build_function_type
- (build_reference_type (build_qualified_type (type_info_type_node,
- TYPE_QUAL_CONST)),
- void_list_node);
+
+ tinfo_decl_id = get_identifier ("__tf");
+ tinfo_decl_type = build_function_type
+ (build_reference_type
+ (build_qualified_type
+ (type_info_type_node, TYPE_QUAL_CONST)),
+ void_list_node);
+ tinfo_var_id = get_identifier ("__ti");
}
/* Given a pointer to an object with at least one virtual table
@@ -224,7 +229,7 @@ get_tinfo_decl_dynamic (exp)
t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
else
t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
- TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
+ TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
return t;
}
@@ -238,7 +243,6 @@ build_typeid (exp)
tree exp;
{
tree cond = NULL_TREE;
- tree type;
int nonnull = 0;
if (! flag_rtti)
@@ -287,7 +291,7 @@ static tree
get_tinfo_var (type)
tree type;
{
- tree tname = build_overload_with_type (get_identifier ("__ti"), type);
+ tree tname = build_overload_with_type (tinfo_var_id, type);
tree arrtype;
int size;
@@ -325,11 +329,21 @@ get_tinfo_var (type)
return declare_global_var (tname, arrtype);
}
+/* Generate the NTBS name of a type. */
+static tree
+tinfo_name (type)
+ tree type;
+{
+ const char *name = build_overload_name (type, 1, 1);
+ tree name_string = combine_strings (build_string (strlen (name) + 1, name));
+ return name_string;
+}
+
/* Returns a decl for a function or variable which can be used to obtain a
type_info object for TYPE. The old-abi uses functions, the new-abi will
use the type_info object directly. You can take the address of the
- returned decl, to save the decl. To use the generator call
- tinfo_from_generator. You must arrange that the decl is mark_used, if
+ returned decl, to save the decl. To use the decl call
+ tinfo_from_decl. You must arrange that the decl is mark_used, if
actually use it --- decls in vtables are only used if the vtable is
output. */
@@ -346,12 +360,12 @@ get_tinfo_decl (type)
type = build_function_type (TREE_TYPE (type),
TREE_CHAIN (TYPE_ARG_TYPES (type)));
- name = build_overload_with_type (tinfo_fn_id, type);
+ name = build_overload_with_type (tinfo_decl_id, type);
if (IDENTIFIER_GLOBAL_VALUE (name))
return IDENTIFIER_GLOBAL_VALUE (name);
- d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type);
+ d = build_lang_decl (FUNCTION_DECL, name, tinfo_decl_type);
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (d) = 1;
@@ -373,7 +387,7 @@ static tree
tinfo_from_decl (expr)
tree expr;
{
- tree t = build_call (expr, TREE_TYPE (tinfo_fn_type), NULL_TREE);
+ tree t = build_call (expr, TREE_TYPE (tinfo_decl_type), NULL_TREE);
return t;
}
@@ -439,6 +453,42 @@ ifnonnull (test, result)
result);
}
+/* Generate the constant expression describing where direct base BINFO
+ appears within the PARENT. How to interpret this expression depends on
+ details of the ABI, which the runtime must be aware of. */
+
+static tree
+get_base_offset (binfo, parent)
+ tree binfo;
+ tree parent;
+{
+ tree offset;
+
+ if (!TREE_VIA_VIRTUAL (binfo))
+ offset = BINFO_OFFSET (binfo);
+ else if (!vbase_offsets_in_vtable_p ())
+ {
+ tree t = BINFO_TYPE (binfo);
+ const char *name;
+ tree field;
+
+ FORMAT_VBASE_NAME (name, t);
+ field = lookup_field (parent, get_identifier (name), 0, 0);
+ offset = size_binop (FLOOR_DIV_EXPR,
+ DECL_FIELD_BITPOS (field),
+ size_int (BITS_PER_UNIT));
+ offset = convert (sizetype, offset);
+ }
+ else
+ {
+ /* Under the new ABI, we store the vtable offset at which
+ the virtual base offset can be found. */
+ tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), parent);
+ offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
+ }
+ return offset;
+}
+
/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
paper. */
@@ -710,8 +760,7 @@ expand_si_desc (tdecl, type)
tree type;
{
tree t, elems, fn;
- const char *name = build_overload_name (type, 1, 1);
- tree name_string = combine_strings (build_string (strlen (name)+1, name));
+ tree name_string = tinfo_name (type);
type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
finish_expr_stmt (get_typeid_1 (type));
@@ -756,7 +805,6 @@ expand_class_desc (tdecl, type)
{
tree name_string;
tree fn, tmp;
- const char *name;
int i = CLASSTYPE_N_BASECLASSES (type);
int base_cnt = 0;
@@ -768,15 +816,14 @@ expand_class_desc (tdecl, type)
#endif
tree base, elems, access, offset, isvir;
tree elt, elts = NULL_TREE;
- static tree base_info_type_node;
- if (base_info_type_node == NULL_TREE)
+ if (base_desc_type_node == NULL_TREE)
{
tree fields [4];
/* A reasonably close approximation of __class_type_info::base_info */
- base_info_type_node = make_aggr_type (RECORD_TYPE);
+ base_desc_type_node = make_aggr_type (RECORD_TYPE);
/* Actually const __user_type_info * */
fields [0] = build_lang_decl
@@ -801,7 +848,7 @@ expand_class_desc (tdecl, type)
DECL_BIT_FIELD (fields[3]) = 1;
DECL_FIELD_SIZE (fields[3]) = 2;
- finish_builtin_type (base_info_type_node, "__base_info", fields,
+ finish_builtin_type (base_desc_type_node, "__base_info", fields,
3, ptr_type_node);
}
@@ -811,33 +858,8 @@ expand_class_desc (tdecl, type)
finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
-
- if (TREE_VIA_VIRTUAL (binfo))
- {
- if (!vbase_offsets_in_vtable_p ())
- {
- tree t = BINFO_TYPE (binfo);
- const char *name;
- tree field;
-
- FORMAT_VBASE_NAME (name, 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));
- offset = convert (sizetype, offset);
- }
- else
- {
- /* Under the new ABI, we store the vtable offset at which
- the virtual base offset can be found. */
- tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), type);
- offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
- }
- }
- else
- offset = BINFO_OFFSET (binfo);
-
+ offset = get_base_offset (binfo, type);
+
if (TREE_VIA_PUBLIC (binfo))
access = access_public_node;
else if (TREE_VIA_PROTECTED (binfo))
@@ -850,7 +872,7 @@ expand_class_desc (tdecl, type)
isvir = boolean_false_node;
elt = build
- (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons
+ (CONSTRUCTOR, base_desc_type_node, NULL_TREE, tree_cons
(NULL_TREE, base, tree_cons
(NULL_TREE, offset, tree_cons
(NULL_TREE, isvir, tree_cons
@@ -893,11 +915,10 @@ expand_class_desc (tdecl, type)
}
#endif
- name = build_overload_name (type, 1, 1);
- name_string = combine_strings (build_string (strlen (name)+1, name));
+ name_string = tinfo_name (type);
{
- tree arrtype = build_array_type (base_info_type_node, NULL_TREE);
+ tree arrtype = build_array_type (base_desc_type_node, NULL_TREE);
elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
= TREE_STATIC (elts) = 1;
@@ -919,7 +940,7 @@ expand_class_desc (tdecl, type)
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, tree_cons
- (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons
+ (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
(NULL_TREE, sizetype, void_list_node))));
tmp = build_function_type (void_type_node, tmp);
@@ -944,8 +965,7 @@ expand_ptr_desc (tdecl, type)
tree type;
{
tree t, elems, fn;
- const char *name = build_overload_name (type, 1, 1);
- tree name_string = combine_strings (build_string (strlen (name)+1, name));
+ tree name_string = tinfo_name (type);
type = TREE_TYPE (type);
finish_expr_stmt (get_typeid_1 (type));
@@ -989,8 +1009,7 @@ expand_attr_desc (tdecl, type)
tree type;
{
tree elems, t, fn;
- const char *name = build_overload_name (type, 1, 1);
- tree name_string = combine_strings (build_string (strlen (name)+1, name));
+ tree name_string = tinfo_name (type);
tree attrval = build_int_2 (TYPE_QUALS (type), 0);
finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
@@ -1035,8 +1054,7 @@ expand_generic_desc (tdecl, type, fnname)
tree type;
const char *fnname;
{
- const char *name = build_overload_name (type, 1, 1);
- tree name_string = combine_strings (build_string (strlen (name)+1, name));
+ tree name_string = tinfo_name (type);
tree elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), NULL_TREE));