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:
parent
b38b6477f8
commit
aaaa46d2b0
@ -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
|
||||
|
@ -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.
|
||||
|
291
gcc/cp/class.c
291
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;
|
||||
|
||||
/* 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) ||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
13
gcc/cp/pt.c
13
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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
100
gcc/cp/search.c
100
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)))
|
||||
|
@ -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;
|
||||
|
19
gcc/vec.h
19
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user