Patchwork Support dumping type bindings and 'mutable' qualifier in lambda diagnostics.

login
register
mail settings
Submitter Adam Butcher
Date Aug. 28, 2013, 12:54 a.m.
Message ID <1377651279-30425-1-git-send-email-adam@jessamine.co.uk>
Download mbox | patch
Permalink /patch/270418/
State New
Headers show

Comments

Adam Butcher - Aug. 28, 2013, 12:54 a.m.
* error.c (dump_function_decl): Use standard diagnostic flow to dump a
	lambda diagnostic, albeit without stating the function name or
	duplicating the parameter spec (which is dumped as part of the type).
	Rather than qualifying the diagnostic with 'const' for plain lambdas,
	qualify with 'mutable' if non-const.
---
Okay to commit?
---
 gcc/cp/error.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)
Gabriel Dos Reis - Aug. 28, 2013, 12:53 p.m.
On Tue, Aug 27, 2013 at 7:54 PM, Adam Butcher <adam@jessamine.co.uk> wrote:
>         * error.c (dump_function_decl): Use standard diagnostic flow to dump a
>         lambda diagnostic, albeit without stating the function name or
>         duplicating the parameter spec (which is dumped as part of the type).
>         Rather than qualifying the diagnostic with 'const' for plain lambdas,
>         qualify with 'mutable' if non-const.
> ---
> Okay to commit?

This looks good to me.  I have one suggestion.  See below.

> ---
>  gcc/cp/error.c | 27 +++++++++++++++------------
>  1 file changed, 15 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/cp/error.c b/gcc/cp/error.c
> index c82a0ce..a8ca269 100644
> --- a/gcc/cp/error.c
> +++ b/gcc/cp/error.c
> @@ -1380,14 +1380,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
>    int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
>    tree exceptions;
>    vec<tree, va_gc> *typenames = NULL;
> -
> -  if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
> -    {
> -      /* A lambda's signature is essentially its "type", so defer.  */
> -      gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t)));
> -      dump_type (pp, DECL_CONTEXT (t), flags);
> -      return;
> -    }
> +  bool lambda_p = false;
>
>    flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
>    if (TREE_CODE (t) == TEMPLATE_DECL)
> @@ -1449,21 +1442,31 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
>    else if (cname)
>      {
>        dump_type (pp, cname, flags);
> -      pp_cxx_colon_colon (pp);
> +      if (LAMBDA_TYPE_P (cname))
> +       lambda_p = true;

Instead of introducing the local variable lambda_p and then
weave your way through the existing maze, do this instead:
    (1)  Introduce a new function, call it dump_lambda_expr
          (or something like that) that does only the formatting
          of a lambda expression, and nothing else.

   (2) when you arrive here where you test LAMBDA_TYPE_P
        then do a
            return dump_lambda_expr (pp, flags);

The result is much simpler and cleaner that way.
Thanks,

> +      else
> +       pp_cxx_colon_colon (pp);
>      }
>    else
>      dump_scope (pp, CP_DECL_CONTEXT (t), flags);
>
> -  dump_function_name (pp, t, flags);
> +  /* A lambda's signature is essentially its "type", which has already been
> +     dumped.  */
> +  if (!lambda_p)
> +    dump_function_name (pp, t, flags);
>
>    if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
>      {
> -      dump_parameters (pp, parmtypes, flags);
> +      if (!lambda_p)
> +       dump_parameters (pp, parmtypes, flags);
>
>        if (TREE_CODE (fntype) == METHOD_TYPE)
>         {
>           pp->padding = pp_before;
> -         pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
> +         if (!lambda_p)
> +           pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
> +         else if (!(TYPE_QUALS (class_of_this_parm (fntype)) & TYPE_QUAL_CONST))
> +           pp_c_ws_string (pp, "mutable");
>           dump_ref_qualifier (pp, fntype, flags);
>         }
>
> --
> 1.8.4
>

Patch

diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index c82a0ce..a8ca269 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1380,14 +1380,7 @@  dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
   tree exceptions;
   vec<tree, va_gc> *typenames = NULL;
-
-  if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
-    {
-      /* A lambda's signature is essentially its "type", so defer.  */
-      gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t)));
-      dump_type (pp, DECL_CONTEXT (t), flags);
-      return;
-    }
+  bool lambda_p = false;
 
   flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
   if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -1449,21 +1442,31 @@  dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   else if (cname)
     {
       dump_type (pp, cname, flags);
-      pp_cxx_colon_colon (pp);
+      if (LAMBDA_TYPE_P (cname))
+	lambda_p = true;
+      else
+	pp_cxx_colon_colon (pp);
     }
   else
     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
 
-  dump_function_name (pp, t, flags);
+  /* A lambda's signature is essentially its "type", which has already been
+     dumped.  */
+  if (!lambda_p)
+    dump_function_name (pp, t, flags);
 
   if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
     {
-      dump_parameters (pp, parmtypes, flags);
+      if (!lambda_p)
+	dump_parameters (pp, parmtypes, flags);
 
       if (TREE_CODE (fntype) == METHOD_TYPE)
 	{
 	  pp->padding = pp_before;
-	  pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
+	  if (!lambda_p)
+	    pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
+	  else if (!(TYPE_QUALS (class_of_this_parm (fntype)) & TYPE_QUAL_CONST))
+	    pp_c_ws_string (pp, "mutable");
 	  dump_ref_qualifier (pp, fntype, flags);
 	}