On Sat, Jul 20, 2024 at 02:42:23PM -0600, Sandra Loosemore wrote:
> --- a/gcc/c/c-parser.cc
> +++ b/gcc/c/c-parser.cc
> @@ -263,9 +263,24 @@ struct GTY(()) c_parser {
>       otherwise NULL.  */
>    vec<c_token, va_gc> *in_omp_attribute_pragma;
>  
> +  /* When in_omp_attribute_pragma is non-null, these fields save the values
> +     of the tokens and tokens_avail fields, so that they can be restored
> +     after parsing the attribute.  Note that parsing the body of a
> +     metadirective uses its own save/restore mechanism as those can be
> +     nested with or without the attribute pragmas in the body.  */
> +    c_token * GTY((skip)) save_tokens;
> +    unsigned int save_tokens_avail;

The indentation of the above 2 is wrong.
Plus if those members are for metadirective parsing, their names are too
generic.

> +
>    /* Set for omp::decl attribute parsing to the decl to which it
>       appertains.  */
>    tree in_omp_decl_attribute;
> +
> +  /* Set if we are processing a statement body associated with a
> +     metadirective variant.  */
> +  BOOL_BITFIELD in_metadirective_body : 1;

And the member ordering creates just too much padding.
Pointer, 32-bit int, pointer, 1-bit bitfield, pointer, 32-bit int,
reordering them slightly would get rid of that.

> +
> +  vec<tree> * GTY((skip)) metadirective_body_labels;
> +  unsigned int metadirective_region_num;

But more importantly, for something parsed really rarely, wouldn't it be
better to just add a single pointer to a new structure that contains
all you need for metadirective parsing?

> +  const char *old_name = IDENTIFIER_POINTER (name);
> +  char *new_name = (char *) alloca (strlen (old_name) + 32);

  char *new_name = XALLOCAVEC (char, strlen (old_name) + 32);
please.

> +  sprintf (new_name, "%s_MDR%u", old_name, parser->metadirective_region_num);
> +  return get_identifier (new_name);
> +}
> +
>  /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
>  
>     label:
> @@ -7431,6 +7483,9 @@ c_parser_label (c_parser *parser, tree std_attrs)
>        gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
>        c_parser_consume_token (parser);
>        attrs = c_parser_gnu_attributes (parser);
> +      if (parser->in_metadirective_body
> +       && parser->metadirective_body_labels->contains (name))
> +     name = mangle_metadirective_region_label (parser, name);
>        tlab = define_label (loc2, name);
>        if (tlab)
>       {
> @@ -7658,8 +7713,11 @@ c_parser_statement_after_labels (c_parser *parser, 
> bool *if_p,
>         c_parser_consume_token (parser);
>         if (c_parser_next_token_is (parser, CPP_NAME))
>           {
> -           stmt = c_finish_goto_label (loc,
> -                                       c_parser_peek_token (parser)->value);
> +           tree name = c_parser_peek_token (parser)->value;
> +           if (parser->in_metadirective_body
> +               && parser->metadirective_body_labels->contains (name))
> +             name = mangle_metadirective_region_label (parser, name);
> +           stmt = c_finish_goto_label (loc, name);
>             c_parser_consume_token (parser);
>           }
>         else if (c_parser_next_token_is (parser, CPP_MULT))
> @@ -14736,6 +14794,10 @@ c_parser_pragma (c_parser *parser, enum 
> pragma_context context, bool *if_p)
>        c_parser_omp_nothing (parser);
>        return false;
>  
> +    case PRAGMA_OMP_METADIRECTIVE:
> +      c_parser_omp_metadirective (parser, if_p);
> +      return true;
> +
>      case PRAGMA_OMP_ERROR:
>        return c_parser_omp_error (parser, context);
>  
> @@ -24879,7 +24941,7 @@ c_parser_omp_declare_simd (c_parser *parser, enum 
> pragma_context context)
>  
>  static tree
>  c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set,
> -                            tree parms)
> +                            tree parms, bool metadirective_p)
>  {
>    tree ret = NULL_TREE;
>    do
> @@ -25026,12 +25088,18 @@ c_parser_omp_context_selector (c_parser *parser, 
> enum omp_tss_code set,
>               {
>                 mark_exp_read (t);
>                 t = c_fully_fold (t, false, NULL);
> -               /* FIXME: this is bogus, both device_num and
> -                  condition selectors allow arbitrary expressions.  */

Not in 5.0, that is a 5.1 feature that hasn't been implemented in the
initial declare variant implementation (and target_device set with
device_num didn't exist there at all).

> -               if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
> -                   || !tree_fits_shwi_p (t))
> -                 error_at (token->location, "property must be "
> -                           "constant integer expression");
> +               /* FIXME: I believe it is an unimplemented feature rather
> +                  than a user error to have non-constant expressions
> +                  inside "declare variant".  */
> +               if (!metadirective_p
> +                   && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
> +                       || !tree_fits_shwi_p  (t)))
> +                 error_at (token->location,
> +                           "property must be constant integer expression");
> +               else if (metadirective_p
> +                        && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
> +                 error_at (token->location,
> +                           "property must be integer expression");
>                 else
>                   properties = make_trait_property (NULL_TREE, t,
>                                                     properties);

> +       /* Remove the selector from further consideration if can be
> +          evaluated as a non-match at this point.  */

if it can be ?

        Jakub

Reply via email to