On Wed, May 26, 2021 at 10:15:28PM +0200, Tobias Burnus wrote:
> @@ -15508,6 +15511,57 @@ c_parser_omp_iterators (c_parser *parser)
>    return ret ? ret : error_mark_node;
>  }
>  
> +/* OpenMP 5.0:
> +   affinity ( [aff-modifier :] variable-list )
> +   aff-modifier:
> +     iterator ( iterators-definition )  */
> +
> +static tree
> +c_parser_omp_clause_affinity (c_parser *parser, tree list)
> +{
> +  location_t clause_loc = c_parser_peek_token (parser)->location;
> +  tree nl, iterators = NULL_TREE;
> +
> +  matching_parens parens;
> +  if (!parens.require_open (parser))
> +    return list;
> +
> +  if (c_parser_next_token_is (parser, CPP_NAME))
> +    {
> +      const char *p = IDENTIFIER_POINTER (c_parser_peek_token 
> (parser)->value);
> +      if (strcmp ("iterator", p) == 0)
> +     {
> +       iterators = c_parser_omp_iterators (parser);
> +       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
> +         {
> +           if (iterators)
> +             pop_scope ();
> +           parens.skip_until_found_close (parser);
> +           return list;
> +         }
> +     }

One important thing I've missed.
Unlike depend clause where dependence-type : is required, in affinity clause
the aff-modifier is optional.
So
affinity (iterator)
should be valid (provided iterator is a variable), similarly
affinity (iterator(1,2,3)[0])
(e.g. if iterator is a function returning pointer), etc.
This is something that should be tested in the testsuite coverage, and
during parsing what we likely want to do is if we see iterator as the first
CPP_NAME, check if next token is ( and if yes, tentatively search for
corresponding balanced ) and check if it is followed by : and only in that
case c_parser_omp_iterators etc.
As Marcel found, in the C FE one can use c_parser_peek_nth_token_raw
for it and we even have c_parser_check_balanced_raw_token_sequence.

> +  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
> +    {
> +      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
> +      const char *p = IDENTIFIER_POINTER (id);
> +      if (strcmp ("iterator", p) == 0)
> +     {
> +       begin_scope (sk_omp, NULL);
> +       iterators = cp_parser_omp_iterators (parser);
> +       if (!cp_parser_require (parser, CPP_COLON, RT_COLON))

In the C++ FE we have two options, do tentative parsing (provided
that cp_parser_omp_iterators or anything it calls doesn't emit premature
errors), or can use cp_parser_skip_balanced_tokens to skip over the
( ... ) after iterator without consuming tokens to see if it is followed
by :.

> @@ -996,6 +999,107 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, 
> gfc_omp_map_op map_op,
>    return false;
>  }
>  
> +static match
> +gfc_match_iterator (gfc_namespace **ns)
> +{
> +  if (gfc_match ("iterator ( ") != MATCH_YES)
> +    return MATCH_NO;
> +
> +  gfc_typespec ts;
> +  gfc_symbol *last = NULL;
> +  gfc_expr *begin, *end, *step;
> +  *ns = gfc_build_block_ns (gfc_current_ns);

What happens with this block ns:

> +  char name[GFC_MAX_SYMBOL_LEN + 1];
> +  while (true)
> +    {
> +      locus old_loc = gfc_current_locus;
> +      if (gfc_match_type_spec (&ts) == MATCH_YES
> +       && gfc_match (" :: ") == MATCH_YES)
> +     {
> +       if (ts.type != BT_INTEGER)
> +         {
> +           gfc_error ("Expected INTEGER type at %L", &old_loc);

In the error handling?
Especially if it is tentative and user code just contains
affinity (iterator(4))
for say
integer :: iterator(20)
?

        Jakub

Reply via email to