* [PATCH] tree: introduce range adaptor for TREE_VEC
@ 2022-05-11 19:20 Patrick Palka
2022-05-11 19:29 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Patrick Palka @ 2022-05-11 19:20 UTC (permalink / raw)
To: gcc-patches
This patch implements a simple tree wrapper, named tree_vec_range, which
lets us idiomatically iterate 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++ frontend by r12-340-g3307b9a07a3c51.
This patch also converts some existing loops over TREE_VEC within the
C++ frontend to use tree_vec_range and range-for.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
useful?
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 (and simplify).
(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 access of length member.
(class tree_vec_range): Define.
---
gcc/cp/constraint.cc | 9 +++----
gcc/cp/pt.cc | 57 +++++++++++++++++---------------------------
gcc/cp/tree.cc | 5 ++--
gcc/tree.h | 15 +++++++++++-
4 files changed, 41 insertions(+), 45 deletions(-)
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 94f6222b436..591155cee22 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -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;
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 9932d861af6..2c7c5f8bb5d 100644
--- a/gcc/cp/pt.cc
+++ b/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))
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 633cc164a3a..bc38c8fbdbe 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -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;
diff --git a/gcc/tree.h b/gcc/tree.h
index 82eb8ba39d2..0c12c60ee7e 100644
--- a/gcc/tree.h
+++ b/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 an 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, ...);
--
2.36.0.63.gf5aaf72f1b
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] tree: introduce range adaptor for TREE_VEC
2022-05-11 19:20 [PATCH] tree: introduce range adaptor for TREE_VEC Patrick Palka
@ 2022-05-11 19:29 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2022-05-11 19:29 UTC (permalink / raw)
To: Patrick Palka, gcc-patches
On 5/11/22 15:20, Patrick Palka wrote:
> This patch implements a simple tree wrapper, named tree_vec_range, which
> lets us idiomatically iterate 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++ frontend by r12-340-g3307b9a07a3c51.
>
> This patch also converts some existing loops over TREE_VEC within the
> C++ frontend to use tree_vec_range and range-for.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> useful?
OK.
> 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 (and simplify).
> (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 access of length member.
> (class tree_vec_range): Define.
> ---
> gcc/cp/constraint.cc | 9 +++----
> gcc/cp/pt.cc | 57 +++++++++++++++++---------------------------
> gcc/cp/tree.cc | 5 ++--
> gcc/tree.h | 15 +++++++++++-
> 4 files changed, 41 insertions(+), 45 deletions(-)
>
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index 94f6222b436..591155cee22 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -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;
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 9932d861af6..2c7c5f8bb5d 100644
> --- a/gcc/cp/pt.cc
> +++ b/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))
> diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
> index 633cc164a3a..bc38c8fbdbe 100644
> --- a/gcc/cp/tree.cc
> +++ b/gcc/cp/tree.cc
> @@ -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;
>
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 82eb8ba39d2..0c12c60ee7e 100644
> --- a/gcc/tree.h
> +++ b/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 an 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, ...);
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-05-11 19:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-11 19:20 [PATCH] tree: introduce range adaptor for TREE_VEC Patrick Palka
2022-05-11 19:29 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).