Commit aaaa46d2 by Mark Mitchell

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
parent b38b6477
2004-07-15 Nathan Sidwell <nathan@codesourcery.com>
* vec.h (VEC_address): New function.
2004-07-14 Jason Merrill <jason@redhat.com> 2004-07-14 Jason Merrill <jason@redhat.com>
PR middle-end/15885 PR middle-end/15885
......
2004-07-15 Mark Mitchell <mark@codesourcery.com>
* 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 <jason@redhat.com> 2004-07-15 Jason Merrill <jason@redhat.com>
* cp-lang.c (cxx_types_compatible_p): To the middle-end, * cp-lang.c (cxx_types_compatible_p): To the middle-end,
...@@ -13,7 +64,7 @@ ...@@ -13,7 +64,7 @@
(copy_binfo): Declare. (copy_binfo): Declare.
2004-07-15 Mark Mitchell <mark@codesourcery.com> 2004-07-15 Mark Mitchell <mark@codesourcery.com>
* name-lookup.c (set_inherited_value_binding_p): Add class_type * name-lookup.c (set_inherited_value_binding_p): Add class_type
parameter. parameter.
(get_class_binding): Adjust. (get_class_binding): Adjust.
......
...@@ -795,43 +795,42 @@ modify_vtable_entry (tree t, ...@@ -795,43 +795,42 @@ modify_vtable_entry (tree t,
} }
/* Add method METHOD to class TYPE. If ERROR_P is true, we are adding /* Add method METHOD to class TYPE. */
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.) */
void void
add_method (tree type, tree method, int error_p) add_method (tree type, tree method)
{ {
int using; int using;
int len; size_t len;
int slot; size_t slot;
tree method_vec;
tree overload; tree overload;
int template_conv_p; int template_conv_p;
VEC(tree) *method_vec;
bool complete_p;
if (method == error_mark_node) if (method == error_mark_node)
return; return;
complete_p = COMPLETE_TYPE_P (type);
using = (DECL_CONTEXT (method) != type); using = (DECL_CONTEXT (method) != type);
template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
&& DECL_TEMPLATE_CONV_FN_P (method)); && 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); 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. */ /* Constructors and destructors go in special slots. */
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method)) if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
...@@ -849,103 +848,52 @@ add_method (tree type, tree method, int error_p) ...@@ -849,103 +848,52 @@ add_method (tree type, tree method, int error_p)
} }
else 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. */ /* 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); m = OVL_CURRENT (m);
if (template_conv_p) if (template_conv_p)
{ {
have_template_convs_p = (TREE_CODE (m) == TEMPLATE_DECL if (TREE_CODE (m) == TEMPLATE_DECL
&& DECL_TEMPLATE_CONV_FN_P (m)); && DECL_TEMPLATE_CONV_FN_P (m))
insert_p = false;
/* 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++;
}
break; break;
} }
if (DECL_NAME (m) == DECL_NAME (method)) if (conv_p && !DECL_CONV_FN_P (m))
break; break;
} if (DECL_NAME (m) == DECL_NAME (method))
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
{ {
/* We know the last slot in the vector is empty insert_p = false;
because we know that at this point there's room break;
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;
} }
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) if (processing_template_decl)
...@@ -957,7 +905,7 @@ add_method (tree type, tree method, int error_p) ...@@ -957,7 +905,7 @@ add_method (tree type, tree method, int error_p)
tree fns; tree fns;
/* Check to see if we've already got this method. */ /* 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;
fns = OVL_NEXT (fns)) fns = OVL_NEXT (fns))
{ {
...@@ -1027,13 +975,14 @@ add_method (tree type, tree method, int error_p) ...@@ -1027,13 +975,14 @@ add_method (tree type, tree method, int error_p)
} }
/* Add the new binding. */ /* 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) if (!DECL_CONSTRUCTOR_P (method)
&& !DECL_DESTRUCTOR_P (method)) && !DECL_DESTRUCTOR_P (method)
&& !complete_p)
push_class_level_binding (DECL_NAME (method), overload); push_class_level_binding (DECL_NAME (method), overload);
/* Actually insert the new method. */ /* Actually insert the new method. */
TREE_VEC_ELT (method_vec, slot) = overload; VEC_replace (tree, method_vec, slot, overload);
} }
/* Subroutines of finish_struct. */ /* Subroutines of finish_struct. */
...@@ -1171,7 +1120,7 @@ handle_using_decl (tree using_decl, tree t) ...@@ -1171,7 +1120,7 @@ handle_using_decl (tree using_decl, tree t)
if (flist) if (flist)
for (; flist; flist = OVL_NEXT (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); alter_access (t, OVL_CURRENT (flist), access);
} }
else else
...@@ -1637,9 +1586,7 @@ maybe_warn_about_overly_private_class (tree t) ...@@ -1637,9 +1586,7 @@ maybe_warn_about_overly_private_class (tree t)
if (!TYPE_HAS_INIT_REF (t)) if (!TYPE_HAS_INIT_REF (t))
nonprivate_ctor = 1; nonprivate_ctor = 1;
else else
for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn))
fn;
fn = OVL_NEXT (fn))
{ {
tree ctor = OVL_CURRENT (fn); tree ctor = OVL_CURRENT (fn);
/* Ideally, we wouldn't count copy constructors (or, in /* Ideally, we wouldn't count copy constructors (or, in
...@@ -1721,24 +1668,24 @@ resort_type_method_vec (void* obj, ...@@ -1721,24 +1668,24 @@ resort_type_method_vec (void* obj,
gt_pointer_operator new_value, gt_pointer_operator new_value,
void* cookie) void* cookie)
{ {
tree method_vec = obj; VEC(tree) *method_vec = (VEC(tree) *) obj;
int len = TREE_VEC_LENGTH (method_vec); int len = VEC_length (tree, method_vec);
int slot; size_t slot;
tree fn;
/* The type conversion ops have to live at the front of the vec, so we /* The type conversion ops have to live at the front of the vec, so we
can't sort them. */ can't sort them. */
for (slot = 2; slot < len; ++slot) for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
{ (fn = VEC_iterate (tree, method_vec, slot));
tree fn = TREE_VEC_ELT (method_vec, slot); ++slot)
if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) break;
break;
}
if (len - slot > 1) if (len - slot > 1)
{ {
resort_data.new_value = new_value; resort_data.new_value = new_value;
resort_data.cookie = cookie; 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); resort_method_name_cmp);
} }
} }
...@@ -1763,7 +1710,7 @@ static void ...@@ -1763,7 +1710,7 @@ static void
finish_struct_methods (tree t) finish_struct_methods (tree t)
{ {
tree fn_fields; tree fn_fields;
tree method_vec; VEC(tree) *method_vec;
int slot, len; int slot, len;
if (!TYPE_METHODS (t)) if (!TYPE_METHODS (t))
...@@ -1772,13 +1719,13 @@ finish_struct_methods (tree t) ...@@ -1772,13 +1719,13 @@ finish_struct_methods (tree t)
these incorrectly. */ these incorrectly. */
TYPE_HAS_CONSTRUCTOR (t) = 0; TYPE_HAS_CONSTRUCTOR (t) = 0;
TYPE_HAS_DESTRUCTOR (t) = 0; TYPE_HAS_DESTRUCTOR (t) = 0;
CLASSTYPE_METHOD_VEC (t) = NULL_TREE; CLASSTYPE_METHOD_VEC (t) = NULL;
return; return;
} }
method_vec = CLASSTYPE_METHOD_VEC (t); method_vec = CLASSTYPE_METHOD_VEC (t);
my_friendly_assert (method_vec != NULL_TREE, 19991215); my_friendly_assert (method_vec, 19991215);
len = TREE_VEC_LENGTH (method_vec); len = VEC_length (tree, method_vec);
/* First fill in entry 0 with the constructors, entry 1 with destructors, /* First fill in entry 0 with the constructors, entry 1 with destructors,
and the next few with type conversion operators (if any). */ and the next few with type conversion operators (if any). */
...@@ -1796,23 +1743,16 @@ finish_struct_methods (tree t) ...@@ -1796,23 +1743,16 @@ finish_struct_methods (tree t)
no methods, then some public defaults are generated. */ no methods, then some public defaults are generated. */
maybe_warn_about_overly_private_class (t); 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 /* The type conversion ops have to live at the front of the vec, so we
can't sort them. */ can't sort them. */
for (slot = 2; slot < len; ++slot) for (slot = 2;
{ (fn_fields = VEC_iterate (tree, method_vec, slot));
tree fn = TREE_VEC_ELT (method_vec, slot); ++slot)
if (!DECL_CONV_FN_P (OVL_CURRENT (fn_fields)))
if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) break;
break;
}
if (len - slot > 1) if (len - slot > 1)
qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree), qsort (VEC_address (tree, method_vec) + slot,
method_name_cmp); len-slot, sizeof (tree), method_name_cmp);
} }
/* Make BINFO's vtable have N entries, including RTTI entries, /* Make BINFO's vtable have N entries, including RTTI entries,
...@@ -2369,7 +2309,7 @@ get_basefndecls (tree name, tree t) ...@@ -2369,7 +2309,7 @@ get_basefndecls (tree name, tree t)
/* Find virtual functions in T with the indicated NAME. */ /* Find virtual functions in T with the indicated NAME. */
i = lookup_fnfields_1 (t, name); i = lookup_fnfields_1 (t, name);
if (i != -1) 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;
methods = OVL_NEXT (methods)) methods = OVL_NEXT (methods))
{ {
...@@ -2430,14 +2370,16 @@ check_for_override (tree decl, tree ctype) ...@@ -2430,14 +2370,16 @@ check_for_override (tree decl, tree ctype)
void void
warn_hidden (tree t) warn_hidden (tree t)
{ {
tree method_vec = CLASSTYPE_METHOD_VEC (t); VEC(tree) *method_vec = CLASSTYPE_METHOD_VEC (t);
int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; tree fns;
int i; size_t i;
/* We go through each separately named virtual function. */ /* 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 name;
tree fndecl; tree fndecl;
tree base_fndecls; tree base_fndecls;
...@@ -2445,7 +2387,7 @@ warn_hidden (tree t) ...@@ -2445,7 +2387,7 @@ warn_hidden (tree t)
/* All functions in this slot in the CLASSTYPE_METHOD_VEC will /* All functions in this slot in the CLASSTYPE_METHOD_VEC will
have the same name. Figure out what name that is. */ 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. */ /* There are no possibly hidden functions yet. */
base_fndecls = NULL_TREE; base_fndecls = NULL_TREE;
/* Iterate through all of the base classes looking for possibly /* Iterate through all of the base classes looking for possibly
...@@ -2462,9 +2404,9 @@ warn_hidden (tree t) ...@@ -2462,9 +2404,9 @@ warn_hidden (tree t)
continue; continue;
/* Remove any overridden functions. */ /* 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)) if (DECL_VINDEX (fndecl))
{ {
tree *prev = &base_fndecls; tree *prev = &base_fndecls;
...@@ -2486,8 +2428,7 @@ warn_hidden (tree t) ...@@ -2486,8 +2428,7 @@ warn_hidden (tree t)
{ {
/* Here we know it is a hider, and no overrider exists. */ /* Here we know it is a hider, and no overrider exists. */
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls)); cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
cp_warning_at (" by `%D'", cp_warning_at (" by `%D'", fns);
OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
base_fndecls = TREE_CHAIN (base_fndecls); base_fndecls = TREE_CHAIN (base_fndecls);
} }
} }
...@@ -2629,21 +2570,18 @@ add_implicitly_declared_members (tree t, ...@@ -2629,21 +2570,18 @@ add_implicitly_declared_members (tree t,
implicit_fns = default_fn; implicit_fns = default_fn;
} }
/* Assignment operator. */ /* If there is no assignment operator, one will be created if and
if (! TYPE_HAS_ASSIGN_REF (t) && ! TYPE_FOR_JAVA (t)) 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
default_fn non-const reference. */
= implicitly_declare_fn (sfk_assignment_operator, t, if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
/*const_p=*/!cant_have_const_assignment); TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
TREE_CHAIN (default_fn) = implicit_fns;
implicit_fns = default_fn;
}
/* Now, hook all of the new functions on to TYPE_METHODS, /* Now, hook all of the new functions on to TYPE_METHODS,
and add them to the CLASSTYPE_METHOD_VEC. */ and add them to the CLASSTYPE_METHOD_VEC. */
for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) 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); maybe_add_class_template_decl_list (current_class_type, *f, /*friend_p=*/0);
} }
if (abi_version_at_least (2)) if (abi_version_at_least (2))
...@@ -3923,10 +3861,10 @@ clone_function_decl (tree fn, int update_method_vec_p) ...@@ -3923,10 +3861,10 @@ clone_function_decl (tree fn, int update_method_vec_p)
and a not-in-charge version. */ and a not-in-charge version. */
clone = build_clone (fn, complete_ctor_identifier); clone = build_clone (fn, complete_ctor_identifier);
if (update_method_vec_p) 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); clone = build_clone (fn, base_ctor_identifier);
if (update_method_vec_p) if (update_method_vec_p)
add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); add_method (DECL_CONTEXT (clone), clone);
} }
else else
{ {
...@@ -3945,14 +3883,14 @@ clone_function_decl (tree fn, int update_method_vec_p) ...@@ -3945,14 +3883,14 @@ clone_function_decl (tree fn, int update_method_vec_p)
{ {
clone = build_clone (fn, deleting_dtor_identifier); clone = build_clone (fn, deleting_dtor_identifier);
if (update_method_vec_p) 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); clone = build_clone (fn, complete_dtor_identifier);
if (update_method_vec_p) 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); clone = build_clone (fn, base_dtor_identifier);
if (update_method_vec_p) 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. */ /* Note that this is an abstract function that is never emitted. */
...@@ -4181,7 +4119,6 @@ check_bases_and_members (tree t) ...@@ -4181,7 +4119,6 @@ check_bases_and_members (tree t)
CLASSTYPE_NON_POD_P (t) CLASSTYPE_NON_POD_P (t)
|= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t) |= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t)
|| TYPE_HAS_ASSIGN_REF (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_COMPLEX_ASSIGN_REF (t)
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t); |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
...@@ -5164,10 +5101,10 @@ finish_struct_1 (tree t) ...@@ -5164,10 +5101,10 @@ finish_struct_1 (tree t)
build_vtt (t); build_vtt (t);
if (warn_nonvdtor && TYPE_POLYMORPHIC_P (t) && TYPE_HAS_DESTRUCTOR (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 */ /* Warn only if the dtor is non-private or the class has friends */
if (!TREE_PRIVATE (dtor) || if (!TREE_PRIVATE (dtor) ||
......
...@@ -991,11 +991,9 @@ struct lang_type_class GTY(()) ...@@ -991,11 +991,9 @@ struct lang_type_class GTY(())
unsigned ptrmemfunc_flag : 1; unsigned ptrmemfunc_flag : 1;
unsigned was_anonymous : 1; unsigned was_anonymous : 1;
unsigned has_real_assign_ref : 1;
unsigned has_const_init_ref : 1; unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1; unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1; unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1; unsigned non_aggregate : 1;
unsigned java_interface : 1; unsigned java_interface : 1;
...@@ -1006,7 +1004,7 @@ struct lang_type_class GTY(()) ...@@ -1006,7 +1004,7 @@ struct lang_type_class GTY(())
/* There are some bits left to fill out a 32-bit word. Keep track /* 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 of this by updating the size of this bitfield whenever you add or
remove a flag. */ remove a flag. */
unsigned dummy : 9; unsigned dummy : 11;
tree primary_base; tree primary_base;
tree vfields; tree vfields;
...@@ -1018,7 +1016,7 @@ struct lang_type_class GTY(()) ...@@ -1018,7 +1016,7 @@ struct lang_type_class GTY(())
tree as_base; tree as_base;
tree pure_virtuals; tree pure_virtuals;
tree friend_classes; tree friend_classes;
tree GTY ((reorder ("resort_type_method_vec"))) methods; VEC (tree) * GTY((reorder ("resort_type_method_vec"))) methods;
tree key_method; tree key_method;
tree decl_list; tree decl_list;
tree template_info; tree template_info;
...@@ -1093,6 +1091,9 @@ struct lang_type GTY(()) ...@@ -1093,6 +1091,9 @@ struct lang_type GTY(())
/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */
#define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref) #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) \ #define TYPE_HAS_CONST_ASSIGN_REF(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref)
...@@ -1166,12 +1167,12 @@ struct lang_type GTY(()) ...@@ -1166,12 +1167,12 @@ struct lang_type GTY(())
/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These /* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These
are the constructors that take an in-charge parameter. */ are the constructors that take an in-charge parameter. */
#define CLASSTYPE_CONSTRUCTORS(NODE) \ #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 /* A FUNCTION_DECL for the destructor for NODE. These are the
destructors that take an in-charge parameter. */ destructors that take an in-charge parameter. */
#define CLASSTYPE_DESTRUCTORS(NODE) \ #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. */ /* Mark bits for depth-first and breath-first searches. */
...@@ -2367,9 +2368,7 @@ struct lang_decl GTY(()) ...@@ -2367,9 +2368,7 @@ struct lang_decl GTY(())
(IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
/* Nonzero if there is a user-defined X::op=(x&) for this class. */ /* 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_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) #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]: /* Nonzero if TYPE has a trivial destructor. From [class.dtor]:
...@@ -3598,7 +3597,7 @@ extern tree build_vfn_ref (tree, tree); ...@@ -3598,7 +3597,7 @@ extern tree build_vfn_ref (tree, tree);
extern tree get_vtable_decl (tree, int); extern tree get_vtable_decl (tree, int);
extern void resort_type_method_vec extern void resort_type_method_vec
(void *, void *, gt_pointer_operator, void *); (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 int currently_open_class (tree);
extern tree currently_open_derived_class (tree); extern tree currently_open_derived_class (tree);
extern tree finish_struct (tree, tree); extern tree finish_struct (tree, tree);
......
...@@ -8352,8 +8352,6 @@ void grok_special_member_properties (tree decl) ...@@ -8352,8 +8352,6 @@ void grok_special_member_properties (tree decl)
TYPE_HAS_ASSIGN_REF (DECL_CONTEXT (decl)) = 1; TYPE_HAS_ASSIGN_REF (DECL_CONTEXT (decl)) = 1;
if (assop != 1) if (assop != 1)
TYPE_HAS_CONST_ASSIGN_REF (DECL_CONTEXT (decl)) = 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;
} }
} }
} }
......
...@@ -630,14 +630,14 @@ check_classfn (tree ctype, tree function, tree template_parms) ...@@ -630,14 +630,14 @@ check_classfn (tree ctype, tree function, tree template_parms)
if (ix >= 0) if (ix >= 0)
{ {
tree methods = CLASSTYPE_METHOD_VEC (ctype); VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
tree fndecls, fndecl = 0; tree fndecls, fndecl = 0;
bool is_conv_op; bool is_conv_op;
bool pop_p; bool pop_p;
const char *format = NULL; const char *format = NULL;
pop_p = push_scope (ctype); pop_p = push_scope (ctype);
for (fndecls = TREE_VEC_ELT (methods, ix); for (fndecls = VEC_index (tree, methods, ix);
fndecls; fndecls = OVL_NEXT (fndecls)) fndecls; fndecls = OVL_NEXT (fndecls))
{ {
tree p1, p2; tree p1, p2;
...@@ -685,7 +685,7 @@ check_classfn (tree ctype, tree function, tree template_parms) ...@@ -685,7 +685,7 @@ check_classfn (tree ctype, tree function, tree template_parms)
if (is_conv_op) if (is_conv_op)
ix = CLASSTYPE_FIRST_CONVERSION_SLOT; ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
fndecls = TREE_VEC_ELT (methods, ix); fndecls = VEC_index (tree, methods, ix);
while (fndecls) while (fndecls)
{ {
fndecl = OVL_CURRENT (fndecls); fndecl = OVL_CURRENT (fndecls);
...@@ -693,10 +693,10 @@ check_classfn (tree ctype, tree function, tree template_parms) ...@@ -693,10 +693,10 @@ check_classfn (tree ctype, tree function, tree template_parms)
if (!fndecls && is_conv_op) if (!fndecls && is_conv_op)
{ {
if (TREE_VEC_LENGTH (methods) > ix) if (VEC_length (tree, methods) > (size_t) ix)
{ {
ix++; ix++;
fndecls = TREE_VEC_ELT (methods, ix); fndecls = VEC_index (tree, methods, ix);
if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls))) if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
{ {
fndecls = NULL_TREE; fndecls = NULL_TREE;
...@@ -726,7 +726,7 @@ check_classfn (tree ctype, tree function, tree template_parms) ...@@ -726,7 +726,7 @@ check_classfn (tree ctype, tree function, tree template_parms)
case we'll only confuse ourselves when the function is declared case we'll only confuse ourselves when the function is declared
properly within the class. */ properly within the class. */
if (COMPLETE_TYPE_P (ctype)) if (COMPLETE_TYPE_P (ctype))
add_method (ctype, function, /*error_p=*/1); add_method (ctype, function);
return NULL_TREE; return NULL_TREE;
} }
......
...@@ -825,13 +825,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*), ...@@ -825,13 +825,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
static tree static tree
locate_dtor (tree type, void *client ATTRIBUTE_UNUSED) locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
{ {
tree fns; return CLASSTYPE_DESTRUCTORS (type);
if (!TYPE_HAS_DESTRUCTOR (type))
return NULL_TREE;
fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
CLASSTYPE_DESTRUCTOR_SLOT);
return fns;
} }
/* Locate the default ctor of TYPE. */ /* Locate the default ctor of TYPE. */
...@@ -843,10 +837,8 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED) ...@@ -843,10 +837,8 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
return NULL_TREE; return NULL_TREE;
fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns))
CLASSTYPE_CONSTRUCTOR_SLOT);
for (; fns; fns = OVL_NEXT (fns))
{ {
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
...@@ -885,7 +877,7 @@ locate_copy (tree type, void *client_) ...@@ -885,7 +877,7 @@ locate_copy (tree type, void *client_)
ix = CLASSTYPE_CONSTRUCTOR_SLOT; ix = CLASSTYPE_CONSTRUCTOR_SLOT;
if (ix < 0) if (ix < 0)
return NULL_TREE; 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)) for (; fns; fns = OVL_NEXT (fns))
{ {
...@@ -989,6 +981,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -989,6 +981,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
if (raises) if (raises)
fn_type = build_exception_variant (fn_type, raises); fn_type = build_exception_variant (fn_type, raises);
fn = build_lang_decl (FUNCTION_DECL, name, fn_type); 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) if (kind == sfk_constructor || kind == sfk_copy_constructor)
DECL_CONSTRUCTOR_P (fn) = 1; DECL_CONSTRUCTOR_P (fn) = 1;
else if (kind == sfk_destructor) else if (kind == sfk_destructor)
...@@ -1013,8 +1006,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -1013,8 +1006,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
TYPE_UNQUALIFIED); TYPE_UNQUALIFIED);
grok_special_member_properties (fn); grok_special_member_properties (fn);
TREE_PUBLIC (fn) = !decl_function_context (TYPE_MAIN_DECL (type)); TREE_PUBLIC (fn) = !decl_function_context (TYPE_MAIN_DECL (type));
cp_finish_decl (fn, /*init=*/NULL_TREE, /*asmspec_tree=*/NULL_TREE, rest_of_decl_compilation (fn, /*asmspec=*/NULL,
/*flags=*/LOOKUP_ONLYCONVERTING); toplevel_bindings_p (), at_eof);
DECL_IN_AGGR_P (fn) = 1; DECL_IN_AGGR_P (fn) = 1;
DECL_ARTIFICIAL (fn) = 1; DECL_ARTIFICIAL (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_NOT_REALLY_EXTERN (fn) = 1;
......
...@@ -1821,11 +1821,12 @@ check_explicit_specialization (tree declarator, ...@@ -1821,11 +1821,12 @@ check_explicit_specialization (tree declarator,
{ {
idx = lookup_fnfields_1 (ctype, name); idx = lookup_fnfields_1 (ctype, name);
if (idx >= 0) if (idx >= 0)
fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx); fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (ctype), idx);
} }
else else
{ {
tree methods; VEC(tree) *methods;
tree ovl;
/* For a type-conversion operator, we cannot do a /* For a type-conversion operator, we cannot do a
name-based lookup. We might be looking for `operator name-based lookup. We might be looking for `operator
...@@ -1837,11 +1838,10 @@ check_explicit_specialization (tree declarator, ...@@ -1837,11 +1838,10 @@ check_explicit_specialization (tree declarator,
methods = CLASSTYPE_METHOD_VEC (ctype); methods = CLASSTYPE_METHOD_VEC (ctype);
if (methods) if (methods)
for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT; 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 (!DECL_CONV_FN_P (OVL_CURRENT (ovl)))
if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl)))
/* There are no more conversion functions. */ /* There are no more conversion functions. */
break; break;
...@@ -5385,7 +5385,6 @@ instantiate_class_template (tree type) ...@@ -5385,7 +5385,6 @@ instantiate_class_template (tree type)
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern); TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (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_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_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern);
TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_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); TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern);
......
...@@ -139,8 +139,6 @@ cxx_print_type (FILE *file, tree node, int indent) ...@@ -139,8 +139,6 @@ cxx_print_type (FILE *file, tree node, int indent)
fprintf (file, " interface-only"); fprintf (file, " interface-only");
if (CLASSTYPE_INTERFACE_UNKNOWN (node)) if (CLASSTYPE_INTERFACE_UNKNOWN (node))
fprintf (file, " interface-unknown"); fprintf (file, " interface-unknown");
print_node (file, "member-functions", CLASSTYPE_METHOD_VEC (node),
indent + 4);
} }
} }
......
...@@ -1382,7 +1382,7 @@ emit_support_tinfos (void) ...@@ -1382,7 +1382,7 @@ emit_support_tinfos (void)
pop_nested_namespace (abi_node); pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (bltn_type)) if (!COMPLETE_TYPE_P (bltn_type))
return; return;
dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1); dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
if (DECL_EXTERNAL (dtor)) if (DECL_EXTERNAL (dtor))
return; return;
doing_runtime = 1; doing_runtime = 1;
......
...@@ -1060,7 +1060,7 @@ lookup_field_r (tree binfo, void *data) ...@@ -1060,7 +1060,7 @@ lookup_field_r (tree binfo, void *data)
{ {
int idx = lookup_fnfields_1 (type, lfi->name); int idx = lookup_fnfields_1 (type, lfi->name);
if (idx >= 0) if (idx >= 0)
nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); nval = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), idx);
} }
if (!nval) if (!nval)
...@@ -1312,20 +1312,16 @@ lookup_conversion_operator (tree class_type, tree type) ...@@ -1312,20 +1312,16 @@ lookup_conversion_operator (tree class_type, tree type)
{ {
int pass; int pass;
int i; 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 (pass = 0; pass < 2; ++pass)
for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
i < TREE_VEC_LENGTH (methods); (fn = VEC_iterate (tree, methods, i));
++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 /* All the conversion operators come near the beginning of the
class. Therefore, if FN is not a conversion operator, there class. Therefore, if FN is not a conversion operator, there
is no matching conversion operator in CLASS_TYPE. */ is no matching conversion operator in CLASS_TYPE. */
...@@ -1364,12 +1360,11 @@ lookup_conversion_operator (tree class_type, tree type) ...@@ -1364,12 +1360,11 @@ lookup_conversion_operator (tree class_type, tree type)
int int
lookup_fnfields_1 (tree type, tree name) lookup_fnfields_1 (tree type, tree name)
{ {
tree method_vec; VEC(tree) *method_vec;
tree *methods; tree fn;
tree tmp; tree tmp;
int i; size_t i;
int len;
if (!CLASS_TYPE_P (type)) if (!CLASS_TYPE_P (type))
return -1; return -1;
...@@ -1378,35 +1373,58 @@ lookup_fnfields_1 (tree type, tree name) ...@@ -1378,35 +1373,58 @@ lookup_fnfields_1 (tree type, tree name)
if (!method_vec) if (!method_vec)
return -1; return -1;
methods = &TREE_VEC_ELT (method_vec, 0);
len = TREE_VEC_LENGTH (method_vec);
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
n_calls_lookup_fnfields_1++; n_calls_lookup_fnfields_1++;
#endif /* GATHER_STATISTICS */ #endif /* GATHER_STATISTICS */
/* Constructors are first... */ /* Constructors are first... */
if (name == ctor_identifier) 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. */ /* and destructors are second. */
if (name == dtor_identifier) 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)) if (IDENTIFIER_TYPENAME_P (name))
return lookup_conversion_operator (type, TREE_TYPE (name)); return lookup_conversion_operator (type, TREE_TYPE (name));
/* Skip the conversion operators. */ /* Skip the conversion operators. */
i = CLASSTYPE_FIRST_CONVERSION_SLOT; for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
while (i < len && methods[i] && DECL_CONV_FN_P (OVL_CURRENT (methods[i]))) (fn = VEC_iterate (tree, method_vec, i));
i++; ++i)
if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
break;
/* If the type is complete, use binary search. */ /* If the type is complete, use binary search. */
if (COMPLETE_TYPE_P (type)) if (COMPLETE_TYPE_P (type))
{ {
int lo = i; int lo;
int hi = len; 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) while (lo < hi)
{ {
i = (lo + hi) / 2; i = (lo + hi) / 2;
...@@ -1415,13 +1433,9 @@ lookup_fnfields_1 (tree type, tree name) ...@@ -1415,13 +1433,9 @@ lookup_fnfields_1 (tree type, tree name)
n_outer_fields_searched++; n_outer_fields_searched++;
#endif /* GATHER_STATISTICS */ #endif /* GATHER_STATISTICS */
tmp = methods[i]; tmp = VEC_index (tree, method_vec, i);
/* This slot may be empty; we allocate more slots than we tmp = DECL_NAME (OVL_CURRENT (tmp));
need. In that case, the entry we're looking for is if (tmp > name)
closer to the beginning of the list. */
if (tmp)
tmp = DECL_NAME (OVL_CURRENT (tmp));
if (!tmp || tmp > name)
hi = i; hi = i;
else if (tmp < name) else if (tmp < name)
lo = i + 1; lo = i + 1;
...@@ -1430,14 +1444,14 @@ lookup_fnfields_1 (tree type, tree name) ...@@ -1430,14 +1444,14 @@ lookup_fnfields_1 (tree type, tree name)
} }
} }
else else
for (; i < len && methods[i]; ++i) for (;
(fn = VEC_iterate (tree, method_vec, i));
++i)
{ {
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
n_outer_fields_searched++; n_outer_fields_searched++;
#endif /* GATHER_STATISTICS */ #endif /* GATHER_STATISTICS */
if (DECL_NAME (OVL_CURRENT (fn)) == name)
tmp = OVL_CURRENT (methods[i]);
if (DECL_NAME (tmp) == name)
return i; return i;
} }
...@@ -1781,7 +1795,7 @@ look_for_overrides_here (tree type, tree fndecl) ...@@ -1781,7 +1795,7 @@ look_for_overrides_here (tree type, tree fndecl)
ix = lookup_fnfields_1 (type, DECL_NAME (fndecl)); ix = lookup_fnfields_1 (type, DECL_NAME (fndecl));
if (ix >= 0) 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)) for (; fns; fns = OVL_NEXT (fns))
{ {
...@@ -2050,17 +2064,19 @@ reinit_search_statistics (void) ...@@ -2050,17 +2064,19 @@ reinit_search_statistics (void)
static tree static tree
add_conversions (tree binfo, void *data) add_conversions (tree binfo, void *data)
{ {
int i; size_t i;
tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo)); VEC(tree) *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
tree *conversions = (tree *) data; tree *conversions = (tree *) data;
tree tmp;
/* Some builtin types have no method vector, not even an empty one. */ /* Some builtin types have no method vector, not even an empty one. */
if (!method_vec) if (!method_vec)
return NULL_TREE; 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; tree name;
if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp))) if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
......
...@@ -2154,7 +2154,7 @@ finish_member_declaration (tree decl) ...@@ -2154,7 +2154,7 @@ finish_member_declaration (tree decl)
{ {
/* We also need to add this function to the /* We also need to add this function to the
CLASSTYPE_METHOD_VEC. */ 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); TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
TYPE_METHODS (current_class_type) = decl; TYPE_METHODS (current_class_type) = decl;
......
...@@ -244,6 +244,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -244,6 +244,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
removed object. This is an O(1) operation. */ removed object. This is an O(1) operation. */
#define VEC_unordered_remove(TDEF,V,I) (VEC_OP(TDEF,unordered_remove)(V,I)) #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 #if !IN_GENGTYPE
/* Reallocate an array of elements with prefix. */ /* Reallocate an array of elements with prefix. */
extern void *vec_p_reserve (void *, int MEM_STAT_DECL); extern void *vec_p_reserve (void *, int MEM_STAT_DECL);
...@@ -449,6 +456,12 @@ static inline TDEF VEC_OP (TDEF,unordered_remove) \ ...@@ -449,6 +456,12 @@ static inline TDEF VEC_OP (TDEF,unordered_remove) \
return obj_; \ return obj_; \
} \ } \
\ \
static inline TDEF *VEC_OP (TDEF,address) \
(VEC (TDEF) *vec_) \
{ \
return vec_ ? vec_->vec : 0; \
} \
\
struct vec_swallow_trailing_semi struct vec_swallow_trailing_semi
#endif #endif
...@@ -612,6 +625,12 @@ static inline void VEC_OP (TDEF,unordered_remove) \ ...@@ -612,6 +625,12 @@ static inline void VEC_OP (TDEF,unordered_remove) \
vec_->vec[ix_] = vec_->vec[--vec_->num]; \ 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 struct vec_swallow_trailing_semi
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment