c++: C++11 range-for and ovl/lkp_iterator
We can't use C++11 range-based 'for' over a tree directly, because we don't know what kind of range we want to use it as. I suppose in some cases we could guess, but it seems better to tersely make it explicit. This patch adds range adaptors ovl_range and lkp_range for use as the range of a range-for, e.g. for (tree fn : lkp_range (fns)) { ... } This patch also removes the private copy ops from ovl_iterator; it's necessary for range-for, and these are effectively C++ forward_iterators, which allow copying, so I don't see a reason to prevent it. A bit more would need to be done to make them actually conform as C++11 forward iterators, but I don't think we particularly want to #include <iterator> yet. gcc/cp/ChangeLog: * cp-tree.h (class ovl_iterator): Allow copying. Add op==. (class ovl_range, class lkp_range): New. * call.c (build_op_call_1, add_candidates): Use them. (build_op_delete_call, has_trivial_copy_assign_p): Likewise. (has_trivial_copy_p): Likewise. * class.c (handle_using_decl, get_basefndecls): Likewise. (maybe_warn_about_overly_private_class): Likewise. (warn_hidden, add_implicitly_declared_members): Likewise. (check_methods, clone_constructors_and_destructors): Likewise. (type_has_user_nondefault_constructor): Likewise.
This commit is contained in:
parent
3c65858787
commit
3307b9a07a
@ -4914,10 +4914,8 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
|
||||
|| TYPE_REFFN_P (totype)
|
||||
|| (TYPE_REF_P (totype)
|
||||
&& TYPE_PTRFN_P (TREE_TYPE (totype))))
|
||||
for (ovl_iterator iter (TREE_VALUE (convs)); iter; ++iter)
|
||||
for (tree fn : ovl_range (TREE_VALUE (convs)))
|
||||
{
|
||||
tree fn = *iter;
|
||||
|
||||
if (DECL_NONCONVERTING_P (fn))
|
||||
continue;
|
||||
|
||||
@ -5981,10 +5979,8 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
|
||||
which = non_templates;
|
||||
|
||||
again:
|
||||
for (lkp_iterator iter (fns); iter; ++iter)
|
||||
for (tree fn : lkp_range (fns))
|
||||
{
|
||||
fn = *iter;
|
||||
|
||||
if (check_converting && DECL_NONCONVERTING_P (fn))
|
||||
continue;
|
||||
if (check_list_ctor && !is_list_ctor (fn))
|
||||
@ -7016,10 +7012,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
||||
the usual deallocation function, so we shouldn't complain
|
||||
about using the operator delete (void *, size_t). */
|
||||
if (DECL_CLASS_SCOPE_P (fn))
|
||||
for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns));
|
||||
iter; ++iter)
|
||||
for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
|
||||
{
|
||||
tree elt = *iter;
|
||||
if (usual_deallocation_fn_p (elt)
|
||||
&& FUNCTION_ARG_CHAIN (elt) == void_list_node)
|
||||
goto ok;
|
||||
@ -7062,9 +7056,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
||||
allocation function. If the lookup finds a single matching
|
||||
deallocation function, that function will be called; otherwise, no
|
||||
deallocation function will be called." */
|
||||
for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns)); iter; ++iter)
|
||||
for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
|
||||
{
|
||||
tree elt = *iter;
|
||||
dealloc_info di_elt;
|
||||
if (usual_deallocation_fn_p (elt, &di_elt))
|
||||
{
|
||||
@ -9669,10 +9662,8 @@ has_trivial_copy_assign_p (tree type, bool access, bool *hasassign)
|
||||
/* Iterate over overloads of the assignment operator, checking
|
||||
accessible copy assignments for triviality. */
|
||||
|
||||
for (ovl_iterator oi (fns); oi; ++oi)
|
||||
for (tree f : ovl_range (fns))
|
||||
{
|
||||
tree f = *oi;
|
||||
|
||||
/* Skip operators that aren't copy assignments. */
|
||||
if (!copy_fn_p (f))
|
||||
continue;
|
||||
@ -9715,10 +9706,8 @@ has_trivial_copy_p (tree type, bool access, bool hasctor[2])
|
||||
tree fns = get_class_binding (type, complete_ctor_identifier);
|
||||
bool all_trivial = true;
|
||||
|
||||
for (ovl_iterator oi (fns); oi; ++oi)
|
||||
for (tree f : ovl_range (fns))
|
||||
{
|
||||
tree f = *oi;
|
||||
|
||||
/* Skip template constructors. */
|
||||
if (TREE_CODE (f) != FUNCTION_DECL)
|
||||
continue;
|
||||
|
@ -1347,10 +1347,10 @@ handle_using_decl (tree using_decl, tree t)
|
||||
|
||||
/* Make type T see field decl FDECL with access ACCESS. */
|
||||
if (flist)
|
||||
for (ovl_iterator iter (flist); iter; ++iter)
|
||||
for (tree f : ovl_range (flist))
|
||||
{
|
||||
add_method (t, *iter, true);
|
||||
alter_access (t, *iter, access);
|
||||
add_method (t, f, true);
|
||||
alter_access (t, f, access);
|
||||
}
|
||||
else if (USING_DECL_UNRELATED_P (using_decl))
|
||||
{
|
||||
@ -2259,18 +2259,20 @@ maybe_warn_about_overly_private_class (tree t)
|
||||
if (!TYPE_HAS_COPY_CTOR (t))
|
||||
nonprivate_ctor = true;
|
||||
else
|
||||
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t));
|
||||
!nonprivate_ctor && iter; ++iter)
|
||||
if (TREE_PRIVATE (*iter))
|
||||
for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
|
||||
if (TREE_PRIVATE (fn))
|
||||
continue;
|
||||
else if (copy_fn_p (*iter) || move_fn_p (*iter))
|
||||
else if (copy_fn_p (fn) || move_fn_p (fn))
|
||||
/* Ideally, we wouldn't count any constructor that takes
|
||||
an argument of the class type as a parameter, because
|
||||
such things cannot be used to construct an instance of
|
||||
the class unless you already have one. */
|
||||
copy_or_move = *iter;
|
||||
copy_or_move = fn;
|
||||
else
|
||||
nonprivate_ctor = true;
|
||||
{
|
||||
nonprivate_ctor = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nonprivate_ctor)
|
||||
{
|
||||
@ -2876,10 +2878,8 @@ get_basefndecls (tree name, tree t, vec<tree> *base_fndecls)
|
||||
bool found_decls = false;
|
||||
|
||||
/* Find virtual functions in T with the indicated NAME. */
|
||||
for (ovl_iterator iter (get_class_binding (t, name)); iter; ++iter)
|
||||
for (tree method : ovl_range (get_class_binding (t, name)))
|
||||
{
|
||||
tree method = *iter;
|
||||
|
||||
if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method))
|
||||
{
|
||||
base_fndecls->safe_push (method);
|
||||
@ -2988,9 +2988,8 @@ warn_hidden (tree t)
|
||||
continue;
|
||||
|
||||
/* Remove any overridden functions. */
|
||||
for (ovl_iterator iter (fns); iter; ++iter)
|
||||
for (tree fndecl : ovl_range (fns))
|
||||
{
|
||||
tree fndecl = *iter;
|
||||
if (TREE_CODE (fndecl) == FUNCTION_DECL
|
||||
&& DECL_VINDEX (fndecl))
|
||||
{
|
||||
@ -3334,8 +3333,8 @@ add_implicitly_declared_members (tree t, tree* access_decls,
|
||||
tree ctor_list = decl;
|
||||
location_t loc = input_location;
|
||||
input_location = DECL_SOURCE_LOCATION (using_decl);
|
||||
for (ovl_iterator iter (ctor_list); iter; ++iter)
|
||||
one_inherited_ctor (*iter, t, using_decl);
|
||||
for (tree fn : ovl_range (ctor_list))
|
||||
one_inherited_ctor (fn, t, using_decl);
|
||||
*access_decls = TREE_CHAIN (*access_decls);
|
||||
input_location = loc;
|
||||
}
|
||||
@ -4751,9 +4750,8 @@ check_methods (tree t)
|
||||
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true;
|
||||
}
|
||||
|
||||
for (ovl_iterator i (CLASSTYPE_CONSTRUCTORS (t)); i; ++i)
|
||||
for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
|
||||
{
|
||||
tree fn = *i;
|
||||
if (!user_provided_p (fn))
|
||||
/* Might be trivial. */;
|
||||
else if (copy_fn_p (fn))
|
||||
@ -4762,10 +4760,8 @@ check_methods (tree t)
|
||||
TYPE_HAS_COMPLEX_MOVE_CTOR (t) = true;
|
||||
}
|
||||
|
||||
for (ovl_iterator i (get_class_binding_direct (t, assign_op_identifier));
|
||||
i; ++i)
|
||||
for (tree fn : ovl_range (get_class_binding_direct (t, assign_op_identifier)))
|
||||
{
|
||||
tree fn = *i;
|
||||
if (!user_provided_p (fn))
|
||||
/* Might be trivial. */;
|
||||
else if (copy_fn_p (fn))
|
||||
@ -5107,8 +5103,8 @@ clone_constructors_and_destructors (tree t)
|
||||
{
|
||||
/* We do not need to propagate the usingness to the clone, at this
|
||||
point that is not needed. */
|
||||
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
|
||||
clone_cdtor (*iter, /*update_methods=*/true);
|
||||
for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
|
||||
clone_cdtor (fn, /*update_methods=*/true);
|
||||
|
||||
if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
|
||||
clone_cdtor (dtor, /*update_methods=*/true);
|
||||
@ -5283,9 +5279,8 @@ type_has_user_nondefault_constructor (tree t)
|
||||
if (!TYPE_HAS_USER_CONSTRUCTOR (t))
|
||||
return false;
|
||||
|
||||
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
|
||||
for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t)))
|
||||
{
|
||||
tree fn = *iter;
|
||||
if (user_provided_p (fn)
|
||||
&& (TREE_CODE (fn) == TEMPLATE_DECL
|
||||
|| (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
|
||||
|
@ -817,11 +817,6 @@ class ovl_iterator {
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
/* Do not duplicate. */
|
||||
ovl_iterator &operator= (const ovl_iterator &);
|
||||
ovl_iterator (const ovl_iterator &);
|
||||
|
||||
public:
|
||||
operator bool () const
|
||||
{
|
||||
@ -841,6 +836,10 @@ class ovl_iterator {
|
||||
|
||||
return fn;
|
||||
}
|
||||
bool operator== (const ovl_iterator &o) const
|
||||
{
|
||||
return ovl == o.ovl;
|
||||
}
|
||||
tree get_using () const
|
||||
{
|
||||
gcc_checking_assert (using_p ());
|
||||
@ -903,6 +902,19 @@ class ovl_iterator {
|
||||
static tree reveal_node (tree ovl, tree node);
|
||||
};
|
||||
|
||||
/* Treat a tree as a range of ovl_iterator, e.g.
|
||||
for (tree f : ovl_range (fns)) { ... } */
|
||||
|
||||
class ovl_range
|
||||
{
|
||||
tree t;
|
||||
bool allow;
|
||||
public:
|
||||
explicit ovl_range (tree t, bool allow = false): t(t), allow(allow) { }
|
||||
ovl_iterator begin() { return ovl_iterator (t, allow); }
|
||||
ovl_iterator end() { return ovl_iterator (NULL_TREE, allow); }
|
||||
};
|
||||
|
||||
/* Iterator over a (potentially) 2 dimensional overload, which is
|
||||
produced by name lookup. */
|
||||
|
||||
@ -935,6 +947,18 @@ class lkp_iterator : public ovl_iterator {
|
||||
}
|
||||
};
|
||||
|
||||
/* Treat a tree as a range of lkp_iterator, e.g.
|
||||
for (tree f : lkp_range (fns)) { ... } */
|
||||
|
||||
class lkp_range
|
||||
{
|
||||
tree t;
|
||||
public:
|
||||
lkp_range (tree t): t(t) { }
|
||||
lkp_iterator begin() { return lkp_iterator (t); }
|
||||
lkp_iterator end() { return lkp_iterator (NULL_TREE); }
|
||||
};
|
||||
|
||||
/* hash traits for declarations. Hashes potential overload sets via
|
||||
DECL_NAME. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user