This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: printing types in a more logical way


Hiya,

here is the patch that makes gcc print types as discussed yesterday.

The background/motivation for change is summarized below:

* Warning and error messages from gcc is looked upon as a 'standard'
  for type writing style by many starting programmers.  GCC should
  indeed use a format for the printing of types that the C++ gurus
  can vouch for.

* This patch makes two changes in how types are printed.

  1) The pointer qualifier `*' and the reference qualifier `&'
     are put to the left -- this to avoid confusing them
     with operator*() and operator&().
     I think that this is a commonly accepted style among
     C++ gurus.  It is among others the coding style that is
     used by the Cygnus stdc++ library team, see point 01. at
     http://sourceware.cygnus.com/libstdc++/17_intro/C++STYLE

  2) Put the qualifiers `const', `volatile' and `__restrict'
     to the right of the type they `operate' on.
     The reasoning behind this is that it makes all qualifiers
     equal: they ALL work on EVERYTHING on the left of them.
     The order of these qualifiers was changed also, instead
     of printing "const volatile __restrict int", we would
     now print "int __restrict volatile const".

A Real Life example that point 2) is less confusing can be found
in the error messages of gcc-2.96:

test.cc: In function `void foo (const T &) [with T = const int *]':

Seems to imply, at first sight, something like foo(const const int *&).

With this patch (and most notable point 2) above), this error message
becomes:

test.cc: In function `void foo (T const&) [with T = int const*]':

which gives after a direct 'string' replacement of `T' the correct
notation of the actual type: int const* const&.

Please let me know if there is anything I can do to improve this patch!

Thanks,

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

PS Here are a few examples of types that I tested (using 2.96 + patch)

    int volatile const
    int const** const
    int const* const** const***
    int const (* const) ()
    int const (** const) ()
    int const& (* const&) ()
    A<int>
    A<int const&> 
    A<int const& (* const& const) ()>
    int volatile (A<signed char>::*) () const

  Bonus question: How did I succeed in letting it print the
  A<int const& (* const& const) ()>?  in some error message? }:-)

Index: gcc/cp/error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.94
diff -u -d -p -c -3 -p -r1.94 error.c
*** error.c	1999/09/29 17:24:18	1.94
--- error.c	1999/10/30 19:49:45
*************** dump_qualifiers (t, p)
*** 185,193 ****
       enum pad p;
  {
    static const int masks[] =
!     {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
    static const char *const names[] =
!     {"const", "volatile", "__restrict"};
    int ix;
    int quals = TYPE_QUALS (t);
    int do_after = p == after;
--- 185,193 ----
       enum pad p;
  {
    static const int masks[] =
!     {TYPE_QUAL_RESTRICT, TYPE_QUAL_VOLATILE, TYPE_QUAL_CONST};
    static const char *const names[] =
!     {"__restrict", "volatile", "const"};
    int ix;
    int quals = TYPE_QUALS (t);
    int do_after = p == after;
*************** dump_type (t, flags)
*** 396,402 ****
      case BOOLEAN_TYPE:
        {
  	tree type;
- 	dump_qualifiers (t, after);
  	type = flags & TS_CHASE_TYPEDEFS ? TYPE_MAIN_VARIANT (t) : t;
  	if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
  	  OB_PUTID (TYPE_IDENTIFIER (type));
--- 396,401 ----
*************** dump_type (t, flags)
*** 405,410 ****
--- 404,410 ----
  	     These don't come up in user error messages, but it's nice
  	     to be able to print them from the debugger.  */
  	  OB_PUTS ("{anonymous}");
+ 	dump_qualifiers (t, before);
        }
        break;
  
*************** dump_type (t, flags)
*** 428,438 ****
        break;
  
      case TEMPLATE_TYPE_PARM:
-       dump_qualifiers (t, after);
        if (TYPE_IDENTIFIER (t))
  	OB_PUTID (TYPE_IDENTIFIER (t));
        else
  	OB_PUTS ("{anonymous template type parameter}");
        break;
  
        /* This is not always necessary for pointers and such, but doing this
--- 428,438 ----
        break;
  
      case TEMPLATE_TYPE_PARM:
        if (TYPE_IDENTIFIER (t))
  	OB_PUTID (TYPE_IDENTIFIER (t));
        else
  	OB_PUTS ("{anonymous template type parameter}");
+       dump_qualifiers (t, before);
        break;
  
        /* This is not always necessary for pointers and such, but doing this
*************** dump_type_prefix (t, flags)
*** 595,606 ****
  	   so let the OFFSET_TYPE case handle it.  */
  	if (!TYPE_PTRMEM_P (t))
  	  {
- 	    if (padding != none)
- 	      OB_PUTC (' ');
  	    if (TREE_CODE (sub) == ARRAY_TYPE)
  	      OB_PUTC ('(');
              OB_PUTC ("&*"[TREE_CODE (t) == POINTER_TYPE]);
! 	    padding = dump_qualifiers (t, none);
  	  }
        }
        break;
--- 595,607 ----
  	   so let the OFFSET_TYPE case handle it.  */
  	if (!TYPE_PTRMEM_P (t))
  	  {
  	    if (TREE_CODE (sub) == ARRAY_TYPE)
+ 	    {
+ 	      OB_PUTC (' ');
  	      OB_PUTC ('(');
+ 	    }
              OB_PUTC ("&*"[TREE_CODE (t) == POINTER_TYPE]);
! 	    padding = dump_qualifiers (t, before);
  	  }
        }
        break;
*************** dump_type_prefix (t, flags)
*** 623,638 ****
           correct if FUNCTION_DECLs used it.  */
      case FUNCTION_TYPE:
        padding = dump_type_prefix (TREE_TYPE (t), flags);
!       if (padding != none)
!         OB_PUTC (' ');
        OB_PUTC ('(');
        padding = none;
        break;
  
      case METHOD_TYPE:
        padding = dump_type_prefix (TREE_TYPE (t), flags);
!       if (padding != none)
!         OB_PUTC (' ');
        OB_PUTC ('(');
        padding = none;
        dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
--- 624,637 ----
           correct if FUNCTION_DECLs used it.  */
      case FUNCTION_TYPE:
        padding = dump_type_prefix (TREE_TYPE (t), flags);
!       OB_PUTC (' ');
        OB_PUTC ('(');
        padding = none;
        break;
  
      case METHOD_TYPE:
        padding = dump_type_prefix (TREE_TYPE (t), flags);
!       OB_PUTC (' ');
        OB_PUTC ('(');
        padding = none;
        dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]