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
This commit is contained in:
Mark Mitchell 2004-07-16 01:15:43 +00:00
parent b38b6477f8
commit aaaa46d2b0
13 changed files with 276 additions and 262 deletions

View File

@ -1,3 +1,7 @@
2004-07-15 Nathan Sidwell <nathan@codesourcery.com>
* vec.h (VEC_address): New function.
2004-07-14 Jason Merrill <jason@redhat.com>
PR middle-end/15885

View File

@ -1,3 +1,54 @@
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>
* cp-lang.c (cxx_types_compatible_p): To the middle-end,
@ -13,7 +64,7 @@
(copy_binfo): Declare.
2004-07-15 Mark Mitchell <mark@codesourcery.com>
* name-lookup.c (set_inherited_value_binding_p): Add class_type
parameter.
(get_class_binding): Adjust.

View File

@ -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;
/* See if we already have an entry with this name. */
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot)
{
tree m = TREE_VEC_ELT (method_vec, slot);
bool insert_p = true;
bool conv_p = DECL_CONV_FN_P (method);
tree m;
if (!m)
break;
/* See if we already have an entry with this name. */
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
(m = VEC_iterate (tree, method_vec, slot));
++slot)
{
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 (conv_p && !DECL_CONV_FN_P (m))
break;
if (DECL_NAME (m) == DECL_NAME (method))
{
insert_p = false;
break;
}
if (complete_p
&& !DECL_CONV_FN_P (m)
&& DECL_NAME (m) > DECL_NAME (method))
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
{
/* 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;
}
}
/* 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) ||

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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)))

View File

@ -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;

View File

@ -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