> The problem is that the logic in c_parser_declaration_or_fndef for setting
> DECL_ARGUMENTS (not previously meaningful in non-definition declarations
> at all), as introduced by
>
> r253411 | dmalcolm | 2017-10-04 14:10:59 +0000 (Wed, 04 Oct 2017) | 85 lines
>
> C: underline parameters in mismatching function calls
>
> (and subsequently changed by r268574, but that change isn't relevant here)
> is incorrect.
As a matter of fact, this logic helped -fdump-ada-spec too by making the name
of the parameters available in non-definition declarations.
> Rather than checking if the outermost declarator is
> cdk_function and using its parameters if so, it's necessary to check if
> the *innermost declarator that isn't cdk_id or cdk_attrs* is cdk_function
> and use its parameters if so, as that's what actually determines if the
> declarator for the entity being declared has the form of a function
> declarator (see how grokdeclarator determines funcdef_syntax).
Thanks for the hint. Tentative patch attached based on it, which certainly
makes -fdump-ada-spec happy, as witnessed by the dump-ada-spec-15.c change.
Is it something that you would approve for mainline?
c/
* c-parser.c (c_parser_declaration_or_fndef): Set DECL_ARGUMENTS of a
FUNCTION_DECL to the right value in the presence of nested declarators.
testsuite/
* c-c++-common/dump-ada-spec-15.c: Check that the parameters are named.
--
Eric Botcazou
Index: c/c-parser.c
===================================================================
--- c/c-parser.c (revision 274744)
+++ c/c-parser.c (working copy)
@@ -2161,10 +2161,40 @@ c_parser_declaration_or_fndef (c_parser *parser, b
all_prefix_attrs));
if (d
&& TREE_CODE (d) == FUNCTION_DECL
- && declarator->kind == cdk_function
&& DECL_ARGUMENTS (d) == NULL_TREE
&& DECL_INITIAL (d) == NULL_TREE)
- DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
+ {
+ /* Check if the innermost declarator that isn't cdk_id or
+ cdk_attrs is cdk_function. */
+ const struct c_declarator *decl = declarator;
+ const struct c_declarator *last_non_id_attrs = NULL;
+
+ while (decl)
+ switch (decl->kind)
+ {
+ case cdk_array:
+ case cdk_function:
+ case cdk_pointer:
+ last_non_id_attrs = decl;
+ decl = decl->declarator;
+ break;
+
+ case cdk_attrs:
+ decl = decl->declarator;
+ break;
+
+ case cdk_id:
+ decl = 0;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ /* If so, use its parameters for the function. */
+ if (last_non_id_attrs
+ && last_non_id_attrs->kind == cdk_function)
+ DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms;
+ }
if (omp_declare_simd_clauses.exists ())
{
tree parms = NULL_TREE;
Index: testsuite/c-c++-common/dump-ada-spec-15.c
===================================================================
--- testsuite/c-c++-common/dump-ada-spec-15.c (revision 274794)
+++ testsuite/c-c++-common/dump-ada-spec-15.c (working copy)
@@ -3,4 +3,6 @@
extern void (*signal (int __sig, void (*__handler)(int)))(int);
+/* { dg-final { scan-ada-spec "uu_sig" } } */
+/* { dg-final { scan-ada-spec "uu_handler" } } */
/* { dg-final { cleanup-ada-spec } } */