diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 397 |
1 files changed, 217 insertions, 180 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 5f054f0..fe5b861 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -710,7 +710,8 @@ build_vtable (binfo, type) /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ import_export_vtable (decl, type, 0); - IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl); + decl = pushdecl_top_level (decl); + SET_IDENTIFIER_GLOBAL_VALUE (name, decl); /* Initialize the association list for this type, based on our first approximation. */ TYPE_BINFO_VTABLE (type) = decl; @@ -1072,42 +1073,24 @@ void add_method (type, fields, method) tree type, *fields, method; { - /* We must make a copy of METHOD here, since we must be sure that - we have exclusive title to this method's DECL_CHAIN. */ - tree decl; - push_obstacks (&permanent_obstack, &permanent_obstack); - { - decl = copy_node (method); - if (DECL_RTL (decl) == 0 - && (!processing_template_decl - || !uses_template_parms (decl))) - { - make_function_rtl (decl); - DECL_RTL (method) = DECL_RTL (decl); - } - } if (fields && *fields) - { - /* Take care not to hide destructor. */ - DECL_CHAIN (decl) = DECL_CHAIN (*fields); - DECL_CHAIN (*fields) = decl; - } + *fields = build_overload (method, *fields); else if (CLASSTYPE_METHOD_VEC (type) == 0) { tree method_vec = make_node (TREE_VEC); - if (TYPE_IDENTIFIER (type) == DECL_NAME (decl)) + if (TYPE_IDENTIFIER (type) == DECL_NAME (method)) { /* ??? Is it possible for there to have been enough room in the current chunk for the tree_vec structure but not a tree_vec plus a tree*? Will this work in that case? */ obstack_free (current_obstack, method_vec); obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *)); - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) - TREE_VEC_ELT (method_vec, 1) = decl; + if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method))) + TREE_VEC_ELT (method_vec, 1) = method; else - TREE_VEC_ELT (method_vec, 0) = decl; + TREE_VEC_ELT (method_vec, 0) = method; TREE_VEC_LENGTH (method_vec) = 2; } else @@ -1117,7 +1100,7 @@ add_method (type, fields, method) plus a tree*? Will this work in that case? */ obstack_free (current_obstack, method_vec); obstack_blank (current_obstack, sizeof (struct tree_vec) + 2*sizeof (tree *)); - TREE_VEC_ELT (method_vec, 2) = decl; + TREE_VEC_ELT (method_vec, 2) = method; TREE_VEC_LENGTH (method_vec) = 3; obstack_finish (current_obstack); } @@ -1130,15 +1113,13 @@ add_method (type, fields, method) /* Adding a new ctor or dtor. This is easy because our METHOD_VEC always has a slot for such entries. */ - if (TYPE_IDENTIFIER (type) == DECL_NAME (decl)) + if (TYPE_IDENTIFIER (type) == DECL_NAME (method)) { - int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)); - /* TREE_VEC_ELT (method_vec, idx) = decl; */ - if (decl != TREE_VEC_ELT (method_vec, idx)) - { - DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, idx); - TREE_VEC_ELT (method_vec, idx) = decl; - } + int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)); + /* TREE_VEC_ELT (method_vec, idx) = method; */ + if (method != TREE_VEC_ELT (method_vec, idx)) + TREE_VEC_ELT (method_vec, idx) = + build_overload (method, TREE_VEC_ELT (method_vec, idx)); } else { @@ -1177,7 +1158,7 @@ add_method (type, fields, method) } obstack_finish (ob); - TREE_VEC_ELT (method_vec, len) = decl; + TREE_VEC_ELT (method_vec, len) = method; TREE_VEC_LENGTH (method_vec) = len + 1; CLASSTYPE_METHOD_VEC (type) = method_vec; @@ -1194,8 +1175,8 @@ add_method (type, fields, method) } } } - DECL_CONTEXT (decl) = type; - DECL_CLASS_CONTEXT (decl) = type; + DECL_CONTEXT (method) = type; + DECL_CLASS_CONTEXT (method) = type; pop_obstacks (); } @@ -1866,16 +1847,11 @@ grow_method (fndecl, method_vec_ptr) tree *testp = &TREE_VEC_ELT (method_vec, 2); while (testp < (tree *) obstack_next_free (&class_obstack) - && (*testp == NULL_TREE || DECL_NAME (*testp) != DECL_NAME (fndecl))) + && (*testp == NULL_TREE || DECL_NAME (OVL_CURRENT (*testp)) != DECL_NAME (fndecl))) testp++; if (testp < (tree *) obstack_next_free (&class_obstack)) - { - tree *p; - for (p = testp; *p; ) - p = &DECL_CHAIN (*p); - *p = fndecl; - } + *testp = build_overload (fndecl, *testp); else { obstack_ptr_grow (&class_obstack, fndecl); @@ -1966,14 +1942,14 @@ finish_struct_methods (t, fn_fields, nonprivate_method) if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields))) { /* Destructors go in slot 1. */ - DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 1); - TREE_VEC_ELT (method_vec, 1) = fn_fields; + TREE_VEC_ELT (method_vec, 1) = + build_overload (fn_fields, TREE_VEC_ELT (method_vec, 1)); } else { /* Constructors go in slot 0. */ - DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0); - TREE_VEC_ELT (method_vec, 0) = fn_fields; + TREE_VEC_ELT (method_vec, 0) = + build_overload (fn_fields, TREE_VEC_ELT (method_vec, 0)); } } else if (IDENTIFIER_TYPENAME_P (fn_name)) @@ -2057,7 +2033,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method) for (i = 2; i < len; i++) { TREE_VEC_ELT (baselink_vec, i) - = get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i))); + = get_baselinks (baselink_binfo, t, + DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))); if (TREE_VEC_ELT (baselink_vec, i) != 0) any_links = 1; } @@ -2098,8 +2075,8 @@ duplicate_tag_error (t) tree unchain = TREE_VEC_ELT (method_vec, i); while (unchain != NULL_TREE) { - TREE_CHAIN (unchain) = NULL_TREE; - unchain = DECL_CHAIN (unchain); + TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE; + unchain = OVL_NEXT (unchain); } } } @@ -3675,8 +3652,8 @@ finish_struct_1 (t, warn_anon) for (ctor = TREE_VEC_ELT (method_vec, 0); ctor; - ctor = DECL_CHAIN (ctor)) - if (! TREE_PRIVATE (ctor)) + ctor = OVL_NEXT (ctor)) + if (! TREE_PRIVATE (OVL_CURRENT (ctor))) { nonprivate_ctor = 1; break; @@ -3710,10 +3687,19 @@ finish_struct_1 (t, warn_anon) int i = 2; tree tmp; + /* Functions are represented as TREE_LIST, with the purpose + being the type and the value the functions. Other members + come as themselves. */ if (TREE_CODE (fdecl) == TREE_LIST) { + /* Ignore base type this came from. */ + fdecl = TREE_VALUE (fdecl); + } + if (TREE_CODE (fdecl) == OVERLOAD) + { + /* We later iterate over all functions. */ flist = fdecl; - fdecl = TREE_VALUE (flist); + fdecl = OVL_FUNCTION (flist); } name = DECL_NAME (fdecl); @@ -3746,12 +3732,11 @@ finish_struct_1 (t, warn_anon) /* Make type T see field decl FDECL with access ACCESS.*/ if (flist) { - fdecl = TREE_VALUE (flist); - while (fdecl) + while (flist) { - if (alter_access (t, fdecl, access) == 0) + if (alter_access (t, OVL_FUNCTION (flist), access) == 0) break; - fdecl = DECL_CHAIN (fdecl); + flist = OVL_CHAIN (flist); } } else @@ -4921,6 +4906,29 @@ pop_lang_context () /* Type instantiation routines. */ +static tree +validate_lhs (lhstype, complain) + tree lhstype; + int complain; +{ + if (TYPE_PTRMEMFUNC_P (lhstype)) + lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype); + + if (TREE_CODE (lhstype) == POINTER_TYPE) + { + if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE) + lhstype = TREE_TYPE (lhstype); + else + { + if (complain) + error ("invalid type combination for overload"); + return error_mark_node; + } + } + return lhstype; +} + /* This function will instantiate the type of the expression given in RHS to match the type of LHSTYPE. If errors exist, then return error_mark_node. If only complain is COMPLAIN is set. If we are @@ -4955,7 +4963,10 @@ instantiate_type (lhstype, rhs, complain) return error_mark_node; } - rhs = copy_node (rhs); + /* We don't overwrite rhs if it is an overloaded function. + Copying it would destroy the tree link. */ + if (TREE_CODE (rhs) != OVERLOAD) + rhs = copy_node (rhs); /* This should really only be used when attempting to distinguish what sort of a pointer to function we have. For now, any @@ -5016,6 +5027,9 @@ instantiate_type (lhstype, rhs, complain) return function; } + /* I could not trigger this code. MvL */ + my_friendly_abort (980326); +#if 0 my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178); my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE), @@ -5056,6 +5070,7 @@ instantiate_type (lhstype, rhs, complain) error ("no appropriate overload exists for COMPONENT_REF"); return error_mark_node; } +#endif return rhs; } @@ -5064,149 +5079,167 @@ instantiate_type (lhstype, rhs, complain) explicit_targs = TREE_OPERAND (rhs, 1); rhs = TREE_OPERAND (rhs, 0); } - /* fall through */ + /* fall through */ + my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401); - case TREE_LIST: + case OVERLOAD: { - tree elem, baselink, name = NULL_TREE; - int globals = overloaded_globals_p (rhs); + tree elem, elems; - /* First look for an exact match. Search either overloaded - functions or member functions. May have to undo what - `default_conversion' might do to lhstype. */ + /* First look for an exact match. Search overloaded + functions. May have to undo what `default_conversion' + might do to lhstype. */ - if (TYPE_PTRMEMFUNC_P (lhstype)) - lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype); + lhstype = validate_lhs (lhstype, complain); + if (lhstype == error_mark_node) + return lhstype; - if (TREE_CODE (lhstype) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE) - lhstype = TREE_TYPE (lhstype); - else - { - if (complain) - error ("invalid type combination for overload"); - return error_mark_node; - } - } - - if (TREE_CODE (lhstype) != FUNCTION_TYPE && globals > 0) + if (TREE_CODE (lhstype) != FUNCTION_TYPE) { + rhs = DECL_NAME (OVL_FUNCTION (rhs)); if (complain) - cp_error ("cannot resolve overloaded function `%D' based on non-function type", - TREE_PURPOSE (rhs)); + cp_error("cannot resolve overloaded function `%D' " + "based on non-function type", rhs); return error_mark_node; } - - if (globals > 0) - { - elem = get_first_fn (rhs); - /* If there are explicit_targs, only a template function - can match. */ - if (explicit_targs == NULL_TREE) - while (elem) + + elems = rhs; + /* If there are explicit_targs, only a template function + can match. */ + if (explicit_targs == NULL_TREE) + while (elems) + { + elem = OVL_FUNCTION (elems); + if (! comptypes (lhstype, TREE_TYPE (elem), 1)) + elems = OVL_CHAIN (elems); + else { - if (! comptypes (lhstype, TREE_TYPE (elem), 1)) - elem = DECL_CHAIN (elem); - else - { - mark_used (elem); - return elem; - } + mark_used (elem); + return elem; } + } - /* No exact match found, look for a compatible template. */ - { - tree save_elem = 0; - for (elem = get_first_fn (rhs); elem; elem = DECL_CHAIN (elem)) - if (TREE_CODE (elem) == TEMPLATE_DECL) + /* No exact match found, look for a compatible template. */ + { + tree save_elem = 0; + elems = rhs; + if (TREE_CODE (elems) == TREE_LIST) + elems = TREE_VALUE (rhs); + for (; elems; elems = OVL_NEXT (elems)) + if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL) + { + int n = DECL_NTPARMS (elem); + tree t = make_scratch_vec (n); + int i; + i = type_unification + (DECL_INNERMOST_TEMPLATE_PARMS (elem), t, + TYPE_ARG_TYPES (TREE_TYPE (elem)), + TYPE_ARG_TYPES (lhstype), explicit_targs, 1, 1); + if (i == 0) { - int n = DECL_NTPARMS (elem); - tree t = make_scratch_vec (n); - int i; - i = type_unification - (DECL_INNERMOST_TEMPLATE_PARMS (elem), t, - TYPE_ARG_TYPES (TREE_TYPE (elem)), - TYPE_ARG_TYPES (lhstype), explicit_targs, 1, 1); - if (i == 0) + if (save_elem) { - if (save_elem) - { - cp_error ("ambiguous template instantiation converting to `%#T'", lhstype); - return error_mark_node; - } - save_elem = instantiate_template (elem, t); - /* Check the return type. */ - if (! comptypes (TREE_TYPE (lhstype), - TREE_TYPE (TREE_TYPE (save_elem)), 1)) - save_elem = 0; + cp_error ("ambiguous template instantiation converting to `%#T'", lhstype); + return error_mark_node; } + save_elem = instantiate_template (elem, t); + /* Check the return type. */ + if (! comptypes (TREE_TYPE (lhstype), + TREE_TYPE (TREE_TYPE (save_elem)), 1)) + save_elem = 0; } - if (save_elem) - { - mark_used (save_elem); - return save_elem; - } + } + if (save_elem) + { + mark_used (save_elem); + return save_elem; } + } - /* If there are explicit_targs, only a template function - can match. */ - if (explicit_targs == NULL_TREE) + /* If there are explicit_targs, only a template function + can match. */ + if (explicit_targs == NULL_TREE) + { + /* No match found, look for a compatible function. */ + tree elems = rhs; + elems = rhs; + for (; elems; elems = OVL_NEXT (elems)) { - /* No match found, look for a compatible function. */ - elem = get_first_fn (rhs); - while (elem && comp_target_types (lhstype, - TREE_TYPE (elem), 1) <= 0) - elem = DECL_CHAIN (elem); - if (elem) + elem = OVL_CURRENT (elems); + if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0) + break; + } + if (elems) + { + tree save_elem = elem; + for (elems = OVL_CHAIN (elems); elems; + elems = OVL_CHAIN (elems)) + { + elem = OVL_FUNCTION (elems); + if (comp_target_types (lhstype, TREE_TYPE (elem), 0) > 0) + break; + } + if (elems) { - tree save_elem = elem; - elem = DECL_CHAIN (elem); - while (elem - && comp_target_types (lhstype, - TREE_TYPE (elem), 0) <= 0) - elem = DECL_CHAIN (elem); - if (elem) + if (complain) { - if (complain) - { - cp_error - ("cannot resolve overload to target type `%#T'", - lhstype); - cp_error_at (" ambiguity between `%#D'", - save_elem); - cp_error_at (" and `%#D', at least", elem); - } - return error_mark_node; + cp_error + ("cannot resolve overload to target type `%#T'", + lhstype); + cp_error_at (" ambiguity between `%#D'", save_elem); + cp_error_at (" and `%#D', at least", elem); } - mark_used (save_elem); - return save_elem; + return error_mark_node; } + mark_used (save_elem); + return save_elem; } - if (complain) - { - cp_error ("cannot resolve overload to target type `%#T'", - lhstype); - cp_error - (" because no suitable overload of function `%D' exists", - TREE_PURPOSE (rhs)); - } - return error_mark_node; } + if (complain) + { + cp_error ("cannot resolve overload to target type `%#T'", lhstype); + cp_error + (" because no suitable overload of function `%D' exists", + DECL_NAME (OVL_FUNCTION (rhs))); + } + return error_mark_node; + } + + case TREE_LIST: + { + tree elem, baselink, name = NULL_TREE; + + if (TREE_PURPOSE (rhs) == error_mark_node) + { + /* Make sure we don't drop the non-local flag, as the old code + would rely on it. */ + int nl = TREE_NONLOCAL_FLAG (rhs); + /* We don't need the type of this node. */ + rhs = TREE_VALUE (rhs); + my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331); + } + /* Now we should have a baselink. */ + my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC, 980331); + /* First look for an exact match. Search member functions. + May have to undo what `default_conversion' might do to + lhstype. */ + + lhstype = validate_lhs (lhstype, complain); + if (lhstype == error_mark_node) + return lhstype; if (TREE_NONLOCAL_FLAG (rhs)) { + my_friendly_abort (980401); /* Got to get it as a baselink. */ rhs = lookup_fnfields (TYPE_BINFO (current_class_type), - TREE_PURPOSE (rhs), 0); + DECL_NAME (OVL_FUNCTION (rhs)), 0); } else { my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181); - if (TREE_CODE (TREE_VALUE (rhs)) == TREE_LIST) - rhs = TREE_VALUE (rhs); - my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL, + my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL + || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD, 182); } @@ -5215,13 +5248,13 @@ instantiate_type (lhstype, rhs, complain) { elem = TREE_VALUE (baselink); while (elem) - if (comptypes (lhstype, TREE_TYPE (elem), 1)) + if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1)) { - mark_used (elem); - return elem; + mark_used (OVL_CURRENT (elem)); + return OVL_CURRENT (elem); } else - elem = DECL_CHAIN (elem); + elem = OVL_NEXT (elem); } /* No exact match found, look for a compatible method. */ @@ -5229,16 +5262,17 @@ instantiate_type (lhstype, rhs, complain) baselink = next_baselink (baselink)) { elem = TREE_VALUE (baselink); - while (elem && comp_target_types (lhstype, - TREE_TYPE (elem), 1) <= 0) - elem = DECL_CHAIN (elem); + for (; elem; elem = OVL_NEXT (elem)) + if (comp_target_types (lhstype, + TREE_TYPE (OVL_CURRENT (elem)), 1) > 0) + break; if (elem) { - tree save_elem = elem; - elem = DECL_CHAIN (elem); - while (elem && comp_target_types (lhstype, - TREE_TYPE (elem), 0) <= 0) - elem = DECL_CHAIN (elem); + tree save_elem = OVL_CURRENT (elem); + for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem)) + if (comp_target_types (lhstype, + TREE_TYPE (OVL_CURRENT (elem)), 0) > 0) + break; if (elem) { if (complain) @@ -5248,7 +5282,10 @@ instantiate_type (lhstype, rhs, complain) mark_used (save_elem); return save_elem; } - name = DECL_NAME (TREE_VALUE (rhs)); + name = rhs; + while (TREE_CODE (name) == TREE_LIST) + name = TREE_VALUE (name); + name = DECL_NAME (OVL_CURRENT (name)); #if 0 if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0) { |