Julian Brown wrote:
This patch adds support for parsing general lvalues ("locator list item
types") for OpenMP "map", "to" and "from" clauses to the C front-end,
similar to the previously-posted patch for C++. Such syntax is permitted
for OpenMP 5.0 and above. It was previously posted for mainline here
...
In libgomp/libgomp.texi, the following can now be set to 'Y':
@item C/C++'s lvalue expressions in @code{to}, @code{from}
and @code{map} clauses @tab N @tab
@@ -11253,16 +11263,41 @@ c_parser_postfix_expression_after_primary (c_parser
*parser,
case CPP_OPEN_SQUARE:
/* Array reference. */
c_parser_consume_token (parser);
- idx = c_parser_expression (parser).value;
- c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
- "expected %<]%>");
- start = expr.get_start ();
- finish = parser->tokens_buf[0].location;
- expr.value = build_array_ref (op_loc, expr.value, idx);
- set_c_expr_source_range (&expr, start, finish);
- expr.original_code = ERROR_MARK;
- expr.original_type = NULL;
- expr.m_decimal = 0;
+ idx = len = NULL_TREE;
+ if (!c_omp_array_section_p
+ || c_parser_next_token_is_not (parser, CPP_COLON))
+ idx = c_parser_expression (parser).value;
+
+ if (c_omp_array_section_p
+ && c_parser_next_token_is (parser, CPP_COLON))
+ {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
+ len = c_parser_expression (parser).value;
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ "expected %<]%>");
+
+ start = expr.get_start ();
+ finish = parser->tokens_buf[0].location;
+ expr.value = build_omp_array_section (op_loc, expr.value, idx,
+ len);
+ set_c_expr_source_range (&expr, start, finish);
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
+ }
+ else
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ "expected %<]%>");
+ start = expr.get_start ();
+ finish = parser->tokens_buf[0].location;
+ expr.value = build_array_ref (op_loc, expr.value, idx);
+ set_c_expr_source_range (&expr, start, finish);
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
+ expr.m_decimal = 0;
+ }
I think that's more readable when moving everything but the expr.value
assignment after the if/else (obviously for "if" also everything until
"len =" has to remain). That also adds the missing "m_decimal = 0" for
the "if" case.
@@ -13915,8 +13955,97 @@ c_parser_omp_variable_list (c_parser *parser,
...
+ else if (TREE_CODE (decl) == INDIRECT_REF)
+ {
+ /* Turn *foo into the representation previously used for
+ foo[0]. */
+ decl = TREE_OPERAND (decl, 0);
+ STRIP_NOPS (decl);
+
+ decl = build_omp_array_section (loc, decl, integer_zero_node,
+ integer_one_node);
+ }
I wonder whether we shouldn't use the C++ wording, i.e.
/* If we have "*foo" and
- it's an indirection of a reference, "unconvert" it,
i.e. strip the indirection (to just "foo").
- it's an indirection of a pointer, turn it into
"foo[0:1]". */
* * *
As remarked for cp/typecheck.cc's build_omp_array_section:
+tree
+build_omp_array_section (location_t loc, tree array, tree index, tree length)
+{
+ tree idxtype;
+
+ if (index != NULL_TREE
+ && length != NULL_TREE
+ && INTEGRAL_TYPE_P (TREE_TYPE (index))
+ && INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ {
+ tree low = fold_convert (sizetype, index);
+ tree high = fold_convert (sizetype, length);
+ high = size_binop (PLUS_EXPR, low, high);
+ high = size_binop (MINUS_EXPR, high, size_one_node);
+ idxtype = build_range_type (sizetype, low, high);
+ }
+ else if ((index == NULL_TREE || integer_zerop (index))
+ && length != NULL_TREE
+ && INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ idxtype = build_index_type (length);
+ else
+ idxtype = NULL_TREE;
+
+ tree type = TREE_TYPE (array);
+ gcc_assert (type);
+
+ tree sectype, eltype = TREE_TYPE (type);
+
+ /* It's not an array or pointer type. Just reuse the type of the original
+ expression as the type of the array section (an error will be raised
+ anyway, later). */
+ if (eltype == NULL_TREE
+ || error_operand_p (eltype)
+ || error_operand_p (idxtype))
+ sectype = TREE_TYPE (array);
+ else
+ sectype = build_array_type (eltype, idxtype);
+
+ return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array, index, length);
+}
I think that's more readable when having that if condition at the top
and moving everything before into the else branch.
Otherwise, LGTM.
Thanks for the patch!
Tobias