aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r--gcc/c/c-parser.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index a36397b..1a5e39e 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -206,6 +206,9 @@ struct GTY(()) c_parser {
/* Buffer to hold all the tokens from parsing the vector attribute for the
SIMD-enabled functions (formerly known as elemental functions). */
vec <c_token, va_gc> *cilk_simd_fn_tokens;
+
+ /* Location of the last consumed token. */
+ location_t last_token_location;
};
/* Return a pointer to the Nth token in PARSERs tokens_buf. */
@@ -770,6 +773,7 @@ c_parser_consume_token (c_parser *parser)
gcc_assert (parser->tokens[0].type != CPP_EOF);
gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
+ parser->last_token_location = parser->tokens[0].location;
if (parser->tokens != &parser->tokens_buf[0])
parser->tokens++;
else if (parser->tokens_avail == 2)
@@ -2120,6 +2124,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
tree d = start_decl (declarator, specs, false,
chainon (postfix_attrs,
all_prefix_attrs));
+ if (d && TREE_CODE (d) == FUNCTION_DECL)
+ if (declarator->kind == cdk_function)
+ if (DECL_ARGUMENTS (d) == NULL_TREE)
+ DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
if (omp_declare_simd_clauses.exists ()
|| !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
{
@@ -4039,6 +4047,9 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
c_parser_skip_to_end_of_parameter (parser);
return NULL;
}
+
+ location_t start_loc = c_parser_peek_token (parser)->location;
+
specs = build_null_declspecs ();
if (attrs)
{
@@ -4061,8 +4072,33 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
}
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
postfix_attrs = c_parser_attributes (parser);
+
+ /* Generate a location for the parameter, ranging from the start of the
+ initial token to the end of the final token.
+
+ If we have a identifier, then use it for the caret location, e.g.
+
+ extern int callee (int one, int (*two)(int, int), float three);
+ ~~~~~~^~~~~~~~~~~~~~
+
+ otherwise, reuse the start location for the caret location e.g.:
+
+ extern int callee (int one, int (*)(int, int), float three);
+ ^~~~~~~~~~~~~~~~~
+ */
+ location_t end_loc = parser->last_token_location;
+
+ /* Find any cdk_id declarator; determine if we have an identifier. */
+ c_declarator *id_declarator = declarator;
+ while (id_declarator && id_declarator->kind != cdk_id)
+ id_declarator = id_declarator->declarator;
+ location_t caret_loc = (id_declarator->u.id
+ ? id_declarator->id_loc
+ : start_loc);
+ location_t param_loc = make_location (caret_loc, start_loc, end_loc);
+
return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
- declarator);
+ declarator, param_loc);
}
/* Parse a string literal in an asm expression. It should not be