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:
parent
88459c3965
commit
25addf8352
4 changed files with 41 additions and 45 deletions
|
@ -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;
|
||||
|
|
57
gcc/cp/pt.cc
57
gcc/cp/pt.cc
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
15
gcc/tree.h
15
gcc/tree.h
|
@ -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, ...);
|
||||
|
|
Loading…
Add table
Reference in a new issue