static void c_parser_initelt (c_parser *, struct obstack *);
static void c_parser_initval (c_parser *, struct c_expr *,
struct obstack *);
-static tree c_parser_compound_statement (c_parser *);
-static void c_parser_compound_statement_nostart (c_parser *);
+static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
+static location_t c_parser_compound_statement_nostart (c_parser *);
static void c_parser_label (c_parser *);
static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
static void c_parser_statement_after_labels (c_parser *, bool *,
static void c_parser_objc_at_dynamic_declaration (c_parser *);
static bool c_parser_objc_diagnose_bad_element_prefix
(c_parser *, struct c_declspecs *);
-
-static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass);
+static location_t c_parser_parse_rtl_body (c_parser *, char *);
/* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
= c_parser_peek_token (parser)->location;
+ location_t endloc;
/* If the definition was marked with __RTL, use the RTL parser now,
consuming the function body. */
if (specs->declspec_il == cdil_rtl)
{
- c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
+ endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
/* Normally, store_parm_decls sets next_is_function_body,
anticipating a function body. We need a push_scope/pop_scope
push_scope ();
pop_scope ();
- finish_function ();
+ finish_function (endloc);
return;
}
/* If the definition was marked with __GIMPLE then parse the
specs->declspec_il,
specs->entry_bb_count);
in_late_binary_op = saved;
+ struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl);
+ endloc = fun->function_start_locus;
}
else
- fnbody = c_parser_compound_statement (parser);
+ fnbody = c_parser_compound_statement (parser, &endloc);
tree fndecl = current_function_decl;
if (nested)
{
by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
DECL_STATIC_CHAIN (decl) = 1;
add_stmt (fnbody);
- finish_function ();
+ finish_function (endloc);
c_pop_function_context ();
add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
}
{
if (fnbody)
add_stmt (fnbody);
- finish_function ();
+ finish_function (endloc);
}
/* Get rid of the empty stmt list for GIMPLE/RTL. */
if (specs->declspec_il != cdil_none)
cancellation-point-directive */
static tree
-c_parser_compound_statement (c_parser *parser)
+c_parser_compound_statement (c_parser *parser, location_t *endlocp)
{
tree stmt;
location_t brace_loc;
return error_mark_node;
}
stmt = c_begin_compound_stmt (true);
- c_parser_compound_statement_nostart (parser);
+ location_t end_loc = c_parser_compound_statement_nostart (parser);
+ if (endlocp)
+ *endlocp = end_loc;
return c_end_compound_stmt (brace_loc, stmt, true);
}
used for parsing both compound statements and statement expressions
(which follow different paths to handling the opening). */
-static void
+static location_t
c_parser_compound_statement_nostart (c_parser *parser)
{
bool last_stmt = false;
location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
- add_debug_begin_stmt (c_parser_peek_token (parser)->location);
+ location_t endloc = c_parser_peek_token (parser)->location;
+ add_debug_begin_stmt (endloc);
c_parser_consume_token (parser);
- return;
+ return endloc;
}
mark_valid_location_for_stdc_pragma (true);
if (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
+ location_t endloc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
- return;
+ return endloc;
}
while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
{
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
- return;
+ return c_parser_peek_token (parser)->location;
}
else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
{
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
error_at (loc, "expected %<}%> before %<else%>");
- return;
+ return c_parser_peek_token (parser)->location;
}
else
{
}
if (last_label)
error_at (label_loc, "label at end of compound statement");
+ location_t endloc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
/* Restore the value we started with. */
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
+ return endloc;
}
/* Parse all consecutive labels, possibly preceded by standard
Take ownership of START_WITH_PASS, if non-NULL. */
-void
+location_t
c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
{
if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
{
free (start_with_pass);
- return;
+ return c_parser_peek_token (parser)->location;
}
location_t start_loc = c_parser_peek_token (parser)->location;
case CPP_EOF:
error_at (start_loc, "no closing brace");
free (start_with_pass);
- return;
+ return c_parser_peek_token (parser)->location;
default:
break;
}
if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
{
free (start_with_pass);
- return;
+ return end_loc;
}
/* Run the backend on the cfun created above, transferring ownership of
START_WITH_PASS. */
run_rtl_passes (start_with_pass);
+ return end_loc;
}
#include "gt-c-c-parser.h"