diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 920 |
1 files changed, 423 insertions, 497 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6f3b4a583a6..774f51612e3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -44,7 +44,7 @@ extern int array_notation_label_no; extern void extract_array_notation_exprs (tree, bool, tree **, int *); extern tree fix_unary_array_notation_exprs (tree); extern bool contains_array_notation_expr (tree); -struct pragma_simd_values cilkplus_local_simd_values; + /* The lexer. */ @@ -238,7 +238,7 @@ static tree cp_literal_operator_id (const char *); static tree cp_parser_array_notation - (cp_parser *, tree, tree); + (location_t, cp_parser *, tree, tree); static vec<tree, va_gc> *cp_parser_elem_fn_expression_list (cp_parser *); @@ -621,30 +621,7 @@ cp_lexer_new_main (void) gcc_assert (!lexer->next_token->purged_p); - /* Here we initialize the cilkplus_local_simd_values structure. We only need - it initialized the first time, after each consumptions, for-loop will - automatically consume the values and delete the information. */ - cilkplus_local_simd_values.index = 0; - cilkplus_local_simd_values.pragma_encountered = false; - cilkplus_local_simd_values.types = P_SIMD_NOASSERT; - cilkplus_local_simd_values.vectorlength = NULL_TREE; - cilkplus_local_simd_values.vec_length_list = NULL; - cilkplus_local_simd_values.vec_length_size = 0; - cilkplus_local_simd_values.private_vars = NULL_TREE; - cilkplus_local_simd_values.priv_var_list = NULL; - cilkplus_local_simd_values.priv_var_size = 0; - - cilkplus_local_simd_values.linear_vars = NULL_TREE; - cilkplus_local_simd_values.linear_var_size = 0; - cilkplus_local_simd_values.linear_var_list = NULL; - cilkplus_local_simd_values.linear_steps = NULL_TREE; - cilkplus_local_simd_values.linear_steps_list = NULL; - cilkplus_local_simd_values.linear_steps_size = 0; - cilkplus_local_simd_values.reduction_vals = NULL; - cilkplus_local_simd_values.ptr_next = NULL; - - clear_pragma_simd_list (); - + array_notation_label_no = 0; return lexer; @@ -2393,15 +2370,16 @@ static tree cp_parser_cilk_for_condition static tree cp_parser_cilk_for_expression_iterator (cp_parser *parser); static void cp_parser_simd_vectorlength - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_private - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_reduction - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_linear - (cp_parser *parser, cp_token *pragma_token); + (cp_parser *parser, cp_token *pragma_token, struct pragma_simd_values *); static void cp_parser_simd_assert - (cp_parser *parser, cp_token *pragma_token, bool is_assert); + (cp_parser *parser, cp_token *pragma_token, bool is_assert, + struct pragma_simd_values *); /* Returns nonzero if we are parsing tentatively. */ @@ -6093,7 +6071,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, /* If we reach here, then we have something like this: ARRAY [:] */ - postfix_expression = cp_parser_array_notation (parser, NULL_TREE, + postfix_expression = cp_parser_array_notation (loc, parser, NULL_TREE, postfix_expression); else { @@ -6132,7 +6110,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, } if (flag_enable_cilk && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON) - postfix_expression = cp_parser_array_notation (parser, index, + postfix_expression = cp_parser_array_notation (loc, parser, index, postfix_expression); else { @@ -9749,24 +9727,13 @@ cp_parser_for (cp_parser *parser, struct pragma_simd_values *cilkplus_ps_values) if (!is_range_for && statement != error_mark_node) { - if (cilkplus_ps_values != NULL) - { - FOR_STMT_PRAGMA_SIMD_INDEX (statement) = - psv_head_insert (*cilkplus_ps_values); - /* Now we initialize them all to zeros. */ - cilkplus_ps_values->pragma_encountered = false; - cilkplus_ps_values->types = P_SIMD_NOASSERT; - cilkplus_ps_values->vectorlength = NULL_TREE; - cilkplus_ps_values->private_vars = NULL_TREE; - cilkplus_ps_values->linear_vars = NULL_TREE; - cilkplus_ps_values->linear_steps = NULL_TREE; - cilkplus_ps_values->reduction_vals = NULL; - } + if (flag_enable_cilk && cilkplus_ps_values + && p_simd_valid_stmts_in_body_p (FOR_BODY (statement))) + FOR_STMT_PRAGMA_SIMD_INDEX (statement) = + p_simd_head_insert (cilkplus_ps_values); else FOR_STMT_PRAGMA_SIMD_INDEX (statement) = INVALID_PRAGMA_SIMD_SLOT; } - - return statement; } @@ -28851,12 +28818,59 @@ cp_parser_initial_pragma (cp_token *first_token) cp_lexer_get_preprocessor_token (NULL, first_token); } +/* Handles the parsing of next clause for pragma simd. */ + +static void +cp_parser_simd_handle_next_clause (cp_parser *parser, const char *token_name, + cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) +{ + if (!strcmp (token_name, "linear")) + cp_parser_simd_linear (parser, pragma_token, p_simd_values); + else if (!strcmp (token_name, "private")) + cp_parser_simd_private (parser, pragma_token, p_simd_values); + else if (!strcmp (token_name, "reduction")) + cp_parser_simd_reduction (parser, pragma_token, p_simd_values); + else if (!strcmp (token_name, "assert")) + cp_parser_simd_assert (parser, pragma_token, true, p_simd_values); + else if (!strcmp (token_name, "noassert")) + cp_parser_simd_assert (parser, pragma_token, false, p_simd_values); + else if (!strcmp (token_name, "vectorlength")) + cp_parser_simd_vectorlength (parser, pragma_token, p_simd_values); + else + { + error_at (input_location, "unknown pragma simd clause: %s", + token_name); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + } +} + +static void +cp_parser_simd_construct (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + if (token->type != CPP_PRAGMA_EOL) + cp_lexer_consume_token (parser->lexer); + + /* This would mean that it has reached CPP_PRAGMA_EOL. */ + if (!token->u.value || token->type == CPP_PRAGMA_EOL) + cp_parser_simd_assert (parser, pragma_token, false, p_simd_values); + else + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); +} + + /* Normal parsing of a pragma token. Here we can (and must) use the regular lexer. */ static bool cp_parser_pragma (cp_parser *parser, enum pragma_context context) { + struct pragma_simd_values p_simd_values; cp_token *pragma_tok; unsigned int id; @@ -28966,59 +28980,12 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) } cp_parser_cilk_grainsize (parser, pragma_tok); return true; - - case PRAGMA_SIMD_ASSERT: - if (context == pragma_external) - { - error("%<#pragma simd assert%> may only be used inside a function"); - break; - } - cp_parser_simd_assert (parser, pragma_tok, true); - return true; - case PRAGMA_SIMD_NOASSERT: - if (context == pragma_external) - { - error("%<#pragma simd assert%> may only be used inside a function"); - break; - } - cp_parser_simd_assert (parser, pragma_tok, false); - return true; - - case PRAGMA_SIMD_VECTORLENGTH: - if (context == pragma_external) - { - error("%<#pragma simd vectorlength%> may only be used inside a function"); - break; - } - cp_parser_simd_vectorlength (parser, pragma_tok); - return true; - - case PRAGMA_SIMD_PRIVATE: - if (context == pragma_external) - { - error("%<#pragma simd private%> may only be used inside a function"); - break; - } - cp_parser_simd_private (parser, pragma_tok); - return true; - - case PRAGMA_SIMD_LINEAR: + case CILKPLUS_PRAGMA_SIMD: if (context == pragma_external) - { - error("%<#pragma simd linear%> may only be used inside a function"); - break; - } - cp_parser_simd_linear (parser, pragma_tok); - return true; - - case PRAGMA_SIMD_REDUCTION: - if (context == pragma_external) - { - error("%<#pragma simd reduction%> may only be used inside a function"); - break; - } - cp_parser_simd_reduction (parser, pragma_tok); + goto bad_stmt; + memset (&p_simd_values, 0, sizeof (struct pragma_simd_values)); + cp_parser_simd_construct (parser, pragma_tok, &p_simd_values); return true; default: @@ -29382,510 +29349,458 @@ cp_parser_cilk_for_expression_iterator (cp_parser *parser) build2 (t_code, TREE_TYPE (name), name, expr)); } -/* This function will parse the pragma simd vectorlength. */ +/* Returns true of a same variable is found in sub-field vectors + linear_var_list, priv_var_list and reduction_list of P_SIMD_VALUES. */ + +static bool +same_var_in_multiple_lists_p (struct pragma_simd_values *p_simd_values) +{ + size_t ii, jj, kk; + if (!p_simd_values) + return false; + + /* First check linear and private lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->linear_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->priv_var_list); jj++) + { + tree linear_var = (*(p_simd_values->linear_var_list))[ii]; + tree priv_var = (*(p_simd_values->priv_var_list))[jj]; + if (simple_cst_equal (linear_var, priv_var) == 1) + { + error_at (p_simd_values->loc, "ill-formed pragma: variable %qE" + " listed in both linear and private pragma simd clause", + priv_var); + return true; + } + } + + /* Now check linear and reduction lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->linear_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->reduction_list); jj++) + { + struct reduction_node r_node = (*(p_simd_values->reduction_list))[jj]; + for (kk = 0; kk < vec_safe_length (r_node.reduction_vars); kk++) + { + tree linear_var = (*(p_simd_values->linear_var_list))[ii]; + tree red_var = (*(r_node.reduction_vars))[kk]; + if (simple_cst_equal (linear_var, red_var) == 1) + { + error_at (p_simd_values->loc, + "ill-formed pragma: variable %qE listed in both " + "reduction and linear pragma simd clause", red_var); + return true; + } + } + } + + /* Finally check private and reduction lists. */ + for (ii = 0; ii < vec_safe_length (p_simd_values->priv_var_list); ii++) + for (jj = 0; jj < vec_safe_length (p_simd_values->reduction_list); jj++) + { + struct reduction_node r_node = (*(p_simd_values->reduction_list))[jj]; + for (kk = 0; kk < vec_safe_length (r_node.reduction_vars); kk++) + { + tree priv_var = (*(p_simd_values->priv_var_list))[ii]; + tree red_var = (*(r_node.reduction_vars))[kk]; + if (simple_cst_equal (priv_var, red_var) == 1) + { + error_at (p_simd_values->loc, + "ill-formed pragma: variable %qE listed in both " + "reduction and private pragma simd clause", red_var); + return true; + } + } + } + return false; +} + +/* This function will parse the pragma simd assert clause. */ static void -cp_parser_simd_vectorlength (cp_parser *parser, cp_token *pragma_token) +cp_parser_simd_assert (cp_parser *parser, cp_token *pragma_token, + bool is_assert, struct pragma_simd_values *p_simd_values) { - cp_token *token = NULL; - tree vec_length_list = NULL_TREE, v_length_value = NULL_TREE; - - cilkplus_local_simd_values.pragma_encountered = true; - cilkplus_local_simd_values.types |= P_SIMD_VECTORLENGTH; + cp_token *token; - if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + if (is_assert) { - while (true) + if (p_simd_values->assert_requested == P_SIMD_NOASSERT) { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER)) - { - cp_parser_error (parser, "expected number"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - vec_length_list = NULL_TREE; - break; - } - else - { - token = cp_lexer_peek_token (parser->lexer); - if (token != NULL) - v_length_value = token->u.value; - cp_lexer_consume_token (parser->lexer); - vec_length_list = tree_cons (NULL_TREE, v_length_value, - vec_length_list); - } - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - break; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); + error_at (input_location, "assert and noassert cannot be used in the" + " same pragma"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; } + p_simd_values->assert_requested = P_SIMD_ASSERT; } - else - cp_parser_error (parser, "expected %<(%>"); - - cilkplus_local_simd_values.vectorlength = vec_length_list; - cilkplus_local_simd_values.pragma_encountered = true; - - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + else + { + if (p_simd_values->assert_requested == P_SIMD_ASSERT) + { + error_at (input_location, "assert and noassert cannot be used in the" + "same pragma"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + p_simd_values->assert_requested = P_SIMD_NOASSERT; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, - "ill-formed pragma: Same variable in multiple " - "clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function will parse the pragma simd private clause. */ +/* Parses the pragma simd linear clause in Cilk Plus language extension. + The syntax is: + #pragma simd linear (<variable>:[<steps], ... ) +*/ static void -cp_parser_simd_private (cp_parser *parser, cp_token *pragma_token) +cp_parser_simd_linear (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) { - cp_token *token = NULL; - tree private_var = NULL_TREE, private_var_list = NULL_TREE; - - cilkplus_local_simd_values.types |= P_SIMD_PRIVATE; - cilkplus_local_simd_values.pragma_encountered = true; + tree linear_var, linear_step; + cp_token *token; - if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) { - while (true) + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + + while (true) + { + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, "expected variable-name"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + vec_safe_truncate (p_simd_values->linear_var_list, 0); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + break; + } + linear_var = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); + vec_safe_push (p_simd_values->linear_var_list, linear_var); + + if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER)) { - cp_parser_error (parser, "expected variable"); + cp_parser_error (parser, "expected step-size"); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + vec_safe_truncate (p_simd_values->linear_var_list, 0); cp_parser_skip_to_pragma_eol (parser, pragma_token); - break; - } - else - { - token = cp_lexer_peek_token (parser->lexer); - if (token != NULL) - private_var = token->u.value; - else - { - cp_parser_error (parser, "expected variable"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - /* you exit here because this should NEVER happen. If it does - something very bad is going on */ - exit (-1); - } - cp_lexer_consume_token (parser->lexer); - private_var_list = tree_cons (NULL_TREE, private_var, - private_var_list); - } - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - break; + return; } - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); + linear_step = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); + } + else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + || cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + linear_step = integer_one_node; + else + { + cp_parser_error (parser, "expected %<:%> or %<,%> after variable-" + "name"); + vec_safe_truncate (p_simd_values->linear_steps_list, 0); + vec_safe_truncate (p_simd_values->linear_var_list, 0); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; } + vec_safe_push (p_simd_values->linear_steps_list, linear_step); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + break; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); } - else - cp_parser_error (parser, "expected %<(%>"); - cilkplus_local_simd_values.pragma_encountered = true; - cilkplus_local_simd_values.types |= P_SIMD_PRIVATE; - cilkplus_local_simd_values.private_vars = private_var_list; - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, "ill-formed pragma: Same variable in " - "multiple clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function will handle the pragma simd reduction clause. */ +/* Parses the private clause of simd pragma that is part of Cilk Plus language + extension. + The correct syntax is: + #pragma simd private (<variable> [, <variable]) +*/ static void -cp_parser_simd_reduction (cp_parser *parser, cp_token *pragma_token) +cp_parser_simd_private (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) { - cp_token *token = NULL; - tree var_list = NULL_TREE, vars = NULL_TREE; - enum tree_code op_code = PLUS_EXPR; + tree private_var; + cp_token *token; - if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) { - token = cp_lexer_peek_token (parser->lexer); - - switch (token->type) - { - case CPP_PLUS: - op_code = PLUS_EXPR; - break; - case CPP_MINUS: - op_code = MINUS_EXPR; - break; - case CPP_MULT: - op_code = MULT_EXPR; - break; - case CPP_AND: - op_code = BIT_AND_EXPR; - break; - case CPP_OR: - op_code = BIT_IOR_EXPR; - break; - case CPP_XOR: - op_code = BIT_XOR_EXPR; - break; - case CPP_OR_OR: - op_code = TRUTH_ORIF_EXPR; - break; - case CPP_AND_AND: - op_code = TRUTH_ANDIF_EXPR; - break; - default: - cp_parser_error (parser, "expected one of the following: " - "%<+%> %<-%> %<*%> %<&%> %<|%> %<^%> %<||%> %<&&%>"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - var_list = NULL_TREE; - vars = NULL_TREE; - return; - } - cp_lexer_consume_token (parser->lexer); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + vec_safe_truncate (p_simd_values->priv_var_list, 0); + return; + } - if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + while (true) + { + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) { - cp_parser_error (parser, "expected %<:%>"); + error_at (input_location, "expected variable-name"); cp_parser_skip_to_pragma_eol (parser, pragma_token); - var_list = NULL_TREE; - vars = NULL_TREE; - return; + vec_safe_truncate (p_simd_values->priv_var_list, 0); + break; } - + private_var = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); - - while (true) + vec_safe_push (p_simd_values->priv_var_list, private_var); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) - { - cp_parser_error (parser, "expected variable name"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - break; - } - token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (token != NULL) - vars = token->u.value; - else - { - cp_parser_error (parser, "expected variable name"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - exit (-1); - } - var_list = tree_cons (NULL_TREE, vars, var_list); - - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - break; - } - - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); + break; } + else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); } - else - cp_parser_error (parser, "expected %<(%>"); - - insert_reduction_values (&cilkplus_local_simd_values.reduction_vals, op_code, - var_list); - cilkplus_local_simd_values.types |= P_SIMD_REDUCTION; - cilkplus_local_simd_values.pragma_encountered = true; - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, - "ill-formed pragma: Same variable in multiple " - "clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function handles the linear clause of pragma simd of Cilk Plus. */ +/* Parses the vectorlength clause of SIMD pragmas that is part of Cilk Plus + language extension. + + The correct syntax is: + #pragma simd vectorlength (<INTEGER> [, <INTEGER]) +*/ static void -cp_parser_simd_linear (cp_parser *parser, cp_token *pragma_token) +cp_parser_simd_vectorlength (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) { - cp_token *token = NULL; - tree linear_var = NULL_TREE, linear_var_list = NULL_TREE; - tree linear_step = NULL_TREE, linear_steps_list = NULL_TREE; - cilkplus_local_simd_values.types |= P_SIMD_LINEAR; - cilkplus_local_simd_values.pragma_encountered = true; - if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) { - while (true) - { - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) - { - cp_parser_error (parser, "expected variable"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - linear_var_list = NULL_TREE; - linear_steps_list = NULL_TREE; - break; - } - token = cp_lexer_peek_token (parser->lexer); - if (token) - linear_var = token->u.value; + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + while (true) + { + tree vlength_value = cp_parser_expression (parser, false, false, NULL); + if (!TREE_TYPE (vlength_value) || !TREE_CONSTANT (vlength_value) + || !INTEGRAL_TYPE_P (TREE_TYPE (vlength_value))) + { + error_at (input_location, "vectorlength must be an integral" + " constant"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + vec_safe_truncate (p_simd_values->vec_length_list, 0); + break; + } + else + vec_safe_push (p_simd_values->vec_length_list, vlength_value); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { cp_lexer_consume_token (parser->lexer); - linear_var_list = tree_cons (NULL_TREE, linear_var, linear_var_list); - if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - { - cp_lexer_consume_token (parser->lexer); - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER)) - { - cp_parser_error (parser, "expected step-size"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - linear_var = NULL_TREE; - linear_var_list = NULL_TREE; - break; - } - else - { - token = cp_lexer_peek_token (parser->lexer); - if (token) - linear_step = token->u.value; - cp_lexer_consume_token (parser->lexer); - } - } - else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) - || cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - linear_step = integer_one_node; - else - { - cp_parser_error (parser, "expected : or , after variable name"); - cp_parser_skip_to_pragma_eol (parser, pragma_token); - return; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_lexer_consume_token (parser->lexer); - linear_steps_list = tree_cons (NULL_TREE, linear_step, - linear_steps_list); - break; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - { - cp_lexer_consume_token (parser->lexer); - linear_steps_list = tree_cons (NULL_TREE, linear_step, - linear_steps_list); - } + break; } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + break; } - else - { - cp_parser_error (parser, "expected %<(%>"); - return; - } - - gcc_assert (list_length (linear_steps_list) == - list_length (linear_var_list)); - - cilkplus_local_simd_values.linear_vars = linear_var_list; - cilkplus_local_simd_values.linear_var_size = list_length (linear_var_list); - cilkplus_local_simd_values.linear_steps = linear_steps_list; - cilkplus_local_simd_values.linear_steps_size = - list_length (linear_steps_list); - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { - token = cp_lexer_peek_token (parser->lexer); + cp_token *token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, "ill-formed pragma: Same variable in " - "multiple clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } -/* This function will parse the pragma simd assert clause. */ +/* Parses the reduction clause of SIMD pragma that is part of the Cilk Plus + language specification: + The correct syntax is: + #pragma simd reduction (<operator>:<variable> [, <variable>]) +*/ static void -cp_parser_simd_assert (cp_parser *parser, cp_token *pragma_token, - bool is_assert) +cp_parser_simd_reduction (cp_parser *parser, cp_token *pragma_token, + struct pragma_simd_values *p_simd_values) { - cp_token *token; + tree vars = NULL_TREE; + enum tree_code op_code = PLUS_EXPR; + struct reduction_node red_node; + + memset (&red_node, 0, sizeof (struct reduction_node)); - if ((cilkplus_local_simd_values.types == P_SIMD_ASSERT) && is_assert) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) { - cp_parser_error (parser, "multiple simd assert/noassert pragmas found"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); return; } - else + + switch (cp_lexer_peek_token (parser->lexer)->type) { - if (is_assert) - cilkplus_local_simd_values.types |= P_SIMD_ASSERT; - else - cilkplus_local_simd_values.types |= P_SIMD_NOASSERT; + case CPP_PLUS: + op_code = PLUS_EXPR; + break; + case CPP_MINUS: + op_code = MINUS_EXPR; + break; + case CPP_MULT: + op_code = MULT_EXPR; + break; + case CPP_AND: + op_code = BIT_AND_EXPR; + break; + case CPP_OR: + op_code = BIT_IOR_EXPR; + break; + case CPP_XOR: + op_code = BIT_XOR_EXPR; + break; + case CPP_OR_OR: + op_code = TRUTH_ORIF_EXPR; + break; + case CPP_AND_AND: + op_code = TRUTH_ANDIF_EXPR; + break; + default: + error_at (input_location, "pragma simd reduction operators must be one" + " of the following: " + "%<+%> %<-%> %<*%> %<&%> %<|%> %<^%> %<||%> %<&&%>"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; } - - cilkplus_local_simd_values.pragma_encountered = true; + cp_lexer_consume_token (parser->lexer); + red_node.reduction_type = op_code; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + { + cp_parser_error (parser, "expected %<:%>"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + return; + } + cp_lexer_consume_token (parser->lexer); - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)) + while (true) { - token = cp_lexer_peek_token (parser->lexer); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, "expected variable-name"); + cp_parser_skip_to_pragma_eol (parser, pragma_token); + break; + } + vars = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); + vec_safe_push (red_node.reduction_vars, vars); - if (strcmp (IDENTIFIER_POINTER (token->u.value), "linear") == 0) - cp_parser_simd_linear (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "private") == 0) - cp_parser_simd_private (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), - "vectorlength") == 0) - cp_parser_simd_vectorlength (parser, pragma_token); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "assert") == 0) - cp_parser_simd_assert (parser, pragma_token, true); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "noassert") == 0) - cp_parser_simd_assert (parser, pragma_token, false); - else if (strcmp (IDENTIFIER_POINTER (token->u.value), "reduction") == 0) - cp_parser_simd_reduction (parser, pragma_token); - else - cp_parser_error (parser, "Unknown identifier"); + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + vec_safe_push (p_simd_values->reduction_list, red_node); + break; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + } + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + + cp_parser_simd_handle_next_clause (parser, + IDENTIFIER_POINTER (token->u.value), + pragma_token, p_simd_values); } else { cp_parser_skip_to_pragma_eol (parser, pragma_token); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) - { - if (same_var_in_multiple_lists_p (&cilkplus_local_simd_values)) - cp_parser_error (parser, - "ill-formed pragma: Same variable in multiple " - "clause"); - cp_lexer_consume_token (parser->lexer); - cp_parser_for (parser, &cilkplus_local_simd_values); + { + if (!same_var_in_multiple_lists_p (p_simd_values)) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_for (parser, p_simd_values); + } } - else - cp_parser_error (parser, "for statement expected"); - } - return; + else + error_at (input_location, "for statement expression after pragma simd"); + } } @@ -30010,7 +29925,8 @@ cp_parser_cilk_for_init_statement (cp_parser *parser, tree *init) ARRAY_NOTATION_REF. If some error occurred it returns NULL_TREE. */ static tree -cp_parser_array_notation (cp_parser *parser, tree init_index, tree array_value) +cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, + tree array_value) { cp_token *token = NULL; tree start_index = NULL_TREE, length_index = NULL_TREE, stride = NULL_TREE; @@ -30026,7 +29942,15 @@ cp_parser_array_notation (cp_parser *parser, tree init_index, tree array_value) if (processing_template_decl) { array_type = TREE_TYPE (array_value); - type = TREE_TYPE (array_type); + if (array_type) + type = TREE_TYPE (array_type); + else if (TREE_CODE (array_value) == ARRAY_REF) + { + array_type = TREE_TYPE (TREE_OPERAND (array_value, 0)); + type = TREE_TYPE (array_type); + } + else + type = array_type; } else { @@ -30116,6 +30040,8 @@ cp_parser_array_notation (cp_parser *parser, tree init_index, tree array_value) value_tree = build_array_notation_ref (input_location, array_value, start_index, length_index, stride, type); + if (value_tree != error_mark_node) + SET_EXPR_LOCATION (value_tree, loc); return value_tree; } |