/* Call-backs for C++ error reporting.
This code is non-reentrant.
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
Boston, MA 02111-1307, USA. */
#include "config.h"
-#include <stdio.h>
+#include "system.h"
#include "tree.h"
#include "cp-tree.h"
#include "obstack.h"
-#include <ctype.h>
+#include "toplev.h"
typedef char* cp_printer ();
#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, Q, _, _, 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
#undef Q
#undef T
#undef V
-#undef _
+#undef o
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
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));
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));
-static void dump_type_prefix PROTO((tree, int));
-static void dump_type_suffix PROTO((tree, int));
+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_qualifiers PROTO((tree, enum pad));
static void dump_char PROTO((int));
static char *aggr_variety PROTO((tree));
static tree ident_fndecl PROTO((tree));
}
static void
-dump_readonly_or_volatile (t, p)
+dump_qualifiers (t, p)
tree t;
enum pad p;
{
- if (TYPE_READONLY (t) || TYPE_VOLATILE (t))
+ if (TYPE_QUALS (t))
{
if (p == before) OB_PUTC (' ');
- if (TYPE_READONLY (t))
- OB_PUTS ("const");
- if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
- OB_PUTC (' ');
- if (TYPE_VOLATILE (t))
- OB_PUTS ("volatile");
+ switch (TYPE_QUALS (t))
+ {
+ case TYPE_QUAL_CONST:
+ OB_PUTS ("const");
+ break;
+
+ case TYPE_QUAL_VOLATILE:
+ OB_PUTS ("volatile");
+ break;
+
+ case TYPE_QUAL_RESTRICT:
+ OB_PUTS ("__restrict");
+ break;
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
+ OB_PUTS ("const volatile");
+ break;
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
+ OB_PUTS ("const __restrict");
+ break;
+
+ case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ OB_PUTS ("volatile __restrict");
+ break;
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ OB_PUTS ("const volatile __restrict");
+ break;
+
+ default:
+ my_friendly_abort (0);
+ }
if (p == after) OB_PUTC (' ');
}
}
/* 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;
/* 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)
{
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 (" ...");
break;
case TREE_VEC:
- dump_type (BINFO_TYPE (t), v);
+ dump_type_real (BINFO_TYPE (t), v, canonical_name);
break;
case RECORD_TYPE:
if (TYPE_LANG_SPECIFIC (t)
&& (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
{
- if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
- dump_readonly_or_volatile (t, after);
- dump_type (SIGNATURE_TYPE (t), v);
+ dump_qualifiers (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:
+ case NAMESPACE_DECL:
dump_decl (t, v);
break;
case COMPLEX_TYPE:
OB_PUTS ("complex ");
- dump_type (TREE_TYPE (t), v);
+ dump_type_real (TREE_TYPE (t), v, canonical_name);
break;
case INTEGER_TYPE:
case REAL_TYPE:
case VOID_TYPE:
case BOOLEAN_TYPE:
- dump_readonly_or_volatile (t, after);
- OB_PUTID (TYPE_IDENTIFIER (t));
+ {
+ tree type;
+ dump_qualifiers (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_TEMPLATE_PARM:
+ if (!TEMPLATE_TEMPLATE_PARM_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 = TYPE_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 TEMPLATE_TYPE_PARM:
- dump_readonly_or_volatile (t, after);
+ dump_qualifiers (t, after);
if (TYPE_IDENTIFIER (t))
OB_PUTID (TYPE_IDENTIFIER (t));
else
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 (TYPE_CONTEXT (t), 0);
+ dump_type_real (TYPE_CONTEXT (t), 0, canonical_name);
OB_PUTS ("::");
OB_PUTID (TYPE_IDENTIFIER (t));
break;
+ case TYPEOF_TYPE:
+ OB_PUTS ("__typeof (");
+ dump_expr (TYPE_FIELDS (t), 1);
+ OB_PUTC (')');
+ break;
+
default:
sorry ("`%s' not supported by dump_type",
tree_code_name[(int) TREE_CODE (t)]);
return "struct";
}
+static void
+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)
+dump_aggr_type (t, v, canonical_name)
tree t;
int v; /* verbose? */
+ int canonical_name;
{
tree name;
char *variety = aggr_variety (t);
- dump_readonly_or_volatile (t, after);
+ dump_qualifiers (t, after);
if (v > 0)
{
OB_PUTC (' ');
}
- name = TYPE_NAME (t);
+ name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t);
- if (name && DECL_CONTEXT (name))
+ if (name && CP_DECL_CONTEXT (name) != global_namespace)
{
/* FUNCTION_DECL or RECORD_TYPE */
dump_decl (DECL_CONTEXT (name), 0);
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))
{
switch (TREE_CODE (t))
{
case POINTER_TYPE:
+ case REFERENCE_TYPE:
{
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)
+ if (!TYPE_PTRMEM_P (t))
{
switch (TREE_CODE (sub))
{
case POINTER_TYPE:
/* We don't want "char * *" */
- if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
+ if (TYPE_QUALS (sub) == TYPE_UNQUALIFIED)
break;
/* But we do want "char *const *" */
default:
OB_PUTC (' ');
}
- OB_PUTC ('*');
- dump_readonly_or_volatile (t, none);
- }
- }
- break;
-
- case REFERENCE_TYPE:
- {
- tree sub = TREE_TYPE (t);
- dump_type_prefix (sub, v);
-
- switch (TREE_CODE (sub))
- {
- case ARRAY_TYPE:
- OB_PUTC2 (' ', '(');
- break;
-
- case POINTER_TYPE:
- /* We don't want "char * &" */
- if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
- break;
- /* But we do want "char *const &" */
-
- default:
- OB_PUTC (' ');
+ if (TREE_CODE (t) == POINTER_TYPE)
+ OB_PUTC ('*');
+ else
+ OB_PUTC ('&');
+ dump_qualifiers (t, none);
}
}
- OB_PUTC ('&');
- dump_readonly_or_volatile (t, none);
break;
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 ('*');
- dump_readonly_or_volatile (t, none);
+ dump_qualifiers (t, none);
break;
/* 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:
case REAL_TYPE:
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
- dump_type (t, v);
+ dump_type_real (t, v, canonical_name);
break;
default:
}
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);
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 */
OB_PUTS ("...");
OB_PUTC (')');
if (TREE_CODE (t) == METHOD_TYPE)
- dump_readonly_or_volatile
+ dump_qualifiers
(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;
}
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:
case REAL_TYPE:
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
}
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 (' ');
+ }
+ if (CP_DECL_CONTEXT (t) != global_namespace)
+ {
+ dump_decl (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 */
/* Don't say 'typedef class A' */
if (DECL_ARTIFICIAL (t))
{
+ 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:
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
OB_PUTS ("vtable for ");
- dump_type (DECL_CONTEXT (t), v);
+ if (TYPE_P (DECL_CONTEXT (t)))
+ dump_type (DECL_CONTEXT (t), v);
+ else
+ /* This case can arise with -fno-vtable-thunks. See
+ expand_upcast_fixups. It's not clear what to print
+ here. */
+ OB_PUTS ("{unknown type}");
break;
}
/* 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_simple_decl (t, TREE_TYPE (t), v);
+ break;
+
+ case NAMESPACE_DECL:
+ if (CP_DECL_CONTEXT (t) != global_namespace)
{
- dump_type (DECL_CONTEXT (t), 0);
- OB_PUTC2 (':', ':');
+ dump_decl (DECL_CONTEXT (t), v);
+ OB_PUTC2 (':',':');
}
- if (DECL_NAME (t))
- dump_decl (DECL_NAME (t), v);
+ if (DECL_NAME (t) == anonymous_namespace_name)
+ OB_PUTS ("{anonymous}");
else
- OB_PUTS ("{anon}");
- if (v > 0)
- dump_type_suffix (TREE_TYPE (t), v);
+ OB_PUTID (DECL_NAME (t));
break;
- case NAMESPACE_DECL:
- 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);
arg = TREE_VALUE (arg);
if (TREE_CODE (arg) == TYPE_DECL)
{
- OB_PUTS ("class ");
- OB_PUTID (DECL_NAME (arg));
+ 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 (" = ");
- dump_decl (defval, 1);
+ if (TREE_CODE (arg) == TYPE_DECL
+ || TREE_CODE (arg) == TEMPLATE_DECL)
+ dump_type (defval, 1);
+ else
+ dump_expr (defval, 1);
}
OB_PUTC2 (',', ' ');
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
dump_type (TREE_TYPE (t), v);
+ else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
+ dump_decl (DECL_TEMPLATE_RESULT (t), v);
else if (TREE_TYPE (t) == NULL_TREE)
my_friendly_abort (353);
else switch (NEXT_CODE (t))
break;
default:
- my_friendly_abort (353);
+ /* This case can occur with some illegal code. */
+ dump_type (TREE_TYPE (t), v);
}
}
break;
OB_PUTC ('<');
for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
{
- if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't')
+ 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);
break;
case LOOKUP_EXPR:
- OB_PUTID (TREE_OPERAND (t, 0));
+ dump_decl (TREE_OPERAND (t, 0), v);
break;
case LABEL_DECL:
case CONST_DECL:
if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
|| (DECL_INITIAL (t) &&
- TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_CONST_PARM))
- goto general;
+ 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
parmtypes = TYPE_ARG_TYPES (fntype);
/* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */
- if (DECL_CONTEXT (t))
+ if (DECL_CLASS_SCOPE_P (t))
cname = DECL_CLASS_CONTEXT (t);
/* this is for partially instantiated template methods */
else if (TREE_CODE (fntype) == METHOD_TYPE)
if (DECL_STATIC_FUNCTION_P (t))
OB_PUTS ("static ");
- if (! IDENTIFIER_TYPENAME_P (name)
+ if (! DECL_CONV_FN_P (t)
&& ! DECL_CONSTRUCTOR_P (t)
- && ! DESTRUCTOR_NAME_P (name))
+ && ! DECL_DESTRUCTOR_P (t))
{
- dump_type_prefix (TREE_TYPE (fntype), 1);
+ dump_type_prefix (TREE_TYPE (fntype), 1, 0);
OB_PUTC (' ');
}
}
/* Skip past "in_charge" identifier. */
parmtypes = TREE_CHAIN (parmtypes);
}
+ else if (CP_DECL_CONTEXT (t) != global_namespace)
+ {
+ dump_decl (DECL_CONTEXT (t), 0);
+ OB_PUTC2 (':',':');
+ }
if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus)
parmtypes = TREE_CHAIN (parmtypes);
OB_PUTC (')');
- if (v && ! IDENTIFIER_TYPENAME_P (name))
- dump_type_suffix (TREE_TYPE (fntype), 1);
+ if (v && ! DECL_CONV_FN_P (t))
+ dump_type_suffix (TREE_TYPE (fntype), 1, 0);
if (TREE_CODE (fntype) == METHOD_TYPE)
{
if (IS_SIGNATURE (cname))
/* We look at the type pointed to by the `optr' field of `this.' */
- dump_readonly_or_volatile
+ dump_qualifiers
(TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
else
- dump_readonly_or_volatile
+ dump_qualifiers
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
}
}
{
tree name = DECL_NAME (t);
- /* There ought to be a better way to find out whether or not something is
- a destructor. */
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))
- && DECL_LANGUAGE (t) == lang_cplusplus)
+ if (DECL_DESTRUCTOR_P (t))
{
OB_PUTC ('~');
dump_decl (name, 0);
}
- else if (IDENTIFIER_TYPENAME_P (name))
+ else if (DECL_CONV_FN_P (t))
{
/* This cannot use the hack that the operator's return
type is stashed off of its name because it may be
else
dump_decl (name, 0);
- if (DECL_LANG_SPECIFIC (t)
- && (DECL_TEMPLATE_SPECIALIZATION (t) || DECL_IMPLICIT_INSTANTIATION (t))
- && (DECL_CLASS_CONTEXT (t) == NULL_TREE || is_member_template (t)))
+ if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)
+ && DECL_TEMPLATE_INFO (t)
+ && (DECL_TEMPLATE_SPECIALIZATION (t)
+ || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
+ || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
+ || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
{
- tree args = DECL_TEMPLATE_INFO (t)
- ? DECL_TI_ARGS (t) : NULL_TREE;
-
+ tree args = DECL_TEMPLATE_INFO (t) ? DECL_TI_ARGS (t) : NULL_TREE;
OB_PUTC ('<');
/* Be careful only to print things when we have them, so as not
{
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')
+ if (TREE_CODE_CLASS (TREE_CODE (a)) == 't'
+ || TREE_CODE (a) == TEMPLATE_DECL)
dump_type (a, 0);
else
dump_expr (a, 0);
{
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, 0);
-
+ 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')
+ if (TREE_CODE_CLASS (TREE_CODE (a)) == 't'
+ || TREE_CODE (a) == TEMPLATE_DECL)
dump_type (a, 0);
else
dump_expr (a, 0);
OB_PUTS ("\\\"");
break;
default:
- if (isprint (c))
+ if (ISPRINT (c))
OB_PUTC (c);
else
{
case CONST_DECL:
case FUNCTION_DECL:
case TEMPLATE_DECL:
+ case NAMESPACE_DECL:
dump_decl (t, -1);
break;
#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++);
OB_PUTCP (digit_buffer);
break;
+ case PTRMEM_CST:
+ OB_PUTC ('&');
+ dump_type (PTRMEM_CST_CLASS (t), 0);
+ OB_PUTS ("::");
+ OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t)));
+ break;
+
case STRING_CST:
{
char *p = TREE_STRING_POINTER (t);
}
break;
- case NEW_EXPR:
+ case AGGR_INIT_EXPR:
OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
OB_PUTC ('(');
if (TREE_OPERAND (t, 1))
}
break;
+ 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:
/* Note that this only works for G++ target exprs. If somebody
builds a general TARGET_EXPR, there's no way to represent that
case OFFSET_REF:
{
tree ob = TREE_OPERAND (t, 0);
- if (TREE_CODE (ob) == NOP_EXPR
- && TREE_OPERAND (ob, 0) == error_mark_node
- && TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
- /* A::f */
- dump_expr (TREE_OPERAND (t, 1), 0);
+ if (is_dummy_object (ob))
+ {
+ if (TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
+ /* A::f */
+ dump_expr (TREE_OPERAND (t, 1), 0);
+ else
+ dump_decl (TREE_OPERAND (t, 1), 0);
+ }
else
{
dump_expr (TREE_OPERAND (t, 0), 0);
break;
}
- case TEMPLATE_CONST_PARM:
- {
- int l = current_template_parms ?
- list_length (current_template_parms) : 0;
-
- if (l >= TEMPLATE_CONST_LEVEL (t))
- {
- int i;
- tree parms = current_template_parms;
- tree r;
-
- for (i = 0; i < l - TEMPLATE_CONST_LEVEL (t); ++i)
- {
- parms = TREE_CHAIN (parms);
- my_friendly_assert (parms != NULL_TREE, 0);
- }
-
- r = TREE_VEC_ELT (TREE_VALUE (parms),
- TEMPLATE_CONST_IDX (t));
- dump_decl (TREE_VALUE (r), -1);
- }
- else
- {
- OB_PUTS ("<tparm ");
- OB_PUTI (TEMPLATE_CONST_IDX (t));
- OB_PUTS (">");
- }
- }
+ case TEMPLATE_PARM_INDEX:
+ dump_decl (TEMPLATE_PARM_DECL (t), -1);
break;
case IDENTIFIER_NODE:
OB_PUTID (TREE_OPERAND (t, 0));
break;
+ case ARROW_EXPR:
+ dump_expr (TREE_OPERAND (t, 0), nop);
+ OB_PUTS ("->");
+ break;
+
case SIZEOF_EXPR:
- OB_PUTS ("sizeof (");
+ 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
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)
{
/* fall through to ERROR_MARK... */
case ERROR_MARK:
- error:
OB_PUTCP ("{error}");
break;
}
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 ();
OB_INIT ();
- if (v == 1 && DECL_CONTEXT (decl)
- && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
+ if (v == 1 && DECL_CLASS_SCOPE_P (decl))
{
tree cname;
if (TREE_CODE (decl) == FUNCTION_DECL)
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_MAIN_DECL (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))
+ if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
+ && TYPE_MAIN_DECL (TREE_TYPE (t)))
t = TREE_TYPE (t);
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
char *
code_as_string (c, v)
enum tree_code c;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
return tree_code_name [c];
}
char *
language_as_string (c, v)
enum languages c;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
switch (c)
{
case lang_cplusplus:
return "C++";
+ case lang_java:
+ return "Java";
+
default:
my_friendly_abort (355);
return 0;
char *
parm_as_string (p, v)
- int p, v;
+ int p;
+ int v ATTRIBUTE_UNUSED;
{
if (p < 0)
return "`this'";
char *
op_as_string (p, v)
enum tree_code p;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
static char buf[] = "operator ";
char *
assop_as_string (p, v)
enum tree_code p;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
static char buf[] = "operator ";
char *
cv_as_string (p, v)
tree p;
- int v;
+ int v ATTRIBUTE_UNUSED;
{
OB_INIT ();
- dump_readonly_or_volatile (p, before);
+ dump_qualifiers (p, before);
OB_FINISH ();