cp-tree.h (ovl_iterator::using_p): New predicate.
* cp-tree.h (ovl_iterator::using_p): New predicate. (ovl_iterator::remove_node): New worker. (ovl_insert): Declare. * tree.c (ovl_insert): New. (ovl_iterator::remove_node): New. * class.c (add_method): Use ovl_iterator, ovl_insert. (clone_function_decl): Fix description. (clone_constructors_and_destructors): Use ovl_iterator. From-SVN: r248151
This commit is contained in:
parent
19b476fb8d
commit
36f4bc9ce8
@ -1,5 +1,14 @@
|
||||
2017-05-17 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* cp-tree.h (ovl_iterator::using_p): New predicate.
|
||||
(ovl_iterator::remove_node): New worker.
|
||||
(ovl_insert): Declare.
|
||||
* tree.c (ovl_insert): New.
|
||||
(ovl_iterator::remove_node): New.
|
||||
* class.c (add_method): Use ovl_iterator, ovl_insert.
|
||||
(clone_function_decl): Fix description.
|
||||
(clone_constructors_and_destructors): Use ovl_iterator.
|
||||
|
||||
* class.c (handle_using_decl): Use OVL_FIRST, ovl_iterator.
|
||||
(maybe_warn_about_overly_private_class): Use ovl_iterator.
|
||||
(method_name_cmp, resort_method_name_cmp): Use OVL_NAME.
|
||||
|
@ -1010,7 +1010,6 @@ bool
|
||||
add_method (tree type, tree method, bool via_using)
|
||||
{
|
||||
unsigned slot;
|
||||
tree overload;
|
||||
bool template_conv_p = false;
|
||||
bool conv_p;
|
||||
vec<tree, va_gc> *method_vec;
|
||||
@ -1059,7 +1058,7 @@ add_method (tree type, tree method, bool via_using)
|
||||
vec_safe_iterate (method_vec, slot, &m);
|
||||
++slot)
|
||||
{
|
||||
m = OVL_CURRENT (m);
|
||||
m = OVL_FIRST (m);
|
||||
if (template_conv_p)
|
||||
{
|
||||
if (TREE_CODE (m) == TEMPLATE_DECL
|
||||
@ -1083,24 +1082,23 @@ add_method (tree type, tree method, bool via_using)
|
||||
current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
|
||||
|
||||
/* Check to see if we've already got this method. */
|
||||
for (tree *p = ¤t_fns; *p; )
|
||||
for (ovl_iterator iter (current_fns); iter; ++iter)
|
||||
{
|
||||
tree fns = *p;
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
tree fn = *iter;
|
||||
tree fn_type;
|
||||
tree method_type;
|
||||
tree parms1;
|
||||
tree parms2;
|
||||
|
||||
if (TREE_CODE (fn) != TREE_CODE (method))
|
||||
goto cont;
|
||||
continue;
|
||||
|
||||
/* Two using-declarations can coexist, we'll complain about ambiguity in
|
||||
overload resolution. */
|
||||
if (via_using && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)
|
||||
if (via_using && iter.using_p ()
|
||||
/* Except handle inherited constructors specially. */
|
||||
&& ! DECL_CONSTRUCTOR_P (fn))
|
||||
goto cont;
|
||||
continue;
|
||||
|
||||
/* [over.load] Member function declarations with the
|
||||
same name and the same parameter types cannot be
|
||||
@ -1134,7 +1132,7 @@ add_method (tree type, tree method, bool via_using)
|
||||
== FUNCTION_REF_QUALIFIED (method_type))
|
||||
&& (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
|
||||
|| type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
|
||||
goto cont;
|
||||
continue;
|
||||
|
||||
/* For templates, the return type and template parameters
|
||||
must be identical. */
|
||||
@ -1143,7 +1141,7 @@ add_method (tree type, tree method, bool via_using)
|
||||
TREE_TYPE (method_type))
|
||||
|| !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
|
||||
DECL_TEMPLATE_PARMS (method))))
|
||||
goto cont;
|
||||
continue;
|
||||
|
||||
if (! DECL_STATIC_FUNCTION_P (fn))
|
||||
parms1 = TREE_CHAIN (parms1);
|
||||
@ -1187,8 +1185,9 @@ add_method (tree type, tree method, bool via_using)
|
||||
mangle_decl (method);
|
||||
}
|
||||
cgraph_node::record_function_versions (fn, method);
|
||||
goto cont;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DECL_INHERITED_CTOR (method))
|
||||
{
|
||||
if (DECL_INHERITED_CTOR (fn))
|
||||
@ -1202,7 +1201,7 @@ add_method (tree type, tree method, bool via_using)
|
||||
/* Inheriting the same constructor along different
|
||||
paths, combine them. */
|
||||
SET_DECL_INHERITED_CTOR
|
||||
(fn, ovl_cons (DECL_INHERITED_CTOR (method),
|
||||
(fn, ovl_make (DECL_INHERITED_CTOR (method),
|
||||
DECL_INHERITED_CTOR (fn)));
|
||||
/* And discard the new one. */
|
||||
return false;
|
||||
@ -1210,7 +1209,7 @@ add_method (tree type, tree method, bool via_using)
|
||||
else
|
||||
/* Inherited ctors can coexist until overload
|
||||
resolution. */
|
||||
goto cont;
|
||||
continue;
|
||||
}
|
||||
error_at (DECL_SOURCE_LOCATION (method),
|
||||
"%q#D", method);
|
||||
@ -1228,8 +1227,8 @@ add_method (tree type, tree method, bool via_using)
|
||||
else if (flag_new_inheriting_ctors
|
||||
&& DECL_INHERITED_CTOR (fn))
|
||||
{
|
||||
/* Hide the inherited constructor. */
|
||||
*p = OVL_NEXT (fns);
|
||||
/* Remove the inherited constructor. */
|
||||
current_fns = iter.remove_node (current_fns);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@ -1238,33 +1237,19 @@ add_method (tree type, tree method, bool via_using)
|
||||
error ("with %q+#D", fn);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cont:
|
||||
if (TREE_CODE (fns) == OVERLOAD)
|
||||
p = &OVL_CHAIN (fns);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* A class should never have more than one destructor. */
|
||||
if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
|
||||
return false;
|
||||
|
||||
/* Add the new binding. */
|
||||
if (via_using)
|
||||
{
|
||||
overload = ovl_cons (method, current_fns);
|
||||
OVL_USED (overload) = true;
|
||||
}
|
||||
else
|
||||
overload = build_overload (method, current_fns);
|
||||
current_fns = ovl_insert (method, current_fns, via_using);
|
||||
|
||||
if (conv_p)
|
||||
TYPE_HAS_CONVERSION (type) = 1;
|
||||
else if (slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
|
||||
push_class_level_binding (DECL_NAME (method), overload);
|
||||
push_class_level_binding (DECL_NAME (method), current_fns);
|
||||
|
||||
if (insert_p)
|
||||
{
|
||||
@ -1279,13 +1264,13 @@ add_method (tree type, tree method, bool via_using)
|
||||
if (reallocated)
|
||||
CLASSTYPE_METHOD_VEC (type) = method_vec;
|
||||
if (slot == method_vec->length ())
|
||||
method_vec->quick_push (overload);
|
||||
method_vec->quick_push (current_fns);
|
||||
else
|
||||
method_vec->quick_insert (slot, overload);
|
||||
method_vec->quick_insert (slot, current_fns);
|
||||
}
|
||||
else
|
||||
/* Replace the current slot. */
|
||||
(*method_vec)[slot] = overload;
|
||||
(*method_vec)[slot] = current_fns;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4873,8 +4858,7 @@ decl_cloned_function_p (const_tree decl, bool just_testing)
|
||||
|
||||
/* Produce declarations for all appropriate clones of FN. If
|
||||
UPDATE_METHODS is true, the clones are added to the
|
||||
CLASTYPE_METHOD_VEC. VIA_USING indicates whether these are cloning
|
||||
decls brought in via using declarations (i.e. inheriting ctors). */
|
||||
CLASSTYPE_METHOD_VEC. */
|
||||
|
||||
void
|
||||
clone_function_decl (tree fn, bool update_methods)
|
||||
@ -5017,8 +5001,6 @@ adjust_clone_args (tree decl)
|
||||
static void
|
||||
clone_constructors_and_destructors (tree t)
|
||||
{
|
||||
tree fns;
|
||||
|
||||
/* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
|
||||
out now. */
|
||||
if (!CLASSTYPE_METHOD_VEC (t))
|
||||
@ -5026,10 +5008,10 @@ clone_constructors_and_destructors (tree t)
|
||||
|
||||
/* While constructors can be via a using declaration, at this point
|
||||
we no longer need to know that. */
|
||||
for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
|
||||
clone_function_decl (OVL_CURRENT (fns), /*update_methods=*/true);
|
||||
for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
|
||||
clone_function_decl (OVL_CURRENT (fns), /*update_methods=*/true);
|
||||
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
|
||||
clone_function_decl (*iter, /*update_methods=*/true);
|
||||
for (ovl_iterator iter (CLASSTYPE_DESTRUCTORS (t)); iter; ++iter)
|
||||
clone_function_decl (*iter, /*update_methods=*/true);
|
||||
}
|
||||
|
||||
/* Deduce noexcept for a destructor DTOR. */
|
||||
|
@ -680,6 +680,22 @@ class ovl_iterator
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
public:
|
||||
/* Whether this overload was introduced by a using decl. */
|
||||
bool using_p () const
|
||||
{
|
||||
return TREE_CODE (ovl) == OVERLOAD && OVL_USED (ovl);
|
||||
}
|
||||
tree remove_node (tree head)
|
||||
{
|
||||
return remove_node (head, ovl);
|
||||
}
|
||||
|
||||
private:
|
||||
/* We make this a static function to avoid the address of the
|
||||
iterator escaping the local context. */
|
||||
static tree remove_node (tree head, tree node);
|
||||
};
|
||||
|
||||
/* Iterator over a (potentially) 2 dimensional overload, which is
|
||||
@ -6768,6 +6784,8 @@ extern tree build_ref_qualified_type (tree, cp_ref_qualifier);
|
||||
inline tree ovl_first (tree) ATTRIBUTE_PURE;
|
||||
extern tree ovl_make (tree fn,
|
||||
tree next = NULL_TREE);
|
||||
extern tree ovl_insert (tree fn, tree maybe_ovl,
|
||||
bool using_p = false);
|
||||
extern tree lookup_add (tree lookup, tree ovl);
|
||||
extern int is_overloaded_fn (tree);
|
||||
extern tree dependent_name (tree);
|
||||
|
@ -2124,6 +2124,65 @@ ovl_make (tree fn, tree next)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Add FN to the (potentially NULL) overload set OVL. USING_P is
|
||||
true, if FN is via a using declaration. Overloads are ordered as
|
||||
using, regular. */
|
||||
|
||||
tree
|
||||
ovl_insert (tree fn, tree maybe_ovl, bool using_p)
|
||||
{
|
||||
int weight = using_p;
|
||||
|
||||
tree result = NULL_TREE;
|
||||
tree insert_after = NULL_TREE;
|
||||
|
||||
/* Find insertion point. */
|
||||
while (maybe_ovl && TREE_CODE (maybe_ovl) == OVERLOAD
|
||||
&& (weight < OVL_USED (maybe_ovl)))
|
||||
{
|
||||
if (!result)
|
||||
result = maybe_ovl;
|
||||
insert_after = maybe_ovl;
|
||||
maybe_ovl = OVL_CHAIN (maybe_ovl);
|
||||
}
|
||||
|
||||
tree trail = fn;
|
||||
if (maybe_ovl || using_p || TREE_CODE (fn) == TEMPLATE_DECL)
|
||||
{
|
||||
trail = ovl_make (fn, maybe_ovl);
|
||||
if (using_p)
|
||||
OVL_USED (trail) = true;
|
||||
}
|
||||
|
||||
if (insert_after)
|
||||
{
|
||||
TREE_CHAIN (insert_after) = trail;
|
||||
TREE_TYPE (insert_after) = unknown_type_node;
|
||||
}
|
||||
else
|
||||
result = trail;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* NODE is on the overloads of OVL. Remove it. */
|
||||
|
||||
tree
|
||||
ovl_iterator::remove_node (tree overload, tree node)
|
||||
{
|
||||
tree *slot = &overload;
|
||||
while (*slot != node)
|
||||
slot = &OVL_CHAIN (*slot);
|
||||
|
||||
/* Stitch out NODE. We don't have to worry about now making a
|
||||
singleton overload (and consequently maybe setting its type),
|
||||
because all uses of this function will be followed by inserting a
|
||||
new node that must follow the place we've cut this out from. */
|
||||
*slot = OVL_CHAIN (node);
|
||||
|
||||
return overload;
|
||||
}
|
||||
|
||||
/* Add a potential overload into a lookup set. */
|
||||
|
||||
tree
|
||||
|
Loading…
Reference in New Issue
Block a user