From 9e93bc9dcc9b0dbec075bb15580ccd62dc359b70 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 27 Sep 1999 08:26:00 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 62 +++ gcc/cp/cp-tree.h | 40 +- gcc/cp/error.c | 1377 +++++++++++++++++++++++++++++++----------------------- gcc/cp/pt.c | 8 +- 4 files changed, 880 insertions(+), 607 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 19e4dd3..fa5f56b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,65 @@ +1999-09-27 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. + 1999-09-26 Mark Mitchell * cp-tree.h (expand_throw): Remove prototype. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3abea7d..9202354 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3122,6 +3122,30 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; #define TEMPLATE_TYPE_DECL(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 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 */ /* Indexed by TREE_CODE, these tables give C-looking names to operators represented by TREE_CODES. For example, @@ -3430,18 +3454,10 @@ extern void cp_deprecated PROTO((const char*)); /* in error.c */ extern void init_error PROTO((void)); -extern const char *fndecl_as_string PROTO((tree, int)); -extern const char *type_as_string PROTO((tree, int)); -extern const char *type_as_string_real PROTO((tree, int, int)); -extern const char *args_as_string PROTO((tree, int)); -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 *type_as_string PROTO((tree, enum tree_string_flags)); +extern const char *decl_as_string PROTO((tree, enum tree_string_flags)); +extern const char *expr_as_string PROTO((tree, enum tree_string_flags)); +extern const char *context_as_string PROTO((tree, enum tree_string_flags)); extern const char *lang_decl_name PROTO((tree, int)); extern const char *cp_file_of PROTO((tree)); extern int cp_line_of PROTO((tree)); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 883a2e5..fc64cab 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -28,43 +28,6 @@ Boston, MA 02111-1307, USA. */ 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_free free @@ -84,39 +47,88 @@ static char *scratch_firstobj; # 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)); \ OB_PUTCP (digit_buffer); } while (0) -# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N)); # 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] == '>') \ - ? OB_PUTC2 (' ', '>') : OB_PUTC ('>')) + ? OB_PUTC (' ') : (void)0), OB_PUTC ('>')) # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) 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((const char *, tree, int)); -static void dump_binary_op PROTO((const char *, tree)); -static void dump_aggr_type PROTO((tree, int, int)); -static void dump_type_prefix PROTO((tree, int, int)); -static void dump_type_suffix PROTO((tree, int, int)); -static void dump_function_name PROTO((tree)); -static void dump_expr_list PROTO((tree)); +static const char *args_to_string PROTO((tree, int)); +static const char *assop_to_string PROTO((enum tree_code, int)); +static const char *code_to_string PROTO((enum tree_code, int)); +static const char *cv_to_string PROTO((tree, int)); +static const char *decl_to_string PROTO((tree, int)); +static const char *expr_to_string PROTO((tree, int)); +static const char *fndecl_to_string PROTO((tree, int)); +static const char *language_to_string PROTO((enum languages, int)); +static const char *op_to_string PROTO((enum tree_code, int)); +static const char *parm_to_string PROTO((int, int)); +static const char *type_to_string PROTO((tree, int)); + +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_qualifiers PROTO((tree, enum pad)); +static enum pad dump_qualifiers PROTO((tree, enum pad)); static void dump_char PROTO((int)); -static void dump_parameters PROTO((tree, int, int)); -static void dump_exception_spec PROTO((tree, int)); +static void dump_parameters PROTO((tree, enum tree_string_flags)); +static void dump_exception_spec PROTO((tree, enum tree_string_flags)); static const char *aggr_variety PROTO((tree)); static tree ident_fndecl PROTO((tree)); -static int interesting_scope_p PROTO((tree)); -static void dump_template_value PROTO((tree, int, int)); +static void dump_template_value PROTO((tree, enum tree_string_flags)); +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 init_error () @@ -125,92 +137,102 @@ init_error () 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 -interesting_scope_p (scope) +static void +dump_scope (scope, flags) tree scope; + enum tree_string_flags flags; { - if (scope == NULL_TREE - || scope == global_namespace) - return 0; - - return (TREE_CODE (scope) == NAMESPACE_DECL - || AGGREGATE_TYPE_P (scope)); + if (scope == NULL_TREE) + return; + + if (TREE_CODE (scope) == NAMESPACE_DECL) + { + 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) tree t; 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 (' '); - 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 (' '); + for (ix = 0; ix != 3; ix++) + if (masks[ix] & quals) + { + if (p == before) + OB_PUTC (' '); + p = before; + OB_PUTCP (names[ix]); + } + if (do_after) + OB_PUTC (' '); } + else + p = none; + return p; } /* This must be large enough to hold any printed integer or floating-point value. */ static char digit_buffer[128]; -/* Dump a template parameter or template argument VALUE at VERBOSITY - level. The boolean CANONICAL_NAME indicates whether to dump abstract - names, e.g. typedefs, or not. */ +/* Dump a template parameter or template argument VALUE under + control of FLAGS. */ static void -dump_template_value (value, verbosity, canonical_name) +dump_template_value (value, flags) tree value; - int verbosity, canonical_name; + enum tree_string_flags flags; { if (TREE_CODE_CLASS (TREE_CODE (value)) == 't' || TREE_CODE (value) == TEMPLATE_DECL) - dump_type_real (value, verbosity, canonical_name); + dump_type (value, flags & ~TS_AGGR_TAGS); 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 -dump_type_real (t, v, canonical_name) +dump_type (t, flags) tree t; - int v; /* verbose? */ - int canonical_name; + enum tree_string_flags flags; { if (t == NULL_TREE) return; @@ -220,17 +242,13 @@ dump_type_real (t, v, canonical_name) switch (TREE_CODE (t)) { - case ERROR_MARK: - OB_PUTS ("{error}"); - break; - case UNKNOWN_TYPE: OB_PUTS ("{unknown type}"); break; case TREE_LIST: /* A list of function parms. */ - dump_parameters (t, 0, canonical_name); + dump_parameters (t, flags); break; case IDENTIFIER_NODE: @@ -238,24 +256,32 @@ dump_type_real (t, v, canonical_name) break; case TREE_VEC: - dump_type_real (BINFO_TYPE (t), v, canonical_name); + dump_type (BINFO_TYPE (t), flags); break; case RECORD_TYPE: case UNION_TYPE: case ENUMERAL_TYPE: - dump_aggr_type (t, v, canonical_name); + dump_aggr_type (t, flags); break; 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 NAMESPACE_DECL: - dump_decl (t, v); + dump_decl (t, flags & ~TS_DECL_TYPE); break; - + case COMPLEX_TYPE: OB_PUTS ("complex "); - dump_type_real (TREE_TYPE (t), v, canonical_name); + dump_type (TREE_TYPE (t), flags); break; case INTEGER_TYPE: @@ -271,7 +297,7 @@ dump_type_real (t, v, canonical_name) { tree type; 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)) OB_PUTID (TYPE_IDENTIFIER (type)); else @@ -299,9 +325,10 @@ dump_type_real (t, v, canonical_name) OB_PUTC ('<'); for (i = 0; i < TREE_VEC_LENGTH (args); i++) { - dump_template_value (TREE_VEC_ELT (args, i), 0, canonical_name); - if (i < TREE_VEC_LENGTH (args)-1) - OB_PUTC2 (',', ' '); + tree arg = TREE_VEC_ELT (args, i); + if (i) + OB_PUTS (", "); + dump_template_value (arg, flags); } OB_END_TEMPLATE_ID (); } @@ -324,29 +351,37 @@ dump_type_real (t, v, canonical_name) offset_type: case FUNCTION_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; - + } case TYPENAME_TYPE: OB_PUTS ("typename "); - dump_type_real (TYPE_CONTEXT (t), 0, canonical_name); + dump_type (TYPE_CONTEXT (t), flags); OB_PUTS ("::"); - dump_decl (TYPENAME_TYPE_FULLNAME (t), v); + dump_decl (TYPENAME_TYPE_FULLNAME (t), flags); break; case TYPEOF_TYPE: OB_PUTS ("__typeof ("); - dump_expr (TYPE_FIELDS (t), 1); + dump_expr (TYPE_FIELDS (t), flags & ~TS_EXPR_PARENS); OB_PUTC (')'); break; default: sorry ("`%s' not supported by dump_type", 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 * aggr_variety (t) tree t; @@ -361,50 +396,59 @@ aggr_variety (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'. */ +/* Print out a class declaration T under the control of FLAGS, + in the form `class foo'. */ static void -dump_aggr_type (t, v, canonical_name) +dump_aggr_type (t, flags) tree t; - int v; /* verbose? */ - int canonical_name; + enum tree_string_flags flags; { tree name; const char *variety = aggr_variety (t); + int typdef = 0; + int tmplate = 0; dump_qualifiers (t, after); - if (v > 0) + if (flags & TS_AGGR_TAGS) { OB_PUTCP (variety); 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 */ - dump_decl (DECL_CONTEXT (name), 0); - OB_PUTC2 (':', ':'); + typdef = !DECL_ARTIFICIAL (name); + tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE + && 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)) { OB_PUTS ("{anonymous"); - if (!v) + if (!(flags & TS_AGGR_TAGS)) { OB_PUTC (' '); OB_PUTCP (variety); @@ -413,6 +457,10 @@ dump_aggr_type (t, v, canonical_name) } else 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. @@ -424,14 +472,18 @@ dump_aggr_type (t, v, canonical_name) deal with prefix and suffix. 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 -dump_type_prefix (t, v, canonical_name) +static enum pad +dump_type_prefix (t, flags) tree t; - int v; /* verbosity */ - int canonical_name; + enum tree_string_flags flags; { + enum pad padding = before; + if (TYPE_PTRMEMFUNC_P (t)) { t = TYPE_PTRMEMFUNC_FN_TYPE (t); @@ -445,73 +497,60 @@ dump_type_prefix (t, v, canonical_name) { 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, so let the OFFSET_TYPE case handle it. */ if (!TYPE_PTRMEM_P (t)) { - switch (TREE_CODE (sub)) - { - /* We don't want int ( *)() */ - case FUNCTION_TYPE: - case METHOD_TYPE: - break; - - 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); + if (padding != none) + OB_PUTC (' '); + if (TREE_CODE (sub) == ARRAY_TYPE) + OB_PUTC ('('); + OB_PUTC ("&*"[TREE_CODE (t) == POINTER_TYPE]); + padding = dump_qualifiers (t, none); } } break; case 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 */ { - OB_PUTC (' '); - dump_type_real (TYPE_OFFSET_BASETYPE (t), 0, canonical_name); - OB_PUTC2 (':', ':'); + if (padding != none) + OB_PUTC (' '); + dump_type (TYPE_OFFSET_BASETYPE (t), flags); + OB_PUTS ("::"); } OB_PUTC ('*'); - dump_qualifiers (t, none); + padding = 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, canonical_name); - OB_PUTC2 (' ', '('); + padding = dump_type_prefix (TREE_TYPE (t), flags); + if (padding != none) + OB_PUTC (' '); + OB_PUTC ('('); + padding = none; break; case METHOD_TYPE: - dump_type_prefix (TREE_TYPE (t), v, canonical_name); - OB_PUTC2 (' ', '('); - dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0, canonical_name); - OB_PUTC2 (':', ':'); + padding = dump_type_prefix (TREE_TYPE (t), flags); + if (padding != none) + OB_PUTC (' '); + OB_PUTC ('('); + padding = none; + dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags); + OB_PUTS ("::"); break; case ARRAY_TYPE: - dump_type_prefix (TREE_TYPE (t), v, canonical_name); + padding = dump_type_prefix (TREE_TYPE (t), flags); break; case ENUMERAL_TYPE: - case ERROR_MARK: case IDENTIFIER_NODE: case INTEGER_TYPE: case BOOLEAN_TYPE: @@ -527,20 +566,28 @@ dump_type_prefix (t, v, canonical_name) case VOID_TYPE: case TYPENAME_TYPE: case COMPLEX_TYPE: - dump_type_real (t, v, canonical_name); + dump_type (t, flags); + padding = before; break; default: sorry ("`%s' not supported by dump_type_prefix", 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 -dump_type_suffix (t, v, canonical_name) +dump_type_suffix (t, flags) tree t; - int v; /* verbose? */ - int canonical_name; + enum tree_string_flags flags; { if (TYPE_PTRMEMFUNC_P (t)) t = TYPE_PTRMEMFUNC_FN_TYPE (t); @@ -552,7 +599,7 @@ dump_type_suffix (t, v, canonical_name) case OFFSET_TYPE: if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) OB_PUTC (')'); - dump_type_suffix (TREE_TYPE (t), v, canonical_name); + dump_type_suffix (TREE_TYPE (t), flags); break; /* Can only be reached through function pointer */ @@ -567,13 +614,13 @@ dump_type_suffix (t, v, canonical_name) /* Function pointers don't have default args. Not in standard C++, 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) dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); - dump_type_suffix (TREE_TYPE (t), v, canonical_name); - dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), canonical_name); + dump_type_suffix (TREE_TYPE (t), flags); + dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags); break; } @@ -584,18 +631,19 @@ dump_type_suffix (t, v, canonical_name) if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST) OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) - dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0); + dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), + flags & ~TS_EXPR_PARENS); else dump_expr (fold (build_binary_op (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), - integer_one_node)), 0); + integer_one_node)), + flags & ~TS_EXPR_PARENS); } OB_PUTC (']'); - dump_type_suffix (TREE_TYPE (t), v, canonical_name); + dump_type_suffix (TREE_TYPE (t), flags); break; case ENUMERAL_TYPE: - case ERROR_MARK: case IDENTIFIER_NODE: case INTEGER_TYPE: case BOOLEAN_TYPE: @@ -616,6 +664,11 @@ dump_type_suffix (t, v, canonical_name) default: sorry ("`%s' not supported by dump_type_suffix", 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) } static void -dump_simple_decl (t, type, v) +dump_simple_decl (t, type, flags) tree t; tree type; - int v; + enum tree_string_flags flags; { - if (v > 0) + if (flags & TS_DECL_TYPE) { - dump_type_prefix (type, v, 0); - OB_PUTC (' '); - } - if (interesting_scope_p (DECL_CONTEXT (t))) - { - dump_decl (DECL_CONTEXT (t), 0); - OB_PUTC2 (':',':'); + if (dump_type_prefix (type, flags) != none) + OB_PUTC (' '); } + if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX) + dump_scope (CP_DECL_CONTEXT (t), flags); if (DECL_NAME (t)) - dump_decl (DECL_NAME (t), v); + dump_decl (DECL_NAME (t), flags); else OB_PUTS ("{anon}"); - if (v > 0) - dump_type_suffix (type, v, 0); + if (flags & TS_DECL_TYPE) + dump_type_suffix (type, flags); } +/* Dump a human readable string for the decl T under control of FLAGS. */ + static void -dump_decl (t, v) +dump_decl (t, flags) tree t; - int v; /* verbosity */ + enum tree_string_flags flags; { if (t == NULL_TREE) return; switch (TREE_CODE (t)) { - case ERROR_MARK: - OB_PUTS (" /* decl error */ "); - break; - case TYPE_DECL: { /* Don't say 'typedef class A' */ 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'. */ OB_PUTS ("class "); - dump_type (TREE_TYPE (t), v); + dump_type (TREE_TYPE (t), flags); break; } } - if (v > 0) + if (flags & TS_DECORATE) OB_PUTS ("typedef "); 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; case VAR_DECL: @@ -735,7 +785,7 @@ dump_decl (t, v) { OB_PUTS ("vtable for "); if (TYPE_P (DECL_CONTEXT (t))) - dump_type (DECL_CONTEXT (t), v); + dump_type (DECL_CONTEXT (t), flags); else /* This case can arise with -fno-vtable-thunks. See expand_upcast_fixups. It's not clear what to print @@ -746,15 +796,11 @@ dump_decl (t, v) /* else fall through */ case FIELD_DECL: case PARM_DECL: - dump_simple_decl (t, TREE_TYPE (t), v); + dump_simple_decl (t, TREE_TYPE (t), flags); break; case NAMESPACE_DECL: - if (CP_DECL_CONTEXT (t) != global_namespace) - { - dump_decl (DECL_CONTEXT (t), v); - OB_PUTC2 (':',':'); - } + dump_scope (CP_DECL_CONTEXT (t), flags); if (DECL_NAME (t) == anonymous_namespace_name) OB_PUTS ("{anonymous}"); else @@ -762,24 +808,23 @@ dump_decl (t, v) break; case SCOPE_REF: - dump_decl (TREE_OPERAND (t, 0), 0); + dump_decl (TREE_OPERAND (t, 0), flags & ~TS_DECL_TYPE); OB_PUTS ("::"); - dump_decl (TREE_OPERAND (t, 1), 0); + dump_decl (TREE_OPERAND (t, 1), flags); break; case ARRAY_REF: - dump_decl (TREE_OPERAND (t, 0), v); + dump_decl (TREE_OPERAND (t, 0), flags); OB_PUTC ('['); - dump_decl (TREE_OPERAND (t, 1), v); + dump_decl (TREE_OPERAND (t, 1), flags); OB_PUTC (']'); break; - /* So that we can do dump_decl in dump_aggr_type and have it work for - both class and function scope. */ + /* So that we can do dump_decl on an aggr type. */ case RECORD_TYPE: case UNION_TYPE: case ENUMERAL_TYPE: - dump_type (t, v); + dump_type (t, flags); break; case TYPE_EXPR: @@ -795,13 +840,13 @@ dump_decl (t, v) && DECL_LANGUAGE (f) == lang_cplusplus) { OB_PUTC ('~'); - dump_decl (DECL_NAME (f), 0); + dump_decl (DECL_NAME (f), flags); } else if (IDENTIFIER_TYPENAME_P (t)) { OB_PUTS ("operator "); /* Not exactly IDENTIFIER_TYPE_VALUE. */ - dump_type (TREE_TYPE (t), 0); + dump_type (TREE_TYPE (t), flags); break; } else if (IDENTIFIER_OPNAME_P (t)) @@ -824,77 +869,17 @@ dump_decl (t, v) dump_global_iord (DECL_ASSEMBLER_NAME (t)); else if (! DECL_LANG_SPECIFIC (t)) OB_PUTS ("{internal}"); + else if (flags & TS_PEDANTIC_NAME) + dump_function_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE); else - dump_function_decl (t, v); + dump_function_decl (t, flags); break; case TEMPLATE_DECL: - { - tree orig_args = DECL_TEMPLATE_PARMS (t); - tree args; - int i; - 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); - } - } + if (flags & TS_PEDANTIC_NAME) + dump_template_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE); + else + dump_template_decl (t, flags); break; case TEMPLATE_ID_EXPR: @@ -903,20 +888,20 @@ dump_decl (t, v) tree name = TREE_OPERAND (t, 0); if (is_overloaded_fn (name)) name = DECL_NAME (get_first_fn (name)); - dump_decl (name, v); + dump_decl (name, flags); OB_PUTC ('<'); 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)) - OB_PUTC2 (',', ' '); + OB_PUTS (", "); } OB_END_TEMPLATE_ID (); } break; case LOOKUP_EXPR: - dump_decl (TREE_OPERAND (t, 0), v); + dump_decl (TREE_OPERAND (t, 0), flags); break; case LABEL_DECL: @@ -927,18 +912,18 @@ dump_decl (t, v) if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) || (DECL_INITIAL (t) && TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) - dump_simple_decl (t, TREE_TYPE (t), v); + dump_simple_decl (t, TREE_TYPE (t), flags); else if (DECL_NAME (t)) - dump_decl (DECL_NAME (t), v); + dump_decl (DECL_NAME (t), flags); else if (DECL_INITIAL (t)) - dump_expr (DECL_INITIAL (t), 0); + dump_expr (DECL_INITIAL (t), flags | TS_EXPR_PARENS); else OB_PUTS ("enumerator"); break; case USING_DECL: OB_PUTS ("using "); - dump_type (DECL_INITIAL (t), 0); + dump_type (DECL_INITIAL (t), flags); OB_PUTS ("::"); OB_PUTID (DECL_NAME (t)); break; @@ -946,33 +931,114 @@ dump_decl (t, v) default: sorry ("`%s' not supported by dump_decl", 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 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 - function declaration. We use V to tell us what. - V - 01 23 - args - ++ ++ - retval - -+ ++ - default- -+ -+ - throw - -- ++ + function declaration. The TS_FUNC bits in FLAGS tells us how to behave. 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. */ static void -dump_function_decl (t, v) +dump_function_decl (t, flags) tree t; - int v; + enum tree_string_flags flags; { - tree name; tree fntype; tree parmtypes; tree cname = NULL_TREE; + int show_return = !(flags & TS_FUNC_NORETURN) && (flags & TS_DECL_TYPE); if (TREE_CODE (t) == TEMPLATE_DECL) t = DECL_TEMPLATE_RESULT (t); - name = DECL_ASSEMBLER_NAME (t); fntype = TREE_TYPE (t); parmtypes = TYPE_ARG_TYPES (fntype); @@ -983,90 +1049,86 @@ dump_function_decl (t, v) else if (TREE_CODE (fntype) == METHOD_TYPE) cname = TREE_TYPE (TREE_VALUE (parmtypes)); - /* Print the return type. */ - if (v > 0) + if (!(flags & TS_DECORATE)) + /* 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)) - OB_PUTS ("static "); - - if (! DECL_CONV_FN_P (t) - && ! DECL_CONSTRUCTOR_P (t) - && ! DECL_DESTRUCTOR_P (t)) - { - dump_type_prefix (TREE_TYPE (fntype), 0, 0); - OB_PUTC (' '); - } + if (dump_type_prefix (TREE_TYPE (fntype), flags) != none) + OB_PUTC (' '); } /* Print the function name. */ if (cname) { - dump_type (cname, 0); - OB_PUTC2 (':', ':'); - 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 (':',':'); + dump_type (cname, flags); + OB_PUTS ("::"); } + else + dump_scope (CP_DECL_CONTEXT (t), flags); - if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus) - parmtypes = TREE_CHAIN (parmtypes); + dump_function_name (t, flags); - dump_function_name (t); - - /* If V is negative, we don't print the argument types. */ - if (v < 0) + if (!(flags & TS_DECL_TYPE)) return; - - dump_parameters (parmtypes, v & 1, 0); + if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes) + /* 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)) - dump_type_suffix (TREE_TYPE (fntype), 1, 0); + if (show_return) + dump_type_suffix (TREE_TYPE (fntype), flags); if (TREE_CODE (fntype) == METHOD_TYPE) dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before); - if (v >= 2) - dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), 0); + if (flags & TS_FUNC_THROW) + dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags); } -/* Print a parameter list. V indicates if we show default values or not. If - these are for a member function, the member object ptr - (and any other hidden args) should have already been removed. */ +/* Print a parameter list. If this is for a member function, the + member object ptr (and any other hidden args) should have + already been removed. */ static void -dump_parameters (parmtypes, v, canonical_name) +dump_parameters (parmtypes, flags) tree parmtypes; - int v; - int canonical_name; + enum tree_string_flags flags; { int first; - OB_PUTC ('('); + OB_PUTS (" ("); for (first = 1; parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { if (!first) - OB_PUTC2 (',', ' '); + OB_PUTS (", "); first = 0; if (!parmtypes) { OB_PUTS ("..."); 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 (" = "); - 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) /* Print an exception specification. T is the exception specification. */ static void -dump_exception_spec (t, canonical_name) +dump_exception_spec (t, flags) tree t; - int canonical_name; + enum tree_string_flags flags; { if (t) { @@ -1086,11 +1148,11 @@ dump_exception_spec (t, canonical_name) if (TREE_VALUE (t) != NULL_TREE) while (1) { - dump_type_real (TREE_VALUE (t), 0, canonical_name); + dump_type (TREE_VALUE (t), flags); t = TREE_CHAIN (t); if (!t) break; - OB_PUTC2 (',', ' '); + OB_PUTS (", "); } OB_PUTC (')'); } @@ -1100,15 +1162,16 @@ dump_exception_spec (t, canonical_name) and destructors properly. */ static void -dump_function_name (t) +dump_function_name (t, flags) tree t; + enum tree_string_flags flags; { tree name = DECL_NAME (t); if (DECL_DESTRUCTOR_P (t)) { OB_PUTC ('~'); - dump_decl (name, 0); + dump_decl (name, TS_PLAIN); } else if (DECL_CONV_FN_P (t)) { @@ -1119,7 +1182,7 @@ dump_function_name (t) the types will be different, hence the TREE_TYPE field of the first name will be clobbered by the second. */ 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)) { @@ -1128,66 +1191,118 @@ dump_function_name (t) OB_PUTCP (name_string); } else - dump_decl (name, 0); + dump_decl (name, flags); - if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t) - && DECL_TEMPLATE_INFO (t) + if (DECL_LANG_SPECIFIC (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; - OB_PUTC ('<'); + dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags); +} - /* 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. */ - if (args) - { - if (TREE_CODE (args) == TREE_LIST) - { - tree arg; - int need_comma = 0; - - for (arg = args; arg; arg = TREE_CHAIN (arg)) - { - tree a = TREE_VALUE (arg); - - if (need_comma) - OB_PUTS (", "); - - if (a) - dump_template_value (a, 0, 0); - - need_comma = 1; - } - } - else if (TREE_CODE (args) == TREE_VEC) - { - int i; - int need_comma = 0; - - if (TREE_VEC_LENGTH (args) > 0 - && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) - args = TREE_VEC_ELT (args, - TREE_VEC_LENGTH (args) - 1); - - for (i = 0; i < TREE_VEC_LENGTH (args); i++) - { - tree a = TREE_VEC_ELT (args, i); - - if (need_comma) - OB_PUTS (", "); - - if (a) - dump_template_value (a, 0, 0); - - need_comma = 1; - } - } - } - OB_END_TEMPLATE_ID (); + if (args && !primary) + { + int len = 0; + int ix = 0; + int need_comma = 0; + + if (TREE_CODE (args) == TREE_VEC) + { + if (TREE_VEC_LENGTH (args) > 0 + && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) + args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); + + len = TREE_VEC_LENGTH (args); + } + else if (TREE_CODE (args) == TREE_LIST) + len = -1; + while (ix != len && args) + { + tree arg; + if (len >= 0) + { + arg = TREE_VEC_ELT (args, ix); + ix++; + } + else + { + arg = TREE_VALUE (args); + args = TREE_CHAIN (args); + } + if (need_comma) + OB_PUTS (", "); + + if (!arg) + OB_PUTS ("{tplparmerror}"); + else + dump_template_value (arg, flags); + need_comma = 1; + } + } + else if (flags & TS_PEDANTIC_NAME) + { + tree tpl = TI_TEMPLATE (info); + tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tpl)); + int len = TREE_VEC_LENGTH (parms); + 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 @@ -1240,24 +1355,25 @@ dump_char (c) /* Print out a list of initializers (subr of dump_expr) */ static void -dump_expr_list (l) +dump_expr_list (l, flags) tree l; + enum tree_string_flags flags; { while (l) { - dump_expr (TREE_VALUE (l), 0); - if (TREE_CHAIN (l)) - OB_PUTC2 (',', ' '); + dump_expr (TREE_VALUE (l), flags | TS_EXPR_PARENS); l = TREE_CHAIN (l); + if (l) + OB_PUTS (", "); } } -/* Print out an expression */ +/* Print out an expression E under control of FLAGS. */ static void -dump_expr (t, nop) +dump_expr (t, flags) tree t; - int nop; /* suppress parens */ + enum tree_string_flags flags; { switch (TREE_CODE (t)) { @@ -1269,7 +1385,7 @@ dump_expr (t, nop) case TEMPLATE_DECL: case NAMESPACE_DECL: case OVERLOAD: - dump_decl (t, -1); + dump_decl (t, flags & ~TS_DECL_TYPE); break; case INTEGER_CST: @@ -1341,7 +1457,7 @@ dump_expr (t, nop) case PTRMEM_CST: OB_PUTC ('&'); - dump_type (PTRMEM_CST_CLASS (t), 0); + dump_type (PTRMEM_CST_CLASS (t), flags); OB_PUTS ("::"); OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t))); break; @@ -1360,16 +1476,20 @@ dump_expr (t, nop) break; 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; case COND_EXPR: OB_PUTC ('('); - dump_expr (TREE_OPERAND (t, 0), 0); + dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS); OB_PUTS (" ? "); - dump_expr (TREE_OPERAND (t, 1), 0); + dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS); OB_PUTS (" : "); - dump_expr (TREE_OPERAND (t, 2), 0); + dump_expr (TREE_OPERAND (t, 2), flags | TS_EXPR_PARENS); OB_PUTC (')'); break; @@ -1377,11 +1497,11 @@ dump_expr (t, nop) if (TREE_HAS_CONSTRUCTOR (t)) { OB_PUTS ("new "); - dump_type (TREE_TYPE (TREE_TYPE (t)), 0); + dump_type (TREE_TYPE (TREE_TYPE (t)), flags); } else { - dump_expr (TREE_OPERAND (t, 0), 0); + dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS); } break; @@ -1404,7 +1524,7 @@ dump_expr (t, nop) } OB_PUTC ('('); 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 (')'); break; @@ -1421,20 +1541,20 @@ dump_expr (t, nop) tree ob = TREE_VALUE (args); 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 ('.'); } else if (TREE_CODE (ob) != PARM_DECL || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) { - dump_expr (ob, 0); - OB_PUTC2 ('-', '>'); + dump_expr (ob, flags | TS_EXPR_PARENS); + OB_PUTS ("->"); } args = TREE_CHAIN (args); } - dump_expr (fn, 0); + dump_expr (fn, flags | TS_EXPR_PARENS); OB_PUTC ('('); - dump_expr_list (args); + dump_expr_list (args, flags); OB_PUTC (')'); } break; @@ -1448,7 +1568,7 @@ dump_expr (t, nop) if (TREE_OPERAND (t, 0)) { OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 0)); + dump_expr_list (TREE_OPERAND (t, 0), flags); OB_PUTS (") "); } if (TREE_CODE (type) == ARRAY_REF) @@ -1456,11 +1576,11 @@ dump_expr (t, nop) (TREE_OPERAND (type, 0), build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1), integer_one_node))); - dump_type (type, 0); + dump_type (type, flags); if (TREE_OPERAND (t, 2)) { OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 2)); + dump_expr_list (TREE_OPERAND (t, 2), flags); OB_PUTC (')'); } } @@ -1473,7 +1593,7 @@ dump_expr (t, nop) default argument. Note we may have cleared out the first operand in expand_expr, so don't go killing ourselves. */ if (TREE_OPERAND (t, 1)) - dump_expr (TREE_OPERAND (t, 1), 0); + dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS); break; case INIT_EXPR: @@ -1500,19 +1620,19 @@ dump_expr (t, nop) case EQ_EXPR: case NE_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; case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: - dump_binary_op ("/", t); + dump_binary_op ("/", t, flags); break; case CEIL_MOD_EXPR: case FLOOR_MOD_EXPR: case ROUND_MOD_EXPR: - dump_binary_op ("%", t); + dump_binary_op ("%", t, flags); break; case COMPONENT_REF: @@ -1524,23 +1644,23 @@ dump_expr (t, nop) if (TREE_CODE (ob) != PARM_DECL || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) { - dump_expr (ob, 0); - OB_PUTC2 ('-', '>'); + dump_expr (ob, flags | TS_EXPR_PARENS); + OB_PUTS ("->"); } } else { - dump_expr (ob, 0); + dump_expr (ob, flags | TS_EXPR_PARENS); OB_PUTC ('.'); } - dump_expr (TREE_OPERAND (t, 1), 1); + dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS); } break; case ARRAY_REF: - dump_expr (TREE_OPERAND (t, 0), 0); + dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS); OB_PUTC ('['); - dump_expr (TREE_OPERAND (t, 1), 0); + dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS); OB_PUTC (']'); break; @@ -1548,18 +1668,18 @@ dump_expr (t, nop) if (same_type_p (TREE_TYPE (t), void_type_node)) { OB_PUTS ("(void)"); - dump_expr (TREE_OPERAND (t, 0), 0); + dump_expr (TREE_OPERAND (t, 0), flags); } else - dump_unary_op ("+", t, nop); + dump_unary_op ("+", t, flags); break; case ADDR_EXPR: if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL || 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 - dump_unary_op ("&", t, nop); + dump_unary_op ("&", t, flags); break; case INDIRECT_REF: @@ -1567,9 +1687,9 @@ dump_expr (t, nop) { t = TREE_OPERAND (t, 0); 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 ('('); - dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); + dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); OB_PUTC (')'); } else @@ -1577,9 +1697,9 @@ dump_expr (t, nop) if (TREE_OPERAND (t,0) != NULL_TREE && TREE_TYPE (TREE_OPERAND (t, 0)) && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) - dump_expr (TREE_OPERAND (t, 0), nop); + dump_expr (TREE_OPERAND (t, 0), flags); else - dump_unary_op ("*", t, nop); + dump_unary_op ("*", t, flags); } break; @@ -1588,13 +1708,13 @@ dump_expr (t, nop) case TRUTH_NOT_EXPR: case PREDECREMENT_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; case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: 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_PUTC (')'); break; @@ -1612,19 +1732,21 @@ dump_expr (t, nop) if (TREE_CODE (next) == FUNCTION_TYPE) { - if (!nop) OB_PUTC ('('); + if (flags & TS_EXPR_PARENS) + OB_PUTC ('('); OB_PUTC ('*'); - dump_expr (TREE_OPERAND (t, 0), 1); - if (!nop) OB_PUTC (')'); + dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS); + if (flags & TS_EXPR_PARENS) + OB_PUTC (')'); break; } /* else FALLTHRU */ } - dump_expr (TREE_OPERAND (t, 0), 0); + dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS); break; case NOP_EXPR: - dump_expr (TREE_OPERAND (t, 0), nop); + dump_expr (TREE_OPERAND (t, 0), flags); break; case CONSTRUCTOR: @@ -1635,7 +1757,7 @@ dump_expr (t, nop) if (integer_all_onesp (idx)) { tree pfn = PFN_FROM_PTRMEMFUNC (t); - dump_unary_op ("&", pfn, 0); + dump_unary_op ("&", pfn, flags | TS_EXPR_PARENS); break; } else if (TREE_CODE (idx) == INTEGER_CST @@ -1643,7 +1765,7 @@ dump_expr (t, nop) { /* A NULL pointer-to-member constant. */ OB_PUTS ("(("); - dump_type (TREE_TYPE (t), 0); + dump_type (TREE_TYPE (t), flags); OB_PUTS (") 0)"); break; } @@ -1670,13 +1792,14 @@ dump_expr (t, nop) } if (virtuals) { - dump_expr (TREE_VALUE (virtuals), 0); + dump_expr (TREE_VALUE (virtuals), + flags | TS_EXPR_PARENS); break; } } } OB_PUTC ('{'); - dump_expr_list (CONSTRUCTOR_ELTS (t)); + dump_expr_list (CONSTRUCTOR_ELTS (t), flags); OB_PUTC ('}'); break; @@ -1688,31 +1811,31 @@ dump_expr (t, nop) t = TREE_OPERAND (t, 1); if (TREE_CODE (t) == FUNCTION_DECL) /* A::f */ - dump_expr (t, 0); + dump_expr (t, flags | TS_EXPR_PARENS); 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 - dump_decl (t, 0); + dump_decl (t, flags); } else { 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 (" ->* "); } else { - dump_expr (ob, 0); + dump_expr (ob, flags | TS_EXPR_PARENS); OB_PUTS (" .* "); } - dump_expr (TREE_OPERAND (t, 1), 0); + dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS); } break; } case TEMPLATE_PARM_INDEX: - dump_decl (TEMPLATE_PARM_DECL (t), -1); + dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TS_DECL_TYPE); break; case IDENTIFIER_NODE: @@ -1720,27 +1843,27 @@ dump_expr (t, nop) break; case SCOPE_REF: - dump_type (TREE_OPERAND (t, 0), 0); + dump_type (TREE_OPERAND (t, 0), flags); OB_PUTS ("::"); - dump_expr (TREE_OPERAND (t, 1), 0); + dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS); break; case CAST_EXPR: if (TREE_OPERAND (t, 0) == NULL_TREE || TREE_CHAIN (TREE_OPERAND (t, 0))) { - dump_type (TREE_TYPE (t), 0); + dump_type (TREE_TYPE (t), flags); OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 0)); + dump_expr_list (TREE_OPERAND (t, 0), flags); OB_PUTC (')'); } else { OB_PUTC ('('); - 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 (')'); } break; @@ -1750,7 +1873,7 @@ dump_expr (t, nop) break; case ARROW_EXPR: - dump_expr (TREE_OPERAND (t, 0), nop); + dump_expr (TREE_OPERAND (t, 0), flags); OB_PUTS ("->"); break; @@ -1764,9 +1887,9 @@ dump_expr (t, nop) OB_PUTS ("__alignof__ ("); } 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 - dump_unary_op ("*", t, 0); + dump_unary_op ("*", t, flags | TS_EXPR_PARENS); OB_PUTC (')'); break; @@ -1777,19 +1900,19 @@ dump_expr (t, nop) case TRY_CATCH_EXPR: case WITH_CLEANUP_EXPR: case CLEANUP_POINT_EXPR: - dump_expr (TREE_OPERAND (t, 0), nop); + dump_expr (TREE_OPERAND (t, 0), flags); break; case PSEUDO_DTOR_EXPR: - dump_expr (TREE_OPERAND (t, 2), nop); + dump_expr (TREE_OPERAND (t, 2), flags); OB_PUTS ("."); - dump_type (TREE_OPERAND (t, 0), nop); + dump_type (TREE_OPERAND (t, 0), flags); OB_PUTS ("::~"); - dump_type (TREE_OPERAND (t, 1), nop); + dump_type (TREE_OPERAND (t, 1), flags); break; case TEMPLATE_ID_EXPR: - dump_decl (t, 0); + dump_decl (t, flags); break; case STMT_EXPR: @@ -1800,19 +1923,19 @@ dump_expr (t, nop) case BIND_EXPR: OB_PUTS ("{ "); - dump_expr (TREE_OPERAND (t, 1), nop); + dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS); OB_PUTS ("} "); break; case LOOP_EXPR: OB_PUTS ("while (1) { "); - dump_expr (TREE_OPERAND (t, 0), nop); + dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS); OB_PUTS ("} "); break; case EXIT_EXPR: OB_PUTS ("if ("); - dump_expr (TREE_OPERAND (t, 0), nop); + dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS); OB_PUTS (") break; "); break; @@ -1833,112 +1956,97 @@ dump_expr (t, nop) /* fall through to ERROR_MARK... */ case ERROR_MARK: - OB_PUTCP ("{error}"); + OB_PUTCP ("{exprerror}"); break; } } static void -dump_binary_op (opstring, t) +dump_binary_op (opstring, t, flags) const char *opstring; tree t; + enum tree_string_flags flags; { OB_PUTC ('('); - dump_expr (TREE_OPERAND (t, 0), 1); + dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS); OB_PUTC (' '); if (opstring) OB_PUTCP (opstring); else OB_PUTS (""); OB_PUTC (' '); - dump_expr (TREE_OPERAND (t, 1), 1); + dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS); OB_PUTC (')'); } static void -dump_unary_op (opstring, t, nop) +dump_unary_op (opstring, t, flags) const char *opstring; tree t; - int nop; + enum tree_string_flags flags; { - if (!nop) OB_PUTC ('('); + if (flags & TS_EXPR_PARENS) + OB_PUTC ('('); OB_PUTCP (opstring); - dump_expr (TREE_OPERAND (t, 0), 1); - if (!nop) OB_PUTC (')'); + dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS); + 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 * -fndecl_as_string (fndecl, print_default_args_p) - tree fndecl; - int print_default_args_p; +type_as_string (typ, flags) + tree typ; + enum tree_string_flags flags; { OB_INIT (); - dump_function_decl (fndecl, 2 + print_default_args_p); - + dump_type (typ, flags); + OB_FINISH (); 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 * -type_as_string_real (typ, v, canonical_name) - tree typ; - int v; - int canonical_name; +expr_as_string (decl, flags) + tree decl; + enum tree_string_flags flags; { OB_INIT (); - dump_type_real (typ, v, canonical_name); + dump_expr (decl, flags); OB_FINISH (); return (char *)obstack_base (&scratch_obstack); } - const char * -type_as_string (typ, v) - tree typ; - int v; -{ - return type_as_string_real (typ, v, 0); -} - -const char * -expr_as_string (decl, v) +decl_as_string (decl, flags) tree decl; - int v ATTRIBUTE_UNUSED; + enum tree_string_flags flags; { OB_INIT (); - dump_expr (decl, 1); + dump_decl (decl, flags); OB_FINISH (); return (char *)obstack_base (&scratch_obstack); } -/* A cross between type_as_string and fndecl_as_string. - Only called from substitute_nice_name. */ - const char * -decl_as_string (decl, v) - tree decl; - int v; +context_as_string (context, flags) + tree context; + enum tree_string_flags flags; { OB_INIT (); - - dump_decl (decl, v); - + + dump_scope (context, flags); + OB_FINISH (); return (char *)obstack_base (&scratch_obstack); @@ -1952,7 +2060,7 @@ lang_decl_name (decl, v) int v; { if (v >= 2) - return decl_as_string (decl, 1); + return decl_as_string (decl, TS_DECL_TYPE); OB_INIT (); @@ -1963,20 +2071,19 @@ lang_decl_name (decl, v) cname = DECL_CLASS_CONTEXT (decl); else cname = DECL_CONTEXT (decl); - dump_type (cname, 0); - OB_PUTC2 (':', ':'); + dump_type (cname, TS_PLAIN); + OB_PUTS ("::"); } if (TREE_CODE (decl) == FUNCTION_DECL) - dump_function_name (decl); + dump_function_name (decl, TS_PLAIN); else - dump_decl (DECL_NAME (decl), 0); + dump_decl (DECL_NAME (decl), TS_PLAIN); OB_FINISH (); return (char *)obstack_base (&scratch_obstack); } - const char * cp_file_of (t) @@ -2016,16 +2123,79 @@ cp_line_of (t) return line; } -const char * -code_as_string (c, v) +/* Now the interfaces from cp_error et al to dump_type et al. Each takes an + 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; int v ATTRIBUTE_UNUSED; { return tree_code_name [c]; } -const char * -language_as_string (c, v) +static const char * +language_to_string (c, v) enum languages c; int v ATTRIBUTE_UNUSED; { @@ -2048,8 +2218,8 @@ language_as_string (c, v) /* Return the proper printed version of a parameter to a C++ function. */ -const char * -parm_as_string (p, v) +static const char * +parm_to_string (p, v) int p; int v ATTRIBUTE_UNUSED; { @@ -2060,8 +2230,8 @@ parm_as_string (p, v) return digit_buffer; } -const char * -op_as_string (p, v) +static const char * +op_to_string (p, v) enum tree_code p; int v ATTRIBUTE_UNUSED; { @@ -2074,8 +2244,29 @@ op_as_string (p, v) return buf; } -const char * -assop_as_string (p, v) +static const char * +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; int v ATTRIBUTE_UNUSED; { @@ -2088,16 +2279,20 @@ assop_as_string (p, v) return buf; } -const char * -args_as_string (p, v) +static const char * +args_to_string (p, verbose) tree p; - int v; + int verbose; { + enum tree_string_flags flags = 0; + if (verbose) + flags |= TS_AGGR_TAGS; + if (p == NULL_TREE) return ""; if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't') - return type_as_string (p, v); + return type_as_string (p, flags); OB_INIT (); for (; p; p = TREE_CHAIN (p)) @@ -2105,7 +2300,7 @@ args_as_string (p, v) if (TREE_VALUE (p) == null_node) OB_PUTS ("NULL"); else - dump_type (error_type (TREE_VALUE (p)), v); + dump_type (error_type (TREE_VALUE (p)), flags); if (TREE_CHAIN (p)) OB_PUTS (", "); } @@ -2113,8 +2308,8 @@ args_as_string (p, v) return (char *)obstack_base (&scratch_obstack); } -const char * -cv_as_string (p, v) +static const char * +cv_to_string (p, v) tree p; int v ATTRIBUTE_UNUSED; { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3fca3d87..a4cb422 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3527,7 +3527,7 @@ mangle_class_name_for_template (name, parms, arglist) if (TREE_CODE (parm) == TYPE_DECL) { - cat (type_as_string_real (arg, 0, 1)); + cat (type_as_string (arg, TS_CHASE_TYPEDEFS)); continue; } else if (TREE_CODE (parm) == TEMPLATE_DECL) @@ -3551,7 +3551,7 @@ mangle_class_name_for_template (name, parms, arglist) } else /* Output the parameter declaration */ - cat (type_as_string_real (arg, 0, 1)); + cat (type_as_string (arg, TS_CHASE_TYPEDEFS)); continue; } else @@ -4401,7 +4401,7 @@ print_template_context (err) /* Avoid redundancy with the the "In function" line. */; else 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; file = p->file; @@ -4412,7 +4412,7 @@ print_template_context (err) for (; p; p = p->next) { 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; file = p->file; } -- 2.7.4