@@ -5949,12 +5949,13 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
return result;
}
-/* Issue the error given by GMSGID, indicating that it occurred before
- TOKEN, which had the associated VALUE. */
+/* Issue the error given by GMSGID at RICHLOC, indicating that it occurred
+ before TOKEN, which had the associated VALUE. */
void
c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
- tree value, unsigned char token_flags)
+ tree value, unsigned char token_flags,
+ rich_location *richloc)
{
#define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
@@ -5995,7 +5996,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
else
message = catenate_messages (gmsgid, " before %s'\\x%x'");
- error (message, prefix, val);
+ error_at_rich_loc (richloc, message, prefix, val);
free (message);
message = NULL;
}
@@ -6023,7 +6024,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
else if (token_type == CPP_NAME)
{
message = catenate_messages (gmsgid, " before %qE");
- error (message, value);
+ error_at_rich_loc (richloc, message, value);
free (message);
message = NULL;
}
@@ -6036,16 +6037,16 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
else if (token_type < N_TTYPES)
{
message = catenate_messages (gmsgid, " before %qs token");
- error (message, cpp_type2name (token_type, token_flags));
+ error_at_rich_loc (richloc, message, cpp_type2name (token_type, token_flags));
free (message);
message = NULL;
}
else
- error (gmsgid);
+ error_at_rich_loc (richloc, gmsgid);
if (message)
{
- error (message);
+ error_at_rich_loc (richloc, message);
free (message);
}
#undef catenate_messages
@@ -1124,7 +1124,8 @@ extern void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
extern void builtin_define_type_sizeof (const char *, tree);
extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const line_map_ordinary *);
-extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char);
+extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char,
+ rich_location *richloc);
/* In c-ppoutput.c */
extern void init_pp_output (FILE *);
@@ -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;
@@ -6937,9 +7111,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;
@@ -7166,10 +7341,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)
{
@@ -7248,11 +7424,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;
@@ -7411,7 +7588,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++;
@@ -7553,7 +7731,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;
@@ -7799,7 +7977,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:
@@ -7836,7 +8014,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;
@@ -7876,25 +8055,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)
@@ -8011,34 +8190,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);
@@ -8204,67 +8383,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);
@@ -8857,7 +9036,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))
@@ -8877,7 +9057,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);
@@ -9411,9 +9591,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
@@ -9619,7 +9800,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))
{
@@ -9642,7 +9824,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
@@ -9691,13 +9873,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;
@@ -9991,9 +10174,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;
@@ -10081,7 +10266,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);
@@ -10741,7 +10926,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);
@@ -10778,7 +10964,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;
}
@@ -10936,10 +11122,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;
}
@@ -11076,10 +11263,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;
@@ -11131,7 +11319,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))
{
@@ -11171,7 +11360,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;
@@ -11234,7 +11423,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))
@@ -11315,7 +11505,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)
@@ -11414,7 +11604,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);
@@ -11422,7 +11613,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)))
{
@@ -11459,7 +11650,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);
@@ -11467,7 +11659,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)))
{
@@ -11504,7 +11696,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);
@@ -11512,7 +11705,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)))
{
@@ -11549,7 +11742,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);
@@ -11557,7 +11751,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)))
{
@@ -11595,7 +11789,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);
@@ -11603,7 +11798,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)))
{
@@ -11632,7 +11827,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))
{
@@ -11660,14 +11856,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;
}
@@ -11704,7 +11900,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;
@@ -11713,7 +11910,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;
@@ -12043,9 +12240,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;
@@ -12099,7 +12297,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;
@@ -12197,7 +12396,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;
}
@@ -12225,7 +12424,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);
@@ -12336,7 +12536,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,
@@ -12449,7 +12649,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);
@@ -12457,7 +12658,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)))
{
@@ -12493,7 +12694,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);
@@ -12501,7 +12703,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)))
{
@@ -12541,7 +12743,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,
@@ -12568,7 +12771,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;
}
@@ -12587,7 +12790,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
@@ -12610,7 +12814,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))
{
@@ -12642,7 +12846,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;
}
@@ -12655,7 +12859,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;
@@ -12672,7 +12877,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;
@@ -12693,7 +12898,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;
@@ -12710,7 +12916,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;
@@ -12822,7 +13028,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))
@@ -12852,7 +13059,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;
}
@@ -12870,13 +13077,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;
}
@@ -12904,7 +13111,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))
@@ -12971,7 +13179,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;
}
@@ -12991,7 +13199,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;
}
}
@@ -13001,7 +13209,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;
}
@@ -13012,7 +13220,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);
@@ -13020,7 +13229,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)))
{
@@ -13049,7 +13258,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))
@@ -13070,7 +13280,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,
@@ -13099,7 +13309,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))
@@ -13118,7 +13329,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;
@@ -13126,7 +13337,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;
}
@@ -13157,11 +13368,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;
}
@@ -14954,7 +15166,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. */
@@ -15061,7 +15274,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;
@@ -17568,7 +17781,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;
@@ -17604,7 +17818,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;
}
@@ -17626,7 +17840,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;
@@ -17688,7 +17903,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;
}
@@ -18052,7 +18267,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);
@@ -18061,7 +18277,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;
@@ -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);
@@ -2551,9 +2551,9 @@ static void set_and_check_decl_spec_loc
static bool cp_parser_friend_p
(const cp_decl_specifier_seq *);
static void cp_parser_required_error
- (cp_parser *, required_token, bool);
+ (cp_parser *, required_token, bool, location_t);
static cp_token *cp_parser_require
- (cp_parser *, enum cpp_ttype, required_token);
+ (cp_parser *, enum cpp_ttype, required_token, location_t = UNKNOWN_LOCATION);
static cp_token *cp_parser_require_keyword
(cp_parser *, enum rid, required_token);
static bool cp_parser_token_starts_function_definition_p
@@ -2804,12 +2804,13 @@ cp_parser_error (cp_parser* parser, const char* gmsgid)
}
}
+ rich_location richloc (line_table, input_location);
c_parse_error (gmsgid,
/* Because c_parser_error does not understand
CPP_KEYWORD, keywords are treated like
identifiers. */
(token->type == CPP_KEYWORD ? CPP_NAME : token->type),
- token->u.value, token->flags);
+ token->u.value, token->flags, &richloc);
}
}
@@ -4503,6 +4504,90 @@ struct tentative_firewall
}
};
+/* 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 (cp_parser *parser)
+ {
+ m_open_loc = cp_lexer_peek_token (parser->lexer)->location;
+ return cp_parser_require (parser, traits_t::open_token_type,
+ traits_t::required_token_open);
+ }
+
+ /* Consume the next token from PARSER, recording its location as
+ that of the opening token within the pair. */
+
+ cp_token * consume_open (cp_parser *parser)
+ {
+ cp_token *tok = cp_lexer_consume_token (parser->lexer);
+ gcc_assert (tok->type == traits_t::open_token_type);
+ m_open_loc = tok->location;
+ return tok;
+ }
+
+ /* If the next token is the closing symbol for this pair, consume it
+ and return it.
+ Otherwise, issue an error, highlighting the location of the
+ corresponding opening token, and return NULL. */
+
+ cp_token *require_close (cp_parser *parser) const
+ {
+ return cp_parser_require (parser, traits_t::close_token_type,
+ traits_t::required_token_close,
+ 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 enum required_token required_token_open = RT_OPEN_PAREN;
+ static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
+ static const enum required_token required_token_close = RT_CLOSE_PAREN;
+};
+
+/* "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 enum required_token required_token_open = RT_OPEN_BRACE;
+ static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
+ static const enum required_token required_token_close = RT_CLOSE_BRACE;
+};
+
+/* "matching_braces" is a token_pair<T> class for tracking matching
+ pairs of braces. */
+
+typedef token_pair<matching_brace_traits> matching_braces;
+
+
/* Parse a GNU statement-expression, i.e. ({ stmts }), except for the
enclosing parentheses. */
@@ -4513,7 +4598,8 @@ cp_parser_statement_expr (cp_parser *parser)
/* Consume the '('. */
location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
/* Start the statement-expression. */
tree expr = begin_stmt_expr ();
/* Parse the compound-statement. */
@@ -4522,7 +4608,7 @@ cp_parser_statement_expr (cp_parser *parser)
expr = finish_stmt_expr (expr, false);
/* Consume the ')'. */
location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_end_of_statement (parser);
cp_parser_end_tentative_firewall (parser, start, expr);
@@ -4928,7 +5014,8 @@ cp_parser_primary_expression (cp_parser *parser,
location_t open_paren_loc = token->location;
/* Consume the `('. */
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
/* Within a parenthesized expression, a `>' token is always
the greater-than operator. */
saved_greater_than_is_operator_p
@@ -4976,7 +5063,7 @@ cp_parser_primary_expression (cp_parser *parser,
token = cp_lexer_peek_token (parser->lexer);
location_t close_paren_loc = token->location;
expr.set_range (open_paren_loc, close_paren_loc);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)
+ if (!parens.require_close (parser)
&& !cp_parser_uncommitted_to_tentative_parse_p (parser))
cp_parser_skip_to_end_of_statement (parser);
@@ -5098,7 +5185,8 @@ cp_parser_primary_expression (cp_parser *parser,
`va_arg'. Consume the `__builtin_va_arg' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the opening `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Now, parse the assignment-expression. */
expression = cp_parser_assignment_expression (parser);
/* Look for the `,'. */
@@ -5112,7 +5200,7 @@ cp_parser_primary_expression (cp_parser *parser,
/* Look for the closing `)'. */
location_t finish_loc
= cp_lexer_peek_token (parser->lexer)->location;
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Using `va_arg' in a constant-expression is not
allowed. */
if (cp_parser_non_integral_constant_expression (parser,
@@ -6345,9 +6433,6 @@ cp_parser_qualifying_entity (cp_parser *parser,
static bool
cp_parser_compound_literal_p (cp_parser *parser)
{
- /* Consume the `('. */
- cp_lexer_consume_token (parser->lexer);
-
cp_lexer_save_tokens (parser->lexer);
/* Skip tokens until the next token is a closing parenthesis.
@@ -6465,7 +6550,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
parser->greater_than_is_operator_p = true;
/* And the expression which is being cast. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
expression = cp_parser_expression (parser, & idk, /*cast_p=*/true);
cp_token *close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
RT_CLOSE_PAREN);
@@ -6526,7 +6612,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Consume the `typeid' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the `(' token. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Types cannot be defined in a `typeid' expression. */
saved_message = parser->type_definition_forbidden_message;
parser->type_definition_forbidden_message
@@ -6542,8 +6629,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Look for the `)' token. Otherwise, we can't be sure that
we're not looking at an expression: consider `typeid (int
(3))', for example. */
- cp_token *close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
- RT_CLOSE_PAREN);
+ cp_token *close_paren = parens.require_close (parser);
/* If all went well, simply lookup the type-id. */
if (cp_parser_parse_definitely (parser))
postfix_expression = get_typeid (type, tf_warning_or_error);
@@ -6557,8 +6643,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Compute its typeid. */
postfix_expression = build_typeid (expression, tf_warning_or_error);
/* Look for the `)' token. */
- close_paren
- = cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ close_paren = parens.require_close (parser);
}
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
@@ -6759,6 +6844,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
cp_parser_parse_tentatively (parser);
+ matching_parens parens;
+ parens.consume_open (parser);
+
/* Avoid calling cp_parser_type_id pointlessly, see comment
in cp_parser_cast_expression about c++/29234. */
if (!cp_parser_compound_literal_p (parser))
@@ -6770,8 +6858,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
parser->in_type_id_in_expr_p = true;
type = cp_parser_type_id (parser);
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
- /* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
}
/* If things aren't going well, there's no need to
@@ -7561,7 +7648,8 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
if (non_constant_p)
*non_constant_p = false;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return NULL;
expression_list = make_tree_vector ();
@@ -7657,7 +7745,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
if (close_paren_loc)
*close_paren_loc = cp_lexer_peek_token (parser->lexer)->location;
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
{
int ending;
@@ -7957,7 +8045,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
bool saved_greater_than_is_operator_p;
cp_lexer_consume_token (parser->lexer);
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
saved_message = parser->type_definition_forbidden_message;
parser->type_definition_forbidden_message
@@ -7991,7 +8080,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
parser->type_definition_forbidden_message = saved_message;
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
return finish_noexcept_expr (expr, tf_warning_or_error);
}
@@ -8235,7 +8324,8 @@ cp_parser_new_expression (cp_parser* parser)
const char *saved_message = parser->type_definition_forbidden_message;
/* Consume the `('. */
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
/* Parse the type-id. */
parser->type_definition_forbidden_message
@@ -8247,7 +8337,7 @@ cp_parser_new_expression (cp_parser* parser)
parser->type_definition_forbidden_message = saved_message;
/* Look for the closing `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
token = cp_lexer_peek_token (parser->lexer);
/* There should not be a direct-new-declarator in this production,
but GCC used to allowed this, so we check and emit a sensible error
@@ -8787,7 +8877,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
parser->type_definition_forbidden_message
= G_("types may not be defined in casts");
/* Consume the `('. */
- cp_token *open_paren = cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ cp_token *open_paren = parens.consume_open (parser);
location_t open_paren_loc = open_paren->location;
location_t close_paren_loc = UNKNOWN_LOCATION;
@@ -8852,8 +8943,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Look for the type-id. */
type = cp_parser_type_id (parser);
/* Look for the closing `)'. */
- cp_token *close_paren
- = cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ cp_token *close_paren = parens.require_close (parser);
if (close_paren)
close_paren_loc = close_paren->location;
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
@@ -9638,7 +9728,8 @@ cp_parser_builtin_offsetof (cp_parser *parser)
/* Consume the "__builtin_offsetof" token. */
cp_lexer_consume_token (parser->lexer);
/* Consume the opening `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Parse the type-id. */
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
type = cp_parser_type_id (parser);
@@ -9688,7 +9779,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
default:
/* Error. We know the following require will fail, but
that gives the proper error message. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
expr = error_mark_node;
goto failure;
@@ -9834,7 +9925,8 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
{
type_id_in_expr_sentinel s (parser);
@@ -9873,7 +9965,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
}
}
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Complete the trait expression, which may mean either processing
the trait expr now or saving it for template instantiation. */
@@ -10354,7 +10446,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
opening parenthesis if present. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
begin_scope (sk_function_parms, /*entity=*/NULL_TREE);
@@ -10369,7 +10462,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_Wpedantic,
"default argument specified for lambda parameter");
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
attributes = cp_parser_attributes_opt (parser);
@@ -10526,7 +10619,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
start_lambda_scope (fco);
body = begin_function_body ();
- if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ matching_braces braces;
+ if (!braces.require_open (parser))
goto out;
/* Push the proxies for any explicit captures. */
@@ -10567,7 +10661,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
expr = cp_parser_expression (parser, &idk);
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
if (cp_parser_parse_definitely (parser))
{
@@ -10591,7 +10685,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
cp_parser_label_declaration (parser);
cp_parser_statement_seq_opt (parser, NULL_TREE);
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
}
finish_compound_stmt (compound_stmt);
@@ -11127,9 +11221,10 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
int bcs_flags, bool function_body)
{
tree compound_stmt;
+ matching_braces braces;
/* Consume the `{'. */
- if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ if (!braces.require_open (parser))
return error_mark_node;
if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
&& !function_body && cxx_dialect < cxx14)
@@ -11145,7 +11240,7 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
/* Finish the compound-statement. */
finish_compound_stmt (compound_stmt);
/* Consume the `}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
return compound_stmt;
}
@@ -11266,7 +11361,8 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
}
/* Look for the `('. */
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
{
cp_parser_skip_to_end_of_statement (parser);
return error_mark_node;
@@ -11295,7 +11391,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
/* Parse the condition. */
condition = cp_parser_condition (parser);
/* Look for the `)'. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, true, false,
/*consume_paren=*/true);
@@ -12082,12 +12178,13 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep)
/* Begin the while-statement. */
statement = begin_while_stmt ();
/* Look for the `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Parse the condition. */
condition = cp_parser_condition (parser);
finish_while_stmt_cond (condition, statement, ivdep);
/* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Parse the dependent statement. */
parser->in_statement = IN_ITERATION_STMT;
cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
@@ -12111,13 +12208,14 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep)
/* Look for the `while' keyword. */
cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE);
/* Look for the `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Parse the expression. */
expression = cp_parser_expression (parser);
/* We're done with the do-statement. */
finish_do_stmt (expression, statement, ivdep);
/* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Look for the `;'. */
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
}
@@ -12126,12 +12224,13 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep)
case RID_FOR:
{
/* Look for the `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
statement = cp_parser_for (parser, ivdep);
/* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Parse the body of the for-statement. */
parser->in_statement = IN_ITERATION_STMT;
@@ -12481,13 +12580,14 @@ cp_parser_already_scoped_statement (cp_parser* parser, bool *if_p,
{
/* Avoid calling cp_parser_compound_statement, so that we
don't create a new scope. Do everything else by hand. */
- cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+ matching_braces braces;
+ braces.require_open (parser);
/* If the next keyword is `__label__' we have a label declaration. */
while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
cp_parser_label_declaration (parser);
/* Parse an (optional) statement-seq. */
cp_parser_statement_seq_opt (parser, NULL_TREE);
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
}
}
@@ -13714,11 +13814,12 @@ cp_parser_linkage_specification (cp_parser* parser)
cp_ensure_no_oacc_routine (parser);
/* Consume the `{' token. */
- cp_lexer_consume_token (parser->lexer);
+ matching_braces braces;
+ braces.consume_open (parser)->location;
/* Parse the declarations. */
cp_parser_declaration_seq_opt (parser);
/* Look for the closing `}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
}
/* Otherwise, there's just one declaration. */
else
@@ -13770,7 +13871,8 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
cp_parser_commit_to_tentative_parse (parser);
/* Parse the `(' starting the static assertion condition. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Parse the constant-expression. Allow a non-constant expression
here in order to give better diagnostics in finish_static_assert. */
@@ -13802,7 +13904,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
/*wide_ok=*/true);
/* A `)' completes the static assertion. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser,
/*recovering=*/true,
/*or_comma=*/false,
@@ -13956,7 +14058,8 @@ cp_parser_decltype (cp_parser *parser)
return error_mark_node;
/* Parse the opening `('. */
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return error_mark_node;
/* decltype (auto) */
@@ -13964,7 +14067,7 @@ cp_parser_decltype (cp_parser *parser)
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
{
cp_lexer_consume_token (parser->lexer);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
return error_mark_node;
expr = make_decltype_auto ();
AUTO_IS_DECLTYPE (expr) = true;
@@ -14019,7 +14122,7 @@ cp_parser_decltype (cp_parser *parser)
= saved_non_integral_constant_expression_p;
/* Parse to the closing `)'. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
{
cp_parser_skip_to_closing_parenthesis (parser, true, false,
/*consume_paren=*/true);
@@ -14718,11 +14821,14 @@ cp_parser_operator (cp_parser* parser)
break;
case CPP_OPEN_PAREN:
- /* Consume the `('. */
- cp_lexer_consume_token (parser->lexer);
- /* Look for the matching `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
- return cp_operator_id (CALL_EXPR);
+ {
+ /* Consume the `('. */
+ matching_parens parens;
+ parens.consume_open (parser);
+ /* Look for the matching `)'. */
+ parens.require_close (parser);
+ return cp_operator_id (CALL_EXPR);
+ }
case CPP_OPEN_SQUARE:
/* Consume the `['. */
@@ -18095,7 +18201,8 @@ cp_parser_enum_specifier (cp_parser* parser)
begin_scope (sk_scoped_enum, type);
/* Consume the opening brace. */
- cp_lexer_consume_token (parser->lexer);
+ matching_braces braces;
+ braces.consume_open (parser);
if (type == error_mark_node)
; /* Nothing to add */
@@ -18128,7 +18235,7 @@ cp_parser_enum_specifier (cp_parser* parser)
cp_parser_enumerator_list (parser, type);
/* Consume the final '}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
if (scoped_enum_p)
finish_scope ();
@@ -18421,13 +18528,14 @@ cp_parser_namespace_definition (cp_parser* parser)
warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
/* Look for the `{' to validate starting the namespace. */
- if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ matching_braces braces;
+ if (braces.require_open (parser))
{
/* Parse the body of the namespace. */
cp_parser_namespace_body (parser);
/* Look for the final `}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
}
if (has_visibility)
@@ -19808,7 +19916,8 @@ cp_parser_direct_declarator (cp_parser* parser,
cp_parser_parse_tentatively (parser);
/* Consume the `('. */
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
if (first)
{
/* If this is going to be an abstract declarator, we're
@@ -19823,7 +19932,7 @@ cp_parser_direct_declarator (cp_parser* parser,
params = cp_parser_parameter_declaration_clause (parser);
/* Consume the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* If all went well, parse the cv-qualifier-seq,
ref-qualifier and the exception-specification. */
@@ -19919,7 +20028,8 @@ cp_parser_direct_declarator (cp_parser* parser,
parser->in_declarator_p = saved_in_declarator_p;
/* Consume the `('. */
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
/* Parse the nested declarator. */
saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
parser->in_type_id_in_expr_p = true;
@@ -19930,7 +20040,7 @@ cp_parser_direct_declarator (cp_parser* parser,
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
first = false;
/* Expect a `)'. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
declarator = cp_error_declarator;
if (declarator == cp_error_declarator)
break;
@@ -21778,7 +21888,8 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
/* Consume the `{' token. */
- cp_lexer_consume_token (parser->lexer);
+ matching_braces braces;
+ braces.consume_open (parser);
/* Create a CONSTRUCTOR to represent the braced-initializer. */
initializer = make_node (CONSTRUCTOR);
/* If it's not a `}', then there is a non-trivial initializer. */
@@ -21795,7 +21906,7 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
*non_constant_p = false;
/* Now, there should be a trailing `}'. */
location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
TREE_TYPE (initializer) = init_list_type_node;
cp_expr result (initializer);
@@ -22222,7 +22333,8 @@ cp_parser_class_specifier_1 (cp_parser* parser)
}
/* Look for the `{'. */
- if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ matching_braces braces;
+ if (!braces.require_open (parser))
{
pop_deferring_access_checks ();
return error_mark_node;
@@ -22274,7 +22386,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
cp_parser_member_specification_opt (parser);
/* Look for the trailing `}'. */
- closing_brace = cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ closing_brace = braces.require_close (parser);
/* Look for trailing attributes to apply to this class. */
if (cp_parser_allow_gnu_extensions_p (parser))
attributes = cp_parser_gnu_attributes_opt (parser);
@@ -23753,11 +23865,12 @@ cp_parser_constant_initializer (cp_parser* parser)
cp_parser_error (parser,
"a brace-enclosed initializer is not allowed here");
/* Consume the opening brace. */
- cp_lexer_consume_token (parser->lexer);
+ matching_braces braces;
+ braces.consume_open (parser);
/* Skip the initializer. */
cp_parser_skip_to_closing_brace (parser);
/* Look for the trailing `}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
return error_mark_node;
}
@@ -24013,7 +24126,8 @@ cp_parser_noexcept_specification_opt (cp_parser* parser,
if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
{
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
if (require_constexpr)
{
@@ -24033,7 +24147,7 @@ cp_parser_noexcept_specification_opt (cp_parser* parser,
*consumed_expr = true;
}
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
}
else
{
@@ -24087,7 +24201,8 @@ cp_parser_exception_specification_opt (cp_parser* parser)
cp_lexer_consume_token (parser->lexer);
/* Look for the `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -24123,7 +24238,7 @@ cp_parser_exception_specification_opt (cp_parser* parser)
type_id_list = empty_except_spec;
/* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
return type_id_list;
}
@@ -24270,10 +24385,11 @@ cp_parser_handler (cp_parser* parser)
cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH);
handler = begin_handler ();
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
declaration = cp_parser_exception_declaration (parser);
finish_handler_parms (declaration, handler);
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
finish_handler (handler);
}
@@ -24389,13 +24505,14 @@ cp_parser_asm_specification_opt (cp_parser* parser)
/* Consume the `asm' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Look for the string-literal. */
asm_specification = cp_parser_string_literal (parser, false, false);
/* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
return asm_specification;
}
@@ -24447,11 +24564,12 @@ cp_parser_asm_operand_list (cp_parser* parser)
string_literal = cp_parser_string_literal (parser, false, false);
/* Look for the `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
/* Parse the expression. */
expression = cp_parser_expression (parser);
/* Look for the `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
if (name == error_mark_node
|| string_literal == error_mark_node
@@ -24705,8 +24823,10 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
/* Consume the `__attribute__' keyword. */
cp_lexer_consume_token (parser->lexer);
/* Look for the two `(' tokens. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens outer_parens;
+ outer_parens.require_open (parser);
+ matching_parens inner_parens;
+ inner_parens.require_open (parser);
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -24719,9 +24839,9 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
attribute_list = NULL;
/* Look for the two `)' tokens. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!inner_parens.require_close (parser))
ok = false;
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!outer_parens.require_close (parser))
ok = false;
if (!ok)
cp_parser_skip_to_end_of_statement (parser);
@@ -25148,7 +25268,8 @@ cp_parser_std_attribute_spec (cp_parser *parser)
cp_lexer_consume_token (parser->lexer);
maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
- if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN) == NULL)
+ matching_parens parens;
+ if (!parens.require_open (parser))
{
cp_parser_error (parser, "expected %<(%>");
return error_mark_node;
@@ -25181,7 +25302,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
if (alignas_expr == error_mark_node)
return error_mark_node;
- if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) == NULL)
+ if (!parens.require_close (parser))
{
cp_parser_error (parser, "expected %<)%>");
return error_mark_node;
@@ -25413,12 +25534,13 @@ cp_parser_requires_expression (cp_parser *parser)
static tree
cp_parser_requirement_parameter_list (cp_parser *parser)
{
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return error_mark_node;
tree parms = cp_parser_parameter_declaration_clause (parser);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
return error_mark_node;
return parms;
@@ -25431,12 +25553,13 @@ cp_parser_requirement_parameter_list (cp_parser *parser)
static tree
cp_parser_requirement_body (cp_parser *parser)
{
- if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ matching_braces braces;
+ if (!braces.require_open (parser))
return error_mark_node;
tree reqs = cp_parser_requirement_list (parser);
- if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
+ if (!braces.require_close (parser))
return error_mark_node;
return reqs;
@@ -25575,14 +25698,15 @@ static tree
cp_parser_compound_requirement (cp_parser *parser)
{
/* Parse an expression enclosed in '{ }'s. */
- if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ matching_braces braces;
+ if (!braces.require_open (parser))
return error_mark_node;
tree expr = cp_parser_expression (parser, NULL, false, false);
if (!expr || expr == error_mark_node)
return error_mark_node;
- if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
+ if (!braces.require_close (parser))
return error_mark_node;
/* Parse the optional noexcept. */
@@ -26653,7 +26777,8 @@ cp_parser_template_introduction (cp_parser* parser, bool member_p)
cp_parser_simulate_error (parser);
/* Look for opening brace for introduction. */
- cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+ matching_braces braces;
+ braces.require_open (parser);
if (!cp_parser_parse_definitely (parser))
return false;
@@ -26673,7 +26798,7 @@ cp_parser_template_introduction (cp_parser* parser, bool member_p)
}
/* Look for closing brace for introduction. */
- if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
+ if (!braces.require_close (parser))
return true;
if (tmpl_decl == error_mark_node)
@@ -27558,9 +27683,10 @@ cp_parser_sizeof_pack (cp_parser *parser)
cp_lexer_consume_token (parser->lexer);
maybe_warn_variadic_templates ();
+ matching_parens parens;
bool paren = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN);
if (paren)
- cp_lexer_consume_token (parser->lexer);
+ parens.consume_open (parser);
else
permerror (cp_lexer_peek_token (parser->lexer)->location,
"%<sizeof...%> argument must be surrounded by parentheses");
@@ -27585,7 +27711,7 @@ cp_parser_sizeof_pack (cp_parser *parser)
PACK_EXPANSION_SIZEOF_P (expr) = true;
if (paren)
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
return expr;
}
@@ -27639,6 +27765,10 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
/* We can't be sure yet whether we're looking at a type-id or an
expression. */
cp_parser_parse_tentatively (parser);
+
+ matching_parens parens;
+ parens.consume_open (parser);
+
/* Note: as a GNU Extension, compound literals are considered
postfix-expressions as they are in C99, so they are valid
arguments to sizeof. See comment in cp_parser_cast_expression
@@ -27652,7 +27782,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
/* Look for the type-id. */
type = cp_parser_type_id (parser);
/* Look for the closing `)'. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
}
@@ -27934,187 +28064,245 @@ cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
return decl_spec_seq_has_spec_p (decl_specifiers, ds_friend);
}
+/* Get a description of the matching symbol to TOKEN_DESC e.g. "(" for
+ RT_CLOSE_PAREN. */
+
+static const char *
+get_matching_symbol (required_token token_desc)
+{
+ switch (token_desc)
+ {
+ default:
+ gcc_unreachable ();
+ return "";
+ case RT_CLOSE_BRACE:
+ return "{";
+ case RT_CLOSE_PAREN:
+ return "(";
+ }
+}
+
/* Issue an error message indicating that TOKEN_DESC was expected.
If KEYWORD is true, it indicated this function is called by
cp_parser_require_keword and the required token can only be
- a indicated keyword. */
+ a indicated keyword.
+
+ 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 TOKEN_DESC is
+ RT_CLOSE_PAREN). */
static void
cp_parser_required_error (cp_parser *parser,
required_token token_desc,
- bool keyword)
+ bool keyword,
+ location_t matching_location)
{
+ if (cp_parser_simulate_error (parser))
+ return;
+
+ const char *gmsgid = NULL;
switch (token_desc)
{
case RT_NEW:
- cp_parser_error (parser, "expected %<new%>");
- return;
+ gmsgid = G_("expected %<new%>");
+ break;
case RT_DELETE:
- cp_parser_error (parser, "expected %<delete%>");
- return;
+ gmsgid = G_("expected %<delete%>");
+ break;
case RT_RETURN:
- cp_parser_error (parser, "expected %<return%>");
- return;
+ gmsgid = G_("expected %<return%>");
+ break;
case RT_WHILE:
- cp_parser_error (parser, "expected %<while%>");
- return;
+ gmsgid = G_("expected %<while%>");
+ break;
case RT_EXTERN:
- cp_parser_error (parser, "expected %<extern%>");
- return;
+ gmsgid = G_("expected %<extern%>");
+ break;
case RT_STATIC_ASSERT:
- cp_parser_error (parser, "expected %<static_assert%>");
- return;
+ gmsgid = G_("expected %<static_assert%>");
+ break;
case RT_DECLTYPE:
- cp_parser_error (parser, "expected %<decltype%>");
- return;
+ gmsgid = G_("expected %<decltype%>");
+ break;
case RT_OPERATOR:
- cp_parser_error (parser, "expected %<operator%>");
- return;
+ gmsgid = G_("expected %<operator%>");
+ break;
case RT_CLASS:
- cp_parser_error (parser, "expected %<class%>");
- return;
+ gmsgid = G_("expected %<class%>");
+ break;
case RT_TEMPLATE:
- cp_parser_error (parser, "expected %<template%>");
- return;
+ gmsgid = G_("expected %<template%>");
+ break;
case RT_NAMESPACE:
- cp_parser_error (parser, "expected %<namespace%>");
- return;
+ gmsgid = G_("expected %<namespace%>");
+ break;
case RT_USING:
- cp_parser_error (parser, "expected %<using%>");
- return;
+ gmsgid = G_("expected %<using%>");
+ break;
case RT_ASM:
- cp_parser_error (parser, "expected %<asm%>");
- return;
+ gmsgid = G_("expected %<asm%>");
+ break;
case RT_TRY:
- cp_parser_error (parser, "expected %<try%>");
- return;
+ gmsgid = G_("expected %<try%>");
+ break;
case RT_CATCH:
- cp_parser_error (parser, "expected %<catch%>");
- return;
+ gmsgid = G_("expected %<catch%>");
+ break;
case RT_THROW:
- cp_parser_error (parser, "expected %<throw%>");
- return;
+ gmsgid = G_("expected %<throw%>");
+ break;
case RT_LABEL:
- cp_parser_error (parser, "expected %<__label__%>");
- return;
+ gmsgid = G_("expected %<__label__%>");
+ break;
case RT_AT_TRY:
- cp_parser_error (parser, "expected %<@try%>");
- return;
+ gmsgid = G_("expected %<@try%>");
+ break;
case RT_AT_SYNCHRONIZED:
- cp_parser_error (parser, "expected %<@synchronized%>");
- return;
+ gmsgid = G_("expected %<@synchronized%>");
+ break;
case RT_AT_THROW:
- cp_parser_error (parser, "expected %<@throw%>");
- return;
+ gmsgid = G_("expected %<@throw%>");
+ break;
case RT_TRANSACTION_ATOMIC:
- cp_parser_error (parser, "expected %<__transaction_atomic%>");
- return;
+ gmsgid = G_("expected %<__transaction_atomic%>");
+ break;
case RT_TRANSACTION_RELAXED:
- cp_parser_error (parser, "expected %<__transaction_relaxed%>");
- return;
+ gmsgid = G_("expected %<__transaction_relaxed%>");
+ break;
default:
break;
}
- if (!keyword)
+
+ if (!gmsgid && !keyword)
{
switch (token_desc)
{
case RT_SEMICOLON:
- cp_parser_error (parser, "expected %<;%>");
- return;
+ gmsgid = G_("expected %<;%>");
+ break;
case RT_OPEN_PAREN:
- cp_parser_error (parser, "expected %<(%>");
- return;
+ gmsgid = G_("expected %<(%>");
+ break;
case RT_CLOSE_BRACE:
- cp_parser_error (parser, "expected %<}%>");
- return;
+ gmsgid = G_("expected %<}%>");
+ break;
case RT_OPEN_BRACE:
- cp_parser_error (parser, "expected %<{%>");
- return;
+ gmsgid = G_("expected %<{%>");
+ break;
case RT_CLOSE_SQUARE:
- cp_parser_error (parser, "expected %<]%>");
- return;
+ gmsgid = G_("expected %<]%>");
+ break;
case RT_OPEN_SQUARE:
- cp_parser_error (parser, "expected %<[%>");
- return;
+ gmsgid = G_("expected %<[%>");
+ break;
case RT_COMMA:
- cp_parser_error (parser, "expected %<,%>");
- return;
+ gmsgid = G_("expected %<,%>");
+ break;
case RT_SCOPE:
- cp_parser_error (parser, "expected %<::%>");
- return;
+ gmsgid = G_("expected %<::%>");
+ break;
case RT_LESS:
- cp_parser_error (parser, "expected %<<%>");
- return;
+ gmsgid = G_("expected %<<%>");
+ break;
case RT_GREATER:
- cp_parser_error (parser, "expected %<>%>");
- return;
+ gmsgid = G_("expected %<>%>");
+ break;
case RT_EQ:
- cp_parser_error (parser, "expected %<=%>");
- return;
+ gmsgid = G_("expected %<=%>");
+ break;
case RT_ELLIPSIS:
- cp_parser_error (parser, "expected %<...%>");
- return;
+ gmsgid = G_("expected %<...%>");
+ break;
case RT_MULT:
- cp_parser_error (parser, "expected %<*%>");
- return;
+ gmsgid = G_("expected %<*%>");
+ break;
case RT_COMPL:
- cp_parser_error (parser, "expected %<~%>");
- return;
+ gmsgid = G_("expected %<~%>");
+ break;
case RT_COLON:
- cp_parser_error (parser, "expected %<:%>");
- return;
+ gmsgid = G_("expected %<:%>");
+ break;
case RT_COLON_SCOPE:
- cp_parser_error (parser, "expected %<:%> or %<::%>");
- return;
+ gmsgid = G_("expected %<:%> or %<::%>");
+ break;
case RT_CLOSE_PAREN:
- cp_parser_error (parser, "expected %<)%>");
- return;
+ gmsgid = G_("expected %<)%>");
+ break;
case RT_COMMA_CLOSE_PAREN:
- cp_parser_error (parser, "expected %<,%> or %<)%>");
- return;
+ gmsgid = G_("expected %<,%> or %<)%>");
+ break;
case RT_PRAGMA_EOL:
- cp_parser_error (parser, "expected end of line");
- return;
+ gmsgid = G_("expected end of line");
+ break;
case RT_NAME:
- cp_parser_error (parser, "expected identifier");
- return;
+ gmsgid = G_("expected identifier");
+ break;
case RT_SELECT:
- cp_parser_error (parser, "expected selection-statement");
- return;
+ gmsgid = G_("expected selection-statement");
+ break;
case RT_ITERATION:
- cp_parser_error (parser, "expected iteration-statement");
- return;
+ gmsgid = G_("expected iteration-statement");
+ break;
case RT_JUMP:
- cp_parser_error (parser, "expected jump-statement");
- return;
+ gmsgid = G_("expected jump-statement");
+ break;
case RT_CLASS_KEY:
- cp_parser_error (parser, "expected class-key");
- return;
+ gmsgid = G_("expected class-key");
+ break;
case RT_CLASS_TYPENAME_TEMPLATE:
- cp_parser_error (parser,
- "expected %<class%>, %<typename%>, or %<template%>");
- return;
+ gmsgid = G_("expected %<class%>, %<typename%>, or %<template%>");
+ break;
default:
gcc_unreachable ();
}
}
- else
- gcc_unreachable ();
-}
+ if (gmsgid)
+ {
+ /* Emulate rest of cp_parser_error. */
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ cp_lexer_set_source_position_from_token (token);
+
+ gcc_rich_location richloc (input_location);
+
+ /* 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);
+
+ c_parse_error (gmsgid,
+ (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
+ token->u.value, token->flags, &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 (token_desc));
+ }
+}
/* If the next token is of the indicated TYPE, consume it. Otherwise,
issue an error message indicating that TOKEN_DESC was expected.
Returns the token consumed, if the token had the appropriate type.
- Otherwise, returns NULL. */
+ Otherwise, returns NULL.
+
+ 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 TOKEN_DESC is
+ RT_CLOSE_PAREN). */
static cp_token *
cp_parser_require (cp_parser* parser,
enum cpp_ttype type,
- required_token token_desc)
+ required_token token_desc,
+ location_t matching_location)
{
if (cp_lexer_next_token_is (parser->lexer, type))
return cp_lexer_consume_token (parser->lexer);
@@ -28122,7 +28310,8 @@ cp_parser_require (cp_parser* parser,
{
/* Output the MESSAGE -- unless we're parsing tentatively. */
if (!cp_parser_simulate_error (parser))
- cp_parser_required_error (parser, token_desc, /*keyword=*/false);
+ cp_parser_required_error (parser, token_desc, /*keyword=*/false,
+ matching_location);
return NULL;
}
}
@@ -28224,7 +28413,8 @@ cp_parser_require_keyword (cp_parser* parser,
if (token && token->keyword != keyword)
{
- cp_parser_required_error (parser, token_desc, /*keyword=*/true);
+ cp_parser_required_error (parser, token_desc, /*keyword=*/true,
+ UNKNOWN_LOCATION);
return NULL;
}
@@ -29035,10 +29225,11 @@ cp_parser_objc_encode_expression (cp_parser* parser)
location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
token = cp_lexer_peek_token (parser->lexer);
type = complete_type (cp_parser_type_id (parser));
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
if (!type)
{
@@ -29080,9 +29271,10 @@ cp_parser_objc_defs_expression (cp_parser *parser)
tree name;
cp_lexer_consume_token (parser->lexer); /* Eat '@defs'. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
name = cp_parser_identifier (parser);
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
return objc_get_class_ivars (name);
}
@@ -29101,9 +29293,10 @@ cp_parser_objc_protocol_expression (cp_parser* parser)
location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
proto = cp_parser_identifier (parser);
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Build a location of the form:
@protocol(prot)
@@ -29141,7 +29334,8 @@ cp_parser_objc_selector_expression (cp_parser* parser)
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_lexer_consume_token (parser->lexer); /* Eat '@selector'. */
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
token = cp_lexer_peek_token (parser->lexer);
while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON
@@ -29188,7 +29382,7 @@ cp_parser_objc_selector_expression (cp_parser* parser)
}
finish_selector:
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* Build a location of the form:
@@ -29395,7 +29589,8 @@ cp_parser_objc_typename (cp_parser* parser)
{
tree proto_quals, cp_type = NULL_TREE;
- cp_lexer_consume_token (parser->lexer); /* Eat '('. */
+ matching_parens parens;
+ parens.consume_open (parser); /* Eat '('. */
proto_quals = cp_parser_objc_protocol_qualifiers (parser);
/* An ObjC type name may consist of just protocol qualifiers, in which
@@ -29421,7 +29616,7 @@ cp_parser_objc_typename (cp_parser* parser)
}
}
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
type_name = build_tree_list (proto_quals, cp_type);
}
@@ -30035,7 +30230,8 @@ cp_parser_objc_superclass_or_category (cp_parser *parser,
}
else if (next->type == CPP_OPEN_PAREN)
{
- cp_lexer_consume_token (parser->lexer); /* Eat '('. */
+ matching_parens parens;
+ parens.consume_open (parser); /* Eat '('. */
/* If there is no category name, and this is an @interface, we
have a class extension. */
@@ -30047,7 +30243,7 @@ cp_parser_objc_superclass_or_category (cp_parser *parser,
else
*categ = cp_parser_identifier (parser);
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
}
}
@@ -30235,9 +30431,10 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
cp_parameter_declarator *parm;
tree parameter_declaration = error_mark_node;
bool seen_open_paren = false;
+ matching_parens parens;
cp_lexer_consume_token (parser->lexer);
- if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ if (parens.require_open (parser))
seen_open_paren = true;
if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
{
@@ -30263,7 +30460,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
/*attrlist=*/NULL);
}
if (seen_open_paren)
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
else
{
/* If there was no open parenthesis, we are recovering from
@@ -30317,9 +30514,10 @@ cp_parser_objc_synchronized_statement (cp_parser *parser)
location = cp_lexer_peek_token (parser->lexer)->location;
objc_maybe_warn_exceptions (location);
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
lock = cp_parser_expression (parser);
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
/* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
node, lest it get absorbed into the surrounding block. */
@@ -30560,7 +30758,8 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
/* Eat the '('. */
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
while (true)
{
@@ -30648,7 +30847,7 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
"error: expected ‘)’ before ‘,’ token". This is because
cp_parser_require, unlike the C counterpart, will produce an
error even if we are in error recovery. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
{
cp_parser_skip_to_closing_parenthesis (parser,
/*recovering=*/true,
@@ -31339,13 +31538,14 @@ cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
{
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
tree t = cp_parser_assignment_expression (parser, NULL, false, false);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
{
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
@@ -31392,7 +31592,8 @@ cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind,
if (cp_lexer_next_token_is (lexer, CPP_OPEN_PAREN))
{
- cp_lexer_consume_token (lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
do
{
@@ -31466,7 +31667,7 @@ cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind,
}
while (1);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
goto cleanup_error;
}
@@ -31612,12 +31813,13 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location
HOST_WIDE_INT n;
loc = cp_lexer_peek_token (parser->lexer)->location;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
num = cp_parser_constant_expression (parser);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -31656,7 +31858,8 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list,
enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
tree c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
@@ -31699,7 +31902,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list,
}
if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -31723,13 +31926,14 @@ cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_condition (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -31760,7 +31964,8 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
tree t, c;
enum tree_code if_modifier = ERROR_MARK;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
if (is_omp && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -31843,7 +32048,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
t = cp_parser_condition (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -31938,13 +32143,14 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -31968,13 +32174,14 @@ cp_parser_omp_clause_num_tasks (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -31998,13 +32205,14 @@ cp_parser_omp_clause_grainsize (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32028,13 +32236,14 @@ cp_parser_omp_clause_priority (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32058,13 +32267,14 @@ cp_parser_omp_clause_hint (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32088,7 +32298,8 @@ cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
tree c, id;
const char *p;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -32120,7 +32331,7 @@ cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
goto out_err;
}
cp_lexer_consume_token (parser->lexer);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
goto out_err;
check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULTMAP, "defaultmap",
@@ -32155,11 +32366,12 @@ cp_parser_omp_clause_ordered (cp_parser *parser,
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
num = cp_parser_constant_expression (parser);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32316,7 +32528,8 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
tree c, t;
int modifiers = 0, nmodifiers = 0;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
@@ -32410,7 +32623,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
else
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
goto resync_fail;
}
else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
@@ -32516,13 +32729,14 @@ cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32546,13 +32760,14 @@ cp_parser_omp_clause_thread_limit (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32577,7 +32792,8 @@ cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
tree nlist, c, alignment = NULL_TREE;
bool colon;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALIGNED, list,
@@ -32587,7 +32803,7 @@ cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
{
alignment = cp_parser_constant_expression (parser);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32618,7 +32834,8 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
bool colon;
enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
if (!is_cilk_simd_fn
@@ -32648,7 +32865,7 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
colon = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
if (colon)
cp_parser_require (parser, CPP_COLON, RT_COLON);
- else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ else if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32686,7 +32903,7 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
sorry ("using parameters for %<linear%> step is not supported yet");
step = integer_one_node;
}
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32713,13 +32930,14 @@ cp_parser_omp_clause_safelen (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_constant_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32742,13 +32960,14 @@ cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_constant_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -32864,7 +33083,8 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
tree nlist, c;
enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -32896,7 +33116,7 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
OMP_CLAUSE_DEPEND_KIND (c) = kind;
OMP_CLAUSE_DECL (c) = NULL_TREE;
OMP_CLAUSE_CHAIN (c) = list;
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -33027,13 +33247,14 @@ cp_parser_omp_clause_device (cp_parser *parser, tree list,
{
tree t, c;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -33058,7 +33279,8 @@ cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
{
tree c, t;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return list;
c = build_omp_clause (location, OMP_CLAUSE_DIST_SCHEDULE);
@@ -33077,7 +33299,7 @@ cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
goto resync_fail;
OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
goto resync_fail;
}
else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
@@ -33163,11 +33385,12 @@ cp_parser_oacc_clause_async (cp_parser *parser, tree list)
if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
{
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
t = cp_parser_expression (parser);
if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -34217,12 +34440,13 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
- cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.consume_open (parser);
name = cp_parser_identifier (parser);
if (name == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -34720,7 +34944,8 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
}
loc = cp_lexer_consume_token (parser->lexer)->location;
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return NULL;
init = orig_init = decl = real_decl = NULL;
@@ -34852,7 +35077,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
protected_set_expr_location (incr, input_location);
}
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/true);
@@ -35211,7 +35436,8 @@ cp_parser_omp_sections_scope (cp_parser *parser)
bool error_suppress = false;
cp_token *tok;
- if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+ matching_braces braces;
+ if (!braces.require_open (parser))
return NULL_TREE;
stmt = push_stmt_list ();
@@ -35248,7 +35474,7 @@ cp_parser_omp_sections_scope (cp_parser *parser)
substmt = build1 (OMP_SECTION, void_type_node, substmt);
add_stmt (substmt);
}
- cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ braces.require_close (parser);
substmt = pop_stmt_list (stmt);
@@ -37110,7 +37336,8 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
if (strcmp (p, "initializer") == 0)
{
cp_lexer_consume_token (parser->lexer);
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return false;
p = "";
@@ -37201,12 +37428,13 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
if (ctor)
add_decl_expr (omp_orig);
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
return false;
}
if (!cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
- cp_parser_required_error (parser, RT_PRAGMA_EOL, /*keyword=*/false);
+ cp_parser_required_error (parser, RT_PRAGMA_EOL, /*keyword=*/false,
+ UNKNOWN_LOCATION);
return true;
}
@@ -37634,7 +37862,8 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
/* Look for optional '( name )'. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
- cp_lexer_consume_token (parser->lexer); /* '(' */
+ matching_parens parens;
+ parens.consume_open (parser); /* '(' */
/* We parse the name as an id-expression. If it resolves to
anything other than a non-overloaded function at namespace
@@ -37651,7 +37880,7 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, name_loc);
if (decl == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ || !parens.require_close (parser))
{
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
parser->oacc_routine = NULL;
@@ -38083,12 +38312,13 @@ cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
if (!noex || !noex_expr
|| cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
{
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ matching_parens parens;
+ parens.require_open (parser);
expr = cp_parser_expression (parser);
expr = finish_parenthesized_expr (expr);
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ parens.require_close (parser);
}
else
{
@@ -38676,7 +38906,8 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
check_no_duplicate_clause (clauses, OMP_CLAUSE_SIMDLEN, "vectorlength",
loc);
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ matching_parens parens;
+ if (!parens.require_open (parser))
return error_mark_node;
expr = cp_parser_constant_expression (parser);
@@ -38713,7 +38944,7 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
}
}
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ if (!parens.require_close (parser))
return error_mark_node;
return clauses;
}
new file mode 100644
@@ -0,0 +1,33 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+/* Verify that the C/C++ frontends show the pertinent opening symbol when
+ a closing symbol is missing. */
+
+/* Verify that, when they are on the same line, that the opening symbol is
+ shown as a secondary range within the main diagnostic. */
+
+void test_static_assert_same_line (void)
+{
+ _Static_assert(sizeof(int) >= sizeof(char), "msg"; /* { dg-error "expected '\\)' before ';' token" } */
+ /* { dg-begin-multiline-output "" }
+ _Static_assert(sizeof(int) >= sizeof(char), "msg";
+ ~ ^
+ { dg-end-multiline-output "" } */
+}
+
+/* Verify that, when they are on different lines, that the opening symbol is
+ shown via a secondary diagnostic. */
+
+void test_static_assert_different_line (void)
+{
+ _Static_assert(sizeof(int) >= sizeof(char), /* { dg-message "to match this '\\('" } */
+ "msg"; /* { dg-error "expected '\\)' before ';' token" } */
+ /* { dg-begin-multiline-output "" }
+ "msg";
+ ^
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ _Static_assert(sizeof(int) >= sizeof(char),
+ ^
+ { dg-end-multiline-output "" } */
+}
new file mode 100644
@@ -0,0 +1,50 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+extern int foo (void);
+extern int bar (void);
+
+int missing_close_paren_in_switch (int i)
+{
+ switch (i /* { dg-message "10: to match this '\\('" } */
+ { /* { dg-error "5: expected '\\)' before '.' token" } */
+ /* { dg-begin-multiline-output "" }
+ {
+ ^
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ switch (i
+ ^
+ { dg-end-multiline-output "" } */
+
+ case 0:
+ return 5;
+ default:
+ return i;
+ }
+} /* { dg-error "1: expected" } */
+ /* { dg-begin-multiline-output "" }
+ }
+ ^
+ { dg-end-multiline-output "" } */
+
+void missing_close_paren_in_if (void)
+{
+ if (foo () /* { dg-line start_of_if } */
+ && bar ()
+ { /* { dg-error "5: expected '\\)' before '.' token" } */
+ /* { dg-begin-multiline-output "" }
+ {
+ ^
+ { dg-end-multiline-output "" } */
+ /* { dg-message "6: to match this '\\('" "" { target *-*-* } start_of_if } */
+ /* { dg-begin-multiline-output "" }
+ if (foo ()
+ ^
+ { dg-end-multiline-output "" } */
+ }
+
+} /* { dg-error "1: expected" } */
+ /* { dg-begin-multiline-output "" }
+ }
+ ^
+ { dg-end-multiline-output "" } */
new file mode 100644
@@ -0,0 +1,3 @@
+extern "C" { /* { dg-message "12: to match this '.'" } */
+
+void test (void); /* { dg-error "17: expected '.' at end of input" } */
new file mode 100644
@@ -0,0 +1,3 @@
+void test (void)
+{ /* { dg-message "1: to match this '.'" } */
+ int filler; /* { dg-error "13: expected '.' at end of input" } */
new file mode 100644
@@ -0,0 +1,2 @@
+namespace unclosed { /* { dg-message "20: to match this '.'" } */
+int filler; /* { dg-error "11: expected '.' at end of input" } */
new file mode 100644
@@ -0,0 +1,3 @@
+struct unclosed { /* { dg-message "17: to match this '.'" } */
+ int dummy; /* { dg-error "12: expected '.' at end of input" } */
+ // { dg-error "expected unqualified-id at end of input" "" { target *-*-* } .-1 }
@@ -4,5 +4,5 @@
// does not.
int f(int x,
#pragma interface // { dg-error "not allowed here" }
- // The parser gets confused and issues an error on the next line.
- int y); // { dg-bogus "" "" { xfail *-*-* } }
+ // { dg-bogus "expected identifier" "" { xfail *-*-* } .-1 }
+ int y);
new file mode 100644
@@ -0,0 +1,3 @@
+int unclosed[] = { /* { dg-message "18: to match this '.'" } */
+ 42
+ /* { dg-error "0: expected '.' at end of input" } */