diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 171 |
1 files changed, 92 insertions, 79 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 80a767ebe2d..09e19a23a5f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -77,6 +77,8 @@ typedef struct cp_token GTY (()) KEYWORD is RID_MAX) iff this name was looked up and found to be ambiguous. An error has already been reported. */ BOOL_BITFIELD ambiguous_p : 1; + /* The location at which this token was found. */ + location_t location; /* The value associated with this token, if any. */ union cp_token_value { /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */ @@ -84,8 +86,6 @@ typedef struct cp_token GTY (()) /* Use for all other tokens. */ tree GTY((tag ("0"))) value; } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u; - /* The location at which this token was found. */ - location_t location; } cp_token; /* We use a stack of token pointer for saving token sets. */ @@ -95,8 +95,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap); static cp_token eof_token = { - CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, { NULL }, - 0 + CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, 0, { NULL } }; /* The cp_lexer structure represents the C++ lexer. It is responsible @@ -310,8 +309,7 @@ cp_lexer_new_main (void) /* Subsequent preprocessor diagnostics should use compiler diagnostic functions to get the compiler source location. */ - cpp_get_options (parse_in)->client_diagnostic = true; - cpp_get_callbacks (parse_in)->error = cp_cpp_error; + done_lexing = true; gcc_assert (lexer->next_token->type != CPP_PURGED); return lexer; @@ -1616,7 +1614,7 @@ static tree cp_parser_delete_expression static tree cp_parser_cast_expression (cp_parser *, bool, bool, cp_id_kind *); static tree cp_parser_binary_expression - (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *); + (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *); static tree cp_parser_question_colon_clause (cp_parser *, tree); static tree cp_parser_assignment_expression @@ -4732,7 +4730,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } koenig_p = false; - if (idk == CP_ID_KIND_UNQUALIFIED) + if (idk == CP_ID_KIND_UNQUALIFIED + || idk == CP_ID_KIND_TEMPLATE_ID) { if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) { @@ -4823,9 +4822,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, koenig_p, tf_warning_or_error); - if (warn_disallowed_functions) - warn_if_disallowed_function_p (postfix_expression); - /* The POSTFIX_EXPRESSION is certainly no longer an id. */ idk = CP_ID_KIND_NONE; } @@ -6215,6 +6211,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, static tree cp_parser_binary_expression (cp_parser* parser, bool cast_p, + bool no_toplevel_fold_p, enum cp_parser_prec prec, cp_id_kind * pidk) { @@ -6297,6 +6294,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, goto get_rhs; pop: + lookahead_prec = new_prec; /* If the stack is not empty, we have parsed into LHS the right side (`4' in the example above) of an expression we had suspended. We can use the information on the stack to recover the LHS (`3') @@ -6321,8 +6319,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, pass the correct tree_code unless the unary expression was surrounded by parentheses. */ - lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type, - &overloaded_p, tf_warning_or_error); + if (no_toplevel_fold_p + && lookahead_prec <= prec + && sp == stack + && TREE_CODE_CLASS (tree_type) == tcc_comparison) + lhs = build2 (tree_type, boolean_type_node, lhs, rhs); + else + lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type, + &overloaded_p, tf_warning_or_error); lhs_type = tree_type; /* If the binary operator required the use of an overloaded operator, @@ -6408,7 +6412,8 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, else { /* Parse the binary expressions (logical-or-expression). */ - expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR, pidk); + expr = cp_parser_binary_expression (parser, cast_p, false, + PREC_NOT_OPERATOR, pidk); /* If the next token is a `?' then we're actually looking at a conditional-expression. */ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) @@ -10323,7 +10328,7 @@ cp_parser_template_name (cp_parser* parser, && !template_keyword_p && parser->scope && TYPE_P (parser->scope) && check_dependency_p - && dependent_type_p (parser->scope) + && dependent_scope_p (parser->scope) /* Do not do this for dtors (or ctors), since they never need the template keyword before their name. */ && !constructor_name_p (identifier, parser->scope)) @@ -10882,7 +10887,6 @@ cp_parser_explicit_specialization (cp_parser* parser) if (!begin_specialization ()) { end_specialization (); - cp_parser_skip_to_end_of_block_or_statement (parser); return; } @@ -11580,7 +11584,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, type = make_typename_type (parser->scope, decl, typename_type, /*complain=*/tf_error); - else + /* If the `typename' keyword is in effect and DECL is not a type + decl. Then type is non existant. */ + else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) + type = NULL_TREE; + else type = TREE_TYPE (decl); } @@ -13268,6 +13276,13 @@ cp_parser_direct_declarator (cp_parser* parser, &non_constant_p); if (!non_constant_p) bounds = fold_non_dependent_expr (bounds); + else if (processing_template_decl) + { + /* Remember this wasn't a constant-expression. */ + bounds = build_nop (TREE_TYPE (bounds), bounds); + TREE_SIDE_EFFECTS (bounds) = 1; + } + /* Normally, the array bound must be an integral constant expression. However, as an extension, we allow VLAs in function scopes. */ @@ -17023,35 +17038,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cannot look up the name if the scope is not a class type; it might, for example, be a template type parameter. */ dependent_p = (TYPE_P (parser->scope) - && !(parser->in_declarator_p - && currently_open_class (parser->scope)) - && dependent_type_p (parser->scope)); + && dependent_scope_p (parser->scope)); if ((check_dependency || !CLASS_TYPE_P (parser->scope)) - && dependent_p) - { - if (tag_type) - { - tree type; - - /* The resolution to Core Issue 180 says that `struct - A::B' should be considered a type-name, even if `A' - is dependent. */ - type = make_typename_type (parser->scope, name, tag_type, - /*complain=*/tf_error); - decl = TYPE_NAME (type); - } - else if (is_template - && (cp_parser_next_token_ends_template_argument_p (parser) - || cp_lexer_next_token_is (parser->lexer, - CPP_CLOSE_PAREN))) - decl = make_unbound_class_template (parser->scope, - name, NULL_TREE, - /*complain=*/tf_error); - else - decl = build_qualified_name (/*type=*/NULL_TREE, - parser->scope, name, - is_template); - } + && dependent_p) + /* Defer lookup. */ + decl = error_mark_node; else { tree pushed_scope = NULL_TREE; @@ -17072,14 +17063,42 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /*complain=*/true); /* If we have a single function from a using decl, pull it out. */ - if (decl - && TREE_CODE (decl) == OVERLOAD + if (TREE_CODE (decl) == OVERLOAD && !really_overloaded_fn (decl)) decl = OVL_FUNCTION (decl); if (pushed_scope) pop_scope (pushed_scope); } + + /* If the scope is a dependent type and either we deferred lookup or + we did lookup but didn't find the name, rememeber the name. */ + if (decl == error_mark_node && TYPE_P (parser->scope) + && dependent_type_p (parser->scope)) + { + if (tag_type) + { + tree type; + + /* The resolution to Core Issue 180 says that `struct + A::B' should be considered a type-name, even if `A' + is dependent. */ + type = make_typename_type (parser->scope, name, tag_type, + /*complain=*/tf_error); + decl = TYPE_NAME (type); + } + else if (is_template + && (cp_parser_next_token_ends_template_argument_p (parser) + || cp_lexer_next_token_is (parser->lexer, + CPP_CLOSE_PAREN))) + decl = make_unbound_class_template (parser->scope, + name, NULL_TREE, + /*complain=*/tf_error); + else + decl = build_qualified_name (/*type=*/NULL_TREE, + parser->scope, name, + is_template); + } parser->qualifying_scope = parser->scope; parser->object_scope = NULL_TREE; } @@ -18286,6 +18305,11 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) /* Parse the assignment-expression. */ parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); + if (parsed_arg == error_mark_node) + { + cp_parser_pop_lexer (parser); + continue; + } if (!processing_template_decl) parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg); @@ -21000,41 +21024,39 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok) static tree cp_parser_omp_for_cond (cp_parser *parser, tree decl) { - tree lhs = cp_parser_cast_expression (parser, false, false, NULL), rhs; - enum tree_code op; - cp_token *token; + tree cond = cp_parser_binary_expression (parser, false, true, + PREC_NOT_OPERATOR, NULL); + bool overloaded_p; - if (lhs != decl) + if (cond == error_mark_node + || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - token = cp_lexer_peek_token (parser->lexer); - op = binops_by_token [token->type].tree_type; - switch (op) + switch (TREE_CODE (cond)) { - case LT_EXPR: - case LE_EXPR: case GT_EXPR: case GE_EXPR: + case LT_EXPR: + case LE_EXPR: break; default: - cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_binary_expression (parser, false, - PREC_RELATIONAL_EXPRESSION, NULL); - if (rhs == error_mark_node - || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - cp_parser_skip_to_end_of_statement (parser); - return error_mark_node; - } + /* If decl is an iterator, preserve LHS and RHS of the relational + expr until finish_omp_for. */ + if (decl + && (type_dependent_expression_p (decl) + || CLASS_TYPE_P (TREE_TYPE (decl)))) + return cond; - return build2 (op, boolean_type_node, lhs, rhs); + return build_x_binary_op (TREE_CODE (cond), + TREE_OPERAND (cond, 0), ERROR_MARK, + TREE_OPERAND (cond, 1), ERROR_MARK, + &overloaded_p, tf_warning_or_error); } /* Helper function, to parse omp for increment expression. */ @@ -21083,7 +21105,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs); } - lhs = cp_parser_binary_expression (parser, false, + lhs = cp_parser_binary_expression (parser, false, false, PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); decl_first = lhs == decl; @@ -21097,7 +21119,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) { op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR; cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_binary_expression (parser, false, + rhs = cp_parser_binary_expression (parser, false, false, PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first) @@ -21406,16 +21428,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) cond = NULL; if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - /* If decl is an iterator, preserve LHS and RHS of the relational - expr until finish_omp_for. */ - if (decl - && (type_dependent_expression_p (decl) - || CLASS_TYPE_P (TREE_TYPE (decl)))) - cond = cp_parser_omp_for_cond (parser, decl); - else - cond = cp_parser_condition (parser); - } + cond = cp_parser_omp_for_cond (parser, decl); cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); incr = NULL; |