if (t == void_list_node)
return t;
+ if ((TREE_PURPOSE (t) && PACK_EXPANSION_P (TREE_PURPOSE (t)))
+ || (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))))
+ {
+ /* We have pack expansions, so expand those and
+ create a new list out of it. */
+
+ /* Expand the argument expressions. */
+ tree purposevec = NULL_TREE;
+ if (TREE_PURPOSE (t))
+ purposevec = tsubst_pack_expansion (TREE_PURPOSE (t), args,
+ complain, in_decl);
+ if (purposevec == error_mark_node)
+ return error_mark_node;
+
+ tree valuevec = NULL_TREE;
+ if (TREE_VALUE (t))
+ valuevec = tsubst_pack_expansion (TREE_VALUE (t), args,
+ complain, in_decl);
+ if (valuevec == error_mark_node)
+ return error_mark_node;
+
+ /* Build the rest of the list. */
+ tree chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ chain = tsubst (chain, args, complain, in_decl);
+ if (chain == error_mark_node)
+ return error_mark_node;
+
+ /* Determine the number of arguments. */
+ int len = -1;
+ if (purposevec && TREE_CODE (purposevec) == TREE_VEC)
+ {
+ len = TREE_VEC_LENGTH (purposevec);
+ gcc_assert (!valuevec || len == TREE_VEC_LENGTH (valuevec));
+ }
+ else if (TREE_CODE (valuevec) == TREE_VEC)
+ len = TREE_VEC_LENGTH (valuevec);
+ else
+ {
+ /* Since we only performed a partial substitution into
+ the argument pack, we only RETURN (a single list
+ node. */
+ if (purposevec == TREE_PURPOSE (t)
+ && valuevec == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ return t;
+
+ return tree_cons (purposevec, valuevec, chain);
+ }
+
+ /* Convert the argument vectors into a TREE_LIST. */
+ for (int i = len; i-- > 0; )
+ {
+ purpose = (purposevec ? TREE_VEC_ELT (purposevec, i)
+ : NULL_TREE);
+ value = (valuevec ? TREE_VEC_ELT (valuevec, i)
+ : NULL_TREE);
+
+ /* Build the list (backwards). */
+ chain = hash_tree_cons (purpose, value, chain);
+ }
+
+ return chain;
+ }
+
purpose = TREE_PURPOSE (t);
if (purpose)
{
{
tree type1 = tsubst (TRAIT_EXPR_TYPE1 (t), args,
complain, in_decl);
-
- tree type2 = TRAIT_EXPR_TYPE2 (t);
- if (type2 && TREE_CODE (type2) == TREE_LIST)
- type2 = RECUR (type2);
- else if (type2)
- type2 = tsubst (type2, args, complain, in_decl);
-
+ tree type2 = tsubst (TRAIT_EXPR_TYPE2 (t), args,
+ complain, in_decl);
RETURN (finish_trait_expr (TRAIT_EXPR_LOCATION (t),
TRAIT_EXPR_KIND (t), type1, type2));
}