On Sat, Jul 20, 2024 at 02:42:24PM -0600, Sandra Loosemore wrote:
> + const char *old_name = IDENTIFIER_POINTER (name);
> + char *new_name = (char *) alloca (strlen (old_name) + 32);
XALLOCAVEC like for the C FE patch.
> + /* FIXME: I believe it is an unimplemented feature rather
> + than a user error to have non-constant expressions
> + inside "declare variant". */
> + t = metadirective_p
> + ? cp_parser_expression (parser)
> + : cp_parser_constant_expression (parser);
> if (t != error_mark_node)
> {
> t = fold_non_dependent_expr (t);
> - if (!value_dependent_expression_p (t)
> + if (!metadirective_p
> + && !value_dependent_expression_p (t)
> && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
> || !tree_fits_shwi_p (t)))
> error_at (token->location, "property must be "
> "constant integer expression");
> + if (metadirective_p
> + && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
Shouldn't this be && !type_dependent_expression_p (t) before the
!INTEGRAL_TYPE_P check?
I mean
template <typename T, T N>
void
foo ()
{
#pragma omp metadirective ... user={condition(N)} ...
...
}
should be valid, or just typename T and foo (T x) and condition(x).
> + error_at (token->location,
> + "property must be integer expression");
> --- a/gcc/cp/parser.h
> +++ b/gcc/cp/parser.h
> @@ -450,6 +450,13 @@ struct GTY(()) cp_parser {
> /* Pointer to state for parsing omp_loops. Managed by
> cp_parser_omp_for_loop in parser.cc and not used outside that file. */
> struct omp_for_parse_data * GTY((skip)) omp_for_parse_state;
> +
> + /* Set if we are processing a statement body associated with a
> + metadirective variant. */
> + bool in_metadirective_body;
> +
> + vec<tree> * GTY((skip)) metadirective_body_labels;
> + unsigned metadirective_region_num;
Again, there is unnecessary padding here (pointer, 8-bit bool, pointer,
32-bit unsigned) and maybe put the stuff into a separate structure and just
use a pointer to it? Like the omp_for_parse_state. Though, it is less
important than in the C++ FE.
> };
>
> /* In parser.cc */
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 108e929b8ee..109121be501 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -17851,6 +17851,79 @@ tsubst_omp_clauses (tree clauses, enum
> c_omp_region_type ort,
> return new_clauses;
> }
>
> +/* Like tsubst_copy, but specifically for OpenMP context selectors. */
> +static tree
> +tsubst_omp_context_selector (tree ctx, tree args, tsubst_flags_t complain,
> + tree in_decl)
> +{
> + tree new_ctx = NULL_TREE;
> + for (tree set = ctx; set; set = TREE_CHAIN (set))
> + {
> + tree selectors = NULL_TREE;
> + for (tree sel = OMP_TSS_TRAIT_SELECTORS (set); sel;
> + sel = TREE_CHAIN (sel))
> + {
> + enum omp_ts_code code = OMP_TS_CODE (sel);
> + tree properties = NULL_TREE;
> + tree score = OMP_TS_SCORE (sel);
> + tree t;
> +
> + if (score)
> + {
> + score = tsubst_expr (score, args, complain, in_decl);
> + score = fold_non_dependent_expr (score);
I think for partial template specialization processing_template_decl
can be true, so wonder if in that case it shouldn't again not diagnose
anything if score is still value dependent expression.
> + switch (omp_ts_map[OMP_TS_CODE (sel)].tp_type)
> + {
> + case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
> + case OMP_TRAIT_PROPERTY_BOOL_EXPR:
> + t = tsubst_expr (OMP_TP_VALUE (OMP_TS_PROPERTIES (sel)),
> + args, complain, in_decl);
> + t = fold_non_dependent_expr (t);
> + if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
> + error_at (cp_expr_loc_or_input_loc (t),
> + "property must be integer expression");
And similarly here. Also, where do we do instantiation of the declare
variant selectors (if we do that at all)?
Jakub