From: Mark Mitchell Date: Fri, 16 Jul 2004 01:15:43 +0000 (+0000) Subject: vec.h (VEC_address): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=aaaa46d2b0cb797b68b079e6f7b9deb5bcb4a774;p=gcc.git vec.h (VEC_address): New function. * vec.h (VEC_address): New function. * cp-tree.h (lang_type_class): Remove has_real_assign_ref and has_abstract_assign_ref. Make methods a VEC(tree) *. (TYPE_HAS_CONST_ASSIGN_REF): Add documentation. (CLASSTYPE_CONSTRUCTORS): Adjust for changes to CLASSTYPE_METHOD_VEC. (CLASSTYPE_DESTRUCTORS): Likewise. (TYPE_HAS_REAL_ASSIGN_REF): Remove. (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise. (add_method): Change prototoype. * class.c (add_method): Remove error_p parameter. Adjust for changes to CLASSTYPE_METHOD_VEC. (handle_using_decl): Adjust call to add_method. (maybe_warn_about_overly_private_class): Adjust for changes to CLASSTYPE_METHOD_VEC. (resort_type_method_vec): Likewise. (finish_struct_methods): Likewise. (check_for_override): Likewise. (warn_hidden): Likewise. (add_implicitly_declared_members): Defer creation of assignment operators. Adjust call to add_method. (clone_function_decl): Adjust call to add_method. (check_bases_and_members): Don't set TYPE_HAS_REAL_ASSIGN_REF. (finish_struct_1): Use CLASSTYPE_DESTRUCTORS. * decl.c (grok_special_member_properties): Don't set TYPE_HAS_ABSTRACT_ASSIGN_REF. * decl2.c (check_classfn): Adjust for changes to CLASSTYPE_METHOD_VEC. * method.c (locate_dtor): Use CLASSTYPE_DESTRUCTORS. (locate_ctor): Use CLASSTYPE_CONSTRUCTORS. (locate_copy): Adjust for changes to CLASSTYPE_METHOD_VEC. (implicitly_declare_fn): Set DECL_SOURCE_LOCATION. Do not call cp_finish_decl. * pt.c (check_explicit_specialization): Adjust for changes to CLASSTYPE_METHOD_VEC. (instantiate_class_template): Do not set TYPE_HAS_ABSTRACT_ASSIGN_REF. * ptree.c (cxx_print_type): Don't try to print CLASSTYPE_METHOD_VEC. * rtti.c (emit_support_tinfos): Use CLASSTYPE_DESTRUCTORS. * search.c (lookup_field_r): Adjust for changes to CLASSTYPE_METHOD_VEC. (lookup_fnfields): Likewise. (lookup_conversion_operator): Likewise. (lookup_fnfields_1): Likewise. Create assignment operators lazily. (look_for_overrides_here): Adjust for changes to CLASSTYPE_METHOD_VEC. (add_conversions): Likewise. * semantics.c (finish_member_declaration): Adjust call to add_method. From-SVN: r84796 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c1b4a8b88c..ae44c8b9e91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2004-07-15 Nathan Sidwell + + * vec.h (VEC_address): New function. + 2004-07-14 Jason Merrill PR middle-end/15885 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 830fc4b69fe..6a3bb289e70 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,54 @@ +2004-07-15 Mark Mitchell + + * cp-tree.h (lang_type_class): Remove has_real_assign_ref and + has_abstract_assign_ref. Make methods a VEC(tree) *. + (TYPE_HAS_CONST_ASSIGN_REF): Add documentation. + (CLASSTYPE_CONSTRUCTORS): Adjust for changes to CLASSTYPE_METHOD_VEC. + (CLASSTYPE_DESTRUCTORS): Likewise. + (TYPE_HAS_REAL_ASSIGN_REF): Remove. + (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise. + (add_method): Change prototoype. + * class.c (add_method): Remove error_p parameter. Adjust for + changes to CLASSTYPE_METHOD_VEC. + (handle_using_decl): Adjust call to add_method. + (maybe_warn_about_overly_private_class): Adjust for + changes to CLASSTYPE_METHOD_VEC. + (resort_type_method_vec): Likewise. + (finish_struct_methods): Likewise. + (check_for_override): Likewise. + (warn_hidden): Likewise. + (add_implicitly_declared_members): Defer creation of assignment + operators. Adjust call to add_method. + (clone_function_decl): Adjust call to add_method. + (check_bases_and_members): Don't set TYPE_HAS_REAL_ASSIGN_REF. + (finish_struct_1): Use CLASSTYPE_DESTRUCTORS. + * decl.c (grok_special_member_properties): Don't set + TYPE_HAS_ABSTRACT_ASSIGN_REF. + * decl2.c (check_classfn): Adjust for + changes to CLASSTYPE_METHOD_VEC. + * method.c (locate_dtor): Use CLASSTYPE_DESTRUCTORS. + (locate_ctor): Use CLASSTYPE_CONSTRUCTORS. + (locate_copy): Adjust for changes to CLASSTYPE_METHOD_VEC. + (implicitly_declare_fn): Set DECL_SOURCE_LOCATION. Do not call + cp_finish_decl. + * pt.c (check_explicit_specialization): Adjust for + changes to CLASSTYPE_METHOD_VEC. + (instantiate_class_template): Do not set + TYPE_HAS_ABSTRACT_ASSIGN_REF. + * ptree.c (cxx_print_type): Don't try to print + CLASSTYPE_METHOD_VEC. + * rtti.c (emit_support_tinfos): Use CLASSTYPE_DESTRUCTORS. + * search.c (lookup_field_r): Adjust for + changes to CLASSTYPE_METHOD_VEC. + (lookup_fnfields): Likewise. + (lookup_conversion_operator): Likewise. + (lookup_fnfields_1): Likewise. Create assignment operators + lazily. + (look_for_overrides_here): Adjust for + changes to CLASSTYPE_METHOD_VEC. + (add_conversions): Likewise. + * semantics.c (finish_member_declaration): Adjust call to add_method. + 2004-07-15 Jason Merrill * cp-lang.c (cxx_types_compatible_p): To the middle-end, @@ -13,7 +64,7 @@ (copy_binfo): Declare. 2004-07-15 Mark Mitchell - + * name-lookup.c (set_inherited_value_binding_p): Add class_type parameter. (get_class_binding): Adjust. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 2957ac1be14..708c1b5b3eb 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -795,43 +795,42 @@ modify_vtable_entry (tree t, } -/* Add method METHOD to class TYPE. If ERROR_P is true, we are adding - the method after the class has already been defined because a - declaration for it was seen. (Even though that is erroneous, we - add the method for improved error recovery.) */ +/* Add method METHOD to class TYPE. */ void -add_method (tree type, tree method, int error_p) +add_method (tree type, tree method) { int using; - int len; - int slot; - tree method_vec; + size_t len; + size_t slot; tree overload; int template_conv_p; + VEC(tree) *method_vec; + bool complete_p; if (method == error_mark_node) return; - + + complete_p = COMPLETE_TYPE_P (type); using = (DECL_CONTEXT (method) != type); template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL && DECL_TEMPLATE_CONV_FN_P (method)); - if (!CLASSTYPE_METHOD_VEC (type)) - /* Make a new method vector. We start with 8 entries. We must - allocate at least two (for constructors and destructors), and - we're going to end up with an assignment operator at some point - as well. - - We could use a TREE_LIST for now, and convert it to a TREE_VEC - in finish_struct, but we would probably waste more memory - making the links in the list than we would by over-allocating - the size of the vector here. Furthermore, we would complicate - all the code that expects this to be a vector. */ - CLASSTYPE_METHOD_VEC (type) = make_tree_vec (8); - method_vec = CLASSTYPE_METHOD_VEC (type); - len = TREE_VEC_LENGTH (method_vec); + if (!method_vec) + { + /* Make a new method vector. We start with 8 entries. We must + allocate at least two (for constructors and destructors), and + we're going to end up with an assignment operator at some + point as well. */ + method_vec = VEC_alloc (tree, 8); + /* Create slots for constructors and destructors. */ + VEC_quick_push (tree, method_vec, NULL_TREE); + VEC_quick_push (tree, method_vec, NULL_TREE); + CLASSTYPE_METHOD_VEC (type) = method_vec; + } + + len = VEC_length (tree, method_vec); /* Constructors and destructors go in special slots. */ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method)) @@ -849,103 +848,52 @@ add_method (tree type, tree method, int error_p) } else { - int have_template_convs_p = 0; - + bool insert_p = true; + bool conv_p = DECL_CONV_FN_P (method); + tree m; + /* See if we already have an entry with this name. */ - for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot) + for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; + (m = VEC_iterate (tree, method_vec, slot)); + ++slot) { - tree m = TREE_VEC_ELT (method_vec, slot); - - if (!m) - break; m = OVL_CURRENT (m); - if (template_conv_p) { - have_template_convs_p = (TREE_CODE (m) == TEMPLATE_DECL - && DECL_TEMPLATE_CONV_FN_P (m)); - - /* If we need to move things up, see if there's - space. */ - if (!have_template_convs_p) - { - slot = len - 1; - if (TREE_VEC_ELT (method_vec, slot)) - slot++; - } + if (TREE_CODE (m) == TEMPLATE_DECL + && DECL_TEMPLATE_CONV_FN_P (m)) + insert_p = false; break; } - if (DECL_NAME (m) == DECL_NAME (method)) + if (conv_p && !DECL_CONV_FN_P (m)) break; - } - - if (slot == len) - { - /* We need a bigger method vector. */ - int new_len; - tree new_vec; - - /* In the non-error case, we are processing a class - definition. Double the size of the vector to give room - for new methods. */ - if (!error_p) - new_len = 2 * len; - /* In the error case, the vector is already complete. We - don't expect many errors, and the rest of the front-end - will get confused if there are empty slots in the vector. */ - else - new_len = len + 1; - - new_vec = make_tree_vec (new_len); - memcpy (&TREE_VEC_ELT (new_vec, 0), &TREE_VEC_ELT (method_vec, 0), - len * sizeof (tree)); - len = new_len; - method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec; - } - - if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot)) - { - /* Type conversion operators have to come before ordinary - methods; add_conversions depends on this to speed up - looking for conversion operators. So, if necessary, we - slide some of the vector elements up. In theory, this - makes this algorithm O(N^2) but we don't expect many - conversion operators. */ - if (template_conv_p) - slot = CLASSTYPE_FIRST_CONVERSION_SLOT; - else - for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot) - { - tree fn = TREE_VEC_ELT (method_vec, slot); - - if (!fn) - /* There are no more entries in the vector, so we - can insert the new conversion operator here. */ - break; - - if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) - /* We can insert the new function right at the - SLOTth position. */ - break; - } - - if (template_conv_p && have_template_convs_p) - /*OK*/; - else if (!TREE_VEC_ELT (method_vec, slot)) - /* There is nothing in the Ith slot, so we can avoid - moving anything. */ - ; - else + if (DECL_NAME (m) == DECL_NAME (method)) { - /* We know the last slot in the vector is empty - because we know that at this point there's room - for a new function. */ - memmove (&TREE_VEC_ELT (method_vec, slot + 1), - &TREE_VEC_ELT (method_vec, slot), - (len - slot - 1) * sizeof (tree)); - TREE_VEC_ELT (method_vec, slot) = NULL_TREE; + insert_p = false; + break; } + if (complete_p + && !DECL_CONV_FN_P (m) + && DECL_NAME (m) > DECL_NAME (method)) + break; } + + /* If we need a new slot, make room. */ + if (insert_p) + { + /* We expect to add few methods in the COMPLETE_P case, so + just make room for one more method. */ + if (complete_p) + VEC_reserve (tree, method_vec, 1); + if (slot == len) + VEC_safe_push (tree, method_vec, NULL_TREE); + else + VEC_safe_insert (tree, method_vec, slot, NULL_TREE); + len++; + /* Inserting a new slot may have caused the vector to be + reallocated. */ + CLASSTYPE_METHOD_VEC (type) = method_vec; + } } if (processing_template_decl) @@ -957,7 +905,7 @@ add_method (tree type, tree method, int error_p) tree fns; /* Check to see if we've already got this method. */ - for (fns = TREE_VEC_ELT (method_vec, slot); + for (fns = VEC_index (tree, method_vec, slot); fns; fns = OVL_NEXT (fns)) { @@ -1027,13 +975,14 @@ add_method (tree type, tree method, int error_p) } /* Add the new binding. */ - overload = build_overload (method, TREE_VEC_ELT (method_vec, slot)); + overload = build_overload (method, VEC_index (tree, method_vec, slot)); if (!DECL_CONSTRUCTOR_P (method) - && !DECL_DESTRUCTOR_P (method)) + && !DECL_DESTRUCTOR_P (method) + && !complete_p) push_class_level_binding (DECL_NAME (method), overload); /* Actually insert the new method. */ - TREE_VEC_ELT (method_vec, slot) = overload; + VEC_replace (tree, method_vec, slot, overload); } /* Subroutines of finish_struct. */ @@ -1171,7 +1120,7 @@ handle_using_decl (tree using_decl, tree t) if (flist) for (; flist; flist = OVL_NEXT (flist)) { - add_method (t, OVL_CURRENT (flist), /*error_p=*/0); + add_method (t, OVL_CURRENT (flist)); alter_access (t, OVL_CURRENT (flist), access); } else @@ -1637,9 +1586,7 @@ maybe_warn_about_overly_private_class (tree t) if (!TYPE_HAS_INIT_REF (t)) nonprivate_ctor = 1; else - for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); - fn; - fn = OVL_NEXT (fn)) + for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn)) { tree ctor = OVL_CURRENT (fn); /* Ideally, we wouldn't count copy constructors (or, in @@ -1721,24 +1668,24 @@ resort_type_method_vec (void* obj, gt_pointer_operator new_value, void* cookie) { - tree method_vec = obj; - int len = TREE_VEC_LENGTH (method_vec); - int slot; + VEC(tree) *method_vec = (VEC(tree) *) obj; + int len = VEC_length (tree, method_vec); + size_t slot; + tree fn; /* The type conversion ops have to live at the front of the vec, so we can't sort them. */ - for (slot = 2; slot < len; ++slot) - { - tree fn = TREE_VEC_ELT (method_vec, slot); - - if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) - break; - } + for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; + (fn = VEC_iterate (tree, method_vec, slot)); + ++slot) + if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) + break; + if (len - slot > 1) { resort_data.new_value = new_value; resort_data.cookie = cookie; - qsort (&TREE_VEC_ELT (method_vec, slot), len - slot, sizeof (tree), + qsort (VEC_address (tree, method_vec) + slot, len - slot, sizeof (tree), resort_method_name_cmp); } } @@ -1763,7 +1710,7 @@ static void finish_struct_methods (tree t) { tree fn_fields; - tree method_vec; + VEC(tree) *method_vec; int slot, len; if (!TYPE_METHODS (t)) @@ -1772,13 +1719,13 @@ finish_struct_methods (tree t) these incorrectly. */ TYPE_HAS_CONSTRUCTOR (t) = 0; TYPE_HAS_DESTRUCTOR (t) = 0; - CLASSTYPE_METHOD_VEC (t) = NULL_TREE; + CLASSTYPE_METHOD_VEC (t) = NULL; return; } method_vec = CLASSTYPE_METHOD_VEC (t); - my_friendly_assert (method_vec != NULL_TREE, 19991215); - len = TREE_VEC_LENGTH (method_vec); + my_friendly_assert (method_vec, 19991215); + len = VEC_length (tree, method_vec); /* First fill in entry 0 with the constructors, entry 1 with destructors, and the next few with type conversion operators (if any). */ @@ -1796,23 +1743,16 @@ finish_struct_methods (tree t) no methods, then some public defaults are generated. */ maybe_warn_about_overly_private_class (t); - /* Now sort the methods. */ - while (len > 2 && TREE_VEC_ELT (method_vec, len-1) == NULL_TREE) - len--; - TREE_VEC_LENGTH (method_vec) = len; - /* The type conversion ops have to live at the front of the vec, so we can't sort them. */ - for (slot = 2; slot < len; ++slot) - { - tree fn = TREE_VEC_ELT (method_vec, slot); - - if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) - break; - } + for (slot = 2; + (fn_fields = VEC_iterate (tree, method_vec, slot)); + ++slot) + if (!DECL_CONV_FN_P (OVL_CURRENT (fn_fields))) + break; if (len - slot > 1) - qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree), - method_name_cmp); + qsort (VEC_address (tree, method_vec) + slot, + len-slot, sizeof (tree), method_name_cmp); } /* Make BINFO's vtable have N entries, including RTTI entries, @@ -2369,7 +2309,7 @@ get_basefndecls (tree name, tree t) /* Find virtual functions in T with the indicated NAME. */ i = lookup_fnfields_1 (t, name); if (i != -1) - for (methods = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), i); + for (methods = VEC_index (tree, CLASSTYPE_METHOD_VEC (t), i); methods; methods = OVL_NEXT (methods)) { @@ -2430,14 +2370,16 @@ check_for_override (tree decl, tree ctype) void warn_hidden (tree t) { - tree method_vec = CLASSTYPE_METHOD_VEC (t); - int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - int i; + VEC(tree) *method_vec = CLASSTYPE_METHOD_VEC (t); + tree fns; + size_t i; /* We go through each separately named virtual function. */ - for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i) + for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; + (fns = VEC_iterate (tree, method_vec, i)); + ++i) { - tree fns; + tree fn; tree name; tree fndecl; tree base_fndecls; @@ -2445,7 +2387,7 @@ warn_hidden (tree t) /* All functions in this slot in the CLASSTYPE_METHOD_VEC will have the same name. Figure out what name that is. */ - name = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); + name = DECL_NAME (OVL_CURRENT (fns)); /* There are no possibly hidden functions yet. */ base_fndecls = NULL_TREE; /* Iterate through all of the base classes looking for possibly @@ -2462,9 +2404,9 @@ warn_hidden (tree t) continue; /* Remove any overridden functions. */ - for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns)) + for (fn = fns; fn; fn = OVL_NEXT (fn)) { - fndecl = OVL_CURRENT (fns); + fndecl = OVL_CURRENT (fn); if (DECL_VINDEX (fndecl)) { tree *prev = &base_fndecls; @@ -2486,8 +2428,7 @@ warn_hidden (tree t) { /* Here we know it is a hider, and no overrider exists. */ cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls)); - cp_warning_at (" by `%D'", - OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); + cp_warning_at (" by `%D'", fns); base_fndecls = TREE_CHAIN (base_fndecls); } } @@ -2629,21 +2570,18 @@ add_implicitly_declared_members (tree t, implicit_fns = default_fn; } - /* Assignment operator. */ - if (! TYPE_HAS_ASSIGN_REF (t) && ! TYPE_FOR_JAVA (t)) - { - default_fn - = implicitly_declare_fn (sfk_assignment_operator, t, - /*const_p=*/!cant_have_const_assignment); - TREE_CHAIN (default_fn) = implicit_fns; - implicit_fns = default_fn; - } - + /* If there is no assignment operator, one will be created if and + when it is needed. For now, just record whether or not the type + of the parameter to the assignment operator will be a const or + non-const reference. */ + if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t)) + TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment; + /* Now, hook all of the new functions on to TYPE_METHODS, and add them to the CLASSTYPE_METHOD_VEC. */ for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) { - add_method (t, *f, /*error_p=*/0); + add_method (t, *f); maybe_add_class_template_decl_list (current_class_type, *f, /*friend_p=*/0); } if (abi_version_at_least (2)) @@ -3923,10 +3861,10 @@ clone_function_decl (tree fn, int update_method_vec_p) and a not-in-charge version. */ clone = build_clone (fn, complete_ctor_identifier); if (update_method_vec_p) - add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + add_method (DECL_CONTEXT (clone), clone); clone = build_clone (fn, base_ctor_identifier); if (update_method_vec_p) - add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + add_method (DECL_CONTEXT (clone), clone); } else { @@ -3945,14 +3883,14 @@ clone_function_decl (tree fn, int update_method_vec_p) { clone = build_clone (fn, deleting_dtor_identifier); if (update_method_vec_p) - add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + add_method (DECL_CONTEXT (clone), clone); } clone = build_clone (fn, complete_dtor_identifier); if (update_method_vec_p) - add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + add_method (DECL_CONTEXT (clone), clone); clone = build_clone (fn, base_dtor_identifier); if (update_method_vec_p) - add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + add_method (DECL_CONTEXT (clone), clone); } /* Note that this is an abstract function that is never emitted. */ @@ -4181,7 +4119,6 @@ check_bases_and_members (tree t) CLASSTYPE_NON_POD_P (t) |= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t) || TYPE_HAS_ASSIGN_REF (t)); - TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t); TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t); @@ -5164,10 +5101,10 @@ finish_struct_1 (tree t) build_vtt (t); if (warn_nonvdtor && TYPE_POLYMORPHIC_P (t) && TYPE_HAS_DESTRUCTOR (t) - && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE) + && !DECL_VINDEX (CLASSTYPE_DESTRUCTORS (t))) { - tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1); + tree dtor = CLASSTYPE_DESTRUCTORS (t); /* Warn only if the dtor is non-private or the class has friends */ if (!TREE_PRIVATE (dtor) || diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1e921d823d2..d8e83d6ee0e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -991,11 +991,9 @@ struct lang_type_class GTY(()) unsigned ptrmemfunc_flag : 1; unsigned was_anonymous : 1; - unsigned has_real_assign_ref : 1; unsigned has_const_init_ref : 1; unsigned has_complex_init_ref : 1; unsigned has_complex_assign_ref : 1; - unsigned has_abstract_assign_ref : 1; unsigned non_aggregate : 1; unsigned java_interface : 1; @@ -1006,7 +1004,7 @@ struct lang_type_class GTY(()) /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ - unsigned dummy : 9; + unsigned dummy : 11; tree primary_base; tree vfields; @@ -1018,7 +1016,7 @@ struct lang_type_class GTY(()) tree as_base; tree pure_virtuals; tree friend_classes; - tree GTY ((reorder ("resort_type_method_vec"))) methods; + VEC (tree) * GTY((reorder ("resort_type_method_vec"))) methods; tree key_method; tree decl_list; tree template_info; @@ -1093,6 +1091,9 @@ struct lang_type GTY(()) /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ #define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref) + +/* True iff the class type NODE has an "operator =" whose parameter + has a parameter of type "const X&". */ #define TYPE_HAS_CONST_ASSIGN_REF(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref) @@ -1166,12 +1167,12 @@ struct lang_type GTY(()) /* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These are the constructors that take an in-charge parameter. */ #define CLASSTYPE_CONSTRUCTORS(NODE) \ - (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_CONSTRUCTOR_SLOT)) + (VEC_index (tree, CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_CONSTRUCTOR_SLOT)) /* A FUNCTION_DECL for the destructor for NODE. These are the destructors that take an in-charge parameter. */ #define CLASSTYPE_DESTRUCTORS(NODE) \ - (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_DESTRUCTOR_SLOT)) + (VEC_index (tree, CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_DESTRUCTOR_SLOT)) /* Mark bits for depth-first and breath-first searches. */ @@ -2367,9 +2368,7 @@ struct lang_decl GTY(()) (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) /* Nonzero if there is a user-defined X::op=(x&) for this class. */ -#define TYPE_HAS_REAL_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_real_assign_ref) #define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref) -#define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_abstract_assign_ref) #define TYPE_HAS_COMPLEX_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_init_ref) /* Nonzero if TYPE has a trivial destructor. From [class.dtor]: @@ -3598,7 +3597,7 @@ extern tree build_vfn_ref (tree, tree); extern tree get_vtable_decl (tree, int); extern void resort_type_method_vec (void *, void *, gt_pointer_operator, void *); -extern void add_method (tree, tree, int); +extern void add_method (tree, tree); extern int currently_open_class (tree); extern tree currently_open_derived_class (tree); extern tree finish_struct (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6aac5bae547..75487214b79 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8352,8 +8352,6 @@ void grok_special_member_properties (tree decl) TYPE_HAS_ASSIGN_REF (DECL_CONTEXT (decl)) = 1; if (assop != 1) TYPE_HAS_CONST_ASSIGN_REF (DECL_CONTEXT (decl)) = 1; - if (DECL_PURE_VIRTUAL_P (decl)) - TYPE_HAS_ABSTRACT_ASSIGN_REF (DECL_CONTEXT (decl)) = 1; } } } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 4465873c018..8467ad62e7b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -630,14 +630,14 @@ check_classfn (tree ctype, tree function, tree template_parms) if (ix >= 0) { - tree methods = CLASSTYPE_METHOD_VEC (ctype); + VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype); tree fndecls, fndecl = 0; bool is_conv_op; bool pop_p; const char *format = NULL; pop_p = push_scope (ctype); - for (fndecls = TREE_VEC_ELT (methods, ix); + for (fndecls = VEC_index (tree, methods, ix); fndecls; fndecls = OVL_NEXT (fndecls)) { tree p1, p2; @@ -685,7 +685,7 @@ check_classfn (tree ctype, tree function, tree template_parms) if (is_conv_op) ix = CLASSTYPE_FIRST_CONVERSION_SLOT; - fndecls = TREE_VEC_ELT (methods, ix); + fndecls = VEC_index (tree, methods, ix); while (fndecls) { fndecl = OVL_CURRENT (fndecls); @@ -693,10 +693,10 @@ check_classfn (tree ctype, tree function, tree template_parms) if (!fndecls && is_conv_op) { - if (TREE_VEC_LENGTH (methods) > ix) + if (VEC_length (tree, methods) > (size_t) ix) { ix++; - fndecls = TREE_VEC_ELT (methods, ix); + fndecls = VEC_index (tree, methods, ix); if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls))) { fndecls = NULL_TREE; @@ -726,7 +726,7 @@ check_classfn (tree ctype, tree function, tree template_parms) case we'll only confuse ourselves when the function is declared properly within the class. */ if (COMPLETE_TYPE_P (ctype)) - add_method (ctype, function, /*error_p=*/1); + add_method (ctype, function); return NULL_TREE; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 63fd1e7a10b..1a9ecadbd77 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -825,13 +825,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*), static tree locate_dtor (tree type, void *client ATTRIBUTE_UNUSED) { - tree fns; - - if (!TYPE_HAS_DESTRUCTOR (type)) - return NULL_TREE; - fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), - CLASSTYPE_DESTRUCTOR_SLOT); - return fns; + return CLASSTYPE_DESTRUCTORS (type); } /* Locate the default ctor of TYPE. */ @@ -843,10 +837,8 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED) if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) return NULL_TREE; - - fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), - CLASSTYPE_CONSTRUCTOR_SLOT); - for (; fns; fns = OVL_NEXT (fns)) + + for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); @@ -885,7 +877,7 @@ locate_copy (tree type, void *client_) ix = CLASSTYPE_CONSTRUCTOR_SLOT; if (ix < 0) return NULL_TREE; - fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix); + fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix); for (; fns; fns = OVL_NEXT (fns)) { @@ -989,6 +981,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) if (raises) fn_type = build_exception_variant (fn_type, raises); fn = build_lang_decl (FUNCTION_DECL, name, fn_type); + DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type)); if (kind == sfk_constructor || kind == sfk_copy_constructor) DECL_CONSTRUCTOR_P (fn) = 1; else if (kind == sfk_destructor) @@ -1013,8 +1006,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) TYPE_UNQUALIFIED); grok_special_member_properties (fn); TREE_PUBLIC (fn) = !decl_function_context (TYPE_MAIN_DECL (type)); - cp_finish_decl (fn, /*init=*/NULL_TREE, /*asmspec_tree=*/NULL_TREE, - /*flags=*/LOOKUP_ONLYCONVERTING); + rest_of_decl_compilation (fn, /*asmspec=*/NULL, + toplevel_bindings_p (), at_eof); DECL_IN_AGGR_P (fn) = 1; DECL_ARTIFICIAL (fn) = 1; DECL_NOT_REALLY_EXTERN (fn) = 1; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6dd3c646212..4a429d6140b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1821,11 +1821,12 @@ check_explicit_specialization (tree declarator, { idx = lookup_fnfields_1 (ctype, name); if (idx >= 0) - fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx); + fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (ctype), idx); } else { - tree methods; + VEC(tree) *methods; + tree ovl; /* For a type-conversion operator, we cannot do a name-based lookup. We might be looking for `operator @@ -1837,11 +1838,10 @@ check_explicit_specialization (tree declarator, methods = CLASSTYPE_METHOD_VEC (ctype); if (methods) for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT; - idx < TREE_VEC_LENGTH (methods); ++idx) + (ovl = VEC_iterate (tree, methods, idx)); + ++idx) { - tree ovl = TREE_VEC_ELT (methods, idx); - - if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl))) + if (!DECL_CONV_FN_P (OVL_CURRENT (ovl))) /* There are no more conversion functions. */ break; @@ -5385,7 +5385,6 @@ instantiate_class_template (tree type) TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern); TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern); TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern); - TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern); TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern); TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern); TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern); diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index a74edc37dea..289cb19828d 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -139,8 +139,6 @@ cxx_print_type (FILE *file, tree node, int indent) fprintf (file, " interface-only"); if (CLASSTYPE_INTERFACE_UNKNOWN (node)) fprintf (file, " interface-unknown"); - print_node (file, "member-functions", CLASSTYPE_METHOD_VEC (node), - indent + 4); } } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 794c38ba168..71a7611f712 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1382,7 +1382,7 @@ emit_support_tinfos (void) pop_nested_namespace (abi_node); if (!COMPLETE_TYPE_P (bltn_type)) return; - dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1); + dtor = CLASSTYPE_DESTRUCTORS (bltn_type); if (DECL_EXTERNAL (dtor)) return; doing_runtime = 1; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 506c581e86d..97b97899e4f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1060,7 +1060,7 @@ lookup_field_r (tree binfo, void *data) { int idx = lookup_fnfields_1 (type, lfi->name); if (idx >= 0) - nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); + nval = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), idx); } if (!nval) @@ -1312,20 +1312,16 @@ lookup_conversion_operator (tree class_type, tree type) { int pass; int i; + tree fn; + VEC(tree) *methods; - tree methods = CLASSTYPE_METHOD_VEC (class_type); + methods = CLASSTYPE_METHOD_VEC (class_type); for (pass = 0; pass < 2; ++pass) for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; - i < TREE_VEC_LENGTH (methods); + (fn = VEC_iterate (tree, methods, i)); ++i) { - tree fn = TREE_VEC_ELT (methods, i); - /* The size of the vector may have some unused slots at the - end. */ - if (!fn) - break; - /* All the conversion operators come near the beginning of the class. Therefore, if FN is not a conversion operator, there is no matching conversion operator in CLASS_TYPE. */ @@ -1364,12 +1360,11 @@ lookup_conversion_operator (tree class_type, tree type) int lookup_fnfields_1 (tree type, tree name) { - tree method_vec; - tree *methods; + VEC(tree) *method_vec; + tree fn; tree tmp; - int i; - int len; - + size_t i; + if (!CLASS_TYPE_P (type)) return -1; @@ -1378,35 +1373,58 @@ lookup_fnfields_1 (tree type, tree name) if (!method_vec) return -1; - methods = &TREE_VEC_ELT (method_vec, 0); - len = TREE_VEC_LENGTH (method_vec); - #ifdef GATHER_STATISTICS n_calls_lookup_fnfields_1++; #endif /* GATHER_STATISTICS */ /* Constructors are first... */ if (name == ctor_identifier) - return (methods[CLASSTYPE_CONSTRUCTOR_SLOT] - ? CLASSTYPE_CONSTRUCTOR_SLOT : -1); + { + fn = CLASSTYPE_CONSTRUCTORS (type); + return fn ? CLASSTYPE_CONSTRUCTOR_SLOT : -1; + } /* and destructors are second. */ if (name == dtor_identifier) - return (methods[CLASSTYPE_DESTRUCTOR_SLOT] - ? CLASSTYPE_DESTRUCTOR_SLOT : -1); + { + fn = CLASSTYPE_DESTRUCTORS (type); + return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1; + } if (IDENTIFIER_TYPENAME_P (name)) return lookup_conversion_operator (type, TREE_TYPE (name)); /* Skip the conversion operators. */ - i = CLASSTYPE_FIRST_CONVERSION_SLOT; - while (i < len && methods[i] && DECL_CONV_FN_P (OVL_CURRENT (methods[i]))) - i++; + for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; + (fn = VEC_iterate (tree, method_vec, i)); + ++i) + if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) + break; /* If the type is complete, use binary search. */ if (COMPLETE_TYPE_P (type)) { - int lo = i; - int hi = len; + int lo; + int hi; + + /* All non-Java classes have "operator=" -- but we do not + actually create the declaration until it is needed. */ + if (name == ansi_assopname(NOP_EXPR) + && !TYPE_HAS_ASSIGN_REF (type) + && !TYPE_FOR_JAVA (type)) + { + tree fn; + + /* Declare the function. */ + fn = implicitly_declare_fn (sfk_assignment_operator, type, + TYPE_HAS_CONST_ASSIGN_REF (type)); + add_method (type, fn); + TREE_CHAIN (fn) = TYPE_METHODS (type); + TYPE_METHODS (type) = fn; + maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0); + method_vec = CLASSTYPE_METHOD_VEC (type); + } + lo = i; + hi = VEC_length (tree, method_vec); while (lo < hi) { i = (lo + hi) / 2; @@ -1415,13 +1433,9 @@ lookup_fnfields_1 (tree type, tree name) n_outer_fields_searched++; #endif /* GATHER_STATISTICS */ - tmp = methods[i]; - /* This slot may be empty; we allocate more slots than we - need. In that case, the entry we're looking for is - closer to the beginning of the list. */ - if (tmp) - tmp = DECL_NAME (OVL_CURRENT (tmp)); - if (!tmp || tmp > name) + tmp = VEC_index (tree, method_vec, i); + tmp = DECL_NAME (OVL_CURRENT (tmp)); + if (tmp > name) hi = i; else if (tmp < name) lo = i + 1; @@ -1430,14 +1444,14 @@ lookup_fnfields_1 (tree type, tree name) } } else - for (; i < len && methods[i]; ++i) + for (; + (fn = VEC_iterate (tree, method_vec, i)); + ++i) { #ifdef GATHER_STATISTICS n_outer_fields_searched++; #endif /* GATHER_STATISTICS */ - - tmp = OVL_CURRENT (methods[i]); - if (DECL_NAME (tmp) == name) + if (DECL_NAME (OVL_CURRENT (fn)) == name) return i; } @@ -1781,7 +1795,7 @@ look_for_overrides_here (tree type, tree fndecl) ix = lookup_fnfields_1 (type, DECL_NAME (fndecl)); if (ix >= 0) { - tree fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix); + tree fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix); for (; fns; fns = OVL_NEXT (fns)) { @@ -2050,17 +2064,19 @@ reinit_search_statistics (void) static tree add_conversions (tree binfo, void *data) { - int i; - tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo)); + size_t i; + VEC(tree) *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo)); tree *conversions = (tree *) data; + tree tmp; /* Some builtin types have no method vector, not even an empty one. */ if (!method_vec) return NULL_TREE; - for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i) + for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; + (tmp = VEC_iterate (tree, method_vec, i)); + ++i) { - tree tmp = TREE_VEC_ELT (method_vec, i); tree name; if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp))) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 929a0e632a1..6bc7e68f298 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2154,7 +2154,7 @@ finish_member_declaration (tree decl) { /* We also need to add this function to the CLASSTYPE_METHOD_VEC. */ - add_method (current_class_type, decl, /*error_p=*/0); + add_method (current_class_type, decl); TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); TYPE_METHODS (current_class_type) = decl; diff --git a/gcc/vec.h b/gcc/vec.h index f795ba13f0b..6d78c832b24 100644 --- a/gcc/vec.h +++ b/gcc/vec.h @@ -244,6 +244,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA removed object. This is an O(1) operation. */ #define VEC_unordered_remove(TDEF,V,I) (VEC_OP(TDEF,unordered_remove)(V,I)) +/* Get the address of the array of elements + T *VEC_T_address (VEC(T) v) + + If you need to directly manipulate the array (for instance, you + want to feed it to qsort), use this accessor. */ +#define VEC_address(TDEF,V) (VEC_OP(TDEF,address)(V)) + #if !IN_GENGTYPE /* Reallocate an array of elements with prefix. */ extern void *vec_p_reserve (void *, int MEM_STAT_DECL); @@ -449,6 +456,12 @@ static inline TDEF VEC_OP (TDEF,unordered_remove) \ return obj_; \ } \ \ +static inline TDEF *VEC_OP (TDEF,address) \ + (VEC (TDEF) *vec_) \ +{ \ + return vec_ ? vec_->vec : 0; \ +} \ + \ struct vec_swallow_trailing_semi #endif @@ -612,6 +625,12 @@ static inline void VEC_OP (TDEF,unordered_remove) \ vec_->vec[ix_] = vec_->vec[--vec_->num]; \ } \ \ +static inline TDEF *VEC_OP (TDEF,address) \ + (VEC (TDEF) *vec_) \ +{ \ + return vec_ ? vec_->vec : 0; \ +} \ + \ struct vec_swallow_trailing_semi #endif