gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Convert a TREE_VEC
of arguments into a TREE_LIST for sake of pretty printing.
* cxx-pretty-print.cc (pp_cxx_trait): Handle TREE_VEC
instead of TREE_LIST of variadic trait arguments.
* method.cc (constructible_expr): Likewise.
(is_xible_helper): Likewise.
* parser.cc (cp_parser_trait): Represent variadic trait
arguments as a TREE_VEC instead of TREE_LIST.
* pt.cc (value_dependent_expression_p): Handle TREE_VEC
instead of TREE_LIST of variadic trait arguments.
* semantics.cc (finish_type_pack_element): Likewise.
(check_trait_type): Likewise.
---
gcc/cp/constraint.cc | 10 ++++++++++
gcc/cp/cxx-pretty-print.cc | 6 +++---
gcc/cp/method.cc | 17 +++++++++--------
gcc/cp/parser.cc | 10 ++++++----
gcc/cp/pt.cc | 9 ++++-----
gcc/cp/semantics.cc | 15 +++++++++------
6 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 273d15ab097..dfead28e8c7 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3675,6 +3675,16 @@ diagnose_trait_expr (tree expr, tree args)
tree t1 = TRAIT_EXPR_TYPE1 (expr);
tree t2 = TRAIT_EXPR_TYPE2 (expr);
+ if (t2 && TREE_CODE (t2) == TREE_VEC)
+ {
+ /* Convert the TREE_VEC of arguments into a TREE_LIST, since the
+ pretty printer cannot directly print a TREE_VEC but it can a
+ TREE_LIST via the E format specifier. */
+ tree list = NULL_TREE;
+ for (tree t : tree_vec_range (t2))
+ list = tree_cons (NULL_TREE, t, list);
+ t2 = nreverse (list);
+ }
switch (TRAIT_EXPR_KIND (expr))
{
case CPTK_HAS_NOTHROW_ASSIGN:
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index c33919873f1..4cda27f2b30 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -2640,16 +2640,16 @@ pp_cxx_trait (cxx_pretty_printer *pp, tree t)
}
if (type2)
{
- if (TREE_CODE (type2) != TREE_LIST)
+ if (TREE_CODE (type2) != TREE_VEC)
{
pp_cxx_separate_with (pp, ',');
pp->type_id (type2);
}
else
- for (tree arg = type2; arg; arg = TREE_CHAIN (arg))
+ for (tree arg : tree_vec_range (type2))
{
pp_cxx_separate_with (pp, ',');
- pp->type_id (TREE_VALUE (arg));
+ pp->type_id (arg);
}
}
if (kind == CPTK_TYPE_PACK_ELEMENT)
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 225ec456143..00eae56eb5b 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -2075,8 +2075,9 @@ constructible_expr (tree to, tree from)
if (!TYPE_REF_P (to))
to = cp_build_reference_type (to, /*rval*/false);
tree ob = build_stub_object (to);
- for (; from; from = TREE_CHAIN (from))
- vec_safe_push (args, build_stub_object (TREE_VALUE (from)));
+ vec_alloc (args, TREE_VEC_LENGTH (from));
+ for (tree arg : tree_vec_range (from))
+ args->quick_push (build_stub_object (arg));
expr = build_special_member_call (ob, complete_ctor_identifier, &args,
ctype, LOOKUP_NORMAL, tf_none);
if (expr == error_mark_node)
@@ -2096,9 +2097,9 @@ constructible_expr (tree to, tree from)
}
else
{
- if (from == NULL_TREE)
+ const int len = TREE_VEC_LENGTH (from);
+ if (len == 0)
return build_value_init (strip_array_types (to), tf_none);
- const int len = list_length (from);
if (len > 1)
{
if (cxx_dialect < cxx20)
@@ -2112,9 +2113,9 @@ constructible_expr (tree to, tree from)
should be true. */
vec<constructor_elt, va_gc> *v;
vec_alloc (v, len);
- for (tree t = from; t; t = TREE_CHAIN (t))
+ for (tree arg : tree_vec_range (from))
{
- tree stub = build_stub_object (TREE_VALUE (t));
+ tree stub = build_stub_object (arg);
constructor_elt elt = { NULL_TREE, stub };
v->quick_push (elt);
}
@@ -2123,7 +2124,7 @@ constructible_expr (tree to, tree from)
CONSTRUCTOR_IS_PAREN_INIT (from) = true;
}
else
- from = build_stub_object (TREE_VALUE (from));
+ from = build_stub_object (TREE_VEC_ELT (from, 0));
expr = perform_direct_initialization_if_possible (to, from,
/*cast*/false,
tf_none);
@@ -2160,7 +2161,7 @@ is_xible_helper (enum tree_code code, tree to, tree from,
bool trivial)
tree expr;
if (code == MODIFY_EXPR)
expr = assignable_expr (to, from);
- else if (trivial && from && TREE_CHAIN (from)
+ else if (trivial && TREE_VEC_LENGTH (from) > 1
&& cxx_dialect < cxx20)
return error_mark_node; // only 0- and 1-argument ctors can be trivial
// before C++20 aggregate paren init
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index ee1497b7071..7ecf97b937b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -11003,9 +11003,8 @@ cp_parser_trait (cp_parser* parser, enum rid keyword)
"is not a type");
return error_mark_node;
}
- type2 = tree_cons (NULL_TREE, elt, type2);
}
- type2 = nreverse (type2);
+ type2 = rest;
}
else if (binary)
{
@@ -11021,6 +11020,7 @@ cp_parser_trait (cp_parser* parser, enum rid keyword)
}
else if (variadic)
{
+ auto_vec<tree, 4> rest;
while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
{
cp_lexer_consume_token (parser->lexer);
@@ -11032,9 +11032,11 @@ cp_parser_trait (cp_parser* parser, enum rid keyword)
}
if (elt == error_mark_node)
return error_mark_node;
- type2 = tree_cons (NULL_TREE, elt, type2);
+ rest.safe_push (elt);
}
- type2 = nreverse (type2);
+ type2 = make_tree_vec (rest.length ());
+ for (int i = 0; i < TREE_VEC_LENGTH (type2); ++i)
+ TREE_VEC_ELT (type2, i) = rest[i];
}
location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f65f2d58b28..d393c99ba9e 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -28065,19 +28065,18 @@ value_dependent_expression_p (tree expression)
case TRAIT_EXPR:
{
- tree type2 = TRAIT_EXPR_TYPE2 (expression);
-
if (dependent_type_p (TRAIT_EXPR_TYPE1 (expression)))
return true;
+ tree type2 = TRAIT_EXPR_TYPE2 (expression);
if (!type2)
return false;
- if (TREE_CODE (type2) != TREE_LIST)
+ if (TREE_CODE (type2) != TREE_VEC)
return dependent_type_p (type2);
- for (; type2; type2 = TREE_CHAIN (type2))
- if (dependent_type_p (TREE_VALUE (type2)))
+ for (tree arg : tree_vec_range (type2))
+ if (dependent_type_p (arg))
return true;
return false;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a4f30fdac11..9ba316ab3be 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4490,14 +4490,13 @@ finish_type_pack_element (tree idx, tree types,
tsubst_flags_t complain)
error ("%<__type_pack_element%> index is negative");
return error_mark_node;
}
- tree result = chain_index (val, types);
- if (!result)
+ if (val >= TREE_VEC_LENGTH (types))
{
if (complain & tf_error)
error ("%<__type_pack_element%> index is out of range");
return error_mark_node;
}
- return TREE_VALUE (result);
+ return TREE_VEC_ELT (types, val);
}
/* Implement the __direct_bases keyword: Return the direct base classes
@@ -12121,9 +12120,13 @@ check_trait_type (tree type, int kind = 1)
if (type == NULL_TREE)
return true;
- if (TREE_CODE (type) == TREE_LIST)
- return (check_trait_type (TREE_VALUE (type))
- && check_trait_type (TREE_CHAIN (type)));
+ if (TREE_CODE (type) == TREE_VEC)
+ {
+ for (tree arg : tree_vec_range (type))
+ if (!check_trait_type (arg, kind))
+ return false;
+ return true;
+ }
if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
return true; // Array of unknown bound. Don't care about completeness.