Conversion operators kept on single overload set

Conversion operators kept on single overload set
	* class.c (add_method): Keep all conv-ops on one slot.
	* name-lookup.c (lookup_conversion_operator): Pull the desired
	conv op out of overload set.
	* search.c (lookup_conversions_r): Lose template/non-template
	distinction.
	(lookup_conversions): Likewise.

From-SVN: r251340
This commit is contained in:
Nathan Sidwell 2017-08-24 18:39:41 +00:00 committed by Nathan Sidwell
parent 281de9c2d5
commit 2e12a8554c
4 changed files with 77 additions and 153 deletions

View file

@ -1,3 +1,13 @@
2017-08-24 Nathan Sidwell <nathan@acm.org>
Conversion operators kept on single overload set
* class.c (add_method): Keep all conv-ops on one slot.
* name-lookup.c (lookup_conversion_operator): Pull the desired
conv op out of overload set.
* search.c (lookup_conversions_r): Lose template/non-template
distinction.
(lookup_conversions): Likewise.
2017-08-23 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (lookup_field_1, lookup_fnfields_slot,

View file

@ -1014,30 +1014,16 @@ modify_vtable_entry (tree t,
bool
add_method (tree type, tree method, bool via_using)
{
unsigned slot;
bool template_conv_p = false;
bool conv_p;
vec<tree, va_gc> *method_vec;
bool complete_p;
bool insert_p = false;
tree current_fns;
if (method == error_mark_node)
return false;
complete_p = COMPLETE_TYPE_P (type);
conv_p = DECL_CONV_FN_P (method);
if (conv_p)
template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
&& DECL_TEMPLATE_CONV_FN_P (method));
bool complete_p = COMPLETE_TYPE_P (type);
bool conv_p = DECL_CONV_FN_P (method);
method_vec = CLASSTYPE_METHOD_VEC (type);
vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
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. */
/* Make a new method vector. We start with 8 entries. */
vec_alloc (method_vec, 8);
CLASSTYPE_METHOD_VEC (type) = method_vec;
}
@ -1045,24 +1031,22 @@ add_method (tree type, tree method, bool via_using)
/* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */
grok_special_member_properties (method);
bool insert_p = true;
unsigned slot;
tree m;
insert_p = true;
/* See if we already have an entry with this name. */
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
vec_safe_iterate (method_vec, slot, &m);
++slot)
{
m = OVL_FIRST (m);
if (template_conv_p)
if (conv_p)
{
if (TREE_CODE (m) == TEMPLATE_DECL
&& DECL_TEMPLATE_CONV_FN_P (m))
if (DECL_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;
@ -1073,7 +1057,8 @@ add_method (tree type, tree method, bool via_using)
&& DECL_NAME (m) > DECL_NAME (method))
break;
}
current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
tree current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
gcc_assert (!DECL_EXTERN_C_P (method));
/* Check to see if we've already got this method. */
for (ovl_iterator iter (current_fns); iter; ++iter)
@ -1216,8 +1201,7 @@ add_method (tree type, tree method, bool via_using)
}
/* A class should never have more than one destructor. */
if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
return false;
gcc_assert (!current_fns || !DECL_DESTRUCTOR_P (method));
current_fns = ovl_insert (method, current_fns, via_using);

View file

@ -1096,34 +1096,31 @@ lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *args)
static tree
lookup_conversion_operator (tree class_type, tree type)
{
tree tpls = NULL_TREE;
tree convs = NULL_TREE;
if (TYPE_HAS_CONVERSION (class_type))
{
tree fns;
tree fns = NULL_TREE;
tree tpls = NULL_TREE;
vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
for (int i = CLASSTYPE_FIRST_CONVERSION_SLOT;
vec_safe_iterate (methods, i, &fns); ++i)
vec_safe_iterate (methods, CLASSTYPE_FIRST_CONVERSION_SLOT, &fns);
if (fns && !DECL_CONV_FN_P (OVL_FIRST (fns)))
fns = NULL_TREE;
for (ovl_iterator iter (fns); iter; ++iter)
{
/* 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. */
tree fn = OVL_FIRST (fns);
if (!DECL_CONV_FN_P (fn))
break;
if (same_type_p (DECL_CONV_FN_TYPE (*iter), type))
convs = lookup_add (*iter, convs);
if (TREE_CODE (fn) == TEMPLATE_DECL)
/* All the templated conversion functions are on the same
slot, so remember it. */
tpls = fns;
else if (same_type_p (DECL_CONV_FN_TYPE (fn), type))
return fns;
if (TREE_CODE (*iter) == TEMPLATE_DECL)
tpls = lookup_add (*iter, tpls);
}
if (!convs)
convs = tpls;
}
return tpls;
return convs;
}
/* TYPE is a class type. Return the member functions in the method

View file

@ -38,8 +38,7 @@ static tree dfs_dcast_hint_post (tree, void *);
static tree dfs_debug_mark (tree, void *);
static int check_hidden_convs (tree, int, int, tree, tree, tree);
static tree split_conversions (tree, tree, tree, tree);
static int lookup_conversions_r (tree, int, int,
tree, tree, tree, tree, tree *, tree *);
static int lookup_conversions_r (tree, int, int, tree, tree, tree *);
static int look_for_overrides_r (tree, tree);
static tree lookup_field_r (tree, void *);
static tree dfs_accessible_post (tree, void *);
@ -2333,14 +2332,13 @@ split_conversions (tree my_convs, tree parent_convs,
}
/* Worker for lookup_conversions. Lookup conversion functions in
BINFO and its children. VIRTUAL_DEPTH is nonzero, if BINFO is in
a morally virtual base, and VIRTUALNESS is nonzero, if we've
encountered virtual bases already in the tree walk. PARENT_CONVS &
PARENT_TPL_CONVS are lists of list of conversions within parent
binfos. OTHER_CONVS and OTHER_TPL_CONVS are conversions found
elsewhere in the tree. Return the conversions found within this
portion of the graph in CONVS and TPL_CONVS. Return nonzero is we
encountered virtualness. We keep template and non-template
BINFO and its children. VIRTUAL_DEPTH is nonzero, if BINFO is in a
morally virtual base, and VIRTUALNESS is nonzero, if we've
encountered virtual bases already in the tree walk. PARENT_CONVS
is a list of conversions within parent binfos. OTHER_CONVS are
conversions found elsewhere in the tree. Return the conversions
found within this portion of the graph in CONVS. Return nonzero if
we encountered virtualness. We keep template and non-template
conversions separate, to avoid unnecessary type comparisons.
The located conversion functions are held in lists of lists. The
@ -2353,26 +2351,17 @@ split_conversions (tree my_convs, tree parent_convs,
is the converted-to type. */
static int
lookup_conversions_r (tree binfo,
int virtual_depth, int virtualness,
tree parent_convs, tree parent_tpl_convs,
tree other_convs, tree other_tpl_convs,
tree *convs, tree *tpl_convs)
lookup_conversions_r (tree binfo, int virtual_depth, int virtualness,
tree parent_convs, tree other_convs, tree *convs)
{
int my_virtualness = 0;
tree my_convs = NULL_TREE;
tree my_tpl_convs = NULL_TREE;
tree child_convs = NULL_TREE;
tree child_tpl_convs = NULL_TREE;
unsigned i;
tree base_binfo;
vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
tree conv;
/* If we have no conversion operators, then don't look. */
if (!TYPE_HAS_CONVERSION (BINFO_TYPE (binfo)))
{
*convs = *tpl_convs = NULL_TREE;
*convs = NULL_TREE;
return 0;
}
@ -2381,60 +2370,32 @@ lookup_conversions_r (tree binfo,
virtual_depth++;
/* First, locate the unhidden ones at this level. */
for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
vec_safe_iterate (method_vec, i, &conv);
++i)
vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
tree conv = NULL_TREE;
vec_safe_iterate (method_vec, CLASSTYPE_FIRST_CONVERSION_SLOT, &conv);
if (conv && !DECL_CONV_FN_P (OVL_FIRST (conv)))
conv = NULL_TREE;
for (ovl_iterator iter (conv); iter; ++iter)
{
tree cur = OVL_FIRST (conv);
tree fn = *iter;
tree type = DECL_CONV_FN_TYPE (fn);
if (!DECL_CONV_FN_P (cur))
break;
if (TREE_CODE (cur) == TEMPLATE_DECL)
/* Only template conversions can be overloaded, and we must
flatten them out and check each one individually. */
for (ovl_iterator iter (conv); iter; ++iter)
{
tree tpl = *iter;
tree type = DECL_CONV_FN_TYPE (tpl);
if (check_hidden_convs (binfo, virtual_depth, virtualness,
type, parent_tpl_convs, other_tpl_convs))
{
my_tpl_convs = tree_cons (binfo, tpl, my_tpl_convs);
TREE_TYPE (my_tpl_convs) = type;
if (virtual_depth)
{
TREE_STATIC (my_tpl_convs) = 1;
my_virtualness = 1;
}
}
}
else
if (TREE_CODE (fn) != TEMPLATE_DECL && type_uses_auto (type))
{
tree name = DECL_NAME (cur);
mark_used (fn);
type = DECL_CONV_FN_TYPE (fn);
}
if (!IDENTIFIER_MARKED (name))
if (check_hidden_convs (binfo, virtual_depth, virtualness,
type, parent_convs, other_convs))
{
my_convs = tree_cons (binfo, fn, my_convs);
TREE_TYPE (my_convs) = type;
if (virtual_depth)
{
tree type = DECL_CONV_FN_TYPE (cur);
if (type_uses_auto (type))
{
mark_used (cur);
type = DECL_CONV_FN_TYPE (cur);
}
if (check_hidden_convs (binfo, virtual_depth, virtualness,
type, parent_convs, other_convs))
{
my_convs = tree_cons (binfo, conv, my_convs);
TREE_TYPE (my_convs) = type;
if (virtual_depth)
{
TREE_STATIC (my_convs) = 1;
my_virtualness = 1;
}
IDENTIFIER_MARKED (name) = 1;
}
TREE_STATIC (my_convs) = 1;
my_virtualness = 1;
}
}
}
@ -2446,41 +2407,27 @@ lookup_conversions_r (tree binfo,
TREE_STATIC (parent_convs) = 1;
}
if (my_tpl_convs)
{
parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
if (virtual_depth)
TREE_STATIC (parent_tpl_convs) = 1;
}
child_convs = other_convs;
child_tpl_convs = other_tpl_convs;
/* Now iterate over each base, looking for more conversions. */
unsigned i;
tree base_binfo;
for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
tree base_convs, base_tpl_convs;
tree base_convs;
unsigned base_virtualness;
base_virtualness = lookup_conversions_r (base_binfo,
virtual_depth, virtualness,
parent_convs, parent_tpl_convs,
child_convs, child_tpl_convs,
&base_convs, &base_tpl_convs);
parent_convs, child_convs,
&base_convs);
if (base_virtualness)
my_virtualness = virtualness = 1;
child_convs = chainon (base_convs, child_convs);
child_tpl_convs = chainon (base_tpl_convs, child_tpl_convs);
}
/* Unmark the conversions found at this level */
for (conv = my_convs; conv; conv = TREE_CHAIN (conv))
IDENTIFIER_MARKED (OVL_NAME (TREE_VALUE (conv))) = 0;
*convs = split_conversions (my_convs, parent_convs,
child_convs, other_convs);
*tpl_convs = split_conversions (my_tpl_convs, parent_tpl_convs,
child_tpl_convs, other_tpl_convs);
return my_virtualness;
}
@ -2497,17 +2444,16 @@ lookup_conversions_r (tree binfo,
tree
lookup_conversions (tree type)
{
tree convs, tpl_convs;
tree list = NULL_TREE;
tree convs;
complete_type (type);
if (!CLASS_TYPE_P (type) || !TYPE_BINFO (type))
return NULL_TREE;
lookup_conversions_r (TYPE_BINFO (type), 0, 0,
NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
&convs, &tpl_convs);
lookup_conversions_r (TYPE_BINFO (type), 0, 0, NULL_TREE, NULL_TREE, &convs);
tree list = NULL_TREE;
/* Flatten the list-of-lists */
for (; convs; convs = TREE_CHAIN (convs))
{
@ -2522,19 +2468,6 @@ lookup_conversions (tree type)
}
}
for (; tpl_convs; tpl_convs = TREE_CHAIN (tpl_convs))
{
tree probe, next;
for (probe = TREE_VALUE (tpl_convs); probe; probe = next)
{
next = TREE_CHAIN (probe);
TREE_CHAIN (probe) = list;
list = probe;
}
}
return list;
}