diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ed36709..6f273bf 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -36406,11 +36406,22 @@ check_no_duplicate_clause (tree clauses, enum omp_clause_code code, The optional ALLOW_DEREF argument is true if list items can use the deref (->) operator. */ +struct omp_dim +{ + tree low_bound, length; + location_t loc; + bool no_colon; + omp_dim (tree lb, tree len, location_t lo, bool nc) + : low_bound (lb), length (len), loc (lo), no_colon (nc) {} +}; + static tree cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, tree list, bool *colon, bool allow_deref = false) { + auto_vec<omp_dim> dims; + bool array_section_p; cp_token *token; bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; if (colon) @@ -36491,6 +36502,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, case OMP_CLAUSE_MAP: case OMP_CLAUSE_FROM: case OMP_CLAUSE_TO: + start_component_ref: while (cp_lexer_next_token_is (parser->lexer, CPP_DOT) || (allow_deref && cp_lexer_next_token_is (parser->lexer, CPP_DEREF))) @@ -36514,14 +36526,19 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_IN_REDUCTION: case OMP_CLAUSE_TASK_REDUCTION: + array_section_p = false; + dims.truncate (0); while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { + location_t loc = UNKNOWN_LOCATION; tree low_bound = NULL_TREE, length = NULL_TREE; + bool no_colon = false; parser->colon_corrects_to_scope_p = false; cp_lexer_consume_token (parser->lexer); if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { + loc = cp_lexer_peek_token (parser->lexer)->location; low_bound = cp_parser_expression (parser); /* Later handling is not prepared to see through these. */ gcc_checking_assert (!location_wrapper_p (low_bound)); @@ -36530,7 +36547,10 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE)) - length = integer_one_node; + { + length = integer_one_node; + no_colon = true; + } else { /* Look for `:'. */ @@ -36543,6 +36563,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, } if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) cp_parser_commit_to_tentative_parse (parser); + else + array_section_p = true; if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE)) { @@ -36561,8 +36583,30 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, goto skip_comma; } - decl = tree_cons (low_bound, length, decl); + dims.safe_push (omp_dim (low_bound, length, loc, no_colon)); } + + if ((kind == OMP_CLAUSE_MAP + || kind == OMP_CLAUSE_FROM + || kind == OMP_CLAUSE_TO) + && !array_section_p + && (cp_lexer_next_token_is (parser->lexer, CPP_DOT) + || (allow_deref + && cp_lexer_next_token_is (parser->lexer, + CPP_DEREF)))) + { + for (unsigned i = 0; i < dims.length (); i++) + { + gcc_assert (dims[i].length == integer_one_node); + decl = build_array_ref (dims[i].loc, + decl, dims[i].low_bound); + } + goto start_component_ref; + } + else + for (unsigned i = 0; i < dims.length (); i++) + decl = tree_cons (dims[i].low_bound, dims[i].length, decl); + break; default: break; @@ -40064,11 +40108,13 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE, clauses); else - clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, clauses); + clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, clauses, + true); c_name = "to"; break; case PRAGMA_OMP_CLAUSE_FROM: - clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, clauses); + clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, clauses, + true); c_name = "from"; break; case PRAGMA_OMP_CLAUSE_UNIFORM: |