diff options
author | David Malcolm <dmalcolm@redhat.com> | 2017-08-10 13:22:27 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2017-08-10 13:22:27 +0000 |
commit | 32129a17506ba18a34d07145eb2c1e9f9827034f (patch) | |
tree | f8018f92c534466fa12d6791f1df3d201d24df10 /gcc/c | |
parent | 7c23ac0d25d2d5f814f53a6357d4c572e48f06d3 (diff) | |
download | gcc-32129a17506ba18a34d07145eb2c1e9f9827034f.zip gcc-32129a17506ba18a34d07145eb2c1e9f9827034f.tar.gz gcc-32129a17506ba18a34d07145eb2c1e9f9827034f.tar.bz2 |
C/C++: show pertinent open token when missing a close token
gcc/c/ChangeLog:
* c-parser.c (c_parser_error): Rename to...
(c_parser_error_richloc): ...this, making static, and adding
"richloc" parameter, passing it to the c_parse_error call,
rather than calling c_parser_set_source_position_from_token.
(c_parser_error): Reintroduce, reimplementing in terms of the
above, converting return type from void to bool.
(class token_pair): New class.
(struct matching_paren_traits): New struct.
(matching_parens): New typedef.
(struct matching_brace_traits): New struct.
(matching_braces): New typedef.
(get_matching_symbol): New function.
(c_parser_require): Add param MATCHING_LOCATION, using it to
highlight matching "opening" tokens for missing "closing" tokens.
(c_parser_skip_until_found): Likewise.
(c_parser_static_assert_declaration_no_semi): Convert explicit
parsing of CPP_OPEN_PAREN and CPP_CLOSE_PAREN to use of
class matching_parens, so that the pertinent open parenthesis is
highlighted when there are problems locating the close
parenthesis.
(c_parser_struct_or_union_specifier): Likewise.
(c_parser_typeof_specifier): Likewise.
(c_parser_alignas_specifier): Likewise.
(c_parser_simple_asm_expr): Likewise.
(c_parser_braced_init): Likewise, for matching_braces.
(c_parser_paren_condition): Likewise, for matching_parens.
(c_parser_switch_statement): Likewise.
(c_parser_for_statement): Likewise.
(c_parser_asm_statement): Likewise.
(c_parser_asm_operands): Likewise.
(c_parser_cast_expression): Likewise.
(c_parser_sizeof_expression): Likewise.
(c_parser_alignof_expression): Likewise.
(c_parser_generic_selection): Likewise.
(c_parser_postfix_expression): Likewise for cases RID_VA_ARG,
RID_OFFSETOF, RID_TYPES_COMPATIBLE_P, RID_AT_SELECTOR,
RID_AT_PROTOCOL, RID_AT_ENCODE, reindenting as necessary.
In case CPP_OPEN_PAREN, pass loc_open_paren to the
c_parser_skip_until_found call.
(c_parser_objc_class_definition): Use class matching_parens as
above.
(c_parser_objc_method_decl): Likewise.
(c_parser_objc_try_catch_finally_statement): Likewise.
(c_parser_objc_synchronized_statement): Likewise.
(c_parser_objc_at_property_declaration): Likewise.
(c_parser_oacc_wait_list): Likewise.
(c_parser_omp_var_list_parens): Likewise.
(c_parser_omp_clause_collapse): Likewise.
(c_parser_omp_clause_default): Likewise.
(c_parser_omp_clause_if): Likewise.
(c_parser_omp_clause_num_threads): Likewise.
(c_parser_omp_clause_num_tasks): Likewise.
(c_parser_omp_clause_grainsize): Likewise.
(c_parser_omp_clause_priority): Likewise.
(c_parser_omp_clause_hint): Likewise.
(c_parser_omp_clause_defaultmap): Likewise.
(c_parser_oacc_single_int_clause): Likewise.
(c_parser_omp_clause_ordered): Likewise.
(c_parser_omp_clause_reduction): Likewise.
(c_parser_omp_clause_schedule): Likewise.
(c_parser_omp_clause_num_teams): Likewise.
(c_parser_omp_clause_thread_limit): Likewise.
(c_parser_omp_clause_aligned): Likewise.
(c_parser_omp_clause_linear): Likewise.
(c_parser_omp_clause_safelen): Likewise.
(c_parser_omp_clause_simdlen): Likewise.
(c_parser_omp_clause_depend): Likewise.
(c_parser_omp_clause_map): Likewise.
(c_parser_omp_clause_device): Likewise.
(c_parser_omp_clause_dist_schedule): Likewise.
(c_parser_omp_clause_proc_bind): Likewise.
(c_parser_omp_clause_uniform): Likewise.
(c_parser_omp_for_loop): Likewise.
(c_parser_cilk_clause_vectorlength): Likewise.
(c_parser_cilk_clause_linear): Likewise.
(c_parser_transaction_expression): Likewise.
* c-parser.h (c_parser_require): Add param matching_location with
default UNKNOWN_LOCATION.
(c_parser_error): Convert return type from void to bool.
(c_parser_skip_until_found): Add param matching_location with
default UNKNOWN_LOCATION.
gcc/c-family/ChangeLog:
* c-common.c (c_parse_error): Add rich_location * param, using it
rather implicitly using input_location.
* c-common.h (c_parse_error): Add rich_location * param.
gcc/cp/ChangeLog:
* parser.c (cp_parser_error): Update for new param to
c_parse_error.
(class token_pair): New class.
(struct matching_paren_traits): New struct.
(matching_parens): New typedef.
(struct matching_brace_traits): New struct.
(matching_braces): New typedef.
(cp_parser_statement_expr): Convert explicit parsing of
CPP_OPEN_PAREN and CPP_CLOSE_PAREN to use of
class matching_parens, so that the pertinent open parenthesis is
highlighted when there are problems locating the close
parenthesis.
(cp_parser_primary_expression): Likewise.
(cp_parser_compound_literal_p): Remove consumption of opening
paren.
(cp_parser_postfix_expression): Convert explicit parsing of
CPP_OPEN_PAREN and CPP_CLOSE_PAREN to use matching parens, as
above. Use it to consume the opening paren previously consumed by
cp_parser_compound_literal_p.
(cp_parser_parenthesized_expression_list): Likewise.
(cp_parser_unary_expression): Likewise.
(cp_parser_new_expression): Likewise.
(cp_parser_cast_expression): Likewise.
(cp_parser_builtin_offsetof): Likewise.
(cp_parser_trait_expr): Likewise.
(cp_parser_lambda_declarator_opt): Likewise.
(cp_parser_lambda_body): Likewise, for matching_braces.
(cp_parser_compound_statement): Likewise.
(cp_parser_selection_statement): Likewise, for matching_parens.
(cp_parser_iteration_statement): Likewise.
(cp_parser_already_scoped_statement): Likewise, for
matching_braces.
(cp_parser_linkage_specification): Likewise.
(cp_parser_static_assert): Likewise, for matching_parens.
(cp_parser_decltype): Likewise.
(cp_parser_operator): Likewise.
(cp_parser_enum_specifier): Likewise.
(cp_parser_namespace_definition): Likewise.
(cp_parser_direct_declarator): Likewise.
(cp_parser_braced_list): Likewise.
(cp_parser_class_specifier_1): Likewise, for matching_braces.
(cp_parser_constant_initializer): Likewise.
(cp_parser_noexcept_specification_opt): Likewise, for
matching_parens.
(cp_parser_exception_specification_opt): Likewise.
(cp_parser_handler): Likewise.
(cp_parser_asm_specification_opt): Likewise.
(cp_parser_asm_operand_list): Likewise.
(cp_parser_gnu_attributes_opt): Likewise.
(cp_parser_std_attribute_spec): Likewise.
(cp_parser_requirement_parameter_list): Likewise.
(cp_parser_requirement_body): Likewise, for matching_braces.
(cp_parser_compound_requirement): Likewise.
(cp_parser_template_introduction): Likewise.
(cp_parser_sizeof_pack): Likewise, for matching_parens.
(cp_parser_sizeof_operand): Likewise; use it to consume the
opening paren previously consumed by cp_parser_compound_literal_p.
(get_matching_symbol): New function.
(cp_parser_required_error): Add param "matching_location". Remove
calls to cp_parser_error, instead setting a non-NULL gmsgid, and
handling it if set by calling c_parse_error, potentially with a
secondary location if matching_location was set.
(cp_parser_require): Add param "matching_location", with a default
value of UNKNOWN_LOCATION.
(cp_parser_require_keyword): Update for new param of
cp_parser_required_error.
(cp_parser_objc_encode_expression): Update to class matching_parens
as above.
(cp_parser_objc_defs_expression): Likewise.
(cp_parser_objc_protocol_expression): Likewise.
(cp_parser_objc_selector_expression): Likewise.
(cp_parser_objc_typename): Likewise.
(cp_parser_objc_superclass_or_category): Likewise.
(cp_parser_objc_try_catch_finally_statement): Likewise.
(cp_parser_objc_synchronized_statement): Likewise.
(cp_parser_objc_at_property_declaration): Likewise.
(cp_parser_oacc_single_int_clause): Likewise.
(cp_parser_oacc_shape_clause): Likewise.
(cp_parser_omp_clause_collapse): Likewise.
(cp_parser_omp_clause_default): Likewise.
(cp_parser_omp_clause_final): Likewise.
(cp_parser_omp_clause_if): Likewise.
(cp_parser_omp_clause_num_threads): Likewise.
(cp_parser_omp_clause_num_tasks): Likewise.
(cp_parser_omp_clause_grainsize): Likewise.
(cp_parser_omp_clause_priority): Likewise.
(cp_parser_omp_clause_hint): Likewise.
(cp_parser_omp_clause_defaultmap): Likewise.
(cp_parser_omp_clause_ordered): Likewise.
(cp_parser_omp_clause_schedule): Likewise.
(cp_parser_omp_clause_num_teams): Likewise.
(cp_parser_omp_clause_thread_limit): Likewise.
(cp_parser_omp_clause_aligned): Likewise.
(cp_parser_omp_clause_linear): Likewise.
(cp_parser_omp_clause_safelen): Likewise.
(cp_parser_omp_clause_simdlen): Likewise.
(cp_parser_omp_clause_depend): Likewise.
(cp_parser_omp_clause_device): Likewise.
(cp_parser_omp_clause_dist_schedule): Likewise.
(cp_parser_oacc_clause_async): Likewise.
(cp_parser_omp_critical): Likewise.
(cp_parser_omp_for_loop): Likewise.
(cp_parser_omp_sections_scope): Likewise.
(cp_parser_omp_declare_reduction_exprs): Likewise.
Update for new param to cp_parser_required_error.
(cp_parser_oacc_routine): Likewise.
(cp_parser_transaction_expression): Likewise.
(cp_parser_cilk_simd_vectorlength): Likewise.
gcc/testsuite/ChangeLog:
* c-c++-common/missing-close-symbol.c: New test case.
* c-c++-common/missing-symbol.c: New test case.
* gcc.dg/unclosed-init.c: New test case.
* g++.dg/diagnostic/unclosed-extern-c.C: New test case.
* g++.dg/diagnostic/unclosed-function.C: New test case.
* g++.dg/diagnostic/unclosed-namespace.C: New test case.
* g++.dg/diagnostic/unclosed-struct.C: New test case.
* g++.dg/parse/pragma2.C: Update to reflect movement of the
"expected identifier" error.
From-SVN: r251026
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 84 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 644 | ||||
-rw-r--r-- | gcc/c/c-parser.h | 8 |
3 files changed, 519 insertions, 217 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index a7cc746..6e29334 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,87 @@ +2017-08-10 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_error): Rename to... + (c_parser_error_richloc): ...this, making static, and adding + "richloc" parameter, passing it to the c_parse_error call, + rather than calling c_parser_set_source_position_from_token. + (c_parser_error): Reintroduce, reimplementing in terms of the + above, converting return type from void to bool. + (class token_pair): New class. + (struct matching_paren_traits): New struct. + (matching_parens): New typedef. + (struct matching_brace_traits): New struct. + (matching_braces): New typedef. + (get_matching_symbol): New function. + (c_parser_require): Add param MATCHING_LOCATION, using it to + highlight matching "opening" tokens for missing "closing" tokens. + (c_parser_skip_until_found): Likewise. + (c_parser_static_assert_declaration_no_semi): Convert explicit + parsing of CPP_OPEN_PAREN and CPP_CLOSE_PAREN to use of + class matching_parens, so that the pertinent open parenthesis is + highlighted when there are problems locating the close + parenthesis. + (c_parser_struct_or_union_specifier): Likewise. + (c_parser_typeof_specifier): Likewise. + (c_parser_alignas_specifier): Likewise. + (c_parser_simple_asm_expr): Likewise. + (c_parser_braced_init): Likewise, for matching_braces. + (c_parser_paren_condition): Likewise, for matching_parens. + (c_parser_switch_statement): Likewise. + (c_parser_for_statement): Likewise. + (c_parser_asm_statement): Likewise. + (c_parser_asm_operands): Likewise. + (c_parser_cast_expression): Likewise. + (c_parser_sizeof_expression): Likewise. + (c_parser_alignof_expression): Likewise. + (c_parser_generic_selection): Likewise. + (c_parser_postfix_expression): Likewise for cases RID_VA_ARG, + RID_OFFSETOF, RID_TYPES_COMPATIBLE_P, RID_AT_SELECTOR, + RID_AT_PROTOCOL, RID_AT_ENCODE, reindenting as necessary. + In case CPP_OPEN_PAREN, pass loc_open_paren to the + c_parser_skip_until_found call. + (c_parser_objc_class_definition): Use class matching_parens as + above. + (c_parser_objc_method_decl): Likewise. + (c_parser_objc_try_catch_finally_statement): Likewise. + (c_parser_objc_synchronized_statement): Likewise. + (c_parser_objc_at_property_declaration): Likewise. + (c_parser_oacc_wait_list): Likewise. + (c_parser_omp_var_list_parens): Likewise. + (c_parser_omp_clause_collapse): Likewise. + (c_parser_omp_clause_default): Likewise. + (c_parser_omp_clause_if): Likewise. + (c_parser_omp_clause_num_threads): Likewise. + (c_parser_omp_clause_num_tasks): Likewise. + (c_parser_omp_clause_grainsize): Likewise. + (c_parser_omp_clause_priority): Likewise. + (c_parser_omp_clause_hint): Likewise. + (c_parser_omp_clause_defaultmap): Likewise. + (c_parser_oacc_single_int_clause): Likewise. + (c_parser_omp_clause_ordered): Likewise. + (c_parser_omp_clause_reduction): Likewise. + (c_parser_omp_clause_schedule): Likewise. + (c_parser_omp_clause_num_teams): Likewise. + (c_parser_omp_clause_thread_limit): Likewise. + (c_parser_omp_clause_aligned): Likewise. + (c_parser_omp_clause_linear): Likewise. + (c_parser_omp_clause_safelen): Likewise. + (c_parser_omp_clause_simdlen): Likewise. + (c_parser_omp_clause_depend): Likewise. + (c_parser_omp_clause_map): Likewise. + (c_parser_omp_clause_device): Likewise. + (c_parser_omp_clause_dist_schedule): Likewise. + (c_parser_omp_clause_proc_bind): Likewise. + (c_parser_omp_clause_uniform): Likewise. + (c_parser_omp_for_loop): Likewise. + (c_parser_cilk_clause_vectorlength): Likewise. + (c_parser_cilk_clause_linear): Likewise. + (c_parser_transaction_expression): Likewise. + * c-parser.h (c_parser_require): Add param matching_location with + default UNKNOWN_LOCATION. + (c_parser_error): Convert return type from void to bool. + (c_parser_skip_until_found): Add param matching_location with + default UNKNOWN_LOCATION. + 2017-08-09 Marek Polacek <polacek@redhat.com> * c-decl.c (build_enumerator): Use true/false instead of 1/0. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 6d40a97..1402ba6 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -850,21 +850,26 @@ c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind, MESSAGE (specified by the caller) is usually of the form "expected OTHER-TOKEN". + Use RICHLOC as the location of the diagnostic. + Do not issue a diagnostic if still recovering from an error. + Return true iff an error was actually emitted. + ??? This is taken from the C++ parser, but building up messages in this way is not i18n-friendly and some other approach should be used. */ -void -c_parser_error (c_parser *parser, const char *gmsgid) +static bool +c_parser_error_richloc (c_parser *parser, const char *gmsgid, + rich_location *richloc) { c_token *token = c_parser_peek_token (parser); if (parser->error) - return; + return false; parser->error = true; if (!gmsgid) - return; + return false; /* If this is actually a conflict marker, report it as such. */ if (token->type == CPP_LSHIFT @@ -875,13 +880,10 @@ c_parser_error (c_parser *parser, const char *gmsgid) if (c_parser_peek_conflict_marker (parser, token->type, &loc)) { error_at (loc, "version control conflict marker in file"); - return; + return true; } } - /* This diagnostic makes more sense if it is tagged to the line of - the token we just peeked at. */ - c_parser_set_source_position_from_token (token); c_parse_error (gmsgid, /* Because c_parse_error does not understand CPP_KEYWORD, keywords are treated like @@ -891,18 +893,157 @@ c_parser_error (c_parser *parser, const char *gmsgid) token, we need to pass 0 here and we will not get the source spelling of some tokens but rather the canonical spelling. */ - token->value, /*flags=*/0); + token->value, /*flags=*/0, richloc); + return true; +} + +/* As c_parser_error_richloc, but issue the message at the + location of PARSER's next token, or at input_location + if the next token is EOF. */ + +bool +c_parser_error (c_parser *parser, const char *gmsgid) +{ + c_token *token = c_parser_peek_token (parser); + c_parser_set_source_position_from_token (token); + rich_location richloc (line_table, input_location); + return c_parser_error_richloc (parser, gmsgid, &richloc); +} + +/* Some tokens naturally come in pairs e.g.'(' and ')'. + This class is for tracking such a matching pair of symbols. + In particular, it tracks the location of the first token, + so that if the second token is missing, we can highlight the + location of the first token when notifying the user about the + problem. */ + +template <typename traits_t> +class token_pair +{ + public: + /* token_pair's ctor. */ + token_pair () : m_open_loc (UNKNOWN_LOCATION) {} + + /* If the next token is the opening symbol for this pair, consume it and + return true. + Otherwise, issue an error and return false. + In either case, record the location of the opening token. */ + + bool require_open (c_parser *parser) + { + c_token *token = c_parser_peek_token (parser); + if (token) + m_open_loc = token->location; + + return c_parser_require (parser, traits_t::open_token_type, + traits_t::open_gmsgid); + } + + /* Consume the next token from PARSER, recording its location as + that of the opening token within the pair. */ + + void consume_open (c_parser *parser) + { + c_token *token = c_parser_peek_token (parser); + gcc_assert (token->type == traits_t::open_token_type); + m_open_loc = token->location; + c_parser_consume_token (parser); + } + + /* If the next token is the closing symbol for this pair, consume it + and return true. + Otherwise, issue an error, highlighting the location of the + corresponding opening token, and return false. */ + + bool require_close (c_parser *parser) const + { + return c_parser_require (parser, traits_t::close_token_type, + traits_t::close_gmsgid, m_open_loc); + } + + /* Like token_pair::require_close, except that tokens will be skipped + until the desired token is found. An error message is still produced + if the next token is not as expected. */ + + void skip_until_found_close (c_parser *parser) const + { + c_parser_skip_until_found (parser, traits_t::close_token_type, + traits_t::close_gmsgid, m_open_loc); + } + + private: + location_t m_open_loc; +}; + +/* Traits for token_pair<T> for tracking matching pairs of parentheses. */ + +struct matching_paren_traits +{ + static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN; + static const char * const open_gmsgid; + static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN; + static const char * const close_gmsgid; +}; + +const char * const matching_paren_traits::open_gmsgid = "expected %<(%>"; +const char * const matching_paren_traits::close_gmsgid = "expected %<)%>"; + +/* "matching_parens" is a token_pair<T> class for tracking matching + pairs of parentheses. */ + +typedef token_pair<matching_paren_traits> matching_parens; + +/* Traits for token_pair<T> for tracking matching pairs of braces. */ + +struct matching_brace_traits +{ + static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE; + static const char * const open_gmsgid; + static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE; + static const char * const close_gmsgid; +}; + +const char * const matching_brace_traits::open_gmsgid = "expected %<{%>"; +const char * const matching_brace_traits::close_gmsgid = "expected %<}%>"; + +/* "matching_braces" is a token_pair<T> class for tracking matching + pairs of braces. */ + +typedef token_pair<matching_brace_traits> matching_braces; + +/* Get a description of the matching symbol to TYPE e.g. "(" for + CPP_CLOSE_PAREN. */ + +static const char * +get_matching_symbol (enum cpp_ttype type) +{ + switch (type) + { + default: + gcc_unreachable (); + return ""; + case CPP_CLOSE_PAREN: + return "("; + case CPP_CLOSE_BRACE: + return "{"; + } } /* If the next token is of the indicated TYPE, consume it. Otherwise, issue the error MSGID. If MSGID is NULL then a message has already been produced and no message will be produced this time. Returns - true if found, false otherwise. */ + true if found, false otherwise. + + If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it + within any error as the location of an "opening" token matching + the close token TYPE (e.g. the location of the '(' when TYPE is + CPP_CLOSE_PAREN). */ bool c_parser_require (c_parser *parser, enum cpp_ttype type, - const char *msgid) + const char *msgid, + location_t matching_location) { if (c_parser_next_token_is (parser, type)) { @@ -911,7 +1052,24 @@ c_parser_require (c_parser *parser, } else { - c_parser_error (parser, msgid); + location_t next_token_loc = c_parser_peek_token (parser)->location; + gcc_rich_location richloc (next_token_loc); + + /* If matching_location != UNKNOWN_LOCATION, highlight it. + Attempt to consolidate diagnostics by printing it as a + secondary range within the main diagnostic. */ + bool added_matching_location = false; + if (matching_location != UNKNOWN_LOCATION) + added_matching_location + = richloc.add_location_if_nearby (matching_location); + + if (c_parser_error_richloc (parser, msgid, &richloc)) + /* If we weren't able to consolidate matching_location, then + print it as a secondary diagnostic. */ + if (matching_location != UNKNOWN_LOCATION && !added_matching_location) + inform (matching_location, "to match this %qs", + get_matching_symbol (type)); + return false; } } @@ -940,16 +1098,22 @@ c_parser_require_keyword (c_parser *parser, desired token is found. An error message is still produced if the next token is not as expected. If MSGID is NULL then a message has already been produced and no message will be produced this - time. */ + time. + + If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it + within any error as the location of an "opening" token matching + the close token TYPE (e.g. the location of the '(' when TYPE is + CPP_CLOSE_PAREN). */ void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type, - const char *msgid) + const char *msgid, + location_t matching_location) { unsigned nesting_depth = 0; - if (c_parser_require (parser, type, msgid)) + if (c_parser_require (parser, type, msgid, matching_location)) return; /* Skip tokens until the desired token is found. */ @@ -2210,7 +2374,8 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser) pedwarn_c99 (assert_loc, OPT_Wpedantic, "ISO C90 does not support %<_Static_assert%>"); c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return; location_t value_tok_loc = c_parser_peek_token (parser)->location; value = c_parser_expr_no_commas (parser, NULL).value; @@ -2237,7 +2402,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser) parser->lex_untranslated_string = false; return; } - c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.require_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) { @@ -2922,7 +3087,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) tree name; gcc_assert (c_dialect_objc ()); c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) goto end_at_defs; if (c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) @@ -2936,8 +3102,7 @@ c_parser_struct_or_union_specifier (c_parser *parser) c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); goto end_at_defs; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + parens.skip_until_found_close (parser); contents = nreverse (objc_get_class_ivars (name)); } end_at_defs: @@ -3224,7 +3389,8 @@ c_parser_typeof_specifier (c_parser *parser) c_parser_consume_token (parser); c_inhibit_evaluation_warnings++; in_typeof++; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) { c_inhibit_evaluation_warnings--; in_typeof--; @@ -3265,7 +3431,7 @@ c_parser_typeof_specifier (c_parser *parser) if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec)) ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED); } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return ret; } @@ -3291,7 +3457,8 @@ c_parser_alignas_specifier (c_parser * parser) else pedwarn_c99 (loc, OPT_Wpedantic, "ISO C90 does not support %<_Alignas%>"); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return ret; if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) { @@ -3302,7 +3469,7 @@ c_parser_alignas_specifier (c_parser * parser) } else ret = c_parser_expr_no_commas (parser, NULL).value; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return ret; } @@ -3953,14 +4120,15 @@ c_parser_simple_asm_expr (c_parser *parser) lex_untranslated_string kludge. */ parser->lex_untranslated_string = true; c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) { parser->lex_untranslated_string = false; return NULL_TREE; } str = c_parser_asm_string_literal (parser); parser->lex_untranslated_string = false; - if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) + if (!parens.require_close (parser)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return NULL_TREE; @@ -4398,7 +4566,8 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p, location_t brace_loc = c_parser_peek_token (parser)->location; gcc_obstack_init (&braced_init_obstack); gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); - c_parser_consume_token (parser); + matching_braces braces; + braces.consume_open (parser); if (nested_p) { finish_implicit_inits (brace_loc, outer_obstack); @@ -4436,7 +4605,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p, ret.value = error_mark_node; ret.original_code = ERROR_MARK; ret.original_type = NULL; - c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>"); + braces.skip_until_found_close (parser); pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma); obstack_free (&braced_init_obstack, NULL); return ret; @@ -5459,10 +5628,11 @@ static tree c_parser_paren_condition (c_parser *parser) { tree cond; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return error_mark_node; cond = c_parser_condition (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return cond; } @@ -5731,7 +5901,8 @@ c_parser_switch_statement (c_parser *parser, bool *if_p) c_parser_consume_token (parser); block = c_begin_compound_stmt (flag_isoc99); bool explicit_cast_p = false; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { switch_cond_loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) @@ -5746,7 +5917,7 @@ c_parser_switch_statement (c_parser *parser, bool *if_p) "%<_Cilk_spawn%> statement cannot be used as a condition for switch statement", switch_cond_loc)) expr = error_mark_node; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } else { @@ -5956,7 +6127,8 @@ c_parser_for_statement (c_parser *parser, bool ivdep, bool *if_p) block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ()); cond = error_mark_node; incr = error_mark_node; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { /* Parse the initialization declaration or expression. */ object_expression = error_mark_node; @@ -6103,7 +6275,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, bool *if_p) incr = c_process_expr_stmt (loc, ce.value); } } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } save_break = c_break_label; c_break_label = NULL_TREE; @@ -6197,7 +6369,8 @@ c_parser_asm_statement (c_parser *parser) parser->lex_untranslated_string = true; ret = NULL; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) goto error; str = c_parser_asm_string_literal (parser); @@ -6255,7 +6428,7 @@ c_parser_asm_statement (c_parser *parser) } done_asm: - if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) + if (!parens.require_close (parser)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); goto error; @@ -6320,7 +6493,8 @@ c_parser_asm_operands (c_parser *parser) if (str == NULL_TREE) return NULL_TREE; parser->lex_untranslated_string = false; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) { parser->lex_untranslated_string = true; return NULL_TREE; @@ -6328,7 +6502,7 @@ c_parser_asm_operands (c_parser *parser) expr = c_parser_expression (parser); mark_exp_read (expr.value); parser->lex_untranslated_string = true; - if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) + if (!parens.require_close (parser)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return NULL_TREE; @@ -6940,9 +7114,10 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) struct c_type_name *type_name; struct c_expr ret; struct c_expr expr; - c_parser_consume_token (parser); + matching_parens parens; + parens.consume_open (parser); type_name = c_parser_type_name (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (type_name == NULL) { ret.value = error_mark_node; @@ -7169,10 +7344,11 @@ c_parser_sizeof_expression (c_parser *parser) /* Either sizeof ( type-name ) or sizeof unary-expression starting with a compound literal. */ struct c_type_name *type_name; - c_parser_consume_token (parser); + matching_parens parens; + parens.consume_open (parser); expr_loc = c_parser_peek_token (parser)->location; type_name = c_parser_type_name (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); finish = parser->tokens_buf[0].location; if (type_name == NULL) { @@ -7251,11 +7427,12 @@ c_parser_alignof_expression (c_parser *parser) location_t loc; struct c_type_name *type_name; struct c_expr ret; - c_parser_consume_token (parser); + matching_parens parens; + parens.consume_open (parser); loc = c_parser_peek_token (parser)->location; type_name = c_parser_type_name (parser); end_loc = c_parser_peek_token (parser)->location; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (type_name == NULL) { struct c_expr ret; @@ -7414,7 +7591,8 @@ c_parser_generic_selection (c_parser *parser) pedwarn_c99 (generic_loc, OPT_Wpedantic, "ISO C90 does not support %<_Generic%>"); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return error_expr; c_inhibit_evaluation_warnings++; @@ -7556,7 +7734,7 @@ c_parser_generic_selection (c_parser *parser) c_parser_consume_token (parser); } - if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) + if (!parens.require_close (parser)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return error_expr; @@ -7802,7 +7980,7 @@ c_parser_postfix_expression (c_parser *parser) location_t loc_close_paren = c_parser_peek_token (parser)->location; set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + "expected %<)%>", loc_open_paren); } break; case CPP_KEYWORD: @@ -7839,7 +8017,8 @@ c_parser_postfix_expression (c_parser *parser) { location_t start_loc = loc; c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) { expr.set_error (); break; @@ -7879,25 +8058,25 @@ c_parser_postfix_expression (c_parser *parser) } break; case RID_OFFSETOF: - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - expr.set_error (); - break; - } - t1 = c_parser_type_name (parser); - if (t1 == NULL) - parser->error = true; - if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) - gcc_assert (parser->error); - if (parser->error) - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - expr.set_error (); - break; - } - { + c_parser_consume_token (parser); + matching_parens parens; + if (!parens.require_open (parser)) + { + expr.set_error (); + break; + } + t1 = c_parser_type_name (parser); + if (t1 == NULL) + parser->error = true; + if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) + gcc_assert (parser->error); + if (parser->error) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + expr.set_error (); + break; + } tree type = groktypename (t1, NULL, NULL); tree offsetof_ref; if (type == error_mark_node) @@ -8014,34 +8193,34 @@ c_parser_postfix_expression (c_parser *parser) break; } case RID_TYPES_COMPATIBLE_P: - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - expr.set_error (); - break; - } - t1 = c_parser_type_name (parser); - if (t1 == NULL) - { - expr.set_error (); - break; - } - if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - expr.set_error (); - break; - } - t2 = c_parser_type_name (parser); - if (t2 == NULL) - { - expr.set_error (); - break; - } { + c_parser_consume_token (parser); + matching_parens parens; + if (!parens.require_open (parser)) + { + expr.set_error (); + break; + } + t1 = c_parser_type_name (parser); + if (t1 == NULL) + { + expr.set_error (); + break; + } + if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + expr.set_error (); + break; + } + t2 = c_parser_type_name (parser); + if (t2 == NULL) + { + expr.set_error (); + break; + } location_t close_paren_loc = c_parser_peek_token (parser)->location; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + parens.skip_until_found_close (parser); tree e1, e2; e1 = groktypename (t1, NULL, NULL); e2 = groktypename (t2, NULL, NULL); @@ -8207,67 +8386,67 @@ c_parser_postfix_expression (c_parser *parser) break; } case RID_AT_SELECTOR: - gcc_assert (c_dialect_objc ()); - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - expr.set_error (); - break; - } { + gcc_assert (c_dialect_objc ()); + c_parser_consume_token (parser); + matching_parens parens; + if (!parens.require_open (parser)) + { + expr.set_error (); + break; + } tree sel = c_parser_objc_selector_arg (parser); location_t close_loc = c_parser_peek_token (parser)->location; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + parens.skip_until_found_close (parser); expr.value = objc_build_selector_expr (loc, sel); set_c_expr_source_range (&expr, loc, close_loc); } break; case RID_AT_PROTOCOL: - gcc_assert (c_dialect_objc ()); - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - expr.set_error (); - break; - } - if (c_parser_next_token_is_not (parser, CPP_NAME)) - { - c_parser_error (parser, "expected identifier"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - expr.set_error (); - break; - } { + gcc_assert (c_dialect_objc ()); + c_parser_consume_token (parser); + matching_parens parens; + if (!parens.require_open (parser)) + { + expr.set_error (); + break; + } + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + c_parser_error (parser, "expected identifier"); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + expr.set_error (); + break; + } tree id = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); location_t close_loc = c_parser_peek_token (parser)->location; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + parens.skip_until_found_close (parser); expr.value = objc_build_protocol_expr (id); set_c_expr_source_range (&expr, loc, close_loc); } break; case RID_AT_ENCODE: - /* Extension to support C-structures in the archiver. */ - gcc_assert (c_dialect_objc ()); - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - expr.set_error (); - break; - } - t1 = c_parser_type_name (parser); - if (t1 == NULL) - { - expr.set_error (); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - break; - } { + /* Extension to support C-structures in the archiver. */ + gcc_assert (c_dialect_objc ()); + c_parser_consume_token (parser); + matching_parens parens; + if (!parens.require_open (parser)) + { + expr.set_error (); + break; + } + t1 = c_parser_type_name (parser); + if (t1 == NULL) + { + expr.set_error (); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + break; + } location_t close_loc = c_parser_peek_token (parser)->location; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + parens.skip_until_found_close (parser); tree type = groktypename (t1, NULL, NULL); expr.value = objc_build_encode_expr (type); set_c_expr_source_range (&expr, loc, close_loc); @@ -8860,7 +9039,8 @@ c_parser_objc_class_definition (c_parser *parser, tree attributes) /* We have a category or class extension. */ tree id2; tree proto = NULL_TREE; - c_parser_consume_token (parser); + matching_parens parens; + parens.consume_open (parser); if (c_parser_next_token_is_not (parser, CPP_NAME)) { if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) @@ -8880,7 +9060,7 @@ c_parser_objc_class_definition (c_parser *parser, tree attributes) id2 = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!iface_p) { objc_start_category_implementation (id1, id2); @@ -9414,9 +9594,10 @@ c_parser_objc_method_decl (c_parser *parser, bool is_class_method, *attributes = NULL_TREE; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) { - c_parser_consume_token (parser); + matching_parens parens; + parens.consume_open (parser); type = c_parser_objc_type_name (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } sel = c_parser_objc_selector (parser); /* If there is no selector, or a colon follows, we have an @@ -9622,7 +9803,8 @@ c_parser_objc_try_catch_finally_statement (c_parser *parser) bool seen_open_paren = false; c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) seen_open_paren = true; if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) { @@ -9645,7 +9827,7 @@ c_parser_objc_try_catch_finally_statement (c_parser *parser) parameter_declaration = grokparm (parm, NULL); } if (seen_open_paren) - c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.require_close (parser); else { /* If there was no open parenthesis, we are recovering from @@ -9694,13 +9876,14 @@ c_parser_objc_synchronized_statement (c_parser *parser) c_parser_consume_token (parser); loc = c_parser_peek_token (parser)->location; objc_maybe_warn_exceptions (loc); - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { struct c_expr ce = c_parser_expression (parser); ce = convert_lvalue_to_rvalue (loc, ce, false, false); expr = ce.value; expr = c_fully_fold (expr, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } else expr = error_mark_node; @@ -9994,9 +10177,11 @@ c_parser_objc_at_property_declaration (c_parser *parser) /* Parse the optional attribute list... */ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) { + matching_parens parens; + /* Eat the '(' */ - c_parser_consume_token (parser); - + parens.consume_open (parser); + /* Property attribute keywords are valid now. */ parser->objc_property_attr_context = true; @@ -10084,7 +10269,7 @@ c_parser_objc_at_property_declaration (c_parser *parser) break; } parser->objc_property_attr_context = false; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } /* ... and the property declaration(s). */ properties = c_parser_struct_declaration (parser); @@ -10744,7 +10929,8 @@ c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list) vec<tree, va_gc> *args; tree t, args_tree; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL); @@ -10781,7 +10967,7 @@ c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list) } release_tree_vector (args); - c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.require_close (parser); return list; } @@ -10939,10 +11125,11 @@ c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, /* The clauses location. */ location_t loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { list = c_parser_omp_variable_list (parser, loc, kind, list); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } return list; } @@ -11079,10 +11266,11 @@ c_parser_omp_clause_collapse (c_parser *parser, tree list) check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { num = c_parser_expr_no_commas (parser, NULL).value; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } if (num == error_mark_node) return list; @@ -11134,7 +11322,8 @@ c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc) location_t loc = c_parser_peek_token (parser)->location; tree c; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (c_parser_next_token_is (parser, CPP_NAME)) { @@ -11174,7 +11363,7 @@ c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc) else c_parser_error (parser, "expected %<none%> or %<shared%>"); } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) return list; @@ -11237,7 +11426,8 @@ c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp) location_t location = c_parser_peek_token (parser)->location; enum tree_code if_modifier = ERROR_MARK; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (is_omp && c_parser_next_token_is (parser, CPP_NAME)) @@ -11318,7 +11508,7 @@ c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp) } tree t = c_parser_condition (parser), c; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF) @@ -11417,7 +11607,8 @@ static tree c_parser_omp_clause_num_threads (c_parser *parser, tree list) { location_t num_threads_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -11425,7 +11616,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -11462,7 +11653,8 @@ static tree c_parser_omp_clause_num_tasks (c_parser *parser, tree list) { location_t num_tasks_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -11470,7 +11662,7 @@ c_parser_omp_clause_num_tasks (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -11507,7 +11699,8 @@ static tree c_parser_omp_clause_grainsize (c_parser *parser, tree list) { location_t grainsize_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -11515,7 +11708,7 @@ c_parser_omp_clause_grainsize (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -11552,7 +11745,8 @@ static tree c_parser_omp_clause_priority (c_parser *parser, tree list) { location_t priority_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -11560,7 +11754,7 @@ c_parser_omp_clause_priority (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -11598,7 +11792,8 @@ static tree c_parser_omp_clause_hint (c_parser *parser, tree list) { location_t hint_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -11606,7 +11801,7 @@ c_parser_omp_clause_hint (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -11635,7 +11830,8 @@ c_parser_omp_clause_defaultmap (c_parser *parser, tree list) tree c; const char *p; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (!c_parser_next_token_is (parser, CPP_NAME)) { @@ -11663,14 +11859,14 @@ c_parser_omp_clause_defaultmap (c_parser *parser, tree list) goto out_err; } c_parser_consume_token (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULTMAP, "defaultmap"); c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP); OMP_CLAUSE_CHAIN (c) = list; return c; out_err: - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return list; } @@ -11707,7 +11903,8 @@ c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code, { location_t loc = c_parser_peek_token (parser)->location; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; location_t expr_loc = c_parser_peek_token (parser)->location; @@ -11716,7 +11913,7 @@ c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code, tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (t == error_mark_node) return list; @@ -12046,9 +12243,10 @@ c_parser_omp_clause_ordered (c_parser *parser, tree list) location_t loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) { - c_parser_consume_token (parser); + matching_parens parens; + parens.consume_open (parser); num = c_parser_expr_no_commas (parser, NULL).value; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } if (num == error_mark_node) return list; @@ -12102,7 +12300,8 @@ static tree c_parser_omp_clause_reduction (c_parser *parser, tree list) { location_t clause_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { enum tree_code code = ERROR_MARK; tree reduc_id = NULL_TREE; @@ -12200,7 +12399,7 @@ c_parser_omp_clause_reduction (c_parser *parser, tree list) list = nl; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } return list; } @@ -12228,7 +12427,8 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) location_t loc = c_parser_peek_token (parser)->location; int modifiers = 0, nmodifiers = 0; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE); @@ -12339,7 +12539,7 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) else c_parser_error (parser, "expected integer expression"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } else c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, @@ -12452,7 +12652,8 @@ static tree c_parser_omp_clause_num_teams (c_parser *parser, tree list) { location_t num_teams_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -12460,7 +12661,7 @@ c_parser_omp_clause_num_teams (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -12496,7 +12697,8 @@ static tree c_parser_omp_clause_thread_limit (c_parser *parser, tree list) { location_t num_thread_limit_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expression (parser); @@ -12504,7 +12706,7 @@ c_parser_omp_clause_thread_limit (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -12544,7 +12746,8 @@ c_parser_omp_clause_aligned (c_parser *parser, tree list) location_t clause_loc = c_parser_peek_token (parser)->location; tree nl, c; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; nl = c_parser_omp_variable_list (parser, clause_loc, @@ -12571,7 +12774,7 @@ c_parser_omp_clause_aligned (c_parser *parser, tree list) OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return nl; } @@ -12590,7 +12793,8 @@ c_parser_omp_clause_linear (c_parser *parser, tree list, bool is_cilk_simd_fn) tree nl, c, step; enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (!is_cilk_simd_fn @@ -12613,7 +12817,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list, bool is_cilk_simd_fn) OMP_CLAUSE_LINEAR, list); if (kind != OMP_CLAUSE_LINEAR_DEFAULT) - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (c_parser_next_token_is (parser, CPP_COLON)) { @@ -12645,7 +12849,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list, bool is_cilk_simd_fn) OMP_CLAUSE_LINEAR_KIND (c) = kind; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return nl; } @@ -12658,7 +12862,8 @@ c_parser_omp_clause_safelen (c_parser *parser, tree list) location_t clause_loc = c_parser_peek_token (parser)->location; tree c, t; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; location_t expr_loc = c_parser_peek_token (parser)->location; @@ -12675,7 +12880,7 @@ c_parser_omp_clause_safelen (c_parser *parser, tree list) t = NULL_TREE; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (t == NULL_TREE || t == error_mark_node) return list; @@ -12696,7 +12901,8 @@ c_parser_omp_clause_simdlen (c_parser *parser, tree list) location_t clause_loc = c_parser_peek_token (parser)->location; tree c, t; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; location_t expr_loc = c_parser_peek_token (parser)->location; @@ -12713,7 +12919,7 @@ c_parser_omp_clause_simdlen (c_parser *parser, tree list) t = NULL_TREE; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (t == NULL_TREE || t == error_mark_node) return list; @@ -12825,7 +13031,8 @@ c_parser_omp_clause_depend (c_parser *parser, tree list) enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT; tree nl, c; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (c_parser_next_token_is (parser, CPP_NAME)) @@ -12855,7 +13062,7 @@ c_parser_omp_clause_depend (c_parser *parser, tree list) OMP_CLAUSE_DEPEND_KIND (c) = kind; OMP_CLAUSE_DECL (c) = NULL_TREE; OMP_CLAUSE_CHAIN (c) = list; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return c; } @@ -12873,13 +13080,13 @@ c_parser_omp_clause_depend (c_parser *parser, tree list) OMP_CLAUSE_DEPEND_KIND (c) = kind; } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return nl; invalid_kind: c_parser_error (parser, "invalid depend kind"); resync_fail: - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return list; } @@ -12907,7 +13114,8 @@ c_parser_omp_clause_map (c_parser *parser, tree list) tree always_id = NULL_TREE; tree nl, c; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (c_parser_next_token_is (parser, CPP_NAME)) @@ -12974,7 +13182,7 @@ c_parser_omp_clause_map (c_parser *parser, tree list) if (always_id_kind != C_ID_ID) { c_parser_error (parser, "expected identifier"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return list; } @@ -12994,7 +13202,7 @@ c_parser_omp_clause_map (c_parser *parser, tree list) } if (always == 1) { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return list; } } @@ -13004,7 +13212,7 @@ c_parser_omp_clause_map (c_parser *parser, tree list) for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) OMP_CLAUSE_SET_MAP_KIND (c, kind); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return nl; } @@ -13015,7 +13223,8 @@ static tree c_parser_omp_clause_device (c_parser *parser, tree list) { location_t clause_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { location_t expr_loc = c_parser_peek_token (parser)->location; c_expr expr = c_parser_expr_no_commas (parser, NULL); @@ -13023,7 +13232,7 @@ c_parser_omp_clause_device (c_parser *parser, tree list) tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { @@ -13052,7 +13261,8 @@ c_parser_omp_clause_dist_schedule (c_parser *parser, tree list) tree c, t = NULL_TREE; location_t loc = c_parser_peek_token (parser)->location; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (!c_parser_next_token_is_keyword (parser, RID_STATIC)) @@ -13073,7 +13283,7 @@ c_parser_omp_clause_dist_schedule (c_parser *parser, tree list) expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); t = expr.value; t = c_fully_fold (t, false, NULL); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } else c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, @@ -13102,7 +13312,8 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list) enum omp_clause_proc_bind_kind kind; tree c; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return list; if (c_parser_next_token_is (parser, CPP_NAME)) @@ -13121,7 +13332,7 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list) goto invalid_kind; c_parser_consume_token (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND); OMP_CLAUSE_PROC_BIND_KIND (c) = kind; OMP_CLAUSE_CHAIN (c) = list; @@ -13129,7 +13340,7 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list) invalid_kind: c_parser_error (parser, "invalid proc_bind kind"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return list; } @@ -13160,11 +13371,12 @@ c_parser_omp_clause_uniform (c_parser *parser, tree list) /* The clauses location. */ location_t loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM, list); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); } return list; } @@ -14957,7 +15169,8 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, { int bracecount = 0; - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) goto pop_scopes; /* Parse the initialization declaration or expression. */ @@ -15064,7 +15277,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, incr = c_process_expr_stmt (incr_loc, c_parser_expression (parser).value); } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); if (decl == NULL || decl == error_mark_node || init == error_mark_node) fail = true; @@ -17571,7 +17784,8 @@ c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses, clause. Represent it in OpenMP terms. */ check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength"); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return clauses; location_t loc = c_parser_peek_token (parser)->location; @@ -17607,7 +17821,7 @@ c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses, } } - c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.require_close (parser); return clauses; } @@ -17629,7 +17843,8 @@ c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses, static tree c_parser_cilk_clause_linear (c_parser *parser, tree clauses) { - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (!parens.require_open (parser)) return clauses; location_t loc = c_parser_peek_token (parser)->location; @@ -17691,7 +17906,7 @@ c_parser_cilk_clause_linear (c_parser *parser, tree clauses) c_parser_consume_token (parser); } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + parens.skip_until_found_close (parser); return clauses; } @@ -18055,7 +18270,8 @@ c_parser_transaction_expression (c_parser *parser, enum rid keyword) } parser->in_transaction = this_in; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + matching_parens parens; + if (parens.require_open (parser)) { tree expr = c_parser_expression (parser).value; ret.original_type = TREE_TYPE (expr); @@ -18064,7 +18280,7 @@ c_parser_transaction_expression (c_parser *parser, enum rid keyword) TRANSACTION_EXPR_RELAXED (ret.value) = 1; SET_EXPR_LOCATION (ret.value, loc); ret.original_code = TRANSACTION_EXPR; - if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) + if (!parens.require_close (parser)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); goto error; diff --git a/gcc/c/c-parser.h b/gcc/c/c-parser.h index 1e344c4..01a7b72 100644 --- a/gcc/c/c-parser.h +++ b/gcc/c/c-parser.h @@ -136,11 +136,13 @@ extern c_token * c_parser_peek_token (c_parser *parser); extern c_token * c_parser_peek_2nd_token (c_parser *parser); extern c_token * c_parser_peek_nth_token (c_parser *parser, unsigned int n); extern bool c_parser_require (c_parser *parser, enum cpp_ttype type, - const char *msgid); -extern void c_parser_error (c_parser *parser, const char *gmsgid); + const char *msgid, + location_t matching_location = UNKNOWN_LOCATION); +extern bool c_parser_error (c_parser *parser, const char *gmsgid); extern void c_parser_consume_token (c_parser *parser); extern void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type, - const char *msgid); + const char *msgid, + location_t = UNKNOWN_LOCATION); extern bool c_parser_next_token_starts_declspecs (c_parser *parser); bool c_parser_next_tokens_start_declaration (c_parser *parser); bool c_token_starts_typename (c_token *token); |