Commit 9e93bc9d by Nathan Sidwell Committed by Nathan Sidwell

Augment stringification of trees.

	* cp-tree.h (tree_string_flags): New error stringifying enumeration.
	(fndecl_as_string, type_as_string_real, args_as_string,
	code_as_string, language_as_string, parm_as_string,
	op_as_string, assop_as_string, cv_as_string): Remove.
	(type_as_string, decl_as_string, expr_as_string): Adjust prototype.
	(context_as_string): Declare new function.
	* error.c (cp_printers): Move definition.
	(OB_UNPUT): Remove.
	(OB_END_TEMPLATE_ID): Adjust.
	(interesting_scope_p): Remove.
	(dump_scope): New static function.
	(dump_qualifiers): Adjust prototype, reimplement.
	(dump_template_value): Use tree_string_flags.
	(dump_type_real): Move back to dump_type.
	(dump_type): Adjust prototype. Use tree_string_flags.
	(dump_aggr_type): Likewise. Use dump_template_parms.
	(dump_type_prefix): Adjust prototype. Use tree_string_flags. Return pad flag.
	(dump_type_suffix): Adjust prototype. Use tree_string_flags.
	(dump_simple_decl): Likewise.
	(dump_decl): Likewise. Use dump_template_decl.
	(dump_template_decl): New static function broken out of dump_decl.
	(dump_function_decl): Adjust prototype. Use tree_string_flags.
	(dump_parameters): Likewise. Prefix space.
	(dump_exception_spec): Adjust prototype. Use tree_string_flags.
	(dump_function_name): Likewise. Use dump_template_parms.
	(dump_template_parms): New static function broken out of
	dump_function_name.
	(dump_expr_list): Adjust prototype. Use tree_string_flags.
	(dump_expr): Likewise.
	(fndecl_as_string): Removed
	(type_as_string_real): Removed
	(dump_binary_op): Adjust prototype. Use tree_string_flags.
	(dump_unary_op): Likewise.
	(type_as_string): Likewise.
	(expr_as_string): Likewise.
	(decl_as_string): Likewise.
	(context_as_string): New function.
	(lang_decl_name): Adjust.
	(decl_to_string): New static print callback.
	(expr_to_string): Likewise.
	(fndecl_to_string): Likewise.
	(code_as_string): Renamed to ...
	(code_to_string): ... here. Adjust.
	(language_as_string): Renamed to ...
	(language_to_string): ... here. Adjust.
	(parm_as_string): Renamed to ...
	(parm_to_string): ... here.
	(op_as_string): Renamed to ...
	(op_to_string): ... here.
	(assop_as_string): Renamed to ...
	(assop_to_string): ... here.
	(type_to_string): New static print callback.
	(args_as_string): Renamed to ...
	(args_to_string): ... here. Adjust.
	(cv_as_string): Renamed to ...
	(cv_to_string): ... here. Adjust.
	* pt.c (mangle_class_name_for_template): Use tree_string_flags.
	(print_template_context): Likewise.

From-SVN: r29673
parent cf9d61d5
1999-09-27 Nathan Sidwell <nathan@acm.org>
Augment stringification of trees.
* cp-tree.h (tree_string_flags): New error stringifying enumeration.
(fndecl_as_string, type_as_string_real, args_as_string,
code_as_string, language_as_string, parm_as_string,
op_as_string, assop_as_string, cv_as_string): Remove.
(type_as_string, decl_as_string, expr_as_string): Adjust prototype.
(context_as_string): Declare new function.
* error.c (cp_printers): Move definition.
(OB_UNPUT): Remove.
(OB_END_TEMPLATE_ID): Adjust.
(interesting_scope_p): Remove.
(dump_scope): New static function.
(dump_qualifiers): Adjust prototype, reimplement.
(dump_template_value): Use tree_string_flags.
(dump_type_real): Move back to dump_type.
(dump_type): Adjust prototype. Use tree_string_flags.
(dump_aggr_type): Likewise. Use dump_template_parms.
(dump_type_prefix): Adjust prototype. Use tree_string_flags. Return pad flag.
(dump_type_suffix): Adjust prototype. Use tree_string_flags.
(dump_simple_decl): Likewise.
(dump_decl): Likewise. Use dump_template_decl.
(dump_template_decl): New static function broken out of dump_decl.
(dump_function_decl): Adjust prototype. Use tree_string_flags.
(dump_parameters): Likewise. Prefix space.
(dump_exception_spec): Adjust prototype. Use tree_string_flags.
(dump_function_name): Likewise. Use dump_template_parms.
(dump_template_parms): New static function broken out of
dump_function_name.
(dump_expr_list): Adjust prototype. Use tree_string_flags.
(dump_expr): Likewise.
(fndecl_as_string): Removed
(type_as_string_real): Removed
(dump_binary_op): Adjust prototype. Use tree_string_flags.
(dump_unary_op): Likewise.
(type_as_string): Likewise.
(expr_as_string): Likewise.
(decl_as_string): Likewise.
(context_as_string): New function.
(lang_decl_name): Adjust.
(decl_to_string): New static print callback.
(expr_to_string): Likewise.
(fndecl_to_string): Likewise.
(code_as_string): Renamed to ...
(code_to_string): ... here. Adjust.
(language_as_string): Renamed to ...
(language_to_string): ... here. Adjust.
(parm_as_string): Renamed to ...
(parm_to_string): ... here.
(op_as_string): Renamed to ...
(op_to_string): ... here.
(assop_as_string): Renamed to ...
(assop_to_string): ... here.
(type_to_string): New static print callback.
(args_as_string): Renamed to ...
(args_to_string): ... here. Adjust.
(cv_as_string): Renamed to ...
(cv_to_string): ... here. Adjust.
* pt.c (mangle_class_name_for_template): Use tree_string_flags.
(print_template_context): Likewise.
1999-09-26 Mark Mitchell <mark@codesourcery.com> 1999-09-26 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (expand_throw): Remove prototype. * cp-tree.h (expand_throw): Remove prototype.
......
...@@ -3122,6 +3122,30 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; ...@@ -3122,6 +3122,30 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define TEMPLATE_TYPE_DECL(NODE) \ #define TEMPLATE_TYPE_DECL(NODE) \
(TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE))) (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
/* Control stringification of trees (types, decls & exprs).
Bit or them together. */
enum tree_string_flags
{
TS_PLAIN, /* nothing special */
TS_CHASE_TYPEDEFS = 1 << 0, /* look through typedefs */
TS_DECORATE = 1 << 1, /* decorate things */
TS_FUNC_NORETURN = 1 << 2, /* inhibit function return type */
TS_FUNC_THROW = 1 << 3, /* show throw spec */
TS_PARM_DEFAULTS = 1 << 4, /* show parm defaults */
TS_EXPR_PARENS = 1 << 5, /* enclose in parens */
TS_AGGR_TAGS = 1 << 6, /* show struct tags */
TS_DECL_TYPE = 1 << 7, /* show decl's type */
TS_FUNC_SCOPE = 1 << 8, /* show function scope */
TS_PEDANTIC_NAME = 1 << 9, /* pedantically name things */
TS_TEMPLATE_PREFIX= 1 << 10, /* show template <parms> prefix */
/* Internal use flags */
TS_TEMPLATE_PARM = 1 << 11, /* decl is really a non-type template parm */
TS_TEMPLATE_PLAIN = 1 << 12, /* don't decorate primary template_name */
TS_NEXT_BIT = 13 /* next available bit */
};
/* in lex.c */ /* in lex.c */
/* Indexed by TREE_CODE, these tables give C-looking names to /* Indexed by TREE_CODE, these tables give C-looking names to
operators represented by TREE_CODES. For example, operators represented by TREE_CODES. For example,
...@@ -3430,18 +3454,10 @@ extern void cp_deprecated PROTO((const char*)); ...@@ -3430,18 +3454,10 @@ extern void cp_deprecated PROTO((const char*));
/* in error.c */ /* in error.c */
extern void init_error PROTO((void)); extern void init_error PROTO((void));
extern const char *fndecl_as_string PROTO((tree, int)); extern const char *type_as_string PROTO((tree, enum tree_string_flags));
extern const char *type_as_string PROTO((tree, int)); extern const char *decl_as_string PROTO((tree, enum tree_string_flags));
extern const char *type_as_string_real PROTO((tree, int, int)); extern const char *expr_as_string PROTO((tree, enum tree_string_flags));
extern const char *args_as_string PROTO((tree, int)); extern const char *context_as_string PROTO((tree, enum tree_string_flags));
extern const char *decl_as_string PROTO((tree, int));
extern const char *expr_as_string PROTO((tree, int));
extern const char *code_as_string PROTO((enum tree_code, int));
extern const char *language_as_string PROTO((enum languages, int));
extern const char *parm_as_string PROTO((int, int));
extern const char *op_as_string PROTO((enum tree_code, int));
extern const char *assop_as_string PROTO((enum tree_code, int));
extern const char *cv_as_string PROTO((tree, int));
extern const char *lang_decl_name PROTO((tree, int)); extern const char *lang_decl_name PROTO((tree, int));
extern const char *cp_file_of PROTO((tree)); extern const char *cp_file_of PROTO((tree));
extern int cp_line_of PROTO((tree)); extern int cp_line_of PROTO((tree));
......
...@@ -28,43 +28,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -28,43 +28,6 @@ Boston, MA 02111-1307, USA. */
typedef const char *cp_printer (); typedef const char *cp_printer ();
#define A args_as_string
#define C code_as_string
#define D decl_as_string
#define E expr_as_string
#define F fndecl_as_string
#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 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 */
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, F, 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 E
#undef F
#undef L
#undef O
#undef P
#undef Q
#undef T
#undef V
#undef o
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free
...@@ -84,39 +47,88 @@ static char *scratch_firstobj; ...@@ -84,39 +47,88 @@ static char *scratch_firstobj;
# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
# define OB_PUTI(CST) do { sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(CST)); \ # define OB_PUTI(CST) do { sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(CST)); \
OB_PUTCP (digit_buffer); } while (0) OB_PUTCP (digit_buffer); } while (0)
# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));
# define OB_END_TEMPLATE_ID() \ # define OB_END_TEMPLATE_ID() \
((obstack_next_free (&scratch_obstack) != obstack_base (&scratch_obstack) \ (((obstack_next_free (&scratch_obstack) != obstack_base (&scratch_obstack) \
&& obstack_next_free (&scratch_obstack)[-1] == '>') \ && obstack_next_free (&scratch_obstack)[-1] == '>') \
? OB_PUTC2 (' ', '>') : OB_PUTC ('>')) ? OB_PUTC (' ') : (void)0), OB_PUTC ('>'))
# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
enum pad { none, before, after }; enum pad { none, before, after };
static void dump_type PROTO((tree, int)); static const char *args_to_string PROTO((tree, int));
static void dump_type_real PROTO((tree, int, int)); static const char *assop_to_string PROTO((enum tree_code, int));
static void dump_simple_decl PROTO((tree, tree, int)); static const char *code_to_string PROTO((enum tree_code, int));
static void dump_decl PROTO((tree, int)); static const char *cv_to_string PROTO((tree, int));
static void dump_function_decl PROTO((tree, int)); static const char *decl_to_string PROTO((tree, int));
static void dump_expr PROTO((tree, int)); static const char *expr_to_string PROTO((tree, int));
static void dump_unary_op PROTO((const char *, tree, int)); static const char *fndecl_to_string PROTO((tree, int));
static void dump_binary_op PROTO((const char *, tree)); static const char *language_to_string PROTO((enum languages, int));
static void dump_aggr_type PROTO((tree, int, int)); static const char *op_to_string PROTO((enum tree_code, int));
static void dump_type_prefix PROTO((tree, int, int)); static const char *parm_to_string PROTO((int, int));
static void dump_type_suffix PROTO((tree, int, int)); static const char *type_to_string PROTO((tree, int));
static void dump_function_name PROTO((tree));
static void dump_expr_list PROTO((tree)); static void dump_type PROTO((tree, enum tree_string_flags));
static void dump_simple_decl PROTO((tree, tree, enum tree_string_flags));
static void dump_decl PROTO((tree, enum tree_string_flags));
static void dump_template_decl PROTO((tree, enum tree_string_flags));
static void dump_function_decl PROTO((tree, enum tree_string_flags));
static void dump_expr PROTO((tree, enum tree_string_flags));
static void dump_unary_op PROTO((const char *, tree, enum tree_string_flags));
static void dump_binary_op PROTO((const char *, tree, enum tree_string_flags));
static void dump_aggr_type PROTO((tree, enum tree_string_flags));
static enum pad dump_type_prefix PROTO((tree, enum tree_string_flags));
static void dump_type_suffix PROTO((tree, enum tree_string_flags));
static void dump_function_name PROTO((tree, enum tree_string_flags));
static void dump_expr_list PROTO((tree, enum tree_string_flags));
static void dump_global_iord PROTO((tree)); static void dump_global_iord PROTO((tree));
static void dump_qualifiers PROTO((tree, enum pad)); static enum pad dump_qualifiers PROTO((tree, enum pad));
static void dump_char PROTO((int)); static void dump_char PROTO((int));
static void dump_parameters PROTO((tree, int, int)); static void dump_parameters PROTO((tree, enum tree_string_flags));
static void dump_exception_spec PROTO((tree, int)); static void dump_exception_spec PROTO((tree, enum tree_string_flags));
static const char *aggr_variety PROTO((tree)); static const char *aggr_variety PROTO((tree));
static tree ident_fndecl PROTO((tree)); static tree ident_fndecl PROTO((tree));
static int interesting_scope_p PROTO((tree)); static void dump_template_value PROTO((tree, enum tree_string_flags));
static void dump_template_value PROTO((tree, int, int)); static void dump_scope PROTO((tree, enum tree_string_flags));
static void dump_template_parms PROTO((tree, int, enum tree_string_flags));
#define A args_to_string
#define C code_to_string
#define D decl_to_string
#define E expr_to_string
#define F fndecl_to_string
#define L language_to_string
#define O op_to_string
#define P parm_to_string
#define Q assop_to_string
#define T type_to_string
#define V cv_to_string
#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 */
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, F, 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 E
#undef F
#undef L
#undef O
#undef P
#undef Q
#undef T
#undef V
#undef o
void void
init_error () init_error ()
...@@ -125,92 +137,102 @@ init_error () ...@@ -125,92 +137,102 @@ init_error ()
scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
} }
/* Returns nonzero if SCOPE is something we want to print for random decls. */ /* Dump a scope, if deemed necessary. */
static int static void
interesting_scope_p (scope) dump_scope (scope, flags)
tree scope; tree scope;
enum tree_string_flags flags;
{ {
if (scope == NULL_TREE if (scope == NULL_TREE)
|| scope == global_namespace) return;
return 0;
if (TREE_CODE (scope) == NAMESPACE_DECL)
return (TREE_CODE (scope) == NAMESPACE_DECL {
|| AGGREGATE_TYPE_P (scope)); if (scope != global_namespace)
{
dump_decl (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
| TS_FUNC_NORETURN | TS_DECL_TYPE);
OB_PUTS ("::");
}
else if (flags & TS_PEDANTIC_NAME)
OB_PUTS ("::");
}
else if (AGGREGATE_TYPE_P (scope))
{
dump_type (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
| TS_FUNC_NORETURN | TS_DECL_TYPE);
OB_PUTS ("::");
}
else if ((flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE))
&& TREE_CODE (scope) == FUNCTION_DECL)
{
dump_function_decl (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
| TS_FUNC_NORETURN | TS_DECL_TYPE);
OB_PUTS ("::");
}
} }
static void /* Dump type qualifiers, providing padding as requested. Return an
indication of whether we dumped something. */
static enum pad
dump_qualifiers (t, p) dump_qualifiers (t, p)
tree t; tree t;
enum pad p; enum pad p;
{ {
if (TYPE_QUALS (t)) 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;
if (quals)
{ {
if (p == before) OB_PUTC (' '); for (ix = 0; ix != 3; ix++)
switch (TYPE_QUALS (t)) if (masks[ix] & quals)
{ {
case TYPE_QUAL_CONST: if (p == before)
OB_PUTS ("const"); OB_PUTC (' ');
break; p = before;
OB_PUTCP (names[ix]);
case TYPE_QUAL_VOLATILE: }
OB_PUTS ("volatile"); if (do_after)
break; OB_PUTC (' ');
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 (' ');
} }
else
p = none;
return p;
} }
/* This must be large enough to hold any printed integer or floating-point /* This must be large enough to hold any printed integer or floating-point
value. */ value. */
static char digit_buffer[128]; static char digit_buffer[128];
/* Dump a template parameter or template argument VALUE at VERBOSITY /* Dump a template parameter or template argument VALUE under
level. The boolean CANONICAL_NAME indicates whether to dump abstract control of FLAGS. */
names, e.g. typedefs, or not. */
static void static void
dump_template_value (value, verbosity, canonical_name) dump_template_value (value, flags)
tree value; tree value;
int verbosity, canonical_name; enum tree_string_flags flags;
{ {
if (TREE_CODE_CLASS (TREE_CODE (value)) == 't' if (TREE_CODE_CLASS (TREE_CODE (value)) == 't'
|| TREE_CODE (value) == TEMPLATE_DECL) || TREE_CODE (value) == TEMPLATE_DECL)
dump_type_real (value, verbosity, canonical_name); dump_type (value, flags & ~TS_AGGR_TAGS);
else else
dump_expr (value, verbosity); dump_expr (value, (flags | TS_EXPR_PARENS) & ~TS_AGGR_TAGS);
} }
/* Dump into the obstack a human-readable equivalent of TYPE. */ /* Dump into the obstack a human-readable equivalent of TYPE. FLAGS
controls the format. */
static void static void
dump_type_real (t, v, canonical_name) dump_type (t, flags)
tree t; tree t;
int v; /* verbose? */ enum tree_string_flags flags;
int canonical_name;
{ {
if (t == NULL_TREE) if (t == NULL_TREE)
return; return;
...@@ -220,17 +242,13 @@ dump_type_real (t, v, canonical_name) ...@@ -220,17 +242,13 @@ dump_type_real (t, v, canonical_name)
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
case ERROR_MARK:
OB_PUTS ("{error}");
break;
case UNKNOWN_TYPE: case UNKNOWN_TYPE:
OB_PUTS ("{unknown type}"); OB_PUTS ("{unknown type}");
break; break;
case TREE_LIST: case TREE_LIST:
/* A list of function parms. */ /* A list of function parms. */
dump_parameters (t, 0, canonical_name); dump_parameters (t, flags);
break; break;
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
...@@ -238,24 +256,32 @@ dump_type_real (t, v, canonical_name) ...@@ -238,24 +256,32 @@ dump_type_real (t, v, canonical_name)
break; break;
case TREE_VEC: case TREE_VEC:
dump_type_real (BINFO_TYPE (t), v, canonical_name); dump_type (BINFO_TYPE (t), flags);
break; break;
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
dump_aggr_type (t, v, canonical_name); dump_aggr_type (t, flags);
break; break;
case TYPE_DECL: case TYPE_DECL:
if (flags & TS_CHASE_TYPEDEFS)
{
dump_type (DECL_ORIGINAL_TYPE (t)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
break;
}
/* else fallthrough */
case TEMPLATE_DECL: case TEMPLATE_DECL:
case NAMESPACE_DECL: case NAMESPACE_DECL:
dump_decl (t, v); dump_decl (t, flags & ~TS_DECL_TYPE);
break; break;
case COMPLEX_TYPE: case COMPLEX_TYPE:
OB_PUTS ("complex "); OB_PUTS ("complex ");
dump_type_real (TREE_TYPE (t), v, canonical_name); dump_type (TREE_TYPE (t), flags);
break; break;
case INTEGER_TYPE: case INTEGER_TYPE:
...@@ -271,7 +297,7 @@ dump_type_real (t, v, canonical_name) ...@@ -271,7 +297,7 @@ dump_type_real (t, v, canonical_name)
{ {
tree type; tree type;
dump_qualifiers (t, after); dump_qualifiers (t, after);
type = canonical_name ? TYPE_MAIN_VARIANT (t) : t; type = flags & TS_CHASE_TYPEDEFS ? TYPE_MAIN_VARIANT (t) : t;
if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
OB_PUTID (TYPE_IDENTIFIER (type)); OB_PUTID (TYPE_IDENTIFIER (type));
else else
...@@ -299,9 +325,10 @@ dump_type_real (t, v, canonical_name) ...@@ -299,9 +325,10 @@ dump_type_real (t, v, canonical_name)
OB_PUTC ('<'); OB_PUTC ('<');
for (i = 0; i < TREE_VEC_LENGTH (args); i++) for (i = 0; i < TREE_VEC_LENGTH (args); i++)
{ {
dump_template_value (TREE_VEC_ELT (args, i), 0, canonical_name); tree arg = TREE_VEC_ELT (args, i);
if (i < TREE_VEC_LENGTH (args)-1) if (i)
OB_PUTC2 (',', ' '); OB_PUTS (", ");
dump_template_value (arg, flags);
} }
OB_END_TEMPLATE_ID (); OB_END_TEMPLATE_ID ();
} }
...@@ -324,29 +351,37 @@ dump_type_real (t, v, canonical_name) ...@@ -324,29 +351,37 @@ dump_type_real (t, v, canonical_name)
offset_type: offset_type:
case FUNCTION_TYPE: case FUNCTION_TYPE:
case METHOD_TYPE: case METHOD_TYPE:
dump_type_prefix (t, v, canonical_name); {
dump_type_suffix (t, v, canonical_name); dump_type_prefix (t, flags);
dump_type_suffix (t, flags);
break; break;
}
case TYPENAME_TYPE: case TYPENAME_TYPE:
OB_PUTS ("typename "); OB_PUTS ("typename ");
dump_type_real (TYPE_CONTEXT (t), 0, canonical_name); dump_type (TYPE_CONTEXT (t), flags);
OB_PUTS ("::"); OB_PUTS ("::");
dump_decl (TYPENAME_TYPE_FULLNAME (t), v); dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
break; break;
case TYPEOF_TYPE: case TYPEOF_TYPE:
OB_PUTS ("__typeof ("); OB_PUTS ("__typeof (");
dump_expr (TYPE_FIELDS (t), 1); dump_expr (TYPE_FIELDS (t), flags & ~TS_EXPR_PARENS);
OB_PUTC (')'); OB_PUTC (')');
break; break;
default: default:
sorry ("`%s' not supported by dump_type", sorry ("`%s' not supported by dump_type",
tree_code_name[(int) TREE_CODE (t)]); tree_code_name[(int) TREE_CODE (t)]);
/* Fall through to error. */
case ERROR_MARK:
OB_PUTS ("{typeerror}");
break;
} }
} }
/* Return the name of the supplied aggregate, or enumeral type. */
static const char * static const char *
aggr_variety (t) aggr_variety (t)
tree t; tree t;
...@@ -361,50 +396,59 @@ aggr_variety (t) ...@@ -361,50 +396,59 @@ aggr_variety (t)
return "struct"; return "struct";
} }
static void /* Print out a class declaration T under the control of FLAGS,
dump_type (t, v) in the form `class foo'. */
tree t;
int v; /* verbose? */
{
dump_type_real (t, v, 0);
}
/* Print out a class declaration, in the form `class foo'. */
static void static void
dump_aggr_type (t, v, canonical_name) dump_aggr_type (t, flags)
tree t; tree t;
int v; /* verbose? */ enum tree_string_flags flags;
int canonical_name;
{ {
tree name; tree name;
const char *variety = aggr_variety (t); const char *variety = aggr_variety (t);
int typdef = 0;
int tmplate = 0;
dump_qualifiers (t, after); dump_qualifiers (t, after);
if (v > 0) if (flags & TS_AGGR_TAGS)
{ {
OB_PUTCP (variety); OB_PUTCP (variety);
OB_PUTC (' '); OB_PUTC (' ');
} }
name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t); if (flags & TS_CHASE_TYPEDEFS)
t = TYPE_MAIN_VARIANT (t);
if (name && CP_DECL_CONTEXT (name) != global_namespace) name = TYPE_NAME (t);
if (name)
{ {
/* FUNCTION_DECL or RECORD_TYPE */ typdef = !DECL_ARTIFICIAL (name);
dump_decl (DECL_CONTEXT (name), 0); tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
OB_PUTC2 (':', ':'); && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
&& (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
|| TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
|| DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
|| PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
dump_scope (CP_DECL_CONTEXT (name), flags | TS_FUNC_SCOPE);
if (tmplate)
{
/* Because the template names are mangled, we have to locate
the most general template, and use that name. */
tree tpl = CLASSTYPE_TI_TEMPLATE (t);
while (DECL_TEMPLATE_INFO (tpl))
tpl = DECL_TI_TEMPLATE (tpl);
name = tpl;
}
name = DECL_NAME (name);
} }
/* kludge around weird behavior on g++.brendan/line1.C */
if (name && TREE_CODE (name) != IDENTIFIER_NODE)
name = DECL_NAME (name);
if (name == 0 || ANON_AGGRNAME_P (name)) if (name == 0 || ANON_AGGRNAME_P (name))
{ {
OB_PUTS ("{anonymous"); OB_PUTS ("{anonymous");
if (!v) if (!(flags & TS_AGGR_TAGS))
{ {
OB_PUTC (' '); OB_PUTC (' ');
OB_PUTCP (variety); OB_PUTCP (variety);
...@@ -413,6 +457,10 @@ dump_aggr_type (t, v, canonical_name) ...@@ -413,6 +457,10 @@ dump_aggr_type (t, v, canonical_name)
} }
else else
OB_PUTID (name); OB_PUTID (name);
if (tmplate)
dump_template_parms (TYPE_TEMPLATE_INFO (t),
!CLASSTYPE_USE_TEMPLATE (t),
flags & ~TS_TEMPLATE_PREFIX);
} }
/* Dump into the obstack the initial part of the output for a given type. /* Dump into the obstack the initial part of the output for a given type.
...@@ -424,14 +472,18 @@ dump_aggr_type (t, v, canonical_name) ...@@ -424,14 +472,18 @@ dump_aggr_type (t, v, canonical_name)
deal with prefix and suffix. deal with prefix and suffix.
Arrays must also do this for DECL nodes, like int a[], and for things like Arrays must also do this for DECL nodes, like int a[], and for things like
int *[]&. */ int *[]&.
Return indicates how you should pad an object name after this. I.e. you
want to pad non-*, non-& cores, but not pad * or & types. */
static void static enum pad
dump_type_prefix (t, v, canonical_name) dump_type_prefix (t, flags)
tree t; tree t;
int v; /* verbosity */ enum tree_string_flags flags;
int canonical_name;
{ {
enum pad padding = before;
if (TYPE_PTRMEMFUNC_P (t)) if (TYPE_PTRMEMFUNC_P (t))
{ {
t = TYPE_PTRMEMFUNC_FN_TYPE (t); t = TYPE_PTRMEMFUNC_FN_TYPE (t);
...@@ -445,73 +497,60 @@ dump_type_prefix (t, v, canonical_name) ...@@ -445,73 +497,60 @@ dump_type_prefix (t, v, canonical_name)
{ {
tree sub = TREE_TYPE (t); tree sub = TREE_TYPE (t);
dump_type_prefix (sub, v, canonical_name); padding = dump_type_prefix (sub, flags);
/* A tree for a member pointer looks like pointer to offset, /* A tree for a member pointer looks like pointer to offset,
so let the OFFSET_TYPE case handle it. */ so let the OFFSET_TYPE case handle it. */
if (!TYPE_PTRMEM_P (t)) if (!TYPE_PTRMEM_P (t))
{ {
switch (TREE_CODE (sub)) if (padding != none)
{ OB_PUTC (' ');
/* We don't want int ( *)() */ if (TREE_CODE (sub) == ARRAY_TYPE)
case FUNCTION_TYPE: OB_PUTC ('(');
case METHOD_TYPE: OB_PUTC ("&*"[TREE_CODE (t) == POINTER_TYPE]);
break; padding = dump_qualifiers (t, none);
case ARRAY_TYPE:
OB_PUTC2 (' ', '(');
break;
case POINTER_TYPE:
/* We don't want "char * *" */
if (TYPE_QUALS (sub) == TYPE_UNQUALIFIED)
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);
} }
} }
break; break;
case OFFSET_TYPE: case OFFSET_TYPE:
offset_type: offset_type:
dump_type_prefix (TREE_TYPE (t), v, canonical_name); padding = dump_type_prefix (TREE_TYPE (t), flags);
if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
{ {
OB_PUTC (' '); if (padding != none)
dump_type_real (TYPE_OFFSET_BASETYPE (t), 0, canonical_name); OB_PUTC (' ');
OB_PUTC2 (':', ':'); dump_type (TYPE_OFFSET_BASETYPE (t), flags);
OB_PUTS ("::");
} }
OB_PUTC ('*'); OB_PUTC ('*');
dump_qualifiers (t, none); padding = dump_qualifiers (t, none);
break; break;
/* Can only be reached through function pointer -- this would not be /* Can only be reached through function pointer -- this would not be
correct if FUNCTION_DECLs used it. */ correct if FUNCTION_DECLs used it. */
case FUNCTION_TYPE: case FUNCTION_TYPE:
dump_type_prefix (TREE_TYPE (t), v, canonical_name); padding = dump_type_prefix (TREE_TYPE (t), flags);
OB_PUTC2 (' ', '('); if (padding != none)
OB_PUTC (' ');
OB_PUTC ('(');
padding = none;
break; break;
case METHOD_TYPE: case METHOD_TYPE:
dump_type_prefix (TREE_TYPE (t), v, canonical_name); padding = dump_type_prefix (TREE_TYPE (t), flags);
OB_PUTC2 (' ', '('); if (padding != none)
dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0, canonical_name); OB_PUTC (' ');
OB_PUTC2 (':', ':'); OB_PUTC ('(');
padding = none;
dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
OB_PUTS ("::");
break; break;
case ARRAY_TYPE: case ARRAY_TYPE:
dump_type_prefix (TREE_TYPE (t), v, canonical_name); padding = dump_type_prefix (TREE_TYPE (t), flags);
break; break;
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
case ERROR_MARK:
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
case INTEGER_TYPE: case INTEGER_TYPE:
case BOOLEAN_TYPE: case BOOLEAN_TYPE:
...@@ -527,20 +566,28 @@ dump_type_prefix (t, v, canonical_name) ...@@ -527,20 +566,28 @@ dump_type_prefix (t, v, canonical_name)
case VOID_TYPE: case VOID_TYPE:
case TYPENAME_TYPE: case TYPENAME_TYPE:
case COMPLEX_TYPE: case COMPLEX_TYPE:
dump_type_real (t, v, canonical_name); dump_type (t, flags);
padding = before;
break; break;
default: default:
sorry ("`%s' not supported by dump_type_prefix", sorry ("`%s' not supported by dump_type_prefix",
tree_code_name[(int) TREE_CODE (t)]); tree_code_name[(int) TREE_CODE (t)]);
case ERROR_MARK:
OB_PUTS ("{typeprefixerror}");
break;
} }
return padding;
} }
/* Dump the suffix of type T, under control of FLAGS. This is the part
which appears after the identifier (or function parms). */
static void static void
dump_type_suffix (t, v, canonical_name) dump_type_suffix (t, flags)
tree t; tree t;
int v; /* verbose? */ enum tree_string_flags flags;
int canonical_name;
{ {
if (TYPE_PTRMEMFUNC_P (t)) if (TYPE_PTRMEMFUNC_P (t))
t = TYPE_PTRMEMFUNC_FN_TYPE (t); t = TYPE_PTRMEMFUNC_FN_TYPE (t);
...@@ -552,7 +599,7 @@ dump_type_suffix (t, v, canonical_name) ...@@ -552,7 +599,7 @@ dump_type_suffix (t, v, canonical_name)
case OFFSET_TYPE: case OFFSET_TYPE:
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
OB_PUTC (')'); OB_PUTC (')');
dump_type_suffix (TREE_TYPE (t), v, canonical_name); dump_type_suffix (TREE_TYPE (t), flags);
break; break;
/* Can only be reached through function pointer */ /* Can only be reached through function pointer */
...@@ -567,13 +614,13 @@ dump_type_suffix (t, v, canonical_name) ...@@ -567,13 +614,13 @@ dump_type_suffix (t, v, canonical_name)
/* Function pointers don't have default args. Not in standard C++, /* Function pointers don't have default args. Not in standard C++,
anyway; they may in g++, but we'll just pretend otherwise. */ anyway; they may in g++, but we'll just pretend otherwise. */
dump_parameters (arg, 0, canonical_name); dump_parameters (arg, flags & ~TS_PARM_DEFAULTS);
if (TREE_CODE (t) == METHOD_TYPE) if (TREE_CODE (t) == METHOD_TYPE)
dump_qualifiers dump_qualifiers
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
dump_type_suffix (TREE_TYPE (t), v, canonical_name); dump_type_suffix (TREE_TYPE (t), flags);
dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), canonical_name); dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
break; break;
} }
...@@ -584,18 +631,19 @@ dump_type_suffix (t, v, canonical_name) ...@@ -584,18 +631,19 @@ dump_type_suffix (t, v, canonical_name)
if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST) if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); 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) else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0); dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0),
flags & ~TS_EXPR_PARENS);
else else
dump_expr (fold (build_binary_op dump_expr (fold (build_binary_op
(PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
integer_one_node)), 0); integer_one_node)),
flags & ~TS_EXPR_PARENS);
} }
OB_PUTC (']'); OB_PUTC (']');
dump_type_suffix (TREE_TYPE (t), v, canonical_name); dump_type_suffix (TREE_TYPE (t), flags);
break; break;
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
case ERROR_MARK:
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
case INTEGER_TYPE: case INTEGER_TYPE:
case BOOLEAN_TYPE: case BOOLEAN_TYPE:
...@@ -616,6 +664,11 @@ dump_type_suffix (t, v, canonical_name) ...@@ -616,6 +664,11 @@ dump_type_suffix (t, v, canonical_name)
default: default:
sorry ("`%s' not supported by dump_type_suffix", sorry ("`%s' not supported by dump_type_suffix",
tree_code_name[(int) TREE_CODE (t)]); tree_code_name[(int) TREE_CODE (t)]);
case ERROR_MARK:
/* Don't mark it here, we should have already done in
dump_type_prefix. */
break;
} }
} }
...@@ -674,60 +727,57 @@ dump_global_iord (t) ...@@ -674,60 +727,57 @@ dump_global_iord (t)
} }
static void static void
dump_simple_decl (t, type, v) dump_simple_decl (t, type, flags)
tree t; tree t;
tree type; tree type;
int v; enum tree_string_flags flags;
{ {
if (v > 0) if (flags & TS_DECL_TYPE)
{ {
dump_type_prefix (type, v, 0); if (dump_type_prefix (type, flags) != none)
OB_PUTC (' '); OB_PUTC (' ');
}
if (interesting_scope_p (DECL_CONTEXT (t)))
{
dump_decl (DECL_CONTEXT (t), 0);
OB_PUTC2 (':',':');
} }
if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
dump_scope (CP_DECL_CONTEXT (t), flags);
if (DECL_NAME (t)) if (DECL_NAME (t))
dump_decl (DECL_NAME (t), v); dump_decl (DECL_NAME (t), flags);
else else
OB_PUTS ("{anon}"); OB_PUTS ("{anon}");
if (v > 0) if (flags & TS_DECL_TYPE)
dump_type_suffix (type, v, 0); dump_type_suffix (type, flags);
} }
/* Dump a human readable string for the decl T under control of FLAGS. */
static void static void
dump_decl (t, v) dump_decl (t, flags)
tree t; tree t;
int v; /* verbosity */ enum tree_string_flags flags;
{ {
if (t == NULL_TREE) if (t == NULL_TREE)
return; return;
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
case ERROR_MARK:
OB_PUTS (" /* decl error */ ");
break;
case TYPE_DECL: case TYPE_DECL:
{ {
/* Don't say 'typedef class A' */ /* Don't say 'typedef class A' */
if (DECL_ARTIFICIAL (t)) if (DECL_ARTIFICIAL (t))
{ {
if (v > 0 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) if ((flags & TS_DECL_TYPE)
&& TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
/* Say `class T' not just `T'. */ /* Say `class T' not just `T'. */
OB_PUTS ("class "); OB_PUTS ("class ");
dump_type (TREE_TYPE (t), v); dump_type (TREE_TYPE (t), flags);
break; break;
} }
} }
if (v > 0) if (flags & TS_DECORATE)
OB_PUTS ("typedef "); OB_PUTS ("typedef ");
dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), v); ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
flags);
break; break;
case VAR_DECL: case VAR_DECL:
...@@ -735,7 +785,7 @@ dump_decl (t, v) ...@@ -735,7 +785,7 @@ dump_decl (t, v)
{ {
OB_PUTS ("vtable for "); OB_PUTS ("vtable for ");
if (TYPE_P (DECL_CONTEXT (t))) if (TYPE_P (DECL_CONTEXT (t)))
dump_type (DECL_CONTEXT (t), v); dump_type (DECL_CONTEXT (t), flags);
else else
/* This case can arise with -fno-vtable-thunks. See /* This case can arise with -fno-vtable-thunks. See
expand_upcast_fixups. It's not clear what to print expand_upcast_fixups. It's not clear what to print
...@@ -746,15 +796,11 @@ dump_decl (t, v) ...@@ -746,15 +796,11 @@ dump_decl (t, v)
/* else fall through */ /* else fall through */
case FIELD_DECL: case FIELD_DECL:
case PARM_DECL: case PARM_DECL:
dump_simple_decl (t, TREE_TYPE (t), v); dump_simple_decl (t, TREE_TYPE (t), flags);
break; break;
case NAMESPACE_DECL: case NAMESPACE_DECL:
if (CP_DECL_CONTEXT (t) != global_namespace) dump_scope (CP_DECL_CONTEXT (t), flags);
{
dump_decl (DECL_CONTEXT (t), v);
OB_PUTC2 (':',':');
}
if (DECL_NAME (t) == anonymous_namespace_name) if (DECL_NAME (t) == anonymous_namespace_name)
OB_PUTS ("{anonymous}"); OB_PUTS ("{anonymous}");
else else
...@@ -762,24 +808,23 @@ dump_decl (t, v) ...@@ -762,24 +808,23 @@ dump_decl (t, v)
break; break;
case SCOPE_REF: case SCOPE_REF:
dump_decl (TREE_OPERAND (t, 0), 0); dump_decl (TREE_OPERAND (t, 0), flags & ~TS_DECL_TYPE);
OB_PUTS ("::"); OB_PUTS ("::");
dump_decl (TREE_OPERAND (t, 1), 0); dump_decl (TREE_OPERAND (t, 1), flags);
break; break;
case ARRAY_REF: case ARRAY_REF:
dump_decl (TREE_OPERAND (t, 0), v); dump_decl (TREE_OPERAND (t, 0), flags);
OB_PUTC ('['); OB_PUTC ('[');
dump_decl (TREE_OPERAND (t, 1), v); dump_decl (TREE_OPERAND (t, 1), flags);
OB_PUTC (']'); OB_PUTC (']');
break; break;
/* So that we can do dump_decl in dump_aggr_type and have it work for /* So that we can do dump_decl on an aggr type. */
both class and function scope. */
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
dump_type (t, v); dump_type (t, flags);
break; break;
case TYPE_EXPR: case TYPE_EXPR:
...@@ -795,13 +840,13 @@ dump_decl (t, v) ...@@ -795,13 +840,13 @@ dump_decl (t, v)
&& DECL_LANGUAGE (f) == lang_cplusplus) && DECL_LANGUAGE (f) == lang_cplusplus)
{ {
OB_PUTC ('~'); OB_PUTC ('~');
dump_decl (DECL_NAME (f), 0); dump_decl (DECL_NAME (f), flags);
} }
else if (IDENTIFIER_TYPENAME_P (t)) else if (IDENTIFIER_TYPENAME_P (t))
{ {
OB_PUTS ("operator "); OB_PUTS ("operator ");
/* Not exactly IDENTIFIER_TYPE_VALUE. */ /* Not exactly IDENTIFIER_TYPE_VALUE. */
dump_type (TREE_TYPE (t), 0); dump_type (TREE_TYPE (t), flags);
break; break;
} }
else if (IDENTIFIER_OPNAME_P (t)) else if (IDENTIFIER_OPNAME_P (t))
...@@ -824,77 +869,17 @@ dump_decl (t, v) ...@@ -824,77 +869,17 @@ dump_decl (t, v)
dump_global_iord (DECL_ASSEMBLER_NAME (t)); dump_global_iord (DECL_ASSEMBLER_NAME (t));
else if (! DECL_LANG_SPECIFIC (t)) else if (! DECL_LANG_SPECIFIC (t))
OB_PUTS ("{internal}"); OB_PUTS ("{internal}");
else if (flags & TS_PEDANTIC_NAME)
dump_function_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
else else
dump_function_decl (t, v); dump_function_decl (t, flags);
break; break;
case TEMPLATE_DECL: case TEMPLATE_DECL:
{ if (flags & TS_PEDANTIC_NAME)
tree orig_args = DECL_TEMPLATE_PARMS (t); dump_template_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
tree args; else
int i; dump_template_decl (t, flags);
for (args = orig_args = nreverse (orig_args);
args;
args = TREE_CHAIN (args))
{
int len = TREE_VEC_LENGTH (TREE_VALUE (args));
OB_PUTS ("template <");
for (i = 0; i < len; i++)
{
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 (',', ' ');
}
if (len != 0)
OB_UNPUT (2);
OB_END_TEMPLATE_ID ();
OB_PUTC (' ');
}
nreverse(orig_args);
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))
{
case METHOD_TYPE:
case FUNCTION_TYPE:
dump_function_decl (t, v);
break;
default:
/* This case can occur with some illegal code. */
dump_type (TREE_TYPE (t), v);
}
}
break; break;
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
...@@ -903,20 +888,20 @@ dump_decl (t, v) ...@@ -903,20 +888,20 @@ dump_decl (t, v)
tree name = TREE_OPERAND (t, 0); tree name = TREE_OPERAND (t, 0);
if (is_overloaded_fn (name)) if (is_overloaded_fn (name))
name = DECL_NAME (get_first_fn (name)); name = DECL_NAME (get_first_fn (name));
dump_decl (name, v); dump_decl (name, flags);
OB_PUTC ('<'); OB_PUTC ('<');
for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
{ {
dump_template_value (TREE_VALUE (args), 0, 0); dump_template_value (TREE_VALUE (args), flags);
if (TREE_CHAIN (args)) if (TREE_CHAIN (args))
OB_PUTC2 (',', ' '); OB_PUTS (", ");
} }
OB_END_TEMPLATE_ID (); OB_END_TEMPLATE_ID ();
} }
break; break;
case LOOKUP_EXPR: case LOOKUP_EXPR:
dump_decl (TREE_OPERAND (t, 0), v); dump_decl (TREE_OPERAND (t, 0), flags);
break; break;
case LABEL_DECL: case LABEL_DECL:
...@@ -927,18 +912,18 @@ dump_decl (t, v) ...@@ -927,18 +912,18 @@ dump_decl (t, v)
if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
|| (DECL_INITIAL (t) && || (DECL_INITIAL (t) &&
TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
dump_simple_decl (t, TREE_TYPE (t), v); dump_simple_decl (t, TREE_TYPE (t), flags);
else if (DECL_NAME (t)) else if (DECL_NAME (t))
dump_decl (DECL_NAME (t), v); dump_decl (DECL_NAME (t), flags);
else if (DECL_INITIAL (t)) else if (DECL_INITIAL (t))
dump_expr (DECL_INITIAL (t), 0); dump_expr (DECL_INITIAL (t), flags | TS_EXPR_PARENS);
else else
OB_PUTS ("enumerator"); OB_PUTS ("enumerator");
break; break;
case USING_DECL: case USING_DECL:
OB_PUTS ("using "); OB_PUTS ("using ");
dump_type (DECL_INITIAL (t), 0); dump_type (DECL_INITIAL (t), flags);
OB_PUTS ("::"); OB_PUTS ("::");
OB_PUTID (DECL_NAME (t)); OB_PUTID (DECL_NAME (t));
break; break;
...@@ -946,33 +931,114 @@ dump_decl (t, v) ...@@ -946,33 +931,114 @@ dump_decl (t, v)
default: default:
sorry ("`%s' not supported by dump_decl", sorry ("`%s' not supported by dump_decl",
tree_code_name[(int) TREE_CODE (t)]); tree_code_name[(int) TREE_CODE (t)]);
/* Fallthrough to error. */
case ERROR_MARK:
OB_PUTS ("{declerror}");
break;
}
}
/* Dump a template declaration T under control of FLAGS. This means the
'template <...> leaders plus the 'class X' or 'void fn(...)' part. */
static void
dump_template_decl (t, flags)
tree t;
enum tree_string_flags flags;
{
tree orig_args = DECL_TEMPLATE_PARMS (t);
tree args;
int i;
if (flags & TS_TEMPLATE_PREFIX)
{
for (args = orig_args = nreverse (orig_args);
args;
args = TREE_CHAIN (args))
{
int len = TREE_VEC_LENGTH (TREE_VALUE (args));
OB_PUTS ("template <");
for (i = 0; i < len; i++)
{
tree arg = TREE_VEC_ELT (TREE_VALUE (args), i);
tree defval = TREE_PURPOSE (arg);
arg = TREE_VALUE (arg);
if (i)
OB_PUTS (", ");
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, flags | TS_DECL_TYPE);
if (defval)
{
OB_PUTS (" = ");
if (TREE_CODE (arg) == TYPE_DECL
|| TREE_CODE (arg) == TEMPLATE_DECL)
dump_type (defval, flags);
else
dump_expr (defval, flags | TS_EXPR_PARENS);
}
}
OB_END_TEMPLATE_ID ();
OB_PUTC (' ');
}
nreverse(orig_args);
/* If we've shown the template<args> prefix, we'd better show the
* decl's type too. */
flags |= TS_DECL_TYPE;
}
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
dump_type (TREE_TYPE (t),
((flags & ~TS_AGGR_TAGS) | TS_TEMPLATE_PLAIN
| (flags & TS_DECL_TYPE ? TS_AGGR_TAGS : 0)));
else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
dump_decl (DECL_TEMPLATE_RESULT (t), flags | TS_TEMPLATE_PLAIN);
else if (TREE_TYPE (t) == NULL_TREE)
my_friendly_abort (353);
else
switch (NEXT_CODE (t))
{
case METHOD_TYPE:
case FUNCTION_TYPE:
dump_function_decl (t, flags | TS_TEMPLATE_PLAIN);
break;
default:
/* This case can occur with some illegal code. */
dump_type (TREE_TYPE (t),
(flags & ~TS_AGGR_TAGS) | TS_TEMPLATE_PLAIN
| (flags & TS_DECL_TYPE ? TS_AGGR_TAGS : 0));
} }
} }
/* Pretty print a function decl. There are several ways we want to print a /* Pretty print a function decl. There are several ways we want to print a
function declaration. We use V to tell us what. function declaration. The TS_FUNC bits in FLAGS tells us how to behave.
V - 01 23
args - ++ ++
retval - -+ ++
default- -+ -+
throw - -- ++
As cp_error can only apply the '#' flag once to give 0 and 1 for V, there As cp_error can only apply the '#' flag once to give 0 and 1 for V, there
is %D which doesn't print the throw specs, and %F which does. */ is %D which doesn't print the throw specs, and %F which does. */
static void static void
dump_function_decl (t, v) dump_function_decl (t, flags)
tree t; tree t;
int v; enum tree_string_flags flags;
{ {
tree name;
tree fntype; tree fntype;
tree parmtypes; tree parmtypes;
tree cname = NULL_TREE; tree cname = NULL_TREE;
int show_return = !(flags & TS_FUNC_NORETURN) && (flags & TS_DECL_TYPE);
if (TREE_CODE (t) == TEMPLATE_DECL) if (TREE_CODE (t) == TEMPLATE_DECL)
t = DECL_TEMPLATE_RESULT (t); t = DECL_TEMPLATE_RESULT (t);
name = DECL_ASSEMBLER_NAME (t);
fntype = TREE_TYPE (t); fntype = TREE_TYPE (t);
parmtypes = TYPE_ARG_TYPES (fntype); parmtypes = TYPE_ARG_TYPES (fntype);
...@@ -983,90 +1049,86 @@ dump_function_decl (t, v) ...@@ -983,90 +1049,86 @@ dump_function_decl (t, v)
else if (TREE_CODE (fntype) == METHOD_TYPE) else if (TREE_CODE (fntype) == METHOD_TYPE)
cname = TREE_TYPE (TREE_VALUE (parmtypes)); cname = TREE_TYPE (TREE_VALUE (parmtypes));
/* Print the return type. */ if (!(flags & TS_DECORATE))
if (v > 0) /* OK */;
else if (DECL_STATIC_FUNCTION_P (t))
OB_PUTS ("static ");
else if (TYPE_VIRTUAL_P (t))
OB_PUTS ("virtual ");
/* Print the return type? */
if (show_return)
show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t)
&& !DECL_DESTRUCTOR_P (t);
if (show_return)
{ {
if (DECL_STATIC_FUNCTION_P (t)) if (dump_type_prefix (TREE_TYPE (fntype), flags) != none)
OB_PUTS ("static "); OB_PUTC (' ');
if (! DECL_CONV_FN_P (t)
&& ! DECL_CONSTRUCTOR_P (t)
&& ! DECL_DESTRUCTOR_P (t))
{
dump_type_prefix (TREE_TYPE (fntype), 0, 0);
OB_PUTC (' ');
}
} }
/* Print the function name. */ /* Print the function name. */
if (cname) if (cname)
{ {
dump_type (cname, 0); dump_type (cname, flags);
OB_PUTC2 (':', ':'); OB_PUTS ("::");
if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
parmtypes = TREE_CHAIN (parmtypes);
if (DECL_CONSTRUCTOR_FOR_VBASE_P (t))
/* 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 (':',':');
} }
else
dump_scope (CP_DECL_CONTEXT (t), flags);
if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus) dump_function_name (t, flags);
parmtypes = TREE_CHAIN (parmtypes);
dump_function_name (t); if (!(flags & TS_DECL_TYPE))
/* If V is negative, we don't print the argument types. */
if (v < 0)
return; return;
if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
dump_parameters (parmtypes, v & 1, 0); /* Skip "this" parameter. */
parmtypes = TREE_CHAIN (parmtypes);
if (DECL_DESTRUCTOR_P (t) || DECL_CONSTRUCTOR_FOR_VBASE_P (t))
/* Skip past "in_charge" identifier. */
parmtypes = TREE_CHAIN (parmtypes);
dump_parameters (parmtypes, flags);
if (v && ! DECL_CONV_FN_P (t)) if (show_return)
dump_type_suffix (TREE_TYPE (fntype), 1, 0); dump_type_suffix (TREE_TYPE (fntype), flags);
if (TREE_CODE (fntype) == METHOD_TYPE) if (TREE_CODE (fntype) == METHOD_TYPE)
dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
before); before);
if (v >= 2) if (flags & TS_FUNC_THROW)
dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), 0); dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
} }
/* Print a parameter list. V indicates if we show default values or not. If /* Print a parameter list. If this is for a member function, the
these are for a member function, the member object ptr member object ptr (and any other hidden args) should have
(and any other hidden args) should have already been removed. */ already been removed. */
static void static void
dump_parameters (parmtypes, v, canonical_name) dump_parameters (parmtypes, flags)
tree parmtypes; tree parmtypes;
int v; enum tree_string_flags flags;
int canonical_name;
{ {
int first; int first;
OB_PUTC ('('); OB_PUTS (" (");
for (first = 1; parmtypes != void_list_node; for (first = 1; parmtypes != void_list_node;
parmtypes = TREE_CHAIN (parmtypes)) parmtypes = TREE_CHAIN (parmtypes))
{ {
if (!first) if (!first)
OB_PUTC2 (',', ' '); OB_PUTS (", ");
first = 0; first = 0;
if (!parmtypes) if (!parmtypes)
{ {
OB_PUTS ("..."); OB_PUTS ("...");
break; break;
} }
dump_type_real (TREE_VALUE (parmtypes), 0, canonical_name); dump_type (TREE_VALUE (parmtypes), flags);
if (TREE_PURPOSE (parmtypes) && v) if ((flags & TS_PARM_DEFAULTS) && TREE_PURPOSE (parmtypes))
{ {
OB_PUTS (" = "); OB_PUTS (" = ");
dump_expr (TREE_PURPOSE (parmtypes), 0); dump_expr (TREE_PURPOSE (parmtypes), flags | TS_EXPR_PARENS);
} }
} }
...@@ -1076,9 +1138,9 @@ dump_parameters (parmtypes, v, canonical_name) ...@@ -1076,9 +1138,9 @@ dump_parameters (parmtypes, v, canonical_name)
/* Print an exception specification. T is the exception specification. */ /* Print an exception specification. T is the exception specification. */
static void static void
dump_exception_spec (t, canonical_name) dump_exception_spec (t, flags)
tree t; tree t;
int canonical_name; enum tree_string_flags flags;
{ {
if (t) if (t)
{ {
...@@ -1086,11 +1148,11 @@ dump_exception_spec (t, canonical_name) ...@@ -1086,11 +1148,11 @@ dump_exception_spec (t, canonical_name)
if (TREE_VALUE (t) != NULL_TREE) if (TREE_VALUE (t) != NULL_TREE)
while (1) while (1)
{ {
dump_type_real (TREE_VALUE (t), 0, canonical_name); dump_type (TREE_VALUE (t), flags);
t = TREE_CHAIN (t); t = TREE_CHAIN (t);
if (!t) if (!t)
break; break;
OB_PUTC2 (',', ' '); OB_PUTS (", ");
} }
OB_PUTC (')'); OB_PUTC (')');
} }
...@@ -1100,15 +1162,16 @@ dump_exception_spec (t, canonical_name) ...@@ -1100,15 +1162,16 @@ dump_exception_spec (t, canonical_name)
and destructors properly. */ and destructors properly. */
static void static void
dump_function_name (t) dump_function_name (t, flags)
tree t; tree t;
enum tree_string_flags flags;
{ {
tree name = DECL_NAME (t); tree name = DECL_NAME (t);
if (DECL_DESTRUCTOR_P (t)) if (DECL_DESTRUCTOR_P (t))
{ {
OB_PUTC ('~'); OB_PUTC ('~');
dump_decl (name, 0); dump_decl (name, TS_PLAIN);
} }
else if (DECL_CONV_FN_P (t)) else if (DECL_CONV_FN_P (t))
{ {
...@@ -1119,7 +1182,7 @@ dump_function_name (t) ...@@ -1119,7 +1182,7 @@ dump_function_name (t)
the types will be different, hence the TREE_TYPE field the types will be different, hence the TREE_TYPE field
of the first name will be clobbered by the second. */ of the first name will be clobbered by the second. */
OB_PUTS ("operator "); OB_PUTS ("operator ");
dump_type (TREE_TYPE (TREE_TYPE (t)), 0); dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
} }
else if (IDENTIFIER_OPNAME_P (name)) else if (IDENTIFIER_OPNAME_P (name))
{ {
...@@ -1128,66 +1191,118 @@ dump_function_name (t) ...@@ -1128,66 +1191,118 @@ dump_function_name (t)
OB_PUTCP (name_string); OB_PUTCP (name_string);
} }
else else
dump_decl (name, 0); dump_decl (name, flags);
if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t) if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
&& DECL_TEMPLATE_INFO (t)
&& (DECL_TEMPLATE_SPECIALIZATION (t) && (DECL_TEMPLATE_SPECIALIZATION (t)
|| TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
|| DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t)) || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
|| PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
{ dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
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 /* Dump the template parameters from the template info INFO under control of
FLAGS. PRIMARY indicates whether this is a primary template decl, or
specialization (partial or complete). For partial specializations we show
the specialized parameter values. For a primary template we show no
decoration. */
static void
dump_template_parms (info, primary, flags)
tree info;
int primary;
enum tree_string_flags flags;
{
tree args = info ? TI_ARGS (info) : NULL_TREE;
if (primary && flags & TS_TEMPLATE_PLAIN)
return;
flags &= ~(TS_AGGR_TAGS | TS_TEMPLATE_PLAIN);
OB_PUTC ('<');
/* Be careful only to print things when we have them, so as not
to crash producing error messages. */ to crash producing error messages. */
if (args) if (args && !primary)
{ {
if (TREE_CODE (args) == TREE_LIST) int len = 0;
{ int ix = 0;
tree arg; int need_comma = 0;
int need_comma = 0;
if (TREE_CODE (args) == TREE_VEC)
for (arg = args; arg; arg = TREE_CHAIN (arg)) {
{ if (TREE_VEC_LENGTH (args) > 0
tree a = TREE_VALUE (arg); && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
if (need_comma)
OB_PUTS (", "); len = TREE_VEC_LENGTH (args);
}
if (a) else if (TREE_CODE (args) == TREE_LIST)
dump_template_value (a, 0, 0); len = -1;
while (ix != len && args)
need_comma = 1; {
} tree arg;
} if (len >= 0)
else if (TREE_CODE (args) == TREE_VEC) {
{ arg = TREE_VEC_ELT (args, ix);
int i; ix++;
int need_comma = 0; }
else
if (TREE_VEC_LENGTH (args) > 0 {
&& TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) arg = TREE_VALUE (args);
args = TREE_VEC_ELT (args, args = TREE_CHAIN (args);
TREE_VEC_LENGTH (args) - 1); }
if (need_comma)
for (i = 0; i < TREE_VEC_LENGTH (args); i++) OB_PUTS (", ");
{
tree a = TREE_VEC_ELT (args, i); if (!arg)
OB_PUTS ("{tplparmerror}");
if (need_comma) else
OB_PUTS (", "); dump_template_value (arg, flags);
need_comma = 1;
if (a) }
dump_template_value (a, 0, 0); }
else if (flags & TS_PEDANTIC_NAME)
need_comma = 1; {
} tree tpl = TI_TEMPLATE (info);
} tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tpl));
} int len = TREE_VEC_LENGTH (parms);
OB_END_TEMPLATE_ID (); int ix;
for (ix = 0; ix != len; ix++)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
if (ix)
OB_PUTS (", ");
if (TREE_CODE (parm) == TYPE_DECL)
OB_PUTS ("class");
else if (TREE_CODE (parm) == TEMPLATE_DECL)
dump_decl (DECL_TEMPLATE_RESULT (parm), flags);
else
dump_type (TREE_TYPE (parm),
flags | TS_TEMPLATE_PARM);
}
}
else if (primary)
{
tree tpl = TI_TEMPLATE (info);
tree parms = DECL_TEMPLATE_PARMS (tpl);
int len, ix;
parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
len = parms ? TREE_VEC_LENGTH (parms) : 0;
for (ix = 0; ix != len; ix++)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
if (ix)
OB_PUTS (", ");
dump_decl (parm, flags & ~TS_DECL_TYPE);
}
} }
OB_END_TEMPLATE_ID ();
} }
static void static void
...@@ -1240,24 +1355,25 @@ dump_char (c) ...@@ -1240,24 +1355,25 @@ dump_char (c)
/* Print out a list of initializers (subr of dump_expr) */ /* Print out a list of initializers (subr of dump_expr) */
static void static void
dump_expr_list (l) dump_expr_list (l, flags)
tree l; tree l;
enum tree_string_flags flags;
{ {
while (l) while (l)
{ {
dump_expr (TREE_VALUE (l), 0); dump_expr (TREE_VALUE (l), flags | TS_EXPR_PARENS);
if (TREE_CHAIN (l))
OB_PUTC2 (',', ' ');
l = TREE_CHAIN (l); l = TREE_CHAIN (l);
if (l)
OB_PUTS (", ");
} }
} }
/* Print out an expression */ /* Print out an expression E under control of FLAGS. */
static void static void
dump_expr (t, nop) dump_expr (t, flags)
tree t; tree t;
int nop; /* suppress parens */ enum tree_string_flags flags;
{ {
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
...@@ -1269,7 +1385,7 @@ dump_expr (t, nop) ...@@ -1269,7 +1385,7 @@ dump_expr (t, nop)
case TEMPLATE_DECL: case TEMPLATE_DECL:
case NAMESPACE_DECL: case NAMESPACE_DECL:
case OVERLOAD: case OVERLOAD:
dump_decl (t, -1); dump_decl (t, flags & ~TS_DECL_TYPE);
break; break;
case INTEGER_CST: case INTEGER_CST:
...@@ -1341,7 +1457,7 @@ dump_expr (t, nop) ...@@ -1341,7 +1457,7 @@ dump_expr (t, nop)
case PTRMEM_CST: case PTRMEM_CST:
OB_PUTC ('&'); OB_PUTC ('&');
dump_type (PTRMEM_CST_CLASS (t), 0); dump_type (PTRMEM_CST_CLASS (t), flags);
OB_PUTS ("::"); OB_PUTS ("::");
OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t))); OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t)));
break; break;
...@@ -1360,16 +1476,20 @@ dump_expr (t, nop) ...@@ -1360,16 +1476,20 @@ dump_expr (t, nop)
break; break;
case COMPOUND_EXPR: case COMPOUND_EXPR:
dump_binary_op (",", t); OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTS (", ");
dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
OB_PUTC (')');
break; break;
case COND_EXPR: case COND_EXPR:
OB_PUTC ('('); OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTS (" ? "); OB_PUTS (" ? ");
dump_expr (TREE_OPERAND (t, 1), 0); dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
OB_PUTS (" : "); OB_PUTS (" : ");
dump_expr (TREE_OPERAND (t, 2), 0); dump_expr (TREE_OPERAND (t, 2), flags | TS_EXPR_PARENS);
OB_PUTC (')'); OB_PUTC (')');
break; break;
...@@ -1377,11 +1497,11 @@ dump_expr (t, nop) ...@@ -1377,11 +1497,11 @@ dump_expr (t, nop)
if (TREE_HAS_CONSTRUCTOR (t)) if (TREE_HAS_CONSTRUCTOR (t))
{ {
OB_PUTS ("new "); OB_PUTS ("new ");
dump_type (TREE_TYPE (TREE_TYPE (t)), 0); dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
} }
else else
{ {
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
} }
break; break;
...@@ -1404,7 +1524,7 @@ dump_expr (t, nop) ...@@ -1404,7 +1524,7 @@ dump_expr (t, nop)
} }
OB_PUTC ('('); OB_PUTC ('(');
if (TREE_OPERAND (t, 1)) if (TREE_OPERAND (t, 1))
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
OB_PUTC (')'); OB_PUTC (')');
break; break;
...@@ -1421,20 +1541,20 @@ dump_expr (t, nop) ...@@ -1421,20 +1541,20 @@ dump_expr (t, nop)
tree ob = TREE_VALUE (args); tree ob = TREE_VALUE (args);
if (TREE_CODE (ob) == ADDR_EXPR) if (TREE_CODE (ob) == ADDR_EXPR)
{ {
dump_expr (TREE_OPERAND (ob, 0), 0); dump_expr (TREE_OPERAND (ob, 0), flags | TS_EXPR_PARENS);
OB_PUTC ('.'); OB_PUTC ('.');
} }
else if (TREE_CODE (ob) != PARM_DECL else if (TREE_CODE (ob) != PARM_DECL
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
{ {
dump_expr (ob, 0); dump_expr (ob, flags | TS_EXPR_PARENS);
OB_PUTC2 ('-', '>'); OB_PUTS ("->");
} }
args = TREE_CHAIN (args); args = TREE_CHAIN (args);
} }
dump_expr (fn, 0); dump_expr (fn, flags | TS_EXPR_PARENS);
OB_PUTC ('('); OB_PUTC ('(');
dump_expr_list (args); dump_expr_list (args, flags);
OB_PUTC (')'); OB_PUTC (')');
} }
break; break;
...@@ -1448,7 +1568,7 @@ dump_expr (t, nop) ...@@ -1448,7 +1568,7 @@ dump_expr (t, nop)
if (TREE_OPERAND (t, 0)) if (TREE_OPERAND (t, 0))
{ {
OB_PUTC ('('); OB_PUTC ('(');
dump_expr_list (TREE_OPERAND (t, 0)); dump_expr_list (TREE_OPERAND (t, 0), flags);
OB_PUTS (") "); OB_PUTS (") ");
} }
if (TREE_CODE (type) == ARRAY_REF) if (TREE_CODE (type) == ARRAY_REF)
...@@ -1456,11 +1576,11 @@ dump_expr (t, nop) ...@@ -1456,11 +1576,11 @@ dump_expr (t, nop)
(TREE_OPERAND (type, 0), (TREE_OPERAND (type, 0),
build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1), build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1),
integer_one_node))); integer_one_node)));
dump_type (type, 0); dump_type (type, flags);
if (TREE_OPERAND (t, 2)) if (TREE_OPERAND (t, 2))
{ {
OB_PUTC ('('); OB_PUTC ('(');
dump_expr_list (TREE_OPERAND (t, 2)); dump_expr_list (TREE_OPERAND (t, 2), flags);
OB_PUTC (')'); OB_PUTC (')');
} }
} }
...@@ -1473,7 +1593,7 @@ dump_expr (t, nop) ...@@ -1473,7 +1593,7 @@ dump_expr (t, nop)
default argument. Note we may have cleared out the first default argument. Note we may have cleared out the first
operand in expand_expr, so don't go killing ourselves. */ operand in expand_expr, so don't go killing ourselves. */
if (TREE_OPERAND (t, 1)) if (TREE_OPERAND (t, 1))
dump_expr (TREE_OPERAND (t, 1), 0); dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
break; break;
case INIT_EXPR: case INIT_EXPR:
...@@ -1500,19 +1620,19 @@ dump_expr (t, nop) ...@@ -1500,19 +1620,19 @@ dump_expr (t, nop)
case EQ_EXPR: case EQ_EXPR:
case NE_EXPR: case NE_EXPR:
case EXACT_DIV_EXPR: case EXACT_DIV_EXPR:
dump_binary_op (opname_tab[(int) TREE_CODE (t)], t); dump_binary_op (opname_tab[(int) TREE_CODE (t)], t, flags);
break; break;
case CEIL_DIV_EXPR: case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR: case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR: case ROUND_DIV_EXPR:
dump_binary_op ("/", t); dump_binary_op ("/", t, flags);
break; break;
case CEIL_MOD_EXPR: case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR: case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR: case ROUND_MOD_EXPR:
dump_binary_op ("%", t); dump_binary_op ("%", t, flags);
break; break;
case COMPONENT_REF: case COMPONENT_REF:
...@@ -1524,23 +1644,23 @@ dump_expr (t, nop) ...@@ -1524,23 +1644,23 @@ dump_expr (t, nop)
if (TREE_CODE (ob) != PARM_DECL if (TREE_CODE (ob) != PARM_DECL
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
{ {
dump_expr (ob, 0); dump_expr (ob, flags | TS_EXPR_PARENS);
OB_PUTC2 ('-', '>'); OB_PUTS ("->");
} }
} }
else else
{ {
dump_expr (ob, 0); dump_expr (ob, flags | TS_EXPR_PARENS);
OB_PUTC ('.'); OB_PUTC ('.');
} }
dump_expr (TREE_OPERAND (t, 1), 1); dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS);
} }
break; break;
case ARRAY_REF: case ARRAY_REF:
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTC ('['); OB_PUTC ('[');
dump_expr (TREE_OPERAND (t, 1), 0); dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
OB_PUTC (']'); OB_PUTC (']');
break; break;
...@@ -1548,18 +1668,18 @@ dump_expr (t, nop) ...@@ -1548,18 +1668,18 @@ dump_expr (t, nop)
if (same_type_p (TREE_TYPE (t), void_type_node)) if (same_type_p (TREE_TYPE (t), void_type_node))
{ {
OB_PUTS ("(void)"); OB_PUTS ("(void)");
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags);
} }
else else
dump_unary_op ("+", t, nop); dump_unary_op ("+", t, flags);
break; break;
case ADDR_EXPR: case ADDR_EXPR:
if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
|| TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST) || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
else else
dump_unary_op ("&", t, nop); dump_unary_op ("&", t, flags);
break; break;
case INDIRECT_REF: case INDIRECT_REF:
...@@ -1567,9 +1687,9 @@ dump_expr (t, nop) ...@@ -1567,9 +1687,9 @@ dump_expr (t, nop)
{ {
t = TREE_OPERAND (t, 0); t = TREE_OPERAND (t, 0);
my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237); my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTC ('('); OB_PUTC ('(');
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
OB_PUTC (')'); OB_PUTC (')');
} }
else else
...@@ -1577,9 +1697,9 @@ dump_expr (t, nop) ...@@ -1577,9 +1697,9 @@ dump_expr (t, nop)
if (TREE_OPERAND (t,0) != NULL_TREE if (TREE_OPERAND (t,0) != NULL_TREE
&& TREE_TYPE (TREE_OPERAND (t, 0)) && TREE_TYPE (TREE_OPERAND (t, 0))
&& NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
dump_expr (TREE_OPERAND (t, 0), nop); dump_expr (TREE_OPERAND (t, 0), flags);
else else
dump_unary_op ("*", t, nop); dump_unary_op ("*", t, flags);
} }
break; break;
...@@ -1588,13 +1708,13 @@ dump_expr (t, nop) ...@@ -1588,13 +1708,13 @@ dump_expr (t, nop)
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
case PREDECREMENT_EXPR: case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR: case PREINCREMENT_EXPR:
dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, nop); dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, flags);
break; break;
case POSTDECREMENT_EXPR: case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR: case POSTINCREMENT_EXPR:
OB_PUTC ('('); OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTCP (opname_tab[(int)TREE_CODE (t)]); OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
OB_PUTC (')'); OB_PUTC (')');
break; break;
...@@ -1612,19 +1732,21 @@ dump_expr (t, nop) ...@@ -1612,19 +1732,21 @@ dump_expr (t, nop)
if (TREE_CODE (next) == FUNCTION_TYPE) if (TREE_CODE (next) == FUNCTION_TYPE)
{ {
if (!nop) OB_PUTC ('('); if (flags & TS_EXPR_PARENS)
OB_PUTC ('(');
OB_PUTC ('*'); OB_PUTC ('*');
dump_expr (TREE_OPERAND (t, 0), 1); dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
if (!nop) OB_PUTC (')'); if (flags & TS_EXPR_PARENS)
OB_PUTC (')');
break; break;
} }
/* else FALLTHRU */ /* else FALLTHRU */
} }
dump_expr (TREE_OPERAND (t, 0), 0); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
break; break;
case NOP_EXPR: case NOP_EXPR:
dump_expr (TREE_OPERAND (t, 0), nop); dump_expr (TREE_OPERAND (t, 0), flags);
break; break;
case CONSTRUCTOR: case CONSTRUCTOR:
...@@ -1635,7 +1757,7 @@ dump_expr (t, nop) ...@@ -1635,7 +1757,7 @@ dump_expr (t, nop)
if (integer_all_onesp (idx)) if (integer_all_onesp (idx))
{ {
tree pfn = PFN_FROM_PTRMEMFUNC (t); tree pfn = PFN_FROM_PTRMEMFUNC (t);
dump_unary_op ("&", pfn, 0); dump_unary_op ("&", pfn, flags | TS_EXPR_PARENS);
break; break;
} }
else if (TREE_CODE (idx) == INTEGER_CST else if (TREE_CODE (idx) == INTEGER_CST
...@@ -1643,7 +1765,7 @@ dump_expr (t, nop) ...@@ -1643,7 +1765,7 @@ dump_expr (t, nop)
{ {
/* A NULL pointer-to-member constant. */ /* A NULL pointer-to-member constant. */
OB_PUTS ("(("); OB_PUTS ("((");
dump_type (TREE_TYPE (t), 0); dump_type (TREE_TYPE (t), flags);
OB_PUTS (") 0)"); OB_PUTS (") 0)");
break; break;
} }
...@@ -1670,13 +1792,14 @@ dump_expr (t, nop) ...@@ -1670,13 +1792,14 @@ dump_expr (t, nop)
} }
if (virtuals) if (virtuals)
{ {
dump_expr (TREE_VALUE (virtuals), 0); dump_expr (TREE_VALUE (virtuals),
flags | TS_EXPR_PARENS);
break; break;
} }
} }
} }
OB_PUTC ('{'); OB_PUTC ('{');
dump_expr_list (CONSTRUCTOR_ELTS (t)); dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
OB_PUTC ('}'); OB_PUTC ('}');
break; break;
...@@ -1688,31 +1811,31 @@ dump_expr (t, nop) ...@@ -1688,31 +1811,31 @@ dump_expr (t, nop)
t = TREE_OPERAND (t, 1); t = TREE_OPERAND (t, 1);
if (TREE_CODE (t) == FUNCTION_DECL) if (TREE_CODE (t) == FUNCTION_DECL)
/* A::f */ /* A::f */
dump_expr (t, 0); dump_expr (t, flags | TS_EXPR_PARENS);
else if (BASELINK_P (t)) else if (BASELINK_P (t))
dump_expr (OVL_CURRENT (TREE_VALUE (t)), 0); dump_expr (OVL_CURRENT (TREE_VALUE (t)), flags | TS_EXPR_PARENS);
else else
dump_decl (t, 0); dump_decl (t, flags);
} }
else else
{ {
if (TREE_CODE (ob) == INDIRECT_REF) if (TREE_CODE (ob) == INDIRECT_REF)
{ {
dump_expr (TREE_OPERAND (ob, 0), 0); dump_expr (TREE_OPERAND (ob, 0), flags | TS_EXPR_PARENS);
OB_PUTS (" ->* "); OB_PUTS (" ->* ");
} }
else else
{ {
dump_expr (ob, 0); dump_expr (ob, flags | TS_EXPR_PARENS);
OB_PUTS (" .* "); OB_PUTS (" .* ");
} }
dump_expr (TREE_OPERAND (t, 1), 0); dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
} }
break; break;
} }
case TEMPLATE_PARM_INDEX: case TEMPLATE_PARM_INDEX:
dump_decl (TEMPLATE_PARM_DECL (t), -1); dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TS_DECL_TYPE);
break; break;
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
...@@ -1720,27 +1843,27 @@ dump_expr (t, nop) ...@@ -1720,27 +1843,27 @@ dump_expr (t, nop)
break; break;
case SCOPE_REF: case SCOPE_REF:
dump_type (TREE_OPERAND (t, 0), 0); dump_type (TREE_OPERAND (t, 0), flags);
OB_PUTS ("::"); OB_PUTS ("::");
dump_expr (TREE_OPERAND (t, 1), 0); dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
break; break;
case CAST_EXPR: case CAST_EXPR:
if (TREE_OPERAND (t, 0) == NULL_TREE if (TREE_OPERAND (t, 0) == NULL_TREE
|| TREE_CHAIN (TREE_OPERAND (t, 0))) || TREE_CHAIN (TREE_OPERAND (t, 0)))
{ {
dump_type (TREE_TYPE (t), 0); dump_type (TREE_TYPE (t), flags);
OB_PUTC ('('); OB_PUTC ('(');
dump_expr_list (TREE_OPERAND (t, 0)); dump_expr_list (TREE_OPERAND (t, 0), flags);
OB_PUTC (')'); OB_PUTC (')');
} }
else else
{ {
OB_PUTC ('('); OB_PUTC ('(');
dump_type (TREE_TYPE (t), 0); dump_type (TREE_TYPE (t), flags);
OB_PUTC (')'); OB_PUTC (')');
OB_PUTC ('('); OB_PUTC ('(');
dump_expr_list (TREE_OPERAND (t, 0)); dump_expr_list (TREE_OPERAND (t, 0), flags);
OB_PUTC (')'); OB_PUTC (')');
} }
break; break;
...@@ -1750,7 +1873,7 @@ dump_expr (t, nop) ...@@ -1750,7 +1873,7 @@ dump_expr (t, nop)
break; break;
case ARROW_EXPR: case ARROW_EXPR:
dump_expr (TREE_OPERAND (t, 0), nop); dump_expr (TREE_OPERAND (t, 0), flags);
OB_PUTS ("->"); OB_PUTS ("->");
break; break;
...@@ -1764,9 +1887,9 @@ dump_expr (t, nop) ...@@ -1764,9 +1887,9 @@ dump_expr (t, nop)
OB_PUTS ("__alignof__ ("); OB_PUTS ("__alignof__ (");
} }
if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't') if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
dump_type (TREE_OPERAND (t, 0), 0); dump_type (TREE_OPERAND (t, 0), flags);
else else
dump_unary_op ("*", t, 0); dump_unary_op ("*", t, flags | TS_EXPR_PARENS);
OB_PUTC (')'); OB_PUTC (')');
break; break;
...@@ -1777,19 +1900,19 @@ dump_expr (t, nop) ...@@ -1777,19 +1900,19 @@ dump_expr (t, nop)
case TRY_CATCH_EXPR: case TRY_CATCH_EXPR:
case WITH_CLEANUP_EXPR: case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR: case CLEANUP_POINT_EXPR:
dump_expr (TREE_OPERAND (t, 0), nop); dump_expr (TREE_OPERAND (t, 0), flags);
break; break;
case PSEUDO_DTOR_EXPR: case PSEUDO_DTOR_EXPR:
dump_expr (TREE_OPERAND (t, 2), nop); dump_expr (TREE_OPERAND (t, 2), flags);
OB_PUTS ("."); OB_PUTS (".");
dump_type (TREE_OPERAND (t, 0), nop); dump_type (TREE_OPERAND (t, 0), flags);
OB_PUTS ("::~"); OB_PUTS ("::~");
dump_type (TREE_OPERAND (t, 1), nop); dump_type (TREE_OPERAND (t, 1), flags);
break; break;
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
dump_decl (t, 0); dump_decl (t, flags);
break; break;
case STMT_EXPR: case STMT_EXPR:
...@@ -1800,19 +1923,19 @@ dump_expr (t, nop) ...@@ -1800,19 +1923,19 @@ dump_expr (t, nop)
case BIND_EXPR: case BIND_EXPR:
OB_PUTS ("{ "); OB_PUTS ("{ ");
dump_expr (TREE_OPERAND (t, 1), nop); dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS);
OB_PUTS ("} "); OB_PUTS ("} ");
break; break;
case LOOP_EXPR: case LOOP_EXPR:
OB_PUTS ("while (1) { "); OB_PUTS ("while (1) { ");
dump_expr (TREE_OPERAND (t, 0), nop); dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
OB_PUTS ("} "); OB_PUTS ("} ");
break; break;
case EXIT_EXPR: case EXIT_EXPR:
OB_PUTS ("if ("); OB_PUTS ("if (");
dump_expr (TREE_OPERAND (t, 0), nop); dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
OB_PUTS (") break; "); OB_PUTS (") break; ");
break; break;
...@@ -1833,112 +1956,97 @@ dump_expr (t, nop) ...@@ -1833,112 +1956,97 @@ dump_expr (t, nop)
/* fall through to ERROR_MARK... */ /* fall through to ERROR_MARK... */
case ERROR_MARK: case ERROR_MARK:
OB_PUTCP ("{error}"); OB_PUTCP ("{exprerror}");
break; break;
} }
} }
static void static void
dump_binary_op (opstring, t) dump_binary_op (opstring, t, flags)
const char *opstring; const char *opstring;
tree t; tree t;
enum tree_string_flags flags;
{ {
OB_PUTC ('('); OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), 1); dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTC (' '); OB_PUTC (' ');
if (opstring) if (opstring)
OB_PUTCP (opstring); OB_PUTCP (opstring);
else else
OB_PUTS ("<unknown operator>"); OB_PUTS ("<unknown operator>");
OB_PUTC (' '); OB_PUTC (' ');
dump_expr (TREE_OPERAND (t, 1), 1); dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
OB_PUTC (')'); OB_PUTC (')');
} }
static void static void
dump_unary_op (opstring, t, nop) dump_unary_op (opstring, t, flags)
const char *opstring; const char *opstring;
tree t; tree t;
int nop; enum tree_string_flags flags;
{ {
if (!nop) OB_PUTC ('('); if (flags & TS_EXPR_PARENS)
OB_PUTC ('(');
OB_PUTCP (opstring); OB_PUTCP (opstring);
dump_expr (TREE_OPERAND (t, 0), 1); dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
if (!nop) OB_PUTC (')'); if (flags & TS_EXPR_PARENS)
OB_PUTC (')');
} }
/* Print a function decl with exception specification included. */ /* Exported interface to stringifying types, exprs and decls under TS_*
control. */
const char * const char *
fndecl_as_string (fndecl, print_default_args_p) type_as_string (typ, flags)
tree fndecl; tree typ;
int print_default_args_p; enum tree_string_flags flags;
{ {
OB_INIT (); OB_INIT ();
dump_function_decl (fndecl, 2 + print_default_args_p); dump_type (typ, flags);
OB_FINISH (); OB_FINISH ();
return (char *)obstack_base (&scratch_obstack); return (char *)obstack_base (&scratch_obstack);
} }
/* Same, but handle a _TYPE.
Called from convert_to_reference, mangle_class_name_for_template,
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. */
const char * const char *
type_as_string_real (typ, v, canonical_name) expr_as_string (decl, flags)
tree typ; tree decl;
int v; enum tree_string_flags flags;
int canonical_name;
{ {
OB_INIT (); OB_INIT ();
dump_type_real (typ, v, canonical_name); dump_expr (decl, flags);
OB_FINISH (); OB_FINISH ();
return (char *)obstack_base (&scratch_obstack); return (char *)obstack_base (&scratch_obstack);
} }
const char * const char *
type_as_string (typ, v) decl_as_string (decl, flags)
tree typ;
int v;
{
return type_as_string_real (typ, v, 0);
}
const char *
expr_as_string (decl, v)
tree decl; tree decl;
int v ATTRIBUTE_UNUSED; enum tree_string_flags flags;
{ {
OB_INIT (); OB_INIT ();
dump_expr (decl, 1); dump_decl (decl, flags);
OB_FINISH (); OB_FINISH ();
return (char *)obstack_base (&scratch_obstack); return (char *)obstack_base (&scratch_obstack);
} }
/* A cross between type_as_string and fndecl_as_string.
Only called from substitute_nice_name. */
const char * const char *
decl_as_string (decl, v) context_as_string (context, flags)
tree decl; tree context;
int v; enum tree_string_flags flags;
{ {
OB_INIT (); OB_INIT ();
dump_decl (decl, v); dump_scope (context, flags);
OB_FINISH (); OB_FINISH ();
return (char *)obstack_base (&scratch_obstack); return (char *)obstack_base (&scratch_obstack);
...@@ -1952,7 +2060,7 @@ lang_decl_name (decl, v) ...@@ -1952,7 +2060,7 @@ lang_decl_name (decl, v)
int v; int v;
{ {
if (v >= 2) if (v >= 2)
return decl_as_string (decl, 1); return decl_as_string (decl, TS_DECL_TYPE);
OB_INIT (); OB_INIT ();
...@@ -1963,20 +2071,19 @@ lang_decl_name (decl, v) ...@@ -1963,20 +2071,19 @@ lang_decl_name (decl, v)
cname = DECL_CLASS_CONTEXT (decl); cname = DECL_CLASS_CONTEXT (decl);
else else
cname = DECL_CONTEXT (decl); cname = DECL_CONTEXT (decl);
dump_type (cname, 0); dump_type (cname, TS_PLAIN);
OB_PUTC2 (':', ':'); OB_PUTS ("::");
} }
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
dump_function_name (decl); dump_function_name (decl, TS_PLAIN);
else else
dump_decl (DECL_NAME (decl), 0); dump_decl (DECL_NAME (decl), TS_PLAIN);
OB_FINISH (); OB_FINISH ();
return (char *)obstack_base (&scratch_obstack); return (char *)obstack_base (&scratch_obstack);
} }
const char * const char *
cp_file_of (t) cp_file_of (t)
...@@ -2016,16 +2123,79 @@ cp_line_of (t) ...@@ -2016,16 +2123,79 @@ cp_line_of (t)
return line; return line;
} }
const char * /* Now the interfaces from cp_error et al to dump_type et al. Each takes an
code_as_string (c, v) on/off VERBOSE flag and supply the appropriate TS_ flags to a dump_
function. */
static const char *
decl_to_string (decl, verbose)
tree decl;
int verbose;
{
enum tree_string_flags flags = 0;
if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
|| TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
flags = TS_AGGR_TAGS;
if (verbose)
flags |= TS_DECL_TYPE | TS_DECORATE | TS_PARM_DEFAULTS;
else if (TREE_CODE (decl) == FUNCTION_DECL)
flags |= TS_DECL_TYPE | TS_FUNC_NORETURN;
flags |= TS_TEMPLATE_PREFIX;
OB_INIT ();
dump_decl (decl, flags);
OB_FINISH ();
return (char *)obstack_base (&scratch_obstack);
}
static const char *
expr_to_string (decl, verbose)
tree decl;
int verbose ATTRIBUTE_UNUSED;
{
OB_INIT ();
dump_expr (decl, 0);
OB_FINISH ();
return (char *)obstack_base (&scratch_obstack);
}
static const char *
fndecl_to_string (fndecl, verbose)
tree fndecl;
int verbose;
{
enum tree_string_flags flags;
flags = TS_FUNC_THROW | TS_DECL_TYPE;
if (verbose)
flags |= TS_PARM_DEFAULTS;
OB_INIT ();
dump_decl (fndecl, flags);
OB_FINISH ();
return (char *)obstack_base (&scratch_obstack);
}
static const char *
code_to_string (c, v)
enum tree_code c; enum tree_code c;
int v ATTRIBUTE_UNUSED; int v ATTRIBUTE_UNUSED;
{ {
return tree_code_name [c]; return tree_code_name [c];
} }
const char * static const char *
language_as_string (c, v) language_to_string (c, v)
enum languages c; enum languages c;
int v ATTRIBUTE_UNUSED; int v ATTRIBUTE_UNUSED;
{ {
...@@ -2048,8 +2218,8 @@ language_as_string (c, v) ...@@ -2048,8 +2218,8 @@ language_as_string (c, v)
/* Return the proper printed version of a parameter to a C++ function. */ /* Return the proper printed version of a parameter to a C++ function. */
const char * static const char *
parm_as_string (p, v) parm_to_string (p, v)
int p; int p;
int v ATTRIBUTE_UNUSED; int v ATTRIBUTE_UNUSED;
{ {
...@@ -2060,8 +2230,8 @@ parm_as_string (p, v) ...@@ -2060,8 +2230,8 @@ parm_as_string (p, v)
return digit_buffer; return digit_buffer;
} }
const char * static const char *
op_as_string (p, v) op_to_string (p, v)
enum tree_code p; enum tree_code p;
int v ATTRIBUTE_UNUSED; int v ATTRIBUTE_UNUSED;
{ {
...@@ -2074,8 +2244,29 @@ op_as_string (p, v) ...@@ -2074,8 +2244,29 @@ op_as_string (p, v)
return buf; return buf;
} }
const char * static const char *
assop_as_string (p, v) type_to_string (typ, verbose)
tree typ;
int verbose;
{
enum tree_string_flags flags;
flags = 0;
if (verbose)
flags |= TS_AGGR_TAGS;
flags |= TS_TEMPLATE_PREFIX;
OB_INIT ();
dump_type (typ, flags);
OB_FINISH ();
return (char *)obstack_base (&scratch_obstack);
}
static const char *
assop_to_string (p, v)
enum tree_code p; enum tree_code p;
int v ATTRIBUTE_UNUSED; int v ATTRIBUTE_UNUSED;
{ {
...@@ -2088,16 +2279,20 @@ assop_as_string (p, v) ...@@ -2088,16 +2279,20 @@ assop_as_string (p, v)
return buf; return buf;
} }
const char * static const char *
args_as_string (p, v) args_to_string (p, verbose)
tree p; tree p;
int v; int verbose;
{ {
enum tree_string_flags flags = 0;
if (verbose)
flags |= TS_AGGR_TAGS;
if (p == NULL_TREE) if (p == NULL_TREE)
return ""; return "";
if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't') if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't')
return type_as_string (p, v); return type_as_string (p, flags);
OB_INIT (); OB_INIT ();
for (; p; p = TREE_CHAIN (p)) for (; p; p = TREE_CHAIN (p))
...@@ -2105,7 +2300,7 @@ args_as_string (p, v) ...@@ -2105,7 +2300,7 @@ args_as_string (p, v)
if (TREE_VALUE (p) == null_node) if (TREE_VALUE (p) == null_node)
OB_PUTS ("NULL"); OB_PUTS ("NULL");
else else
dump_type (error_type (TREE_VALUE (p)), v); dump_type (error_type (TREE_VALUE (p)), flags);
if (TREE_CHAIN (p)) if (TREE_CHAIN (p))
OB_PUTS (", "); OB_PUTS (", ");
} }
...@@ -2113,8 +2308,8 @@ args_as_string (p, v) ...@@ -2113,8 +2308,8 @@ args_as_string (p, v)
return (char *)obstack_base (&scratch_obstack); return (char *)obstack_base (&scratch_obstack);
} }
const char * static const char *
cv_as_string (p, v) cv_to_string (p, v)
tree p; tree p;
int v ATTRIBUTE_UNUSED; int v ATTRIBUTE_UNUSED;
{ {
......
...@@ -3527,7 +3527,7 @@ mangle_class_name_for_template (name, parms, arglist) ...@@ -3527,7 +3527,7 @@ mangle_class_name_for_template (name, parms, arglist)
if (TREE_CODE (parm) == TYPE_DECL) if (TREE_CODE (parm) == TYPE_DECL)
{ {
cat (type_as_string_real (arg, 0, 1)); cat (type_as_string (arg, TS_CHASE_TYPEDEFS));
continue; continue;
} }
else if (TREE_CODE (parm) == TEMPLATE_DECL) else if (TREE_CODE (parm) == TEMPLATE_DECL)
...@@ -3551,7 +3551,7 @@ mangle_class_name_for_template (name, parms, arglist) ...@@ -3551,7 +3551,7 @@ mangle_class_name_for_template (name, parms, arglist)
} }
else else
/* Output the parameter declaration */ /* Output the parameter declaration */
cat (type_as_string_real (arg, 0, 1)); cat (type_as_string (arg, TS_CHASE_TYPEDEFS));
continue; continue;
} }
else else
...@@ -4401,7 +4401,7 @@ print_template_context (err) ...@@ -4401,7 +4401,7 @@ print_template_context (err)
/* Avoid redundancy with the the "In function" line. */; /* Avoid redundancy with the the "In function" line. */;
else else
fprintf (stderr, "%s: In instantiation of `%s':\n", fprintf (stderr, "%s: In instantiation of `%s':\n",
file, decl_as_string (p->decl, 0)); file, decl_as_string (p->decl, TS_DECL_TYPE | TS_FUNC_NORETURN));
line = p->line; line = p->line;
file = p->file; file = p->file;
...@@ -4412,7 +4412,7 @@ print_template_context (err) ...@@ -4412,7 +4412,7 @@ print_template_context (err)
for (; p; p = p->next) for (; p; p = p->next)
{ {
fprintf (stderr, "%s:%d: instantiated from `%s'\n", file, line, fprintf (stderr, "%s:%d: instantiated from `%s'\n", file, line,
decl_as_string (p->decl, 0)); decl_as_string (p->decl, TS_DECL_TYPE | TS_FUNC_NORETURN));
line = p->line; line = p->line;
file = p->file; file = p->file;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment