diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cb389d2..f56c901 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1217,7 +1217,8 @@ typedef struct cp_parser GTY(()) /* The scope in which names should be looked up. If NULL_TREE, then we look up names in the scope that is currently open in the source program. If non-NULL, this is either a TYPE or - NAMESPACE_DECL for the scope in which we should look. + NAMESPACE_DECL for the scope in which we should look. It can + also be ERROR_MARK, when we've parsed a bogus scope. This value is not cleared automatically after a name is looked up, so we must be careful to clear it before starting a new look @@ -1225,7 +1226,7 @@ typedef struct cp_parser GTY(()) will look up `Z' in the scope of `X', rather than the current scope.) Unfortunately, it is difficult to tell when name lookup is complete, because we sometimes peek at a token, look it up, - and then decide not to consume it. */ + and then decide not to consume it. */ tree scope; /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the @@ -2045,7 +2046,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id) if (TREE_CODE (decl) == TEMPLATE_DECL) error ("invalid use of template-name %qE without an argument list", decl); - else if (!parser->scope) + else if (!parser->scope || parser->scope == error_mark_node) { /* Issue an error message. */ error ("%qE does not name a type", id); @@ -2313,36 +2314,48 @@ cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser) static void cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser) { - unsigned nesting_depth = 0; + int nesting_depth = 0; - while (true) + while (nesting_depth >= 0) { - cp_token *token; - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* If we've run out of tokens, stop. */ + cp_token *token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_EOF) break; - /* If the next token is a `;', we have reached the end of the - statement. */ - if (token->type == CPP_SEMICOLON && !nesting_depth) + + switch (token->type) { - /* Consume the `;'. */ - cp_lexer_consume_token (parser->lexer); + case CPP_EOF: + /* If we've run out of tokens, stop. */ + nesting_depth = -1; + continue; + + case CPP_SEMICOLON: + /* Stop if this is an unnested ';'. */ + if (!nesting_depth) + nesting_depth = -1; + break; + + case CPP_CLOSE_BRACE: + /* Stop if this is an unnested '}', or closes the outermost + nesting level. */ + nesting_depth--; + if (!nesting_depth) + nesting_depth = -1; + break; + + case CPP_OPEN_BRACE: + /* Nest. */ + nesting_depth++; + break; + + default: break; } + /* Consume the token. */ - token = cp_lexer_consume_token (parser->lexer); - /* If the next token is a non-nested `}', then we have reached - the end of the current block. */ - if (token->type == CPP_CLOSE_BRACE - && (nesting_depth == 0 || --nesting_depth == 0)) - break; - /* If it the next token is a `{', then we are entering a new - block. Consume the entire block. */ - if (token->type == CPP_OPEN_BRACE) - ++nesting_depth; + cp_lexer_consume_token (parser->lexer); + } } @@ -3664,9 +3677,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, /* Parse a nested-name-specifier. See cp_parser_nested_name_specifier_opt for details. This function behaves identically, except that it will an issue an error if no - nested-name-specifier is present, and it will return - ERROR_MARK_NODE, rather than NULL_TREE, if no nested-name-specifier - is present. */ + nested-name-specifier is present. */ static tree cp_parser_nested_name_specifier (cp_parser *parser, @@ -3688,7 +3699,6 @@ cp_parser_nested_name_specifier (cp_parser *parser, { cp_parser_error (parser, "expected nested-name-specifier"); parser->scope = NULL_TREE; - return error_mark_node; } return scope; @@ -3973,7 +3983,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p) id = cp_parser_identifier (parser); /* Don't process id if nested name specifier is invalid. */ - if (scope == error_mark_node) + if (!scope || scope == error_mark_node) return error_mark_node; /* If we look up a template-id in a non-dependent qualifying scope, there's no need to create a dependent type. */ @@ -9871,12 +9881,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, /* Look for the nested-name-specifier. */ if (tag_type == typename_type) { - if (cp_parser_nested_name_specifier (parser, + if (!cp_parser_nested_name_specifier (parser, /*typename_keyword_p=*/true, /*check_dependency_p=*/true, /*type_p=*/true, - is_declaration) - == error_mark_node) + is_declaration)) return error_mark_node; } else |