tree: introduce range adaptor for TREE_VEC

This patch implements a simple tree wrapper, named tree_vec_range, which
lets us idiomatically loop over all the elements of a TREE_VEC using a
C++11 range-based for loop:

  // v is a TREE_VEC
  for (tree e : tree_vec_range (v))
    ...

This is similar to the existing tree-based range adaptors ovl_range and
lkp_range added to the C++ FE in r12-340-g3307b9a07a3c51.

This patch also converts some existing loops over TREE_VEC within the
C++ FE to use tree_vec_range / range-for.

gcc/cp/ChangeLog:

	* constraint.cc (tsubst_parameter_mapping): Convert loop over
	TREE_VEC into a range-based for loop using tree_vec_range.
	* pt.cc (iterative_hash_template_arg): Likewise.
	(template_parms_level_to_args): Likewise.
	(deducible_template_args): Likewise.
	(check_undeduced_parms): Likewise.
	(dependent_type_p_r): Likewise.
	(value_dependent_expression_p) <case NONTYPE_ARGUMENT_PACK>:
	Likewise.
	(dependent_template_arg_p): Likewise.
	* tree.cc (cp_walk_subtrees) <case NONTYPE_ARGUMENT_PACK>:
	Likewise.

gcc/ChangeLog:

	* tree.h (TREE_VEC_BEGIN): Define.
	(TREE_VEC_END): Correct 'length' member access.
	(class tree_vec_range): Define.
This commit is contained in:
Patrick Palka 2022-05-11 16:14:59 -04:00
parent 88459c3965
commit 25addf8352
4 changed files with 41 additions and 45 deletions

View file

@ -2348,12 +2348,9 @@ tsubst_parameter_mapping (tree map, tree args, subst_info info)
if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
{
tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
for (int i = 0; i < TREE_VEC_LENGTH (pack_args); i++)
{
tree& pack_arg = TREE_VEC_ELT (pack_args, i);
if (TYPE_P (pack_arg))
pack_arg = canonicalize_type_argument (pack_arg, complain);
}
for (tree& pack_arg : tree_vec_range (pack_args))
if (TYPE_P (pack_arg))
pack_arg = canonicalize_type_argument (pack_arg, complain);
}
if (new_arg == error_mark_node)
return error_mark_node;

View file

@ -1811,8 +1811,8 @@ iterative_hash_template_arg (tree arg, hashval_t val)
return iterative_hash_object (IDENTIFIER_HASH_VALUE (arg), val);
case TREE_VEC:
for (int i = 0, len = TREE_VEC_LENGTH (arg); i < len; ++i)
val = iterative_hash_template_arg (TREE_VEC_ELT (arg, i), val);
for (tree elt : tree_vec_range (arg))
val = iterative_hash_template_arg (elt, val);
return val;
case TYPE_PACK_EXPANSION:
@ -4883,15 +4883,15 @@ template_parm_to_arg (tree t)
tree
template_parms_level_to_args (tree parms)
{
tree a = copy_node (parms);
TREE_TYPE (a) = NULL_TREE;
for (int i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
parms = copy_node (parms);
TREE_TYPE (parms) = NULL_TREE;
for (tree& parm : tree_vec_range (parms))
parm = template_parm_to_arg (parm);
if (CHECKING_P)
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (parms, TREE_VEC_LENGTH (parms));
return a;
return parms;
}
/* Given a set of template parameters, return them as a set of template
@ -22470,10 +22470,9 @@ deducible_array_bound (tree domain)
static bool
deducible_template_args (tree args)
{
for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
for (tree elt : tree_vec_range (args))
{
bool deducible;
tree elt = TREE_VEC_ELT (args, i);
if (ARGUMENT_PACK_P (elt))
deducible = deducible_template_args (ARGUMENT_PACK_ARGS (elt));
else
@ -24844,12 +24843,11 @@ static bool
check_undeduced_parms (tree targs, tree args, tree end)
{
bool found = false;
int i;
for (i = TREE_VEC_LENGTH (targs) - 1; i >= 0; --i)
if (TREE_VEC_ELT (targs, i) == NULL_TREE)
for (tree& targ : tree_vec_range (targs))
if (targ == NULL_TREE)
{
found = true;
TREE_VEC_ELT (targs, i) = error_mark_node;
targ = error_mark_node;
}
if (found)
{
@ -27288,10 +27286,9 @@ dependent_type_p_r (tree type)
if (TREE_CODE (type) == TYPE_ARGUMENT_PACK)
{
tree args = ARGUMENT_PACK_ARGS (type);
int i, len = TREE_VEC_LENGTH (args);
for (i = 0; i < len; ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
for (tree arg : tree_vec_range (args))
if (dependent_template_arg_p (arg))
return true;
}
/* All TYPE_PACK_EXPANSIONs are dependent, because parameter packs must
@ -27574,16 +27571,10 @@ value_dependent_expression_p (tree expression)
case NONTYPE_ARGUMENT_PACK:
/* A NONTYPE_ARGUMENT_PACK is value-dependent if any packed argument
is value-dependent. */
{
tree values = ARGUMENT_PACK_ARGS (expression);
int i, len = TREE_VEC_LENGTH (values);
for (i = 0; i < len; ++i)
if (value_dependent_expression_p (TREE_VEC_ELT (values, i)))
return true;
return false;
}
for (tree arg : tree_vec_range (ARGUMENT_PACK_ARGS (expression)))
if (value_dependent_expression_p (arg))
return true;
return false;
case TRAIT_EXPR:
{
@ -28209,13 +28200,9 @@ dependent_template_arg_p (tree arg)
else if (ARGUMENT_PACK_P (arg))
{
tree args = ARGUMENT_PACK_ARGS (arg);
int i, len = TREE_VEC_LENGTH (args);
for (i = 0; i < len; ++i)
{
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
}
for (tree arg : tree_vec_range (args))
if (dependent_template_arg_p (arg))
return true;
return false;
}
else if (TYPE_P (arg))

View file

@ -5414,9 +5414,8 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
case NONTYPE_ARGUMENT_PACK:
{
tree args = ARGUMENT_PACK_ARGS (*tp);
int i, len = TREE_VEC_LENGTH (args);
for (i = 0; i < len; i++)
WALK_SUBTREE (TREE_VEC_ELT (args, i));
for (tree arg : tree_vec_range (args))
WALK_SUBTREE (arg);
}
break;

View file

@ -1107,8 +1107,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* In a TREE_VEC node. */
#define TREE_VEC_LENGTH(NODE) (TREE_VEC_CHECK (NODE)->base.u.length)
#define TREE_VEC_BEGIN(NODE) (&TREE_VEC_CHECK (NODE)->vec.a[0])
#define TREE_VEC_END(NODE) \
((void) TREE_VEC_CHECK (NODE), &((NODE)->vec.a[(NODE)->vec.base.u.length]))
((void) TREE_VEC_CHECK (NODE), &((NODE)->vec.a[(NODE)->base.u.length]))
#define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I)
@ -4481,6 +4482,18 @@ extern tree make_tree_vec (int CXX_MEM_STAT_INFO);
extern tree grow_tree_vec (tree v, int CXX_MEM_STAT_INFO);
/* Treat a TREE_VEC as a range of trees, e.g.
for (tree e : tree_vec_range (v)) { ... } */
class tree_vec_range
{
tree v;
public:
tree_vec_range(tree v) : v(v) { }
tree *begin() { return TREE_VEC_BEGIN (v); }
tree *end() { return TREE_VEC_END (v); }
};
/* Construct various types of nodes. */
extern tree build_nt (enum tree_code, ...);