diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 178 |
1 files changed, 145 insertions, 33 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 38e0d5c5789..78f359a31ef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -237,7 +237,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 *); @@ -649,7 +649,11 @@ cp_lexer_new_main (void) gcc_assert (!lexer->next_token->purged_p); - array_notation_label_no = 0; + if (flag_enable_cilk) + { + array_notation_label_no = 0; + p_simd_nodes_clear (); + } return lexer; } @@ -1248,7 +1252,7 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs) VAR_DECLs or FUNCTION_DECLs) should do that directly. */ static cp_declarator *make_call_declarator - (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, tree, tree); + (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier, tree, tree); static cp_declarator *make_array_declarator (cp_declarator *, tree); static cp_declarator *make_pointer_declarator @@ -1427,6 +1431,7 @@ make_call_declarator (cp_declarator *target, tree parms, cp_cv_quals cv_qualifiers, cp_virt_specifiers virt_specifiers, + cp_ref_qualifier ref_qualifier, tree exception_specification, tree late_return_type) { @@ -1437,6 +1442,7 @@ make_call_declarator (cp_declarator *target, declarator->u.function.parameters = parms; declarator->u.function.qualifiers = cv_qualifiers; declarator->u.function.virt_specifiers = virt_specifiers; + declarator->u.function.ref_qualifier = ref_qualifier; declarator->u.function.exception_specification = exception_specification; declarator->u.function.late_return_type = late_return_type; if (target) @@ -1864,7 +1870,7 @@ static tree cp_parser_qualifying_entity static tree cp_parser_postfix_expression (cp_parser *, bool, bool, bool, bool, cp_id_kind *); static tree cp_parser_postfix_open_square_expression - (cp_parser *, tree, bool); + (cp_parser *, tree, bool, bool); static tree cp_parser_postfix_dot_deref_expression (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t); static vec<tree, va_gc> *cp_parser_parenthesized_expression_list @@ -2032,6 +2038,8 @@ static cp_cv_quals cp_parser_cv_qualifier_seq_opt (cp_parser *); static cp_virt_specifiers cp_parser_virt_specifier_seq_opt (cp_parser *); +static cp_ref_qualifier cp_parser_ref_qualifier_opt + (cp_parser *); static tree cp_parser_late_return_type_opt (cp_parser *, cp_cv_quals); static tree cp_parser_declarator_id @@ -3927,6 +3935,18 @@ cp_parser_translation_unit (cp_parser* parser) return success; } +/* Return the appropriate tsubst flags for parsing, possibly in N3276 + decltype context. */ + +static inline tsubst_flags_t +complain_flags (bool decltype_p) +{ + tsubst_flags_t complain = tf_warning_or_error; + if (decltype_p) + complain |= tf_decltype; + return complain; +} + /* Expressions [gram.expr] */ /* Parse a primary-expression. @@ -5820,7 +5840,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, postfix_expression = cp_parser_postfix_open_square_expression (parser, postfix_expression, - false); + false, + decltype_p); idk = CP_ID_KIND_NONE; is_member_access = false; break; @@ -5832,12 +5853,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, bool is_builtin_constant_p; bool saved_integral_constant_expression_p = false; bool saved_non_integral_constant_expression_p = false; - int complain = tf_warning_or_error; + tsubst_flags_t complain = complain_flags (decltype_p); vec<tree, va_gc> *args; - if (decltype_p) - complain |= tf_decltype; - is_member_access = false; is_builtin_constant_p @@ -6097,7 +6115,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, static tree cp_parser_postfix_open_square_expression (cp_parser *parser, tree postfix_expression, - bool for_offsetof) + bool for_offsetof, + bool decltype_p) { tree index; location_t loc = cp_lexer_peek_token (parser->lexer)->location; @@ -6110,7 +6129,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 { @@ -6149,7 +6168,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 { @@ -6157,7 +6176,8 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); /* Build the ARRAY_REF. */ - postfix_expression = grok_array_decl (loc, postfix_expression, index); + postfix_expression = grok_array_decl (loc, postfix_expression, + index, decltype_p); /* When not doing offsetof, array references are not permitted in constant-expressions. */ @@ -6861,6 +6881,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, tree expression = error_mark_node; non_integral_constant non_constant_p = NIC_NONE; location_t loc = token->location; + tsubst_flags_t complain = complain_flags (decltype_p); /* Consume the operator token. */ token = cp_lexer_consume_token (parser->lexer); @@ -6878,7 +6899,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, non_constant_p = NIC_STAR; expression = build_x_indirect_ref (loc, cast_expression, RO_UNARY_STAR, - tf_warning_or_error); + complain); break; case ADDR_EXPR: @@ -6887,7 +6908,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, case BIT_NOT_EXPR: expression = build_x_unary_op (loc, unary_operator, cast_expression, - tf_warning_or_error); + complain); break; case PREINCREMENT_EXPR: @@ -6899,7 +6920,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, case NEGATE_EXPR: case TRUTH_NOT_EXPR: expression = finish_unary_op_expr (loc, unary_operator, - cast_expression); + cast_expression, complain); break; default: @@ -7727,7 +7748,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, current.lhs = build_x_binary_op (current.loc, current.tree_type, current.lhs, current.lhs_type, rhs, rhs_type, &overload, - tf_warning_or_error); + complain_flags (decltype_p)); current.lhs_type = current.tree_type; if (EXPR_P (current.lhs)) SET_EXPR_LOCATION (current.lhs, current.loc); @@ -7882,7 +7903,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, expr = build_x_modify_expr (loc, expr, assignment_operator, rhs, - tf_warning_or_error); + complain_flags (decltype_p)); input_location = saved_input_location; } } @@ -8028,7 +8049,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p, bool decltype_p, else expression = build_x_compound_expr (loc, expression, assignment_expression, - tf_warning_or_error); + complain_flags (decltype_p)); /* If the next token is not a comma, then we are done with the expression. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) @@ -8179,12 +8200,14 @@ cp_parser_builtin_offsetof (cp_parser *parser) { case CPP_OPEN_SQUARE: /* offsetof-member-designator "[" expression "]" */ - expr = cp_parser_postfix_open_square_expression (parser, expr, true); + expr = cp_parser_postfix_open_square_expression (parser, expr, + true, false); break; case CPP_DEREF: /* offsetof-member-designator "->" identifier */ - expr = grok_array_decl (token->location, expr, integer_zero_node); + expr = grok_array_decl (token->location, expr, + integer_zero_node, false); /* FALLTHRU */ case CPP_DOT: @@ -8804,6 +8827,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST); declarator = make_call_declarator (declarator, param_list, quals, VIRT_SPEC_UNSPECIFIED, + REF_QUAL_NONE, exception_spec, /*late_return_type=*/NULL_TREE); declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr); @@ -9826,7 +9850,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl) range_expr = error_mark_node; stmt = begin_range_for_stmt (scope, init); finish_range_for_decl (stmt, range_decl, range_expr); - if (!type_dependent_expression_p (range_expr) + if (range_expr != error_mark_node + && !type_dependent_expression_p (range_expr) + /* The length of an array might be dependent. */ + && COMPLETE_TYPE_P (TREE_TYPE (range_expr)) /* do_auto_deduction doesn't mess with template init-lists. */ && !BRACE_ENCLOSED_INITIALIZER_P (range_expr)) do_range_for_auto_deduction (range_decl, range_expr); @@ -9974,7 +10001,8 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr) /* The new increment expression. */ expression = finish_unary_op_expr (input_location, - PREINCREMENT_EXPR, begin); + PREINCREMENT_EXPR, begin, + tf_warning_or_error); finish_for_expr (expression, statement); /* The declaration is initialized with *__begin inside the loop body. */ @@ -14998,6 +15026,9 @@ cp_parser_enum_specifier (cp_parser* parser) { identifier = make_anon_name (); is_anonymous = true; + if (scoped_enum_p) + error_at (type_start_token->location, + "anonymous scoped enum is not allowed"); } } pop_deferring_access_checks (); @@ -15145,7 +15176,13 @@ cp_parser_enum_specifier (cp_parser* parser) if (type == error_mark_node) cp_parser_skip_to_end_of_block_or_statement (parser); /* If the next token is not '}', then there are some enumerators. */ - else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE)) + else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE)) + { + if (is_anonymous && !scoped_enum_p) + pedwarn (type_start_token->location, OPT_Wpedantic, + "ISO C++ forbids empty anonymous enum"); + } + else cp_parser_enumerator_list (parser, type); /* Consume the final '}'. */ @@ -16938,6 +16975,7 @@ cp_parser_declarator (cp_parser* parser, declarator-id direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq [opt] + ref-qualifier [opt] exception-specification [opt] direct-declarator [ constant-expression [opt] ] ( declarator ) @@ -16946,6 +16984,7 @@ cp_parser_declarator (cp_parser* parser, direct-abstract-declarator [opt] ( parameter-declaration-clause ) cv-qualifier-seq [opt] + ref-qualifier [opt] exception-specification [opt] direct-abstract-declarator [opt] [ constant-expression [opt] ] ( abstract-declarator ) @@ -17060,12 +17099,13 @@ cp_parser_direct_declarator (cp_parser* parser, /* Consume the `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - /* If all went well, parse the cv-qualifier-seq and the - exception-specification. */ + /* If all went well, parse the cv-qualifier-seq, + ref-qualifier and the exception-specification. */ if (member_p || cp_parser_parse_definitely (parser)) { cp_cv_quals cv_quals; cp_virt_specifiers virt_specifiers; + cp_ref_qualifier ref_qual; tree exception_specification; tree late_return; tree attrs; @@ -17080,6 +17120,8 @@ cp_parser_direct_declarator (cp_parser* parser, /* Parse the cv-qualifier-seq. */ cv_quals = cp_parser_cv_qualifier_seq_opt (parser); + /* Parse the ref-qualifier. */ + ref_qual = cp_parser_ref_qualifier_opt (parser); /* And the exception-specification. */ exception_specification = cp_parser_exception_specification_opt (parser); @@ -17097,6 +17139,7 @@ cp_parser_direct_declarator (cp_parser* parser, params, cv_quals, virt_specifiers, + ref_qual, exception_specification, late_return); declarator->std_attributes = attrs; @@ -17660,6 +17703,59 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) return cv_quals; } +/* Parse an (optional) ref-qualifier + + ref-qualifier: + & + && + + Returns cp_ref_qualifier representing ref-qualifier. */ + +static cp_ref_qualifier +cp_parser_ref_qualifier_opt (cp_parser* parser) +{ + cp_ref_qualifier ref_qual = REF_QUAL_NONE; + + while (true) + { + cp_ref_qualifier curr_ref_qual = REF_QUAL_NONE; + cp_token *token = cp_lexer_peek_token (parser->lexer); + + switch (token->type) + { + case CPP_AND: + curr_ref_qual = REF_QUAL_LVALUE; + break; + + case CPP_AND_AND: + curr_ref_qual = REF_QUAL_RVALUE; + break; + + default: + curr_ref_qual = REF_QUAL_NONE; + break; + } + + if (!curr_ref_qual) + break; + else if (ref_qual) + { + error_at (token->location, "multiple ref-qualifiers"); + cp_lexer_purge_token (parser->lexer); + } + else + { + ref_qual = curr_ref_qual; + cp_lexer_consume_token (parser->lexer); + } + } + + if (ref_qual) + maybe_warn_cpp0x (CPP0X_REF_QUALIFIER); + + return ref_qual; +} + /* Parse an (optional) virt-specifier-seq. virt-specifier-seq: @@ -21506,8 +21602,13 @@ cp_parser_std_attribute (cp_parser *parser) token = cp_lexer_peek_token (parser->lexer); } else - attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id), - NULL_TREE); + { + attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id), + NULL_TREE); + /* C++11 noreturn attribute is equivalent to GNU's. */ + if (is_attribute_p ("noreturn", attr_id)) + TREE_PURPOSE (TREE_PURPOSE (attribute)) = get_identifier ("gnu"); + } /* Now parse the optional argument clause of the attribute. */ @@ -29672,7 +29773,7 @@ cp_parser_simd_private (cp_parser *parser, cp_token *pragma_token, { if (!same_var_in_multiple_lists_p (p_simd_values)) { - cp_lexer_peek_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); cp_parser_for (parser, p_simd_values); } } @@ -29736,7 +29837,7 @@ cp_parser_simd_vectorlength (cp_parser *parser, cp_token *pragma_token, { if (!same_var_in_multiple_lists_p (p_simd_values)) { - cp_lexer_peek_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); cp_parser_for (parser, p_simd_values); } } @@ -29848,7 +29949,7 @@ cp_parser_simd_reduction (cp_parser *parser, cp_token *pragma_token, { if (!same_var_in_multiple_lists_p (p_simd_values)) { - cp_lexer_peek_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); cp_parser_for (parser, p_simd_values); } } @@ -29979,7 +30080,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; @@ -29995,7 +30097,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 { @@ -30085,6 +30195,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; } |