summaryrefslogtreecommitdiff
path: root/contrib/gcc/cp/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/error.c')
-rw-r--r--contrib/gcc/cp/error.c816
1 files changed, 648 insertions, 168 deletions
diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c
index 4eb196e3add5..bb21bcb5021c 100644
--- a/contrib/gcc/cp/error.c
+++ b/contrib/gcc/cp/error.c
@@ -1,6 +1,6 @@
/* Call-backs for C++ error reporting.
This code is non-reentrant.
- Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -20,10 +20,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
+#include "system.h"
#include "tree.h"
#include "cp-tree.h"
#include "obstack.h"
-#include <ctype.h>
+#include "toplev.h"
typedef char* cp_printer ();
@@ -34,21 +35,22 @@ typedef char* cp_printer ();
#define L language_as_string
#define O op_as_string
#define P parm_as_string
+#define Q assop_as_string
#define T type_as_string
#define V cv_as_string
-#define _ (cp_printer *) 0
+#define o (cp_printer *) 0
cp_printer * cp_printers[256] =
-{
+{
/*0 1 2 3 4 5 6 7 8 9 A B C D E F */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */
- _, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */
- P, _, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */
- _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */
+ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */
+ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
+ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
+ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
+ o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */
+ P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
+ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
+ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
};
#undef C
#undef D
@@ -56,9 +58,10 @@ cp_printer * cp_printers[256] =
#undef L
#undef O
#undef P
+#undef Q
#undef T
#undef V
-#undef _
+#undef o
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
@@ -77,16 +80,32 @@ static char *scratch_firstobj;
IDENTIFIER_LENGTH (ID)))
# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
-# define OB_PUTI(CST) do { sprintf (digit_buffer, "%d", (CST)); \
+# define OB_PUTI(CST) do { sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(CST)); \
OB_PUTCP (digit_buffer); } while (0)
# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));
# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
-static void dump_type (), dump_decl (), dump_function_decl ();
-static void dump_expr (), dump_unary_op (), dump_binary_op ();
-static void dump_aggr_type (), dump_type_prefix (), dump_type_suffix ();
-static void dump_function_name ();
+enum pad { none, before, after };
+
+static void dump_type PROTO((tree, int));
+static void dump_type_real PROTO((tree, int, int));
+static void dump_simple_decl PROTO((tree, tree, int));
+static void dump_decl PROTO((tree, int));
+static void dump_function_decl PROTO((tree, int));
+static void dump_expr PROTO((tree, int));
+static void dump_unary_op PROTO((char *, tree, int));
+static void dump_binary_op PROTO((char *, tree));
+static void dump_aggr_type PROTO((tree, int, int));
+static void dump_type_prefix PROTO((tree, int, int));
+static void dump_type_suffix PROTO((tree, int, int));
+static void dump_function_name PROTO((tree));
+static void dump_expr_list PROTO((tree));
+static void dump_global_iord PROTO((tree));
+static void dump_readonly_or_volatile PROTO((tree, enum pad));
+static void dump_char PROTO((int));
+static char *aggr_variety PROTO((tree));
+static tree ident_fndecl PROTO((tree));
void
init_error ()
@@ -95,8 +114,6 @@ init_error ()
scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
}
-enum pad { none, before, after };
-
static void
dump_readonly_or_volatile (t, p)
tree t;
@@ -119,11 +136,13 @@ dump_readonly_or_volatile (t, p)
value. */
static char digit_buffer[128];
-/* Dump into the obstack a human-readable equivalent of TYPE. */
+/* Dump into the obstack a human-readable equivalent of TYPE. */
+
static void
-dump_type (t, v)
+dump_type_real (t, v, canonical_name)
tree t;
int v; /* verbose? */
+ int canonical_name;
{
if (t == NULL_TREE)
return;
@@ -145,19 +164,19 @@ dump_type (t, v)
/* i.e. function taking no arguments */
if (t != void_list_node)
{
- dump_type (TREE_VALUE (t), v);
+ dump_type_real (TREE_VALUE (t), v, canonical_name);
/* Can this happen other than for default arguments? */
if (TREE_PURPOSE (t) && v)
{
OB_PUTS (" = ");
- dump_expr (TREE_PURPOSE (t));
+ dump_expr (TREE_PURPOSE (t), 0);
}
if (TREE_CHAIN (t))
{
if (TREE_CHAIN (t) != void_list_node)
{
OB_PUTC2 (',', ' ');
- dump_type (TREE_CHAIN (t), v);
+ dump_type_real (TREE_CHAIN (t), v, canonical_name);
}
}
else OB_PUTS (" ...");
@@ -169,7 +188,7 @@ dump_type (t, v)
break;
case TREE_VEC:
- dump_type (BINFO_TYPE (t), v);
+ dump_type_real (BINFO_TYPE (t), v, canonical_name);
break;
case RECORD_TYPE:
@@ -179,21 +198,27 @@ dump_type (t, v)
&& (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
{
if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
- dump_readonly_or_volatile (t);
- dump_type (SIGNATURE_TYPE (t), v);
+ dump_readonly_or_volatile (t, after);
+ dump_type_real (SIGNATURE_TYPE (t), v, canonical_name);
if (IS_SIGNATURE_POINTER (t))
OB_PUTC ('*');
else
OB_PUTC ('&');
}
else
- dump_aggr_type (t, v);
+ dump_aggr_type (t, v, canonical_name);
break;
case TYPE_DECL:
+ case TEMPLATE_DECL:
dump_decl (t, v);
break;
+ case COMPLEX_TYPE:
+ OB_PUTS ("complex ");
+ dump_type_real (TREE_TYPE (t), v, canonical_name);
+ break;
+
case INTEGER_TYPE:
if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
OB_PUTS ("unsigned ");
@@ -204,17 +229,56 @@ dump_type (t, v)
case REAL_TYPE:
case VOID_TYPE:
case BOOLEAN_TYPE:
- dump_readonly_or_volatile (t, after);
- OB_PUTID (TYPE_IDENTIFIER (t));
+ {
+ tree type;
+ dump_readonly_or_volatile (t, after);
+ type = canonical_name ? TYPE_MAIN_VARIANT (t) : t;
+ if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
+ OB_PUTID (TYPE_IDENTIFIER (type));
+ else
+ /* Types like intQI_type_node and friends have no names.
+ 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}");
+ }
break;
- case TEMPLATE_TYPE_PARM:
- OB_PUTID (TYPE_IDENTIFIER (t));
+ case TEMPLATE_TEMPLATE_PARM:
+ if (!CLASSTYPE_TEMPLATE_INFO (t))
+ {
+ /* For parameters inside template signature. */
+ if (TYPE_IDENTIFIER (t))
+ OB_PUTID (TYPE_IDENTIFIER (t));
+ else
+ OB_PUTS ("{anonymous template template parm}");
+ }
+ else
+ {
+ int i;
+ tree args = CLASSTYPE_TI_ARGS (t);
+ OB_PUTID (TYPE_IDENTIFIER (t));
+ OB_PUTC ('<');
+ for (i = 0; i < TREE_VEC_LENGTH (args); i++)
+ {
+ tree arg = TREE_VEC_ELT (args, i);
+ if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
+ || TREE_CODE (arg) == TEMPLATE_DECL)
+ dump_type_real (arg, 0, canonical_name);
+ else
+ dump_expr (arg, 0);
+ if (i < TREE_VEC_LENGTH (args)-1)
+ OB_PUTC2 (',', ' ');
+ }
+ OB_PUTC ('>');
+ }
break;
- case UNINSTANTIATED_P_TYPE:
- OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));
- OB_PUTS ("<...>");
+ case TEMPLATE_TYPE_PARM:
+ dump_readonly_or_volatile (t, after);
+ if (TYPE_IDENTIFIER (t))
+ OB_PUTID (TYPE_IDENTIFIER (t));
+ else
+ OB_PUTS ("{anonymous template type parm}");
break;
/* This is not always necessary for pointers and such, but doing this
@@ -226,8 +290,15 @@ dump_type (t, v)
offset_type:
case FUNCTION_TYPE:
case METHOD_TYPE:
- dump_type_prefix (t, v);
- dump_type_suffix (t, v);
+ dump_type_prefix (t, v, canonical_name);
+ dump_type_suffix (t, v, canonical_name);
+ break;
+
+ case TYPENAME_TYPE:
+ OB_PUTS ("typename ");
+ dump_type_real (TYPE_CONTEXT (t), 0, canonical_name);
+ OB_PUTS ("::");
+ OB_PUTID (TYPE_IDENTIFIER (t));
break;
default:
@@ -252,12 +323,22 @@ aggr_variety (t)
return "struct";
}
-/* Print out a class declaration, in the form `class foo'. */
static void
-dump_aggr_type (t, v)
+dump_type (t, v)
tree t;
int v; /* verbose? */
{
+ dump_type_real (t, v, 0);
+}
+
+/* Print out a class declaration, in the form `class foo'. */
+
+static void
+dump_aggr_type (t, v, canonical_name)
+ tree t;
+ int v; /* verbose? */
+ int canonical_name;
+{
tree name;
char *variety = aggr_variety (t);
@@ -269,9 +350,9 @@ dump_aggr_type (t, v)
OB_PUTC (' ');
}
- name = TYPE_NAME (t);
+ name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t);
- if (name && DECL_CONTEXT (name))
+ if (name && DECL_CONTEXT (name) && DECL_CONTEXT (name) != global_namespace)
{
/* FUNCTION_DECL or RECORD_TYPE */
dump_decl (DECL_CONTEXT (name), 0);
@@ -308,9 +389,10 @@ dump_aggr_type (t, v)
int *[]&. */
static void
-dump_type_prefix (t, v)
+dump_type_prefix (t, v, canonical_name)
tree t;
int v; /* verbosity */
+ int canonical_name;
{
if (TYPE_PTRMEMFUNC_P (t))
{
@@ -324,7 +406,7 @@ dump_type_prefix (t, v)
{
tree sub = TREE_TYPE (t);
- dump_type_prefix (sub, v);
+ dump_type_prefix (sub, v, canonical_name);
/* A tree for a member pointer looks like pointer to offset,
so let the OFFSET_TYPE case handle it. */
if (TREE_CODE (sub) != OFFSET_TYPE)
@@ -358,7 +440,7 @@ dump_type_prefix (t, v)
case REFERENCE_TYPE:
{
tree sub = TREE_TYPE (t);
- dump_type_prefix (sub, v);
+ dump_type_prefix (sub, v, canonical_name);
switch (TREE_CODE (sub))
{
@@ -382,11 +464,11 @@ dump_type_prefix (t, v)
case OFFSET_TYPE:
offset_type:
- dump_type_prefix (TREE_TYPE (t), v);
+ dump_type_prefix (TREE_TYPE (t), v, canonical_name);
if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
{
OB_PUTC (' ');
- dump_type (TYPE_OFFSET_BASETYPE (t), 0);
+ dump_type_real (TYPE_OFFSET_BASETYPE (t), 0, canonical_name);
OB_PUTC2 (':', ':');
}
OB_PUTC ('*');
@@ -396,19 +478,19 @@ dump_type_prefix (t, v)
/* Can only be reached through function pointer -- this would not be
correct if FUNCTION_DECLs used it. */
case FUNCTION_TYPE:
- dump_type_prefix (TREE_TYPE (t), v);
+ dump_type_prefix (TREE_TYPE (t), v, canonical_name);
OB_PUTC2 (' ', '(');
break;
case METHOD_TYPE:
- dump_type_prefix (TREE_TYPE (t), v);
+ dump_type_prefix (TREE_TYPE (t), v, canonical_name);
OB_PUTC2 (' ', '(');
- dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0);
+ dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0, canonical_name);
OB_PUTC2 (':', ':');
break;
case ARRAY_TYPE:
- dump_type_prefix (TREE_TYPE (t), v);
+ dump_type_prefix (TREE_TYPE (t), v, canonical_name);
break;
case ENUMERAL_TYPE:
@@ -419,14 +501,16 @@ dump_type_prefix (t, v)
case REAL_TYPE:
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
- case UNINSTANTIATED_P_TYPE:
case UNION_TYPE:
case UNKNOWN_TYPE:
case VOID_TYPE:
- dump_type (t, v);
+ case TYPENAME_TYPE:
+ case COMPLEX_TYPE:
+ dump_type_real (t, v, canonical_name);
break;
default:
@@ -436,9 +520,10 @@ dump_type_prefix (t, v)
}
static void
-dump_type_suffix (t, v)
+dump_type_suffix (t, v, canonical_name)
tree t;
int v; /* verbose? */
+ int canonical_name;
{
if (TYPE_PTRMEMFUNC_P (t))
t = TYPE_PTRMEMFUNC_FN_TYPE (t);
@@ -450,7 +535,7 @@ dump_type_suffix (t, v)
case OFFSET_TYPE:
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
OB_PUTC (')');
- dump_type_suffix (TREE_TYPE (t), v);
+ dump_type_suffix (TREE_TYPE (t), v, canonical_name);
break;
/* Can only be reached through function pointer */
@@ -471,16 +556,25 @@ dump_type_suffix (t, v)
if (TREE_CODE (t) == METHOD_TYPE)
dump_readonly_or_volatile
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
- dump_type_suffix (TREE_TYPE (t), v);
+ dump_type_suffix (TREE_TYPE (t), v, canonical_name);
break;
}
case ARRAY_TYPE:
OB_PUTC ('[');
if (TYPE_DOMAIN (t))
- OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
+ {
+ if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
+ OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
+ else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
+ dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0);
+ else
+ dump_expr (fold (build_binary_op
+ (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
+ integer_one_node, 1)), 0);
+ }
OB_PUTC (']');
- dump_type_suffix (TREE_TYPE (t), v);
+ dump_type_suffix (TREE_TYPE (t), v, canonical_name);
break;
case ENUMERAL_TYPE:
@@ -491,13 +585,15 @@ dump_type_suffix (t, v)
case REAL_TYPE:
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
- case UNINSTANTIATED_P_TYPE:
case UNION_TYPE:
case UNKNOWN_TYPE:
case VOID_TYPE:
+ case TYPENAME_TYPE:
+ case COMPLEX_TYPE:
break;
default:
@@ -508,7 +604,8 @@ dump_type_suffix (t, v)
/* Return a function declaration which corresponds to the IDENTIFIER_NODE
argument. */
-tree
+
+static tree
ident_fndecl (t)
tree t;
{
@@ -538,9 +635,9 @@ ident_fndecl (t)
#endif
#define GLOBAL_IORD_P(NODE) \
- !strncmp(IDENTIFIER_POINTER(NODE),GLOBAL_THING,sizeof(GLOBAL_THING)-1)
+ ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
-void
+static void
dump_global_iord (t)
tree t;
{
@@ -560,6 +657,31 @@ dump_global_iord (t)
}
static void
+dump_simple_decl (t, type, v)
+ tree t;
+ tree type;
+ int v;
+{
+ if (v > 0)
+ {
+ dump_type_prefix (type, v, 0);
+ OB_PUTC (' ');
+ dump_readonly_or_volatile (t, after);
+ }
+ if (DECL_CLASS_SCOPE_P (t))
+ {
+ dump_type (DECL_CONTEXT (t), 0);
+ OB_PUTC2 (':', ':');
+ }
+ if (DECL_NAME (t))
+ dump_decl (DECL_NAME (t), v);
+ else
+ OB_PUTS ("{anon}");
+ if (v > 0)
+ dump_type_suffix (type, v, 0);
+}
+
+static void
dump_decl (t, v)
tree t;
int v; /* verbosity */
@@ -576,18 +698,20 @@ dump_decl (t, v)
case TYPE_DECL:
{
/* Don't say 'typedef class A' */
- tree type = TREE_TYPE (t);
- if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type))
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && type == TYPE_MAIN_VARIANT (type))
+ if (DECL_ARTIFICIAL (t))
{
- dump_type (type, v);
+ if (v > 0 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
+ /* Say `class T' not just `T'. */
+ OB_PUTS ("class ");
+
+ dump_type (TREE_TYPE (t), v);
break;
}
}
if (v > 0)
OB_PUTS ("typedef ");
- goto general;
+ dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
+ ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), v);
break;
case VAR_DECL:
@@ -600,32 +724,24 @@ dump_decl (t, v)
/* else fall through */
case FIELD_DECL:
case PARM_DECL:
- general:
- if (v > 0)
- {
- dump_type_prefix (TREE_TYPE (t), v);
- OB_PUTC (' ');
- dump_readonly_or_volatile (t, after);
- }
- /* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */
- if (DECL_CONTEXT (t)
- && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')
- {
- dump_type (DECL_CONTEXT (t), 0);
- OB_PUTC2 (':', ':');
- }
- if (DECL_NAME (t))
- dump_decl (DECL_NAME (t), v);
- else
- OB_PUTS ("{anon}");
- if (v > 0)
- dump_type_suffix (TREE_TYPE (t), v);
+ dump_simple_decl (t, TREE_TYPE (t), v);
break;
case NAMESPACE_DECL:
+ if (DECL_CONTEXT (t) != global_namespace)
+ {
+ dump_decl (DECL_CONTEXT (t), v);
+ OB_PUTC2 (':',':');
+ }
OB_PUTID (DECL_NAME (t));
break;
+ case SCOPE_REF:
+ dump_decl (TREE_OPERAND (t, 0), 0);
+ OB_PUTS ("::");
+ dump_decl (TREE_OPERAND (t, 1), 0);
+ break;
+
case ARRAY_REF:
dump_decl (TREE_OPERAND (t, 0), v);
OB_PUTC ('[');
@@ -646,7 +762,7 @@ dump_decl (t, v)
break;
/* These special cases are duplicated here so that other functions
- can feed identifiers to cp_error and get them demangled properly. */
+ can feed identifiers to cp_error and get them demangled properly. */
case IDENTIFIER_NODE:
{ tree f;
if (DESTRUCTOR_NAME_P (t)
@@ -677,45 +793,64 @@ dump_decl (t, v)
case FUNCTION_DECL:
if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
dump_global_iord (DECL_ASSEMBLER_NAME (t));
+ else if (! DECL_LANG_SPECIFIC (t))
+ OB_PUTS ("{internal}");
else
dump_function_decl (t, v);
break;
case TEMPLATE_DECL:
{
- tree args = DECL_TEMPLATE_PARMS (t);
- int i, len = args ? TREE_VEC_LENGTH (args) : 0;
- OB_PUTS ("template <");
- for (i = 0; i < len; i++)
+ tree orig_args = DECL_TEMPLATE_PARMS (t);
+ tree args;
+ int i;
+ for (args = orig_args = nreverse (orig_args);
+ args;
+ args = TREE_CHAIN (args))
{
- tree arg = TREE_VEC_ELT (args, i);
- tree defval = TREE_PURPOSE (arg);
- arg = TREE_VALUE (arg);
- if (TREE_CODE (arg) == TYPE_DECL)
- {
- OB_PUTS ("class ");
- OB_PUTID (DECL_NAME (arg));
- }
- else
- dump_decl (arg, 1);
+ int len = TREE_VEC_LENGTH (TREE_VALUE (args));
- if (defval)
+ OB_PUTS ("template <");
+ for (i = 0; i < len; i++)
{
- OB_PUTS (" = ");
- dump_decl (defval, 1);
- }
+ tree arg = TREE_VEC_ELT (TREE_VALUE (args), i);
+ tree defval = TREE_PURPOSE (arg);
+ arg = TREE_VALUE (arg);
+ if (TREE_CODE (arg) == TYPE_DECL)
+ {
+ if (DECL_NAME (arg))
+ {
+ OB_PUTS ("class ");
+ OB_PUTID (DECL_NAME (arg));
+ }
+ else
+ OB_PUTS ("class");
+ }
+ else
+ dump_decl (arg, 1);
+
+ if (defval)
+ {
+ OB_PUTS (" = ");
+ if (TREE_CODE (arg) == TYPE_DECL
+ || TREE_CODE (arg) == TEMPLATE_DECL)
+ dump_type (defval, 1);
+ else
+ dump_expr (defval, 1);
+ }
- OB_PUTC2 (',', ' ');
+ OB_PUTC2 (',', ' ');
+ }
+ if (len != 0)
+ OB_UNPUT (2);
+ OB_PUTC2 ('>', ' ');
}
- if (len != 0)
- OB_UNPUT (2);
- OB_PUTC2 ('>', ' ');
+ nreverse(orig_args);
- if (DECL_TEMPLATE_IS_CLASS (t))
- {
- OB_PUTS ("class ");
- OB_PUTID (DECL_NAME (t));
- }
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
+ dump_type (TREE_TYPE (t), v);
+ else if (TREE_TYPE (t) == NULL_TREE)
+ my_friendly_abort (353);
else switch (NEXT_CODE (t))
{
case METHOD_TYPE:
@@ -724,20 +859,60 @@ dump_decl (t, v)
break;
default:
- my_friendly_abort (353);
+ /* This case can occur with some illegal code. */
+ dump_type (TREE_TYPE (t), v);
+ }
+ }
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ {
+ tree args;
+ tree name = TREE_OPERAND (t, 0);
+ if (is_overloaded_fn (name))
+ name = DECL_NAME (get_first_fn (name));
+ dump_decl (name, v);
+ OB_PUTC ('<');
+ for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't'
+ || TREE_CODE (TREE_VALUE (args)) == TEMPLATE_DECL)
+ dump_type (TREE_VALUE (args), 0);
+ else
+ dump_expr (TREE_VALUE (args), 0);
+ if (TREE_CHAIN (args))
+ OB_PUTC2 (',', ' ');
}
+ OB_PUTC ('>');
}
break;
+ case LOOKUP_EXPR:
+ dump_decl (TREE_OPERAND (t, 0), v);
+ break;
+
case LABEL_DECL:
OB_PUTID (DECL_NAME (t));
break;
case CONST_DECL:
- if (NEXT_CODE (t) == ENUMERAL_TYPE)
- goto general;
- else
+ if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
+ || (DECL_INITIAL (t) &&
+ TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
+ dump_simple_decl (t, TREE_TYPE (t), v);
+ else if (DECL_NAME (t))
+ dump_decl (DECL_NAME (t), v);
+ else if (DECL_INITIAL (t))
dump_expr (DECL_INITIAL (t), 0);
+ else
+ OB_PUTS ("enumerator");
+ break;
+
+ case USING_DECL:
+ OB_PUTS ("using ");
+ dump_type (DECL_INITIAL (t), 0);
+ OB_PUTS ("::");
+ OB_PUTID (DECL_NAME (t));
break;
default:
@@ -755,11 +930,18 @@ dump_function_decl (t, v)
tree t;
int v;
{
- tree name = DECL_ASSEMBLER_NAME (t);
- tree fntype = TREE_TYPE (t);
- tree parmtypes = TYPE_ARG_TYPES (fntype);
+ tree name;
+ tree fntype;
+ tree parmtypes;
tree cname = NULL_TREE;
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ t = DECL_TEMPLATE_RESULT (t);
+
+ name = DECL_ASSEMBLER_NAME (t);
+ fntype = TREE_TYPE (t);
+ parmtypes = TYPE_ARG_TYPES (fntype);
+
/* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */
if (DECL_CONTEXT (t))
cname = DECL_CLASS_CONTEXT (t);
@@ -778,7 +960,7 @@ dump_function_decl (t, v)
&& ! DECL_CONSTRUCTOR_P (t)
&& ! DESTRUCTOR_NAME_P (name))
{
- dump_type_prefix (TREE_TYPE (fntype), 1);
+ dump_type_prefix (TREE_TYPE (fntype), 1, 0);
OB_PUTC (' ');
}
}
@@ -809,7 +991,7 @@ dump_function_decl (t, v)
OB_PUTC (')');
if (v && ! IDENTIFIER_TYPENAME_P (name))
- dump_type_suffix (TREE_TYPE (fntype), 1);
+ dump_type_suffix (TREE_TYPE (fntype), 1, 0);
if (TREE_CODE (fntype) == METHOD_TYPE)
{
@@ -825,6 +1007,7 @@ dump_function_decl (t, v)
/* Handle the function name for a FUNCTION_DECL node, grokking operators
and destructors properly. */
+
static void
dump_function_name (t)
tree t;
@@ -858,11 +1041,98 @@ dump_function_name (t)
}
else
dump_decl (name, 0);
+
+ if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t))
+ {
+ tree args = DECL_TEMPLATE_INFO (t) ? DECL_TI_ARGS (t) : NULL_TREE;
+
+ if (args != NULL_TREE
+ && DECL_CONTEXT (t) != NULL_TREE
+ && uses_template_parms (DECL_CONTEXT (t))
+ /* This next clause checks that there is only one level of
+ template arguments. In that case, they are the
+ arguments for the class context. */
+ && (TREE_CODE (args) == TREE_LIST
+ || (TREE_CODE (args) == TREE_VEC
+ && TREE_VEC_ELT (args, 0) != NULL_TREE
+ && TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC)))
+ /* We have something like this:
+
+ template <class T> struct S { void f(); };
+
+ and we are printing S<int>::f(). This is a template
+ instantiation, but we don't print anything after the f. */
+ ;
+ else
+ {
+ OB_PUTC ('<');
+
+ /* Be careful only to print things when we have them, so as not
+ to crash producing error messages. */
+ if (args)
+ {
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ tree arg;
+ int need_comma = 0;
+
+ for (arg = args; arg; arg = TREE_CHAIN (arg))
+ {
+ tree a = TREE_VALUE (arg);
+
+ if (need_comma)
+ OB_PUTS (", ");
+
+ if (a)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (a)) == 't'
+ || TREE_CODE (a) == TEMPLATE_DECL)
+ dump_type (a, 0);
+ else
+ dump_expr (a, 0);
+ }
+
+ need_comma = 1;
+ }
+ }
+ else if (TREE_CODE (args) == TREE_VEC)
+ {
+ int i;
+ int need_comma = 0;
+
+ if (TREE_VEC_LENGTH (args) > 0
+ && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
+ args = TREE_VEC_ELT (args,
+ TREE_VEC_LENGTH (args) - 1);
+
+ for (i = 0; i < TREE_VEC_LENGTH (args); i++)
+ {
+ tree a = TREE_VEC_ELT (args, i);
+
+ if (need_comma)
+ OB_PUTS (", ");
+
+ if (a)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (a)) == 't'
+ || TREE_CODE (a) == TEMPLATE_DECL)
+ dump_type (a, 0);
+ else
+ dump_expr (a, 0);
+ }
+
+ need_comma = 1;
+ }
+ }
+ }
+ OB_PUTC ('>');
+ }
+ }
}
static void
dump_char (c)
- char c;
+ int c;
{
switch (c)
{
@@ -897,7 +1167,7 @@ dump_char (c)
OB_PUTS ("\\\"");
break;
default:
- if (isprint (c))
+ if (ISPRINT (c))
OB_PUTC (c);
else
{
@@ -908,6 +1178,7 @@ dump_char (c)
}
/* Print out a list of initializers (subr of dump_expr) */
+
static void
dump_expr_list (l)
tree l;
@@ -922,6 +1193,7 @@ dump_expr_list (l)
}
/* Print out an expression */
+
static void
dump_expr (t, nop)
tree t;
@@ -934,6 +1206,8 @@ dump_expr (t, nop)
case FIELD_DECL:
case CONST_DECL:
case FUNCTION_DECL:
+ case TEMPLATE_DECL:
+ case NAMESPACE_DECL:
dump_decl (t, -1);
break;
@@ -950,12 +1224,12 @@ dump_expr (t, nop)
}
else if (type == boolean_type_node)
{
- if (t == boolean_false_node)
+ if (t == boolean_false_node
+ || (TREE_INT_CST_LOW (t) == 0
+ && TREE_INT_CST_HIGH (t) == 0))
OB_PUTS ("false");
else if (t == boolean_true_node)
OB_PUTS ("true");
- else
- my_friendly_abort (366);
}
else if (type == char_type_node)
{
@@ -995,7 +1269,7 @@ dump_expr (t, nop)
#else
{
unsigned char *p = (unsigned char *) &TREE_REAL_CST (t);
- int i;
+ size_t i;
strcpy (digit_buffer, "0x");
for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
@@ -1044,10 +1318,11 @@ dump_expr (t, nop)
}
break;
- case NEW_EXPR:
+ case AGGR_INIT_EXPR:
OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
OB_PUTC ('(');
- dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
+ if (TREE_OPERAND (t, 1))
+ dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
OB_PUTC (')');
break;
@@ -1059,7 +1334,7 @@ dump_expr (t, nop)
if (TREE_CODE (fn) == ADDR_EXPR)
fn = TREE_OPERAND (fn, 0);
- if (NEXT_CODE (fn) == METHOD_TYPE)
+ if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
{
tree ob = TREE_VALUE (args);
if (TREE_CODE (ob) == ADDR_EXPR)
@@ -1076,16 +1351,37 @@ dump_expr (t, nop)
args = TREE_CHAIN (args);
}
dump_expr (fn, 0);
- OB_PUTC('(');
+ OB_PUTC ('(');
dump_expr_list (args);
OB_PUTC (')');
}
break;
- case WITH_CLEANUP_EXPR:
- /* Note that this only works for G++ cleanups. If somebody
- builds a general cleanup, there's no way to represent it. */
- dump_expr (TREE_OPERAND (t, 0), 0);
+ case NEW_EXPR:
+ {
+ tree type = TREE_OPERAND (t, 1);
+ if (NEW_EXPR_USE_GLOBAL (t))
+ OB_PUTS ("::");
+ OB_PUTS ("new ");
+ if (TREE_OPERAND (t, 0))
+ {
+ OB_PUTC ('(');
+ dump_expr_list (TREE_OPERAND (t, 0));
+ OB_PUTS (") ");
+ }
+ if (TREE_CODE (type) == ARRAY_REF)
+ type = build_cplus_array_type
+ (TREE_OPERAND (type, 0),
+ build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1),
+ integer_one_node)));
+ dump_type (type, 0);
+ if (TREE_OPERAND (t, 2))
+ {
+ OB_PUTC ('(');
+ dump_expr_list (TREE_OPERAND (t, 2));
+ OB_PUTC (')');
+ }
+ }
break;
case TARGET_EXPR:
@@ -1188,7 +1484,8 @@ dump_expr (t, nop)
}
else
{
- if (NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
+ if (TREE_OPERAND (t,0) != NULL_TREE
+ && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
dump_expr (TREE_OPERAND (t, 0), nop);
else
dump_unary_op ("*", t, nop);
@@ -1215,7 +1512,7 @@ dump_expr (t, nop)
/* FIXME: This is a KLUDGE workaround for a parsing problem. There
should be another level of INDIRECT_REF so that I don't have to do
this. */
- if (NEXT_CODE (t) == POINTER_TYPE)
+ if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
{
tree next = TREE_TYPE (TREE_TYPE (t));
@@ -1240,8 +1537,46 @@ dump_expr (t, nop)
break;
case CONSTRUCTOR:
+ if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
+ {
+ tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
+
+ if (integer_all_onesp (idx))
+ {
+ tree pfn = PFN_FROM_PTRMEMFUNC (t);
+ dump_expr (pfn, 0);
+ break;
+ }
+ if (TREE_CODE (idx) == INTEGER_CST
+ && TREE_INT_CST_HIGH (idx) == 0)
+ {
+ tree virtuals;
+ unsigned HOST_WIDE_INT n;
+
+ t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
+ t = TYPE_METHOD_BASETYPE (t);
+ virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
+
+ n = TREE_INT_CST_LOW (idx);
+
+ /* Map vtable index back one, to allow for the null pointer to
+ member. */
+ --n;
+
+ while (n > 0 && virtuals)
+ {
+ --n;
+ virtuals = TREE_CHAIN (virtuals);
+ }
+ if (virtuals)
+ {
+ dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
+ break;
+ }
+ }
+ }
OB_PUTC ('{');
- dump_expr_list (CONSTRUCTOR_ELTS (t), 0);
+ dump_expr_list (CONSTRUCTOR_ELTS (t));
OB_PUTC ('}');
break;
@@ -1255,12 +1590,82 @@ dump_expr (t, nop)
dump_expr (TREE_OPERAND (t, 1), 0);
else
{
- sorry ("operand of OFFSET_REF not understood");
- goto error;
+ dump_expr (TREE_OPERAND (t, 0), 0);
+ OB_PUTS (" .* ");
+ dump_expr (TREE_OPERAND (t, 1), 0);
}
break;
}
+ case TEMPLATE_PARM_INDEX:
+ dump_decl (TEMPLATE_PARM_DECL (t), -1);
+ break;
+
+ case IDENTIFIER_NODE:
+ OB_PUTID (t);
+ break;
+
+ case SCOPE_REF:
+ dump_type (TREE_OPERAND (t, 0), 0);
+ OB_PUTS ("::");
+ dump_expr (TREE_OPERAND (t, 1), 0);
+ break;
+
+ case CAST_EXPR:
+ if (TREE_OPERAND (t, 0) == NULL_TREE
+ || TREE_CHAIN (TREE_OPERAND (t, 0)))
+ {
+ dump_type (TREE_TYPE (t), 0);
+ OB_PUTC ('(');
+ dump_expr_list (TREE_OPERAND (t, 0));
+ OB_PUTC (')');
+ }
+ else
+ {
+ OB_PUTC ('(');
+ dump_type (TREE_TYPE (t), 0);
+ OB_PUTC (')');
+ OB_PUTC ('(');
+ dump_expr_list (TREE_OPERAND (t, 0));
+ OB_PUTC (')');
+ }
+ break;
+
+ case LOOKUP_EXPR:
+ OB_PUTID (TREE_OPERAND (t, 0));
+ break;
+
+ case ARROW_EXPR:
+ dump_expr (TREE_OPERAND (t, 0), nop);
+ OB_PUTS ("->");
+ break;
+
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ if (TREE_CODE (t) == SIZEOF_EXPR)
+ OB_PUTS ("sizeof (");
+ else
+ {
+ my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
+ OB_PUTS ("__alignof__ (");
+ }
+ if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
+ dump_type (TREE_OPERAND (t, 0), 0);
+ else
+ dump_unary_op ("*", t, 0);
+ OB_PUTC (')');
+ break;
+
+ case DEFAULT_ARG:
+ OB_PUTS ("{unparsed}");
+ break;
+
+ case TRY_CATCH_EXPR:
+ case WITH_CLEANUP_EXPR:
+ case CLEANUP_POINT_EXPR:
+ dump_expr (TREE_OPERAND (t, 0), nop);
+ break;
+
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
@@ -1278,7 +1683,6 @@ dump_expr (t, nop)
/* fall through to ERROR_MARK... */
case ERROR_MARK:
- error:
OB_PUTCP ("{error}");
break;
}
@@ -1311,34 +1715,47 @@ dump_unary_op (opstring, t, nop)
}
char *
-fndecl_as_string (cname, fndecl, print_ret_type_p)
- tree cname, fndecl;
+fndecl_as_string (fndecl, print_ret_type_p)
+ tree fndecl;
int print_ret_type_p;
{
return decl_as_string (fndecl, print_ret_type_p);
}
-/* Same, but handtype a _TYPE.
+/* Same, but handle a _TYPE.
Called from convert_to_reference, mangle_class_name_for_template,
- build_unary_op, and GNU_xref_decl. */
+ build_unary_op, and GNU_xref_decl. If CANONICAL_NAME is non-zero,
+ when describing a typedef, we use the name of the type described,
+ rather than the name of the typedef. */
+
char *
-type_as_string (typ, v)
+type_as_string_real (typ, v, canonical_name)
tree typ;
int v;
+ int canonical_name;
{
OB_INIT ();
- dump_type (typ, v);
+ dump_type_real (typ, v, canonical_name);
OB_FINISH ();
return (char *)obstack_base (&scratch_obstack);
}
+
+char *
+type_as_string (typ, v)
+ tree typ;
+ int v;
+{
+ return type_as_string_real (typ, v, 0);
+}
+
char *
expr_as_string (decl, v)
tree decl;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
OB_INIT ();
@@ -1351,6 +1768,7 @@ expr_as_string (decl, v)
/* A cross between type_as_string and fndecl_as_string.
Only called from substitute_nice_name. */
+
char *
decl_as_string (decl, v)
tree decl;
@@ -1365,14 +1783,48 @@ decl_as_string (decl, v)
return (char *)obstack_base (&scratch_obstack);
}
+/* Generate the three forms of printable names for lang_printable_name. */
+
+char *
+lang_decl_name (decl, v)
+ tree decl;
+ int v;
+{
+ if (v >= 2)
+ return decl_as_string (decl, 1);
+
+ OB_INIT ();
+
+ if (v == 1 && DECL_CLASS_SCOPE_P (decl))
+ {
+ tree cname;
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cname = DECL_CLASS_CONTEXT (decl);
+ else
+ cname = DECL_CONTEXT (decl);
+ dump_type (cname, 0);
+ OB_PUTC2 (':', ':');
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ dump_function_name (decl);
+ else
+ dump_decl (DECL_NAME (decl), 0);
+
+ OB_FINISH ();
+
+ return (char *)obstack_base (&scratch_obstack);
+}
+
+
char *
cp_file_of (t)
tree t;
{
- if (TREE_CODE (t) == PARM_DECL)
+ if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
return DECL_SOURCE_FILE (DECL_CONTEXT (t));
else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
- return DECL_SOURCE_FILE (TYPE_NAME (t));
+ return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));
else
return DECL_SOURCE_FILE (t);
}
@@ -1382,18 +1834,13 @@ cp_line_of (t)
tree t;
{
int line = 0;
- if (TREE_CODE (t) == PARM_DECL)
+ if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
t = TREE_TYPE (t);
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
- {
- if (IS_AGGR_TYPE (t))
- line = CLASSTYPE_SOURCE_LINE (t);
- else
- line = DECL_SOURCE_LINE (TYPE_NAME (t));
- }
+ line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));
else
line = DECL_SOURCE_LINE (t);
@@ -1406,7 +1853,7 @@ cp_line_of (t)
char *
code_as_string (c, v)
enum tree_code c;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
return tree_code_name [c];
}
@@ -1414,7 +1861,7 @@ code_as_string (c, v)
char *
language_as_string (c, v)
enum languages c;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
switch (c)
{
@@ -1424,6 +1871,9 @@ language_as_string (c, v)
case lang_cplusplus:
return "C++";
+ case lang_java:
+ return "Java";
+
default:
my_friendly_abort (355);
return 0;
@@ -1431,9 +1881,11 @@ language_as_string (c, v)
}
/* Return the proper printed version of a parameter to a C++ function. */
+
char *
parm_as_string (p, v)
- int p, v;
+ int p;
+ int v ATTRIBUTE_UNUSED;
{
if (p < 0)
return "`this'";
@@ -1445,7 +1897,7 @@ parm_as_string (p, v)
char *
op_as_string (p, v)
enum tree_code p;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
static char buf[] = "operator ";
@@ -1457,20 +1909,48 @@ op_as_string (p, v)
}
char *
+assop_as_string (p, v)
+ enum tree_code p;
+ int v ATTRIBUTE_UNUSED;
+{
+ static char buf[] = "operator ";
+
+ if (p == 0)
+ return "{unknown}";
+
+ strcpy (buf + 9, assignop_tab [p]);
+ return buf;
+}
+
+char *
args_as_string (p, v)
tree p;
int v;
{
if (p == NULL_TREE)
- return "...";
+ return "";
+
+ if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't')
+ return type_as_string (p, v);
- return type_as_string (p, v);
+ OB_INIT ();
+ for (; p; p = TREE_CHAIN (p))
+ {
+ if (TREE_VALUE (p) == null_node)
+ OB_PUTS ("NULL");
+ else
+ dump_type (error_type (TREE_VALUE (p)), v);
+ if (TREE_CHAIN (p))
+ OB_PUTS (", ");
+ }
+ OB_FINISH ();
+ return (char *)obstack_base (&scratch_obstack);
}
char *
cv_as_string (p, v)
tree p;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
OB_INIT ();