diff options
Diffstat (limited to 'gcc/cp/rtti.c')
-rw-r--r-- | gcc/cp/rtti.c | 97 |
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; |