aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/rtti.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/rtti.c')
-rw-r--r--gcc/cp/rtti.c97
1 files changed, 57 insertions, 40 deletions
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 0584d60785c..b40edfab763 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -62,13 +62,13 @@ Boston, MA 02111-1307, USA. */
/* Accessors for the type_info objects. We need to remember several things
about each of the type_info types. The global tree nodes such as
bltn_desc_type_node are TREE_LISTs, and these macros are used to access
- the required information. */
-/* The RECORD_TYPE of a type_info derived class. */
+ the required information. */
+/* The RECORD_TYPE of a type_info derived class. */
#define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
/* The VAR_DECL of the vtable for the type_info derived class.
- This is only filled in at the end of the translation. */
+ This is only filled in at the end of the translation. */
#define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
-/* The IDENTIFIER_NODE naming the real class. */
+/* The IDENTIFIER_NODE naming the real class. */
#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
static tree build_headof PARAMS((tree));
@@ -697,7 +697,7 @@ qualifier_flags (type)
return flags;
}
-/* Return non-zero, if the pointer chain TYPE ends at an incomplete type, or
+/* Return nonzero, if the pointer chain TYPE ends at an incomplete type, or
contains a pointer to member of an incomplete class. */
static int
@@ -923,7 +923,7 @@ dfs_class_hint_mark (binfo, data)
return NULL_TREE;
};
-/* Clear the base's dfs marks, after searching for duplicate bases. */
+/* Clear the base's dfs marks, after searching for duplicate bases. */
static tree
dfs_class_hint_unmark (binfo, data)
@@ -977,7 +977,7 @@ class_initializer (desc, target, trail)
return init;
}
-/* Returns non-zero if the typeinfo for type should be placed in
+/* Returns nonzero if the typeinfo for type should be placed in
the runtime library. */
static int
@@ -1006,7 +1006,7 @@ typeinfo_in_lib_p (type)
}
/* Generate the initializer for the type info describing
- TYPE. VAR_DESC is a . NON_PUBLIC_P is set non-zero, if the VAR_DECL
+ TYPE. VAR_DESC is a . NON_PUBLIC_P is set nonzero, if the VAR_DECL
should not be exported from this object file. This should only be
called at the end of translation, when we know that no further
types will be completed. */
@@ -1096,15 +1096,17 @@ get_pseudo_ti_init (type, var_desc, non_public_p)
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
+ TREE_HAS_CONSTRUCTOR (base_init) = 1;
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
}
base_inits = build (CONSTRUCTOR,
NULL_TREE, NULL_TREE, base_inits);
+ TREE_HAS_CONSTRUCTOR (base_inits) = 1;
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
- /* Prepend the hint flags. */
+ /* Prepend the hint flags. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (hint, 0), base_inits);
@@ -1137,8 +1139,7 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
{
tree pseudo_type;
char *pseudo_name;
- int ix;
- tree fields[10];
+ tree fields;
tree field_decl;
tree result;
@@ -1146,24 +1147,27 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
VA_FIXEDARG (ap, const char *, real_name);
VA_FIXEDARG (ap, int, ident);
- /* Generate the pseudo type name. */
+ /* Generate the pseudo type name. */
pseudo_name = (char *)alloca (strlen (real_name) + 30);
strcpy (pseudo_name, real_name);
strcat (pseudo_name, "_pseudo");
if (ident)
sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
- /* First field is the pseudo type_info base class. */
- fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
+ /* First field is the pseudo type_info base class. */
+ fields = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
/* Now add the derived fields. */
- for (ix = 0; (field_decl = va_arg (ap, tree));)
- fields[++ix] = field_decl;
+ while ((field_decl = va_arg (ap, tree)))
+ {
+ TREE_CHAIN (field_decl) = fields;
+ fields = field_decl;
+ }
- /* Create the pseudo type. */
+ /* Create the pseudo type. */
pseudo_type = make_aggr_type (RECORD_TYPE);
- finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
- TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
+ finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
+ CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
TINFO_REAL_NAME (result) = get_identifier (real_name);
@@ -1198,7 +1202,8 @@ get_pseudo_ti_desc (type)
return ptm_desc_type_node;
else if (!COMPLETE_TYPE_P (type))
{
- my_friendly_assert (at_eof, 20020609);
+ if (!at_eof)
+ cxx_incomplete_type_error (NULL_TREE, type);
return class_desc_type_node;
}
else if (!CLASSTYPE_N_BASECLASSES (type))
@@ -1213,7 +1218,7 @@ get_pseudo_ti_desc (type)
&& TREE_PUBLIC (base_binfo)
&& !TREE_VIA_VIRTUAL (base_binfo)
&& integer_zerop (BINFO_OFFSET (base_binfo)))
- /* single non-virtual public. */
+ /* single non-virtual public. */
return si_class_desc_type_node;
else
{
@@ -1271,13 +1276,18 @@ create_tinfo_types ()
/* Create the internal type_info structure. This is used as a base for
the other structures. */
{
- tree fields[2];
+ tree field, fields;
ti_desc_type_node = make_aggr_type (RECORD_TYPE);
- fields[0] = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
- fields[1] = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
- finish_builtin_type (ti_desc_type_node, "__type_info_pseudo",
- fields, 1, ptr_type_node);
+ field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
+ fields = field;
+
+ field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo",
+ fields, NULL_TREE);
TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
}
@@ -1286,7 +1296,7 @@ create_tinfo_types ()
("__fundamental_type_info", 0,
NULL);
- /* Array, function and enum type_info. No additional fields. */
+ /* Array, function and enum type_info. No additional fields. */
ary_desc_type_node = create_pseudo_type_info
("__array_type_info", 0,
NULL);
@@ -1310,24 +1320,29 @@ create_tinfo_types ()
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
- flags. */
+ flags. */
{
- tree fields[2];
+ tree field, fields;
+
+ field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
+ fields = field;
- fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
- fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
+ field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
base_desc_type_node = make_aggr_type (RECORD_TYPE);
- finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
- fields, 1, ptr_type_node);
+ finish_builtin_struct (base_desc_type_node, "__base_class_type_info_pseudo",
+ fields, NULL_TREE);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
}
- /* General hierarchy is created as necessary in this vector. */
+ /* General hierarchy is created as necessary in this vector. */
vmi_class_desc_type_node = make_tree_vec (10);
/* Pointer type_info. Adds two fields, qualification mask
and pointer to the pointed to type. This is really a descendant of
- __pbase_type_info. */
+ __pbase_type_info. */
ptr_desc_type_node = create_pseudo_type_info
("__pointer_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
@@ -1406,7 +1421,7 @@ emit_support_tinfos ()
}
}
-/* Return non-zero, iff T is a type_info variable which has not had a
+/* Return nonzero, iff T is a type_info variable which has not had a
definition emitted for it. */
int
@@ -1418,11 +1433,13 @@ unemitted_tinfo_decl_p (t, data)
TREE_CODE (t) == VAR_DECL
/* whos name points back to itself */
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
- /* whos name's type is non-null */
+ /* whose name's type is non-null */
&& TREE_TYPE (DECL_NAME (t))
- /* and whos type is a struct */
+ /* and whose type is a struct */
&& TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
- /* with a first field of our pseudo type info */
+ /* with a field */
+ && TYPE_FIELDS (TREE_TYPE (t))
+ /* which is our pseudo type info */
&& TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
return 1;
return 0;
@@ -1461,7 +1478,7 @@ emit_tinfo_decl (decl_ptr, data)
DECL_INITIAL (decl) = var_init;
cp_finish_decl (decl, var_init, NULL_TREE, 0);
- /* cp_finish_decl will have dealt with linkage. */
+ /* cp_finish_decl will have dealt with linkage. */
/* Say we've dealt with it. */
TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;