> 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 } } */

Reply via email to