This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: printing types in a more logical way
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: printing types in a more logical way
- From: Carlo Wood <carlo at runaway dot xs4all dot nl>
- Date: Sat, 30 Oct 1999 22:23:39 +0200 (CEST)
- Cc: martin at mira dot isdn dot cs dot tu-berlin dot de
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);