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