This patch implements C++26 Pack Indexing, as described in
<https://wg21.link/P2662R3>.
The issue discussing how to mangle pack indexes has not been resolved
yet <https://github.com/itanium-cxx-abi/cxx-abi/issues/175> and I've
made no attempt to address it so far.
Unlike v1, which used augmented TYPE/EXPR_PACK_EXPANSION codes, this
version introduces two new codes: PACK_INDEX_EXPR and PACK_INDEX_TYPE.
Both carry two operands: the pack expansion and the index. They are
handled in tsubst_pack_index: substitute the index and the pack and
then extract the element from the vector (if possible).
To handle pack indexing in a decltype or with decltype(auto), there is
also the new PACK_INDEX_PARENTHESIZED_P flag.
With this feature, it's valid to write something like
using U = tmpl<Ts...[Is]...>;
where we first expand the template argument into
Ts...[Is#0], Ts...[Is#1], ...
and then substitute each individual pack index.
PR c++/113798
gcc/cp/ChangeLog:
* constexpr.cc (potential_constant_expression_1) <case PACK_INDEX_EXPR>:
New case.
* cp-objcp-common.cc (cp_common_init_ts): Mark PACK_INDEX_TYPE and
PACK_INDEX_EXPR.
* cp-tree.def (PACK_INDEX_TYPE): New.
(PACK_INDEX_EXPR): New.
* cp-tree.h (WILDCARD_TYPE_P): Also check PACK_INDEX_TYPE.
(PACK_INDEX_CHECK): Define.
(PACK_INDEX_P): Define.
(PACK_INDEX_PACK): Define.
(PACK_INDEX_INDEX): Define.
(PACK_INDEX_PARENTHESIZED_P): Define.
(make_pack_index): Declare.
(pack_index_element): Declare.
* cxx-pretty-print.cc (cxx_pretty_printer::expression) <case
PACK_INDEX_EXPR>: New case.
(cxx_pretty_printer::type_id) <case PACK_INDEX_TYPE>: New case.
* error.cc (dump_type) <case PACK_INDEX_TYPE>: New case.
(dump_type_prefix): Handle PACK_INDEX_TYPE.
(dump_type_suffix): Likewise.
(dump_expr) <case PACK_INDEX_EXPR>: New case.
* mangle.cc (write_type) <case PACK_INDEX_TYPE>: New case.
* module.cc (trees_out::type_node) <case PACK_INDEX_TYPE>: New case.
(trees_in::tree_node) <case PACK_INDEX_TYPE>: New case.
* parser.cc (cp_parser_next_tokens_are_pack_index_p): New.
(cp_parser_pack_index): New.
(cp_parser_primary_expression): Handle a C++26 pack-index-expression.
(cp_parser_unqualified_id): Handle a C++26 pack-index-specifier.
(cp_parser_nested_name_specifier_opt): See if a pack-index-specifier
follows.
(cp_parser_qualifying_entity): Handle a C++26 pack-index-specifier.
(cp_parser_decltype_expr): Set id_expression_or_member_access_p for
pack indexing.
(cp_parser_mem_initializer_id): Handle a C++26 pack-index-specifier.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_base_specifier): Likewise.
* pt.cc (iterative_hash_template_arg) <case PACK_INDEX_TYPE,
PACK_INDEX_EXPR>: New case.
(find_parameter_packs_r) <case PACK_INDEX_TYPE, PACK_INDEX_EXPR>: New
case.
(make_pack_index): New.
(tsubst_pack_index): New.
(tsubst): Avoid tsubst on PACK_INDEX_TYPE.
<case TYPENAME_TYPE>: Add a call to error.
<case PACK_INDEX_TYPE>: New case.
(tsubst_expr) <case PACK_INDEX_EXPR>: New case.
(dependent_type_p_r): Return true for PACK_INDEX_TYPE.
(type_dependent_expression_p): Recurse on PACK_INDEX_PACK for
PACK_INDEX_EXPR.
* ptree.cc (cxx_print_type) <case PACK_INDEX_TYPE>: New case.
* semantics.cc (finish_parenthesized_expr): Set
PACK_INDEX_PARENTHESIZED_P for PACK_INDEX_EXPR.
(finish_type_pack_element): Adjust error messages.
(pack_index_element): New.
* tree.cc (cp_tree_equal) <case PACK_INDEX_EXPR>: New case.
(cp_walk_subtrees) <case PACK_INDEX_TYPE, PACK_INDEX_EXPR>: New case.
* typeck.cc (structural_comptypes) <case PACK_INDEX_TYPE>: New case.
* g++.dg/cpp26/pack-indexing1.C: New test.
* g++.dg/cpp26/pack-indexing2.C: New test.
* g++.dg/cpp26/pack-indexing3.C: New test.
* g++.dg/cpp26/pack-indexing4.C: New test.
* g++.dg/cpp26/pack-indexing5.C: New test.
* g++.dg/cpp26/pack-indexing6.C: New test.
* g++.dg/cpp26/pack-indexing7.C: New test.
* g++.dg/cpp26/pack-indexing8.C: New test.
* g++.dg/cpp26/pack-indexing9.C: New test.
* g++.dg/cpp26/pack-indexing10.C: New test.
* g++.dg/cpp26/pack-indexing11.C: New test.
* g++.dg/modules/pack-index-1_a.C: New test.
* g++.dg/modules/pack-index-1_b.C: New test.