diff options
Diffstat (limited to 'contrib/gcc/cp/sig.c')
-rw-r--r-- | contrib/gcc/cp/sig.c | 161 |
1 files changed, 79 insertions, 82 deletions
diff --git a/contrib/gcc/cp/sig.c b/contrib/gcc/cp/sig.c index 65350db..f170df5 100644 --- a/contrib/gcc/cp/sig.c +++ b/contrib/gcc/cp/sig.c @@ -1,5 +1,5 @@ /* Functions dealing with signatures and signature pointers/references. - Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. Contributed by Gerald Baumgartner (gb@cs.purdue.edu) This file is part of GNU CC. @@ -33,18 +33,16 @@ extern struct obstack *current_obstack; extern struct obstack permanent_obstack; extern struct obstack *saveable_obstack; -extern void compiler_error (); - static tree save_this PROTO((tree)); static tree build_sptr_ref PROTO((tree)); static tree build_member_function_pointer PROTO((tree)); static void undo_casts PROTO((tree)); static tree build_signature_pointer_or_reference_name - PROTO((tree, int, int, int)); + PROTO((tree, int, int)); static void build_signature_pointer_or_reference_decl PROTO((tree, tree)); static tree build_signature_pointer_or_reference_type - PROTO((tree, int, int, int)); + PROTO((tree, int, int)); static tree get_sigtable_name PROTO((tree, tree)); static tree build_signature_table_constructor PROTO((tree, tree)); static int match_method_types PROTO((tree, tree)); @@ -58,25 +56,31 @@ static int global_sigtable_name_counter; can use it's name in function name mangling. */ static tree -build_signature_pointer_or_reference_name (to_type, constp, volatilep, refp) +build_signature_pointer_or_reference_name (to_type, type_quals, refp) tree to_type; - int constp, volatilep, refp; + int type_quals; + int refp; { - char * sig_name = TYPE_NAME_STRING (to_type); - int name_len = TYPE_NAME_LENGTH (to_type) + constp + volatilep; + const char * sig_name = TYPE_NAME_STRING (to_type); + int name_len = TYPE_NAME_LENGTH (to_type) + 3 /* Enough room for + C,V,R. */; char * name; + const char *const_rep = (type_quals & TYPE_QUAL_CONST) ? "C" : ""; + const char *restrict_rep = (type_quals & TYPE_QUAL_RESTRICT) ? "R" : ""; + const char *volatile_rep = (type_quals & TYPE_QUAL_VOLATILE) ? "C" : ""; + if (refp) { name = (char *) alloca (name_len + sizeof (SIGNATURE_REFERENCE_NAME) +2); sprintf (name, SIGNATURE_REFERENCE_NAME_FORMAT, - constp ? "C" : "", volatilep ? "V": "", sig_name); + const_rep, volatile_rep, restrict_rep, sig_name); } else { name = (char *) alloca (name_len + sizeof (SIGNATURE_POINTER_NAME) + 2); sprintf (name, SIGNATURE_POINTER_NAME_FORMAT, - constp ? "C" : "", volatilep ? "V": "", sig_name); + const_rep, volatile_rep, restrict_rep, sig_name); } return get_identifier (name); } @@ -98,21 +102,22 @@ build_signature_pointer_or_reference_decl (type, name) TREE_CHAIN (type) = decl; } -/* Construct, lay out and return the type of pointers or references - to signature TO_TYPE. If such a type has already been constructed, - reuse it. If CONSTP or VOLATILEP is specified, make the `optr' const - or volatile, respectively. If we are constructing a const/volatile - type variant and the main type variant doesn't exist yet, it is built - as well. If REFP is 1, we construct a signature reference, otherwise - a signature pointer is constructed. +/* Construct, lay out and return the type of pointers or references to + signature TO_TYPE. If such a type has already been constructed, + reuse it. If TYPE_QUALS are specified, qualify the `optr'. If we + are constructing a const/volatile type variant and the main type + variant doesn't exist yet, it is built as well. If REFP is 1, we + construct a signature reference, otherwise a signature pointer is + constructed. This function is a subroutine of `build_signature_pointer_type' and `build_signature_reference_type'. */ static tree -build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) +build_signature_pointer_or_reference_type (to_type, type_quals, refp) tree to_type; - int constp, volatilep, refp; + int type_quals; + int refp; { register tree t, m; register struct obstack *ambient_obstack = current_obstack; @@ -121,13 +126,11 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) m = refp ? SIGNATURE_REFERENCE_TO (to_type) : SIGNATURE_POINTER_TO (to_type); /* If we don't have the main variant yet, construct it. */ - if (m == NULL_TREE - && (constp || volatilep)) - m = build_signature_pointer_or_reference_type (to_type, 0, 0, refp); + if (m == NULL_TREE && type_quals != TYPE_UNQUALIFIED) + m = build_signature_pointer_or_reference_type (to_type, + TYPE_UNQUALIFIED, refp); /* Treat any nonzero argument as 1. */ - constp = !!constp; - volatilep = !!volatilep; refp = !!refp; /* If not generating auxiliary info, search the chain of variants to see @@ -141,8 +144,8 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) if (m && !flag_gen_aux_info) for (t = m; t; t = TYPE_NEXT_VARIANT (t)) - if (constp == TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t)))) - && volatilep == TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t))))) + if (type_quals == CP_TYPE_QUALS (TREE_TYPE (TREE_TYPE + (TYPE_FIELDS (t))))) return t; /* We need a new one. If TO_TYPE is permanent, make this permanent too. */ @@ -170,7 +173,7 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) t = make_lang_type (RECORD_TYPE); { - tree obj_type = build_type_variant (void_type_node, constp, volatilep); + tree obj_type = build_qualified_type (void_type_node, type_quals); tree optr_type = build_pointer_type (obj_type); tree optr, sptr; @@ -185,7 +188,8 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) sptr = TREE_CHAIN (TYPE_FIELDS (m)); else { - tree sig_tbl_type = cp_build_type_variant (to_type, 1, 0); + tree sig_tbl_type = + cp_build_qualified_type (to_type, TYPE_QUAL_CONST); sptr = build_lang_field_decl (FIELD_DECL, get_identifier (SIGNATURE_SPTR_NAME), @@ -203,12 +207,13 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) TYPE_ALIGN (optr_type)); /* A signature pointer/reference type isn't a `real' class type. */ - IS_AGGR_TYPE (t) = 0; + SET_IS_AGGR_TYPE (t, 0); } { - tree name = build_signature_pointer_or_reference_name (to_type, constp, - volatilep, refp); + tree name = build_signature_pointer_or_reference_name (to_type, + type_quals, + refp); /* Build a DECL node for this type, so the debugger has access to it. */ build_signature_pointer_or_reference_decl (t, name); @@ -250,23 +255,23 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) /* Construct, lay out and return the type of pointers to signature TO_TYPE. */ tree -build_signature_pointer_type (to_type, constp, volatilep) +build_signature_pointer_type (to_type) tree to_type; - int constp, volatilep; { return - build_signature_pointer_or_reference_type (to_type, constp, volatilep, 0); + build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type), + CP_TYPE_QUALS (to_type), 0); } /* Construct, lay out and return the type of pointers to signature TO_TYPE. */ tree -build_signature_reference_type (to_type, constp, volatilep) +build_signature_reference_type (to_type) tree to_type; - int constp, volatilep; { return - build_signature_pointer_or_reference_type (to_type, constp, volatilep, 1); + build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type), + CP_TYPE_QUALS (to_type), 1); } /* Return the name of the signature table (as an IDENTIFIER_NODE) @@ -281,8 +286,8 @@ get_sigtable_name (sig_type, rhs_type) char *buf = (char *) alloca (sizeof (SIGTABLE_NAME_FORMAT_LONG) + IDENTIFIER_LENGTH (sig_type_id) + IDENTIFIER_LENGTH (rhs_type_id) + 20); - char *sig_ptr = IDENTIFIER_POINTER (sig_type_id); - char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id); + const char *sig_ptr = IDENTIFIER_POINTER (sig_type_id); + const char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id); int i, j; for (i = 0; sig_ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) @@ -309,7 +314,7 @@ static tree build_member_function_pointer (member) tree member; { - char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member)); + const char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member)); int namlen = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (member)); char *name; tree entry; @@ -321,7 +326,7 @@ build_member_function_pointer (member) GNU_xref_ref (current_function_decl, name); entry = build_lang_field_decl (FIELD_DECL, get_identifier (name), - TYPE_MAIN_VARIANT (sigtable_entry_type)); + sigtable_entry_type); TREE_CONSTANT (entry) = 1; TREE_READONLY (entry) = 1; @@ -341,49 +346,45 @@ build_member_function_pointer (member) The new FIELD_DECLs are appended at the end of the last (and only) sublist of `list_of_fieldlists.' + T is the signature type. + As a side effect, each member function in the signature gets the `decl.ignored' bit turned on, so we don't output debug info for it. */ void -append_signature_fields (list_of_fieldlists) - tree list_of_fieldlists; +append_signature_fields (t) + tree t; { - tree l, x; - tree last_x = NULL_TREE; + tree x; tree mfptr; tree last_mfptr = NULL_TREE; tree mfptr_list = NULL_TREE; - /* For signatures it should actually be only a list with one element. */ - for (l = list_of_fieldlists; l; l = TREE_CHAIN (l)) + for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { - for (x = TREE_VALUE (l); x; x = TREE_CHAIN (x)) + if (TREE_CODE (x) == FUNCTION_DECL) { - if (TREE_CODE (x) == FUNCTION_DECL) + mfptr = build_member_function_pointer (x); + DECL_MEMFUNC_POINTER_TO (x) = mfptr; + DECL_MEMFUNC_POINTING_TO (mfptr) = x; + DECL_IGNORED_P (x) = 1; + DECL_IN_AGGR_P (mfptr) = 1; + if (! mfptr_list) + mfptr_list = last_mfptr = mfptr; + else { - mfptr = build_member_function_pointer (x); - DECL_MEMFUNC_POINTER_TO (x) = mfptr; - DECL_MEMFUNC_POINTING_TO (mfptr) = x; - DECL_IGNORED_P (x) = 1; - DECL_IN_AGGR_P (mfptr) = 1; - if (! mfptr_list) - mfptr_list = last_mfptr = mfptr; - else - { - TREE_CHAIN (last_mfptr) = mfptr; - last_mfptr = mfptr; - } + TREE_CHAIN (last_mfptr) = mfptr; + last_mfptr = mfptr; } - last_x = x; } } - /* Append the lists. */ - if (last_x && mfptr_list) - { - TREE_CHAIN (last_x) = mfptr_list; - TREE_CHAIN (last_mfptr) = NULL_TREE; - } + /* The member function pointers must come after the TYPE_DECLs, in + this case, because build_signature_table_constructor depends on + finding opaque TYPE_DECLS before the functions that make use of + them. */ + if (last_mfptr) + TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), mfptr_list); } /* Compare the types of a signature member function and a class member @@ -405,7 +406,7 @@ match_method_types (sig_mtype, class_mtype) tree class_arg_types = TYPE_ARG_TYPES (class_mtype); /* The return types have to be the same. */ - if (! comptypes (sig_return_type, class_return_type, 1)) + if (!same_type_p (sig_return_type, class_return_type)) return 0; /* Compare the first argument `this.' */ @@ -422,8 +423,7 @@ match_method_types (sig_mtype, class_mtype) /* If a signature method's `this' is const or volatile, so has to be the corresponding class method's `this.' */ - if ((TYPE_READONLY (sig_this) && ! TYPE_READONLY (class_this)) - || (TYPE_VOLATILE (sig_this) && ! TYPE_VOLATILE (class_this))) + if (!at_least_as_qualified_p (class_this, sig_this)) return 0; } @@ -431,7 +431,7 @@ match_method_types (sig_mtype, class_mtype) class_arg_types = TREE_CHAIN (class_arg_types); /* The number of arguments and the argument types have to be the same. */ - return compparms (sig_arg_types, class_arg_types, 3); + return compparms (sig_arg_types, class_arg_types); } /* Undo casts of opaque type variables to the RHS types. */ @@ -546,12 +546,10 @@ build_signature_table_constructor (sig_ty, rhs) break; if (rhs_methods == NULL_TREE - || (compute_access (basetypes, rhs_method) - != access_public_node)) + || !accessible_p (basetypes, rhs_method)) { - error ("class `%s' does not contain a method conforming to `%s'", - TYPE_NAME_STRING (rhstype), - fndecl_as_string (sig_method, 1)); + cp_error ("`%T' does not contain a method conforming to `%#D'", + rhstype, sig_method); undo_casts (sig_ty); return error_mark_node; } @@ -886,7 +884,7 @@ build_signature_pointer_constructor (lhs, rhs) } else { - if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)) + if (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)) readonly_error (lhs, "assignment", 0); optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR, @@ -980,9 +978,8 @@ build_signature_method_call (function, parms) tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))); TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) - = build_type_variant (build_pointer_type (basetype), - TYPE_READONLY (old_this), - TYPE_VOLATILE (old_this)); + = build_qualified_type (build_pointer_type (basetype), + TYPE_QUALS (old_this)); direct_call = build_function_call (pfn, new_parms); |